From 6498e7d7452f8a4fe0c566df8e10e72d05b85795 Mon Sep 17 00:00:00 2001 From: Wenhui Xie Date: Mon, 27 Nov 2023 09:37:37 +0000 Subject: [PATCH 1/7] Add netxduo regression test. --- .devcontainer/devcontainer.json | 13 + .github/workflows/regression_test.yml | 43 + .gitignore | 2 + addons/azure_iot/nx_azure_iot.c | 1 + addons/azure_iot/nx_azure_iot_adu_agent.c | 4 +- samples/demo_netxduo_snmp.c | 11 + samples/demo_snmp_helper.h | 38 +- scripts/build_nxd.sh | 3 + scripts/install.sh | 32 + scripts/test_nxd.sh | 3 + test/cmake/.gitignore | 2 + test/cmake/libs/CMakeLists.txt | 33 + test/cmake/libs/tx_user.h | 56 + test/cmake/netxduo/CMakeLists.txt | 565 + test/cmake/netxduo/additionals.cmake | 22 + test/cmake/netxduo/coverage.sh | 9 + test/cmake/netxduo/libs | 1 + test/cmake/netxduo/regression/CMakeLists.txt | 1355 +++ test/cmake/netxduo/run.sh | 9 + test/cmake/netxduo/samples/CMakeLists.txt | 61 + .../netx_auto_ip_address_check_test.c | 325 + .../netx_auto_ip_announce_num_test.c | 307 + .../netx_auto_ip_arp_dest_addr_test.c | 501 + .../auto_ip_test/netx_auto_ip_basic_test.c | 438 + .../netx_auto_ip_conflicts_check_test.c | 320 + .../netx_auto_ip_max_conflicts_test.c | 304 + test/regression/bsd_test/bsd_test_setup.docx | Bin 0 -> 24408 bytes test/regression/bsd_test/netx_bsd_aton_test.c | 106 + .../bsd_test/netx_bsd_getaddrinfo_test.c | 1276 +++ .../bsd_test/netx_bsd_inet_addr_pton_test.c | 136 + .../netx_bsd_ioctl_nonblocking_test.c | 1369 +++ .../bsd_test/netx_bsd_multicast_test.c | 429 + test/regression/bsd_test/netx_bsd_ntoa_test.c | 123 + test/regression/bsd_test/netx_bsd_ntop_test.c | 143 + test/regression/bsd_test/netx_bsd_pton_test.c | 141 + .../netx_bsd_raw_basic_blocking_test.c | 472 + .../netx_bsd_raw_basic_nonblocking_test.c | 519 + ...etx_bsd_raw_basic_rx_nohdr_blocking_test.c | 469 + ..._bsd_raw_basic_rx_nohdr_nonblocking_test.c | 542 + .../bsd_test/netx_bsd_raw_bind_connect_test.c | 533 + .../bsd_test/netx_bsd_raw_ping_test.c | 276 + .../bsd_test/netx_bsd_raw_pppoe_test.c | 560 + ...etx_bsd_raw_rx_nohdr_basic_blocking_test.c | 469 + .../bsd_test/netx_bsd_raw_tx_test.c | 549 + .../bsd_test/netx_bsd_tcp_2nd_bind_test.c | 225 + .../netx_bsd_tcp_accept_blocking_test.c | 515 + ...etx_bsd_tcp_accept_blocking_timeout_test.c | 549 + .../netx_bsd_tcp_accept_nonblocking_test.c | 579 + ..._bsd_tcp_accept_nonblocking_timeout_test.c | 610 ++ .../netx_bsd_tcp_accept_noselect_test.c | 583 ++ .../netx_bsd_tcp_basic_blocking_test.c | 1101 ++ .../netx_bsd_tcp_basic_nonblocking_test.c | 1222 +++ .../bsd_test/netx_bsd_tcp_bind_test.c | 809 ++ .../netx_bsd_tcp_blocking_bidirection_test.c | 912 ++ .../netx_bsd_tcp_clients_share_port_test.c | 855 ++ .../netx_bsd_tcp_clients_shared_port_test.c | 585 ++ .../bsd_test/netx_bsd_tcp_disconnect_test.c | 576 + .../bsd_test/netx_bsd_tcp_fionread_test.c | 423 + .../bsd_test/netx_bsd_tcp_getsockname_test.c | 454 + ...tx_bsd_tcp_getsockname_without_bind_test.c | 335 + .../netx_bsd_tcp_multiple_accept_test.c | 552 + .../bsd_test/netx_bsd_tcp_rcvbuf_test.c | 1117 ++ .../netx_bsd_tcp_sendto_recvfrom_test.c | 482 + .../netx_bsd_tcp_servers_share_port_test.c | 927 ++ .../netx_bsd_tcp_servers_shared_port_test.c | 598 ++ .../bsd_test/netx_bsd_tcp_two_blocking_test.c | 399 + .../bsd_test/netx_bsd_tcp_udp_select_test.c | 413 + .../netx_bsd_udp_basic_blocking_test.c | 501 + .../netx_bsd_udp_basic_nonblocking_test.c | 568 + .../bsd_test/netx_bsd_udp_bind_connect_test.c | 553 + .../bsd_test/netx_bsd_udp_bind_test.c | 1268 +++ .../netx_bsd_udp_blocking_bidirection_test.c | 680 ++ .../netx_bsd_udp_checksum_corrupt_test.c | 291 + .../bsd_test/netx_bsd_udp_connect_test.c | 563 + .../cloud_test/netx_cloud_api_test.c | 284 + .../cloud_test/netx_cloud_basic_test.c | 291 + .../cloud_test/netx_cloud_module_event_test.c | 287 + ...tx_cloud_module_register_deregister_test.c | 227 + .../dhcp_test/netx_dhcp_03_01_01_test.c | 380 + .../dhcp_test/netx_dhcp_03_01_02_test.c | 335 + .../dhcp_test/netx_dhcp_03_01_03_test.c | 404 + .../dhcp_test/netx_dhcp_03_02_01_test.c | 388 + .../dhcp_test/netx_dhcp_03_02_02_test.c | 395 + .../dhcp_test/netx_dhcp_03_02_03_test.c | 380 + .../dhcp_test/netx_dhcp_03_04_01_test.c | 367 + .../dhcp_test/netx_dhcp_03_05_01_test.c | 349 + .../dhcp_test/netx_dhcp_04_01_01_test.c | 353 + .../dhcp_test/netx_dhcp_04_03_02_01_test.c | 392 + .../dhcp_test/netx_dhcp_04_03_02_02_test.c | 603 ++ .../dhcp_test/netx_dhcp_04_03_02_03_test.c | 640 ++ .../dhcp_test/netx_dhcp_04_03_05_01_test.c | 383 + .../dhcp_test/netx_dhcp_04_04_01_01_test.c | 350 + .../dhcp_test/netx_dhcp_04_04_01_02_test.c | 540 + .../dhcp_test/netx_dhcp_basic_restore_test.c | 409 + .../dhcp_test/netx_dhcp_basic_test.c | 407 + ...etx_dhcp_client_activate_interfaces_test.c | 871 ++ ...t_arp_probe_fail_multiple_interface_test.c | 1033 ++ ..._client_arpprobe_fail_multiple_interface.c | 1077 ++ .../netx_dhcp_client_arpprobe_fails.c | 702 ++ ..._dhcp_client_arpprobe_multiple_interface.c | 950 ++ ..._client_arpprobe_multiple_interface_test.c | 949 ++ .../netx_dhcp_client_arpprobe_succeeds.c | 614 ++ .../dhcp_test/netx_dhcp_client_decline_test.c | 999 ++ .../netx_dhcp_client_interface_0_only_test.c | 561 + .../netx_dhcp_client_interface_1_only_test.c | 595 ++ .../netx_dhcp_client_interface_order_test.c | 260 + .../netx_dhcp_client_ip_mutex_test.c | 192 + .../netx_dhcp_client_ntp_option_test.c | 537 + .../dhcp_test/netx_dhcp_client_nxe_api_test.c | 299 + .../netx_dhcp_client_parameter_request_test.c | 390 + ...etx_dhcp_client_secondary_interface_test.c | 609 ++ ...lient_send_with_zero_source_address_test.c | 217 + ...netx_dhcp_client_server_source_port_test.c | 414 + ...netx_dhcp_client_special_attributes_test.c | 586 ++ .../netx_dhcp_client_two_interfaces.c | 858 ++ .../dhcp_test/netx_dhcp_clone_function.c | 125 + .../dhcp_test/netx_dhcp_clone_function.h | 6 + .../dhcp_test/netx_dhcp_coverage_test.c | 907 ++ .../dhcp_test/netx_dhcp_delete_test.c | 425 + .../dhcp_test/netx_dhcp_enable_test.c | 419 + .../netx_dhcp_extract_information_test.c | 1034 ++ .../netx_dhcp_get_option_value_test.c | 544 + .../netx_dhcp_multiple_instances_test.c | 525 + .../dhcp_test/netx_dhcp_packet_process_test.c | 459 + .../dhcp_test/netx_dhcp_reinitialize_test.c | 425 + .../dhcp_test/netx_dhcp_release_test.c | 419 + .../netx_dhcp_send_request_internal_test.c | 615 ++ .../netx_dhcp_server_improper_term_test.c | 518 + .../dhcp_test/netx_dhcp_server_options_test.c | 391 + .../netx_dhcp_server_second_interface_test.c | 552 + ...tx_dhcp_server_small_packet_payload_test.c | 327 + .../dhcp_test/netx_dhcp_server_test.c | 525 + .../dhcp_test/netx_dhcp_skip_discover_test.c | 398 + .../dhcp_test/netx_dhcp_start_test.c | 419 + .../dhcp_test/netx_dhcp_stop_test.c | 419 + .../dhcp_test/netx_dhcp_unicast_test.c | 486 + .../netx_dhcp_user_option_add_test.c | 393 + .../dhcp_test/netx_dhcpv6_basic_test.c | 567 + ...x_dhcpv6_client_process_server_duid_test.c | 399 + .../dhcp_test/netx_dhcpv6_extended_api_test.c | 592 ++ .../dhcp_test/netx_dhcpv6_packet_loss_test.c | 1106 ++ .../netx_dhcpv6_server_ia_options_test.c | 699 ++ .../dhcp_test/netx_dhcpv6_server_iana_test.c | 352 + ...dhcpv6_server_process_repeated_msgs_test.c | 771 ++ .../netx_dhcpv6_user_option_add_test.c | 710 ++ .../dns_test/netx_dns_abnormal_packet_test.c | 533 + .../dns_test/netx_dns_coverage_test.c | 146 + .../dns_test/netx_dns_fake_response_test.c | 386 + .../dns_test/netx_dns_function_test.c | 1612 +++ .../netx_dns_invalid_name_unencode_test.c | 407 + .../netx_dns_invalid_resource_get_test.c | 428 + .../dns_test/netx_dns_non_blocking_a_test.c | 420 + .../dns_test/netx_dns_nxe_api_test.c | 261 + .../netx_dns_packet_double_release_test.c | 351 + ...st_a_response_cname_a_smtp_live_com_test.c | 433 + .../dns_test/netx_dns_source_port_test.c | 375 + .../dns_test/response_a_berkley_edu.c | 44 + .../dns_test/response_a_cname_www_npr_org.c | 57 + .../dns_test/response_a_google_com.c | 134 + .../dns_test/response_aaaa_berkley_edu.c | 46 + .../dns_test/response_cname_mail_baidu_com.c | 48 + .../dns_test/response_mx_a_berkley_edu.c | 57 + .../dns_test/response_mx_a_google_com.c | 135 + .../dns_test/response_mx_google_com.c | 89 + .../dns_test/response_ns_a_ti_com.c | 95 + .../dns_test/response_soa_google_com.c | 54 + .../dns_test/response_srv_google_com.c | 122 + .../dns_test/response_txt_google_com.c | 53 + .../dns_test/response_with_invalid_resource.c | 103 + ...netx_ftp_access_control_commands_01_test.c | 317 + ...netx_ftp_access_control_commands_02_test.c | 322 + ...netx_ftp_access_control_commands_03_test.c | 487 + ...netx_ftp_access_control_commands_04_test.c | 381 + .../regression/ftp_test/netx_ftp_basic_test.c | 339 + .../netx_ftp_client_buffer_overflow_test.c | 402 + .../netx_ftp_client_file_write_fail_test.c | 1026 ++ ...nt_invalid_username_password_length_test.c | 293 + ...lient_multiple_connection_responses_test.c | 426 + .../netx_ftp_client_packet_leak_test.c | 358 + .../ftp_test/netx_ftp_client_pasv_denied.c | 670 ++ .../netx_ftp_client_pasv_file_read_test.c | 987 ++ .../netx_ftp_client_pasv_file_write_test.c | 1008 ++ .../netx_ftp_commands_characters_test.c | 377 + .../ftp_test/netx_ftp_commands_replys_test.c | 444 + .../netx_ftp_control_connection_test.c | 294 + .../ftp_test/netx_ftp_data_connection_test.c | 367 + .../netx_ftp_disconnection_event_test.c | 312 + ...tx_ftp_establish_data_connection_03_test.c | 422 + ...tx_ftp_establish_data_connection_05_test.c | 303 + ...tx_ftp_establish_data_connection_06_test.c | 337 + ...tx_ftp_establish_data_connection_08_test.c | 340 + .../ftp_test/netx_ftp_ipv6_epsv_test.c | 467 + .../netx_ftp_parse_ipv6_address_test.c | 118 + .../ftp_test/netx_ftp_pasv_port_test.c | 321 + .../ftp_test/netx_ftp_pasv_stor_test.c | 489 + .../ftp_test/netx_ftp_pasv_twice_test.c | 414 + test/regression/ftp_test/netx_ftp_rst_test.c | 338 + .../netx_ftp_server_abnormal_packet_test.c | 349 + .../netx_ftp_server_dangling_pointer_test.c | 351 + ...netx_ftp_server_invalid_month_crash_test.c | 740 ++ .../netx_ftp_server_list_command_test.c | 535 + .../netx_ftp_server_mss_too_small_test.c | 452 + ...netx_ftp_service_commands_RETR_STOR_test.c | 379 + .../netx_ftp_service_commands_dele_test.c | 396 + ...etx_ftp_service_commands_file_write_test.c | 423 + .../netx_ftp_service_commands_m_d_dir_test.c | 424 + .../netx_ftp_service_commands_nlist_test.c | 433 + .../netx_ftp_service_commands_rename_test.c | 414 + .../ftp_test/netx_ftp_two_listen_test.c | 314 + .../ftp_test/netx_ftp_user_data_type_test.c | 362 + .../netx_http_basic_authenticate_test.c | 443 + .../http_test/netx_http_basic_test.c | 439 + ...etx_http_client_change_connect_port_test.c | 681 ++ .../http_test/netx_http_delete_basic_test.c | 390 + .../netx_http_digest_authenticate_test.c | 528 + ...tx_http_digest_authenticate_timeout_test.c | 531 + .../netx_http_get_content_length_test.c | 615 ++ ...x_http_get_contentlength_packetleak_test.c | 646 ++ .../netx_http_get_put_referred_URI_test.c | 629 ++ .../http_test/netx_http_head_basic_test.c | 390 + .../netx_http_if_modified_since_test.c | 464 + .../netx_http_multipart_fragment_test.c | 599 ++ .../netx_http_multipart_underflow_test.c | 614 ++ .../http_test/netx_http_post_basic_test.c | 464 + ...tx_http_request_in_multiple_packets_test.c | 452 + .../netx_http_server_type_retrieve_test.c | 190 + .../http_test/netx_http_status_400_test.c | 406 + .../http_test/netx_http_status_404_test.c | 392 + .../http_test/netx_http_status_501_test.c | 315 + .../regression/mdns_test/capture/_http._tcp.c | 59 + .../mdns_test/capture/_http._tcp.pcapng | Bin 0 -> 1376 bytes .../mdns_test/capture/_pdl-datastream._tcp.c | 131 + .../capture/_pdl-datastream._tcp.pcapng | Bin 0 -> 2564 bytes .../mdns_test/capture/_printer._tcp.c | 125 + .../mdns_test/capture/_printer._tcp.pcapng | Bin 0 -> 2460 bytes test/regression/mdns_test/capture/_smb._tcp.c | 102 + .../mdns_test/capture/_smb._tcp.pcapng | Bin 0 -> 1672 bytes .../mdns_test/capture/address_change.c | 346 + .../mdns_test/capture/address_change.pcapng | Bin 0 -> 3152 bytes .../announcement_in_multiple_packets.c | 1935 ++++ .../announcement_in_multiple_packets.pcapng | Bin 0 -> 15852 bytes .../mdns_test/capture/case_insensitivity.c | 36 + .../capture/case_insensitivity.pcapng | Bin 0 -> 684 bytes .../mdns_test/capture/client_passive.c | 209 + .../mdns_test/capture/client_passive.pcapng | Bin 0 -> 2064 bytes test/regression/mdns_test/capture/command.txt | 4 + .../mdns_test/capture/continuous_query.c | 122 + .../mdns_test/capture/continuous_query.pcapng | Bin 0 -> 2444 bytes .../mdns_test/capture/continuous_query_a.c | 30 + .../capture/continuous_query_a.pcapng | Bin 0 -> 640 bytes .../capture/continuous_query_unique_answer.c | 53 + .../continuous_query_unique_answer.pcapng | Bin 0 -> 816 bytes .../mdns_test/capture/dns_sd_query.c | 351 + .../mdns_test/capture/dns_sd_query.pcapng | Bin 0 -> 3432 bytes .../capture/duplicate_question_suppression.c | 182 + .../mdns_test/capture/error_response.pcapng | Bin 0 -> 4384 bytes .../regression/mdns_test/capture/ipv6_query.c | 68 + .../mdns_test/capture/ipv6_query.pcapng | Bin 0 -> 1376 bytes .../capture/known_answer_suppression.c | 101 + .../capture/known_answer_suppression.pcapng | Bin 0 -> 2088 bytes .../known_answer_suppression_query_half_ttl.c | 172 + ...n_answer_suppression_query_half_ttl.pcapng | Bin 0 -> 1756 bytes .../known_answer_suppression_response.c | 82 + .../known_answer_suppression_response.pcapng | Bin 0 -> 1048 bytes .../mdns_known_answer_suppression_unique.c | 26 + ...dns_known_answer_suppression_unique.pcapng | Bin 0 -> 644 bytes .../capture/multiple_questions_per_query.c | 68 + .../multiple_questions_per_query.pcapng | Bin 0 -> 948 bytes .../mdns_test/capture/one_shot_query.c | 86 + .../mdns_test/capture/one_shot_query.pcapng | Bin 0 -> 1080 bytes .../mdns_test/capture/probing_conflict.c | 280 + .../mdns_test/capture/probing_conflict.pcapng | Bin 0 -> 2600 bytes .../capture/probing_conflict_any_type.c | 139 + .../capture/probing_conflict_any_type.pcapng | Bin 0 -> 1492 bytes .../capture/query_and_response_chaos.c | 2034 ++++ .../capture/query_and_response_chaos.pcapng | Bin 0 -> 16524 bytes .../mdns_test/capture/query_and_response_v6.c | 99 + .../capture/query_and_response_v6.pcapng | Bin 0 -> 1188 bytes .../capture/query_during_probing_1.c | 240 + .../capture/query_during_probing_1.pcapng | Bin 0 -> 2292 bytes .../capture/query_during_probing_2.c | 56 + .../capture/query_during_probing_2.pcapng | Bin 0 -> 840 bytes .../regression/mdns_test/capture/query_rr_a.c | 42 + .../mdns_test/capture/query_rr_a.pcapng | Bin 0 -> 732 bytes .../mdns_test/capture/query_rr_timeout.c | 83 + .../mdns_test/capture/query_rr_timeout.pcapng | Bin 0 -> 1052 bytes .../mdns_test/capture/query_start_stop.c | 110 + .../mdns_test/capture/query_start_stop.pcapng | Bin 0 -> 1264 bytes .../mdns_test/capture/query_with_tc.c | 658 ++ .../mdns_test/capture/query_with_tc.pcapng | Bin 0 -> 5644 bytes .../mdns_test/capture/responder_cooperating.c | 52 + .../capture/responder_cooperating.pcapng | Bin 0 -> 808 bytes .../capture/responder_cooperating_2.c | 54 + .../capture/responder_cooperating_2.pcapng | Bin 0 -> 828 bytes .../regression/mdns_test/capture/response_a.c | 99 + .../mdns_test/capture/response_a.pcapng | Bin 0 -> 1196 bytes .../mdns_test/capture/response_aggregation.c | 182 + .../capture/response_aggregation.pcapng | Bin 0 -> 1840 bytes .../capture/response_in_multiple_packets.c | 470 + .../response_in_multiple_packets.pcapng | Bin 0 -> 4140 bytes .../mdns_test/capture/response_interval.c | 85 + .../capture/response_interval.pcapng | Bin 0 -> 1072 bytes .../mdns_test/capture/response_interval_2.c | 520 + .../capture/response_interval_2.pcapng | Bin 0 -> 4512 bytes .../mdns_test/capture/response_no_delay.c | 36 + .../capture/response_no_delay.pcapng | Bin 0 -> 684 bytes .../capture/response_to_address_query.c | 42 + .../capture/response_to_address_query.pcapng | Bin 0 -> 732 bytes .../mdns_test/capture/response_with_tc.c | 110 + .../mdns_test/capture/response_with_tc.pcapng | Bin 0 -> 1272 bytes .../regression/mdns_test/capture/rr_timeout.c | 87 + .../mdns_test/capture/rr_timeout.pcapng | Bin 0 -> 1088 bytes .../mdns_test/capture/send_goodbye.c | 229 + .../mdns_test/capture/send_goodbye.pcapng | Bin 0 -> 2220 bytes .../mdns_test/capture/server_announcement.c | 282 + .../capture/server_announcement.pcapng | Bin 0 -> 2628 bytes .../capture/server_announcement_v6.c | 327 + .../capture/server_announcement_v6.pcapng | Bin 0 -> 3008 bytes .../capture/server_announcement_with_txt.c | 276 + .../server_announcement_with_txt.pcapng | Bin 0 -> 2604 bytes .../capture/server_interface_reset.c | 628 ++ .../capture/server_interface_reset.pcapng | Bin 0 -> 5396 bytes .../mdns_test/mdns_address_change_test.c | 382 + ...ns_announcement_in_multiple_packets_test.c | 2000 ++++ .../mdns_basic_ipv6_announcement_test.c | 364 + .../mdns_test/mdns_basic_ipv6_query_test.c | 104 + .../mdns_test/mdns_basic_ipv6_response_test.c | 141 + .../mdns_test/mdns_case_insensitivity_test.c | 58 + .../mdns_test/mdns_client_passive_test.c | 244 + .../mdns_continuous_query_interval_test.c | 174 + .../mdns_test/mdns_continuous_query_test.c | 150 + ...mdns_continuous_query_unique_answer_test.c | 84 + .../mdns_test/mdns_dns_sd_query_test.c | 386 + .../mdns_test/mdns_dns_sd_response_test.c | 381 + .../mdns_duplicate_answer_suppression_test.c | 96 + ...mdns_duplicate_question_suppression_test.c | 251 + .../mdns_known_answer_ignored_test.c | 193 + ...n_answer_suppression_query_half_ttl_test.c | 201 + ...mdns_known_answer_suppression_query_test.c | 139 + ...s_known_answer_suppression_response_test.c | 145 + ...dns_known_answer_suppression_unique_test.c | 55 + .../mdns_multiple_questions_per_query_test.c | 41 + test/regression/mdns_test/mdns_poof_test.c | 103 + .../mdns_test/mdns_probing_conflict_test.c | 321 + .../mdns_query_and_response_chaos_test.c | 2113 ++++ .../mdns_query_during_probing_test.c | 337 + .../mdns_test/mdns_query_http_tcp_test.c | 91 + .../mdns_query_pdl_datastram_tcp_test.c | 153 + .../mdns_test/mdns_query_printer_tcp_test.c | 146 + .../mdns_test/mdns_query_rr_timeout_test.c | 148 + .../mdns_test/mdns_query_smb_tcp_test.c | 123 + .../mdns_test/mdns_query_start_stop_test.c | 189 + .../mdns_test/mdns_query_with_tc_test.c | 691 ++ .../mdns_response_aggregation_test.c | 216 + .../mdns_response_in_multiple_packets_test.c | 479 + .../mdns_test/mdns_response_interval_test.c | 275 + .../mdns_test/mdns_response_no_delay_test.c | 65 + .../mdns_response_to_address_query_test.c | 72 + .../mdns_test/mdns_response_with_tc_test.c | 341 + .../mdns_server_announcement_with_txt_test.c | 328 + .../mdns_test/mdns_server_interface_reset.c | 670 ++ .../mdns_test/mdns_server_send_goodbye_test.c | 62 + .../regression/mdns_test/mdns_test_setup.docx | Bin 0 -> 42485 bytes .../netx_mdns_announcement_repeat_test.c | 498 + .../mdns_test/netx_mdns_bad_packet_test.c | 623 ++ .../mdns_test/netx_mdns_buffer_size_test.c | 176 + .../mdns_test/netx_mdns_create_delete_test.c | 212 + .../mdns_test/netx_mdns_domain_name_test.c | 284 + .../mdns_test/netx_mdns_interface_test.c | 253 + .../netx_mdns_internal_function_test.c | 1182 +++ .../mdns_test/netx_mdns_ipv6_string_test.c | 429 + ...x_mdns_local_cache_continuous_query_test.c | 298 + ...etx_mdns_local_cache_one_shot_query_test.c | 204 + .../netx_mdns_multiple_answers_test.c | 262 + .../mdns_test/netx_mdns_name_test.c | 217 + .../mdns_test/netx_mdns_one_shot_query_test.c | 284 + ...etx_mdns_peer_service_change_notify_test.c | 381 + .../regression/mdns_test/netx_mdns_ram_test.c | 299 + .../mdns_test/netx_mdns_read_overflow_test.c | 406 + .../netx_mdns_responder_cooperating_test.c | 431 + .../netx_mdns_response_with_question_test.c | 255 + .../mdns_test/netx_mdns_run_test_case.c | 829 ++ .../netx_mdns_second_interface_test.c | 282 + .../netx_mdns_service_add_delete_test.c | 399 + .../mdns_test/netx_mdns_service_lookup_test.c | 271 + .../mdns_test/netx_mdns_source_address_test.c | 299 + .../mdns_test/netx_mdns_source_port_test.c | 249 + test/regression/mdns_test/netx_mdns_test.h | 145 + .../regression/mdns_test/netx_mdns_ttl_test.c | 225 + .../mdns_test/netx_mdns_two_buffer_test.c | 304 + .../mdns_test/netx_mdns_txt_notation_test.c | 225 + .../regression/mdns_test/netx_mdns_txt_test.c | 189 + .../regression/mqtt_test/netx_mqtt_api_test.c | 318 + .../mqtt_test/netx_mqtt_branch_test.c | 398 + .../mqtt_test/netx_mqtt_connack_error_test.c | 487 + .../netx_mqtt_connect_auth_empty_test.c | 655 ++ .../mqtt_test/netx_mqtt_connect_auth_test.c | 663 ++ .../netx_mqtt_connect_non_block_2_test.c | 489 + .../netx_mqtt_connect_non_block_test.c | 526 + ...tx_mqtt_connect_packet_send_failure_test.c | 383 + .../mqtt_test/netx_mqtt_connect_test.c | 507 + .../mqtt_test/netx_mqtt_connect_v6_test.c | 555 + .../netx_mqtt_connect_will_message_test.c | 525 + .../netx_mqtt_connect_will_topic_only_test.c | 527 + .../netx_mqtt_connect_with_auth_will_test.c | 553 + .../mqtt_test/netx_mqtt_keepalive_test.c | 656 ++ .../netx_mqtt_keepalive_timeout_test.c | 641 ++ .../netx_mqtt_multiple_receive_test.c | 751 ++ .../mqtt_test/netx_mqtt_not_connected_test.c | 160 + .../mqtt_test/netx_mqtt_null_password_test.c | 147 + .../mqtt_test/netx_mqtt_packet_leak_test.c | 554 + ...etx_mqtt_publish_non_zero_packet_id_test.c | 815 ++ .../netx_mqtt_publish_packet_chain_test.c | 431 + .../mqtt_test/netx_mqtt_publish_qos0_test.c | 582 + .../mqtt_test/netx_mqtt_publish_qos1_test.c | 580 + .../mqtt_test/netx_mqtt_publish_qos2_test.c | 363 + .../mqtt_test/netx_mqtt_receive_qos0_test.c | 587 ++ .../mqtt_test/netx_mqtt_receive_qos1_test.c | 606 ++ .../mqtt_test/netx_mqtt_receive_qos2_test.c | 410 + .../mqtt_test/netx_mqtt_receive_span_test.c | 619 ++ .../netx_mqtt_remaining_length_test.c | 210 + ...x_mqtt_subscribe_non_zero_packet_id_test.c | 723 ++ .../netx_mqtt_subscribe_packet_chain_test.c | 393 + .../mqtt_test/netx_mqtt_subscribe_test.c | 595 ++ .../mqtt_test/netx_mqtt_testcontrol.c | 506 + .../netx_mqtt_transmit_queue_depth_test.c | 360 + .../mqtt_test/netx_mqtt_unsubscribe_test.c | 626 ++ .../netx_mqtt_websocket_block_test.c | 739 ++ .../netx_mqtt_websocket_non_block_test.c | 762 ++ ...etx_nat_entry_removed_after_timeout_test.c | 554 + test/regression/nat_test/netx_nat_icmp_test.c | 492 + .../nat_test/netx_nat_invalid_header_test.c | 489 + .../nat_test/netx_nat_tcp_fragment_test.c | 671 ++ .../nat_test/netx_nat_tcp_port_test.c | 639 ++ .../nat_test/netx_nat_tcp_port_test2.c | 640 ++ ...etx_nat_tcp_remove_oldest_udp_entry_test.c | 618 ++ test/regression/nat_test/netx_nat_tcp_test1.c | 560 + test/regression/nat_test/netx_nat_tcp_test2.c | 573 + .../nat_test/netx_nat_udp_fragment_test.c | 545 + .../nat_test/netx_nat_udp_port_test.c | 630 ++ test/regression/nat_test/netx_nat_udp_test.c | 817 ++ .../netxduo_test/netx_101_17_test.c | 282 + .../netxduo_test/netx_101_18_test.c | 398 + .../netxduo_test/netx_102_18_test.c | 325 + .../netxduo_test/netx_102_19_test.c | 309 + .../netxduo_test/netx_102_20_test.c | 451 + .../netxduo_test/netx_102_21_test.c | 451 + .../netxduo_test/netx_102_22_test.c | 348 + .../netxduo_test/netx_102_23_test.c | 400 + .../netxduo_test/netx_102_24_test.c | 360 + .../netxduo_test/netx_102_25_test.c | 399 + .../netxduo_test/netx_103_17_test.c | 482 + .../netxduo_test/netx_104_17_test.c | 459 + .../netxduo_test/netx_106_17_test.c | 396 + .../netxduo_test/netx_10_23_01_test.c | 363 + .../netxduo_test/netx_10_23_02_test.c | 444 + .../netxduo_test/netx_10_24_01_test.c | 331 + .../netxduo_test/netx_10_24_02_test.c | 362 + .../netxduo_test/netx_10_24_03_test.c | 347 + .../regression/netxduo_test/netx_10_25_test.c | 384 + .../regression/netxduo_test/netx_10_26_test.c | 394 + .../regression/netxduo_test/netx_11_18_test.c | 330 + .../regression/netxduo_test/netx_11_19_test.c | 317 + .../regression/netxduo_test/netx_11_23_test.c | 380 + .../regression/netxduo_test/netx_11_24_test.c | 346 + .../regression/netxduo_test/netx_11_25_test.c | 322 + .../regression/netxduo_test/netx_11_26_test.c | 354 + .../regression/netxduo_test/netx_11_27_test.c | 349 + .../regression/netxduo_test/netx_11_28_test.c | 318 + .../regression/netxduo_test/netx_11_29_test.c | 318 + .../regression/netxduo_test/netx_12_01_test.c | 422 + .../regression/netxduo_test/netx_12_02_test.c | 409 + .../regression/netxduo_test/netx_12_03_test.c | 425 + .../regression/netxduo_test/netx_12_04_test.c | 420 + .../regression/netxduo_test/netx_12_17_test.c | 418 + .../regression/netxduo_test/netx_12_18_test.c | 447 + .../regression/netxduo_test/netx_12_19_test.c | 439 + .../regression/netxduo_test/netx_12_20_test.c | 535 + .../regression/netxduo_test/netx_12_21_test.c | 443 + .../regression/netxduo_test/netx_12_23_test.c | 315 + .../regression/netxduo_test/netx_12_24_test.c | 375 + .../regression/netxduo_test/netx_12_25_test.c | 454 + .../regression/netxduo_test/netx_12_26_test.c | 472 + .../regression/netxduo_test/netx_12_27_test.c | 491 + .../regression/netxduo_test/netx_12_30_test.c | 470 + .../regression/netxduo_test/netx_12_31_test.c | 411 + .../regression/netxduo_test/netx_13_01_test.c | 420 + .../regression/netxduo_test/netx_13_02_test.c | 414 + .../regression/netxduo_test/netx_13_04_test.c | 404 + .../regression/netxduo_test/netx_13_05_test.c | 439 + .../regression/netxduo_test/netx_13_17_test.c | 402 + .../regression/netxduo_test/netx_14_19_test.c | 345 + .../regression/netxduo_test/netx_14_20_test.c | 343 + .../regression/netxduo_test/netx_15_03_test.c | 394 + .../regression/netxduo_test/netx_15_20_test.c | 460 + .../regression/netxduo_test/netx_15_21_test.c | 469 + .../regression/netxduo_test/netx_15_24_test.c | 375 + .../regression/netxduo_test/netx_15_25_test.c | 344 + .../regression/netxduo_test/netx_15_26_test.c | 321 + .../regression/netxduo_test/netx_16_02_test.c | 370 + .../regression/netxduo_test/netx_16_17_test.c | 315 + .../regression/netxduo_test/netx_16_19_test.c | 360 + .../regression/netxduo_test/netx_16_21_test.c | 385 + .../regression/netxduo_test/netx_16_22_test.c | 391 + .../regression/netxduo_test/netx_17_17_test.c | 378 + .../regression/netxduo_test/netx_18_21_test.c | 371 + test/regression/netxduo_test/netx_1_01_test.c | 347 + test/regression/netxduo_test/netx_1_02_test.c | 325 + test/regression/netxduo_test/netx_1_03_test.c | 346 + .../netxduo_test/netx_1_04_ipv6_test.c | 327 + test/regression/netxduo_test/netx_1_04_test.c | 309 + test/regression/netxduo_test/netx_1_05_test.c | 362 + test/regression/netxduo_test/netx_1_17_test.c | 313 + test/regression/netxduo_test/netx_1_18_test.c | 325 + .../netxduo_test/netx_1_19_01_test.c | 321 + .../netxduo_test/netx_1_19_02_test.c | 338 + .../netxduo_test/netx_1_19_03_test.c | 321 + test/regression/netxduo_test/netx_1_20_test.c | 359 + .../netxduo_test/netx_1_21_01_test.c | 377 + .../netxduo_test/netx_1_21_02_test.c | 346 + .../netxduo_test/netx_1_26_01_test.c | 396 + .../netxduo_test/netx_1_26_02_test.c | 362 + .../netxduo_test/netx_1_27_01_test.c | 380 + .../netxduo_test/netx_1_27_02_test.c | 352 + .../netxduo_test/netx_1_27_03_test.c | 385 + .../netxduo_test/netx_1_27_04_test.c | 368 + .../netxduo_test/netx_23_02_01_test.c | 410 + .../netxduo_test/netx_23_02_02_test.c | 415 + .../netxduo_test/netx_23_02_03_test.c | 273 + .../netxduo_test/netx_23_02_04_test.c | 273 + test/regression/netxduo_test/netx_2_01_test.c | 390 + test/regression/netxduo_test/netx_2_02_test.c | 370 + test/regression/netxduo_test/netx_2_17_test.c | 360 + test/regression/netxduo_test/netx_2_20_test.c | 451 + test/regression/netxduo_test/netx_3_01_test.c | 329 + test/regression/netxduo_test/netx_3_02_test.c | 356 + test/regression/netxduo_test/netx_3_03_test.c | 385 + test/regression/netxduo_test/netx_3_04_test.c | 525 + test/regression/netxduo_test/netx_3_06_test.c | 449 + test/regression/netxduo_test/netx_3_07_test.c | 426 + test/regression/netxduo_test/netx_3_08_test.c | 397 + test/regression/netxduo_test/netx_3_17_test.c | 469 + test/regression/netxduo_test/netx_3_18_test.c | 536 + test/regression/netxduo_test/netx_3_19_test.c | 514 + test/regression/netxduo_test/netx_3_20_test.c | 486 + test/regression/netxduo_test/netx_3_21_test.c | 550 + test/regression/netxduo_test/netx_3_23_test.c | 535 + test/regression/netxduo_test/netx_4_01_test.c | 376 + test/regression/netxduo_test/netx_4_17_test.c | 191 + test/regression/netxduo_test/netx_4_21_test.c | 328 + test/regression/netxduo_test/netx_4_23_test.c | 331 + test/regression/netxduo_test/netx_4_24_test.c | 293 + test/regression/netxduo_test/netx_4_25_test.c | 315 + test/regression/netxduo_test/netx_4_26_test.c | 293 + test/regression/netxduo_test/netx_4_27_test.c | 297 + test/regression/netxduo_test/netx_4_28_test.c | 341 + test/regression/netxduo_test/netx_4_29_test.c | 301 + test/regression/netxduo_test/netx_5_18_test.c | 195 + test/regression/netxduo_test/netx_5_19_test.c | 327 + test/regression/netxduo_test/netx_5_20_test.c | 303 + test/regression/netxduo_test/netx_5_21_test.c | 202 + test/regression/netxduo_test/netx_5_22_test.c | 357 + test/regression/netxduo_test/netx_5_23_test.c | 318 + test/regression/netxduo_test/netx_5_24_test.c | 383 + test/regression/netxduo_test/netx_5_25_test.c | 380 + test/regression/netxduo_test/netx_6_17_test.c | 337 + test/regression/netxduo_test/netx_6_18_test.c | 171 + test/regression/netxduo_test/netx_6_20_test.c | 385 + .../netxduo_test/netx_6_22_01_test.c | 387 + .../netxduo_test/netx_6_22_02_test.c | 340 + test/regression/netxduo_test/netx_6_23_test.c | 325 + test/regression/netxduo_test/netx_6_24_test.c | 292 + test/regression/netxduo_test/netx_6_25_test.c | 310 + test/regression/netxduo_test/netx_6_27_test.c | 165 + test/regression/netxduo_test/netx_6_28_test.c | 347 + test/regression/netxduo_test/netx_6_29_test.c | 325 + test/regression/netxduo_test/netx_6_32_test.c | 298 + test/regression/netxduo_test/netx_8_01_test.c | 487 + test/regression/netxduo_test/netx_8_02_test.c | 428 + test/regression/netxduo_test/netx_8_17_test.c | 366 + test/regression/netxduo_test/netx_8_18_test.c | 450 + test/regression/netxduo_test/netx_8_19_test.c | 359 + test/regression/netxduo_test/netx_8_20_test.c | 352 + test/regression/netxduo_test/netx_8_21_test.c | 392 + .../netxduo_test/netx_8_29_01_test.c | 385 + .../netxduo_test/netx_8_29_02_test.c | 380 + .../netxduo_test/netx_8_29_03_test.c | 341 + .../netxduo_test/netx_8_29_04_test.c | 367 + test/regression/netxduo_test/netx_9_17_test.c | 336 + test/regression/netxduo_test/netx_9_18_test.c | 333 + .../netxduo_test/netx_9_19_01_test.c | 372 + .../netxduo_test/netx_9_19_02_test.c | 315 + test/regression/netxduo_test/netx_9_20_test.c | 321 + .../netxduo_test/netx_9_21_01_test.c | 365 + .../netxduo_test/netx_9_21_02_test.c | 359 + test/regression/netxduo_test/netx_9_22_test.c | 349 + test/regression/netxduo_test/netx_9_27_test.c | 428 + .../netxduo_test/netx_api_compile_test.c | 332 + .../netxduo_test/netx_arp_auto_entry_test.c | 168 + .../netxduo_test/netx_arp_basic_test.c | 327 + .../netxduo_test/netx_arp_branch_test.c | 846 ++ .../netxduo_test/netx_arp_conflict_test.c | 183 + .../netxduo_test/netx_arp_dual_pool_test.c | 217 + .../netx_arp_dynamic_entry_fail_test.c | 176 + .../netx_arp_dynamic_entry_set_test.c | 202 + .../netx_arp_dynamic_entry_test.c | 423 + .../netx_arp_dynamic_entry_test2.c | 260 + .../netx_arp_dynamic_entry_test3.c | 174 + .../netx_arp_dynamic_entry_timeout_test.c | 160 + .../netx_arp_dynamic_invalidate_test.c | 405 + .../netx_arp_entry_abnormal_operation_test.c | 570 + .../netxduo_test/netx_arp_entry_cache_test.c | 383 + .../netxduo_test/netx_arp_gratuitous_test.c | 489 + .../netxduo_test/netx_arp_invalid_type_test.c | 149 + .../netx_arp_no_duplicate_entry_test.c | 425 + .../netxduo_test/netx_arp_nxe_api_test.c | 789 ++ .../netx_arp_packet_allocate_test.c | 232 + .../netxduo_test/netx_arp_queue_depth_test.c | 172 + .../netx_arp_static_entries_delete_test.c | 423 + .../netx_arp_static_entry_create_test.c | 316 + .../netx_arp_static_entry_pollute_test.c | 210 + .../netxduo_test/netx_arp_static_entry_test.c | 473 + .../netxduo_test/netx_caller_check_test.c | 1105 ++ .../netxduo_test/netx_checksum_test.c | 323 + .../netx_dest_table_add_fail_test.c | 235 + .../netx_forward_icmp_small_header_test.c | 222 + .../netx_forward_icmp_small_header_test2.c | 299 + .../netx_forward_icmp_small_header_test3.c | 314 + .../netxduo_test/netx_forward_icmp_test.c | 377 + .../netxduo_test/netx_forward_icmp_ttl_test.c | 303 + .../netx_forward_link_local_address_test.c | 187 + .../netx_forward_multicast_test.c | 224 + .../netxduo_test/netx_forward_tcp_test_1.c | 479 + .../netxduo_test/netx_forward_tcp_test_2.c | 476 + .../netxduo_test/netx_forward_tcp_test_3.c | 480 + .../netxduo_test/netx_forward_tcp_test_4.c | 476 + .../netxduo_test/netx_forward_tcp_test_5.c | 476 + .../netx_forward_udp_fragment_test.c | 497 + .../netx_forward_udp_fragment_test2.c | 457 + .../netx_forward_udp_fragment_test3.c | 445 + .../netx_forward_udp_fragment_test4.c | 446 + .../netxduo_test/netx_forward_udp_test.c | 954 ++ .../netxduo_test/netx_http_proxy_basic_test.c | 481 + .../netx_http_proxy_data_fin_test.c | 589 ++ .../netx_http_proxy_disconnect_test.c | 531 + .../netx_http_proxy_error_response_test.c | 545 + .../netx_http_proxy_multiple_response_test.c | 504 + .../netx_http_proxy_non_block_test.c | 479 + .../netxduo_test/netx_icmp_branch_test.c | 242 + .../netx_icmp_broadcast_ping_test.c | 230 + .../netxduo_test/netx_icmp_cleanup_test.c | 422 + .../netx_icmp_interface2_ping6_test.c | 623 ++ .../netx_icmp_interface2_ping_test.c | 206 + .../netx_icmp_invalid_echo_reply_test.c | 159 + .../netx_icmp_invalid_source_test.c | 160 + .../netx_icmp_loopback_fail_test.c | 158 + .../netxduo_test/netx_icmp_loopback_test.c | 171 + .../netxduo_test/netx_icmp_loopback_test2.c | 178 + .../netx_icmp_multiple_ping6_test1.c | 289 + .../netx_icmp_multiple_ping6_test2.c | 277 + .../netx_icmp_multiple_ping_test1.c | 244 + .../netx_icmp_multiple_ping_test2.c | 244 + .../netxduo_test/netx_icmp_nxe_api_test.c | 670 ++ .../netx_icmp_packet_receive_function_test.c | 424 + .../netx_icmp_ping6_data_append_test.c | 194 + .../netx_icmp_ping6_fragment_test.c | 225 + .../netxduo_test/netx_icmp_ping6_test.c | 509 + .../netx_icmp_ping_fragment_test.c | 203 + .../netx_icmp_ping_multicast_test.c | 188 + .../netxduo_test/netx_icmp_ping_test.c | 531 + .../netx_icmp_send_error_message_test.c | 470 + .../netx_icmp_send_error_message_test_1.c | 284 + .../netx_icmp_tunnel_ipv4_ipv4_ping_test.c | 240 + .../netx_icmp_tunnel_ipv4_ipv6_ping_test.c | 280 + .../netx_icmp_tunnel_ipv6_ipv4_ping_test.c | 311 + .../netx_icmp_tunnel_ipv6_ipv6_ping_test.c | 308 + .../netxduo_test/netx_icmpv6_DAD_test.c | 426 + .../netx_icmpv6_abnormal_mtu_in_ra_test.c | 201 + .../netxduo_test/netx_icmpv6_branch_test.c | 578 + ...x_icmpv6_destination_table_periodic_test.c | 985 ++ .../netx_icmpv6_echo_reply_test.c | 287 + .../netx_icmpv6_echo_request_test.c | 288 + .../netx_icmpv6_error_small_packet_test.c | 305 + .../netxduo_test/netx_icmpv6_error_test.c | 548 + .../netx_icmpv6_invalid_length_test.c | 183 + .../netx_icmpv6_invalid_length_test2.c | 177 + .../netx_icmpv6_invalid_message_test.c | 230 + .../netxduo_test/netx_icmpv6_invalid_na.c | 178 + .../netx_icmpv6_invalid_ra_dest_test.c | 189 + .../netx_icmpv6_invalid_ra_option_test.c | 183 + .../netx_icmpv6_mtu_option_test.c | 190 + .../netx_icmpv6_na_buffer_overwrite_test.c | 367 + .../netxduo_test/netx_icmpv6_na_test.c | 262 + .../netx_icmpv6_na_tlla_changed_test.c | 346 + .../netx_icmpv6_ns_buffer_overwrite_test.c | 367 + .../netx_icmpv6_ns_with_small_packet_test.c | 166 + .../netx_icmpv6_ra_address_full_test.c | 198 + .../netx_icmpv6_ra_buffer_overwrite_test.c | 371 + .../netx_icmpv6_ra_flag_callback_test.c | 192 + .../netx_icmpv6_ra_invalid_length_test.c | 176 + .../netx_icmpv6_ra_lifetime_test.c | 231 + .../netx_icmpv6_ra_router_full_test.c | 186 + .../netx_icmpv6_ra_slla_changed_test.c | 253 + ...tx_icmpv6_redirect_buffer_overwrite_test.c | 370 + .../netx_icmpv6_redirect_nd_full_test.c | 283 + .../netxduo_test/netx_icmpv6_redirect_test.c | 540 + .../netx_icmpv6_router_solicitation_test.c | 211 + .../netx_icmpv6_solicitated_ra_test.c | 196 + ...etx_icmpv6_too_big_buffer_overwrite_test.c | 367 + .../netxduo_test/netx_igmp_basic_test.c | 219 + .../netxduo_test/netx_igmp_branch_test.c | 516 + .../netx_igmp_checksum_computation_test.c | 373 + ...igmp_interface_indirect_report_send_test.c | 307 + .../netxduo_test/netx_igmp_join_fail_test.c | 183 + .../netxduo_test/netx_igmp_leave_test.c | 158 + .../netxduo_test/netx_igmp_loopback_test.c | 312 + .../netx_igmp_multicast_basic_test.c | 302 + .../netxduo_test/netx_igmp_nxe_api_test.c | 744 ++ .../netx_igmp_packet_receive_function_test.c | 412 + .../netx_igmp_router_query_test.c | 471 + .../netx_ip_abnormal_packet_test.c | 762 ++ .../netx_ip_address_change_notify_test.c | 223 + .../netx_ip_address_conflict_callback_test.c | 212 + .../netx_ip_address_conflict_detection_test.c | 497 + .../netxduo_test/netx_ip_address_get_test.c | 204 + .../netxduo_test/netx_ip_address_set_test.c | 462 + .../netx_ip_auxiliary_packet_pool_set_test.c | 167 + .../netxduo_test/netx_ip_basic_test.c | 386 + .../netxduo_test/netx_ip_branch_test.c | 1143 ++ .../netx_ip_chain_packet_process_test.c | 358 + .../netxduo_test/netx_ip_create_test.c | 126 + .../netxduo_test/netx_ip_delete_test.c | 727 ++ .../netx_ip_driver_deferred_test.c | 308 + .../netx_ip_fragmentation_disable_test.c | 277 + ...netx_ip_fragmentation_dispatch_fail_test.c | 166 + .../netx_ip_fragmentation_duplicate_test.c | 448 + .../netx_ip_fragmentation_invalid_test.c | 407 + .../netx_ip_fragmentation_order_test.c | 476 + .../netx_ip_fragmentation_packet_copy_test.c | 327 + .../netx_ip_fragmentation_packet_delay_test.c | 328 + .../netx_ip_fragmentation_packet_drop_test.c | 328 + .../netxduo_test/netx_ip_fragmentation_test.c | 503 + ...fragmentation_time_exceeded_message_test.c | 301 + ...netx_ip_fragmentation_timeout_check_test.c | 346 + ...etx_ip_fragmentation_timeout_check_test2.c | 359 + ...mentation_wrong_destination_address_test.c | 361 + ..._fragmentation_wrong_protocol_field_test.c | 359 + ...fragmentation_wrong_protocol_field_test2.c | 395 + .../netx_ip_gateway_address_test.c | 237 + .../netxduo_test/netx_ip_idle_scan_test.c | 213 + .../netx_ip_interface_address_get_test.c | 208 + .../netx_ip_interface_address_set_test.c | 526 + .../netx_ip_interface_attachment_test.c | 229 + .../netx_ip_interface_capability_test.c | 135 + ...x_ip_interface_detachment_arp_table_test.c | 257 + ...etx_ip_interface_detachment_gateway_test.c | 136 + ...interface_detachment_tcp_connection_test.c | 369 + .../netx_ip_interface_detachment_test.c | 321 + .../netx_ip_interface_info_get_test.c | 227 + ...interface_physical_address_set_fail_test.c | 136 + .../netx_ip_interface_physical_address_test.c | 149 + ...netx_ip_interface_status_check_fail_test.c | 280 + .../netx_ip_interface_status_check_test.c | 339 + .../netx_ip_invalid_packet_receive_test.c | 420 + .../netx_ip_link_local_address_test.c | 314 + .../netxduo_test/netx_ip_link_status_test.c | 288 + .../netx_ip_loopback_multihome_test.c | 253 + .../netx_ip_malformed_packet_test.c | 158 + .../netx_ip_malformed_packet_test.h | 9315 +++++++++++++++++ .../netx_ip_max_payload_size_find_test.c | 296 + .../netx_ip_multicast_interface_detach_test.c | 216 + .../netxduo_test/netx_ip_nxe_api_test.c | 1746 +++ .../netx_ip_packet_filter_extended_test.c | 369 + .../netxduo_test/netx_ip_packet_filter_test.c | 369 + .../netxduo_test/netx_ip_raw_loopback_test.c | 240 + .../netx_ip_raw_packet_filter_test.c | 265 + .../netx_ip_raw_packet_queue_test.c | 252 + .../netxduo_test/netx_ip_raw_packet_test.c | 557 + .../netx_ip_route_reachable_test.c | 181 + .../netx_ip_static_route_add_test.c | 184 + .../netx_ip_static_route_delete_test.c | 144 + .../netx_ip_static_route_find_test.c | 216 + .../netxduo_test/netx_ip_status_check_test.c | 198 + .../netx_ipv4_option_process_test.c | 523 + .../netx_ipv6_address_delete_test.c | 373 + .../netxduo_test/netx_ipv6_address_get_test.c | 237 + .../netxduo_test/netx_ipv6_address_set_test.c | 693 ++ .../netxduo_test/netx_ipv6_branch_test.c | 871 ++ .../netx_ipv6_default_router_api_test.c | 496 + .../netx_ipv6_default_router_test.c | 316 + .../netxduo_test/netx_ipv6_disable_test.c | 231 + .../netx_ipv6_fragment_fail_test.c | 188 + .../netx_ipv6_fragmentation_error_test1.c | 248 + .../netx_ipv6_fragmentation_error_test2.c | 271 + .../netx_ipv6_fragmentation_test.c | 275 + .../netx_ipv6_hop_by_hop_fragment_test.c | 400 + .../netx_ipv6_hop_by_hop_option_error_test.c | 279 + ...tx_ipv6_interface_detachment_router_test.c | 196 + .../netx_ipv6_invalid_packet_receive_test.c | 333 + .../netx_ipv6_multicast_basic_test.c | 296 + ...etx_ipv6_multicast_interface_detach_test.c | 232 + .../netx_ipv6_multicast_ping_test.c | 311 + .../netx_ipv6_multicast_ping_test1.c | 193 + .../netx_ipv6_nd_cache_api_test.c | 384 + .../netxduo_test/netx_ipv6_nxe_api_test.c | 991 ++ .../netx_ipv6_packet_chain_test.c | 346 + .../netxduo_test/netx_ipv6_pmtu_test.c | 650 ++ .../netxduo_test/netx_ipv6_prefix_test.c | 407 + .../netxduo_test/netx_ipv6_raw_packet_test.c | 389 + .../netx_ipv6_search_onlink_test.c | 481 + .../netxduo_test/netx_ipv6_send_fail_test.c | 295 + ...x_ipv6_stateless_address_autoconfig_test.c | 460 + .../netxduo_test/netx_ipv6_util_api_test.c | 1139 ++ .../netx_low_watermark_fragment_test.c | 308 + .../netxduo_test/netx_low_watermark_test.c | 502 + .../netx_low_watermark_zero_window_test.c | 330 + .../netxduo_test/netx_nd_cache_add_test.c | 404 + .../netxduo_test/netx_nd_cache_api_test.c | 384 + .../netxduo_test/netx_nd_cache_branch_test.c | 187 + .../netxduo_test/netx_nd_cache_nxe_api_test.c | 420 + ...etx_nd_cache_under_interface_detach_test.c | 324 + .../netx_nd_cache_with_own_address_test.c | 239 + .../netx_nxd_udp_socket_send_special_test.c | 269 + .../netxduo_test/netx_old_api_test.c | 141 + .../netxduo_test/netx_packet_basic_test.c | 733 ++ .../netxduo_test/netx_packet_branch_test.c | 248 + .../netx_packet_data_append_test.c | 131 + .../netx_packet_debug_info_test.c | 553 + .../netxduo_test/netx_packet_nxe_api_test.c | 911 ++ .../netx_packet_payload_size_test.c | 384 + .../netx_packet_suspension_test.c | 241 + .../netx_ramdriver_callback_test.c | 358 + .../netx_rarp_basic_processing_test.c | 453 + .../netxduo_test/netx_rarp_branch_test.c | 383 + .../netx_rarp_multiple_interfaces_test.c | 292 + .../netxduo_test/netx_rarp_nxe_api_test.c | 218 + .../netx_rarp_packet_allocate_fail_test.c | 186 + .../netxduo_test/netx_raw_nxe_api_test.c | 744 ++ .../netxduo_test/netx_raw_special_test.c | 324 + .../netx_tcp_4_duplicate_ack_test.c | 340 + .../netx_tcp_ack_before_release_test.c | 313 + .../netx_tcp_ack_check_for_syn_message_test.c | 383 + .../netx_tcp_ack_check_issue_test.c | 328 + .../netx_tcp_advertised_window_update_test.c | 331 + .../netx_tcp_basic_processing_test.c | 646 ++ .../netxduo_test/netx_tcp_branch_test.c | 2150 ++++ .../netx_tcp_chained_packet_test.c | 295 + .../netx_tcp_client_bind_cleanup_test.c | 305 + .../netx_tcp_client_packet_leak_test.c | 333 + .../netx_tcp_client_socket_bind_test.c | 206 + .../netx_tcp_client_socket_port_get_test.c | 179 + .../netx_tcp_client_socket_unbind_test.c | 193 + .../netx_tcp_connection_reset_test.c | 359 + .../netxduo_test/netx_tcp_cwnd_test.c | 395 + .../netx_tcp_data_transfer_test.c | 545 + .../netxduo_test/netx_tcp_data_trim_test.c | 335 + .../netx_tcp_delayed_retransmission_test.c | 371 + .../netx_tcp_delayed_retransmission_test2.c | 359 + .../netx_tcp_dropped_packet_test.c | 502 + .../netx_tcp_dropped_packet_test2.c | 314 + .../netx_tcp_duplicate_accept_test.c | 294 + .../netx_tcp_error_operation_check_test.c | 235 + .../netx_tcp_fast_disconnect_test.c | 475 + .../netx_tcp_fast_retransmit_test.c | 362 + .../netx_tcp_fin_wait1_to_time_wait_test.c | 306 + .../netx_tcp_fin_wait_recv_test.c | 300 + .../netx_tcp_invalid_length_test.c | 222 + .../netx_tcp_invalid_option_test.c | 492 + .../netx_tcp_invalid_option_test2.c | 459 + .../netx_tcp_invalid_packet_chain_test.c | 397 + .../netx_tcp_ipv4_interface2_mss_test.c | 336 + .../netx_tcp_ipv6_basic_processing_test.c | 546 + ...etx_tcp_ipv6_delayed_retransmission_test.c | 390 + .../netx_tcp_ipv6_interface2_mss_test.c | 379 + .../netx_tcp_ipv6_window_scale_test.c | 361 + .../netxduo_test/netx_tcp_keepalive_test.c | 302 + .../netx_tcp_large_data_transfer_test.c | 295 + .../netxduo_test/netx_tcp_large_mtu_test.c | 318 + .../netxduo_test/netx_tcp_large_mtu_test2.c | 351 + .../netx_tcp_listen_packet_leak_test.c | 339 + .../netxduo_test/netx_tcp_listen_test.c | 332 + .../netxduo_test/netx_tcp_loopback_test.c | 391 + .../netx_tcp_max_window_scale_test.c | 454 + .../netxduo_test/netx_tcp_mss_option_test.c | 428 + .../netx_tcp_multiple_send_test.c | 342 + .../netx_tcp_multiple_send_test2.c | 343 + .../netx_tcp_new_reno_algorithm_test1.c | 616 ++ .../netx_tcp_new_reno_algorithm_test2.c | 711 ++ .../netx_tcp_new_reno_algorithm_test3.c | 684 ++ .../netx_tcp_new_reno_algorithm_test4.c | 590 ++ .../netx_tcp_new_reno_algorithm_test5.c | 370 + .../netxduo_test/netx_tcp_not_enabled_test.c | 289 + .../netxduo_test/netx_tcp_nxe_api_test.c | 2298 ++++ .../netxduo_test/netx_tcp_odd_window_test.c | 314 + .../netx_tcp_out_of_order_ack_test.c | 2801 +++++ .../netx_tcp_out_of_order_packet_max_test.c | 319 + .../netx_tcp_out_of_order_packet_test.c | 493 + ...tx_tcp_out_of_window_control_packet_test.c | 334 + .../netx_tcp_overlapping_packet_test.c | 362 + .../netx_tcp_overlapping_packet_test_10.c | 319 + .../netx_tcp_overlapping_packet_test_11.c | 335 + .../netx_tcp_overlapping_packet_test_12.c | 347 + .../netx_tcp_overlapping_packet_test_13.c | 332 + .../netx_tcp_overlapping_packet_test_14.c | 326 + .../netx_tcp_overlapping_packet_test_15.c | 350 + .../netx_tcp_overlapping_packet_test_16.c | 340 + .../netx_tcp_overlapping_packet_test_17.c | 341 + .../netx_tcp_overlapping_packet_test_18.c | 334 + .../netx_tcp_overlapping_packet_test_2.c | 339 + .../netx_tcp_overlapping_packet_test_3.c | 348 + .../netx_tcp_overlapping_packet_test_4.c | 360 + .../netx_tcp_overlapping_packet_test_5.c | 348 + .../netx_tcp_overlapping_packet_test_6.c | 328 + .../netx_tcp_overlapping_packet_test_7.c | 328 + .../netx_tcp_overlapping_packet_test_8.c | 319 + .../netx_tcp_overlapping_packet_test_9.c | 337 + .../netxduo_test/netx_tcp_packet_leak_test.c | 345 + .../netx_tcp_packet_receive_function_test.c | 451 + .../netx_tcp_queue_depth_notify_test.c | 359 + .../netx_tcp_race_condition_test.c | 304 + .../netx_tcp_race_condition_test2.c | 383 + .../netx_tcp_receive_cleanup_test.c | 261 + ..._tcp_receive_under_interface_detach_test.c | 265 + ...tcp_receive_under_interface_detach_test2.c | 281 + .../netx_tcp_reset_during_send_test.c | 275 + .../netxduo_test/netx_tcp_retransmit_test.c | 334 + .../netxduo_test/netx_tcp_retransmit_test_1.c | 465 + .../netx_tcp_send_disconnect_test.c | 267 + .../netxduo_test/netx_tcp_send_fail_test.c | 466 + .../netxduo_test/netx_tcp_send_fail_test2.c | 323 + .../netxduo_test/netx_tcp_send_fail_test3.c | 277 + .../netx_tcp_server_socket_accept_test.c | 275 + .../netxduo_test/netx_tcp_simultaneous_test.c | 348 + .../netxduo_test/netx_tcp_small_packet_test.c | 159 + .../netx_tcp_small_window_preempt_test.c | 474 + .../netxduo_test/netx_tcp_small_window_test.c | 546 + .../netx_tcp_socket_available_bytes_test.c | 320 + .../netx_tcp_socket_delete_test.c | 184 + .../netx_tcp_socket_listen_queue_test.c | 876 ++ .../netx_tcp_socket_listen_test.c | 161 + .../netxduo_test/netx_tcp_socket_mss_test.c | 361 + .../netx_tcp_socket_receive_rst_test.c | 289 + .../netx_tcp_socket_relisten_test.c | 484 + .../netx_tcp_socket_relisten_test2.c | 503 + .../netx_tcp_socket_send_internal_test.c | 213 + .../netx_tcp_socket_state_wait_test.c | 305 + .../netx_tcp_socket_unaccept_test.c | 360 + .../netx_tcp_socket_unbind_test.c | 273 + .../netx_tcp_socket_unbind_test2.c | 192 + .../netx_tcp_socket_unlisten_test.c | 184 + .../netx_tcp_time_wait_to_close_test.c | 242 + .../netx_tcp_transmit_cleanup_test.c | 427 + .../netx_tcp_transmit_not_done_test.c | 299 + ...tcp_transmit_under_interface_detach_test.c | 288 + .../netx_tcp_tunnel_ipv4_ipv4_basic_test.c | 466 + .../netx_tcp_tunnel_ipv4_ipv6_address_test.c | 419 + .../netx_tcp_tunnel_ipv4_ipv6_basic_test.c | 502 + ...etx_tcp_tunnel_ipv4_ipv6_big_packet_test.c | 515 + ..._tcp_tunnel_ipv4_ipv6_small_windows_test.c | 626 ++ .../netx_tcp_tunnel_ipv6_ipv4_basic_test.c | 521 + .../netx_tcp_tunnel_ipv6_ipv6_basic_test.c | 517 + .../netx_tcp_tx_queue_exceed_test.c | 316 + .../netx_tcp_udp_random_port_test.c | 215 + .../netx_tcp_urgent_packet_test.c | 337 + .../netx_tcp_window_update_test.c | 314 + .../netx_tcp_wrapping_sequence_test.c | 488 + .../netx_tcp_wrapping_sequence_test2.c | 324 + .../netx_tcp_wrapping_sequence_test3.c | 324 + .../netx_tcp_wrapping_sequence_test4.c | 325 + .../netx_tcp_zero_window_probe_2_test.c | 357 + .../netx_tcp_zero_window_probe_3_test.c | 396 + .../netx_tcp_zero_window_probe_test.c | 359 + .../netxduo_test/netx_tcp_zero_window_test.c | 564 + .../netx_udp_basic_processing_test.c | 699 ++ .../netxduo_test/netx_udp_bind_cleanup_test.c | 202 + .../netxduo_test/netx_udp_branch_test.c | 477 + .../netx_udp_checksum_zero_test.c | 296 + .../netxduo_test/netx_udp_fragment_test.c | 566 + .../netx_udp_fragmentation_processing_test.c | 2309 ++++ .../netx_udp_free_port_find_test.c | 218 + .../netx_udp_ipv4_interface2_test_1_test.c | 511 + .../netx_udp_ipv6_interface2_test_1_test.c | 592 ++ .../netxduo_test/netx_udp_loopback_test.c | 358 + .../netx_udp_multiple_ports_test.c | 617 ++ .../netxduo_test/netx_udp_nxe_api_test.c | 1353 +++ .../netx_udp_packet_receive_test.c | 670 ++ .../netxduo_test/netx_udp_packet_type_test.c | 663 ++ .../netx_udp_port_table_udpate_test.c | 347 + .../netx_udp_port_unreachable_test.c | 296 + .../netxduo_test/netx_udp_socket_bind_test.c | 170 + .../netx_udp_socket_delete_test.c | 139 + .../netx_udp_socket_unbind_receive_test.c | 143 + .../netx_udp_socket_unbind_test.c | 232 + .../netxduo_test/netx_udp_source_send_test.c | 545 + .../netx_udp_tunnel_ipv4_ipv4_basic_test.c | 405 + .../netx_udp_tunnel_ipv4_ipv6_basic_test.c | 429 + .../netx_udp_tunnel_ipv6_ipv4_basic_test.c | 446 + .../netx_udp_tunnel_ipv6_ipv6_basic_test.c | 444 + .../netxduo_test/netx_utility_test.c | 688 ++ .../netx_pop3_abnormal_packet_test.c | 157 + .../pop3_test/netx_pop3_mail_receive_test.c | 612 ++ .../netx_pop3_packet_with_endmarker_test.c | 727 ++ .../netx_pop3_two_mails_received_test.c | 732 ++ .../netx_ppp_IPCP_abnormal_packet_test.c | 279 + .../ppp_test/netx_ppp_IPCP_nak_test.c | 490 + .../ppp_test/netx_ppp_IPCP_retransmit_test.c | 425 + .../ppp_test/netx_ppp_IPCP_timeout.c | 362 + .../netx_ppp_LCP_invalid_packet_test.c | 238 + .../ppp_test/netx_ppp_LCP_timeout.c | 233 + .../ppp_test/netx_ppp_PAP_bad_password_test.c | 410 + .../ppp_test/netx_ppp_PAP_bad_username_test.c | 413 + .../ppp_test/netx_ppp_acfc_option_test.c | 431 + ...tx_ppp_chap_bad_secret_failed_retry_test.c | 430 + ...ppp_chap_bad_secret_passed_on_retry_test.c | 474 + .../ppp_test/netx_ppp_check_boundary_test.c | 426 + .../ppp_test/netx_ppp_pap_basic_test.c | 511 + .../netx_ppp_pap_null_name_password_test.c | 340 + .../ppp_test/netx_ppp_pfc_option_test.c | 431 + .../netx_ppp_request_dns_server_test.c | 289 + .../pppoe_test/netx_pppoe_ac_name_test.c | 473 + .../pppoe_test/netx_pppoe_api_extended_test.c | 470 + .../pppoe_test/netx_pppoe_api_test.c | 463 + .../pppoe_test/netx_pppoe_basic_test.c | 457 + .../netx_pppoe_session_control_test.c | 542 + .../netx_ptp_client_announce_timeout_test.c | 254 + .../ptp_test/netx_ptp_client_api_test.c | 279 + .../ptp_test/netx_ptp_client_basic_test.c | 234 + .../ptp_test/netx_ptp_client_calibrate_test.c | 348 + .../ptp_test/netx_ptp_client_ipv6_test.c | 260 + .../netx_ptp_client_master_selection_test.c | 322 + .../netx_ptp_client_two_steps_off_test.c | 234 + test/regression/ptp_test/netx_ptp_utility.c | 526 + test/regression/ptp_test/netx_ptp_utility.h | 70 + .../rtp_test/netx_rtcp_abnormal_packet_test.c | 337 + .../rtp_test/netx_rtcp_basic_test.c | 232 + .../rtp_test/netx_rtcp_packet_process_test.c | 279 + .../rtp_test/netx_rtcp_packet_send_test.c | 203 + test/regression/rtp_test/netx_rtp_api_test.c | 152 + .../regression/rtp_test/netx_rtp_basic_test.c | 264 + .../netx_rtp_free_udp_port_find_test.c | 224 + .../rtp_test/netx_rtp_multi_clients_test.c | 380 + .../rtp_test/netx_rtp_multi_interfaces_test.c | 948 ++ .../rtp_test/netx_rtp_multicast_test.c | 372 + .../rtp_test/netx_rtp_session_aac_send_test.c | 383 + .../netx_rtp_session_h264_send_test.c | 499 + .../netx_rtp_session_jpeg_send_test.c | 558 + .../netx_rtp_session_packet_send_test.c | 355 + .../regression/rtsp_test/netx_rtsp_api_test.c | 312 + .../rtsp_test/netx_rtsp_client_timeout_test.c | 952 ++ .../netx_rtsp_delete_beforehand_test.c | 695 ++ .../rtsp_test/netx_rtsp_error_response_test.c | 402 + .../netx_rtsp_multiple_clients_test.c | 871 ++ .../netx_rtsp_multiple_request_test.c | 359 + .../rtsp_test/netx_rtsp_rtp_basic_test.c | 704 ++ .../rtsp_test/netx_rtsp_rtp_ipv6_basic_test.c | 722 ++ .../netx_rtsp_rtp_ipv6_multicast_test.c | 931 ++ .../rtsp_test/netx_rtsp_rtp_multicast_test.c | 886 ++ .../netx_smtp_abnormal_packet_test.c | 515 + .../netx_smtp_auth_logon_function_test.c | 591 ++ .../netx_smtp_auth_no_type_function_test.c | 586 ++ .../smtp_test/netx_smtp_auth_no_type_test.c | 586 ++ .../smtp_test/netx_smtp_auth_none_test.c | 575 + .../smtp_test/netx_smtp_basic_function_test.c | 584 ++ .../netx_smtp_invalid_release_test.c | 557 + ..._smtp_missing_last_250_EHLO_message_test.c | 654 ++ ...p_two_packet_EHLO_auth_last_message_test.c | 665 ++ .../netx_smtp_two_packet_EHLO_message_test.c | 666 ++ .../smtp_test/smtp_server_packets.c | 299 + test/regression/smtp_test/smtp_test_files.mk | 15 + .../snmp_test/GetSet_IPv4v6Address.c | 57 + .../GetSet_Integers_Large_and_Neg_Numbers.c | 79 + .../snmp_test/GetSet_OctetStrings.c | 58 + .../snmp_test/Get_Miscellaneous_Data_type.c | 137 + .../snmp_test/get_snmp_v3_request.c | 94 + .../netx_snmp_abnormal_packet_test.c | 489 + .../snmp_test/netx_snmp_basic_v2_test.c | 668 ++ .../netx_snmp_no_security_function_test.c | 827 ++ .../netx_snmp_setget_integers_test.c | 668 ++ .../netx_snmp_setget_ip_address_test.c | 721 ++ .../snmp_test/netx_snmp_setget_misc_test.c | 734 ++ .../netx_snmp_setget_octet_strings_test.c | 681 ++ .../netx_snmp_v1_buffer_overwrite_test.c | 504 + ..._snmp_v1_object_id_buffer_overwrite_test.c | 426 + .../netx_snmp_v1_packet_double_release_test.c | 461 + .../netx_snmp_v2_buffer_overwrite_test.c | 477 + .../netx_snmp_v2_get_bulk_request_test.c | 616 ++ .../snmp_test/netx_snmp_v2_send_trap_test.c | 670 ++ .../snmp_test/netx_snmp_v2_unknown_oid_test.c | 634 ++ .../netx_snmp_v3_buffer_overwrite_test.c | 520 + ...nmp_v3_decrypt_pdu_buffer_overwrite_test.c | 524 + ...nmp_v3_encrypt_pdu_buffer_overwrite_test.c | 517 + ...ncrypt_pdu_padding_buffer_overwrite_test.c | 525 + .../netx_snmp_v3_md5_failed_security_test.c | 660 ++ .../netx_snmp_v3_md5_security_extended_test.c | 668 ++ .../netx_snmp_v3_md5_security_test.c | 641 ++ .../netx_snmp_v3_no_security_function_test.c | 660 ++ .../netx_snmp_v3_nosec_traplist_test.c | 895 ++ ..._snmp_v3_object_id_buffer_overwrite_test.c | 517 + test/regression/snmp_test/small_mib_helper.c | 116 + test/regression/snmp_test/small_mib_helper.h | 40 + .../snmp_test/snmp_manager_packets.c | 1980 ++++ .../netx_sntp_client_broadcast_basic_test.c | 334 + ...tx_sntp_client_ipv6_broadcast_basic_test.c | 339 + ...netx_sntp_client_ipv6_unicast_basic_test.c | 339 + .../sntp_test/netx_sntp_client_kod_test.c | 269 + .../netx_sntp_client_packet_chain_test.c | 389 + .../netx_sntp_client_seconds_to_date_test.c | 130 + .../netx_sntp_client_unicast_basic_test.c | 355 + ...tx_sntp_client_unicast_display_date_test.c | 361 + .../netx_sntp_forward_unicast_update_test.c | 322 + .../netx_sntp_request_unicast_test.c | 419 + test/regression/tahi_test/netx_tahi.h | 95 + .../tahi_test/netx_tahi_dhcpv6_test_01_002.c | 164 + .../tahi_test/netx_tahi_dhcpv6_test_01_003.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_004.c | 165 + .../tahi_test/netx_tahi_dhcpv6_test_01_005.c | 165 + .../tahi_test/netx_tahi_dhcpv6_test_01_006.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_007.c | 175 + .../tahi_test/netx_tahi_dhcpv6_test_01_008.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_009.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_010.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_011.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_012.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_013.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_014.c | 229 + .../tahi_test/netx_tahi_dhcpv6_test_01_019.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_020.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_021.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_022.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_023.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_024.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_025.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_026.c | 165 + .../tahi_test/netx_tahi_dhcpv6_test_01_027.c | 165 + .../tahi_test/netx_tahi_dhcpv6_test_01_028.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_029.c | 175 + .../tahi_test/netx_tahi_dhcpv6_test_01_030.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_031.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_032.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_033.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_034.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_035.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_036.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_037.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_038.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_039.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_040.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_041.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_042.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_043.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_044.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_045.c | 177 + .../tahi_test/netx_tahi_dhcpv6_test_01_046.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_047.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_048.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_049.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_050.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_051.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_052.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_053.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_054.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_055.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_056.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_057.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_058.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_059.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_060.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_01_061.c | 174 + .../tahi_test/netx_tahi_dhcpv6_test_01_062.c | 175 + .../tahi_test/netx_tahi_dhcpv6_test_01_063.c | 175 + .../tahi_test/netx_tahi_dhcpv6_test_01_064.c | 175 + .../tahi_test/netx_tahi_dhcpv6_test_01_065.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_066.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_067.c | 175 + .../tahi_test/netx_tahi_dhcpv6_test_01_068.c | 339 + .../tahi_test/netx_tahi_dhcpv6_test_01_069.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_070.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_071.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_072.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_01_073.c | 331 + .../tahi_test/netx_tahi_dhcpv6_test_01_074.c | 340 + .../tahi_test/netx_tahi_dhcpv6_test_01_075.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_01_076.c | 332 + .../tahi_test/netx_tahi_dhcpv6_test_01_077.c | 333 + .../tahi_test/netx_tahi_dhcpv6_test_01_078.c | 164 + .../tahi_test/netx_tahi_dhcpv6_test_01_079.c | 164 + .../tahi_test/netx_tahi_dhcpv6_test_01_080.c | 167 + .../tahi_test/netx_tahi_dhcpv6_test_01_081.c | 175 + .../tahi_test/netx_tahi_dhcpv6_test_01_082.c | 318 + .../tahi_test/netx_tahi_dhcpv6_test_01_083.c | 164 + .../tahi_test/netx_tahi_dhcpv6_test_01_084.c | 314 + .../tahi_test/netx_tahi_dhcpv6_test_01_085.c | 311 + .../tahi_test/netx_tahi_dhcpv6_test_01_086.c | 164 + .../tahi_test/netx_tahi_dhcpv6_test_01_087.c | 325 + .../tahi_test/netx_tahi_dhcpv6_test_01_088.c | 164 + .../tahi_test/netx_tahi_dhcpv6_test_01_089.c | 164 + .../tahi_test/netx_tahi_dhcpv6_test_01_090.c | 324 + .../tahi_test/netx_tahi_dhcpv6_test_01_091.c | 324 + .../tahi_test/netx_tahi_dhcpv6_test_01_092.c | 324 + .../tahi_test/netx_tahi_dhcpv6_test_01_093.c | 324 + .../tahi_test/netx_tahi_dhcpv6_test_01_094.c | 324 + .../tahi_test/netx_tahi_dhcpv6_test_01_095.c | 324 + .../tahi_test/netx_tahi_dhcpv6_test_01_096.c | 324 + .../tahi_test/netx_tahi_dhcpv6_test_01_097.c | 325 + .../tahi_test/netx_tahi_dhcpv6_test_01_098.c | 325 + .../tahi_test/netx_tahi_dhcpv6_test_01_099.c | 324 + .../tahi_test/netx_tahi_dhcpv6_test_04_002.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_04_003.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_04_004.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_04_005.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_04_006.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_04_007.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_04_008.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_04_009.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_04_010.c | 437 + .../tahi_test/netx_tahi_dhcpv6_test_04_012.c | 164 + .../tahi_test/netx_tahi_dhcpv6_test_04_013.c | 164 + .../tahi_test/netx_tahi_dhcpv6_test_04_014.c | 164 + .../tahi_test/netx_tahi_dhcpv6_test_04_015.c | 164 + .../tahi_test/netx_tahi_dhcpv6_test_04_016.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_04_017.c | 166 + .../tahi_test/netx_tahi_dhcpv6_test_04_018.c | 178 + .../tahi_test/netx_tahi_dhcpv6_test_04_019.c | 178 + .../tahi_test/netx_tahi_dhcpv6_test_04_020.c | 417 + .../tahi_test/netx_tahi_dhcpv6_test_04_021.c | 417 + .../tahi_test/netx_tahi_dhcpv6_test_04_022.c | 434 + .../tahi_test/netx_tahi_dhcpv6_test_04_026.c | 163 + .../tahi_test/netx_tahi_dhcpv6_test_04_027.c | 229 + .../tahi_test/netx_tahi_dhcpv6_test_07_002.c | 418 + .../tahi_test/netx_tahi_dhcpv6_test_07_003.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_004.c | 414 + .../tahi_test/netx_tahi_dhcpv6_test_07_005.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_006.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_007.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_008.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_009.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_010.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_011.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_012.c | 414 + .../tahi_test/netx_tahi_dhcpv6_test_07_013.c | 414 + .../tahi_test/netx_tahi_dhcpv6_test_07_014.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_015.c | 323 + .../tahi_test/netx_tahi_dhcpv6_test_07_016.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_017.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_018.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_019.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_020.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_021.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_022.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_023.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_024.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_025.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_026.c | 176 + .../tahi_test/netx_tahi_dhcpv6_test_07_027.c | 238 + .../tahi_test/netx_tahi_run_test_case.c | 1165 +++ test/regression/tahi_test/netx_tahi_test_1.c | 305 + .../tahi_test/netx_tahi_test_2_01.c | 525 + .../tahi_test/netx_tahi_test_2_02.c | 146 + .../tahi_test/netx_tahi_test_2_03.c | 145 + .../tahi_test/netx_tahi_test_2_04.c | 145 + .../tahi_test/netx_tahi_test_2_05.c | 145 + .../tahi_test/netx_tahi_test_2_06.c | 145 + .../tahi_test/netx_tahi_test_2_07.c | 145 + .../tahi_test/netx_tahi_test_2_08.c | 145 + .../tahi_test/netx_tahi_test_2_09.c | 145 + .../tahi_test/netx_tahi_test_2_10.c | 240 + .../tahi_test/netx_tahi_test_2_11.c | 348 + .../tahi_test/netx_tahi_test_3_01.c | 150 + .../tahi_test/netx_tahi_test_3_02.c | 150 + .../tahi_test/netx_tahi_test_3_03.c | 134 + .../tahi_test/netx_tahi_test_3_04.c | 150 + .../tahi_test/netx_tahi_test_3_05.c | 134 + .../tahi_test/netx_tahi_test_3_06.c | 150 + .../tahi_test/netx_tahi_test_3_07.c | 150 + .../tahi_test/netx_tahi_test_3_08.c | 150 + .../tahi_test/netx_tahi_test_3_09.c | 150 + .../tahi_test/netx_tahi_test_3_10.c | 150 + .../tahi_test/netx_tahi_test_3_11.c | 150 + .../tahi_test/netx_tahi_test_3_12.c | 150 + .../tahi_test/netx_tahi_test_3_13.c | 150 + .../tahi_test/netx_tahi_test_3_14.c | 134 + .../tahi_test/netx_tahi_test_3_15.c | 134 + .../tahi_test/netx_tahi_test_3_16.c | 150 + .../tahi_test/netx_tahi_test_3_17.c | 150 + .../tahi_test/netx_tahi_test_3_18.c | 150 + .../tahi_test/netx_tahi_test_3_19.c | 150 + .../tahi_test/netx_tahi_test_3_20.c | 150 + .../tahi_test/netx_tahi_test_3_21.c | 150 + .../tahi_test/netx_tahi_test_3_22.c | 150 + .../tahi_test/netx_tahi_test_3_23.c | 134 + .../tahi_test/netx_tahi_test_3_24.c | 134 + .../tahi_test/netx_tahi_test_3_25.c | 150 + .../tahi_test/netx_tahi_test_3_26.c | 150 + .../tahi_test/netx_tahi_test_3_27.c | 150 + .../tahi_test/netx_tahi_test_3_28.c | 150 + .../tahi_test/netx_tahi_test_3_29.c | 150 + .../tahi_test/netx_tahi_test_3_30.c | 150 + .../tahi_test/netx_tahi_test_3_31.c | 150 + .../tahi_test/netx_tahi_test_3_32.c | 150 + .../tahi_test/netx_tahi_test_3_33.c | 150 + .../tahi_test/netx_tahi_test_3_34.c | 150 + .../tahi_test/netx_tahi_test_3_35.c | 150 + .../tahi_test/netx_tahi_test_3_36.c | 150 + .../tahi_test/netx_tahi_test_3_37.c | 150 + .../tahi_test/netx_tahi_test_3_38.c | 150 + .../tahi_test/netx_tahi_test_3_39.c | 150 + .../tahi_test/netx_tahi_test_3_40.c | 150 + .../tahi_test/netx_tahi_test_3_41.c | 150 + .../tahi_test/netx_tahi_test_3_42.c | 150 + .../tahi_test/netx_tahi_test_3_43.c | 150 + .../tahi_test/netx_tahi_test_3_44.c | 150 + .../tahi_test/netx_tahi_test_3_45.c | 150 + .../tahi_test/netx_tahi_test_4_10.c | 150 + .../tahi_test/netx_tahi_test_4_11.c | 150 + .../tahi_test/netx_tahi_test_4_12.c | 150 + .../tahi_test/netx_tahi_test_4_13.c | 150 + .../tahi_test/netx_tahi_test_4_14.c | 150 + .../tahi_test/netx_tahi_test_4_15.c | 150 + .../tahi_test/netx_tahi_test_4_16.c | 150 + .../regression/tahi_test/netx_tahi_test_4_2.c | 150 + .../regression/tahi_test/netx_tahi_test_4_3.c | 150 + .../regression/tahi_test/netx_tahi_test_4_4.c | 150 + .../regression/tahi_test/netx_tahi_test_4_5.c | 150 + .../regression/tahi_test/netx_tahi_test_4_6.c | 150 + .../regression/tahi_test/netx_tahi_test_4_7.c | 150 + .../regression/tahi_test/netx_tahi_test_4_8.c | 150 + .../regression/tahi_test/netx_tahi_test_4_9.c | 150 + test/regression/tahi_test/netx_tahi_test_5.c | 208 + .../tahi_test/netx_tahi_test_ipsec.c | 625 ++ .../tahi_test/netx_tahi_test_ipsec_2.c | 899 ++ .../tahi_test/netx_tahi_test_ipsec_udp.c | 671 ++ .../tahi_test/netx_tahi_test_ipsec_udp_2.c | 968 ++ test/regression/tahi_test/tahi.a | Bin 0 -> 2198906 bytes test/regression/tahi_test/tahi.so | Bin 0 -> 1705368 bytes test/regression/tahi_test/tahi64.a | Bin 0 -> 2656014 bytes test/regression/tahi_test/tahi64.so | Bin 0 -> 2895190 bytes test/regression/tahi_test/tahi_01_001.c | 32 + test/regression/tahi_test/tahi_01_002.c | 368 + test/regression/tahi_test/tahi_01_003.c | 173 + test/regression/tahi_test/tahi_01_004.c | 175 + test/regression/tahi_test/tahi_01_005.c | 167 + test/regression/tahi_test/tahi_01_006.c | 165 + test/regression/tahi_test/tahi_01_007.c | 106 + test/regression/tahi_test/tahi_01_008.c | 7481 +++++++++++++ test/regression/tahi_test/tahi_01_009.c | 185 + test/regression/tahi_test/tahi_01_010.c | 178 + test/regression/tahi_test/tahi_01_011.c | 185 + test/regression/tahi_test/tahi_01_012.c | 105 + test/regression/tahi_test/tahi_01_013.c | 7699 ++++++++++++++ test/regression/tahi_test/tahi_01_014.c | 188 + test/regression/tahi_test/tahi_01_015.c | 187 + test/regression/tahi_test/tahi_01_016.c | 186 + test/regression/tahi_test/tahi_01_017.c | 189 + test/regression/tahi_test/tahi_01_018.c | 189 + test/regression/tahi_test/tahi_01_019.c | 122 + test/regression/tahi_test/tahi_01_020.c | 191 + test/regression/tahi_test/tahi_01_021.c | 190 + test/regression/tahi_test/tahi_01_022.c | 177 + test/regression/tahi_test/tahi_01_023.c | 177 + test/regression/tahi_test/tahi_01_024.c | 155 + test/regression/tahi_test/tahi_01_025.c | 104 + test/regression/tahi_test/tahi_01_026.c | 183 + test/regression/tahi_test/tahi_01_027.c | 184 + test/regression/tahi_test/tahi_01_028.c | 183 + test/regression/tahi_test/tahi_01_029.c | 117 + test/regression/tahi_test/tahi_01_030.c | 155 + test/regression/tahi_test/tahi_01_031.c | 155 + test/regression/tahi_test/tahi_01_032.c | 155 + test/regression/tahi_test/tahi_01_033.c | 239 + test/regression/tahi_test/tahi_01_034.c | 184 + test/regression/tahi_test/tahi_01_035.c | 183 + test/regression/tahi_test/tahi_01_036.c | 184 + test/regression/tahi_test/tahi_01_037.c | 117 + test/regression/tahi_test/tahi_01_038.c | 436 + test/regression/tahi_test/tahi_01_039.c | 383 + test/regression/tahi_test/tahi_01_040.c | 451 + test/regression/tahi_test/tahi_01_041.c | 450 + test/regression/tahi_test/tahi_01_042.c | 492 + test/regression/tahi_test/tahi_01_043.c | 491 + test/regression/tahi_test/tahi_01_044.c | 489 + test/regression/tahi_test/tahi_01_045.c | 484 + test/regression/tahi_test/tahi_01_046.c | 483 + test/regression/tahi_test/tahi_01_047.c | 1052 ++ test/regression/tahi_test/tahi_01_048.c | 395 + test/regression/tahi_test/tahi_01_049.c | 467 + test/regression/tahi_test/tahi_01_050.c | 411 + test/regression/tahi_test/tahi_01_051.c | 412 + test/regression/tahi_test/tahi_01_052.c | 343 + test/regression/tahi_test/tahi_01_053.c | 181 + test/regression/tahi_test/tahi_01_054.c | 177 + test/regression/tahi_test/tahi_02_001.c | 88 + test/regression/tahi_test/tahi_02_002.c | 72 + test/regression/tahi_test/tahi_02_003.c | 135 + test/regression/tahi_test/tahi_02_004.c | 132 + test/regression/tahi_test/tahi_02_005.c | 200 + test/regression/tahi_test/tahi_02_006.c | 407 + test/regression/tahi_test/tahi_02_007.c | 210 + test/regression/tahi_test/tahi_02_008.c | 279 + test/regression/tahi_test/tahi_02_009.c | 297 + test/regression/tahi_test/tahi_02_010.c | 367 + test/regression/tahi_test/tahi_02_011.c | 367 + test/regression/tahi_test/tahi_02_012.c | 469 + test/regression/tahi_test/tahi_02_013.c | 336 + test/regression/tahi_test/tahi_02_014.c | 336 + test/regression/tahi_test/tahi_02_015.c | 336 + test/regression/tahi_test/tahi_02_016.c | 32 + test/regression/tahi_test/tahi_02_017.c | 31 + test/regression/tahi_test/tahi_02_018.c | 32 + test/regression/tahi_test/tahi_02_019.c | 32 + test/regression/tahi_test/tahi_02_020.c | 32 + test/regression/tahi_test/tahi_02_021.c | 32 + test/regression/tahi_test/tahi_02_022.c | 32 + test/regression/tahi_test/tahi_02_023.c | 33 + test/regression/tahi_test/tahi_02_024.c | 113 + test/regression/tahi_test/tahi_02_025.c | 113 + test/regression/tahi_test/tahi_02_026.c | 85 + test/regression/tahi_test/tahi_02_027.c | 150 + test/regression/tahi_test/tahi_02_028.c | 150 + test/regression/tahi_test/tahi_02_029.c | 86 + test/regression/tahi_test/tahi_02_030.c | 229 + test/regression/tahi_test/tahi_02_031.c | 190 + test/regression/tahi_test/tahi_02_032.c | 229 + test/regression/tahi_test/tahi_02_033.c | 190 + test/regression/tahi_test/tahi_02_034.c | 191 + test/regression/tahi_test/tahi_02_035.c | 191 + test/regression/tahi_test/tahi_02_036.c | 191 + test/regression/tahi_test/tahi_02_037.c | 191 + test/regression/tahi_test/tahi_02_038.c | 166 + test/regression/tahi_test/tahi_02_039.c | 150 + test/regression/tahi_test/tahi_02_040.c | 165 + test/regression/tahi_test/tahi_02_041.c | 178 + test/regression/tahi_test/tahi_02_042.c | 266 + test/regression/tahi_test/tahi_02_043.c | 267 + test/regression/tahi_test/tahi_02_044.c | 227 + test/regression/tahi_test/tahi_02_045.c | 87 + test/regression/tahi_test/tahi_02_046.c | 87 + test/regression/tahi_test/tahi_02_047.c | 87 + test/regression/tahi_test/tahi_02_048.c | 87 + test/regression/tahi_test/tahi_02_049.c | 87 + test/regression/tahi_test/tahi_02_050.c | 87 + test/regression/tahi_test/tahi_02_051.c | 88 + test/regression/tahi_test/tahi_02_052.c | 86 + test/regression/tahi_test/tahi_02_053.c | 86 + test/regression/tahi_test/tahi_02_054.c | 86 + test/regression/tahi_test/tahi_02_055.c | 86 + test/regression/tahi_test/tahi_02_056.c | 85 + test/regression/tahi_test/tahi_02_057.c | 85 + test/regression/tahi_test/tahi_02_058.c | 85 + test/regression/tahi_test/tahi_02_059.c | 85 + test/regression/tahi_test/tahi_02_060.c | 175 + test/regression/tahi_test/tahi_02_061.c | 175 + test/regression/tahi_test/tahi_02_062.c | 112 + test/regression/tahi_test/tahi_02_063.c | 112 + test/regression/tahi_test/tahi_02_064.c | 86 + test/regression/tahi_test/tahi_02_065.c | 188 + test/regression/tahi_test/tahi_02_066.c | 188 + test/regression/tahi_test/tahi_02_067.c | 188 + test/regression/tahi_test/tahi_02_068.c | 188 + test/regression/tahi_test/tahi_02_069.c | 189 + test/regression/tahi_test/tahi_02_070.c | 189 + test/regression/tahi_test/tahi_02_071.c | 189 + test/regression/tahi_test/tahi_02_072.c | 189 + test/regression/tahi_test/tahi_02_073.c | 151 + test/regression/tahi_test/tahi_02_074.c | 151 + test/regression/tahi_test/tahi_02_075.c | 151 + test/regression/tahi_test/tahi_02_076.c | 189 + test/regression/tahi_test/tahi_02_077.c | 189 + test/regression/tahi_test/tahi_02_078.c | 189 + test/regression/tahi_test/tahi_02_079.c | 151 + test/regression/tahi_test/tahi_02_080.c | 151 + test/regression/tahi_test/tahi_02_081.c | 188 + test/regression/tahi_test/tahi_02_082.c | 188 + test/regression/tahi_test/tahi_02_083.c | 151 + test/regression/tahi_test/tahi_02_084.c | 123 + test/regression/tahi_test/tahi_02_085.c | 190 + test/regression/tahi_test/tahi_02_086.c | 190 + test/regression/tahi_test/tahi_02_087.c | 152 + test/regression/tahi_test/tahi_02_088.c | 152 + test/regression/tahi_test/tahi_02_089.c | 191 + test/regression/tahi_test/tahi_02_090.c | 191 + test/regression/tahi_test/tahi_02_091.c | 152 + test/regression/tahi_test/tahi_02_092.c | 152 + test/regression/tahi_test/tahi_02_093.c | 152 + test/regression/tahi_test/tahi_02_094.c | 191 + test/regression/tahi_test/tahi_02_095.c | 152 + test/regression/tahi_test/tahi_02_096.c | 286 + test/regression/tahi_test/tahi_02_097.c | 152 + test/regression/tahi_test/tahi_02_098.c | 152 + test/regression/tahi_test/tahi_02_099.c | 151 + test/regression/tahi_test/tahi_02_100.c | 151 + test/regression/tahi_test/tahi_02_101.c | 127 + test/regression/tahi_test/tahi_02_102.c | 127 + test/regression/tahi_test/tahi_02_103.c | 203 + test/regression/tahi_test/tahi_02_104.c | 203 + test/regression/tahi_test/tahi_02_105.c | 128 + test/regression/tahi_test/tahi_02_106.c | 128 + test/regression/tahi_test/tahi_02_107.c | 204 + test/regression/tahi_test/tahi_02_108.c | 204 + test/regression/tahi_test/tahi_02_109.c | 128 + test/regression/tahi_test/tahi_02_110.c | 165 + test/regression/tahi_test/tahi_02_111.c | 128 + test/regression/tahi_test/tahi_02_112.c | 204 + test/regression/tahi_test/tahi_02_113.c | 128 + test/regression/tahi_test/tahi_02_114.c | 128 + test/regression/tahi_test/tahi_02_115.c | 128 + test/regression/tahi_test/tahi_02_116.c | 165 + test/regression/tahi_test/tahi_02_117.c | 127 + test/regression/tahi_test/tahi_02_118.c | 127 + test/regression/tahi_test/tahi_02_119.c | 282 + test/regression/tahi_test/tahi_02_120.c | 282 + test/regression/tahi_test/tahi_02_121.c | 282 + test/regression/tahi_test/tahi_02_122.c | 282 + test/regression/tahi_test/tahi_02_123.c | 417 + test/regression/tahi_test/tahi_02_124.c | 283 + test/regression/tahi_test/tahi_02_125.c | 283 + test/regression/tahi_test/tahi_02_126.c | 283 + test/regression/tahi_test/tahi_02_127.c | 88 + test/regression/tahi_test/tahi_02_128.c | 91 + test/regression/tahi_test/tahi_02_129.c | 128 + test/regression/tahi_test/tahi_02_130.c | 210 + test/regression/tahi_test/tahi_02_131.c | 96 + test/regression/tahi_test/tahi_02_132.c | 96 + test/regression/tahi_test/tahi_02_133.c | 96 + test/regression/tahi_test/tahi_02_134.c | 96 + test/regression/tahi_test/tahi_02_135.c | 85 + test/regression/tahi_test/tahi_02_136.c | 85 + test/regression/tahi_test/tahi_02_137.c | 85 + test/regression/tahi_test/tahi_02_138.c | 414 + test/regression/tahi_test/tahi_02_139.c | 91 + test/regression/tahi_test/tahi_02_140.c | 92 + test/regression/tahi_test/tahi_02_141.c | 93 + test/regression/tahi_test/tahi_02_142.c | 92 + test/regression/tahi_test/tahi_02_143.c | 92 + test/regression/tahi_test/tahi_02_144.c | 93 + test/regression/tahi_test/tahi_02_145.c | 387 + test/regression/tahi_test/tahi_02_146.c | 387 + test/regression/tahi_test/tahi_02_147.c | 7811 ++++++++++++++ test/regression/tahi_test/tahi_02_148.c | 512 + test/regression/tahi_test/tahi_02_149.c | 516 + test/regression/tahi_test/tahi_02_150.c | 719 ++ test/regression/tahi_test/tahi_02_151.c | 1320 +++ test/regression/tahi_test/tahi_02_152.c | 115 + test/regression/tahi_test/tahi_02_153.c | 128 + test/regression/tahi_test/tahi_02_154.c | 166 + test/regression/tahi_test/tahi_02_155.c | 205 + test/regression/tahi_test/tahi_02_156.c | 206 + test/regression/tahi_test/tahi_02_157.c | 343 + test/regression/tahi_test/tahi_02_158.c | 274 + test/regression/tahi_test/tahi_02_159.c | 273 + test/regression/tahi_test/tahi_02_160.c | 169 + test/regression/tahi_test/tahi_02_161.c | 169 + test/regression/tahi_test/tahi_02_162.c | 169 + test/regression/tahi_test/tahi_02_163.c | 235 + test/regression/tahi_test/tahi_02_164.c | 237 + test/regression/tahi_test/tahi_02_165.c | 236 + test/regression/tahi_test/tahi_02_166.c | 154 + test/regression/tahi_test/tahi_02_167.c | 185 + test/regression/tahi_test/tahi_02_168.c | 88 + test/regression/tahi_test/tahi_02_169.c | 516 + test/regression/tahi_test/tahi_02_170.c | 391 + test/regression/tahi_test/tahi_02_171.c | 318 + test/regression/tahi_test/tahi_02_172.c | 326 + test/regression/tahi_test/tahi_02_173.c | 319 + test/regression/tahi_test/tahi_02_174.c | 318 + test/regression/tahi_test/tahi_02_175.c | 318 + test/regression/tahi_test/tahi_02_176.c | 275 + test/regression/tahi_test/tahi_02_177.c | 275 + test/regression/tahi_test/tahi_02_178.c | 275 + test/regression/tahi_test/tahi_02_179.c | 275 + test/regression/tahi_test/tahi_02_180.c | 275 + test/regression/tahi_test/tahi_02_181.c | 275 + test/regression/tahi_test/tahi_02_182.c | 275 + test/regression/tahi_test/tahi_02_183.c | 275 + test/regression/tahi_test/tahi_02_184.c | 275 + test/regression/tahi_test/tahi_02_185.c | 408 + test/regression/tahi_test/tahi_02_186.c | 416 + test/regression/tahi_test/tahi_02_187.c | 409 + test/regression/tahi_test/tahi_02_188.c | 417 + test/regression/tahi_test/tahi_02_189.c | 410 + test/regression/tahi_test/tahi_02_190.c | 409 + test/regression/tahi_test/tahi_02_191.c | 409 + test/regression/tahi_test/tahi_02_192.c | 409 + test/regression/tahi_test/tahi_02_193.c | 409 + test/regression/tahi_test/tahi_02_194.c | 409 + test/regression/tahi_test/tahi_02_195.c | 409 + test/regression/tahi_test/tahi_02_196.c | 409 + test/regression/tahi_test/tahi_02_197.c | 409 + test/regression/tahi_test/tahi_02_198.c | 541 + test/regression/tahi_test/tahi_02_199.c | 409 + test/regression/tahi_test/tahi_02_200.c | 582 + test/regression/tahi_test/tahi_02_201.c | 410 + test/regression/tahi_test/tahi_02_202.c | 413 + test/regression/tahi_test/tahi_02_203.c | 410 + test/regression/tahi_test/tahi_02_204.c | 385 + test/regression/tahi_test/tahi_02_205.c | 307 + test/regression/tahi_test/tahi_02_206.c | 320 + test/regression/tahi_test/tahi_02_207.c | 328 + test/regression/tahi_test/tahi_02_208.c | 496 + test/regression/tahi_test/tahi_02_209.c | 308 + test/regression/tahi_test/tahi_02_210.c | 334 + test/regression/tahi_test/tahi_02_211.c | 342 + test/regression/tahi_test/tahi_02_212.c | 510 + test/regression/tahi_test/tahi_02_213.c | 410 + test/regression/tahi_test/tahi_02_214.c | 411 + test/regression/tahi_test/tahi_02_215.c | 372 + test/regression/tahi_test/tahi_02_216.c | 380 + test/regression/tahi_test/tahi_02_217.c | 548 + test/regression/tahi_test/tahi_02_218.c | 403 + test/regression/tahi_test/tahi_02_219.c | 404 + test/regression/tahi_test/tahi_02_220.c | 539 + test/regression/tahi_test/tahi_02_221.c | 412 + test/regression/tahi_test/tahi_02_222.c | 580 + test/regression/tahi_test/tahi_02_223.c | 407 + test/regression/tahi_test/tahi_02_224.c | 408 + test/regression/tahi_test/tahi_02_225.c | 446 + test/regression/tahi_test/tahi_02_226.c | 454 + test/regression/tahi_test/tahi_02_227.c | 622 ++ test/regression/tahi_test/tahi_02_228.c | 308 + test/regression/tahi_test/tahi_02_229.c | 308 + test/regression/tahi_test/tahi_02_230.c | 308 + test/regression/tahi_test/tahi_02_231.c | 308 + test/regression/tahi_test/tahi_02_232.c | 308 + test/regression/tahi_test/tahi_02_233.c | 308 + test/regression/tahi_test/tahi_02_234.c | 440 + test/regression/tahi_test/tahi_02_235.c | 308 + test/regression/tahi_test/tahi_02_236.c | 308 + test/regression/tahi_test/tahi_03_001.c | 94 + test/regression/tahi_test/tahi_03_002.c | 161 + test/regression/tahi_test/tahi_03_003.c | 136 + test/regression/tahi_test/tahi_03_004.c | 139 + test/regression/tahi_test/tahi_03_005.c | 136 + test/regression/tahi_test/tahi_03_006.c | 138 + test/regression/tahi_test/tahi_03_007.c | 201 + test/regression/tahi_test/tahi_03_008.c | 201 + test/regression/tahi_test/tahi_03_009.c | 201 + test/regression/tahi_test/tahi_03_010.c | 164 + test/regression/tahi_test/tahi_03_011.c | 164 + test/regression/tahi_test/tahi_03_012.c | 201 + test/regression/tahi_test/tahi_03_013.c | 202 + test/regression/tahi_test/tahi_03_014.c | 173 + test/regression/tahi_test/tahi_03_015.c | 111 + test/regression/tahi_test/tahi_03_016.c | 139 + test/regression/tahi_test/tahi_03_017.c | 165 + test/regression/tahi_test/tahi_03_018.c | 202 + test/regression/tahi_test/tahi_03_019.c | 202 + test/regression/tahi_test/tahi_03_020.c | 284 + test/regression/tahi_test/tahi_03_021.c | 152 + test/regression/tahi_test/tahi_03_022.c | 202 + test/regression/tahi_test/tahi_03_023.c | 174 + test/regression/tahi_test/tahi_03_024.c | 111 + test/regression/tahi_test/tahi_03_025.c | 165 + test/regression/tahi_test/tahi_03_026.c | 202 + test/regression/tahi_test/tahi_03_027.c | 167 + test/regression/tahi_test/tahi_03_028.c | 141 + test/regression/tahi_test/tahi_03_029.c | 141 + test/regression/tahi_test/tahi_03_030.c | 185 + test/regression/tahi_test/tahi_03_031.c | 316 + test/regression/tahi_test/tahi_03_032.c | 342 + test/regression/tahi_test/tahi_03_033.c | 102 + test/regression/tahi_test/tahi_03_034.c | 102 + test/regression/tahi_test/tahi_03_035.c | 102 + test/regression/tahi_test/tahi_03_036.c | 102 + test/regression/tahi_test/tahi_03_037.c | 102 + test/regression/tahi_test/tahi_03_038.c | 102 + test/regression/tahi_test/tahi_03_039.c | 102 + test/regression/tahi_test/tahi_03_040.c | 115 + test/regression/tahi_test/tahi_03_041.c | 141 + test/regression/tahi_test/tahi_03_042.c | 421 + test/regression/tahi_test/tahi_03_043.c | 248 + test/regression/tahi_test/tahi_03_044.c | 329 + test/regression/tahi_test/tahi_03_045.c | 346 + test/regression/tahi_test/tahi_04_002.c | 195 + test/regression/tahi_test/tahi_04_003.c | 499 + test/regression/tahi_test/tahi_04_004.c | 555 + test/regression/tahi_test/tahi_04_005.c | 4970 +++++++++ test/regression/tahi_test/tahi_04_006.c | 1087 ++ test/regression/tahi_test/tahi_04_007.c | 2320 ++++ test/regression/tahi_test/tahi_04_008.c | 1666 +++ test/regression/tahi_test/tahi_04_009.c | 1007 ++ test/regression/tahi_test/tahi_04_010.c | 1007 ++ test/regression/tahi_test/tahi_04_011.c | 1682 +++ test/regression/tahi_test/tahi_04_012.c | 1683 +++ test/regression/tahi_test/tahi_04_013.c | 979 ++ test/regression/tahi_test/tahi_04_014.c | 7101 +++++++++++++ test/regression/tahi_test/tahi_04_015.c | 2007 ++++ test/regression/tahi_test/tahi_04_016.c | 2183 ++++ test/regression/tahi_test/tahi_05_002.c | 418 + test/regression/tahi_test/tahi_05_003.c | 173 + test/regression/tahi_test/tahi_05_004.c | 399 + test/regression/tahi_test/tahi_05_005.c | 375 + test/regression/tahi_test/tahi_05_006.c | 167 + test/regression/tahi_test/tahi_05_007.c | 167 + test/regression/tahi_test/tahi_05_008.c | 351 + test/regression/tahi_test/tahi_05_009.c | 766 ++ test/regression/tahi_test/tahi_05_010.c | 765 ++ test/regression/tahi_test/tahi_05_012.c | 438 + test/regression/tahi_test/tahi_05_013.c | 437 + test/regression/tahi_test/tahi_05_014.c | 417 + test/regression/tahi_test/tahi_05_015.c | 569 + test/regression/tahi_test/tahi_05_017.c | 947 ++ test/regression/tahi_test/tahi_05_018.c | 569 + test/regression/tahi_test/tahi_05_020.c | 948 ++ test/regression/tahi_test/tahi_05_021.c | 569 + test/regression/tahi_test/tahi_05_022.c | 736 ++ test/regression/tahi_test/tahi_05_024.c | 1203 +++ test/regression/tahi_test/tahi_05_025.c | 737 ++ .../regression/tahi_test/tahi_dhcpv6_01_001.c | 28 + .../regression/tahi_test/tahi_dhcpv6_01_002.c | 403 + .../regression/tahi_test/tahi_dhcpv6_01_003.c | 382 + .../regression/tahi_test/tahi_dhcpv6_01_004.c | 489 + .../regression/tahi_test/tahi_dhcpv6_01_005.c | 490 + .../regression/tahi_test/tahi_dhcpv6_01_006.c | 399 + .../regression/tahi_test/tahi_dhcpv6_01_007.c | 319 + .../regression/tahi_test/tahi_dhcpv6_01_008.c | 193 + .../regression/tahi_test/tahi_dhcpv6_01_009.c | 255 + .../regression/tahi_test/tahi_dhcpv6_01_010.c | 281 + .../regression/tahi_test/tahi_dhcpv6_01_011.c | 194 + .../regression/tahi_test/tahi_dhcpv6_01_012.c | 193 + .../regression/tahi_test/tahi_dhcpv6_01_013.c | 193 + .../regression/tahi_test/tahi_dhcpv6_01_014.c | 377 + .../regression/tahi_test/tahi_dhcpv6_01_019.c | 195 + .../regression/tahi_test/tahi_dhcpv6_01_020.c | 216 + .../regression/tahi_test/tahi_dhcpv6_01_021.c | 256 + .../regression/tahi_test/tahi_dhcpv6_01_022.c | 373 + .../regression/tahi_test/tahi_dhcpv6_01_023.c | 194 + .../regression/tahi_test/tahi_dhcpv6_01_024.c | 258 + .../regression/tahi_test/tahi_dhcpv6_01_025.c | 430 + .../regression/tahi_test/tahi_dhcpv6_01_026.c | 366 + .../regression/tahi_test/tahi_dhcpv6_01_027.c | 418 + .../regression/tahi_test/tahi_dhcpv6_01_028.c | 410 + .../regression/tahi_test/tahi_dhcpv6_01_029.c | 320 + .../regression/tahi_test/tahi_dhcpv6_01_030.c | 623 ++ .../regression/tahi_test/tahi_dhcpv6_01_031.c | 189 + .../regression/tahi_test/tahi_dhcpv6_01_032.c | 192 + .../regression/tahi_test/tahi_dhcpv6_01_033.c | 212 + .../regression/tahi_test/tahi_dhcpv6_01_034.c | 292 + .../regression/tahi_test/tahi_dhcpv6_01_035.c | 329 + .../regression/tahi_test/tahi_dhcpv6_01_036.c | 274 + .../regression/tahi_test/tahi_dhcpv6_01_037.c | 253 + .../regression/tahi_test/tahi_dhcpv6_01_038.c | 254 + .../regression/tahi_test/tahi_dhcpv6_01_039.c | 363 + .../regression/tahi_test/tahi_dhcpv6_01_040.c | 473 + .../regression/tahi_test/tahi_dhcpv6_01_041.c | 428 + .../regression/tahi_test/tahi_dhcpv6_01_042.c | 429 + .../regression/tahi_test/tahi_dhcpv6_01_043.c | 454 + .../regression/tahi_test/tahi_dhcpv6_01_044.c | 522 + .../regression/tahi_test/tahi_dhcpv6_01_045.c | 555 + .../regression/tahi_test/tahi_dhcpv6_01_046.c | 365 + .../regression/tahi_test/tahi_dhcpv6_01_047.c | 391 + .../regression/tahi_test/tahi_dhcpv6_01_048.c | 555 + .../regression/tahi_test/tahi_dhcpv6_01_049.c | 441 + .../regression/tahi_test/tahi_dhcpv6_01_050.c | 615 ++ .../regression/tahi_test/tahi_dhcpv6_01_051.c | 442 + .../regression/tahi_test/tahi_dhcpv6_01_052.c | 508 + .../regression/tahi_test/tahi_dhcpv6_01_053.c | 517 + .../regression/tahi_test/tahi_dhcpv6_01_054.c | 482 + .../regression/tahi_test/tahi_dhcpv6_01_055.c | 530 + .../regression/tahi_test/tahi_dhcpv6_01_056.c | 331 + .../regression/tahi_test/tahi_dhcpv6_01_057.c | 461 + .../regression/tahi_test/tahi_dhcpv6_01_058.c | 407 + .../regression/tahi_test/tahi_dhcpv6_01_059.c | 525 + .../regression/tahi_test/tahi_dhcpv6_01_060.c | 296 + .../regression/tahi_test/tahi_dhcpv6_01_061.c | 350 + .../regression/tahi_test/tahi_dhcpv6_01_062.c | 360 + .../regression/tahi_test/tahi_dhcpv6_01_063.c | 367 + .../regression/tahi_test/tahi_dhcpv6_01_064.c | 392 + .../regression/tahi_test/tahi_dhcpv6_01_065.c | 144 + .../regression/tahi_test/tahi_dhcpv6_01_066.c | 362 + .../regression/tahi_test/tahi_dhcpv6_01_067.c | 497 + .../regression/tahi_test/tahi_dhcpv6_01_068.c | 709 ++ .../regression/tahi_test/tahi_dhcpv6_01_069.c | 528 + .../regression/tahi_test/tahi_dhcpv6_01_070.c | 452 + .../regression/tahi_test/tahi_dhcpv6_01_071.c | 313 + .../regression/tahi_test/tahi_dhcpv6_01_072.c | 324 + .../regression/tahi_test/tahi_dhcpv6_01_073.c | 324 + .../regression/tahi_test/tahi_dhcpv6_01_074.c | 439 + .../regression/tahi_test/tahi_dhcpv6_01_075.c | 536 + .../regression/tahi_test/tahi_dhcpv6_01_076.c | 479 + .../regression/tahi_test/tahi_dhcpv6_01_077.c | 478 + .../regression/tahi_test/tahi_dhcpv6_01_078.c | 395 + .../regression/tahi_test/tahi_dhcpv6_01_079.c | 386 + .../regression/tahi_test/tahi_dhcpv6_01_080.c | 331 + .../regression/tahi_test/tahi_dhcpv6_01_081.c | 323 + .../regression/tahi_test/tahi_dhcpv6_01_082.c | 189 + .../regression/tahi_test/tahi_dhcpv6_01_083.c | 250 + .../regression/tahi_test/tahi_dhcpv6_01_084.c | 1555 +++ .../regression/tahi_test/tahi_dhcpv6_01_085.c | 235 + .../regression/tahi_test/tahi_dhcpv6_01_086.c | 325 + .../regression/tahi_test/tahi_dhcpv6_01_087.c | 271 + .../regression/tahi_test/tahi_dhcpv6_01_088.c | 347 + .../regression/tahi_test/tahi_dhcpv6_01_089.c | 291 + .../regression/tahi_test/tahi_dhcpv6_01_090.c | 405 + .../regression/tahi_test/tahi_dhcpv6_01_091.c | 215 + .../regression/tahi_test/tahi_dhcpv6_01_092.c | 431 + .../regression/tahi_test/tahi_dhcpv6_01_093.c | 250 + .../regression/tahi_test/tahi_dhcpv6_01_094.c | 313 + .../regression/tahi_test/tahi_dhcpv6_01_095.c | 299 + .../regression/tahi_test/tahi_dhcpv6_01_096.c | 301 + .../regression/tahi_test/tahi_dhcpv6_01_097.c | 310 + .../regression/tahi_test/tahi_dhcpv6_01_098.c | 311 + .../regression/tahi_test/tahi_dhcpv6_01_099.c | 218 + .../regression/tahi_test/tahi_dhcpv6_04_002.c | 150 + .../regression/tahi_test/tahi_dhcpv6_04_003.c | 260 + .../regression/tahi_test/tahi_dhcpv6_04_004.c | 221 + .../regression/tahi_test/tahi_dhcpv6_04_005.c | 191 + .../regression/tahi_test/tahi_dhcpv6_04_006.c | 256 + .../regression/tahi_test/tahi_dhcpv6_04_007.c | 255 + .../regression/tahi_test/tahi_dhcpv6_04_008.c | 370 + .../regression/tahi_test/tahi_dhcpv6_04_009.c | 312 + .../regression/tahi_test/tahi_dhcpv6_04_010.c | 587 ++ .../regression/tahi_test/tahi_dhcpv6_04_012.c | 309 + .../regression/tahi_test/tahi_dhcpv6_04_013.c | 308 + .../regression/tahi_test/tahi_dhcpv6_04_014.c | 361 + .../regression/tahi_test/tahi_dhcpv6_04_015.c | 359 + .../regression/tahi_test/tahi_dhcpv6_04_016.c | 414 + .../regression/tahi_test/tahi_dhcpv6_04_017.c | 330 + .../regression/tahi_test/tahi_dhcpv6_04_018.c | 375 + .../regression/tahi_test/tahi_dhcpv6_04_019.c | 334 + .../regression/tahi_test/tahi_dhcpv6_04_020.c | 330 + .../regression/tahi_test/tahi_dhcpv6_04_021.c | 336 + .../regression/tahi_test/tahi_dhcpv6_04_022.c | 615 ++ .../regression/tahi_test/tahi_dhcpv6_04_026.c | 164 + .../regression/tahi_test/tahi_dhcpv6_04_027.c | 386 + .../regression/tahi_test/tahi_dhcpv6_07_002.c | 555 + .../regression/tahi_test/tahi_dhcpv6_07_003.c | 469 + .../regression/tahi_test/tahi_dhcpv6_07_004.c | 455 + .../regression/tahi_test/tahi_dhcpv6_07_005.c | 458 + .../regression/tahi_test/tahi_dhcpv6_07_006.c | 531 + .../regression/tahi_test/tahi_dhcpv6_07_007.c | 385 + .../regression/tahi_test/tahi_dhcpv6_07_008.c | 519 + .../regression/tahi_test/tahi_dhcpv6_07_009.c | 467 + .../regression/tahi_test/tahi_dhcpv6_07_010.c | 467 + .../regression/tahi_test/tahi_dhcpv6_07_011.c | 468 + .../regression/tahi_test/tahi_dhcpv6_07_012.c | 458 + .../regression/tahi_test/tahi_dhcpv6_07_013.c | 543 + .../regression/tahi_test/tahi_dhcpv6_07_014.c | 542 + .../regression/tahi_test/tahi_dhcpv6_07_015.c | 422 + .../regression/tahi_test/tahi_dhcpv6_07_016.c | 424 + .../regression/tahi_test/tahi_dhcpv6_07_017.c | 424 + .../regression/tahi_test/tahi_dhcpv6_07_018.c | 424 + .../regression/tahi_test/tahi_dhcpv6_07_019.c | 497 + .../regression/tahi_test/tahi_dhcpv6_07_020.c | 424 + .../regression/tahi_test/tahi_dhcpv6_07_021.c | 428 + .../regression/tahi_test/tahi_dhcpv6_07_022.c | 428 + .../regression/tahi_test/tahi_dhcpv6_07_023.c | 421 + .../regression/tahi_test/tahi_dhcpv6_07_024.c | 427 + .../regression/tahi_test/tahi_dhcpv6_07_025.c | 475 + .../regression/tahi_test/tahi_dhcpv6_07_026.c | 462 + .../regression/tahi_test/tahi_dhcpv6_07_027.c | 612 ++ test/regression/tahi_test/tahi_ipsec_001.c | 163 + test/regression/tahi_test/tahi_ipsec_002.c | 147 + test/regression/tahi_test/tahi_ipsec_003.c | 121 + test/regression/tahi_test/tahi_ipsec_004.c | 119 + test/regression/tahi_test/tahi_ipsec_005.c | 1411 +++ test/regression/tahi_test/tahi_ipsec_006.c | 181 + test/regression/tahi_test/tahi_ipsec_007.c | 135 + test/regression/tahi_test/tahi_ipsec_008.c | 110 + test/regression/tahi_test/tahi_ipsec_008_02.c | 46 + test/regression/tahi_test/tahi_ipsec_009.c | 82 + test/regression/tahi_test/tahi_ipsec_009_02.c | 32 + test/regression/tahi_test/tahi_ipsec_010.c | 148 + test/regression/tahi_test/tahi_ipsec_012.c | 102 + test/regression/tahi_test/tahi_ipsec_013.c | 102 + test/regression/tahi_test/tahi_ipsec_014.c | 82 + test/regression/tahi_test/tahi_ipsec_015.c | 82 + test/regression/tahi_test/tahi_ipsec_016.c | 78 + test/regression/tahi_test/tahi_ipsec_017.c | 85 + test/regression/tahi_test/tahi_ipsec_018.c | 82 + test/regression/tahi_test/tahi_ipsec_019.c | 79 + test/regression/tahi_test/tahi_ipsec_022.c | 92 + test/regression/tahi_test/tahi_ipsec_023.c | 92 + test/regression/tahi_test/tahi_ipsec_024.c | 139 + test/regression/tahi_test/tahi_ipsec_025.c | 169 + test/regression/tahi_test/tahi_ipsec_026.c | 93 + .../regression/tahi_test/tahi_ipsec_udp_001.c | 165 + .../regression/tahi_test/tahi_ipsec_udp_002.c | 147 + .../regression/tahi_test/tahi_ipsec_udp_004.c | 119 + .../regression/tahi_test/tahi_ipsec_udp_005.c | 1279 +++ .../regression/tahi_test/tahi_ipsec_udp_006.c | 180 + .../regression/tahi_test/tahi_ipsec_udp_007.c | 135 + .../regression/tahi_test/tahi_ipsec_udp_008.c | 139 + .../regression/tahi_test/tahi_ipsec_udp_009.c | 82 + .../tahi_test/tahi_ipsec_udp_009_02.c | 32 + .../regression/tahi_test/tahi_ipsec_udp_010.c | 148 + .../regression/tahi_test/tahi_ipsec_udp_011.c | 83 + .../regression/tahi_test/tahi_ipsec_udp_012.c | 101 + .../regression/tahi_test/tahi_ipsec_udp_013.c | 236 + .../regression/tahi_test/tahi_ipsec_udp_014.c | 82 + .../regression/tahi_test/tahi_ipsec_udp_015.c | 82 + .../regression/tahi_test/tahi_ipsec_udp_016.c | 78 + .../regression/tahi_test/tahi_ipsec_udp_017.c | 85 + .../regression/tahi_test/tahi_ipsec_udp_018.c | 82 + .../regression/tahi_test/tahi_ipsec_udp_019.c | 79 + .../regression/tahi_test/tahi_ipsec_udp_022.c | 92 + .../regression/tahi_test/tahi_ipsec_udp_023.c | 92 + .../regression/tahi_test/tahi_ipsec_udp_024.c | 139 + .../regression/tahi_test/tahi_ipsec_udp_025.c | 168 + .../regression/tahi_test/tahi_ipsec_udp_026.c | 92 + .../netx_telnet_activity_timeout_test.c | 567 + .../telnet_test/netx_telnet_basic_test.c | 474 + .../netx_telnet_create_packet_pool_test.c | 387 + .../netx_telnet_max_connections_test.c | 662 ++ .../telnet_test/netx_telnet_rst_test.c | 317 + ...netx_telnet_server_bad_option_reply_test.c | 472 + ...etx_telnet_server_options_negotiate_test.c | 480 + .../telnet_test/netx_telnet_two_listen_test.c | 299 + test/regression/test/netxtestcontrol.c | 3418 ++++++ test/regression/test/netxtestcontrol.h | 8 + .../test/nx_ram_network_driver_test_1500.c | 2879 +++++ .../test/nx_ram_network_driver_test_1500.h | 50 + .../tftp_test/netx_tftp_basic_test.c | 432 + .../netx_tftp_error_destionation_port_test.c | 421 + .../netx_tftp_error_file_name_test.c | 408 + .../tftp_test/netx_tftp_ipv6_basic_test.c | 374 + .../tftp_test/netx_tftp_large_data_test.c | 500 + .../netx_tftp_malformed_packet_test.c | 465 + .../netx_tftp_read_interaction_test.c | 563 + .../netx_tftp_write_interaction_test.c | 501 + test/regression/web_test/ecc_certs.c | 1201 +++ .../web_test/http_digest_authentication.c | 179 + .../regression/web_test/netx_https_api_test.c | 2149 ++++ .../web_test/netx_https_testcontrol.c | 551 + .../web_test/netx_web_abnormal_test.c | 541 + .../netx_web_basic_authenticate_empty_test.c | 502 + .../netx_web_basic_authenticate_test.c | 504 + .../web_test/netx_web_basic_ecc_test.c | 392 + .../regression/web_test/netx_web_basic_test.c | 650 ++ .../netx_web_certifiacte_verify_test.c | 387 + ...netx_web_chunked_request_additional_test.c | 738 ++ .../web_test/netx_web_chunked_request_test.c | 709 ++ ...x_web_chunked_response_packet_chain_test.c | 533 + .../netx_web_chunked_response_process_test.c | 643 ++ .../web_test/netx_web_chunked_response_test.c | 588 ++ .../web_test/netx_web_client_cleanup_test.c | 525 + .../netx_web_client_receive_no_packet_test.c | 435 + .../web_test/netx_web_client_rst_test.c | 323 + .../web_test/netx_web_client_send_fail_test.c | 442 + .../netx_web_concurrent_sessions_test.c | 643 ++ .../netx_web_connect_three_times_test.c | 456 + .../web_test/netx_web_delete_basic_test.c | 525 + .../netx_web_digest_authenticate_test.c | 733 ++ .../netx_web_digest_authenticate_test2.c | 499 + ...etx_web_digest_authenticate_timeout_test.c | 573 + .../web_test/netx_web_external_client_test.c | 350 + .../netx_web_external_server_chunked_test.c | 197 + .../web_test/netx_web_external_server_test.c | 262 + .../netx_web_get_content_length_test.c | 622 ++ .../netx_web_get_put_referred_URI_test.c | 527 + .../web_test/netx_web_head_basic_test.c | 459 + .../web_test/netx_web_host_field_test.c | 510 + .../web_test/netx_web_http_demo_test.c | 221 + .../web_test/netx_web_https_demo_test.c | 441 + .../netx_web_if_modified_since_test.c | 558 + .../web_test/netx_web_invalid_release_test.c | 504 + .../netx_web_keep_alive_abnormal_test.c | 495 + .../web_test/netx_web_keep_alive_test.c | 526 + .../netx_web_multipart_fragment_test.c | 820 ++ .../netx_web_multipart_underflow_test.c | 832 ++ .../netx_web_multiple_sessions_test.c | 549 + .../netx_web_multiple_sessions_timeout_test.c | 485 + .../web_test/netx_web_non_block_basic_test.c | 516 + .../netx_web_non_block_reconnect_test.c | 537 + .../web_test/netx_web_one_session_test.c | 360 + .../web_test/netx_web_packet_allocate_test.c | 580 + .../web_test/netx_web_post_basic_test.c | 484 + .../netx_web_post_long_message_test.c | 401 + .../web_test/netx_web_put_basic_test.c | 513 + ...etx_web_request_in_multiple_packets_test.c | 527 + ...tx_web_response_in_multiple_packets_test.c | 565 + .../netx_web_secure_connect_fail_test.c | 381 + .../web_test/netx_web_secure_reconnect_test.c | 374 + ..._web_server_chunked_content_process_test.c | 657 ++ .../netx_web_server_content_process_test.c | 659 ++ .../netx_web_server_type_get_extended_test.c | 208 + .../web_test/netx_web_status_400_test.c | 499 + .../web_test/netx_web_status_404_test.c | 498 + .../web_test/netx_web_status_501_test.c | 494 + .../web_test/netx_web_status_code_test.c | 397 + .../web_test/netx_web_tcpserver_rst_test.c | 243 + .../netx_web_tcpserver_tls_fail_rst_test.c | 283 + .../netx_web_tcpserver_two_listen_test.c | 275 + test/regression/web_test/test_ca_cert.c | 84 + test/regression/web_test/test_device_cert.c | 190 + test/regression/web_test/test_utility.h | 53 + ...etx_websocket_16_bit_payload_length_test.c | 626 ++ .../netx_websocket_common_process.c | 155 + .../netx_websocket_connect_test.c | 570 + .../netx_websocket_delete_test.c | 395 + .../netx_websocket_disconnect_test.c | 430 + .../websocket_test/netx_websocket_fin_test.c | 466 + .../websocket_test/netx_websocket_mask_test.c | 461 + .../netx_websocket_multi_instance_test.c | 621 ++ .../netx_websocket_non_block_test.c | 622 ++ ...netx_websocket_one_frame_in_packets_test.c | 447 + ...socket_one_packet_with_multi_frames_test.c | 893 ++ .../netx_websocket_opcode_test.c | 460 + .../netx_websocket_send_chain_packets_test.c | 442 + utility/iperf/nx_iperf.c | 1977 ++++ utility/iperf/nx_iperf.h | 1981 +--- 1999 files changed, 742489 insertions(+), 1998 deletions(-) create mode 100644 .devcontainer/devcontainer.json create mode 100644 .github/workflows/regression_test.yml create mode 100755 scripts/build_nxd.sh create mode 100755 scripts/install.sh create mode 100755 scripts/test_nxd.sh create mode 100644 test/cmake/.gitignore create mode 100644 test/cmake/libs/CMakeLists.txt create mode 100644 test/cmake/libs/tx_user.h create mode 100644 test/cmake/netxduo/CMakeLists.txt create mode 100644 test/cmake/netxduo/additionals.cmake create mode 100755 test/cmake/netxduo/coverage.sh create mode 120000 test/cmake/netxduo/libs create mode 100644 test/cmake/netxduo/regression/CMakeLists.txt create mode 100755 test/cmake/netxduo/run.sh create mode 100644 test/cmake/netxduo/samples/CMakeLists.txt create mode 100644 test/regression/auto_ip_test/netx_auto_ip_address_check_test.c create mode 100644 test/regression/auto_ip_test/netx_auto_ip_announce_num_test.c create mode 100644 test/regression/auto_ip_test/netx_auto_ip_arp_dest_addr_test.c create mode 100644 test/regression/auto_ip_test/netx_auto_ip_basic_test.c create mode 100644 test/regression/auto_ip_test/netx_auto_ip_conflicts_check_test.c create mode 100644 test/regression/auto_ip_test/netx_auto_ip_max_conflicts_test.c create mode 100644 test/regression/bsd_test/bsd_test_setup.docx create mode 100644 test/regression/bsd_test/netx_bsd_aton_test.c create mode 100644 test/regression/bsd_test/netx_bsd_getaddrinfo_test.c create mode 100644 test/regression/bsd_test/netx_bsd_inet_addr_pton_test.c create mode 100644 test/regression/bsd_test/netx_bsd_ioctl_nonblocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_multicast_test.c create mode 100644 test/regression/bsd_test/netx_bsd_ntoa_test.c create mode 100644 test/regression/bsd_test/netx_bsd_ntop_test.c create mode 100644 test/regression/bsd_test/netx_bsd_pton_test.c create mode 100644 test/regression/bsd_test/netx_bsd_raw_basic_blocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_raw_basic_nonblocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_raw_basic_rx_nohdr_blocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_raw_basic_rx_nohdr_nonblocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_raw_bind_connect_test.c create mode 100644 test/regression/bsd_test/netx_bsd_raw_ping_test.c create mode 100644 test/regression/bsd_test/netx_bsd_raw_pppoe_test.c create mode 100644 test/regression/bsd_test/netx_bsd_raw_rx_nohdr_basic_blocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_raw_tx_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_2nd_bind_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_accept_blocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_accept_blocking_timeout_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_accept_nonblocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_accept_nonblocking_timeout_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_accept_noselect_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_basic_blocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_basic_nonblocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_bind_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_blocking_bidirection_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_clients_share_port_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_clients_shared_port_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_disconnect_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_fionread_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_getsockname_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_getsockname_without_bind_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_multiple_accept_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_rcvbuf_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_sendto_recvfrom_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_servers_share_port_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_servers_shared_port_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_two_blocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_tcp_udp_select_test.c create mode 100644 test/regression/bsd_test/netx_bsd_udp_basic_blocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_udp_basic_nonblocking_test.c create mode 100644 test/regression/bsd_test/netx_bsd_udp_bind_connect_test.c create mode 100644 test/regression/bsd_test/netx_bsd_udp_bind_test.c create mode 100644 test/regression/bsd_test/netx_bsd_udp_blocking_bidirection_test.c create mode 100644 test/regression/bsd_test/netx_bsd_udp_checksum_corrupt_test.c create mode 100644 test/regression/bsd_test/netx_bsd_udp_connect_test.c create mode 100644 test/regression/cloud_test/netx_cloud_api_test.c create mode 100644 test/regression/cloud_test/netx_cloud_basic_test.c create mode 100644 test/regression/cloud_test/netx_cloud_module_event_test.c create mode 100644 test/regression/cloud_test/netx_cloud_module_register_deregister_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_03_01_01_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_03_01_02_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_03_01_03_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_03_02_01_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_03_02_02_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_03_02_03_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_03_04_01_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_03_05_01_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_04_01_01_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_04_03_02_01_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_04_03_02_02_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_04_03_02_03_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_04_03_05_01_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_04_04_01_01_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_04_04_01_02_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_basic_restore_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_basic_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_activate_interfaces_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_arp_probe_fail_multiple_interface_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_arpprobe_fail_multiple_interface.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_arpprobe_fails.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_arpprobe_multiple_interface.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_arpprobe_multiple_interface_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_arpprobe_succeeds.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_decline_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_interface_0_only_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_interface_1_only_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_interface_order_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_ip_mutex_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_ntp_option_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_nxe_api_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_parameter_request_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_secondary_interface_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_send_with_zero_source_address_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_server_source_port_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_special_attributes_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_client_two_interfaces.c create mode 100644 test/regression/dhcp_test/netx_dhcp_clone_function.c create mode 100644 test/regression/dhcp_test/netx_dhcp_clone_function.h create mode 100644 test/regression/dhcp_test/netx_dhcp_coverage_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_delete_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_enable_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_extract_information_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_get_option_value_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_multiple_instances_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_packet_process_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_reinitialize_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_release_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_send_request_internal_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_server_improper_term_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_server_options_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_server_second_interface_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_server_small_packet_payload_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_server_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_skip_discover_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_start_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_stop_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_unicast_test.c create mode 100644 test/regression/dhcp_test/netx_dhcp_user_option_add_test.c create mode 100644 test/regression/dhcp_test/netx_dhcpv6_basic_test.c create mode 100644 test/regression/dhcp_test/netx_dhcpv6_client_process_server_duid_test.c create mode 100644 test/regression/dhcp_test/netx_dhcpv6_extended_api_test.c create mode 100644 test/regression/dhcp_test/netx_dhcpv6_packet_loss_test.c create mode 100644 test/regression/dhcp_test/netx_dhcpv6_server_ia_options_test.c create mode 100644 test/regression/dhcp_test/netx_dhcpv6_server_iana_test.c create mode 100644 test/regression/dhcp_test/netx_dhcpv6_server_process_repeated_msgs_test.c create mode 100644 test/regression/dhcp_test/netx_dhcpv6_user_option_add_test.c create mode 100644 test/regression/dns_test/netx_dns_abnormal_packet_test.c create mode 100644 test/regression/dns_test/netx_dns_coverage_test.c create mode 100644 test/regression/dns_test/netx_dns_fake_response_test.c create mode 100644 test/regression/dns_test/netx_dns_function_test.c create mode 100644 test/regression/dns_test/netx_dns_invalid_name_unencode_test.c create mode 100644 test/regression/dns_test/netx_dns_invalid_resource_get_test.c create mode 100644 test/regression/dns_test/netx_dns_non_blocking_a_test.c create mode 100644 test/regression/dns_test/netx_dns_nxe_api_test.c create mode 100644 test/regression/dns_test/netx_dns_packet_double_release_test.c create mode 100644 test/regression/dns_test/netx_dns_request_a_response_cname_a_smtp_live_com_test.c create mode 100644 test/regression/dns_test/netx_dns_source_port_test.c create mode 100644 test/regression/dns_test/response_a_berkley_edu.c create mode 100644 test/regression/dns_test/response_a_cname_www_npr_org.c create mode 100644 test/regression/dns_test/response_a_google_com.c create mode 100644 test/regression/dns_test/response_aaaa_berkley_edu.c create mode 100644 test/regression/dns_test/response_cname_mail_baidu_com.c create mode 100644 test/regression/dns_test/response_mx_a_berkley_edu.c create mode 100644 test/regression/dns_test/response_mx_a_google_com.c create mode 100644 test/regression/dns_test/response_mx_google_com.c create mode 100644 test/regression/dns_test/response_ns_a_ti_com.c create mode 100644 test/regression/dns_test/response_soa_google_com.c create mode 100644 test/regression/dns_test/response_srv_google_com.c create mode 100644 test/regression/dns_test/response_txt_google_com.c create mode 100644 test/regression/dns_test/response_with_invalid_resource.c create mode 100644 test/regression/ftp_test/netx_ftp_access_control_commands_01_test.c create mode 100644 test/regression/ftp_test/netx_ftp_access_control_commands_02_test.c create mode 100644 test/regression/ftp_test/netx_ftp_access_control_commands_03_test.c create mode 100644 test/regression/ftp_test/netx_ftp_access_control_commands_04_test.c create mode 100644 test/regression/ftp_test/netx_ftp_basic_test.c create mode 100644 test/regression/ftp_test/netx_ftp_client_buffer_overflow_test.c create mode 100644 test/regression/ftp_test/netx_ftp_client_file_write_fail_test.c create mode 100644 test/regression/ftp_test/netx_ftp_client_invalid_username_password_length_test.c create mode 100644 test/regression/ftp_test/netx_ftp_client_multiple_connection_responses_test.c create mode 100644 test/regression/ftp_test/netx_ftp_client_packet_leak_test.c create mode 100644 test/regression/ftp_test/netx_ftp_client_pasv_denied.c create mode 100644 test/regression/ftp_test/netx_ftp_client_pasv_file_read_test.c create mode 100644 test/regression/ftp_test/netx_ftp_client_pasv_file_write_test.c create mode 100644 test/regression/ftp_test/netx_ftp_commands_characters_test.c create mode 100644 test/regression/ftp_test/netx_ftp_commands_replys_test.c create mode 100644 test/regression/ftp_test/netx_ftp_control_connection_test.c create mode 100644 test/regression/ftp_test/netx_ftp_data_connection_test.c create mode 100644 test/regression/ftp_test/netx_ftp_disconnection_event_test.c create mode 100644 test/regression/ftp_test/netx_ftp_establish_data_connection_03_test.c create mode 100644 test/regression/ftp_test/netx_ftp_establish_data_connection_05_test.c create mode 100644 test/regression/ftp_test/netx_ftp_establish_data_connection_06_test.c create mode 100644 test/regression/ftp_test/netx_ftp_establish_data_connection_08_test.c create mode 100644 test/regression/ftp_test/netx_ftp_ipv6_epsv_test.c create mode 100644 test/regression/ftp_test/netx_ftp_parse_ipv6_address_test.c create mode 100644 test/regression/ftp_test/netx_ftp_pasv_port_test.c create mode 100644 test/regression/ftp_test/netx_ftp_pasv_stor_test.c create mode 100644 test/regression/ftp_test/netx_ftp_pasv_twice_test.c create mode 100644 test/regression/ftp_test/netx_ftp_rst_test.c create mode 100644 test/regression/ftp_test/netx_ftp_server_abnormal_packet_test.c create mode 100644 test/regression/ftp_test/netx_ftp_server_dangling_pointer_test.c create mode 100644 test/regression/ftp_test/netx_ftp_server_invalid_month_crash_test.c create mode 100644 test/regression/ftp_test/netx_ftp_server_list_command_test.c create mode 100644 test/regression/ftp_test/netx_ftp_server_mss_too_small_test.c create mode 100644 test/regression/ftp_test/netx_ftp_service_commands_RETR_STOR_test.c create mode 100644 test/regression/ftp_test/netx_ftp_service_commands_dele_test.c create mode 100644 test/regression/ftp_test/netx_ftp_service_commands_file_write_test.c create mode 100644 test/regression/ftp_test/netx_ftp_service_commands_m_d_dir_test.c create mode 100644 test/regression/ftp_test/netx_ftp_service_commands_nlist_test.c create mode 100644 test/regression/ftp_test/netx_ftp_service_commands_rename_test.c create mode 100644 test/regression/ftp_test/netx_ftp_two_listen_test.c create mode 100644 test/regression/ftp_test/netx_ftp_user_data_type_test.c create mode 100644 test/regression/http_test/netx_http_basic_authenticate_test.c create mode 100644 test/regression/http_test/netx_http_basic_test.c create mode 100644 test/regression/http_test/netx_http_client_change_connect_port_test.c create mode 100644 test/regression/http_test/netx_http_delete_basic_test.c create mode 100644 test/regression/http_test/netx_http_digest_authenticate_test.c create mode 100644 test/regression/http_test/netx_http_digest_authenticate_timeout_test.c create mode 100644 test/regression/http_test/netx_http_get_content_length_test.c create mode 100644 test/regression/http_test/netx_http_get_contentlength_packetleak_test.c create mode 100644 test/regression/http_test/netx_http_get_put_referred_URI_test.c create mode 100644 test/regression/http_test/netx_http_head_basic_test.c create mode 100644 test/regression/http_test/netx_http_if_modified_since_test.c create mode 100644 test/regression/http_test/netx_http_multipart_fragment_test.c create mode 100644 test/regression/http_test/netx_http_multipart_underflow_test.c create mode 100644 test/regression/http_test/netx_http_post_basic_test.c create mode 100644 test/regression/http_test/netx_http_request_in_multiple_packets_test.c create mode 100644 test/regression/http_test/netx_http_server_type_retrieve_test.c create mode 100644 test/regression/http_test/netx_http_status_400_test.c create mode 100644 test/regression/http_test/netx_http_status_404_test.c create mode 100644 test/regression/http_test/netx_http_status_501_test.c create mode 100644 test/regression/mdns_test/capture/_http._tcp.c create mode 100644 test/regression/mdns_test/capture/_http._tcp.pcapng create mode 100644 test/regression/mdns_test/capture/_pdl-datastream._tcp.c create mode 100644 test/regression/mdns_test/capture/_pdl-datastream._tcp.pcapng create mode 100644 test/regression/mdns_test/capture/_printer._tcp.c create mode 100644 test/regression/mdns_test/capture/_printer._tcp.pcapng create mode 100644 test/regression/mdns_test/capture/_smb._tcp.c create mode 100644 test/regression/mdns_test/capture/_smb._tcp.pcapng create mode 100644 test/regression/mdns_test/capture/address_change.c create mode 100644 test/regression/mdns_test/capture/address_change.pcapng create mode 100644 test/regression/mdns_test/capture/announcement_in_multiple_packets.c create mode 100644 test/regression/mdns_test/capture/announcement_in_multiple_packets.pcapng create mode 100644 test/regression/mdns_test/capture/case_insensitivity.c create mode 100644 test/regression/mdns_test/capture/case_insensitivity.pcapng create mode 100644 test/regression/mdns_test/capture/client_passive.c create mode 100644 test/regression/mdns_test/capture/client_passive.pcapng create mode 100644 test/regression/mdns_test/capture/command.txt create mode 100644 test/regression/mdns_test/capture/continuous_query.c create mode 100644 test/regression/mdns_test/capture/continuous_query.pcapng create mode 100644 test/regression/mdns_test/capture/continuous_query_a.c create mode 100644 test/regression/mdns_test/capture/continuous_query_a.pcapng create mode 100644 test/regression/mdns_test/capture/continuous_query_unique_answer.c create mode 100644 test/regression/mdns_test/capture/continuous_query_unique_answer.pcapng create mode 100644 test/regression/mdns_test/capture/dns_sd_query.c create mode 100644 test/regression/mdns_test/capture/dns_sd_query.pcapng create mode 100644 test/regression/mdns_test/capture/duplicate_question_suppression.c create mode 100644 test/regression/mdns_test/capture/error_response.pcapng create mode 100644 test/regression/mdns_test/capture/ipv6_query.c create mode 100644 test/regression/mdns_test/capture/ipv6_query.pcapng create mode 100644 test/regression/mdns_test/capture/known_answer_suppression.c create mode 100644 test/regression/mdns_test/capture/known_answer_suppression.pcapng create mode 100644 test/regression/mdns_test/capture/known_answer_suppression_query_half_ttl.c create mode 100644 test/regression/mdns_test/capture/known_answer_suppression_query_half_ttl.pcapng create mode 100644 test/regression/mdns_test/capture/known_answer_suppression_response.c create mode 100644 test/regression/mdns_test/capture/known_answer_suppression_response.pcapng create mode 100644 test/regression/mdns_test/capture/mdns_known_answer_suppression_unique.c create mode 100644 test/regression/mdns_test/capture/mdns_known_answer_suppression_unique.pcapng create mode 100644 test/regression/mdns_test/capture/multiple_questions_per_query.c create mode 100644 test/regression/mdns_test/capture/multiple_questions_per_query.pcapng create mode 100644 test/regression/mdns_test/capture/one_shot_query.c create mode 100644 test/regression/mdns_test/capture/one_shot_query.pcapng create mode 100644 test/regression/mdns_test/capture/probing_conflict.c create mode 100644 test/regression/mdns_test/capture/probing_conflict.pcapng create mode 100644 test/regression/mdns_test/capture/probing_conflict_any_type.c create mode 100644 test/regression/mdns_test/capture/probing_conflict_any_type.pcapng create mode 100644 test/regression/mdns_test/capture/query_and_response_chaos.c create mode 100644 test/regression/mdns_test/capture/query_and_response_chaos.pcapng create mode 100644 test/regression/mdns_test/capture/query_and_response_v6.c create mode 100644 test/regression/mdns_test/capture/query_and_response_v6.pcapng create mode 100644 test/regression/mdns_test/capture/query_during_probing_1.c create mode 100644 test/regression/mdns_test/capture/query_during_probing_1.pcapng create mode 100644 test/regression/mdns_test/capture/query_during_probing_2.c create mode 100644 test/regression/mdns_test/capture/query_during_probing_2.pcapng create mode 100644 test/regression/mdns_test/capture/query_rr_a.c create mode 100644 test/regression/mdns_test/capture/query_rr_a.pcapng create mode 100644 test/regression/mdns_test/capture/query_rr_timeout.c create mode 100644 test/regression/mdns_test/capture/query_rr_timeout.pcapng create mode 100644 test/regression/mdns_test/capture/query_start_stop.c create mode 100644 test/regression/mdns_test/capture/query_start_stop.pcapng create mode 100644 test/regression/mdns_test/capture/query_with_tc.c create mode 100644 test/regression/mdns_test/capture/query_with_tc.pcapng create mode 100644 test/regression/mdns_test/capture/responder_cooperating.c create mode 100644 test/regression/mdns_test/capture/responder_cooperating.pcapng create mode 100644 test/regression/mdns_test/capture/responder_cooperating_2.c create mode 100644 test/regression/mdns_test/capture/responder_cooperating_2.pcapng create mode 100644 test/regression/mdns_test/capture/response_a.c create mode 100644 test/regression/mdns_test/capture/response_a.pcapng create mode 100644 test/regression/mdns_test/capture/response_aggregation.c create mode 100644 test/regression/mdns_test/capture/response_aggregation.pcapng create mode 100644 test/regression/mdns_test/capture/response_in_multiple_packets.c create mode 100644 test/regression/mdns_test/capture/response_in_multiple_packets.pcapng create mode 100644 test/regression/mdns_test/capture/response_interval.c create mode 100644 test/regression/mdns_test/capture/response_interval.pcapng create mode 100644 test/regression/mdns_test/capture/response_interval_2.c create mode 100644 test/regression/mdns_test/capture/response_interval_2.pcapng create mode 100644 test/regression/mdns_test/capture/response_no_delay.c create mode 100644 test/regression/mdns_test/capture/response_no_delay.pcapng create mode 100644 test/regression/mdns_test/capture/response_to_address_query.c create mode 100644 test/regression/mdns_test/capture/response_to_address_query.pcapng create mode 100644 test/regression/mdns_test/capture/response_with_tc.c create mode 100644 test/regression/mdns_test/capture/response_with_tc.pcapng create mode 100644 test/regression/mdns_test/capture/rr_timeout.c create mode 100644 test/regression/mdns_test/capture/rr_timeout.pcapng create mode 100644 test/regression/mdns_test/capture/send_goodbye.c create mode 100644 test/regression/mdns_test/capture/send_goodbye.pcapng create mode 100644 test/regression/mdns_test/capture/server_announcement.c create mode 100644 test/regression/mdns_test/capture/server_announcement.pcapng create mode 100644 test/regression/mdns_test/capture/server_announcement_v6.c create mode 100644 test/regression/mdns_test/capture/server_announcement_v6.pcapng create mode 100644 test/regression/mdns_test/capture/server_announcement_with_txt.c create mode 100644 test/regression/mdns_test/capture/server_announcement_with_txt.pcapng create mode 100644 test/regression/mdns_test/capture/server_interface_reset.c create mode 100644 test/regression/mdns_test/capture/server_interface_reset.pcapng create mode 100644 test/regression/mdns_test/mdns_address_change_test.c create mode 100644 test/regression/mdns_test/mdns_announcement_in_multiple_packets_test.c create mode 100644 test/regression/mdns_test/mdns_basic_ipv6_announcement_test.c create mode 100644 test/regression/mdns_test/mdns_basic_ipv6_query_test.c create mode 100644 test/regression/mdns_test/mdns_basic_ipv6_response_test.c create mode 100644 test/regression/mdns_test/mdns_case_insensitivity_test.c create mode 100644 test/regression/mdns_test/mdns_client_passive_test.c create mode 100644 test/regression/mdns_test/mdns_continuous_query_interval_test.c create mode 100644 test/regression/mdns_test/mdns_continuous_query_test.c create mode 100644 test/regression/mdns_test/mdns_continuous_query_unique_answer_test.c create mode 100644 test/regression/mdns_test/mdns_dns_sd_query_test.c create mode 100644 test/regression/mdns_test/mdns_dns_sd_response_test.c create mode 100644 test/regression/mdns_test/mdns_duplicate_answer_suppression_test.c create mode 100644 test/regression/mdns_test/mdns_duplicate_question_suppression_test.c create mode 100644 test/regression/mdns_test/mdns_known_answer_ignored_test.c create mode 100644 test/regression/mdns_test/mdns_known_answer_suppression_query_half_ttl_test.c create mode 100644 test/regression/mdns_test/mdns_known_answer_suppression_query_test.c create mode 100644 test/regression/mdns_test/mdns_known_answer_suppression_response_test.c create mode 100644 test/regression/mdns_test/mdns_known_answer_suppression_unique_test.c create mode 100644 test/regression/mdns_test/mdns_multiple_questions_per_query_test.c create mode 100644 test/regression/mdns_test/mdns_poof_test.c create mode 100644 test/regression/mdns_test/mdns_probing_conflict_test.c create mode 100644 test/regression/mdns_test/mdns_query_and_response_chaos_test.c create mode 100644 test/regression/mdns_test/mdns_query_during_probing_test.c create mode 100644 test/regression/mdns_test/mdns_query_http_tcp_test.c create mode 100644 test/regression/mdns_test/mdns_query_pdl_datastram_tcp_test.c create mode 100644 test/regression/mdns_test/mdns_query_printer_tcp_test.c create mode 100644 test/regression/mdns_test/mdns_query_rr_timeout_test.c create mode 100644 test/regression/mdns_test/mdns_query_smb_tcp_test.c create mode 100644 test/regression/mdns_test/mdns_query_start_stop_test.c create mode 100644 test/regression/mdns_test/mdns_query_with_tc_test.c create mode 100644 test/regression/mdns_test/mdns_response_aggregation_test.c create mode 100644 test/regression/mdns_test/mdns_response_in_multiple_packets_test.c create mode 100644 test/regression/mdns_test/mdns_response_interval_test.c create mode 100644 test/regression/mdns_test/mdns_response_no_delay_test.c create mode 100644 test/regression/mdns_test/mdns_response_to_address_query_test.c create mode 100644 test/regression/mdns_test/mdns_response_with_tc_test.c create mode 100644 test/regression/mdns_test/mdns_server_announcement_with_txt_test.c create mode 100644 test/regression/mdns_test/mdns_server_interface_reset.c create mode 100644 test/regression/mdns_test/mdns_server_send_goodbye_test.c create mode 100644 test/regression/mdns_test/mdns_test_setup.docx create mode 100644 test/regression/mdns_test/netx_mdns_announcement_repeat_test.c create mode 100644 test/regression/mdns_test/netx_mdns_bad_packet_test.c create mode 100644 test/regression/mdns_test/netx_mdns_buffer_size_test.c create mode 100644 test/regression/mdns_test/netx_mdns_create_delete_test.c create mode 100644 test/regression/mdns_test/netx_mdns_domain_name_test.c create mode 100644 test/regression/mdns_test/netx_mdns_interface_test.c create mode 100644 test/regression/mdns_test/netx_mdns_internal_function_test.c create mode 100644 test/regression/mdns_test/netx_mdns_ipv6_string_test.c create mode 100644 test/regression/mdns_test/netx_mdns_local_cache_continuous_query_test.c create mode 100644 test/regression/mdns_test/netx_mdns_local_cache_one_shot_query_test.c create mode 100644 test/regression/mdns_test/netx_mdns_multiple_answers_test.c create mode 100644 test/regression/mdns_test/netx_mdns_name_test.c create mode 100644 test/regression/mdns_test/netx_mdns_one_shot_query_test.c create mode 100644 test/regression/mdns_test/netx_mdns_peer_service_change_notify_test.c create mode 100644 test/regression/mdns_test/netx_mdns_ram_test.c create mode 100644 test/regression/mdns_test/netx_mdns_read_overflow_test.c create mode 100644 test/regression/mdns_test/netx_mdns_responder_cooperating_test.c create mode 100644 test/regression/mdns_test/netx_mdns_response_with_question_test.c create mode 100644 test/regression/mdns_test/netx_mdns_run_test_case.c create mode 100644 test/regression/mdns_test/netx_mdns_second_interface_test.c create mode 100644 test/regression/mdns_test/netx_mdns_service_add_delete_test.c create mode 100644 test/regression/mdns_test/netx_mdns_service_lookup_test.c create mode 100644 test/regression/mdns_test/netx_mdns_source_address_test.c create mode 100644 test/regression/mdns_test/netx_mdns_source_port_test.c create mode 100644 test/regression/mdns_test/netx_mdns_test.h create mode 100644 test/regression/mdns_test/netx_mdns_ttl_test.c create mode 100644 test/regression/mdns_test/netx_mdns_two_buffer_test.c create mode 100644 test/regression/mdns_test/netx_mdns_txt_notation_test.c create mode 100644 test/regression/mdns_test/netx_mdns_txt_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_api_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_branch_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_connack_error_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_connect_auth_empty_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_connect_auth_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_connect_non_block_2_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_connect_non_block_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_connect_packet_send_failure_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_connect_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_connect_v6_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_connect_will_message_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_connect_will_topic_only_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_connect_with_auth_will_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_keepalive_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_keepalive_timeout_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_multiple_receive_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_not_connected_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_null_password_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_packet_leak_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_publish_non_zero_packet_id_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_publish_packet_chain_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_publish_qos0_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_publish_qos1_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_publish_qos2_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_receive_qos0_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_receive_qos1_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_receive_qos2_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_receive_span_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_remaining_length_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_subscribe_non_zero_packet_id_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_subscribe_packet_chain_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_subscribe_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_testcontrol.c create mode 100644 test/regression/mqtt_test/netx_mqtt_transmit_queue_depth_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_unsubscribe_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_websocket_block_test.c create mode 100644 test/regression/mqtt_test/netx_mqtt_websocket_non_block_test.c create mode 100644 test/regression/nat_test/netx_nat_entry_removed_after_timeout_test.c create mode 100644 test/regression/nat_test/netx_nat_icmp_test.c create mode 100644 test/regression/nat_test/netx_nat_invalid_header_test.c create mode 100644 test/regression/nat_test/netx_nat_tcp_fragment_test.c create mode 100644 test/regression/nat_test/netx_nat_tcp_port_test.c create mode 100644 test/regression/nat_test/netx_nat_tcp_port_test2.c create mode 100644 test/regression/nat_test/netx_nat_tcp_remove_oldest_udp_entry_test.c create mode 100644 test/regression/nat_test/netx_nat_tcp_test1.c create mode 100644 test/regression/nat_test/netx_nat_tcp_test2.c create mode 100644 test/regression/nat_test/netx_nat_udp_fragment_test.c create mode 100644 test/regression/nat_test/netx_nat_udp_port_test.c create mode 100644 test/regression/nat_test/netx_nat_udp_test.c create mode 100644 test/regression/netxduo_test/netx_101_17_test.c create mode 100644 test/regression/netxduo_test/netx_101_18_test.c create mode 100644 test/regression/netxduo_test/netx_102_18_test.c create mode 100644 test/regression/netxduo_test/netx_102_19_test.c create mode 100644 test/regression/netxduo_test/netx_102_20_test.c create mode 100644 test/regression/netxduo_test/netx_102_21_test.c create mode 100644 test/regression/netxduo_test/netx_102_22_test.c create mode 100644 test/regression/netxduo_test/netx_102_23_test.c create mode 100644 test/regression/netxduo_test/netx_102_24_test.c create mode 100644 test/regression/netxduo_test/netx_102_25_test.c create mode 100644 test/regression/netxduo_test/netx_103_17_test.c create mode 100644 test/regression/netxduo_test/netx_104_17_test.c create mode 100644 test/regression/netxduo_test/netx_106_17_test.c create mode 100644 test/regression/netxduo_test/netx_10_23_01_test.c create mode 100644 test/regression/netxduo_test/netx_10_23_02_test.c create mode 100644 test/regression/netxduo_test/netx_10_24_01_test.c create mode 100644 test/regression/netxduo_test/netx_10_24_02_test.c create mode 100644 test/regression/netxduo_test/netx_10_24_03_test.c create mode 100644 test/regression/netxduo_test/netx_10_25_test.c create mode 100644 test/regression/netxduo_test/netx_10_26_test.c create mode 100644 test/regression/netxduo_test/netx_11_18_test.c create mode 100644 test/regression/netxduo_test/netx_11_19_test.c create mode 100644 test/regression/netxduo_test/netx_11_23_test.c create mode 100644 test/regression/netxduo_test/netx_11_24_test.c create mode 100644 test/regression/netxduo_test/netx_11_25_test.c create mode 100644 test/regression/netxduo_test/netx_11_26_test.c create mode 100644 test/regression/netxduo_test/netx_11_27_test.c create mode 100644 test/regression/netxduo_test/netx_11_28_test.c create mode 100644 test/regression/netxduo_test/netx_11_29_test.c create mode 100644 test/regression/netxduo_test/netx_12_01_test.c create mode 100644 test/regression/netxduo_test/netx_12_02_test.c create mode 100644 test/regression/netxduo_test/netx_12_03_test.c create mode 100644 test/regression/netxduo_test/netx_12_04_test.c create mode 100644 test/regression/netxduo_test/netx_12_17_test.c create mode 100644 test/regression/netxduo_test/netx_12_18_test.c create mode 100644 test/regression/netxduo_test/netx_12_19_test.c create mode 100644 test/regression/netxduo_test/netx_12_20_test.c create mode 100644 test/regression/netxduo_test/netx_12_21_test.c create mode 100644 test/regression/netxduo_test/netx_12_23_test.c create mode 100644 test/regression/netxduo_test/netx_12_24_test.c create mode 100644 test/regression/netxduo_test/netx_12_25_test.c create mode 100644 test/regression/netxduo_test/netx_12_26_test.c create mode 100644 test/regression/netxduo_test/netx_12_27_test.c create mode 100644 test/regression/netxduo_test/netx_12_30_test.c create mode 100644 test/regression/netxduo_test/netx_12_31_test.c create mode 100644 test/regression/netxduo_test/netx_13_01_test.c create mode 100644 test/regression/netxduo_test/netx_13_02_test.c create mode 100644 test/regression/netxduo_test/netx_13_04_test.c create mode 100644 test/regression/netxduo_test/netx_13_05_test.c create mode 100644 test/regression/netxduo_test/netx_13_17_test.c create mode 100644 test/regression/netxduo_test/netx_14_19_test.c create mode 100644 test/regression/netxduo_test/netx_14_20_test.c create mode 100644 test/regression/netxduo_test/netx_15_03_test.c create mode 100644 test/regression/netxduo_test/netx_15_20_test.c create mode 100644 test/regression/netxduo_test/netx_15_21_test.c create mode 100644 test/regression/netxduo_test/netx_15_24_test.c create mode 100644 test/regression/netxduo_test/netx_15_25_test.c create mode 100644 test/regression/netxduo_test/netx_15_26_test.c create mode 100644 test/regression/netxduo_test/netx_16_02_test.c create mode 100644 test/regression/netxduo_test/netx_16_17_test.c create mode 100644 test/regression/netxduo_test/netx_16_19_test.c create mode 100644 test/regression/netxduo_test/netx_16_21_test.c create mode 100644 test/regression/netxduo_test/netx_16_22_test.c create mode 100644 test/regression/netxduo_test/netx_17_17_test.c create mode 100644 test/regression/netxduo_test/netx_18_21_test.c create mode 100644 test/regression/netxduo_test/netx_1_01_test.c create mode 100644 test/regression/netxduo_test/netx_1_02_test.c create mode 100644 test/regression/netxduo_test/netx_1_03_test.c create mode 100644 test/regression/netxduo_test/netx_1_04_ipv6_test.c create mode 100644 test/regression/netxduo_test/netx_1_04_test.c create mode 100644 test/regression/netxduo_test/netx_1_05_test.c create mode 100644 test/regression/netxduo_test/netx_1_17_test.c create mode 100644 test/regression/netxduo_test/netx_1_18_test.c create mode 100644 test/regression/netxduo_test/netx_1_19_01_test.c create mode 100644 test/regression/netxduo_test/netx_1_19_02_test.c create mode 100644 test/regression/netxduo_test/netx_1_19_03_test.c create mode 100644 test/regression/netxduo_test/netx_1_20_test.c create mode 100644 test/regression/netxduo_test/netx_1_21_01_test.c create mode 100644 test/regression/netxduo_test/netx_1_21_02_test.c create mode 100644 test/regression/netxduo_test/netx_1_26_01_test.c create mode 100644 test/regression/netxduo_test/netx_1_26_02_test.c create mode 100644 test/regression/netxduo_test/netx_1_27_01_test.c create mode 100644 test/regression/netxduo_test/netx_1_27_02_test.c create mode 100644 test/regression/netxduo_test/netx_1_27_03_test.c create mode 100644 test/regression/netxduo_test/netx_1_27_04_test.c create mode 100644 test/regression/netxduo_test/netx_23_02_01_test.c create mode 100644 test/regression/netxduo_test/netx_23_02_02_test.c create mode 100644 test/regression/netxduo_test/netx_23_02_03_test.c create mode 100644 test/regression/netxduo_test/netx_23_02_04_test.c create mode 100644 test/regression/netxduo_test/netx_2_01_test.c create mode 100644 test/regression/netxduo_test/netx_2_02_test.c create mode 100644 test/regression/netxduo_test/netx_2_17_test.c create mode 100644 test/regression/netxduo_test/netx_2_20_test.c create mode 100644 test/regression/netxduo_test/netx_3_01_test.c create mode 100644 test/regression/netxduo_test/netx_3_02_test.c create mode 100644 test/regression/netxduo_test/netx_3_03_test.c create mode 100644 test/regression/netxduo_test/netx_3_04_test.c create mode 100644 test/regression/netxduo_test/netx_3_06_test.c create mode 100644 test/regression/netxduo_test/netx_3_07_test.c create mode 100644 test/regression/netxduo_test/netx_3_08_test.c create mode 100644 test/regression/netxduo_test/netx_3_17_test.c create mode 100644 test/regression/netxduo_test/netx_3_18_test.c create mode 100644 test/regression/netxduo_test/netx_3_19_test.c create mode 100644 test/regression/netxduo_test/netx_3_20_test.c create mode 100644 test/regression/netxduo_test/netx_3_21_test.c create mode 100644 test/regression/netxduo_test/netx_3_23_test.c create mode 100644 test/regression/netxduo_test/netx_4_01_test.c create mode 100644 test/regression/netxduo_test/netx_4_17_test.c create mode 100644 test/regression/netxduo_test/netx_4_21_test.c create mode 100644 test/regression/netxduo_test/netx_4_23_test.c create mode 100644 test/regression/netxduo_test/netx_4_24_test.c create mode 100644 test/regression/netxduo_test/netx_4_25_test.c create mode 100644 test/regression/netxduo_test/netx_4_26_test.c create mode 100644 test/regression/netxduo_test/netx_4_27_test.c create mode 100644 test/regression/netxduo_test/netx_4_28_test.c create mode 100644 test/regression/netxduo_test/netx_4_29_test.c create mode 100644 test/regression/netxduo_test/netx_5_18_test.c create mode 100644 test/regression/netxduo_test/netx_5_19_test.c create mode 100644 test/regression/netxduo_test/netx_5_20_test.c create mode 100644 test/regression/netxduo_test/netx_5_21_test.c create mode 100644 test/regression/netxduo_test/netx_5_22_test.c create mode 100644 test/regression/netxduo_test/netx_5_23_test.c create mode 100644 test/regression/netxduo_test/netx_5_24_test.c create mode 100644 test/regression/netxduo_test/netx_5_25_test.c create mode 100644 test/regression/netxduo_test/netx_6_17_test.c create mode 100644 test/regression/netxduo_test/netx_6_18_test.c create mode 100644 test/regression/netxduo_test/netx_6_20_test.c create mode 100644 test/regression/netxduo_test/netx_6_22_01_test.c create mode 100644 test/regression/netxduo_test/netx_6_22_02_test.c create mode 100644 test/regression/netxduo_test/netx_6_23_test.c create mode 100644 test/regression/netxduo_test/netx_6_24_test.c create mode 100644 test/regression/netxduo_test/netx_6_25_test.c create mode 100644 test/regression/netxduo_test/netx_6_27_test.c create mode 100644 test/regression/netxduo_test/netx_6_28_test.c create mode 100644 test/regression/netxduo_test/netx_6_29_test.c create mode 100644 test/regression/netxduo_test/netx_6_32_test.c create mode 100644 test/regression/netxduo_test/netx_8_01_test.c create mode 100644 test/regression/netxduo_test/netx_8_02_test.c create mode 100644 test/regression/netxduo_test/netx_8_17_test.c create mode 100644 test/regression/netxduo_test/netx_8_18_test.c create mode 100644 test/regression/netxduo_test/netx_8_19_test.c create mode 100644 test/regression/netxduo_test/netx_8_20_test.c create mode 100644 test/regression/netxduo_test/netx_8_21_test.c create mode 100644 test/regression/netxduo_test/netx_8_29_01_test.c create mode 100644 test/regression/netxduo_test/netx_8_29_02_test.c create mode 100644 test/regression/netxduo_test/netx_8_29_03_test.c create mode 100644 test/regression/netxduo_test/netx_8_29_04_test.c create mode 100644 test/regression/netxduo_test/netx_9_17_test.c create mode 100644 test/regression/netxduo_test/netx_9_18_test.c create mode 100644 test/regression/netxduo_test/netx_9_19_01_test.c create mode 100644 test/regression/netxduo_test/netx_9_19_02_test.c create mode 100644 test/regression/netxduo_test/netx_9_20_test.c create mode 100644 test/regression/netxduo_test/netx_9_21_01_test.c create mode 100644 test/regression/netxduo_test/netx_9_21_02_test.c create mode 100644 test/regression/netxduo_test/netx_9_22_test.c create mode 100644 test/regression/netxduo_test/netx_9_27_test.c create mode 100644 test/regression/netxduo_test/netx_api_compile_test.c create mode 100644 test/regression/netxduo_test/netx_arp_auto_entry_test.c create mode 100644 test/regression/netxduo_test/netx_arp_basic_test.c create mode 100644 test/regression/netxduo_test/netx_arp_branch_test.c create mode 100644 test/regression/netxduo_test/netx_arp_conflict_test.c create mode 100644 test/regression/netxduo_test/netx_arp_dual_pool_test.c create mode 100644 test/regression/netxduo_test/netx_arp_dynamic_entry_fail_test.c create mode 100644 test/regression/netxduo_test/netx_arp_dynamic_entry_set_test.c create mode 100644 test/regression/netxduo_test/netx_arp_dynamic_entry_test.c create mode 100644 test/regression/netxduo_test/netx_arp_dynamic_entry_test2.c create mode 100644 test/regression/netxduo_test/netx_arp_dynamic_entry_test3.c create mode 100644 test/regression/netxduo_test/netx_arp_dynamic_entry_timeout_test.c create mode 100644 test/regression/netxduo_test/netx_arp_dynamic_invalidate_test.c create mode 100644 test/regression/netxduo_test/netx_arp_entry_abnormal_operation_test.c create mode 100644 test/regression/netxduo_test/netx_arp_entry_cache_test.c create mode 100644 test/regression/netxduo_test/netx_arp_gratuitous_test.c create mode 100644 test/regression/netxduo_test/netx_arp_invalid_type_test.c create mode 100644 test/regression/netxduo_test/netx_arp_no_duplicate_entry_test.c create mode 100644 test/regression/netxduo_test/netx_arp_nxe_api_test.c create mode 100644 test/regression/netxduo_test/netx_arp_packet_allocate_test.c create mode 100644 test/regression/netxduo_test/netx_arp_queue_depth_test.c create mode 100644 test/regression/netxduo_test/netx_arp_static_entries_delete_test.c create mode 100644 test/regression/netxduo_test/netx_arp_static_entry_create_test.c create mode 100644 test/regression/netxduo_test/netx_arp_static_entry_pollute_test.c create mode 100644 test/regression/netxduo_test/netx_arp_static_entry_test.c create mode 100644 test/regression/netxduo_test/netx_caller_check_test.c create mode 100644 test/regression/netxduo_test/netx_checksum_test.c create mode 100644 test/regression/netxduo_test/netx_dest_table_add_fail_test.c create mode 100644 test/regression/netxduo_test/netx_forward_icmp_small_header_test.c create mode 100644 test/regression/netxduo_test/netx_forward_icmp_small_header_test2.c create mode 100644 test/regression/netxduo_test/netx_forward_icmp_small_header_test3.c create mode 100644 test/regression/netxduo_test/netx_forward_icmp_test.c create mode 100644 test/regression/netxduo_test/netx_forward_icmp_ttl_test.c create mode 100644 test/regression/netxduo_test/netx_forward_link_local_address_test.c create mode 100644 test/regression/netxduo_test/netx_forward_multicast_test.c create mode 100644 test/regression/netxduo_test/netx_forward_tcp_test_1.c create mode 100644 test/regression/netxduo_test/netx_forward_tcp_test_2.c create mode 100644 test/regression/netxduo_test/netx_forward_tcp_test_3.c create mode 100644 test/regression/netxduo_test/netx_forward_tcp_test_4.c create mode 100644 test/regression/netxduo_test/netx_forward_tcp_test_5.c create mode 100644 test/regression/netxduo_test/netx_forward_udp_fragment_test.c create mode 100644 test/regression/netxduo_test/netx_forward_udp_fragment_test2.c create mode 100644 test/regression/netxduo_test/netx_forward_udp_fragment_test3.c create mode 100644 test/regression/netxduo_test/netx_forward_udp_fragment_test4.c create mode 100644 test/regression/netxduo_test/netx_forward_udp_test.c create mode 100644 test/regression/netxduo_test/netx_http_proxy_basic_test.c create mode 100644 test/regression/netxduo_test/netx_http_proxy_data_fin_test.c create mode 100644 test/regression/netxduo_test/netx_http_proxy_disconnect_test.c create mode 100644 test/regression/netxduo_test/netx_http_proxy_error_response_test.c create mode 100644 test/regression/netxduo_test/netx_http_proxy_multiple_response_test.c create mode 100644 test/regression/netxduo_test/netx_http_proxy_non_block_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_branch_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_broadcast_ping_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_cleanup_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_interface2_ping6_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_interface2_ping_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_invalid_echo_reply_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_invalid_source_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_loopback_fail_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_loopback_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_loopback_test2.c create mode 100644 test/regression/netxduo_test/netx_icmp_multiple_ping6_test1.c create mode 100644 test/regression/netxduo_test/netx_icmp_multiple_ping6_test2.c create mode 100644 test/regression/netxduo_test/netx_icmp_multiple_ping_test1.c create mode 100644 test/regression/netxduo_test/netx_icmp_multiple_ping_test2.c create mode 100644 test/regression/netxduo_test/netx_icmp_nxe_api_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_packet_receive_function_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_ping6_data_append_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_ping6_fragment_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_ping6_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_ping_fragment_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_ping_multicast_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_ping_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_send_error_message_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_send_error_message_test_1.c create mode 100644 test/regression/netxduo_test/netx_icmp_tunnel_ipv4_ipv4_ping_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_tunnel_ipv4_ipv6_ping_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_tunnel_ipv6_ipv4_ping_test.c create mode 100644 test/regression/netxduo_test/netx_icmp_tunnel_ipv6_ipv6_ping_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_DAD_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_abnormal_mtu_in_ra_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_branch_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_destination_table_periodic_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_echo_reply_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_echo_request_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_error_small_packet_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_error_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_invalid_length_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_invalid_length_test2.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_invalid_message_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_invalid_na.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_invalid_ra_dest_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_invalid_ra_option_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_mtu_option_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_na_buffer_overwrite_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_na_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_na_tlla_changed_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_ns_buffer_overwrite_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_ns_with_small_packet_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_ra_address_full_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_ra_buffer_overwrite_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_ra_flag_callback_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_ra_invalid_length_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_ra_lifetime_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_ra_router_full_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_ra_slla_changed_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_redirect_buffer_overwrite_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_redirect_nd_full_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_redirect_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_router_solicitation_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_solicitated_ra_test.c create mode 100644 test/regression/netxduo_test/netx_icmpv6_too_big_buffer_overwrite_test.c create mode 100644 test/regression/netxduo_test/netx_igmp_basic_test.c create mode 100644 test/regression/netxduo_test/netx_igmp_branch_test.c create mode 100644 test/regression/netxduo_test/netx_igmp_checksum_computation_test.c create mode 100644 test/regression/netxduo_test/netx_igmp_interface_indirect_report_send_test.c create mode 100644 test/regression/netxduo_test/netx_igmp_join_fail_test.c create mode 100644 test/regression/netxduo_test/netx_igmp_leave_test.c create mode 100644 test/regression/netxduo_test/netx_igmp_loopback_test.c create mode 100644 test/regression/netxduo_test/netx_igmp_multicast_basic_test.c create mode 100644 test/regression/netxduo_test/netx_igmp_nxe_api_test.c create mode 100644 test/regression/netxduo_test/netx_igmp_packet_receive_function_test.c create mode 100644 test/regression/netxduo_test/netx_igmp_router_query_test.c create mode 100644 test/regression/netxduo_test/netx_ip_abnormal_packet_test.c create mode 100644 test/regression/netxduo_test/netx_ip_address_change_notify_test.c create mode 100644 test/regression/netxduo_test/netx_ip_address_conflict_callback_test.c create mode 100644 test/regression/netxduo_test/netx_ip_address_conflict_detection_test.c create mode 100644 test/regression/netxduo_test/netx_ip_address_get_test.c create mode 100644 test/regression/netxduo_test/netx_ip_address_set_test.c create mode 100644 test/regression/netxduo_test/netx_ip_auxiliary_packet_pool_set_test.c create mode 100644 test/regression/netxduo_test/netx_ip_basic_test.c create mode 100644 test/regression/netxduo_test/netx_ip_branch_test.c create mode 100644 test/regression/netxduo_test/netx_ip_chain_packet_process_test.c create mode 100644 test/regression/netxduo_test/netx_ip_create_test.c create mode 100644 test/regression/netxduo_test/netx_ip_delete_test.c create mode 100644 test/regression/netxduo_test/netx_ip_driver_deferred_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_disable_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_dispatch_fail_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_duplicate_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_invalid_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_order_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_packet_copy_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_packet_delay_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_packet_drop_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_time_exceeded_message_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_timeout_check_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_timeout_check_test2.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_wrong_destination_address_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_wrong_protocol_field_test.c create mode 100644 test/regression/netxduo_test/netx_ip_fragmentation_wrong_protocol_field_test2.c create mode 100644 test/regression/netxduo_test/netx_ip_gateway_address_test.c create mode 100644 test/regression/netxduo_test/netx_ip_idle_scan_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_address_get_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_address_set_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_attachment_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_capability_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_detachment_arp_table_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_detachment_gateway_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_detachment_tcp_connection_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_detachment_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_info_get_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_physical_address_set_fail_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_physical_address_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_status_check_fail_test.c create mode 100644 test/regression/netxduo_test/netx_ip_interface_status_check_test.c create mode 100644 test/regression/netxduo_test/netx_ip_invalid_packet_receive_test.c create mode 100644 test/regression/netxduo_test/netx_ip_link_local_address_test.c create mode 100644 test/regression/netxduo_test/netx_ip_link_status_test.c create mode 100644 test/regression/netxduo_test/netx_ip_loopback_multihome_test.c create mode 100644 test/regression/netxduo_test/netx_ip_malformed_packet_test.c create mode 100644 test/regression/netxduo_test/netx_ip_malformed_packet_test.h create mode 100644 test/regression/netxduo_test/netx_ip_max_payload_size_find_test.c create mode 100644 test/regression/netxduo_test/netx_ip_multicast_interface_detach_test.c create mode 100644 test/regression/netxduo_test/netx_ip_nxe_api_test.c create mode 100644 test/regression/netxduo_test/netx_ip_packet_filter_extended_test.c create mode 100644 test/regression/netxduo_test/netx_ip_packet_filter_test.c create mode 100644 test/regression/netxduo_test/netx_ip_raw_loopback_test.c create mode 100644 test/regression/netxduo_test/netx_ip_raw_packet_filter_test.c create mode 100644 test/regression/netxduo_test/netx_ip_raw_packet_queue_test.c create mode 100644 test/regression/netxduo_test/netx_ip_raw_packet_test.c create mode 100644 test/regression/netxduo_test/netx_ip_route_reachable_test.c create mode 100644 test/regression/netxduo_test/netx_ip_static_route_add_test.c create mode 100644 test/regression/netxduo_test/netx_ip_static_route_delete_test.c create mode 100644 test/regression/netxduo_test/netx_ip_static_route_find_test.c create mode 100644 test/regression/netxduo_test/netx_ip_status_check_test.c create mode 100644 test/regression/netxduo_test/netx_ipv4_option_process_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_address_delete_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_address_get_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_address_set_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_branch_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_default_router_api_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_default_router_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_disable_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_fragment_fail_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_fragmentation_error_test1.c create mode 100644 test/regression/netxduo_test/netx_ipv6_fragmentation_error_test2.c create mode 100644 test/regression/netxduo_test/netx_ipv6_fragmentation_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_hop_by_hop_fragment_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_hop_by_hop_option_error_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_interface_detachment_router_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_invalid_packet_receive_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_multicast_basic_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_multicast_interface_detach_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_multicast_ping_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_multicast_ping_test1.c create mode 100644 test/regression/netxduo_test/netx_ipv6_nd_cache_api_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_nxe_api_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_packet_chain_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_pmtu_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_prefix_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_raw_packet_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_search_onlink_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_send_fail_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_stateless_address_autoconfig_test.c create mode 100644 test/regression/netxduo_test/netx_ipv6_util_api_test.c create mode 100644 test/regression/netxduo_test/netx_low_watermark_fragment_test.c create mode 100644 test/regression/netxduo_test/netx_low_watermark_test.c create mode 100644 test/regression/netxduo_test/netx_low_watermark_zero_window_test.c create mode 100644 test/regression/netxduo_test/netx_nd_cache_add_test.c create mode 100644 test/regression/netxduo_test/netx_nd_cache_api_test.c create mode 100644 test/regression/netxduo_test/netx_nd_cache_branch_test.c create mode 100644 test/regression/netxduo_test/netx_nd_cache_nxe_api_test.c create mode 100644 test/regression/netxduo_test/netx_nd_cache_under_interface_detach_test.c create mode 100644 test/regression/netxduo_test/netx_nd_cache_with_own_address_test.c create mode 100644 test/regression/netxduo_test/netx_nxd_udp_socket_send_special_test.c create mode 100644 test/regression/netxduo_test/netx_old_api_test.c create mode 100644 test/regression/netxduo_test/netx_packet_basic_test.c create mode 100644 test/regression/netxduo_test/netx_packet_branch_test.c create mode 100644 test/regression/netxduo_test/netx_packet_data_append_test.c create mode 100644 test/regression/netxduo_test/netx_packet_debug_info_test.c create mode 100644 test/regression/netxduo_test/netx_packet_nxe_api_test.c create mode 100644 test/regression/netxduo_test/netx_packet_payload_size_test.c create mode 100644 test/regression/netxduo_test/netx_packet_suspension_test.c create mode 100644 test/regression/netxduo_test/netx_ramdriver_callback_test.c create mode 100644 test/regression/netxduo_test/netx_rarp_basic_processing_test.c create mode 100644 test/regression/netxduo_test/netx_rarp_branch_test.c create mode 100644 test/regression/netxduo_test/netx_rarp_multiple_interfaces_test.c create mode 100644 test/regression/netxduo_test/netx_rarp_nxe_api_test.c create mode 100644 test/regression/netxduo_test/netx_rarp_packet_allocate_fail_test.c create mode 100644 test/regression/netxduo_test/netx_raw_nxe_api_test.c create mode 100644 test/regression/netxduo_test/netx_raw_special_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_4_duplicate_ack_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_ack_before_release_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_ack_check_for_syn_message_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_ack_check_issue_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_advertised_window_update_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_basic_processing_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_branch_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_chained_packet_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_client_bind_cleanup_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_client_packet_leak_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_client_socket_bind_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_client_socket_port_get_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_client_socket_unbind_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_connection_reset_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_cwnd_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_data_transfer_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_data_trim_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_delayed_retransmission_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_delayed_retransmission_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_dropped_packet_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_dropped_packet_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_duplicate_accept_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_error_operation_check_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_fast_disconnect_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_fast_retransmit_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_fin_wait1_to_time_wait_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_fin_wait_recv_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_invalid_length_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_invalid_option_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_invalid_option_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_invalid_packet_chain_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_ipv4_interface2_mss_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_ipv6_basic_processing_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_ipv6_delayed_retransmission_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_ipv6_interface2_mss_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_ipv6_window_scale_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_keepalive_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_large_data_transfer_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_large_mtu_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_large_mtu_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_listen_packet_leak_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_listen_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_loopback_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_max_window_scale_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_mss_option_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_multiple_send_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_multiple_send_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test1.c create mode 100644 test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test3.c create mode 100644 test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test4.c create mode 100644 test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test5.c create mode 100644 test/regression/netxduo_test/netx_tcp_not_enabled_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_nxe_api_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_odd_window_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_out_of_order_ack_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_out_of_order_packet_max_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_out_of_order_packet_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_out_of_window_control_packet_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_10.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_11.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_12.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_13.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_14.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_15.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_16.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_17.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_18.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_2.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_3.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_4.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_5.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_6.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_7.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_8.c create mode 100644 test/regression/netxduo_test/netx_tcp_overlapping_packet_test_9.c create mode 100644 test/regression/netxduo_test/netx_tcp_packet_leak_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_packet_receive_function_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_queue_depth_notify_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_race_condition_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_race_condition_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_receive_cleanup_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_receive_under_interface_detach_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_receive_under_interface_detach_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_reset_during_send_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_retransmit_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_retransmit_test_1.c create mode 100644 test/regression/netxduo_test/netx_tcp_send_disconnect_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_send_fail_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_send_fail_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_send_fail_test3.c create mode 100644 test/regression/netxduo_test/netx_tcp_server_socket_accept_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_simultaneous_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_small_packet_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_small_window_preempt_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_small_window_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_available_bytes_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_delete_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_listen_queue_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_listen_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_mss_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_receive_rst_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_relisten_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_relisten_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_send_internal_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_state_wait_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_unaccept_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_unbind_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_unbind_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_socket_unlisten_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_time_wait_to_close_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_transmit_cleanup_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_transmit_not_done_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_transmit_under_interface_detach_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv4_basic_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_address_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_basic_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_big_packet_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_small_windows_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_tunnel_ipv6_ipv4_basic_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_tunnel_ipv6_ipv6_basic_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_tx_queue_exceed_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_udp_random_port_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_urgent_packet_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_window_update_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_wrapping_sequence_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_wrapping_sequence_test2.c create mode 100644 test/regression/netxduo_test/netx_tcp_wrapping_sequence_test3.c create mode 100644 test/regression/netxduo_test/netx_tcp_wrapping_sequence_test4.c create mode 100644 test/regression/netxduo_test/netx_tcp_zero_window_probe_2_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_zero_window_probe_3_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_zero_window_probe_test.c create mode 100644 test/regression/netxduo_test/netx_tcp_zero_window_test.c create mode 100644 test/regression/netxduo_test/netx_udp_basic_processing_test.c create mode 100644 test/regression/netxduo_test/netx_udp_bind_cleanup_test.c create mode 100644 test/regression/netxduo_test/netx_udp_branch_test.c create mode 100644 test/regression/netxduo_test/netx_udp_checksum_zero_test.c create mode 100644 test/regression/netxduo_test/netx_udp_fragment_test.c create mode 100644 test/regression/netxduo_test/netx_udp_fragmentation_processing_test.c create mode 100644 test/regression/netxduo_test/netx_udp_free_port_find_test.c create mode 100644 test/regression/netxduo_test/netx_udp_ipv4_interface2_test_1_test.c create mode 100644 test/regression/netxduo_test/netx_udp_ipv6_interface2_test_1_test.c create mode 100644 test/regression/netxduo_test/netx_udp_loopback_test.c create mode 100644 test/regression/netxduo_test/netx_udp_multiple_ports_test.c create mode 100644 test/regression/netxduo_test/netx_udp_nxe_api_test.c create mode 100644 test/regression/netxduo_test/netx_udp_packet_receive_test.c create mode 100644 test/regression/netxduo_test/netx_udp_packet_type_test.c create mode 100644 test/regression/netxduo_test/netx_udp_port_table_udpate_test.c create mode 100644 test/regression/netxduo_test/netx_udp_port_unreachable_test.c create mode 100644 test/regression/netxduo_test/netx_udp_socket_bind_test.c create mode 100644 test/regression/netxduo_test/netx_udp_socket_delete_test.c create mode 100644 test/regression/netxduo_test/netx_udp_socket_unbind_receive_test.c create mode 100644 test/regression/netxduo_test/netx_udp_socket_unbind_test.c create mode 100644 test/regression/netxduo_test/netx_udp_source_send_test.c create mode 100644 test/regression/netxduo_test/netx_udp_tunnel_ipv4_ipv4_basic_test.c create mode 100644 test/regression/netxduo_test/netx_udp_tunnel_ipv4_ipv6_basic_test.c create mode 100644 test/regression/netxduo_test/netx_udp_tunnel_ipv6_ipv4_basic_test.c create mode 100644 test/regression/netxduo_test/netx_udp_tunnel_ipv6_ipv6_basic_test.c create mode 100644 test/regression/netxduo_test/netx_utility_test.c create mode 100644 test/regression/pop3_test/netx_pop3_abnormal_packet_test.c create mode 100644 test/regression/pop3_test/netx_pop3_mail_receive_test.c create mode 100644 test/regression/pop3_test/netx_pop3_packet_with_endmarker_test.c create mode 100644 test/regression/pop3_test/netx_pop3_two_mails_received_test.c create mode 100644 test/regression/ppp_test/netx_ppp_IPCP_abnormal_packet_test.c create mode 100644 test/regression/ppp_test/netx_ppp_IPCP_nak_test.c create mode 100644 test/regression/ppp_test/netx_ppp_IPCP_retransmit_test.c create mode 100644 test/regression/ppp_test/netx_ppp_IPCP_timeout.c create mode 100644 test/regression/ppp_test/netx_ppp_LCP_invalid_packet_test.c create mode 100644 test/regression/ppp_test/netx_ppp_LCP_timeout.c create mode 100644 test/regression/ppp_test/netx_ppp_PAP_bad_password_test.c create mode 100644 test/regression/ppp_test/netx_ppp_PAP_bad_username_test.c create mode 100644 test/regression/ppp_test/netx_ppp_acfc_option_test.c create mode 100644 test/regression/ppp_test/netx_ppp_chap_bad_secret_failed_retry_test.c create mode 100644 test/regression/ppp_test/netx_ppp_chap_bad_secret_passed_on_retry_test.c create mode 100644 test/regression/ppp_test/netx_ppp_check_boundary_test.c create mode 100644 test/regression/ppp_test/netx_ppp_pap_basic_test.c create mode 100644 test/regression/ppp_test/netx_ppp_pap_null_name_password_test.c create mode 100644 test/regression/ppp_test/netx_ppp_pfc_option_test.c create mode 100644 test/regression/ppp_test/netx_ppp_request_dns_server_test.c create mode 100644 test/regression/pppoe_test/netx_pppoe_ac_name_test.c create mode 100644 test/regression/pppoe_test/netx_pppoe_api_extended_test.c create mode 100644 test/regression/pppoe_test/netx_pppoe_api_test.c create mode 100644 test/regression/pppoe_test/netx_pppoe_basic_test.c create mode 100644 test/regression/pppoe_test/netx_pppoe_session_control_test.c create mode 100644 test/regression/ptp_test/netx_ptp_client_announce_timeout_test.c create mode 100644 test/regression/ptp_test/netx_ptp_client_api_test.c create mode 100644 test/regression/ptp_test/netx_ptp_client_basic_test.c create mode 100644 test/regression/ptp_test/netx_ptp_client_calibrate_test.c create mode 100644 test/regression/ptp_test/netx_ptp_client_ipv6_test.c create mode 100644 test/regression/ptp_test/netx_ptp_client_master_selection_test.c create mode 100644 test/regression/ptp_test/netx_ptp_client_two_steps_off_test.c create mode 100644 test/regression/ptp_test/netx_ptp_utility.c create mode 100644 test/regression/ptp_test/netx_ptp_utility.h create mode 100644 test/regression/rtp_test/netx_rtcp_abnormal_packet_test.c create mode 100644 test/regression/rtp_test/netx_rtcp_basic_test.c create mode 100644 test/regression/rtp_test/netx_rtcp_packet_process_test.c create mode 100644 test/regression/rtp_test/netx_rtcp_packet_send_test.c create mode 100644 test/regression/rtp_test/netx_rtp_api_test.c create mode 100644 test/regression/rtp_test/netx_rtp_basic_test.c create mode 100644 test/regression/rtp_test/netx_rtp_free_udp_port_find_test.c create mode 100644 test/regression/rtp_test/netx_rtp_multi_clients_test.c create mode 100644 test/regression/rtp_test/netx_rtp_multi_interfaces_test.c create mode 100644 test/regression/rtp_test/netx_rtp_multicast_test.c create mode 100644 test/regression/rtp_test/netx_rtp_session_aac_send_test.c create mode 100644 test/regression/rtp_test/netx_rtp_session_h264_send_test.c create mode 100644 test/regression/rtp_test/netx_rtp_session_jpeg_send_test.c create mode 100644 test/regression/rtp_test/netx_rtp_session_packet_send_test.c create mode 100644 test/regression/rtsp_test/netx_rtsp_api_test.c create mode 100644 test/regression/rtsp_test/netx_rtsp_client_timeout_test.c create mode 100644 test/regression/rtsp_test/netx_rtsp_delete_beforehand_test.c create mode 100644 test/regression/rtsp_test/netx_rtsp_error_response_test.c create mode 100644 test/regression/rtsp_test/netx_rtsp_multiple_clients_test.c create mode 100644 test/regression/rtsp_test/netx_rtsp_multiple_request_test.c create mode 100644 test/regression/rtsp_test/netx_rtsp_rtp_basic_test.c create mode 100644 test/regression/rtsp_test/netx_rtsp_rtp_ipv6_basic_test.c create mode 100644 test/regression/rtsp_test/netx_rtsp_rtp_ipv6_multicast_test.c create mode 100644 test/regression/rtsp_test/netx_rtsp_rtp_multicast_test.c create mode 100644 test/regression/smtp_test/netx_smtp_abnormal_packet_test.c create mode 100644 test/regression/smtp_test/netx_smtp_auth_logon_function_test.c create mode 100644 test/regression/smtp_test/netx_smtp_auth_no_type_function_test.c create mode 100644 test/regression/smtp_test/netx_smtp_auth_no_type_test.c create mode 100644 test/regression/smtp_test/netx_smtp_auth_none_test.c create mode 100644 test/regression/smtp_test/netx_smtp_basic_function_test.c create mode 100644 test/regression/smtp_test/netx_smtp_invalid_release_test.c create mode 100644 test/regression/smtp_test/netx_smtp_missing_last_250_EHLO_message_test.c create mode 100644 test/regression/smtp_test/netx_smtp_two_packet_EHLO_auth_last_message_test.c create mode 100644 test/regression/smtp_test/netx_smtp_two_packet_EHLO_message_test.c create mode 100644 test/regression/smtp_test/smtp_server_packets.c create mode 100644 test/regression/smtp_test/smtp_test_files.mk create mode 100644 test/regression/snmp_test/GetSet_IPv4v6Address.c create mode 100644 test/regression/snmp_test/GetSet_Integers_Large_and_Neg_Numbers.c create mode 100644 test/regression/snmp_test/GetSet_OctetStrings.c create mode 100644 test/regression/snmp_test/Get_Miscellaneous_Data_type.c create mode 100644 test/regression/snmp_test/get_snmp_v3_request.c create mode 100644 test/regression/snmp_test/netx_snmp_abnormal_packet_test.c create mode 100644 test/regression/snmp_test/netx_snmp_basic_v2_test.c create mode 100644 test/regression/snmp_test/netx_snmp_no_security_function_test.c create mode 100644 test/regression/snmp_test/netx_snmp_setget_integers_test.c create mode 100644 test/regression/snmp_test/netx_snmp_setget_ip_address_test.c create mode 100644 test/regression/snmp_test/netx_snmp_setget_misc_test.c create mode 100644 test/regression/snmp_test/netx_snmp_setget_octet_strings_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v1_buffer_overwrite_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v1_object_id_buffer_overwrite_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v1_packet_double_release_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v2_buffer_overwrite_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v2_get_bulk_request_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v2_send_trap_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v2_unknown_oid_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v3_buffer_overwrite_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v3_decrypt_pdu_buffer_overwrite_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v3_encrypt_pdu_buffer_overwrite_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v3_encrypt_pdu_padding_buffer_overwrite_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v3_md5_failed_security_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v3_md5_security_extended_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v3_md5_security_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v3_no_security_function_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v3_nosec_traplist_test.c create mode 100644 test/regression/snmp_test/netx_snmp_v3_object_id_buffer_overwrite_test.c create mode 100644 test/regression/snmp_test/small_mib_helper.c create mode 100644 test/regression/snmp_test/small_mib_helper.h create mode 100644 test/regression/snmp_test/snmp_manager_packets.c create mode 100644 test/regression/sntp_test/netx_sntp_client_broadcast_basic_test.c create mode 100644 test/regression/sntp_test/netx_sntp_client_ipv6_broadcast_basic_test.c create mode 100644 test/regression/sntp_test/netx_sntp_client_ipv6_unicast_basic_test.c create mode 100644 test/regression/sntp_test/netx_sntp_client_kod_test.c create mode 100644 test/regression/sntp_test/netx_sntp_client_packet_chain_test.c create mode 100644 test/regression/sntp_test/netx_sntp_client_seconds_to_date_test.c create mode 100644 test/regression/sntp_test/netx_sntp_client_unicast_basic_test.c create mode 100644 test/regression/sntp_test/netx_sntp_client_unicast_display_date_test.c create mode 100644 test/regression/sntp_test/netx_sntp_forward_unicast_update_test.c create mode 100644 test/regression/sntp_test/netx_sntp_request_unicast_test.c create mode 100644 test/regression/tahi_test/netx_tahi.h create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_002.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_003.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_004.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_005.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_006.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_007.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_008.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_009.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_010.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_011.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_012.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_013.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_014.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_019.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_020.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_021.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_022.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_023.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_024.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_025.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_026.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_027.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_028.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_029.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_030.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_031.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_032.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_033.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_034.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_035.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_036.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_037.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_038.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_039.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_040.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_041.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_042.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_043.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_044.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_045.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_046.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_047.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_048.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_049.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_050.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_051.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_052.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_053.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_054.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_055.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_056.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_057.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_058.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_059.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_060.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_061.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_062.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_063.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_064.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_065.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_066.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_067.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_068.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_069.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_070.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_071.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_072.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_073.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_074.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_075.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_076.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_077.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_078.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_079.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_080.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_081.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_082.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_083.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_084.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_085.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_086.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_087.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_088.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_089.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_090.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_091.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_092.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_093.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_094.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_095.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_096.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_097.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_098.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_01_099.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_002.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_003.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_004.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_005.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_006.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_007.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_008.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_009.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_010.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_012.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_013.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_014.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_015.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_016.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_017.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_018.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_019.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_020.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_021.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_022.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_026.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_04_027.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_002.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_003.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_004.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_005.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_006.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_007.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_008.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_009.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_010.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_011.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_012.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_013.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_014.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_015.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_016.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_017.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_018.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_019.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_020.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_021.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_022.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_023.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_024.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_025.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_026.c create mode 100644 test/regression/tahi_test/netx_tahi_dhcpv6_test_07_027.c create mode 100644 test/regression/tahi_test/netx_tahi_run_test_case.c create mode 100644 test/regression/tahi_test/netx_tahi_test_1.c create mode 100644 test/regression/tahi_test/netx_tahi_test_2_01.c create mode 100644 test/regression/tahi_test/netx_tahi_test_2_02.c create mode 100644 test/regression/tahi_test/netx_tahi_test_2_03.c create mode 100644 test/regression/tahi_test/netx_tahi_test_2_04.c create mode 100644 test/regression/tahi_test/netx_tahi_test_2_05.c create mode 100644 test/regression/tahi_test/netx_tahi_test_2_06.c create mode 100644 test/regression/tahi_test/netx_tahi_test_2_07.c create mode 100644 test/regression/tahi_test/netx_tahi_test_2_08.c create mode 100644 test/regression/tahi_test/netx_tahi_test_2_09.c create mode 100644 test/regression/tahi_test/netx_tahi_test_2_10.c create mode 100644 test/regression/tahi_test/netx_tahi_test_2_11.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_01.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_02.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_03.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_04.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_05.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_06.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_07.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_08.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_09.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_10.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_11.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_12.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_13.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_14.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_15.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_16.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_17.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_18.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_19.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_20.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_21.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_22.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_23.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_24.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_25.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_26.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_27.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_28.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_29.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_30.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_31.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_32.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_33.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_34.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_35.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_36.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_37.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_38.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_39.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_40.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_41.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_42.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_43.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_44.c create mode 100644 test/regression/tahi_test/netx_tahi_test_3_45.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_10.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_11.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_12.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_13.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_14.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_15.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_16.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_2.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_3.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_4.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_5.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_6.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_7.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_8.c create mode 100644 test/regression/tahi_test/netx_tahi_test_4_9.c create mode 100644 test/regression/tahi_test/netx_tahi_test_5.c create mode 100644 test/regression/tahi_test/netx_tahi_test_ipsec.c create mode 100644 test/regression/tahi_test/netx_tahi_test_ipsec_2.c create mode 100644 test/regression/tahi_test/netx_tahi_test_ipsec_udp.c create mode 100644 test/regression/tahi_test/netx_tahi_test_ipsec_udp_2.c create mode 100644 test/regression/tahi_test/tahi.a create mode 100644 test/regression/tahi_test/tahi.so create mode 100644 test/regression/tahi_test/tahi64.a create mode 100644 test/regression/tahi_test/tahi64.so create mode 100644 test/regression/tahi_test/tahi_01_001.c create mode 100644 test/regression/tahi_test/tahi_01_002.c create mode 100644 test/regression/tahi_test/tahi_01_003.c create mode 100644 test/regression/tahi_test/tahi_01_004.c create mode 100644 test/regression/tahi_test/tahi_01_005.c create mode 100644 test/regression/tahi_test/tahi_01_006.c create mode 100644 test/regression/tahi_test/tahi_01_007.c create mode 100644 test/regression/tahi_test/tahi_01_008.c create mode 100644 test/regression/tahi_test/tahi_01_009.c create mode 100644 test/regression/tahi_test/tahi_01_010.c create mode 100644 test/regression/tahi_test/tahi_01_011.c create mode 100644 test/regression/tahi_test/tahi_01_012.c create mode 100644 test/regression/tahi_test/tahi_01_013.c create mode 100644 test/regression/tahi_test/tahi_01_014.c create mode 100644 test/regression/tahi_test/tahi_01_015.c create mode 100644 test/regression/tahi_test/tahi_01_016.c create mode 100644 test/regression/tahi_test/tahi_01_017.c create mode 100644 test/regression/tahi_test/tahi_01_018.c create mode 100644 test/regression/tahi_test/tahi_01_019.c create mode 100644 test/regression/tahi_test/tahi_01_020.c create mode 100644 test/regression/tahi_test/tahi_01_021.c create mode 100644 test/regression/tahi_test/tahi_01_022.c create mode 100644 test/regression/tahi_test/tahi_01_023.c create mode 100644 test/regression/tahi_test/tahi_01_024.c create mode 100644 test/regression/tahi_test/tahi_01_025.c create mode 100644 test/regression/tahi_test/tahi_01_026.c create mode 100644 test/regression/tahi_test/tahi_01_027.c create mode 100644 test/regression/tahi_test/tahi_01_028.c create mode 100644 test/regression/tahi_test/tahi_01_029.c create mode 100644 test/regression/tahi_test/tahi_01_030.c create mode 100644 test/regression/tahi_test/tahi_01_031.c create mode 100644 test/regression/tahi_test/tahi_01_032.c create mode 100644 test/regression/tahi_test/tahi_01_033.c create mode 100644 test/regression/tahi_test/tahi_01_034.c create mode 100644 test/regression/tahi_test/tahi_01_035.c create mode 100644 test/regression/tahi_test/tahi_01_036.c create mode 100644 test/regression/tahi_test/tahi_01_037.c create mode 100644 test/regression/tahi_test/tahi_01_038.c create mode 100644 test/regression/tahi_test/tahi_01_039.c create mode 100644 test/regression/tahi_test/tahi_01_040.c create mode 100644 test/regression/tahi_test/tahi_01_041.c create mode 100644 test/regression/tahi_test/tahi_01_042.c create mode 100644 test/regression/tahi_test/tahi_01_043.c create mode 100644 test/regression/tahi_test/tahi_01_044.c create mode 100644 test/regression/tahi_test/tahi_01_045.c create mode 100644 test/regression/tahi_test/tahi_01_046.c create mode 100644 test/regression/tahi_test/tahi_01_047.c create mode 100644 test/regression/tahi_test/tahi_01_048.c create mode 100644 test/regression/tahi_test/tahi_01_049.c create mode 100644 test/regression/tahi_test/tahi_01_050.c create mode 100644 test/regression/tahi_test/tahi_01_051.c create mode 100644 test/regression/tahi_test/tahi_01_052.c create mode 100644 test/regression/tahi_test/tahi_01_053.c create mode 100644 test/regression/tahi_test/tahi_01_054.c create mode 100644 test/regression/tahi_test/tahi_02_001.c create mode 100644 test/regression/tahi_test/tahi_02_002.c create mode 100644 test/regression/tahi_test/tahi_02_003.c create mode 100644 test/regression/tahi_test/tahi_02_004.c create mode 100644 test/regression/tahi_test/tahi_02_005.c create mode 100644 test/regression/tahi_test/tahi_02_006.c create mode 100644 test/regression/tahi_test/tahi_02_007.c create mode 100644 test/regression/tahi_test/tahi_02_008.c create mode 100644 test/regression/tahi_test/tahi_02_009.c create mode 100644 test/regression/tahi_test/tahi_02_010.c create mode 100644 test/regression/tahi_test/tahi_02_011.c create mode 100644 test/regression/tahi_test/tahi_02_012.c create mode 100644 test/regression/tahi_test/tahi_02_013.c create mode 100644 test/regression/tahi_test/tahi_02_014.c create mode 100644 test/regression/tahi_test/tahi_02_015.c create mode 100644 test/regression/tahi_test/tahi_02_016.c create mode 100644 test/regression/tahi_test/tahi_02_017.c create mode 100644 test/regression/tahi_test/tahi_02_018.c create mode 100644 test/regression/tahi_test/tahi_02_019.c create mode 100644 test/regression/tahi_test/tahi_02_020.c create mode 100644 test/regression/tahi_test/tahi_02_021.c create mode 100644 test/regression/tahi_test/tahi_02_022.c create mode 100644 test/regression/tahi_test/tahi_02_023.c create mode 100644 test/regression/tahi_test/tahi_02_024.c create mode 100644 test/regression/tahi_test/tahi_02_025.c create mode 100644 test/regression/tahi_test/tahi_02_026.c create mode 100644 test/regression/tahi_test/tahi_02_027.c create mode 100644 test/regression/tahi_test/tahi_02_028.c create mode 100644 test/regression/tahi_test/tahi_02_029.c create mode 100644 test/regression/tahi_test/tahi_02_030.c create mode 100644 test/regression/tahi_test/tahi_02_031.c create mode 100644 test/regression/tahi_test/tahi_02_032.c create mode 100644 test/regression/tahi_test/tahi_02_033.c create mode 100644 test/regression/tahi_test/tahi_02_034.c create mode 100644 test/regression/tahi_test/tahi_02_035.c create mode 100644 test/regression/tahi_test/tahi_02_036.c create mode 100644 test/regression/tahi_test/tahi_02_037.c create mode 100644 test/regression/tahi_test/tahi_02_038.c create mode 100644 test/regression/tahi_test/tahi_02_039.c create mode 100644 test/regression/tahi_test/tahi_02_040.c create mode 100644 test/regression/tahi_test/tahi_02_041.c create mode 100644 test/regression/tahi_test/tahi_02_042.c create mode 100644 test/regression/tahi_test/tahi_02_043.c create mode 100644 test/regression/tahi_test/tahi_02_044.c create mode 100644 test/regression/tahi_test/tahi_02_045.c create mode 100644 test/regression/tahi_test/tahi_02_046.c create mode 100644 test/regression/tahi_test/tahi_02_047.c create mode 100644 test/regression/tahi_test/tahi_02_048.c create mode 100644 test/regression/tahi_test/tahi_02_049.c create mode 100644 test/regression/tahi_test/tahi_02_050.c create mode 100644 test/regression/tahi_test/tahi_02_051.c create mode 100644 test/regression/tahi_test/tahi_02_052.c create mode 100644 test/regression/tahi_test/tahi_02_053.c create mode 100644 test/regression/tahi_test/tahi_02_054.c create mode 100644 test/regression/tahi_test/tahi_02_055.c create mode 100644 test/regression/tahi_test/tahi_02_056.c create mode 100644 test/regression/tahi_test/tahi_02_057.c create mode 100644 test/regression/tahi_test/tahi_02_058.c create mode 100644 test/regression/tahi_test/tahi_02_059.c create mode 100644 test/regression/tahi_test/tahi_02_060.c create mode 100644 test/regression/tahi_test/tahi_02_061.c create mode 100644 test/regression/tahi_test/tahi_02_062.c create mode 100644 test/regression/tahi_test/tahi_02_063.c create mode 100644 test/regression/tahi_test/tahi_02_064.c create mode 100644 test/regression/tahi_test/tahi_02_065.c create mode 100644 test/regression/tahi_test/tahi_02_066.c create mode 100644 test/regression/tahi_test/tahi_02_067.c create mode 100644 test/regression/tahi_test/tahi_02_068.c create mode 100644 test/regression/tahi_test/tahi_02_069.c create mode 100644 test/regression/tahi_test/tahi_02_070.c create mode 100644 test/regression/tahi_test/tahi_02_071.c create mode 100644 test/regression/tahi_test/tahi_02_072.c create mode 100644 test/regression/tahi_test/tahi_02_073.c create mode 100644 test/regression/tahi_test/tahi_02_074.c create mode 100644 test/regression/tahi_test/tahi_02_075.c create mode 100644 test/regression/tahi_test/tahi_02_076.c create mode 100644 test/regression/tahi_test/tahi_02_077.c create mode 100644 test/regression/tahi_test/tahi_02_078.c create mode 100644 test/regression/tahi_test/tahi_02_079.c create mode 100644 test/regression/tahi_test/tahi_02_080.c create mode 100644 test/regression/tahi_test/tahi_02_081.c create mode 100644 test/regression/tahi_test/tahi_02_082.c create mode 100644 test/regression/tahi_test/tahi_02_083.c create mode 100644 test/regression/tahi_test/tahi_02_084.c create mode 100644 test/regression/tahi_test/tahi_02_085.c create mode 100644 test/regression/tahi_test/tahi_02_086.c create mode 100644 test/regression/tahi_test/tahi_02_087.c create mode 100644 test/regression/tahi_test/tahi_02_088.c create mode 100644 test/regression/tahi_test/tahi_02_089.c create mode 100644 test/regression/tahi_test/tahi_02_090.c create mode 100644 test/regression/tahi_test/tahi_02_091.c create mode 100644 test/regression/tahi_test/tahi_02_092.c create mode 100644 test/regression/tahi_test/tahi_02_093.c create mode 100644 test/regression/tahi_test/tahi_02_094.c create mode 100644 test/regression/tahi_test/tahi_02_095.c create mode 100644 test/regression/tahi_test/tahi_02_096.c create mode 100644 test/regression/tahi_test/tahi_02_097.c create mode 100644 test/regression/tahi_test/tahi_02_098.c create mode 100644 test/regression/tahi_test/tahi_02_099.c create mode 100644 test/regression/tahi_test/tahi_02_100.c create mode 100644 test/regression/tahi_test/tahi_02_101.c create mode 100644 test/regression/tahi_test/tahi_02_102.c create mode 100644 test/regression/tahi_test/tahi_02_103.c create mode 100644 test/regression/tahi_test/tahi_02_104.c create mode 100644 test/regression/tahi_test/tahi_02_105.c create mode 100644 test/regression/tahi_test/tahi_02_106.c create mode 100644 test/regression/tahi_test/tahi_02_107.c create mode 100644 test/regression/tahi_test/tahi_02_108.c create mode 100644 test/regression/tahi_test/tahi_02_109.c create mode 100644 test/regression/tahi_test/tahi_02_110.c create mode 100644 test/regression/tahi_test/tahi_02_111.c create mode 100644 test/regression/tahi_test/tahi_02_112.c create mode 100644 test/regression/tahi_test/tahi_02_113.c create mode 100644 test/regression/tahi_test/tahi_02_114.c create mode 100644 test/regression/tahi_test/tahi_02_115.c create mode 100644 test/regression/tahi_test/tahi_02_116.c create mode 100644 test/regression/tahi_test/tahi_02_117.c create mode 100644 test/regression/tahi_test/tahi_02_118.c create mode 100644 test/regression/tahi_test/tahi_02_119.c create mode 100644 test/regression/tahi_test/tahi_02_120.c create mode 100644 test/regression/tahi_test/tahi_02_121.c create mode 100644 test/regression/tahi_test/tahi_02_122.c create mode 100644 test/regression/tahi_test/tahi_02_123.c create mode 100644 test/regression/tahi_test/tahi_02_124.c create mode 100644 test/regression/tahi_test/tahi_02_125.c create mode 100644 test/regression/tahi_test/tahi_02_126.c create mode 100644 test/regression/tahi_test/tahi_02_127.c create mode 100644 test/regression/tahi_test/tahi_02_128.c create mode 100644 test/regression/tahi_test/tahi_02_129.c create mode 100644 test/regression/tahi_test/tahi_02_130.c create mode 100644 test/regression/tahi_test/tahi_02_131.c create mode 100644 test/regression/tahi_test/tahi_02_132.c create mode 100644 test/regression/tahi_test/tahi_02_133.c create mode 100644 test/regression/tahi_test/tahi_02_134.c create mode 100644 test/regression/tahi_test/tahi_02_135.c create mode 100644 test/regression/tahi_test/tahi_02_136.c create mode 100644 test/regression/tahi_test/tahi_02_137.c create mode 100644 test/regression/tahi_test/tahi_02_138.c create mode 100644 test/regression/tahi_test/tahi_02_139.c create mode 100644 test/regression/tahi_test/tahi_02_140.c create mode 100644 test/regression/tahi_test/tahi_02_141.c create mode 100644 test/regression/tahi_test/tahi_02_142.c create mode 100644 test/regression/tahi_test/tahi_02_143.c create mode 100644 test/regression/tahi_test/tahi_02_144.c create mode 100644 test/regression/tahi_test/tahi_02_145.c create mode 100644 test/regression/tahi_test/tahi_02_146.c create mode 100644 test/regression/tahi_test/tahi_02_147.c create mode 100644 test/regression/tahi_test/tahi_02_148.c create mode 100644 test/regression/tahi_test/tahi_02_149.c create mode 100644 test/regression/tahi_test/tahi_02_150.c create mode 100644 test/regression/tahi_test/tahi_02_151.c create mode 100644 test/regression/tahi_test/tahi_02_152.c create mode 100644 test/regression/tahi_test/tahi_02_153.c create mode 100644 test/regression/tahi_test/tahi_02_154.c create mode 100644 test/regression/tahi_test/tahi_02_155.c create mode 100644 test/regression/tahi_test/tahi_02_156.c create mode 100644 test/regression/tahi_test/tahi_02_157.c create mode 100644 test/regression/tahi_test/tahi_02_158.c create mode 100644 test/regression/tahi_test/tahi_02_159.c create mode 100644 test/regression/tahi_test/tahi_02_160.c create mode 100644 test/regression/tahi_test/tahi_02_161.c create mode 100644 test/regression/tahi_test/tahi_02_162.c create mode 100644 test/regression/tahi_test/tahi_02_163.c create mode 100644 test/regression/tahi_test/tahi_02_164.c create mode 100644 test/regression/tahi_test/tahi_02_165.c create mode 100644 test/regression/tahi_test/tahi_02_166.c create mode 100644 test/regression/tahi_test/tahi_02_167.c create mode 100644 test/regression/tahi_test/tahi_02_168.c create mode 100644 test/regression/tahi_test/tahi_02_169.c create mode 100644 test/regression/tahi_test/tahi_02_170.c create mode 100644 test/regression/tahi_test/tahi_02_171.c create mode 100644 test/regression/tahi_test/tahi_02_172.c create mode 100644 test/regression/tahi_test/tahi_02_173.c create mode 100644 test/regression/tahi_test/tahi_02_174.c create mode 100644 test/regression/tahi_test/tahi_02_175.c create mode 100644 test/regression/tahi_test/tahi_02_176.c create mode 100644 test/regression/tahi_test/tahi_02_177.c create mode 100644 test/regression/tahi_test/tahi_02_178.c create mode 100644 test/regression/tahi_test/tahi_02_179.c create mode 100644 test/regression/tahi_test/tahi_02_180.c create mode 100644 test/regression/tahi_test/tahi_02_181.c create mode 100644 test/regression/tahi_test/tahi_02_182.c create mode 100644 test/regression/tahi_test/tahi_02_183.c create mode 100644 test/regression/tahi_test/tahi_02_184.c create mode 100644 test/regression/tahi_test/tahi_02_185.c create mode 100644 test/regression/tahi_test/tahi_02_186.c create mode 100644 test/regression/tahi_test/tahi_02_187.c create mode 100644 test/regression/tahi_test/tahi_02_188.c create mode 100644 test/regression/tahi_test/tahi_02_189.c create mode 100644 test/regression/tahi_test/tahi_02_190.c create mode 100644 test/regression/tahi_test/tahi_02_191.c create mode 100644 test/regression/tahi_test/tahi_02_192.c create mode 100644 test/regression/tahi_test/tahi_02_193.c create mode 100644 test/regression/tahi_test/tahi_02_194.c create mode 100644 test/regression/tahi_test/tahi_02_195.c create mode 100644 test/regression/tahi_test/tahi_02_196.c create mode 100644 test/regression/tahi_test/tahi_02_197.c create mode 100644 test/regression/tahi_test/tahi_02_198.c create mode 100644 test/regression/tahi_test/tahi_02_199.c create mode 100644 test/regression/tahi_test/tahi_02_200.c create mode 100644 test/regression/tahi_test/tahi_02_201.c create mode 100644 test/regression/tahi_test/tahi_02_202.c create mode 100644 test/regression/tahi_test/tahi_02_203.c create mode 100644 test/regression/tahi_test/tahi_02_204.c create mode 100644 test/regression/tahi_test/tahi_02_205.c create mode 100644 test/regression/tahi_test/tahi_02_206.c create mode 100644 test/regression/tahi_test/tahi_02_207.c create mode 100644 test/regression/tahi_test/tahi_02_208.c create mode 100644 test/regression/tahi_test/tahi_02_209.c create mode 100644 test/regression/tahi_test/tahi_02_210.c create mode 100644 test/regression/tahi_test/tahi_02_211.c create mode 100644 test/regression/tahi_test/tahi_02_212.c create mode 100644 test/regression/tahi_test/tahi_02_213.c create mode 100644 test/regression/tahi_test/tahi_02_214.c create mode 100644 test/regression/tahi_test/tahi_02_215.c create mode 100644 test/regression/tahi_test/tahi_02_216.c create mode 100644 test/regression/tahi_test/tahi_02_217.c create mode 100644 test/regression/tahi_test/tahi_02_218.c create mode 100644 test/regression/tahi_test/tahi_02_219.c create mode 100644 test/regression/tahi_test/tahi_02_220.c create mode 100644 test/regression/tahi_test/tahi_02_221.c create mode 100644 test/regression/tahi_test/tahi_02_222.c create mode 100644 test/regression/tahi_test/tahi_02_223.c create mode 100644 test/regression/tahi_test/tahi_02_224.c create mode 100644 test/regression/tahi_test/tahi_02_225.c create mode 100644 test/regression/tahi_test/tahi_02_226.c create mode 100644 test/regression/tahi_test/tahi_02_227.c create mode 100644 test/regression/tahi_test/tahi_02_228.c create mode 100644 test/regression/tahi_test/tahi_02_229.c create mode 100644 test/regression/tahi_test/tahi_02_230.c create mode 100644 test/regression/tahi_test/tahi_02_231.c create mode 100644 test/regression/tahi_test/tahi_02_232.c create mode 100644 test/regression/tahi_test/tahi_02_233.c create mode 100644 test/regression/tahi_test/tahi_02_234.c create mode 100644 test/regression/tahi_test/tahi_02_235.c create mode 100644 test/regression/tahi_test/tahi_02_236.c create mode 100644 test/regression/tahi_test/tahi_03_001.c create mode 100644 test/regression/tahi_test/tahi_03_002.c create mode 100644 test/regression/tahi_test/tahi_03_003.c create mode 100644 test/regression/tahi_test/tahi_03_004.c create mode 100644 test/regression/tahi_test/tahi_03_005.c create mode 100644 test/regression/tahi_test/tahi_03_006.c create mode 100644 test/regression/tahi_test/tahi_03_007.c create mode 100644 test/regression/tahi_test/tahi_03_008.c create mode 100644 test/regression/tahi_test/tahi_03_009.c create mode 100644 test/regression/tahi_test/tahi_03_010.c create mode 100644 test/regression/tahi_test/tahi_03_011.c create mode 100644 test/regression/tahi_test/tahi_03_012.c create mode 100644 test/regression/tahi_test/tahi_03_013.c create mode 100644 test/regression/tahi_test/tahi_03_014.c create mode 100644 test/regression/tahi_test/tahi_03_015.c create mode 100644 test/regression/tahi_test/tahi_03_016.c create mode 100644 test/regression/tahi_test/tahi_03_017.c create mode 100644 test/regression/tahi_test/tahi_03_018.c create mode 100644 test/regression/tahi_test/tahi_03_019.c create mode 100644 test/regression/tahi_test/tahi_03_020.c create mode 100644 test/regression/tahi_test/tahi_03_021.c create mode 100644 test/regression/tahi_test/tahi_03_022.c create mode 100644 test/regression/tahi_test/tahi_03_023.c create mode 100644 test/regression/tahi_test/tahi_03_024.c create mode 100644 test/regression/tahi_test/tahi_03_025.c create mode 100644 test/regression/tahi_test/tahi_03_026.c create mode 100644 test/regression/tahi_test/tahi_03_027.c create mode 100644 test/regression/tahi_test/tahi_03_028.c create mode 100644 test/regression/tahi_test/tahi_03_029.c create mode 100644 test/regression/tahi_test/tahi_03_030.c create mode 100644 test/regression/tahi_test/tahi_03_031.c create mode 100644 test/regression/tahi_test/tahi_03_032.c create mode 100644 test/regression/tahi_test/tahi_03_033.c create mode 100644 test/regression/tahi_test/tahi_03_034.c create mode 100644 test/regression/tahi_test/tahi_03_035.c create mode 100644 test/regression/tahi_test/tahi_03_036.c create mode 100644 test/regression/tahi_test/tahi_03_037.c create mode 100644 test/regression/tahi_test/tahi_03_038.c create mode 100644 test/regression/tahi_test/tahi_03_039.c create mode 100644 test/regression/tahi_test/tahi_03_040.c create mode 100644 test/regression/tahi_test/tahi_03_041.c create mode 100644 test/regression/tahi_test/tahi_03_042.c create mode 100644 test/regression/tahi_test/tahi_03_043.c create mode 100644 test/regression/tahi_test/tahi_03_044.c create mode 100644 test/regression/tahi_test/tahi_03_045.c create mode 100644 test/regression/tahi_test/tahi_04_002.c create mode 100644 test/regression/tahi_test/tahi_04_003.c create mode 100644 test/regression/tahi_test/tahi_04_004.c create mode 100644 test/regression/tahi_test/tahi_04_005.c create mode 100644 test/regression/tahi_test/tahi_04_006.c create mode 100644 test/regression/tahi_test/tahi_04_007.c create mode 100644 test/regression/tahi_test/tahi_04_008.c create mode 100644 test/regression/tahi_test/tahi_04_009.c create mode 100644 test/regression/tahi_test/tahi_04_010.c create mode 100644 test/regression/tahi_test/tahi_04_011.c create mode 100644 test/regression/tahi_test/tahi_04_012.c create mode 100644 test/regression/tahi_test/tahi_04_013.c create mode 100644 test/regression/tahi_test/tahi_04_014.c create mode 100644 test/regression/tahi_test/tahi_04_015.c create mode 100644 test/regression/tahi_test/tahi_04_016.c create mode 100644 test/regression/tahi_test/tahi_05_002.c create mode 100644 test/regression/tahi_test/tahi_05_003.c create mode 100644 test/regression/tahi_test/tahi_05_004.c create mode 100644 test/regression/tahi_test/tahi_05_005.c create mode 100644 test/regression/tahi_test/tahi_05_006.c create mode 100644 test/regression/tahi_test/tahi_05_007.c create mode 100644 test/regression/tahi_test/tahi_05_008.c create mode 100644 test/regression/tahi_test/tahi_05_009.c create mode 100644 test/regression/tahi_test/tahi_05_010.c create mode 100644 test/regression/tahi_test/tahi_05_012.c create mode 100644 test/regression/tahi_test/tahi_05_013.c create mode 100644 test/regression/tahi_test/tahi_05_014.c create mode 100644 test/regression/tahi_test/tahi_05_015.c create mode 100644 test/regression/tahi_test/tahi_05_017.c create mode 100644 test/regression/tahi_test/tahi_05_018.c create mode 100644 test/regression/tahi_test/tahi_05_020.c create mode 100644 test/regression/tahi_test/tahi_05_021.c create mode 100644 test/regression/tahi_test/tahi_05_022.c create mode 100644 test/regression/tahi_test/tahi_05_024.c create mode 100644 test/regression/tahi_test/tahi_05_025.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_001.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_002.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_003.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_004.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_005.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_006.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_007.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_008.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_009.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_010.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_011.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_012.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_013.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_014.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_019.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_020.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_021.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_022.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_023.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_024.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_025.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_026.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_027.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_028.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_029.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_030.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_031.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_032.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_033.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_034.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_035.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_036.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_037.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_038.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_039.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_040.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_041.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_042.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_043.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_044.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_045.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_046.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_047.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_048.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_049.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_050.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_051.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_052.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_053.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_054.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_055.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_056.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_057.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_058.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_059.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_060.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_061.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_062.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_063.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_064.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_065.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_066.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_067.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_068.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_069.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_070.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_071.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_072.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_073.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_074.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_075.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_076.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_077.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_078.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_079.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_080.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_081.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_082.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_083.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_084.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_085.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_086.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_087.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_088.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_089.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_090.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_091.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_092.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_093.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_094.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_095.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_096.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_097.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_098.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_01_099.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_002.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_003.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_004.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_005.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_006.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_007.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_008.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_009.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_010.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_012.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_013.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_014.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_015.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_016.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_017.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_018.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_019.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_020.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_021.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_022.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_026.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_04_027.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_002.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_003.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_004.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_005.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_006.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_007.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_008.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_009.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_010.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_011.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_012.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_013.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_014.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_015.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_016.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_017.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_018.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_019.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_020.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_021.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_022.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_023.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_024.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_025.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_026.c create mode 100644 test/regression/tahi_test/tahi_dhcpv6_07_027.c create mode 100644 test/regression/tahi_test/tahi_ipsec_001.c create mode 100644 test/regression/tahi_test/tahi_ipsec_002.c create mode 100644 test/regression/tahi_test/tahi_ipsec_003.c create mode 100644 test/regression/tahi_test/tahi_ipsec_004.c create mode 100644 test/regression/tahi_test/tahi_ipsec_005.c create mode 100644 test/regression/tahi_test/tahi_ipsec_006.c create mode 100644 test/regression/tahi_test/tahi_ipsec_007.c create mode 100644 test/regression/tahi_test/tahi_ipsec_008.c create mode 100644 test/regression/tahi_test/tahi_ipsec_008_02.c create mode 100644 test/regression/tahi_test/tahi_ipsec_009.c create mode 100644 test/regression/tahi_test/tahi_ipsec_009_02.c create mode 100644 test/regression/tahi_test/tahi_ipsec_010.c create mode 100644 test/regression/tahi_test/tahi_ipsec_012.c create mode 100644 test/regression/tahi_test/tahi_ipsec_013.c create mode 100644 test/regression/tahi_test/tahi_ipsec_014.c create mode 100644 test/regression/tahi_test/tahi_ipsec_015.c create mode 100644 test/regression/tahi_test/tahi_ipsec_016.c create mode 100644 test/regression/tahi_test/tahi_ipsec_017.c create mode 100644 test/regression/tahi_test/tahi_ipsec_018.c create mode 100644 test/regression/tahi_test/tahi_ipsec_019.c create mode 100644 test/regression/tahi_test/tahi_ipsec_022.c create mode 100644 test/regression/tahi_test/tahi_ipsec_023.c create mode 100644 test/regression/tahi_test/tahi_ipsec_024.c create mode 100644 test/regression/tahi_test/tahi_ipsec_025.c create mode 100644 test/regression/tahi_test/tahi_ipsec_026.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_001.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_002.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_004.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_005.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_006.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_007.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_008.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_009.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_009_02.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_010.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_011.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_012.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_013.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_014.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_015.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_016.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_017.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_018.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_019.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_022.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_023.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_024.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_025.c create mode 100644 test/regression/tahi_test/tahi_ipsec_udp_026.c create mode 100644 test/regression/telnet_test/netx_telnet_activity_timeout_test.c create mode 100644 test/regression/telnet_test/netx_telnet_basic_test.c create mode 100644 test/regression/telnet_test/netx_telnet_create_packet_pool_test.c create mode 100644 test/regression/telnet_test/netx_telnet_max_connections_test.c create mode 100644 test/regression/telnet_test/netx_telnet_rst_test.c create mode 100644 test/regression/telnet_test/netx_telnet_server_bad_option_reply_test.c create mode 100644 test/regression/telnet_test/netx_telnet_server_options_negotiate_test.c create mode 100644 test/regression/telnet_test/netx_telnet_two_listen_test.c create mode 100644 test/regression/test/netxtestcontrol.c create mode 100644 test/regression/test/netxtestcontrol.h create mode 100644 test/regression/test/nx_ram_network_driver_test_1500.c create mode 100644 test/regression/test/nx_ram_network_driver_test_1500.h create mode 100644 test/regression/tftp_test/netx_tftp_basic_test.c create mode 100644 test/regression/tftp_test/netx_tftp_error_destionation_port_test.c create mode 100644 test/regression/tftp_test/netx_tftp_error_file_name_test.c create mode 100644 test/regression/tftp_test/netx_tftp_ipv6_basic_test.c create mode 100644 test/regression/tftp_test/netx_tftp_large_data_test.c create mode 100644 test/regression/tftp_test/netx_tftp_malformed_packet_test.c create mode 100644 test/regression/tftp_test/netx_tftp_read_interaction_test.c create mode 100644 test/regression/tftp_test/netx_tftp_write_interaction_test.c create mode 100644 test/regression/web_test/ecc_certs.c create mode 100644 test/regression/web_test/http_digest_authentication.c create mode 100644 test/regression/web_test/netx_https_api_test.c create mode 100644 test/regression/web_test/netx_https_testcontrol.c create mode 100644 test/regression/web_test/netx_web_abnormal_test.c create mode 100644 test/regression/web_test/netx_web_basic_authenticate_empty_test.c create mode 100644 test/regression/web_test/netx_web_basic_authenticate_test.c create mode 100644 test/regression/web_test/netx_web_basic_ecc_test.c create mode 100644 test/regression/web_test/netx_web_basic_test.c create mode 100644 test/regression/web_test/netx_web_certifiacte_verify_test.c create mode 100644 test/regression/web_test/netx_web_chunked_request_additional_test.c create mode 100644 test/regression/web_test/netx_web_chunked_request_test.c create mode 100644 test/regression/web_test/netx_web_chunked_response_packet_chain_test.c create mode 100644 test/regression/web_test/netx_web_chunked_response_process_test.c create mode 100644 test/regression/web_test/netx_web_chunked_response_test.c create mode 100644 test/regression/web_test/netx_web_client_cleanup_test.c create mode 100644 test/regression/web_test/netx_web_client_receive_no_packet_test.c create mode 100644 test/regression/web_test/netx_web_client_rst_test.c create mode 100644 test/regression/web_test/netx_web_client_send_fail_test.c create mode 100644 test/regression/web_test/netx_web_concurrent_sessions_test.c create mode 100644 test/regression/web_test/netx_web_connect_three_times_test.c create mode 100644 test/regression/web_test/netx_web_delete_basic_test.c create mode 100644 test/regression/web_test/netx_web_digest_authenticate_test.c create mode 100644 test/regression/web_test/netx_web_digest_authenticate_test2.c create mode 100644 test/regression/web_test/netx_web_digest_authenticate_timeout_test.c create mode 100644 test/regression/web_test/netx_web_external_client_test.c create mode 100644 test/regression/web_test/netx_web_external_server_chunked_test.c create mode 100644 test/regression/web_test/netx_web_external_server_test.c create mode 100644 test/regression/web_test/netx_web_get_content_length_test.c create mode 100644 test/regression/web_test/netx_web_get_put_referred_URI_test.c create mode 100644 test/regression/web_test/netx_web_head_basic_test.c create mode 100644 test/regression/web_test/netx_web_host_field_test.c create mode 100644 test/regression/web_test/netx_web_http_demo_test.c create mode 100644 test/regression/web_test/netx_web_https_demo_test.c create mode 100644 test/regression/web_test/netx_web_if_modified_since_test.c create mode 100644 test/regression/web_test/netx_web_invalid_release_test.c create mode 100644 test/regression/web_test/netx_web_keep_alive_abnormal_test.c create mode 100644 test/regression/web_test/netx_web_keep_alive_test.c create mode 100644 test/regression/web_test/netx_web_multipart_fragment_test.c create mode 100644 test/regression/web_test/netx_web_multipart_underflow_test.c create mode 100644 test/regression/web_test/netx_web_multiple_sessions_test.c create mode 100644 test/regression/web_test/netx_web_multiple_sessions_timeout_test.c create mode 100644 test/regression/web_test/netx_web_non_block_basic_test.c create mode 100644 test/regression/web_test/netx_web_non_block_reconnect_test.c create mode 100644 test/regression/web_test/netx_web_one_session_test.c create mode 100644 test/regression/web_test/netx_web_packet_allocate_test.c create mode 100644 test/regression/web_test/netx_web_post_basic_test.c create mode 100644 test/regression/web_test/netx_web_post_long_message_test.c create mode 100644 test/regression/web_test/netx_web_put_basic_test.c create mode 100644 test/regression/web_test/netx_web_request_in_multiple_packets_test.c create mode 100644 test/regression/web_test/netx_web_response_in_multiple_packets_test.c create mode 100644 test/regression/web_test/netx_web_secure_connect_fail_test.c create mode 100644 test/regression/web_test/netx_web_secure_reconnect_test.c create mode 100644 test/regression/web_test/netx_web_server_chunked_content_process_test.c create mode 100644 test/regression/web_test/netx_web_server_content_process_test.c create mode 100644 test/regression/web_test/netx_web_server_type_get_extended_test.c create mode 100644 test/regression/web_test/netx_web_status_400_test.c create mode 100644 test/regression/web_test/netx_web_status_404_test.c create mode 100644 test/regression/web_test/netx_web_status_501_test.c create mode 100644 test/regression/web_test/netx_web_status_code_test.c create mode 100644 test/regression/web_test/netx_web_tcpserver_rst_test.c create mode 100644 test/regression/web_test/netx_web_tcpserver_tls_fail_rst_test.c create mode 100644 test/regression/web_test/netx_web_tcpserver_two_listen_test.c create mode 100644 test/regression/web_test/test_ca_cert.c create mode 100644 test/regression/web_test/test_device_cert.c create mode 100644 test/regression/web_test/test_utility.h create mode 100644 test/regression/websocket_test/netx_websocket_16_bit_payload_length_test.c create mode 100644 test/regression/websocket_test/netx_websocket_common_process.c create mode 100644 test/regression/websocket_test/netx_websocket_connect_test.c create mode 100644 test/regression/websocket_test/netx_websocket_delete_test.c create mode 100644 test/regression/websocket_test/netx_websocket_disconnect_test.c create mode 100644 test/regression/websocket_test/netx_websocket_fin_test.c create mode 100644 test/regression/websocket_test/netx_websocket_mask_test.c create mode 100644 test/regression/websocket_test/netx_websocket_multi_instance_test.c create mode 100644 test/regression/websocket_test/netx_websocket_non_block_test.c create mode 100644 test/regression/websocket_test/netx_websocket_one_frame_in_packets_test.c create mode 100644 test/regression/websocket_test/netx_websocket_one_packet_with_multi_frames_test.c create mode 100644 test/regression/websocket_test/netx_websocket_opcode_test.c create mode 100644 test/regression/websocket_test/netx_websocket_send_chain_packets_test.c diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..9b4fdaf1 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,13 @@ +{ + "image": "ghcr.io/tiejunms/azure_rtos_docker", + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-vscode.cpptools", + "ms-vscode.cmake-tools" + ], + + "remoteUser": "vscode", + + "runArgs": [ "--cap-add=NET_ADMIN"] +} \ No newline at end of file diff --git a/.github/workflows/regression_test.yml b/.github/workflows/regression_test.yml new file mode 100644 index 00000000..0e19b390 --- /dev/null +++ b/.github/workflows/regression_test.yml @@ -0,0 +1,43 @@ +# This is a basic workflow that is manually triggered + +name: regression_test + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + workflow_dispatch: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + nxd: + permissions: + contents: read + issues: read + checks: write + pull-requests: write + pages: write + id-token: write + uses: azure-rtos/threadx/.github/workflows/regression_template.yml@master + with: + build_script: ./scripts/build_nxd.sh + test_script: ./scripts/test_nxd.sh + cmake_path: ./test/cmake/netxduo + result_affix: NetXDuo + skip_deploy: true + deploy: + permissions: + contents: read + issues: read + checks: write + pull-requests: write + pages: write + id-token: write + needs: [nxd] + uses: azure-rtos/threadx/.github/workflows/regression_template.yml@master + with: + skip_test: true + deploy_list: "NetXDuo" \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9c33dc7f..2d01435e 100755 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .vscode/ _deps/ build/ +coverage_report/ CMakeFiles/ CMakeScripts/ CMakeLists.txt.user @@ -11,4 +12,5 @@ cmake_install.cmake install_manifest.txt compile_commands.json CTestTestfile.cmake +.run.sh diff --git a/addons/azure_iot/nx_azure_iot.c b/addons/azure_iot/nx_azure_iot.c index eef8bf8a..b9df5a98 100644 --- a/addons/azure_iot/nx_azure_iot.c +++ b/addons/azure_iot/nx_azure_iot.c @@ -420,6 +420,7 @@ UINT status; /* Do nothing if the client is not connected. */ if (client_ptr -> nxd_mqtt_client_state != NXD_MQTT_CLIENT_STATE_CONNECTED) { + tx_mutex_put(client_ptr -> nxd_mqtt_client_mutex_ptr); LogError(LogLiteralArgs("MQTT NOT CONNECTED")); return(NX_AZURE_IOT_DISCONNECTED); } diff --git a/addons/azure_iot/nx_azure_iot_adu_agent.c b/addons/azure_iot/nx_azure_iot_adu_agent.c index ed80ea63..47d8750a 100644 --- a/addons/azure_iot/nx_azure_iot_adu_agent.c +++ b/addons/azure_iot/nx_azure_iot_adu_agent.c @@ -1745,8 +1745,8 @@ static UINT nx_azure_iot_adu_agent_jws_split(UCHAR *jws, UINT jws_length, UCHAR **signature, UINT *signature_length) { -UCHAR *dot1_pointer; -UCHAR *dot2_pointer; +UCHAR *dot1_pointer = jws; +UCHAR *dot2_pointer = jws; UINT dot_count = 0; UINT i = 0; diff --git a/samples/demo_netxduo_snmp.c b/samples/demo_netxduo_snmp.c index ede9b484..85f580cb 100644 --- a/samples/demo_netxduo_snmp.c +++ b/samples/demo_netxduo_snmp.c @@ -453,6 +453,17 @@ UINT status; if (mib2_mib[i].object_set_callback) { + /* If the object data type is string. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_OCTET_STRING) + { + + /* Check the string length of the object value. */ + if (object_data -> nx_snmp_object_octet_string_size > mib2_mib[i].length) + { + return(NX_SNMP_ERROR_TOOBIG); + } + } + /* Yes, call the set function. */ status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); } diff --git a/samples/demo_snmp_helper.h b/samples/demo_snmp_helper.h index a9a14e08..73279c7c 100644 --- a/samples/demo_snmp_helper.h +++ b/samples/demo_snmp_helper.h @@ -46,7 +46,7 @@ ULONG ipDefaultTTL = NX_IP_TIME_TO_LIVE; /* ipDefault underlying application driver, but for now simple defaults are used. */ ULONG ifLastChange = 2048; /* ifLastChange:TimeTicks RO */ ULONG ifInOctets = 155; /* ifInOctets:Counter RO */ -ULONG ifInUcastPkts = 0; /* ifInUcastPkts:Counter RO */ +ULONG64 ifInUcastPkts = 0; /* ifInUcastPkts:Counter RO */ UCHAR ifDescr[] = "NetX Physical Interface"; /* ifDescr:OctetString RO */ /* Define the MIB-2 "address translation" group, assuming one address translation. */ @@ -62,31 +62,31 @@ MIB_ENTRY mib2_mib[] = { /* OBJECT ID OBJECT VARIABLE GET ROUTINE/ GET_OCTET_ROUTINE SET ROUTINE LENGTH */ - {(UCHAR *) "1.3.6.1.2.1.1.1.0", sysDescr, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, 0}, - {(UCHAR *) "1.3.6.1.2.1.1.2.0", sysObjectID, nx_snmp_object_id_get, NX_NULL, NX_NULL, 0}, - {(UCHAR *) "1.3.6.1.2.1.1.3.0", &sysUpTime, nx_snmp_object_timetics_get, NX_NULL, NX_NULL, 0}, - {(UCHAR *) "1.3.6.1.2.1.1.4.0", sysContact, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, 0}, - {(UCHAR *) "1.3.6.1.2.1.1.5.0", sysName, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, 0}, - {(UCHAR *) "1.3.6.1.2.1.1.6.0", sysLocation, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, 0}, - {(UCHAR *) "1.3.6.1.2.1.1.7.0", &sysServices, nx_snmp_object_integer_get, NX_NULL, NX_NULL, 0}, + {(UCHAR *) "1.3.6.1.2.1.1.1.0", sysDescr, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, sizeof(sysDescr)}, + {(UCHAR *) "1.3.6.1.2.1.1.2.0", sysObjectID, nx_snmp_object_id_get, NX_NULL, NX_NULL, sizeof(sysObjectID)}, + {(UCHAR *) "1.3.6.1.2.1.1.3.0", &sysUpTime, nx_snmp_object_timetics_get, NX_NULL, NX_NULL, sizeof(sysUpTime)}, + {(UCHAR *) "1.3.6.1.2.1.1.4.0", sysContact, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, sizeof(sysContact)}, + {(UCHAR *) "1.3.6.1.2.1.1.5.0", sysName, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, sizeof(sysName)}, + {(UCHAR *) "1.3.6.1.2.1.1.6.0", sysLocation, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, sizeof(sysLocation)}, + {(UCHAR *) "1.3.6.1.2.1.1.7.0", &sysServices, nx_snmp_object_integer_get, NX_NULL, NX_NULL, sizeof(sysServices)}, - {(UCHAR *) "1.3.6.1.2.1.3.1.1.3.0", &atNetworkAddress, nx_snmp_object_ip_address_get, NX_NULL, nx_snmp_object_ip_address_set, 0}, + {(UCHAR *) "1.3.6.1.2.1.3.1.1.3.0", &atNetworkAddress, nx_snmp_object_ip_address_get, NX_NULL, nx_snmp_object_ip_address_set, sizeof(atNetworkAddress)}, #ifdef FEATURE_NX_IPV6 /* Either GET method should work. IPv6 addresses are handled as octet strings and accept any IPv6 address format e.g. addresses with '::'s are accepted as is. */ - {(UCHAR *) "1.3.6.1.2.1.3.1.1.3.1", &atIPv6NetworkAddress, nx_snmp_object_ipv6_address_get, NX_NULL, nx_snmp_object_ipv6_address_set, 0}, - {(UCHAR *) "1.3.6.1.2.1.3.1.1.3.2", &atIPv6NetworkAddress, NX_NULL, nx_snmp_object_octet_string_get, nx_snmp_object_octet_string_set, 0}, + {(UCHAR *) "1.3.6.1.2.1.3.1.1.3.1", &atIPv6NetworkAddress, nx_snmp_object_ipv6_address_get, NX_NULL, nx_snmp_object_ipv6_address_set, sizeof(atIPv6NetworkAddress)}, + {(UCHAR *) "1.3.6.1.2.1.3.1.1.3.2", &atIPv6NetworkAddress, NX_NULL, nx_snmp_object_octet_string_get, nx_snmp_object_octet_string_set, sizeof(atIPv6NetworkAddress)}, #endif - {(UCHAR *) "1.3.6.1.2.1.2.2.1.2.0", ifDescr, nx_snmp_object_string_get, NX_NULL, NX_NULL, 0}, - {(UCHAR *) "1.3.6.1.2.1.3.1.1.2.0", &atPhysAddress, NX_NULL, nx_snmp_object_octet_string_get, nx_snmp_object_octet_string_set, 0}, - {(UCHAR *) "1.3.6.1.2.1.2.2.1.9.0", &ifLastChange, nx_snmp_object_timetics_get, NX_NULL, nx_snmp_object_timetics_set, 0}, - {(UCHAR *) "1.3.6.1.2.1.2.2.1.10.0", &ifInOctets, nx_snmp_object_counter_get, NX_NULL, nx_snmp_object_counter_set, 0}, - {(UCHAR *) "1.3.6.1.2.1.2.2.1.11.0", &ifInUcastPkts, nx_snmp_object_counter64_get, NX_NULL, nx_snmp_object_counter64_set, 0}, + {(UCHAR *) "1.3.6.1.2.1.2.2.1.2.0", ifDescr, nx_snmp_object_string_get, NX_NULL, NX_NULL, sizeof(ifDescr)}, + {(UCHAR *) "1.3.6.1.2.1.3.1.1.2.0", &atPhysAddress, NX_NULL, nx_snmp_object_octet_string_get, nx_snmp_object_octet_string_set, sizeof(atPhysAddress)}, + {(UCHAR *) "1.3.6.1.2.1.2.2.1.9.0", &ifLastChange, nx_snmp_object_timetics_get, NX_NULL, nx_snmp_object_timetics_set, sizeof(ifLastChange)}, + {(UCHAR *) "1.3.6.1.2.1.2.2.1.10.0", &ifInOctets, nx_snmp_object_counter_get, NX_NULL, nx_snmp_object_counter_set, sizeof(ifInOctets)}, + {(UCHAR *) "1.3.6.1.2.1.2.2.1.11.0", &ifInUcastPkts, nx_snmp_object_counter64_get, NX_NULL, nx_snmp_object_counter64_set, sizeof(ifInUcastPkts)}, - {(UCHAR *) "1.3.6.1.2.1.4.1.0", &ipForwarding, nx_snmp_object_integer_get, NX_NULL, nx_snmp_object_integer_set, 0}, - {(UCHAR *) "1.3.6.1.2.1.4.2.0", &ipDefaultTTL, nx_snmp_object_integer_get, NX_NULL, NX_NULL, 0}, + {(UCHAR *) "1.3.6.1.2.1.4.1.0", &ipForwarding, nx_snmp_object_integer_get, NX_NULL, nx_snmp_object_integer_set, sizeof(ipForwarding)}, + {(UCHAR *) "1.3.6.1.2.1.4.2.0", &ipDefaultTTL, nx_snmp_object_integer_get, NX_NULL, NX_NULL, sizeof(ipDefaultTTL)}, - {(UCHAR *) "1.3.6.1.7", (UCHAR *) "1.3.6.1.7", nx_snmp_object_end_of_mib, NX_NULL, NX_NULL, 0}, + {(UCHAR *) "1.3.6.1.7", (UCHAR *) "1.3.6.1.7", nx_snmp_object_end_of_mib, NX_NULL, NX_NULL, sizeof("1.3.6.1.7") - 1}, {NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, 0} }; diff --git a/scripts/build_nxd.sh b/scripts/build_nxd.sh new file mode 100755 index 00000000..d9948699 --- /dev/null +++ b/scripts/build_nxd.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +$(dirname `realpath $0`)/../test/cmake/netxduo/run.sh build default_build_coverage v4_full_build v6_full_build diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 00000000..25da84ce --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# + +# Remove large folder +rm -rf /opt/hostedtoolcache + +# Install necessary softwares for Ubuntu. + +sudo dpkg --add-architecture i386 +sudo apt-get update +sudo apt-get install -y \ + gcc-multilib \ + git \ + g++ \ + python3-pip \ + ninja-build \ + unifdef \ + p7zip-full \ + tofrodos \ + dos2unix \ + gawk \ + libssl-dev:i386 \ + software-properties-common + +wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add - +CODENAME=$(lsb_release -c | cut -f2 -d':' | sed 's/\t//') +apt-add-repository "deb https://apt.kitware.com/ubuntu/ $CODENAME main" + +python3 -m pip install --upgrade pip +pip3 install gcovr==4.1 +pip install --upgrade cmake + diff --git a/scripts/test_nxd.sh b/scripts/test_nxd.sh new file mode 100755 index 00000000..aad1f8bd --- /dev/null +++ b/scripts/test_nxd.sh @@ -0,0 +1,3 @@ +#! /bin/bash + +CTEST_PARALLEL_LEVEL=4 $(dirname `realpath $0`)/../test/cmake/netxduo/run.sh test default_build_coverage v4_full_build diff --git a/test/cmake/.gitignore b/test/cmake/.gitignore new file mode 100644 index 00000000..58bc3cea --- /dev/null +++ b/test/cmake/.gitignore @@ -0,0 +1,2 @@ +threadx +filex \ No newline at end of file diff --git a/test/cmake/libs/CMakeLists.txt b/test/cmake/libs/CMakeLists.txt new file mode 100644 index 00000000..4552fcbb --- /dev/null +++ b/test/cmake/libs/CMakeLists.txt @@ -0,0 +1,33 @@ +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) + +project(libs LANGUAGES C) + +if($ENV{ENABLE_64}) + message(STATUS "Building for 64bit") +else() + add_compile_options(-m32) + add_link_options(-m32) + message(STATUS "Building for 32bit") +endif() +message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.") + +set(TX_USER_FILE ${CMAKE_CURRENT_SOURCE_DIR}/tx_user.h) +get_filename_component( + externals ${CMAKE_CURRENT_SOURCE_DIR}/../.. ABSOLUTE) +add_subdirectory(${externals}/threadx threadx) +add_subdirectory(${externals}/filex filex) +target_compile_options(threadx PRIVATE -DTX_ENABLE_EVENT_TRACE) +if(NOT DEFINED ENV{ENABLE_IDLE}) + target_compile_options(threadx PRIVATE -DTX_LINUX_NO_IDLE_ENABLE) +endif() + +foreach(lib threadx filex) + get_target_property(dirs ${lib} INCLUDE_DIRECTORIES) + execute_process(COMMAND mkdir -p ${CMAKE_BINARY_DIR}/inc) + foreach(dir ${dirs}) + file(GLOB header_files ${dir}/*.h) + foreach(header_file ${header_files}) + execute_process(COMMAND ln -sf ${header_file} ${CMAKE_BINARY_DIR}/inc) + endforeach() + endforeach() +endforeach() \ No newline at end of file diff --git a/test/cmake/libs/tx_user.h b/test/cmake/libs/tx_user.h new file mode 100644 index 00000000..99dcb050 --- /dev/null +++ b/test/cmake/libs/tx_user.h @@ -0,0 +1,56 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** User Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* tx_user.h PORTABLE C */ +/* 6.0 */ +/* */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains user defines for configuring ThreadX in specific */ +/* ways. This file will have an effect only if the application and */ +/* ThreadX library are built with TX_INCLUDE_USER_DEFINE_FILE defined. */ +/* Note that all the defines in this file may also be made on the */ +/* command line when building ThreadX library and application objects. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 William E. Lamie Initial Version 6.0 */ +/* */ +/**************************************************************************/ + +#ifndef TX_USER_H +#define TX_USER_H + +#define TX_THREAD_USER_EXTENSION int bsd_errno; + +#endif \ No newline at end of file diff --git a/test/cmake/netxduo/CMakeLists.txt b/test/cmake/netxduo/CMakeLists.txt new file mode 100644 index 00000000..6ecaa22f --- /dev/null +++ b/test/cmake/netxduo/CMakeLists.txt @@ -0,0 +1,565 @@ +cmake_minimum_required(VERSION 3.13 FATAL_ERROR) +cmake_policy(SET CMP0054 NEW) +cmake_policy(SET CMP0057 NEW) +cmake_policy(SET CMP0077 NEW) + +project(netxduo_test LANGUAGES C) + +# Set build configurations +set(BUILD_CONFIGURATIONS + default_build_coverage + dhcp_default_build_coverage + dns_default_build_coverage + v4_build + v4_dns_cache_build + v4_no_checksum_build + v4_physical_48_build + v4_small_build + v4_packet_pad_build + v4_full_build + v4_no_frag_build + v4_no_check_build + v4_no_reset_disconn_build + v4_dual_pool_build + v4_no_chain_build + v4_link_cap_build + v4_address_check_build + v4_ipsec_build + v4_ipsec_dual_pool_build + v4_ipsec_packet_pad_build + v4_ipsec_small_build + v4_ipsec_full_build + v4_ipsec_no_frag_build + v4_ipsec_no_chain_build + v4_ipsec_no_check_build + v4_ipsec_no_reset_disconn_build + v4_ipsec_link_cap_build + v6_build + v6_only_build + v6_only_link_cap_build + v6_no_checksum_build + v6_dual_pool_build + v6_packet_pad_build + v6_physical_48_build + v6_small_nd_cache_build + v6_small_build + v6_full_build + v6_no_frag_build + v6_pmtu_no_frag_build + v6_no_chain_build + v6_no_dad_build + v6_no_check_build + v6_no_icmpv6_error_build + v6_no_reset_disconn_build + v6_link_cap_build + v6_address_change_build + v6_multicast_build + v6_no_rs_build + v6_ipsec_build + v6_ipsec_dual_pool_build + v6_ipsec_packet_pad_build + v6_ipsec_tahi_build + v6_ipsec_small_build + v6_ipsec_full_build + v6_ipsec_full_tahi_build + v6_ipsec_no_frag_build + v6_ipsec_no_chain_build + v6_ipsec_no_dad_build + v6_ipsec_no_check_build + v6_ipsec_no_check_tahi_build + v6_ipsec_no_icmpv6_error_build + v6_ipsec_no_reset_disconn_build + v6_ipsec_no_reset_disconn_tahi_build + v6_ipsec_link_cap_build + v6_dhcp_tahi_build + v6_bsd_raw_build + v6_full_secure_build + optimize_build) +set(CMAKE_CONFIGURATION_TYPES + ${BUILD_CONFIGURATIONS} + CACHE STRING "list of supported configuration types" FORCE) +set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + ${CMAKE_CONFIGURATION_TYPES}) +list(GET CMAKE_CONFIGURATION_TYPES 0 BUILD_TYPE) +if((NOT CMAKE_BUILD_TYPE) OR (NOT ("${CMAKE_BUILD_TYPE}" IN_LIST + CMAKE_CONFIGURATION_TYPES))) + set(CMAKE_BUILD_TYPE + "${BUILD_TYPE}" + CACHE STRING "Build Type of the project" FORCE) +endif() + +if(NOT PRODUCT) + set(PRODUCT netxduo) +endif() + +message(STATUS "Build for ${PRODUCT}") +message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") +message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}.") + +set(IPV4 -DNX_DISABLE_IPV6) +set(DISABLE_RX_CHECKSUM + -DNX_DISABLE_ICMPV4_RX_CHECKSUM -DNX_DISABLE_ICMPV6_RX_CHECKSUM + -DNX_DISABLE_IP_RX_CHECKSUM -DNX_DISABLE_TCP_RX_CHECKSUM + -DNX_DISABLE_UDP_RX_CHECKSUM) +set(DISABLE_TX_CHECKSUM + -DNX_DISABLE_ICMPV4_TX_CHECKSUM -DNX_DISABLE_ICMPV6_TX_CHECKSUM + -DNX_DISABLE_IP_TX_CHECKSUM -DNX_DISABLE_TCP_TX_CHECKSUM + -DNX_DISABLE_UDP_TX_CHECKSUM) +set(PHY_HEADER -DNX_PHYSICAL_HEADER=48) +set(NO_INFO + -DNX_DISABLE_ARP_INFO + -DNX_DISABLE_IP_INFO + -DNX_DISABLE_ICMP_INFO + -DNX_DISABLE_PACKET_INFO + -DNX_DISABLE_RARP_INFO + -DNX_DISABLE_TCP_INFO + -DNX_DISABLE_UDP_INFO) +set(NO_FRAG -DNX_DISABLE_FRAGMENTATION) +set(NO_CHECK -DTX_DISABLE_ERROR_CHECKING -DNX_DISABLE_ERROR_CHECKING) +set(NO_RESET_DISCONNECT -DNX_DISABLE_RESET_DISCONNECT) +set(NO_AUTO_ARP_ENTRY -DNX_DISABLE_ARP_AUTO_ENTRY) +set(IMME_ACK -DNX_TCP_ACK_EVERY_N_PACKETS=1) +set(NO_LOOPBACK -DNX_DISABLE_LOOPBACK_INTERFACE) +set(NO_RX_SIZE_CHECK -DNX_DISABLE_RX_SIZE_CHECKING) +set(NO_IGMPV2 -DNX_DISABLE_IGMPV2) +set(TCP_KEEPALIVE -DNX_ENABLE_TCP_KEEPALIVE -DNX_TCP_KEEPALIVE_INITIAL=60 + -DTCP_KEEPALIVE_RETRY -DNX_TCP_KEEPALIVE_RETRY=10) +set(TCP_WINDOW -DNX_ENABLE_TCP_WINDOW_SCALING) +set(IP_STATIC_ROUTING -DNX_ENABLE_IP_STATIC_ROUTING) +set(PACKET_ALIGNMENT -DNX_PACKET_ALIGNMENT=64) +set(MULTI_INTERFACE -DNX_MAX_PHYSICAL_INTERFACES=4 + -DNX_DHCP_CLIENT_MAX_RECORDS=2) +set(IMME_FRAG_ASSEMBLY -DNX_FRAGMENT_IMMEDIATE_ASSEMBLY) +set(MSS_CHECK -DNX_ENABLE_TCP_MSS_CHECK -DNX_TCP_MSS_MINIMUM=32) +set(TCP_QUEUE_NOTIFY -DNX_ENABLE_TCP_QUEUE_DEPTH_UPDATE_NOTIFY) +set(ARP_EXPIRATION_RATE -DNX_ARP_EXPIRATION_RATE=5) +set(NAT -DNX_NAT_ENABLE) +set(IP_PACKET_FILTER -DNX_ENABLE_IP_PACKET_FILTER) +set(TRACE -DTX_ENABLE_EVENT_TRACE) +set(BSD + -D__suseconds_t_defined + -D_STRUCT_TIMEVAL + -D_SYS_SELECT_H + -DNX_ENABLE_EXTENDED_NOTIFY_SUPPORT + -DNX_BSD_SOCKET_QUEUE_MAX=20 + -DNX_BSD_ENABLE + -DNX_IPV6_NEIGHBOR_CACHE_SIZE=32 + -DNX_IPV6_DESTINATION_TABLE_SIZE=32 + -DNX_BSD_ENABLE_DNS + -DNX_DNS_ENABLE_EXTENDED_RR_TYPES) +set(TAHI -DNX_TAHI_ENABLE) +set(IPV6 -DFEATURE_NX_IPV6) +set(IPV6_PMTU_DISCOVERY -DNX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +set(IPSEC -DNX_IPSEC_ENABLE -DNX_ENABLE_CCS -DNX_IPSEC_ANTI_REPLAY_ENABLE + -DNX_IPSEC_ESN_ENABLE -DNX_IPSEC_ENBALE_DEBUG_LOG) +set(IPSEC_TAHI -DNX_IPSEC_ENABLE) +set(NO_DAD -DNX_DISABLE_IPV6_DAD) +set(NO_ICMPV6_ERROR -DNX_DISABLE_ICMPV6_ERROR_MESSAGE) +set(NO_CHAIN -DNX_DISABLE_PACKET_CHAIN -DNX_DISABLE_FRAGMENTATION) +set(LINK_CAP -DNX_ENABLE_INTERFACE_CAPABILITY) +set(ADDRESS_CHANGE_NOTIFY -DNX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY) +set(ADDRESS_CHECK -DNX_ENABLE_SOURCE_ADDRESS_CHECK + -DNX_ENABLE_ICMP_ADDRESS_CHECK) +set(MULTICAST -DNX_ENABLE_IPV6_MULTICAST) +set(LOW_WATERMARK -DNX_ENABLE_LOW_WATERMARK) +if(PRODUCT STREQUAL netxduo) + set(BSD_RAW ${BSD} -DNX_BSD_RAW_SUPPORT -DNX_ENABLE_IP_RAW_PACKET_FILTER + -DNX_BSD_RAW_PPPOE_SUPPORT -DNX_ENABLE_IP_RAW_PACKET_FILTER) + list(REMOVE_ITEM BSD_RAW -DNX_BSD_RAW_PPPOE_SUPPORT) + set(RAW_FILTER -DNX_ENABLE_IP_RAW_PACKET_FILTER) + set(RAW_ALL_STACK -DNX_ENABLE_IP_RAW_PACKET_ALL_STACK) +endif() +set(NO_REDIRECT_PROCESS -DNX_DISABLE_ICMPV6_REDIRECT_PROCESS) +set(NO_RA_PROCESS -DNX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) +set(NO_RS -DNX_DISABLE_ICMPV6_ROUTER_SOLICITATION) +set(STATELESS_AC -DNX_IPV6_STATELESS_AUTOCONFIG_CONTROL) +set(NO_PURGE_UNUSED_CACHE -DNX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES) +set(PACKET_PAD -DNX_PACKET_HEADER_PAD=4) +set(MSS_CHECK -DNX_ENABLE_TCP_MSS_CHECK -DNX_TCP_MSS_MINIMUM=32) +set(DUAL_POOL -DNX_ENABLE_DUAL_PACKET_POOL) +set(DHCPV6_TAHI -DNX_DHCPV6_TAHI_ENABLE) +set(MULTIPART -DNX_HTTP_MULTIPART_ENABLE) +set(PACKET_DEBUG -DNX_ENABLE_PACKET_DEBUG_INFO) +set(TCP_RX_LIMIT -DNX_TCP_MAX_OUT_OF_ORDER_PACKETS=8) +set(TELNET_MAX_CLIENTS -DNX_TELNET_MAX_CLIENTS=2) +set(TELNET_ACTIVITY_TIMEOUT -DNX_TELNET_ACTIVITY_TIMEOUT=10) +set(TELNET_TIMEOUT_PERIOD -DNX_TELNET_TIMEOUT_PERIOD=2) +set(CREATE_TELNET_PACKET_POOL -DNX_TELNET_SERVER_USER_CREATE_PACKET_POOL) +set(LCP_PROTOCOL_RETRIES -DNX_PPP_MAX_LCP_PROTOCOL_RETRIES=5) +set(IPCP_PROTOCOL_RETRIES -DNX_PPP_MAX_IPCP_PROTOCOL_RETRIES=5) +set(PREFIX_LIMIT -DNX_IPV6_PREFIX_LIST_TABLE_SIZE=4) +set(LARGE_DEST_TABLE -DNX_IPV6_DESTINATION_TABLE_SIZE=32) +set(ND_CACHE_LIMIT -DNX_IPV6_NEIGHBOR_CACHE_SIZE=8) +set(TX_RX_INTERFACE_CAPABILITY + -DNX_INTERFACE_CAPABILITY=NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM|NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM|NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM|NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM|NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM|NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM|NX_INTERFACE_CAPABILITY_IPV4_RX_CHECKSUM|NX_INTERFACE_CAPABILITY_TCP_RX_CHECKSUM|NX_INTERFACE_CAPABILITY_UDP_RX_CHECKSUM|NX_INTERFACE_CAPABILITY_ICMPV4_RX_CHECKSUM|NX_INTERFACE_CAPABILITY_ICMPV6_RX_CHECKSUM|NX_INTERFACE_CAPABILITY_IGMP_RX_CHECKSUM +) +set(RX_INTERFACE_CAPABILITY + -DNX_INTERFACE_CAPABILITY=NX_INTERFACE_CAPABILITY_IPV4_RX_CHECKSUM|NX_INTERFACE_CAPABILITY_TCP_RX_CHECKSUM|NX_INTERFACE_CAPABILITY_UDP_RX_CHECKSUM|NX_INTERFACE_CAPABILITY_ICMPV4_RX_CHECKSUM|NX_INTERFACE_CAPABILITY_ICMPV6_RX_CHECKSUM|NX_INTERFACE_CAPABILITY_IGMP_RX_CHECKSUM +) +set(NO_INTERFACE_CAPABILITY -DNX_INTERFACE_CAPABILITY=0) +set(DHCP_ARP_PROBE -DNX_DHCP_CLIENT_SEND_ARP_PROBE) +set(NO_ASSERT -DNX_DISABLE_ASSERT) +set(NO_IPV4 -DNX_DISABLE_IPV4) +set(MDNS_IPV6 -DNX_MDNS_ENABLE_IPV6 -DFEATURE_NX_IPV6 + -DNX_ENABLE_IPV6_MULTICAST -DNX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY) +set(MDNS_NO_CLIENT -DNX_MDNS_DISABLE_CLIENT) +set(MDNS_NO_SERVER -DNX_MDNS_DISABLE_SERVER) +set(PPPOE -DNX_PPP_PPPOE_ENABLE -DNX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE + -DNX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE) +set(PPPOE_CONTROL -DNX_PPPOE_SERVER_SESSION_CONTROL_ENABLE) +set(HTTP_DIGEST -DNX_HTTP_DIGEST_ENABLE) +set(DHCP_RESTORE -DNX_DHCP_CLIENT_RESTORE_STATE) +set(DNS_CACHE -DNX_DNS_CACHE_ENABLE) +set(TCPIP_OFFLOAD -DNX_ENABLE_TCPIP_OFFLOAD ${LINK_CAP}) +set(ARP -DNX_ARP_DEFEND_BY_REPLY) +set(HTTP_PROXY -DNX_ENABLE_HTTP_PROXY) +set(RAND_ID -DNX_ENABLE_IP_ID_RANDOMIZATION) +set(PPP_COMPRESSION -DNX_PPP_COMPRESSION_ENABLE) + +set(v4_build ${IPV4} ${PACKET_DEBUG}) +set(v4_dns_cache_build ${IPV4} ${DNS_CACHE}) +set(v4_no_checksum_build ${IPV4} ${DISABLE_TX_CHECKSUM} ${DISABLE_RX_CHECKSUM}) +set(v4_physical_48_build ${IPV4} ${PHY_HEADER} ${MDNS_NO_CLIENT} ${PPPOE}) +set(v4_small_build + ${IPV4} + ${NO_INFO} + ${NO_FRAG} + ${NO_CHECK} + ${NO_RESET_DISCONNECT} + ${NO_AUTO_ARP_ENTRY} + ${IMME_ACK} + ${NO_LOOPBACK} + ${NO_RX_SIZE_CHECK} + ${NO_IGMPV2} + ${RAND_ID}) +set(v4_packet_pad_build ${IPV4} ${PACKET_ALIGNMENT}) +set(v4_full_build + ${IPV4} + ${TCP_KEEPALIVE} + ${TCP_WINDOW} + ${IP_STATIC_ROUTING} + ${BSD} + ${MULTI_INTERFACE} + ${IMME_FRAG_ASSEMBLY} + ${MSS_CHECK} + ${TCP_QUEUE_NOTIFY} + ${RAW_FILTER} + ${ARP_EXPIRATION_RATE} + ${MULTIPART} + ${NAT} + ${PACKET_DEBUG} + ${DUAL_POOL} + ${IP_PACKET_FILTER} + ${CREATE_TELNET_PACKET_POOL} + ${TELNET_MAX_CLIENTS} + ${TELNET_ACTIVITY_TIMEOUT} + ${TELNET_TIMEOUT_PERIOD} + ${LCP_PROTOCOL_RETRIES} + ${IPCP_PROTOCOL_RETRIES} + ${DHCP_ARP_PROBE} + ${TRACE} + ${DHCP_RESTORE} + ${DNS_CACHE} + ${ARP} + ${HTTP_PROXY} + ${PPP_COMPRESSION}) +set(v4_no_frag_build ${IPV4} ${NO_FRAG}) +set(v4_no_check_build ${IPV4} ${NO_CHECK}) +set(v4_no_reset_disconn_build ${IPV4} ${NO_RESET_DISCONNECT}) + +# netxduo only +set(v4_dual_pool_build ${IPV4} ${DUAL_POOL}) +set(v4_no_chain_build ${IPV4} ${NO_CHAIN} ${MDNS_NO_SERVER}) +set(v4_link_cap_build ${IPV4} ${LINK_CAP} ${RX_INTERFACE_CAPABILITY} + ${MULTI_INTERFACE} ${TCPIP_OFFLOAD}) +set(v4_address_check_build ${IPV4} ${ADDRESS_CHECK}) +set(v4_ipsec_build ${IPV4} ${IPSEC} ${PACKET_DEBUG}) +set(v4_ipsec_dual_pool_build ${IPV4} ${IPSEC} ${DUAL_POOL}) +set(v4_ipsec_packet_pad_build ${IPV4} ${IPSEC} ${PACKET_PAD}) +set(v4_ipsec_small_build + ${IPV4} + ${IPSEC} + ${NO_INFO} + ${NO_FRAG} + ${NO_CHECK} + ${NO_RESET_DISCONNECT} + ${MDNS_NO_CLIENT}) +set(v4_ipsec_full_build + ${IPV4} + ${IPSEC} + ${TCP_KEEPALIVE} + ${TCP_KEEPALIVE_INITIAL} + ${TCP_KEEPALIVE_RETRY} + ${TCP_KEEPALIVE_RETRIES} + ${TCP_WINDOW} + ${IP_STATIC_ROUTING} + ${BSD} + ${MULTI_INTERFACE} + ${MULTIPART} + ${NAT} + ${PACKET_DEBUG} + ${DUAL_POOL} + ${IP_PACKET_FILTER} + ${DHCP_ARP_PROBE}) +set(v4_ipsec_no_frag_build ${IPV4} ${IPSEC} ${NO_FRAG}) +set(v4_ipsec_no_chain_build ${IPV4} ${IPSEC} ${NO_CHAIN}) +set(v4_ipsec_no_check_build ${IPV4} ${IPSEC} ${NO_CHECK} ${BSD} + ${MULTI_INTERFACE} ${NAT}) +set(v4_ipsec_no_reset_disconn_build ${IPV4} ${IPSEC} ${NO_RESET_DISCONNECT} + ${MDNS_NO_SERVER}) +set(v4_ipsec_link_cap_build ${IPV4} ${IPSEC} ${LINK_CAP}) +set(v6_build ${IPV6}) +set(v6_only_build ${IPV6} ${NO_IPV4} ${TRACE} ${MDNS_NO_CLIENT}) +set(v6_only_link_cap_build ${IPV6} ${NO_IPV4} ${LINK_CAP}) +set(v6_no_checksum_build ${IPV6} ${DISABLE_TX_CHECKSUM} ${DISABLE_RX_CHECKSUM}) +set(v6_dual_pool_build ${IPV6} ${DUAL_POOL}) +set(v6_packet_pad_build ${IPV6} ${PACKET_PAD}) +set(v6_physical_48_build ${IPV6} ${PHY_HEADER} ${MDNS_NO_SERVER} ${PPPOE} ${PPPOE_CONTROL}) +set(v6_small_nd_cache_build ${IPV6} ${MULTI_INTERFACE} ${ND_CACHE_LIMIT} + ${NO_PURGE_UNUSED_CACHE} ${LARGE_DEST_TABLE}) +set(v6_small_build + ${IPV6} + ${NO_INFO} + ${NO_FRAG} + ${NO_DAD} + ${NO_CHECK} + ${NO_ICMPV6_ERROR} + ${NO_RESET_DISCONNECT} + ${NO_REDIRECT_PROCESS} + ${NO_RA_PROCESS} + ${NO_RS} + ${NO_PURGE_UNUSED_CACHE} + ${IMME_ACK} + ${NO_LOOPBACK} + ${NO_RX_SIZE_CHECK} + ${PACKET_ALIGNMENT} + ${PREFIX_LIMIT} + ${MDNS_NO_SERVER} + ${RAND_ID}) +set(v6_full_build + ${IPV6} + ${IPV6_PMTU_DISCOVERY} + ${TCP_KEEPALIVE} + ${TCP_KEEPALIVE_INITIAL} + ${TCP_KEEPALIVE_RETRY} + ${TCP_KEEPALIVE_RETRIES} + ${TCP_WINDOW} + ${IP_STATIC_ROUTING} + ${TAHI} + ${BSD} + ${MULTI_INTERFACE} + ${STATELESS_AC} + ${IMME_FRAG_ASSEMBLY} + ${MSS_CHECK} + ${TCP_QUEUE_NOTIFY} + ${RAW_FILTER} + ${RAW_ALL_STACK} + ${ADDRESS_CHANGE_NOTIFY} + ${MULTIPART} + ${NAT} + ${PACKET_DEBUG} + ${DUAL_POOL} + ${IP_PACKET_FILTER} + ${DHCP_ARP_PROBE} + ${MDNS_IPV6} + ${HTTP_DIGEST} + ${DHCP_RESTORE} + ${DNS_CACHE} + ${TCPIP_OFFLOAD} + ${ARP} + ${HTTP_PROXY} + ${PPP_COMPRESSION}) +set(v6_full_secure_build + ${v6_full_build} + -DNX_SECURE_ENABLE) +set(v6_no_frag_build ${IPV6} ${NO_FRAG}) +set(v6_pmtu_no_frag_build ${v6_no_frag_build} ${IPV6_PMTU_DISCOVERY}) +set(v6_no_chain_build ${IPV6} ${NO_CHAIN} ${MDNS_NO_CLIENT}) +set(v6_no_dad_build ${IPV6} ${NO_DAD}) +set(v6_no_check_build ${IPV6} ${NO_CHECK} ${TAHI} ${IPV6_PMTU_DISCOVERY}) +set(v6_no_icmpv6_error_build ${IPV6} ${NO_ICMPV6_ERROR}) +set(v6_no_reset_disconn_build ${IPV6} ${NO_RESET_DISCONNECT} ${TAHI} + ${IPV6_PMTU_DISCOVERY}) +set(v6_link_cap_build ${IPV6} ${LINK_CAP} ${TX_RX_INTERFACE_CAPABILITY} + ${MULTI_INTERFACE}) +set(v6_address_change_build ${IPV6} ${ADDRESS_CHANGE_NOTIFY} ${MDNS_NO_SERVER}) +set(v6_multicast_build ${IPV6} ${MULTICAST} ${MULTI_INTERFACE}) +set(v6_ipsec_build + ${IPV6} + ${IPSEC} + ${BSD} + ${BSD_DNS} + ${MULTI_INTERFACE} + ${NAT} + ${PACKET_DEBUG} + ${TCP_RX_LIMIT} + ${CREATE_TELNET_PACKET_POOL} + ${TELNET_MAX_CLIENTS} + ${TELNET_ACTIVITY_TIMEOUT} + ${TELNET_TIMEOUT_PERIOD} + ${LCP_PROTOCOL_RETRIES} + ${IPCP_PROTOCOL_RETRIES} + ${LOW_WATERMARK} + ${IP_PACKET_FILTER} + ${TRACE} + ${MDNS_IPV6}) +set(v6_ipsec_dual_pool_build ${IPV6} ${IPSEC} ${DUAL_POOL}) +set(v6_ipsec_packet_pad_build ${IPV6} ${IPSEC} ${PACKET_PAD}) +set(v6_ipsec_tahi_build + ${IPV6} + ${IPSEC_TAHI} + ${TAHI} + ${BSD} + ${MULTI_INTERFACE} + ${IPV6_PMTU_DISCOVERY} + ${NAT}) +set(v6_ipsec_small_build + ${IPV6} + ${IPSEC} + ${NO_INFO} + ${NO_FRAG} + ${NO_DAD} + ${NO_CHECK} + ${NO_ICMPV6_ERROR} + ${NO_RESET_DISCONNECT} + ${PACKET_DEBUG}) +set(v6_ipsec_full_build + ${IPV6} + ${IPSEC_TAHI} + ${IPV6_PMTU_DISCOVERY} + ${TCP_KEEPALIVE} + ${TCP_KEEPALIVE_INITIAL} + ${TCP_KEEPALIVE_RETRY} + ${TCP_KEEPALIVE_RETRIES} + ${TCP_WINDOW} + ${IP_STATIC_ROUTING} + ${TAHI} + ${MULTIPART} + ${DUAL_POOL} + ${LOW_WATERMARK} + ${IP_PACKET_FILTER} + ${DHCP_ARP_PROBE} + ${MDNS_IPV6}) +set(v6_ipsec_full_tahi_build + ${IPV6} + ${IPSEC_TAHI} + ${TCP_KEEPALIVE} + ${TCP_KEEPALIVE_INITIAL} + ${TCP_KEEPALIVE_RETRY} + ${TCP_KEEPALIVE_RETRIES} + ${TCP_WINDOW} + ${IP_STATIC_ROUTING} + ${TAHI} + ${BSD} + ${MULTI_INTERFACE} + ${STATELESS_AC} + ${NAT} + ${LOW_WATERMARK} + ${DHCP_ARP_PROBE} + ${IPV6_PMTU_DISCOVERY} + ${MDNS_IPV6}) +set(v6_ipsec_no_frag_build ${IPV6} ${IPSEC} ${NO_FRAG}) +set(v6_ipsec_no_chain_build ${IPV6} ${IPSEC} ${NO_CHAIN} ${MDNS_NO_CLIENT}) +set(v6_ipsec_no_dad_build ${IPV6} ${IPSEC} ${NO_DAD}) +set(v6_ipsec_no_check_build ${IPV6} ${IPSEC_TAHI} ${NO_CHECK} ${TAHI} + ${IPV6_PMTU_DISCOVERY}) +set(v6_ipsec_no_check_tahi_build + ${IPV6} + ${IPSEC_TAHI} + ${NO_CHECK} + ${TAHI} + ${BSD} + ${MULTI_INTERFACE} + ${STATELESS_AC} + ${NAT}) +set(v6_no_rs_build ${IPV6} ${STATELESS_AC} ${NO_RS}) +set(v6_ipsec_no_icmpv6_error_build ${IPV6} ${IPSEC} ${NO_ICMPV6_ERROR}) +set(v6_ipsec_no_reset_disconn_build + ${IPV6} ${IPSEC_TAHI} ${NO_RESET_DISCONNECT} ${TAHI} ${IPV6_PMTU_DISCOVERY}) +set(v6_ipsec_no_reset_disconn_tahi_build + ${IPV6} ${IPSEC_TAHI} ${NO_RESET_DISCONNECT} ${TAHI} ${MDNS_NO_SERVER}) +set(v6_ipsec_link_cap_build ${IPV6} ${IPSEC} ${LINK_CAP}) +set(v6_dhcp_tahi_build ${IPV6} ${ADDRESS_CHANGE_NOTIFY} ${DHCPV6_TAHI} ${TAHI} + ${IPV6_PMTU_DISCOVERY}) +set(v6_bsd_raw_build ${IPV6} ${BSD_RAW} ${MULTI_INTERFACE} ${RAW_ALL_STACK}) +set(default_build_coverage -DNX_TAHI_ENABLE -DNX_MAX_PHYSICAL_INTERFACES=4 -DNX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +set(optimize_build ${default_build_coverage} -O3) +set(dhcp_default_build_coverage ${default_build_coverage} -DNX_DHCP_CLIENT_USER_CREATE_PACKET_POOL -DNX_DISABLE_ASSERT) +set(dns_default_build_coverage ${default_build_coverage} -DNX_DNS_CLIENT_USER_CREATE_PACKET_POOL -DNX_DNS_CLIENT_CLEAR_QUEUE) + +if($ENV{ENABLE_64}) + message(STATUS "Building for 64bit") + set(NXD_ENABLE_FILE_SERVERS OFF) +else() + add_compile_options(-m32) + add_link_options(-m32) + message(STATUS "Building for 32bit") + set(NXD_ENABLE_FILE_SERVERS ON) +endif() +add_compile_options( + -std=c99 + -ggdb + -g3 + -gdwarf-2 + -fdiagnostics-color + # -Werror + -DTX_INCLUDE_USER_DEFINE_FILE + ${${CMAKE_BUILD_TYPE}}) + +enable_testing() + +if("-DNX_BSD_ENABLE" IN_LIST ${CMAKE_BUILD_TYPE}) + set(NXD_ENABLE_BSD ON) +endif() +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../../.. ${PRODUCT}) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/regression regression) +if(NOT "$ENV{ENABLE_64}") + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/samples samples) + if(PRODUCT STREQUAL netxduo) + include(additionals.cmake) + endif() +endif() + +# Coverage +if(CMAKE_BUILD_TYPE MATCHES ".*_coverage") + target_compile_options(${PRODUCT} PRIVATE -fprofile-arcs -ftest-coverage) + target_link_options(${PRODUCT} PRIVATE -fprofile-arcs -ftest-coverage) +endif() + +# Build ThreadX library once +execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/run.sh build_libs) +add_custom_target(build_libs ALL COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/run.sh + build_libs) +add_dependencies(${PRODUCT} build_libs) +target_include_directories(${PRODUCT} PUBLIC ${CMAKE_BINARY_DIR}/../libs/inc) +add_library(threadx SHARED IMPORTED GLOBAL) +add_library("azrtos::threadx" ALIAS threadx) +set_target_properties( + threadx PROPERTIES IMPORTED_LOCATION + ${CMAKE_BINARY_DIR}/../libs/threadx/libthreadx.so) +add_library(filex SHARED IMPORTED GLOBAL) +add_library("azrtos::filex" ALIAS filex) +set_target_properties( + filex PROPERTIES IMPORTED_LOCATION + ${CMAKE_BINARY_DIR}/../libs/filex/libfilex.so) +target_link_libraries(${PRODUCT} PUBLIC filex) + +target_compile_options( + ${PRODUCT} + PRIVATE -Werror + -Wall + -Wextra + -pedantic + -fmessage-length=0 + -fsigned-char + -ffunction-sections + -fdata-sections + -Wunused + -Wuninitialized + -Wmissing-declarations + -Wconversion + -Wpointer-arith + -Wshadow + -Wlogical-op + -Waggregate-return + -Wfloat-equal) diff --git a/test/cmake/netxduo/additionals.cmake b/test/cmake/netxduo/additionals.cmake new file mode 100644 index 00000000..31caa837 --- /dev/null +++ b/test/cmake/netxduo/additionals.cmake @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.13.0 FATAL_ERROR) + +# See https://cmake.org/cmake/help/latest/policy/CMP0079.html for more info +cmake_policy(SET CMP0079 NEW) + +target_include_directories(netxduo PUBLIC ${SOURCE_DIR}) + +get_target_property(SOURCES_LIST netxduo SOURCES) +get_target_property(SOURCE_DIR netxduo SOURCE_DIR) + +if("-DNX_DISABLE_PACKET_CHAIN" IN_LIST ${CMAKE_BUILD_TYPE}) + # Remove nx_secure from build + aux_source_directory(${SOURCE_DIR}/nx_secure/src SECURE_SOURCES) + list(REMOVE_ITEM SOURCES_LIST ${SECURE_SOURCES}) + # Remove MQTT from build + list(REMOVE_ITEM SOURCES_LIST ${SOURCE_DIR}/addons/mqtt/nxd_mqtt_client.c) + # Remove WebSocket from build + list(REMOVE_ITEM SOURCES_LIST ${SOURCE_DIR}/addons/websocket/nx_websocket_client.c) + # Remove RTP from build + list(REMOVE_ITEM SOURCES_LIST ${SOURCE_DIR}/addons/rtp/nx_rtp_sender.c) +endif() +set_target_properties(netxduo PROPERTIES SOURCES "${SOURCES_LIST}") diff --git a/test/cmake/netxduo/coverage.sh b/test/cmake/netxduo/coverage.sh new file mode 100755 index 00000000..435de047 --- /dev/null +++ b/test/cmake/netxduo/coverage.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -e + +cd $(dirname $0) +root_path=$(cd ../../../common/src; pwd) +mkdir -p coverage_report/$1 +gcovr --object-directory=build/$1/netxduo/CMakeFiles/netxduo.dir/common/src -r ../../../common/src -e $root_path/nx_ram_network_driver.c --xml-pretty --output coverage_report/$1.xml +gcovr --object-directory=build/$1/netxduo/CMakeFiles/netxduo.dir/common/src -r ../../../common/src -e $root_path/nx_ram_network_driver.c --html --html-details --output coverage_report/$1/index.html diff --git a/test/cmake/netxduo/libs b/test/cmake/netxduo/libs new file mode 120000 index 00000000..d4bda9b4 --- /dev/null +++ b/test/cmake/netxduo/libs @@ -0,0 +1 @@ +../libs \ No newline at end of file diff --git a/test/cmake/netxduo/regression/CMakeLists.txt b/test/cmake/netxduo/regression/CMakeLists.txt new file mode 100644 index 00000000..c2d25e5d --- /dev/null +++ b/test/cmake/netxduo/regression/CMakeLists.txt @@ -0,0 +1,1355 @@ +cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR) +cmake_policy(SET CMP0057 NEW) + +project(regression_test LANGUAGES C) + +get_filename_component(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../regression + ABSOLUTE) + +set(auto_ip_test_cases + ${SOURCE_DIR}/auto_ip_test/netx_auto_ip_address_check_test.c + ${SOURCE_DIR}/auto_ip_test/netx_auto_ip_arp_dest_addr_test.c + ${SOURCE_DIR}/auto_ip_test/netx_auto_ip_basic_test.c + ${SOURCE_DIR}/auto_ip_test/netx_auto_ip_max_conflicts_test.c + # ${SOURCE_DIR}/auto_ip_test/netx_auto_ip_conflicts_check_test.c + ${SOURCE_DIR}/auto_ip_test/netx_auto_ip_announce_num_test.c) + +if("-DNX_BSD_ENABLE" IN_LIST ${CMAKE_BUILD_TYPE}) + set(bsd_test_cases + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_clients_shared_port_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_accept_noselect_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_blocking_bidirection_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_udp_blocking_bidirection_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_clients_share_port_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_servers_share_port_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_basic_blocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_two_blocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_2nd_bind_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_multicast_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_bind_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_disconnect_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_udp_select_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_accept_nonblocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_pton_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_ntoa_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_ntop_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_ioctl_nonblocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_udp_connect_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_sendto_recvfrom_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_accept_nonblocking_timeout_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_udp_bind_connect_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_udp_basic_nonblocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_multiple_accept_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_udp_bind_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_aton_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_inet_addr_pton_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_accept_blocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_udp_basic_blocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_basic_nonblocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_servers_shared_port_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_getsockname_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_accept_blocking_timeout_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_udp_checksum_corrupt_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_getaddrinfo_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_getsockname_without_bind_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_rcvbuf_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_tcp_fionread_test.c) + if("-DNX_BSD_RAW_SUPPORT" IN_LIST ${CMAKE_BUILD_TYPE}) + list( + APPEND + bsd_test_cases + ${SOURCE_DIR}/bsd_test/netx_bsd_raw_rx_nohdr_basic_blocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_raw_basic_rx_nohdr_nonblocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_raw_bind_connect_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_raw_basic_nonblocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_raw_basic_blocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_raw_basic_rx_nohdr_blocking_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_raw_pppoe_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_raw_ping_test.c + ${SOURCE_DIR}/bsd_test/netx_bsd_raw_tx_test.c) + endif() +endif() + +if(PRODUCT STREQUAL netxduo) + set(cloud_test_cases + ${SOURCE_DIR}/cloud_test/netx_cloud_api_test.c + ${SOURCE_DIR}/cloud_test/netx_cloud_basic_test.c + ${SOURCE_DIR}/cloud_test/netx_cloud_module_event_test.c + ${SOURCE_DIR}/cloud_test/netx_cloud_module_register_deregister_test.c) +endif() + +set(dhcp_test_cases + # ${SOURCE_DIR}/dhcp_test/netx_dhcp_03_01_02_test.c + # ${SOURCE_DIR}/dhcp_test/netx_dhcp_03_01_03_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_03_01_01_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_03_02_01_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_03_02_02_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_03_02_03_test.c + # ${SOURCE_DIR}/dhcp_test/netx_dhcp_03_04_01_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_03_05_01_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_04_01_01_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_04_03_02_01_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_04_03_02_02_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_04_03_02_03_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_04_03_05_01_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_04_04_01_01_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_04_04_01_02_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_basic_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_basic_restore_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_user_option_add_test.c + # ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_arpprobe_fail_multiple_interface. + # c ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_arpprobe_multiple_interface_tes + # t.c ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_arpprobe_multiple_interface.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_packet_process_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_send_with_zero_source_address_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_multiple_instances_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_send_request_internal_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_extract_information_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_get_option_value_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_delete_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_stop_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_enable_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_start_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_release_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_reinitialize_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_activate_interfaces_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_secondary_interface_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_interface_order_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_ip_mutex_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_server_source_port_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_ntp_option_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_parameter_request_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_coverage_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_unicast_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_server_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_server_improper_term_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_server_second_interface_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_server_options_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_server_small_packet_payload_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_skip_discover_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcp_client_nxe_api_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcpv6_basic_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcpv6_extended_api_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcpv6_packet_loss_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcpv6_client_process_server_duid_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcpv6_server_ia_options_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcpv6_server_iana_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcpv6_server_process_repeated_msgs_test.c + ${SOURCE_DIR}/dhcp_test/netx_dhcpv6_user_option_add_test.c) + +set(dns_test_cases + ${SOURCE_DIR}/dns_test/netx_dns_coverage_test.c + ${SOURCE_DIR}/dns_test/netx_dns_function_test.c + ${SOURCE_DIR}/dns_test/netx_dns_request_a_response_cname_a_smtp_live_com_test.c + ${SOURCE_DIR}/dns_test/netx_dns_invalid_name_unencode_test.c + ${SOURCE_DIR}/dns_test/netx_dns_invalid_resource_get_test.c + ${SOURCE_DIR}/dns_test/netx_dns_abnormal_packet_test.c + ${SOURCE_DIR}/dns_test/netx_dns_source_port_test.c + ${SOURCE_DIR}/dns_test/netx_dns_non_blocking_a_test.c + ${SOURCE_DIR}/dns_test/netx_dns_nxe_api_test.c + ${SOURCE_DIR}/dns_test/netx_dns_fake_response_test.c + ${SOURCE_DIR}/dns_test/netx_dns_packet_double_release_test.c) + +set(ftp_test_cases + ${SOURCE_DIR}/ftp_test/netx_ftp_access_control_commands_02_test.c + # ${SOURCE_DIR}/ftp_test/netx_ftp_service_commands_m_d_dir_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_access_control_commands_03_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_client_invalid_username_password_length_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_client_pasv_file_write_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_data_connection_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_service_commands_nlist_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_user_data_type_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_basic_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_establish_data_connection_05_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_commands_replys_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_service_commands_RETR_STOR_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_service_commands_rename_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_establish_data_connection_08_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_access_control_commands_04_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_client_pasv_denied.c + ${SOURCE_DIR}/ftp_test/netx_ftp_commands_characters_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_client_pasv_file_read_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_client_buffer_overflow_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_client_file_write_fail_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_establish_data_connection_06_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_service_commands_file_write_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_establish_data_connection_03_test.c + # ${SOURCE_DIR}/ftp_test/netx_ftp_service_commands_dele_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_access_control_commands_01_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_control_connection_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_server_invalid_month_crash_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_rst_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_two_listen_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_client_multiple_connection_responses_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_client_packet_leak_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_parse_ipv6_address_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_server_abnormal_packet_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_server_list_command_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_server_dangling_pointer_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_server_mss_too_small_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_pasv_twice_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_disconnection_event_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_ipv6_epsv_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_pasv_port_test.c + ${SOURCE_DIR}/ftp_test/netx_ftp_pasv_stor_test.c) + +set(http_test_cases + ${SOURCE_DIR}/http_test/netx_http_get_put_referred_URI_test.c + ${SOURCE_DIR}/http_test/netx_http_if_modified_since_test.c + ${SOURCE_DIR}/http_test/netx_http_client_change_connect_port_test.c + # ${SOURCE_DIR}/http_test/netx_http_status_400_test.c + ${SOURCE_DIR}/http_test/netx_http_post_basic_test.c + ${SOURCE_DIR}/http_test/netx_http_get_contentlength_packetleak_test.c + ${SOURCE_DIR}/http_test/netx_http_status_404_test.c + ${SOURCE_DIR}/http_test/netx_http_basic_test.c + ${SOURCE_DIR}/http_test/netx_http_basic_authenticate_test.c + ${SOURCE_DIR}/http_test/netx_http_get_content_length_test.c + # ${SOURCE_DIR}/http_test/netx_http_status_501_test.c + ${SOURCE_DIR}/http_test/netx_http_request_in_multiple_packets_test.c + ${SOURCE_DIR}/http_test/netx_http_head_basic_test.c + ${SOURCE_DIR}/http_test/netx_http_delete_basic_test.c + ${SOURCE_DIR}/http_test/netx_http_multipart_fragment_test.c + ${SOURCE_DIR}/http_test/netx_http_multipart_underflow_test.c + ${SOURCE_DIR}/http_test/netx_http_digest_authenticate_test.c + ${SOURCE_DIR}/http_test/netx_http_server_type_retrieve_test.c + ${SOURCE_DIR}/http_test/netx_http_digest_authenticate_timeout_test.c) + +if(PRODUCT STREQUAL netxduo) + set(mdns_test_cases + ${SOURCE_DIR}/mdns_test/netx_mdns_announcement_repeat_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_bad_packet_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_buffer_size_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_create_delete_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_domain_name_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_interface_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_second_interface_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_internal_function_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_local_cache_continuous_query_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_local_cache_one_shot_query_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_multiple_answers_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_name_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_one_shot_query_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_responder_cooperating_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_response_with_question_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_service_add_delete_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_service_lookup_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_source_address_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_source_port_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_ttl_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_two_buffer_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_txt_notation_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_txt_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_peer_service_change_notify_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_ipv6_string_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_read_overflow_test.c) + if(NOT "-DNX_DISABLE_IPV4" IN_LIST ${CMAKE_BUILD_TYPE}) + list(APPEND mdns_test_cases ${SOURCE_DIR}/mdns_test/netx_mdns_ram_test.c) + endif() + + set(nat_test_cases + ${SOURCE_DIR}/nat_test/netx_nat_tcp_fragment_test.c + ${SOURCE_DIR}/nat_test/netx_nat_tcp_test1.c + ${SOURCE_DIR}/nat_test/netx_nat_tcp_port_test2.c + ${SOURCE_DIR}/nat_test/netx_nat_udp_fragment_test.c + ${SOURCE_DIR}/nat_test/netx_nat_icmp_test.c + ${SOURCE_DIR}/nat_test/netx_nat_udp_test.c + ${SOURCE_DIR}/nat_test/netx_nat_tcp_test2.c + ${SOURCE_DIR}/nat_test/netx_nat_udp_port_test.c + ${SOURCE_DIR}/nat_test/netx_nat_tcp_port_test.c + ${SOURCE_DIR}/nat_test/netx_nat_invalid_header_test.c) +endif() + +set(netxduo_test_cases + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_mtu_option_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_branch_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_icmp_small_header_test2.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_receive_under_interface_detach_test.c + ${SOURCE_DIR}/netxduo_test/netx_8_29_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_new_reno_algorithm_test4.c + ${SOURCE_DIR}/netxduo_test/netx_15_26_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_ipv6_interface2_test_1_test.c + ${SOURCE_DIR}/netxduo_test/netx_15_24_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_31_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_small_window_preempt_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_conflict_test.c + ${SOURCE_DIR}/netxduo_test/netx_4_29_test.c + ${SOURCE_DIR}/netxduo_test/netx_packet_suspension_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_tunnel_ipv4_ipv6_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_ping_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_interface2_ping6_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_nxe_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_8_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_prefix_test.c + ${SOURCE_DIR}/netxduo_test/netx_11_26_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_unaccept_test.c + ${SOURCE_DIR}/netxduo_test/netx_6_28_test.c + ${SOURCE_DIR}/netxduo_test/netx_9_21_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_10_23_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_6_29_test.c + ${SOURCE_DIR}/netxduo_test/netx_11_27_test.c + ${SOURCE_DIR}/netxduo_test/netx_6_22_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_packet_delay_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_dropped_packet_test2.c + ${SOURCE_DIR}/netxduo_test/netx_10_26_test.c + ${SOURCE_DIR}/netxduo_test/netx_8_19_test.c + ${SOURCE_DIR}/netxduo_test/netx_igmp_leave_test.c + ${SOURCE_DIR}/netxduo_test/netx_igmp_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_14_19_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_address_delete_test.c + ${SOURCE_DIR}/netxduo_test/netx_2_20_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_no_duplicate_entry_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_raw_loopback_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_multiple_send_test.c + ${SOURCE_DIR}/netxduo_test/netx_102_22_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_icmp_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_ack_check_for_syn_message_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_raw_packet_filter_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_max_payload_size_find_test.c + ${SOURCE_DIR}/netxduo_test/netx_3_06_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_21_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_fragmentation_error_test2.c + ${SOURCE_DIR}/netxduo_test/netx_udp_packet_type_test.c + ${SOURCE_DIR}/netxduo_test/netx_raw_special_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_raw_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_udp_test.c + ${SOURCE_DIR}/netxduo_test/netx_api_compile_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_branch_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_cleanup_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_window_update_test.c + ${SOURCE_DIR}/netxduo_test/netx_11_28_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_auto_entry_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_client_socket_unbind_test.c + ${SOURCE_DIR}/netxduo_test/netx_10_24_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_branch_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_malformed_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_idle_scan_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_multiple_send_test2.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_fast_disconnect_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_keepalive_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_abnormal_mtu_in_ra_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_multiple_ping_test1.c + ${SOURCE_DIR}/netxduo_test/netx_old_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_loopback_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_time_exceeded_message_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_icmp_small_header_test.c + ${SOURCE_DIR}/netxduo_test/netx_3_23_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_invalid_ra_dest_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_retransmit_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_basic_processing_test.c + ${SOURCE_DIR}/netxduo_test/netx_3_21_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_client_socket_port_get_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_capability_test.c + ${SOURCE_DIR}/netxduo_test/netx_23_02_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_data_trim_test.c + ${SOURCE_DIR}/netxduo_test/netx_4_26_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_nxe_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_14_20_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_detachment_tcp_connection_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_address_get_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_invalid_echo_reply_test.c + ${SOURCE_DIR}/netxduo_test/netx_10_24_03_test.c + ${SOURCE_DIR}/netxduo_test/netx_packet_branch_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_urgent_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_transmit_cleanup_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_dynamic_entry_fail_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_na_tlla_changed_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_nxe_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_listen_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_disable_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_multiple_ping6_test1.c + ${SOURCE_DIR}/netxduo_test/netx_ip_address_get_test.c + ${SOURCE_DIR}/netxduo_test/netx_10_24_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_default_router_test.c + ${SOURCE_DIR}/netxduo_test/netx_106_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_invalid_packet_receive_test.c + ${SOURCE_DIR}/netxduo_test/netx_igmp_router_query_test.c + ${SOURCE_DIR}/netxduo_test/netx_ramdriver_callback_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_static_entry_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_static_entry_pollute_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_ra_flag_callback_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_udp_fragment_test4.c + ${SOURCE_DIR}/netxduo_test/netx_checksum_test.c + ${SOURCE_DIR}/netxduo_test/netx_102_24_test.c + ${SOURCE_DIR}/netxduo_test/netx_2_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_2.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_11.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_ra_router_full_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_multiple_ping_test2.c + ${SOURCE_DIR}/netxduo_test/netx_forward_tcp_test_5.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_15.c + ${SOURCE_DIR}/netxduo_test/netx_ip_link_local_address_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_address_get_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_tunnel_ipv6_ipv6_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_dynamic_entry_test2.c + ${SOURCE_DIR}/netxduo_test/netx_arp_queue_depth_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_echo_reply_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_connection_reset_test.c + ${SOURCE_DIR}/netxduo_test/netx_packet_payload_size_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_tcp_test_1.c + ${SOURCE_DIR}/netxduo_test/netx_ip_address_conflict_detection_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_tunnel_ipv4_ipv6_ping_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_tunnel_ipv4_ipv4_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_tunnel_ipv6_ipv6_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_socket_unbind_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_static_entry_create_test.c + ${SOURCE_DIR}/netxduo_test/netx_4_28_test.c + # ${SOURCE_DIR}/netxduo_test/netx_18_21_test.c + ${SOURCE_DIR}/netxduo_test/netx_6_24_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_14.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_tunnel_ipv4_ipv4_ping_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_18_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_multiple_ping6_test2.c + ${SOURCE_DIR}/netxduo_test/netx_6_25_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_loopback_fail_test.c + ${SOURCE_DIR}/netxduo_test/netx_102_18_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_link_local_address_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_broadcast_ping_test.c + ${SOURCE_DIR}/netxduo_test/netx_4_24_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_util_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_16_19_test.c + ${SOURCE_DIR}/netxduo_test/netx_igmp_nxe_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_send_error_message_test_1.c + ${SOURCE_DIR}/netxduo_test/netx_arp_dual_pool_test.c + ${SOURCE_DIR}/netxduo_test/netx_6_22_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_queue_depth_notify_test.c + ${SOURCE_DIR}/netxduo_test/netx_16_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_receive_under_interface_detach_test2.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_packet_receive_function_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_address_set_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_pmtu_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_ping6_data_append_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_4.c + ${SOURCE_DIR}/netxduo_test/netx_nd_cache_nxe_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_interface_detachment_router_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_client_bind_cleanup_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_new_reno_algorithm_test2.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_out_of_order_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_12.c + ${SOURCE_DIR}/netxduo_test/netx_9_22_test.c + ${SOURCE_DIR}/netxduo_test/netx_8_21_test.c + ${SOURCE_DIR}/netxduo_test/netx_packet_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_03_test.c + ${SOURCE_DIR}/netxduo_test/netx_5_25_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_27_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_05_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_checksum_zero_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_nxe_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_stateless_address_autoconfig_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_9.c + ${SOURCE_DIR}/netxduo_test/netx_nd_cache_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_11_24_test.c + ${SOURCE_DIR}/netxduo_test/netx_15_20_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_status_check_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_multicast_interface_detach_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_port_unreachable_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_loopback_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_wrapping_sequence_test3.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_nxe_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_packet_nxe_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_5_24_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_27_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_loopback_multihome_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_unbind_test2.c + ${SOURCE_DIR}/netxduo_test/netx_3_04_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_ipv6_delayed_retransmission_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_dynamic_entry_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_wrong_destination_address_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_04_ipv6_test.c + ${SOURCE_DIR}/netxduo_test/netx_2_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_delayed_retransmission_test.c + ${SOURCE_DIR}/netxduo_test/netx_3_20_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_chained_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_icmp_small_header_test3.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_fragmentation_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_large_mtu_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_large_mtu_test2.c + ${SOURCE_DIR}/netxduo_test/netx_low_watermark_zero_window_test.c + ${SOURCE_DIR}/netxduo_test/netx_low_watermark_fragment_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_30_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_create_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_redirect_nd_full_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_echo_request_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_listen_queue_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_packet_receive_function_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_multiple_ports_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_17.c + ${SOURCE_DIR}/netxduo_test/netx_igmp_join_fail_test.c + ${SOURCE_DIR}/netxduo_test/netx_13_04_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_send_fail_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_27_03_test.c + ${SOURCE_DIR}/netxduo_test/netx_9_18_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_19_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_driver_deferred_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_tunnel_ipv4_ipv4_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_9_21_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_packet_receive_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_na_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_na_buffer_overwrite_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_bind_cleanup_test.c + ${SOURCE_DIR}/netxduo_test/netx_16_22_test.c + ${SOURCE_DIR}/netxduo_test/netx_102_20_test.c + ${SOURCE_DIR}/netxduo_test/netx_igmp_packet_receive_function_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_unlisten_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_address_set_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_5_18_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_8.c + ${SOURCE_DIR}/netxduo_test/netx_4_17_test.c + # ${SOURCE_DIR}/netxduo_test/netx_11_23_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_packet_copy_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_multicast_interface_detach_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_socket_delete_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_timeout_check_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_timeout_check_test2.c + ${SOURCE_DIR}/netxduo_test/netx_9_27_test.c + ${SOURCE_DIR}/netxduo_test/netx_8_29_04_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_21_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_server_socket_accept_test.c + ${SOURCE_DIR}/netxduo_test/netx_13_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_ping_multicast_test.c + ${SOURCE_DIR}/netxduo_test/netx_3_07_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_nd_cache_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_send_disconnect_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_ping_fragment_test.c + ${SOURCE_DIR}/netxduo_test/netx_caller_check_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_3.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_5.c + ${SOURCE_DIR}/netxduo_test/netx_103_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_3_03_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_duplicate_test.c + ${SOURCE_DIR}/netxduo_test/netx_6_18_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_basic_processing_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_status_check_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_search_onlink_test.c + ${SOURCE_DIR}/netxduo_test/netx_5_23_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_physical_address_set_fail_test.c + ${SOURCE_DIR}/netxduo_test/netx_3_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_not_enabled_test.c + ${SOURCE_DIR}/netxduo_test/netx_16_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_23_02_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_27_test.c + ${SOURCE_DIR}/netxduo_test/netx_13_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_wrong_protocol_field_test2.c + ${SOURCE_DIR}/netxduo_test/netx_ip_gateway_address_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_static_route_delete_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_relisten_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_chain_packet_process_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_ipv4_interface2_mss_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_retransmit_test_1.c + ${SOURCE_DIR}/netxduo_test/netx_rarp_multiple_interfaces_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_ipv6_window_scale_test.c + ${SOURCE_DIR}/netxduo_test/netx_2_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_5_21_test.c + ${SOURCE_DIR}/netxduo_test/netx_4_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_invalid_packet_receive_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_invalid_length_test2.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_send_error_message_test.c + ${SOURCE_DIR}/netxduo_test/netx_104_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_free_port_find_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv4_option_process_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_10.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_receive_cleanup_test.c + ${SOURCE_DIR}/netxduo_test/netx_5_20_test.c + ${SOURCE_DIR}/netxduo_test/netx_102_19_test.c + ${SOURCE_DIR}/netxduo_test/netx_igmp_branch_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_21_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_gratuitous_test.c + ${SOURCE_DIR}/netxduo_test/netx_4_23_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_interface2_ping_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_dynamic_entry_test3.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_error_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_error_small_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_status_check_fail_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_ipv6_interface2_mss_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_wrapping_sequence_test2.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_16.c + ${SOURCE_DIR}/netxduo_test/netx_ip_route_reachable_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_nxe_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_wrapping_sequence_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_address_conflict_callback_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_send_fail_test3.c + ${SOURCE_DIR}/netxduo_test/netx_6_20_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_ack_check_issue_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_tcp_test_4.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_small_windows_test.c + ${SOURCE_DIR}/netxduo_test/netx_3_18_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_static_entries_delete_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_transmit_under_interface_detach_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_loopback_test2.c + ${SOURCE_DIR}/netxduo_test/netx_5_22_test.c + ${SOURCE_DIR}/netxduo_test/netx_igmp_checksum_computation_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_abnormal_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_16_21_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_delete_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_link_status_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_tunnel_ipv6_ipv6_ping_test.c + ${SOURCE_DIR}/netxduo_test/netx_9_19_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_hop_by_hop_option_error_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_26_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_packet_filter_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_packet_filter_extended_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_invalid_na.c + ${SOURCE_DIR}/netxduo_test/netx_low_watermark_test.c + ${SOURCE_DIR}/netxduo_test/netx_rarp_nxe_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_detachment_arp_table_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_max_window_scale_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_raw_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_out_of_order_packet_max_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_branch_test.c + ${SOURCE_DIR}/netxduo_test/netx_nd_cache_branch_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_24_test.c + ${SOURCE_DIR}/netxduo_test/netx_23_02_03_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_ra_address_full_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_zero_window_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_info_get_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_error_operation_check_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_detachment_gateway_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_duplicate_accept_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_18_test.c + ${SOURCE_DIR}/netxduo_test/netx_3_08_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_ipv4_interface2_test_1_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_address_set_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_DAD_test.c + ${SOURCE_DIR}/netxduo_test/netx_8_29_03_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_23_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_tunnel_ipv6_ipv4_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_fin_wait1_to_time_wait_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_udp_fragment_test3.c + ${SOURCE_DIR}/netxduo_test/netx_igmp_loopback_test.c + ${SOURCE_DIR}/netxduo_test/netx_15_21_test.c + ${SOURCE_DIR}/netxduo_test/netx_101_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_11_25_test.c + ${SOURCE_DIR}/netxduo_test/netx_6_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_9_19_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_entry_cache_test.c + ${SOURCE_DIR}/netxduo_test/netx_13_05_test.c + ${SOURCE_DIR}/netxduo_test/netx_8_18_test.c + ${SOURCE_DIR}/netxduo_test/netx_11_29_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_auxiliary_packet_pool_set_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_physical_address_test.c + ${SOURCE_DIR}/netxduo_test/netx_11_18_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_invalid_length_test.c + ${SOURCE_DIR}/netxduo_test/netx_13_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_dynamic_invalidate_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_raw_packet_queue_test.c + ${SOURCE_DIR}/netxduo_test/netx_dest_table_add_fail_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_static_route_find_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_19_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_9_20_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_mss_option_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_mss_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_13.c + ${SOURCE_DIR}/netxduo_test/netx_6_27_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_fragment_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_available_bytes_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_listen_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_listen_packet_leak_test.c + ${SOURCE_DIR}/netxduo_test/netx_6_23_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_source_send_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_ping6_fragment_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_ipv6_basic_processing_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_attachment_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_send_fail_test2.c + ${SOURCE_DIR}/netxduo_test/netx_1_20_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_18.c + ${SOURCE_DIR}/netxduo_test/netx_arp_invalid_type_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_tx_queue_exceed_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_time_wait_to_close_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_fast_retransmit_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_4_duplicate_ack_test.c + ${SOURCE_DIR}/netxduo_test/netx_15_25_test.c + ${SOURCE_DIR}/netxduo_test/netx_8_20_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_fragmentation_processing_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_address_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_socket_unbind_receive_test.c + ${SOURCE_DIR}/netxduo_test/netx_5_19_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_19_03_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_router_solicitation_test.c + ${SOURCE_DIR}/netxduo_test/netx_rarp_packet_allocate_fail_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_icmp_ttl_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_udp_fragment_test2.c + ${SOURCE_DIR}/netxduo_test/netx_101_18_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_zero_window_probe_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_zero_window_probe_2_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_zero_window_probe_3_test.c + ${SOURCE_DIR}/netxduo_test/netx_6_32_test.c + ${SOURCE_DIR}/netxduo_test/netx_3_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_102_25_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_socket_bind_test.c + ${SOURCE_DIR}/netxduo_test/netx_nxd_udp_socket_send_special_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_send_internal_test.c + ${SOURCE_DIR}/netxduo_test/netx_rarp_basic_processing_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_wrong_protocol_field_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_small_window_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_03_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_new_reno_algorithm_test5.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_delayed_retransmission_test2.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_fin_wait_recv_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_branch_test.c + ${SOURCE_DIR}/netxduo_test/netx_10_23_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_tunnel_ipv6_ipv4_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_15_03_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_destination_table_periodic_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_send_fail_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_udp_fragment_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_transmit_not_done_test.c + ${SOURCE_DIR}/netxduo_test/netx_4_25_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_entry_abnormal_operation_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_port_table_udpate_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_order_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_27_04_test.c + ${SOURCE_DIR}/netxduo_test/netx_forward_tcp_test_2.c + ${SOURCE_DIR}/netxduo_test/netx_23_02_04_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_7.c + ${SOURCE_DIR}/netxduo_test/netx_4_27_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_unbind_test.c + ${SOURCE_DIR}/netxduo_test/netx_udp_branch_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_dispatch_fail_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_26_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_address_change_notify_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_20_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_nd_cache_under_interface_detach_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_invalid_source_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_client_socket_bind_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_client_packet_leak_test.c + ${SOURCE_DIR}/netxduo_test/netx_8_29_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_3_19_test.c + ${SOURCE_DIR}/netxduo_test/netx_packet_debug_info_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_ra_lifetime_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_simultaneous_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_04_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_hop_by_hop_fragment_test.c + ${SOURCE_DIR}/netxduo_test/netx_102_23_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_wrapping_sequence_test4.c + ${SOURCE_DIR}/netxduo_test/netx_nd_cache_add_test.c + ${SOURCE_DIR}/netxduo_test/netx_rarp_branch_test.c + ${SOURCE_DIR}/netxduo_test/netx_igmp_multicast_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_default_router_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_reset_during_send_test.c + ${SOURCE_DIR}/netxduo_test/netx_packet_data_append_test.c + ${SOURCE_DIR}/netxduo_test/netx_igmp_interface_indirect_report_send_test.c + ${SOURCE_DIR}/netxduo_test/netx_17_17_test.c + # ${SOURCE_DIR}/netxduo_test/netx_tcp_ack_before_release_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_out_of_window_control_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_04_test.c + ${SOURCE_DIR}/netxduo_test/netx_10_25_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_fragment_fail_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_invalid_option_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_invalid_option_test2.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_redirect_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_redirect_buffer_overwrite_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_ping6_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_branch_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_new_reno_algorithm_test3.c + ${SOURCE_DIR}/netxduo_test/netx_3_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_dropped_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_12_25_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_delete_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_packet_allocate_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_solicitated_ra_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_disable_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_data_transfer_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_odd_window_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_multicast_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_loopback_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_overlapping_packet_test_6.c + ${SOURCE_DIR}/netxduo_test/netx_ip_static_route_add_test.c + ${SOURCE_DIR}/netxduo_test/netx_raw_nxe_api_test.c + ${SOURCE_DIR}/netxduo_test/netx_4_21_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_ra_slla_changed_test.c + ${SOURCE_DIR}/netxduo_test/netx_102_21_test.c + ${SOURCE_DIR}/netxduo_test/netx_11_19_test.c + ${SOURCE_DIR}/netxduo_test/netx_nd_cache_with_own_address_test.c + ${SOURCE_DIR}/netxduo_test/netx_8_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_relisten_test2.c + ${SOURCE_DIR}/netxduo_test/netx_arp_dynamic_entry_set_test.c + ${SOURCE_DIR}/netxduo_test/netx_arp_dynamic_entry_timeout_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_packet_leak_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmp_tunnel_ipv6_ipv4_ping_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_19_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_fragmentation_error_test1.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_new_reno_algorithm_test1.c + ${SOURCE_DIR}/netxduo_test/netx_ip_interface_detachment_test.c + ${SOURCE_DIR}/netxduo_test/netx_8_01_test.c + ${SOURCE_DIR}/netxduo_test/netx_ip_fragmentation_packet_drop_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_state_wait_test.c + ${SOURCE_DIR}/netxduo_test/netx_1_26_02_test.c + ${SOURCE_DIR}/netxduo_test/netx_9_17_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_multicast_ping_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_multicast_ping_test1.c + ${SOURCE_DIR}/netxduo_test/netx_forward_tcp_test_3.c + ${SOURCE_DIR}/netxduo_test/netx_forward_multicast_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_big_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_udp_random_port_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_invalid_message_test.c + ${SOURCE_DIR}/netxduo_test/netx_ipv6_packet_chain_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_ra_invalid_length_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_ra_buffer_overwrite_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_invalid_length_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_large_data_transfer_test.c + ${SOURCE_DIR}/netxduo_test/netx_utility_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_ns_with_small_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_ns_buffer_overwrite_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_small_packet_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_advertised_window_update_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_invalid_ra_option_test.c + ${SOURCE_DIR}/netxduo_test/netx_icmpv6_too_big_buffer_overwrite_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_race_condition_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_race_condition_test2.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_socket_receive_rst_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_invalid_packet_chain_test.c + ${SOURCE_DIR}/netxduo_test/netx_http_proxy_basic_test.c + ${SOURCE_DIR}/netxduo_test/netx_http_proxy_non_block_test.c + ${SOURCE_DIR}/netxduo_test/netx_http_proxy_multiple_response_test.c + ${SOURCE_DIR}/netxduo_test/netx_http_proxy_error_response_test.c + ${SOURCE_DIR}/netxduo_test/netx_http_proxy_disconnect_test.c + ${SOURCE_DIR}/netxduo_test/netx_http_proxy_data_fin_test.c) + +set(websocket_test_cases + ${SOURCE_DIR}/websocket_test/netx_websocket_send_chain_packets_test.c + ${SOURCE_DIR}/websocket_test/netx_websocket_non_block_test.c + ${SOURCE_DIR}/websocket_test/netx_websocket_multi_instance_test.c + ${SOURCE_DIR}/websocket_test/netx_websocket_delete_test.c + ${SOURCE_DIR}/websocket_test/netx_websocket_16_bit_payload_length_test.c + ${SOURCE_DIR}/websocket_test/netx_websocket_one_packet_with_multi_frames_test.c + ${SOURCE_DIR}/websocket_test/netx_websocket_one_frame_in_packets_test.c + ${SOURCE_DIR}/websocket_test/netx_websocket_disconnect_test.c + ${SOURCE_DIR}/websocket_test/netx_websocket_connect_test.c + ${SOURCE_DIR}/websocket_test/netx_websocket_mask_test.c + ${SOURCE_DIR}/websocket_test/netx_websocket_fin_test.c + ${SOURCE_DIR}/websocket_test/netx_websocket_opcode_test.c) + +set(pop3_test_cases + ${SOURCE_DIR}/pop3_test/netx_pop3_two_mails_received_test.c + ${SOURCE_DIR}/pop3_test/netx_pop3_mail_receive_test.c + ${SOURCE_DIR}/pop3_test/netx_pop3_packet_with_endmarker_test.c + ${SOURCE_DIR}/pop3_test/netx_pop3_abnormal_packet_test.c) + +set(ppp_test_cases + ${SOURCE_DIR}/ppp_test/netx_ppp_PAP_bad_password_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_check_boundary_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_IPCP_timeout.c + ${SOURCE_DIR}/ppp_test/netx_ppp_request_dns_server_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_chap_bad_secret_passed_on_retry_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_chap_bad_secret_failed_retry_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_LCP_timeout.c + ${SOURCE_DIR}/ppp_test/netx_ppp_PAP_bad_username_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_pap_null_name_password_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_LCP_invalid_packet_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_IPCP_abnormal_packet_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_IPCP_nak_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_IPCP_retransmit_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_pap_basic_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_pfc_option_test.c + ${SOURCE_DIR}/ppp_test/netx_ppp_acfc_option_test.c) + +set(pppoe_test_cases + ${SOURCE_DIR}/pppoe_test/netx_pppoe_basic_test.c + ${SOURCE_DIR}/pppoe_test/netx_pppoe_api_test.c + ${SOURCE_DIR}/pppoe_test/netx_pppoe_api_extended_test.c + ${SOURCE_DIR}/pppoe_test/netx_pppoe_ac_name_test.c + ${SOURCE_DIR}/pppoe_test/netx_pppoe_session_control_test.c) + +if(PRODUCT STREQUAL netxduo) + if(NOT "-DNX_DISABLE_IPV4" IN_LIST ${CMAKE_BUILD_TYPE}) + set(ptp_test_cases + ${SOURCE_DIR}/ptp_test/netx_ptp_client_announce_timeout_test.c + ${SOURCE_DIR}/ptp_test/netx_ptp_client_api_test.c + ${SOURCE_DIR}/ptp_test/netx_ptp_client_basic_test.c + ${SOURCE_DIR}/ptp_test/netx_ptp_client_calibrate_test.c + ${SOURCE_DIR}/ptp_test/netx_ptp_client_ipv6_test.c + ${SOURCE_DIR}/ptp_test/netx_ptp_client_master_selection_test.c + ${SOURCE_DIR}/ptp_test/netx_ptp_client_two_steps_off_test.c) + endif() +endif() + +set(rtp_test_cases + ${SOURCE_DIR}/rtp_test/netx_rtp_multi_interfaces_test.c + ${SOURCE_DIR}/rtp_test/netx_rtp_session_packet_send_test.c + ${SOURCE_DIR}/rtp_test/netx_rtp_session_jpeg_send_test.c + ${SOURCE_DIR}/rtp_test/netx_rtp_session_h264_send_test.c + ${SOURCE_DIR}/rtp_test/netx_rtp_session_aac_send_test.c + ${SOURCE_DIR}/rtp_test/netx_rtp_free_udp_port_find_test.c + ${SOURCE_DIR}/rtp_test/netx_rtp_multi_clients_test.c + ${SOURCE_DIR}/rtp_test/netx_rtp_multicast_test.c + ${SOURCE_DIR}/rtp_test/netx_rtp_basic_test.c + ${SOURCE_DIR}/rtp_test/netx_rtp_api_test.c + ${SOURCE_DIR}/rtp_test/netx_rtcp_abnormal_packet_test.c + ${SOURCE_DIR}/rtp_test/netx_rtcp_basic_test.c + ${SOURCE_DIR}/rtp_test/netx_rtcp_packet_process_test.c + ${SOURCE_DIR}/rtp_test/netx_rtcp_packet_send_test.c) + +set(rtsp_test_cases + ${SOURCE_DIR}/rtsp_test/netx_rtsp_api_test.c + ${SOURCE_DIR}/rtsp_test/netx_rtsp_rtp_basic_test.c + ${SOURCE_DIR}/rtsp_test/netx_rtsp_rtp_ipv6_basic_test.c + ${SOURCE_DIR}/rtsp_test/netx_rtsp_rtp_multicast_test.c + ${SOURCE_DIR}/rtsp_test/netx_rtsp_rtp_ipv6_multicast_test.c + ${SOURCE_DIR}/rtsp_test/netx_rtsp_multiple_request_test.c + ${SOURCE_DIR}/rtsp_test/netx_rtsp_multiple_clients_test.c + ${SOURCE_DIR}/rtsp_test/netx_rtsp_client_timeout_test.c + ${SOURCE_DIR}/rtsp_test/netx_rtsp_error_response_test.c + ${SOURCE_DIR}/rtsp_test/netx_rtsp_delete_beforehand_test.c) + +set(smtp_test_cases + ${SOURCE_DIR}/smtp_test/netx_smtp_auth_none_test.c + ${SOURCE_DIR}/smtp_test/netx_smtp_missing_last_250_EHLO_message_test.c + ${SOURCE_DIR}/smtp_test/netx_smtp_auth_logon_function_test.c + ${SOURCE_DIR}/smtp_test/netx_smtp_auth_no_type_test.c + ${SOURCE_DIR}/smtp_test/netx_smtp_two_packet_EHLO_auth_last_message_test.c + ${SOURCE_DIR}/smtp_test/netx_smtp_basic_function_test.c + ${SOURCE_DIR}/smtp_test/netx_smtp_two_packet_EHLO_message_test.c + ${SOURCE_DIR}/smtp_test/netx_smtp_abnormal_packet_test.c + ${SOURCE_DIR}/smtp_test/netx_smtp_invalid_release_test.c) + +set(snmp_test_cases + ${SOURCE_DIR}/snmp_test/netx_snmp_v1_buffer_overwrite_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v1_object_id_buffer_overwrite_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v1_packet_double_release_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_basic_v2_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v2_get_bulk_request_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v2_unknown_oid_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v2_send_trap_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v2_buffer_overwrite_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v3_nosec_traplist_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v3_md5_failed_security_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v3_md5_security_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v3_md5_security_extended_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v3_no_security_function_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v3_buffer_overwrite_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v3_decrypt_pdu_buffer_overwrite_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v3_encrypt_pdu_buffer_overwrite_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v3_encrypt_pdu_padding_buffer_overwrite_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_v3_object_id_buffer_overwrite_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_setget_integers_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_setget_octet_strings_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_setget_ip_address_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_setget_misc_test.c + ${SOURCE_DIR}/snmp_test/netx_snmp_abnormal_packet_test.c) + +set(sntp_test_cases + ${SOURCE_DIR}/sntp_test/netx_sntp_forward_unicast_update_test.c + ${SOURCE_DIR}/sntp_test/netx_sntp_request_unicast_test.c + ${SOURCE_DIR}/sntp_test/netx_sntp_client_unicast_basic_test.c + ${SOURCE_DIR}/sntp_test/netx_sntp_client_ipv6_broadcast_basic_test.c + ${SOURCE_DIR}/sntp_test/netx_sntp_client_ipv6_unicast_basic_test.c + ${SOURCE_DIR}/sntp_test/netx_sntp_client_broadcast_basic_test.c + ${SOURCE_DIR}/sntp_test/netx_sntp_client_unicast_display_date_test.c + ${SOURCE_DIR}/sntp_test/netx_sntp_client_seconds_to_date_test.c + ${SOURCE_DIR}/sntp_test/netx_sntp_client_kod_test.c + ${SOURCE_DIR}/sntp_test/netx_sntp_client_packet_chain_test.c) + +if(PRODUCT STREQUAL netxduo) + if("-DNX_TAHI_ENABLE" IN_LIST ${CMAKE_BUILD_TYPE}) + if("-DNX_ENABLE_IPV6_PATH_MTU_DISCOVERY" IN_LIST ${CMAKE_BUILD_TYPE}) + set(tahi_test_cases + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_15.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_40.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_12.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_33.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_18.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_16.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_15.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_22.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_5.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_35.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_19.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_09.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_16.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_7.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_03.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_04.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_2_05.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_10.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_10.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_01.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_05.c + # ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_44.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_11.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_29.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_34.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_2.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_39.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_2_10.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_2_04.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_12.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_1.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_3.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_02.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_2_01.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_20.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_2_02.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_37.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_5.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_42.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_13.c + # ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_45.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_2_11.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_21.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_41.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_2_06.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_2_09.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_4.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_6.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_32.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_24.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_14.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_06.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_2_07.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_17.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_30.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_07.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_27.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_9.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_31.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_28.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_14.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_13.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_38.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_25.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_11.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_2_08.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_4_8.c + # ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_43.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_23.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_36.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_2_03.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_08.c + ${SOURCE_DIR}/tahi_test/netx_tahi_test_3_26.c) + endif() + + if("-DNX_DHCPV6_TAHI_ENABLE" IN_LIST ${CMAKE_BUILD_TYPE}) + set(tahi_dhcpv6_test_cases + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_011.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_036.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_040.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_041.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_037.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_008.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_087.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_013.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_086.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_018.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_071.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_005.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_079.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_082.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_027.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_074.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_003.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_014.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_032.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_026.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_023.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_052.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_015.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_056.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_017.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_009.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_021.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_089.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_008.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_081.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_007.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_021.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_042.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_022.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_053.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_020.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_072.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_019.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_095.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_020.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_027.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_088.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_091.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_019.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_092.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_076.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_058.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_048.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_002.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_025.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_096.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_044.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_030.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_019.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_066.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_043.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_011.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_007.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_045.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_009.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_065.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_004.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_012.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_060.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_014.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_093.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_003.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_005.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_028.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_012.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_013.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_018.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_016.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_061.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_017.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_085.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_038.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_003.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_063.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_025.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_004.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_069.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_005.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_022.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_024.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_007.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_023.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_027.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_067.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_031.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_039.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_010.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_012.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_034.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_020.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_062.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_002.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_014.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_059.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_057.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_021.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_070.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_002.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_054.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_084.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_006.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_010.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_035.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_008.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_006.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_004.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_077.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_064.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_075.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_098.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_046.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_097.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_073.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_050.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_013.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_015.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_009.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_016.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_047.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_024.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_083.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_080.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_026.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_029.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_04_010.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_022.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_026.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_090.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_055.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_049.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_078.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_033.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_051.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_094.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_07_006.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_068.c + ${SOURCE_DIR}/tahi_test/netx_tahi_dhcpv6_test_01_099.c) + endif() + endif() +endif() + +set(telnet_test_cases + ${SOURCE_DIR}/telnet_test/netx_telnet_activity_timeout_test.c + ${SOURCE_DIR}/telnet_test/netx_telnet_max_connections_test.c + ${SOURCE_DIR}/telnet_test/netx_telnet_create_packet_pool_test.c + ${SOURCE_DIR}/telnet_test/netx_telnet_server_options_negotiate_test.c + ${SOURCE_DIR}/telnet_test/netx_telnet_basic_test.c + ${SOURCE_DIR}/telnet_test/netx_telnet_server_bad_option_reply_test.c + ${SOURCE_DIR}/telnet_test/netx_telnet_rst_test.c + ${SOURCE_DIR}/telnet_test/netx_telnet_two_listen_test.c) + +set(tftp_test_cases + ${SOURCE_DIR}/tftp_test/netx_tftp_basic_test.c + ${SOURCE_DIR}/tftp_test/netx_tftp_write_interaction_test.c + ${SOURCE_DIR}/tftp_test/netx_tftp_error_file_name_test.c + ${SOURCE_DIR}/tftp_test/netx_tftp_read_interaction_test.c + ${SOURCE_DIR}/tftp_test/netx_tftp_error_destionation_port_test.c + ${SOURCE_DIR}/tftp_test/netx_tftp_malformed_packet_test.c) + +if(NOT "-DNX_DISABLE_IPV6" IN_LIST ${CMAKE_BUILD_TYPE}) + list(APPEND tftp_test_cases + ${SOURCE_DIR}/tftp_test/netx_tftp_ipv6_basic_test.c) +endif() + +if("full_build" IN_LIST CMAKE_BUILD_TYPE) + # For test cases requires huge CPU resoures, run for full build only + list(APPEND tftp_test_cases + ${SOURCE_DIR}/tftp_test/netx_tftp_large_data_test.c + ${SOURCE_DIR}/netxduo_test/netx_tcp_cwnd_test.c) +endif() + +set(test_utility_files + ${SOURCE_DIR}/test/nx_ram_network_driver_test_1500.c + ${SOURCE_DIR}/test/netxtestcontrol.c + # DHCP utilities + ${SOURCE_DIR}/dhcp_test/netx_dhcp_clone_function.c + # DNS utilities + ${SOURCE_DIR}/dns_test/response_txt_google_com.c + ${SOURCE_DIR}/dns_test/response_cname_mail_baidu_com.c + ${SOURCE_DIR}/dns_test/response_mx_a_berkley_edu.c + ${SOURCE_DIR}/dns_test/response_mx_a_google_com.c + ${SOURCE_DIR}/dns_test/response_soa_google_com.c + ${SOURCE_DIR}/dns_test/response_mx_google_com.c + ${SOURCE_DIR}/dns_test/response_a_berkley_edu.c + ${SOURCE_DIR}/dns_test/response_aaaa_berkley_edu.c + ${SOURCE_DIR}/dns_test/response_srv_google_com.c + ${SOURCE_DIR}/dns_test/response_a_cname_www_npr_org.c + ${SOURCE_DIR}/dns_test/response_a_google_com.c + ${SOURCE_DIR}/dns_test/response_ns_a_ti_com.c + ${SOURCE_DIR}/dns_test/response_with_invalid_resource.c) +if(NOT "$ENV{ENABLE_64}") + list( + APPEND + test_utility_files + # SMTP utilities + ${SOURCE_DIR}/smtp_test/smtp_server_packets.c + # SNMP utilites + ${SOURCE_DIR}/snmp_test/get_snmp_v3_request.c + ${SOURCE_DIR}/snmp_test/snmp_manager_packets.c + ${SOURCE_DIR}/snmp_test/GetSet_Integers_Large_and_Neg_Numbers.c + ${SOURCE_DIR}/snmp_test/GetSet_IPv4v6Address.c + ${SOURCE_DIR}/snmp_test/GetSet_OctetStrings.c + ${SOURCE_DIR}/snmp_test/Get_Miscellaneous_Data_type.c + ${SOURCE_DIR}/snmp_test/small_mib_helper.c) +endif() + +if(PRODUCT STREQUAL netxduo) + if(NOT "$ENV{ENABLE_64}") + list( + APPEND + test_utility_files + # MDNS utilities + ${SOURCE_DIR}/mdns_test/mdns_address_change_test.c + ${SOURCE_DIR}/mdns_test/mdns_announcement_in_multiple_packets_test.c + ${SOURCE_DIR}/mdns_test/mdns_basic_ipv6_announcement_test.c + ${SOURCE_DIR}/mdns_test/mdns_basic_ipv6_query_test.c + ${SOURCE_DIR}/mdns_test/mdns_basic_ipv6_response_test.c + ${SOURCE_DIR}/mdns_test/mdns_case_insensitivity_test.c + ${SOURCE_DIR}/mdns_test/mdns_client_passive_test.c + ${SOURCE_DIR}/mdns_test/mdns_continuous_query_interval_test.c + ${SOURCE_DIR}/mdns_test/mdns_continuous_query_test.c + ${SOURCE_DIR}/mdns_test/mdns_continuous_query_unique_answer_test.c + ${SOURCE_DIR}/mdns_test/mdns_dns_sd_query_test.c + ${SOURCE_DIR}/mdns_test/mdns_dns_sd_response_test.c + ${SOURCE_DIR}/mdns_test/mdns_duplicate_answer_suppression_test.c + ${SOURCE_DIR}/mdns_test/mdns_duplicate_question_suppression_test.c + ${SOURCE_DIR}/mdns_test/mdns_known_answer_ignored_test.c + ${SOURCE_DIR}/mdns_test/mdns_known_answer_suppression_query_half_ttl_test.c + ${SOURCE_DIR}/mdns_test/mdns_known_answer_suppression_query_test.c + ${SOURCE_DIR}/mdns_test/mdns_known_answer_suppression_response_test.c + ${SOURCE_DIR}/mdns_test/mdns_known_answer_suppression_unique_test.c + ${SOURCE_DIR}/mdns_test/mdns_multiple_questions_per_query_test.c + ${SOURCE_DIR}/mdns_test/mdns_poof_test.c + ${SOURCE_DIR}/mdns_test/mdns_probing_conflict_test.c + ${SOURCE_DIR}/mdns_test/mdns_query_and_response_chaos_test.c + ${SOURCE_DIR}/mdns_test/mdns_query_during_probing_test.c + ${SOURCE_DIR}/mdns_test/mdns_query_http_tcp_test.c + ${SOURCE_DIR}/mdns_test/mdns_query_pdl_datastram_tcp_test.c + ${SOURCE_DIR}/mdns_test/mdns_query_printer_tcp_test.c + ${SOURCE_DIR}/mdns_test/mdns_query_rr_timeout_test.c + ${SOURCE_DIR}/mdns_test/mdns_query_smb_tcp_test.c + ${SOURCE_DIR}/mdns_test/mdns_query_start_stop_test.c + ${SOURCE_DIR}/mdns_test/mdns_query_with_tc_test.c + ${SOURCE_DIR}/mdns_test/mdns_response_aggregation_test.c + ${SOURCE_DIR}/mdns_test/mdns_response_interval_test.c + ${SOURCE_DIR}/mdns_test/mdns_response_in_multiple_packets_test.c + ${SOURCE_DIR}/mdns_test/mdns_response_no_delay_test.c + ${SOURCE_DIR}/mdns_test/mdns_response_to_address_query_test.c + ${SOURCE_DIR}/mdns_test/mdns_response_with_tc_test.c + ${SOURCE_DIR}/mdns_test/mdns_server_announcement_with_txt_test.c + ${SOURCE_DIR}/mdns_test/mdns_server_interface_reset.c + ${SOURCE_DIR}/mdns_test/mdns_server_send_goodbye_test.c + ${SOURCE_DIR}/mdns_test/netx_mdns_run_test_case.c + # PTP utilities + ${SOURCE_DIR}/ptp_test/netx_ptp_utility.c) + endif() + list(APPEND test_utility_files + # TAHI utilities + ${SOURCE_DIR}/tahi_test/netx_tahi_run_test_case.c) +endif() +add_library(test_utility ${test_utility_files}) +target_link_libraries(test_utility PUBLIC azrtos::${PRODUCT}) +target_include_directories(test_utility PUBLIC ${SOURCE_DIR}/test + ${SOURCE_DIR}/tahi_test) +target_compile_definitions(test_utility PUBLIC BATCH_TEST CTEST) +if("-DNX_TAHI_ENABLE" IN_LIST ${CMAKE_BUILD_TYPE}) + add_library(tahi SHARED IMPORTED) + if($ENV{ENABLE_64}) + set_target_properties(tahi PROPERTIES IMPORTED_LOCATION + ${SOURCE_DIR}/tahi_test/tahi64.so) + else() + set_target_properties(tahi PROPERTIES IMPORTED_LOCATION + ${SOURCE_DIR}/tahi_test/tahi.so) + endif() + target_link_libraries(test_utility PUBLIC tahi) +endif() + +if($ENV{ENABLE_64}) + set(test_cases ${netxduo_test_cases} ${dhcp_test_cases} ${dns_test_cases}) +elseif($ENV{DHCP_ONLY}) + set(test_cases ${dhcp_test_cases}) +elseif($ENV{DNS_ONLY}) + set(test_cases ${dns_test_cases}) +else() + set(test_cases + ${auto_ip_test_cases} + ${bsd_test_cases} + ${cloud_test_cases} + ${dhcp_test_cases} + ${dns_test_cases} + ${ftp_test_cases} + ${http_test_cases} + ${ipsec_test_cases} + ${mdns_test_cases} + ${nat_test_cases} + ${netxduo_test_cases} + ${websocket_test_cases} + ${pop3_test_cases} + ${ppp_test_cases} + ${pppoe_test_cases} + ${ptp_test_cases} + ${rtp_test_cases} + ${rtsp_test_cases} + ${smtp_test_cases} + ${snmp_test_cases} + ${sntp_test_cases} + ${tahi_test_cases} + ${tahi_dhcpv6_test_cases} + ${telnet_test_cases} + ${tftp_test_cases}) +endif() + +foreach(test_case ${test_cases}) + get_filename_component(test_name ${test_case} NAME_WE) + add_executable(${test_name} ${test_case}) + target_link_libraries(${test_name} PRIVATE test_utility) + add_test(${CMAKE_BUILD_TYPE}::${test_name} ${test_name}) +endforeach() diff --git a/test/cmake/netxduo/run.sh b/test/cmake/netxduo/run.sh new file mode 100755 index 00000000..ff51762d --- /dev/null +++ b/test/cmake/netxduo/run.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +cd $(dirname $0) + +# if threadx repo does not exist, clone it +[ -d ../threadx ] || git clone https://github.com/azure-rtos/threadx.git ../threadx --depth 1 +[ -d ../filex ] || git clone https://github.com/azure-rtos/filex.git ../filex --depth 1 +[ -f .run.sh ] || ln -sf ../threadx/scripts/cmake_bootstrap.sh .run.sh +./.run.sh $* \ No newline at end of file diff --git a/test/cmake/netxduo/samples/CMakeLists.txt b/test/cmake/netxduo/samples/CMakeLists.txt new file mode 100644 index 00000000..a2241c69 --- /dev/null +++ b/test/cmake/netxduo/samples/CMakeLists.txt @@ -0,0 +1,61 @@ +cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR) +cmake_policy(SET CMP0057 NEW) + +project(samples LANGUAGES C) + +set(SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../../samples) + +set(sample_files + ${SOURCE_DIR}/demo_netxduo_dns.c + ${SOURCE_DIR}/demo_netxduo_ftp.c + ${SOURCE_DIR}/demo_netxduo_http.c + ${SOURCE_DIR}/demo_netxduo_snmp.c + ${SOURCE_DIR}/demo_netxduo_sntp_client.c + ${SOURCE_DIR}/demo_netxduo_telnet.c + ${SOURCE_DIR}/demo_netxduo_tftp.c + ${SOURCE_DIR}/demo_netx_duo_tcp.c + ${SOURCE_DIR}/demo_netx_duo_udp.c) + +if("-DNX_BSD_ENABLE" IN_LIST ${CMAKE_BUILD_TYPE}) + list(APPEND sample_files ${SOURCE_DIR}/demo_bsd_raw.c + ${SOURCE_DIR}/demo_bsd_tcp.c ${SOURCE_DIR}/demo_bsd_udp.c) +endif() +if("-DNX_MAX_PHYSICAL_INTERFACES" IN_LIST ${CMAKE_BUILD_TYPE}) + list(APPEND sample_files ${SOURCE_DIR}/demo_netx_duo_multihome_tcp.c + ${SOURCE_DIR}/demo_netx_duo_multihome_udp.c) +endif() +if(("-DNX_PPP_PPPOE_ENABLE" IN_LIST ${CMAKE_BUILD_TYPE}) + AND NOT ("-DNX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE" IN_LIST + ${CMAKE_BUILD_TYPE})) + list(APPEND sample_files ${SOURCE_DIR}/demo_netx_pppoe_client.c + ${SOURCE_DIR}/demo_netx_pppoe_server.c) +endif() +if(NOT ("-DNX_DISABLE_IPV6" IN_LIST ${CMAKE_BUILD_TYPE})) + list(APPEND sample_files ${SOURCE_DIR}/demo_netxduo_dhcpv6_client.c) +endif() +if(NOT "-DNX_DISABLE_IPV4" IN_LIST ${CMAKE_BUILD_TYPE}) + list( + APPEND + sample_files + ${SOURCE_DIR}/demo_netxduo_smtp_client.c + ${SOURCE_DIR}/demo_netxduo_multihome_dhcp_client.c + ${SOURCE_DIR}/demo_netx_ppp.c + ${SOURCE_DIR}/demo_netx_duo_ptp_client.c + ${SOURCE_DIR}/demo_netxduo_dhcp.c + ${SOURCE_DIR}/demo_netxduo_pop3_client.c + ${SOURCE_DIR}/demo_netx_auto_ip.c) +endif() +if((NOT "-DNX_DISABLE_IPV4" IN_LIST ${CMAKE_BUILD_TYPE}) + AND NOT ("-DNX_DISABLE_PACKET_CHAIN" IN_LIST ${CMAKE_BUILD_TYPE})) + list(APPEND sample_files ${SOURCE_DIR}/demo_netx_secure_tls.c) +endif() + +if("-DNX_BSD_RAW_SUPPORT" IN_LIST ${CMAKE_BUILD_TYPE}) + set(sample_files "") +endif() + +foreach(sample_file ${sample_files}) + get_filename_component(sample_file_name ${sample_file} NAME_WE) + add_executable(${sample_file_name} ${sample_file}) + target_link_libraries(${sample_file_name} PRIVATE azrtos::${PRODUCT}) +endforeach() diff --git a/test/regression/auto_ip_test/netx_auto_ip_address_check_test.c b/test/regression/auto_ip_test/netx_auto_ip_address_check_test.c new file mode 100644 index 00000000..8b064f81 --- /dev/null +++ b/test/regression/auto_ip_test/netx_auto_ip_address_check_test.c @@ -0,0 +1,325 @@ +/* This is a small demo of the NetX TCP/IP stack using the AUTO IP module. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_arp.h" + +#include "nx_auto_ip.h" +#include "nx_ram_network_driver_test_1500.h" + + +#define DEMO_STACK_SIZE 4096 + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the AUTO IP structures for each IP instance. */ + +static NX_AUTO_IP auto_ip_0; + + +/* Define the counters used in the demo application... */ +static ULONG address_changes; +static ULONG error_counter; +static UINT checkNum; +static ULONG conn_ip_address; +static UINT check_source_phyAddr; +static UINT check_source_ip; +static UINT check_dest_phyAddr; +static UINT check_dest_ip; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ip_address_changed(NX_IP *ip_ptr, VOID *auto_ip_address); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_arp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_address_check_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + check_source_phyAddr = NX_FALSE; + check_source_ip = NX_FALSE; + check_dest_phyAddr = NX_FALSE; + check_dest_ip = NX_FALSE; + + /* Initializes the variables. */ + error_counter = 0; + checkNum = NX_AUTO_IP_PROBE_NUM + NX_AUTO_IP_ANNOUNCE_NUM; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 4096, 1); + pointer = pointer + 4096; + + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check UDP enable status. */ + if (status) + error_counter++; + + /* Create the AutoIP instance for each IP instance. */ + status = nx_auto_ip_create(&auto_ip_0, "AutoIP 0", &ip_0, pointer, 4096, 2); + pointer = pointer + 4096; + + /* Check AutoIP create status. */ + if (status) + error_counter++; + + /* Start both AutoIP instances. */ + status = nx_auto_ip_start(&auto_ip_0, IP_ADDRESS(169,254,10,10)); + + /* Check AutoIP start status. */ + if (status) + error_counter++; + + + /* Register an IP address change function for each IP instance. */ + status = nx_ip_address_change_notify(&ip_0, ip_address_changed, (void *) &auto_ip_0); + + /* Check IP address change notify status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +ULONG network_mask; + + printf("NetX Test: Auto_IP Address Check Processing Test....................."); + + advanced_packet_process_callback = my_arp_packet_process; + + /* Wait for IP address to be resolved. */ + tx_thread_sleep(NX_AUTO_IP_PROBE_MAX * checkNum * NX_IP_PERIODIC_RATE); + + /* Call IP status check routine. */ + status = nx_ip_status_check(&ip_0, NX_IP_ADDRESS_RESOLVED, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the current IP address. */ + + nx_ip_address_get(&ip_0, &conn_ip_address, &network_mask); + + /* Check whether the AutoIP allocates addresses in the range of 169.254.1.0 through 169.254.254.255.*/ + if((conn_ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0) || (conn_ip_address < IP_ADDRESS(169, 254, 1, 0)) || (conn_ip_address > IP_ADDRESS(169, 254, 254, 255))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Stop the AutoIP instance auto_ip_0. */ + status = nx_auto_ip_stop(&auto_ip_0); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the AutoIP instance auto_ip_0. */ + status = nx_auto_ip_delete(&auto_ip_0); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + + if ((error_counter) ||(check_source_phyAddr != NX_TRUE) || (check_source_ip != NX_TRUE) || (check_dest_phyAddr != NX_TRUE) || (check_dest_ip != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +void ip_address_changed(NX_IP *ip_ptr, VOID *auto_ip_address) +{ + +ULONG ip_address; +ULONG network_mask; +NX_AUTO_IP *auto_ip_ptr; + + + /* Setup pointer to auto IP instance. */ + auto_ip_ptr = (NX_AUTO_IP *) auto_ip_address; + + /* Pickup the current IP address. */ + nx_ip_address_get(ip_ptr, &ip_address, &network_mask); + + /* Determine if the IP address has changed back to zero. If so, make sure the + AutoIP instance is started. */ + if (ip_address == 0) + { + + /* Get the last AutoIP address for this node. */ + nx_auto_ip_get_address(auto_ip_ptr, &ip_address); + + /* Start this AutoIP instance. */ + nx_auto_ip_start(auto_ip_ptr, ip_address); + } + + /* Determine if the IP address has transitioned to a non local IP address. */ + else if ((ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0)) + { + + /* Stop the AutoIP processing. */ + nx_auto_ip_stop(auto_ip_ptr); + + /* Delete the AutoIP instance. */ + nx_auto_ip_delete(auto_ip_ptr); + } + + /* Increment a counter. */ + address_changes++; +} + + + +static UINT my_arp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +ULONG *message_ptr; +ULONG sender_physical_msw; +ULONG sender_physical_lsw; +ULONG sender_ip_address; +ULONG target_physical_msw; +ULONG target_physical_lsw; +ULONG target_ip_address; +UINT message_type; + + /* Setup a pointer to the ARP message. */ + message_ptr = (ULONG *) packet_ptr -> nx_packet_prepend_ptr; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Pickup the ARP message type. */ + message_type = (UINT) (*(message_ptr+1) & 0xFFFF); + + /* Pick up the sender's physical address from the message. */ + sender_physical_msw = (*(message_ptr+2) >> 16); + sender_physical_lsw = (*(message_ptr+2) << 16) | (*(message_ptr+3) >> 16); + sender_ip_address = (*(message_ptr+3) << 16) | (*(message_ptr+4) >> 16); + target_physical_msw = (*(message_ptr+4) >> 16); + target_physical_lsw = (*(message_ptr+5)); + target_ip_address = (*(message_ptr+6)); + + if (message_type != NX_ARP_OPTION_REQUEST) + error_counter++; + else + { + if((sender_physical_msw == ip_ptr -> nx_ip_interface[auto_ip_0.nx_ip_interface_index].nx_interface_physical_address_msw) && (sender_physical_lsw == ip_ptr -> nx_ip_interface[auto_ip_0.nx_ip_interface_index].nx_interface_physical_address_lsw)) + check_source_phyAddr = NX_TRUE; + if(sender_ip_address == 0) + check_source_ip = NX_TRUE; + if((target_physical_msw == 0) && (target_physical_lsw == 0)) + check_dest_phyAddr = NX_TRUE; + if(target_ip_address == IP_ADDRESS(169,254,10,10)) + check_dest_ip = NX_TRUE; + } + + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + advanced_packet_process_callback = NX_NULL; + return NX_TRUE; + + + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_address_check_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Auto_IP Address Check Processing Test.....................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/auto_ip_test/netx_auto_ip_announce_num_test.c b/test/regression/auto_ip_test/netx_auto_ip_announce_num_test.c new file mode 100644 index 00000000..80e25aa6 --- /dev/null +++ b/test/regression/auto_ip_test/netx_auto_ip_announce_num_test.c @@ -0,0 +1,307 @@ +/* Having probed to determine a unique address to use, the host MUST then announce its claimed address by broadcasting + ANNOUNCE_NUM ARP announcements, spaced ANNOUNCE_INTERVAL seconds apart. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_arp.h" + +#include "nx_auto_ip.h" +#include "nx_ram_network_driver_test_1500.h" + + +#define DEMO_STACK_SIZE 4096 + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the AUTO IP structures for each IP instance. */ + +static NX_AUTO_IP auto_ip_0; + + +/* Define the counters used in the demo application... */ +static ULONG address_changes; +static ULONG error_counter; +static UINT checkNum; +static ULONG conn_ip_address; +static UINT announce_num; +static UINT current_time; +static UINT start_time; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ip_address_changed(NX_IP *ip_ptr, VOID *auto_ip_address); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_arp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_announce_num_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + + /* Initializes the variables. */ + error_counter = 0; + announce_num = 0; + current_time = 0; + start_time = 0; + checkNum = NX_AUTO_IP_PROBE_NUM + NX_AUTO_IP_ANNOUNCE_NUM; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 4096, 1); + pointer = pointer + 4096; + + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check UDP enable status. */ + if (status) + error_counter++; + + /* Create the AutoIP instance for each IP instance. */ + status = nx_auto_ip_create(&auto_ip_0, "AutoIP 0", &ip_0, pointer, 4096, 2); + pointer = pointer + 4096; + + /* Check AutoIP create status. */ + if (status) + error_counter++; + + /* Start both AutoIP instances. */ + status = nx_auto_ip_start(&auto_ip_0, IP_ADDRESS(169,254,10,10)); + + /* Check AutoIP start status. */ + if (status) + error_counter++; + + + /* Register an IP address change function for each IP instance. */ + status = nx_ip_address_change_notify(&ip_0, ip_address_changed, (void *) &auto_ip_0); + + /* Check IP address change notify status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +ULONG network_mask; + + printf("NetX Test: Auto_IP Announce NUM Processing Test......................"); + + advanced_packet_process_callback = my_arp_packet_process; + + /* Wait for IP address to be resolved. */ + tx_thread_sleep(NX_AUTO_IP_PROBE_MAX * checkNum * NX_IP_PERIODIC_RATE); + + /* Call IP status check routine. */ + status = nx_ip_status_check(&ip_0, NX_IP_ADDRESS_RESOLVED, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the current IP address. */ + + nx_ip_address_get(&ip_0, &conn_ip_address, &network_mask); + + /* Check whether the AutoIP allocates addresses in the range of 169.254.1.0 through 169.254.254.255.*/ + if((conn_ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0) || (conn_ip_address < IP_ADDRESS(169, 254, 1, 0)) || (conn_ip_address > IP_ADDRESS(169, 254, 254, 255))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Stop the AutoIP instance auto_ip_0. */ + status = nx_auto_ip_stop(&auto_ip_0); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the AutoIP instance auto_ip_0. */ + status = nx_auto_ip_delete(&auto_ip_0); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if ((error_counter) ||(announce_num != NX_AUTO_IP_ANNOUNCE_NUM)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +void ip_address_changed(NX_IP *ip_ptr, VOID *auto_ip_address) +{ + +ULONG ip_address; +ULONG network_mask; +NX_AUTO_IP *auto_ip_ptr; + + + /* Setup pointer to auto IP instance. */ + auto_ip_ptr = (NX_AUTO_IP *) auto_ip_address; + + /* Pickup the current IP address. */ + nx_ip_address_get(ip_ptr, &ip_address, &network_mask); + + /* Determine if the IP address has changed back to zero. If so, make sure the + AutoIP instance is started. */ + if (ip_address == 0) + { + + /* Get the last AutoIP address for this node. */ + nx_auto_ip_get_address(auto_ip_ptr, &ip_address); + + /* Start this AutoIP instance. */ + nx_auto_ip_start(auto_ip_ptr, ip_address); + } + + /* Determine if the IP address has transitioned to a non local IP address. */ + else if ((ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0)) + { + + /* Stop the AutoIP processing. */ + nx_auto_ip_stop(auto_ip_ptr); + + /* Delete the AutoIP instance. */ + nx_auto_ip_delete(auto_ip_ptr); + } + + /* Increment a counter. */ + address_changes++; +} + + + +static UINT my_arp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +ULONG *message_ptr; +UINT message_type; + + /* Setup a pointer to the ARP message. */ + message_ptr = (ULONG *) packet_ptr -> nx_packet_prepend_ptr; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + + /* Pickup the ARP message type. */ + message_type = (UINT) (*(message_ptr+1) & 0xFFFF); + + if (message_type != NX_ARP_OPTION_REQUEST) + error_counter++; + else + { + if(announce_num == 0) + { + start_time = tx_time_get(); + announce_num++; + } + else + { + current_time = tx_time_get(); + + if(current_time >= start_time + (announce_num * NX_IP_PERIODIC_RATE * NX_AUTO_IP_ANNOUNCE_INTERVAL)) + announce_num++; + } + } + + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + + if(announce_num == NX_AUTO_IP_ANNOUNCE_NUM) + advanced_packet_process_callback = NULL; + + return NX_TRUE; + + + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_announce_num_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Auto_IP Announce NUM Processing Test......................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/auto_ip_test/netx_auto_ip_arp_dest_addr_test.c b/test/regression/auto_ip_test/netx_auto_ip_arp_dest_addr_test.c new file mode 100644 index 00000000..d0ea8b13 --- /dev/null +++ b/test/regression/auto_ip_test/netx_auto_ip_arp_dest_addr_test.c @@ -0,0 +1,501 @@ +/* This is a small demo of the NetX TCP/IP stack using the AUTO IP module. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_auto_ip.h" +#include "nx_arp.h" +#include "nx_ram_network_driver_test_1500.h" + + + +#define DEMO_STACK_SIZE 4096 + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET client_socket; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; + + +/* Define the AUTO IP structures for each IP instance. */ + +static NX_AUTO_IP auto_ip_0; +static NX_AUTO_IP auto_ip_1; + + +/* Define the counters used in the demo application... */ +static ULONG address_changes; +static ULONG error_counter; +static ULONG packet_counter; +static UINT checkNum; +static ULONG conn_ip_address; +static UINT is_arped; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +static void ip_address_changed(NX_IP *ip_ptr, VOID *auto_ip_address); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_arp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_arp_dest_addr_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initializes the variables. */ + error_counter = 0; + packet_counter = 0; + is_arped = NX_FALSE; + + checkNum = NX_AUTO_IP_PROBE_NUM + NX_AUTO_IP_ANNOUNCE_NUM; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 4096, 1); + pointer = pointer + 4096; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 4096, 1); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check UDP enable status. */ + if (status) + error_counter++; + + /* Create the AutoIP instance for each IP instance. */ + status = nx_auto_ip_create(&auto_ip_0, "AutoIP 0", &ip_0, pointer, 4096, 2); + pointer = pointer + 4096; + status += nx_auto_ip_create(&auto_ip_1, "AutoIP 1", &ip_1, pointer, 4096, 2); + pointer = pointer + 4096; + + /* Check AutoIP create status. */ + if (status) + error_counter++; + + /* Start both AutoIP instances. */ + status = nx_auto_ip_start(&auto_ip_0, 0 /*IP_ADDRESS(169,254,254,255)*/); + status += nx_auto_ip_start(&auto_ip_1, 0 /*IP_ADDRESS(169,254,254,255)*/); + + /* Check AutoIP start status. */ + if (status) + error_counter++; + + /* Register an IP address change function for each IP instance. */ + status = nx_ip_address_change_notify(&ip_0, ip_address_changed, (void *) &auto_ip_0); + status += nx_ip_address_change_notify(&ip_1, ip_address_changed, (void *) &auto_ip_1); + + /* Check IP address change notify status. */ + if (status) + error_counter++; + + /* Create semaphores. */ + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + + /* Check semaphore create status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG network_mask; + + printf("NetX Test: Auto_IP ARP Destination Address Processing Test..........."); + + advanced_packet_process_callback = my_arp_packet_process; + + status = tx_semaphore_get(&sema_0, (NX_AUTO_IP_PROBE_NUM * NX_AUTO_IP_PROBE_MAX + NX_AUTO_IP_ANNOUNCE_NUM * NX_AUTO_IP_ANNOUNCE_INTERVAL) * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wakeup thread_1. */ + tx_semaphore_put(&sema_1); + + /* Pickup the current IP address. */ + + nx_ip_address_get(&ip_0, &conn_ip_address, &network_mask); + + /* Check whether the AutoIP allocates addresses in the range of 169.254.1.0 through 169.254.254.255.*/ + if((conn_ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0) || (conn_ip_address < IP_ADDRESS(169, 254, 1, 0)) || (conn_ip_address > IP_ADDRESS(169, 254, 254, 255))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check status. */ + if (status) + error_counter++; + + + + /* Setup this thread to listen. */ + + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Server socket disconnect the connection. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisted on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Stop the AutoIP instance auto_ip_0. */ + status = nx_auto_ip_stop(&auto_ip_0); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the AutoIP instance auto_ip_0. */ + status = nx_auto_ip_delete(&auto_ip_0); + + /* Check for error. */ + if(status) + error_counter++; + +} + + +void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_address; +ULONG network_mask; + + status = tx_semaphore_get(&sema_1, (NX_AUTO_IP_PROBE_NUM * NX_AUTO_IP_PROBE_MAX + NX_AUTO_IP_ANNOUNCE_NUM * NX_AUTO_IP_ANNOUNCE_INTERVAL) * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_semaphore_get(&sema_1, TX_WAIT_FOREVER); + + /* Pickup the current IP address. */ + nx_ip_address_get(&ip_1, &ip_address, &network_mask); + + /* Check whether the AutoIP allocates addresses in the range of 169.254.1.0 through 169.254.254.255.*/ + if((ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0) || (ip_address < IP_ADDRESS(169, 254, 1, 0)) || (ip_address > IP_ADDRESS(169, 254, 254, 255))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, conn_ip_address, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Stop the AutoIP instance auto_ip_1. */ + status = nx_auto_ip_stop(&auto_ip_1); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the AutoIP instance auto_ip_1. */ + status = nx_auto_ip_delete(&auto_ip_1); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if ((error_counter) || (is_arped != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void ip_address_changed(NX_IP *ip_ptr, VOID *auto_ip_address) +{ + +ULONG ip_address; +ULONG network_mask; +NX_AUTO_IP *auto_ip_ptr; + + + /* Setup pointer to auto IP instance. */ + auto_ip_ptr = (NX_AUTO_IP *) auto_ip_address; + + /* Pickup the current IP address. */ + nx_ip_address_get(ip_ptr, &ip_address, &network_mask); + + /* Determine if the IP address has changed back to zero. If so, make sure the + AutoIP instance is started. */ + if (ip_address == 0) + { + + /* Get the last AutoIP address for this node. */ + nx_auto_ip_get_address(auto_ip_ptr, &ip_address); + + /* Start this AutoIP instance. */ + nx_auto_ip_start(auto_ip_ptr, ip_address); + } + + /* Determine if the IP address has transitioned to a non local IP address. */ + else if ((ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0)) + { + + /* Stop the AutoIP processing. */ + nx_auto_ip_stop(auto_ip_ptr); + + /* Delete the AutoIP instance. */ + nx_auto_ip_delete(auto_ip_ptr); + } + + /* Increment a counter. */ + address_changes++; + + /* Wakeup test threads. */ + if(ip_ptr == &ip_0) + tx_semaphore_put(&sema_0); + else + tx_semaphore_put(&sema_1); +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +static UINT my_arp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +ULONG *message_ptr; +UINT message_type; +#if 0 +ULONG target_ip_address; +#endif + + /* Setup a pointer to the ARP message. */ + message_ptr = (ULONG *) packet_ptr -> nx_packet_prepend_ptr; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Pickup the ARP message type. */ + message_type = (UINT) (*(message_ptr+1) & 0xFFFF); +#if 0 + target_ip_address = (*(message_ptr+6)); +#endif + + if (message_type != NX_ARP_OPTION_REQUEST) + error_counter++; + else + { +#if 0 + /* Not clear about the purpose here. Removed by Tiejun. */ + if(target_ip_address == ip_ptr -> nx_ip_interface[auto_ip_0.nx_ip_interface_index].nx_interface_ip_address) +#endif + is_arped = NX_TRUE; + advanced_packet_process_callback = NULL; + } + + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + + + return NX_TRUE; + + + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_arp_dest_addr_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Auto_IP ARP Destination Address Processing Test...........N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/auto_ip_test/netx_auto_ip_basic_test.c b/test/regression/auto_ip_test/netx_auto_ip_basic_test.c new file mode 100644 index 00000000..a6ae5e54 --- /dev/null +++ b/test/regression/auto_ip_test/netx_auto_ip_basic_test.c @@ -0,0 +1,438 @@ +/* This is a small demo of the NetX TCP/IP stack using the AUTO IP module. */ + +#include "nx_auto_ip.h" +#include "tx_api.h" +#include "nx_api.h" + + +#define DEMO_STACK_SIZE 4096 + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET client_socket; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; + + +/* Define the AUTO IP structures for each IP instance. */ + +static NX_AUTO_IP auto_ip_0; +static NX_AUTO_IP auto_ip_1; + + +/* Define the counters used in the demo application... */ +static ULONG address_changes; +static ULONG error_counter; +static ULONG packet_counter; +static ULONG conn_ip_address; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +static void ip_address_changed(NX_IP *ip_ptr, VOID *auto_ip_address); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initializes the variables. */ + error_counter = 0; + packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 4096, 1); + pointer = pointer + 4096; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 4096, 1); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check UDP enable status. */ + if (status) + error_counter++; + + /* Create the AutoIP instance for each IP instance. */ + status = nx_auto_ip_create(&auto_ip_0, "AutoIP 0", &ip_0, pointer, 4096, 2); + pointer = pointer + 4096; + status += nx_auto_ip_create(&auto_ip_1, "AutoIP 1", &ip_1, pointer, 4096, 2); + pointer = pointer + 4096; + + /* Check AutoIP create status. */ + if (status) + error_counter++; + + /* Start both AutoIP instances. */ + status = nx_auto_ip_start(&auto_ip_0, 0 /*IP_ADDRESS(169,254,254,255)*/); + status += nx_auto_ip_start(&auto_ip_1, 0 /*IP_ADDRESS(169,254,254,255)*/); + + /* Check AutoIP start status. */ + if (status) + error_counter++; + + /* Register an IP address change function for each IP instance. */ + status = nx_ip_address_change_notify(&ip_0, ip_address_changed, (void *) &auto_ip_0); + status += nx_ip_address_change_notify(&ip_1, ip_address_changed, (void *) &auto_ip_1); + + /* Check IP address change notify status. */ + if (status) + error_counter++; + + /* Create semaphores. */ + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + + /* Check semaphore create status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG network_mask; + + printf("NetX Test: Auto_IP Basic Processing Test............................."); + + status = tx_semaphore_get(&sema_0, (NX_AUTO_IP_PROBE_NUM * NX_AUTO_IP_PROBE_MAX + NX_AUTO_IP_ANNOUNCE_NUM * NX_AUTO_IP_ANNOUNCE_INTERVAL) * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wakeup thread_1. */ + tx_semaphore_put(&sema_1); + + /* Pickup the current IP address. */ + + nx_ip_address_get(&ip_0, &conn_ip_address, &network_mask); + + /* Check whether the AutoIP allocates addresses in the range of 169.254.1.0 through 169.254.254.255.*/ + if((conn_ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0) || (conn_ip_address < IP_ADDRESS(169, 254, 1, 0)) || (conn_ip_address > IP_ADDRESS(169, 254, 254, 255))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check status. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Server socket disconnect the connection. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisted on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Stop the AutoIP instance auto_ip_0. */ + status = nx_auto_ip_stop(&auto_ip_0); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the AutoIP instance auto_ip_0. */ + status = nx_auto_ip_delete(&auto_ip_0); + + /* Check for error. */ + if(status) + error_counter++; + +} + + +void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_address; +ULONG network_mask; + + status = tx_semaphore_get(&sema_1, (NX_AUTO_IP_PROBE_NUM * NX_AUTO_IP_PROBE_MAX + NX_AUTO_IP_ANNOUNCE_NUM * NX_AUTO_IP_ANNOUNCE_INTERVAL) * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_semaphore_get(&sema_1, TX_WAIT_FOREVER); + + /* Pickup the current IP address. */ + nx_ip_address_get(&ip_1, &ip_address, &network_mask); + + /* Check whether the AutoIP allocates addresses in the range of 169.254.1.0 through 169.254.254.255.*/ + if((ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0) || (ip_address < IP_ADDRESS(169, 254, 1, 0)) || (ip_address > IP_ADDRESS(169, 254, 254, 255))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, conn_ip_address, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Stop the AutoIP instance auto_ip_1. */ + status = nx_auto_ip_stop(&auto_ip_1); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the AutoIP instance auto_ip_1. */ + status = nx_auto_ip_delete(&auto_ip_1); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void ip_address_changed(NX_IP *ip_ptr, VOID *auto_ip_address) +{ + +ULONG ip_address; +ULONG network_mask; +NX_AUTO_IP *auto_ip_ptr; + + + /* Setup pointer to auto IP instance. */ + auto_ip_ptr = (NX_AUTO_IP *) auto_ip_address; + + /* Pickup the current IP address. */ + nx_ip_address_get(ip_ptr, &ip_address, &network_mask); + + /* Determine if the IP address has changed back to zero. If so, make sure the + AutoIP instance is started. */ + if (ip_address == 0) + { + + /* Get the last AutoIP address for this node. */ + nx_auto_ip_get_address(auto_ip_ptr, &ip_address); + + /* Start this AutoIP instance. */ + nx_auto_ip_start(auto_ip_ptr, ip_address); + } + + /* Determine if the IP address has transitioned to a non local IP address. */ + else if ((ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0)) + { + + /* Stop the AutoIP processing. */ + nx_auto_ip_stop(auto_ip_ptr); + + /* Delete the AutoIP instance. */ + nx_auto_ip_delete(auto_ip_ptr); + } + + /* Increment a counter. */ + address_changes++; + + /* Wakeup test threads. */ + if(ip_ptr == &ip_0) + tx_semaphore_put(&sema_0); + else + tx_semaphore_put(&sema_1); +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Auto_IP Basic Processing Test.............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/auto_ip_test/netx_auto_ip_conflicts_check_test.c b/test/regression/auto_ip_test/netx_auto_ip_conflicts_check_test.c new file mode 100644 index 00000000..5586a280 --- /dev/null +++ b/test/regression/auto_ip_test/netx_auto_ip_conflicts_check_test.c @@ -0,0 +1,320 @@ +/* This is a small demo of the NetX TCP/IP stack using the AUTO IP module. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_arp.h" + +#include "nx_auto_ip.h" +#include "nx_ram_network_driver_test_1500.h" + + +#define DEMO_STACK_SIZE 4096 + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the AUTO IP structures for each IP instance. */ + +static NX_AUTO_IP auto_ip_0; + + +/* Define the counters used in the demo application... */ +static ULONG address_changes; +static ULONG error_counter; +static UINT checkNum; +static UINT conflicts_check_counter; +static UINT conflicts_counter; +static UINT is_conflicted; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ip_address_changed(NX_IP *ip_ptr, VOID *auto_ip_address); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_arp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_conflicts_check_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + + /* Initializes the variables. */ + error_counter = 0; + conflicts_check_counter = 0; + conflicts_counter = 0; + is_conflicted = NX_FALSE; + + checkNum = NX_AUTO_IP_PROBE_NUM + NX_AUTO_IP_ANNOUNCE_NUM; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 4096, 1); + pointer = pointer + 4096; + + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check UDP enable status. */ + if (status) + error_counter++; + + /* Create the AutoIP instance for each IP instance. */ + status = nx_auto_ip_create(&auto_ip_0, "AutoIP 0", &ip_0, pointer, 4096, 2); + pointer = pointer + 4096; + + /* Check AutoIP create status. */ + if (status) + error_counter++; + + /* Start both AutoIP instances. */ + status = nx_auto_ip_start(&auto_ip_0, IP_ADDRESS(169,254,10,10)); + + /* Check AutoIP start status. */ + if (status) + error_counter++; + + + /* Register an IP address change function for each IP instance. */ + status = nx_ip_address_change_notify(&ip_0, ip_address_changed, (void *) &auto_ip_0); + + /* Check IP address change notify status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +UINT i; + + printf("NetX Test: Auto_IP Conflicts Check Processing Test..................."); + + advanced_packet_process_callback = my_arp_packet_process; + + + /* Wait for IP address to be resolved. */ + for(i=0; i nx_packet_prepend_ptr; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Pickup the ARP message type. */ + message_type = (UINT) (*(message_ptr+1) & 0xFFFF); + + /* Pick up the sender's physical address from the message. */ + sender_physical_msw = (*(message_ptr+2) >> 16); + sender_physical_lsw = (*(message_ptr+2) << 16) | (*(message_ptr+3) >> 16); + target_ip_address = (*(message_ptr+6)); + + if (message_type != NX_ARP_OPTION_REQUEST) + error_counter++; + else + { + if((sender_physical_msw == ip_ptr -> nx_ip_interface[auto_ip_0.nx_ip_interface_index].nx_interface_physical_address_msw) && (sender_physical_lsw == ip_ptr -> nx_ip_interface[auto_ip_0.nx_ip_interface_index].nx_interface_physical_address_lsw) + && (target_ip_address == IP_ADDRESS(169,254,10,10)) && (conflicts_check_counter == 0)) + { + sender_physical_msw = 0; + conflicts_check_counter = 1; + conflicts_counter = auto_ip_0.nx_auto_ip_conflict_count; + } + else if(conflicts_check_counter == 1) + { + if(auto_ip_0.nx_auto_ip_conflict_count == (conflicts_counter + 1)) + is_conflicted = NX_TRUE; + + advanced_packet_process_callback = NX_NULL; + } + + } + + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + + return NX_TRUE; + + + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_conflicts_check_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Auto_IP Conflicts Check Processing Test...................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/auto_ip_test/netx_auto_ip_max_conflicts_test.c b/test/regression/auto_ip_test/netx_auto_ip_max_conflicts_test.c new file mode 100644 index 00000000..c7f35731 --- /dev/null +++ b/test/regression/auto_ip_test/netx_auto_ip_max_conflicts_test.c @@ -0,0 +1,304 @@ +/* This is a small demo of the NetX TCP/IP stack using the AUTO IP module. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_arp.h" +#include "nx_auto_ip.h" +#include "nx_ram_network_driver_test_1500.h" + + +#define DEMO_STACK_SIZE 4096 + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the AUTO IP structures for each IP instance. */ + +static NX_AUTO_IP auto_ip_0; + + +/* Define the counters used in the demo application... */ +static ULONG error_counter; +static UINT current_time; +static UINT start_time; +static UINT arp_probe; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_arp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_max_conflicts_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initializes the variables. */ + error_counter = 0; + current_time = 0; + start_time = 0; + arp_probe = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 4096, 1); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + + /* Create the AutoIP instance for each IP instance. */ + status = nx_auto_ip_create(&auto_ip_0, "AutoIP 0", &ip_0, pointer, 4096, 2); + pointer = pointer + 4096; + + /* Check AutoIP create status. */ + if (status) + error_counter++; + + /* Start both AutoIP instances. */ + status = nx_auto_ip_start(&auto_ip_0, IP_ADDRESS(169,254,10,10)); + + /* Check AutoIP start status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +ULONG conn_ip_address; +ULONG network_mask; + + printf("NetX Test: Auto_IP MAX Conflicts Processing Test....................."); + + advanced_packet_process_callback = my_arp_packet_process; + + /* Call IP status check routine. */ + status = nx_ip_status_check(&ip_0, NX_IP_ADDRESS_RESOLVED, &actual_status, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the current IP address. */ + nx_ip_address_get(&ip_0, &conn_ip_address, &network_mask); + + /* Check whether the AutoIP allocates addresses in the range of 169.254.1.0 through 169.254.254.255.*/ + if((conn_ip_address & 0xFFFF0000UL) != IP_ADDRESS(169, 254, 0, 0) || (conn_ip_address < IP_ADDRESS(169, 254, 1, 0)) || (conn_ip_address > IP_ADDRESS(169, 254, 254, 255))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Stop the AutoIP instance auto_ip_0. */ + status = nx_auto_ip_stop(&auto_ip_0); + + /* Check for error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the AutoIP instance auto_ip_0. */ + status = nx_auto_ip_delete(&auto_ip_0); + + /* Check for error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if ((error_counter) || (arp_probe != (NX_AUTO_IP_MAX_CONFLICTS + 2)) || + (auto_ip_0.nx_auto_ip_conflict_count != (NX_AUTO_IP_MAX_CONFLICTS + 1))) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_arp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +ULONG *message_ptr; +UINT message_type; +ULONG sender_mac_msw; +ULONG sender_mac_lsw; +ULONG sender_ip; +ULONG receive_mac_msw; +ULONG receive_mac_lsw; +ULONG receive_ip; +NX_PACKET *conflict_packet; + + + /* Setup a pointer to the ARP message. */ + message_ptr = (ULONG *) packet_ptr -> nx_packet_prepend_ptr; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 6)); + + /* Pickup the ARP message type. */ + message_type = (UINT)(*(message_ptr+1) & 0xFFFF); + + /* Pick up the mac and ip address. */ + sender_mac_msw = (*(message_ptr + 2) >> 16); + sender_mac_lsw = ((*(message_ptr + 2) & 0x0000FFFF) << 16) | (*(message_ptr + 3) >> 16); + sender_ip = ((*(message_ptr + 3) & 0x0000FFFF) << 16) | (*(message_ptr + 4) >> 16); + receive_mac_msw = (*(message_ptr + 4) & 0x0000FFFF); + receive_mac_lsw = (*(message_ptr + 5)); + receive_ip = *(message_ptr + 6); + + /* Check if ARP probe. */ + if ((message_type != NX_ARP_OPTION_REQUEST) || + (sender_mac_msw != ip_ptr -> nx_ip_interface[0].nx_interface_physical_address_msw) || + (sender_mac_lsw != ip_ptr -> nx_ip_interface[0].nx_interface_physical_address_lsw) || + (sender_ip != 0) || + (receive_mac_msw != 0) || + (receive_mac_lsw != 0) || + (receive_ip != auto_ip_0.nx_auto_ip_current_local_address)) + { + error_counter++; + return NX_TRUE; + } + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 6)); + + /* Update the arp counter. */ + arp_probe ++; + + /* Check the arp counter. */ + if (arp_probe <= (NX_AUTO_IP_MAX_CONFLICTS + 1)) + { + + /* Check the conflict count. */ + if (arp_probe != (auto_ip_0.nx_auto_ip_conflict_count + 1)) + { + error_counter++; + return NX_TRUE; + } + + /* Initialize the conflict start time. */ + if (arp_probe == (NX_AUTO_IP_MAX_CONFLICTS + 1)) + start_time = tx_time_get(); + + /* Inject conflict arp. */ + if (nx_packet_copy(packet_ptr, &conflict_packet, &pool_0, NX_NO_WAIT)) + { + error_counter++; + return NX_TRUE; + } + + /* Setup a pointer to the conflict ARP message. */ + message_ptr = (ULONG *) conflict_packet -> nx_packet_prepend_ptr; + + /* Just change the sender mac of probe to act as conflict ARP. */ + *(message_ptr + 2) -= 1; + + /* Receive conflict arp. */ + _nx_arp_packet_deferred_receive(ip_ptr, conflict_packet); + } + else + { + current_time = tx_time_get(); + + /* Check the extra delay. */ + if ((current_time - start_time) < (NX_IP_PERIODIC_RATE * NX_AUTO_IP_RATE_LIMIT_INTERVAL)) + error_counter++; + + advanced_packet_process_callback = NX_NULL; + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_auto_ip_max_conflicts_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Auto_IP MAX Conflicts Processing Test.....................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/bsd_test_setup.docx b/test/regression/bsd_test/bsd_test_setup.docx new file mode 100644 index 0000000000000000000000000000000000000000..38b4c031027d372dcb817df947a5a91c144b7c60 GIT binary patch literal 24408 zcmeFZ^Rs9%lr?y5+qP}nwr$(CZQJ+0i+63?wrzV}_f*&P%=CZIUw%lXPEw~T$y!-E z`|N!bq=7+D0Kfns000080T{+9V4MH}07^jt0FVJ7fV73}?OaUlT=Z2u9Za2d={#(0 z2#P>}C<*|8{*C`X<$v)CG^>o;4KN^dt6%Vo^r%G^hF4WV;B??shi>ua6#)_L^go?WZv82#&J_ z*syf4yvSpP-n1`(Oq$|}m$DBN!S z4d&Y#kRwET_!85)C?;dDh1q+@wejpcqO5Uz0_03RH1VytEEhO_;s+WkDZHNT|3XwM zdZPdHj_bVol1)X%<YmbmtG>-*^cQ1<%^450A;qAFe@R_o)x9=U%^g#JfWeJ4{JXL`E-sQ(W| z{}=P}zfCtq z>2y+lB|A8KiMyN!tlm&_xnM2ZKz!HQ!?raVTtRb8J1fW>R(z(x($0Q`o+mM-kSB(* zy6B)OOpt_+$c(w6SSNI>N2MbHM-oywK5+{BIi|X!XY@%OI4iSkLlf50{8pf4RD(@_ z1x}Y8%MZ%zc5N~ebqw6lex1&U%0_a;Db|YenFh;-VU{#E(WnNBZO^i3`B~&wKRPay z2C@(`a`w^3H3wKr58h?H$aA!w8=p{<2F=&|Q#iPZ-h%I+X#M{=($o`;3;D0-FE9WA z4gdt8ySuuCY$YquS@EcnNwQQNopd_!Hg;>vPTzzdLnR8$kLxjw}}EQXw!BL%E{UQ!&X#{_*g%Ik&nnCUx$cETYZvEAq$npe^hV7;O|3@gTNvU8^(EtFj`v3wU{zJ%r zLg~MQ=t@^x`A{OwZ#Uu_UMtT4sLIBflAw&o&<+`OQ&$vVnfG&v&<2x*R2xq+%qZ`J z|7uZe>Z|>S^fNa(Q>iQ^$+Q7_vrWI^@0H5Qc=G8(uJq44{VsUm|SW`9R&DKLly_*FMF3)zdfXrC4vh9l|4VScho_!p3mls< z!-070Lkka@@HNc0ZHkydKOufjxKH2S%W?h-bj94)DE+)~%17*7alHV}kioYd{9&u+ zerNGPq}yczc-3eR43G=&_+l>mOVJzR7h{A7Oa3rLdz4UJ`ndb^OplDXH5-*~ZKQ-S z34cX%s1xpG8L&EjnQ+3Jv1|Vh&)Wvi+u_dLMTK=CfoL|5bG9qq`Q5}v4;Z~GUEeJW z7QQRoEBqkBV{vo6U0iU<`|;8jM0h96`~1rz%DcNuaQ3&hd(JMrc3lLUL*LKY+k3JP zq;KDKYwpia^jKy+;P?o@*wvjk$-Q}M{P^(0z>Exh9uO<7*r)aKypI~nati+fGH9kb z2FcHnXynrk=@DWrfq}^kKgQ4LZZYaoyTC9-jF;JB2xqB0v9%44BhY@=1F^`AKRJ`; z^zYe>&9~almZn>QlIPp~CnLO1E z`kZ}7mJJYsXD*L@KEXt6x>RCa~@GF@ZWM#%WzM|k98&JJ!! z-_d*D*$Fn85cu4Gc#t;Vk7-ygXJmOUVCw9}KRc`rW46(hnz23UBx{ctUHEjl{FZ0s zU$e?jQ-vHQ%E)1GuW(_>epf9yvVYE6N78`Tfv-abaX{qXV`+Fzt{q|ML0nI6k)>IG#GjK?F@1IG1Q;pQ;`oXKJOV5I=(%n;Cyx(tu4qd?Jc9-yCk_r5M zt_RoK$1!Y9`EWesrkIR2F}q^49Du$MX}qt}OZ=}~whNsvIqj1AdJspk^DRa(e4J0n z=J4%au_-@EoWk$>So+=ti(k1n04g@R&RDZ>0yX%i1AS5I$ z83Cw+x$8-Rm$VbrTMgDQ6k{1DjluH)jq5MQeg-jLbZ>SwSlfC+&*I&Sqo$XI08u); zp@m~<6J3L!0dA*0TuT(0qMcpC)tyOUEXj`nT?nSdAN+MRw!Iv$K>d; zzq$pe45&eeZyk?w&ke-Bg5Ze;3HNwX+P~$Pfy@|w3@bAR%VuxA3*A}Ohx*LQ?*3!j z>FtdlCs)mLV7DhI!tLN=u*123y<524PjLtI7BJZ9w0AX_B46aljtMM+FhKgyASmQ< zz)S&MjvopPepf1~CqWUBWC-D2usga&LnW4g1EM}~p|W6n<~zz9k>LJ*&48v744)f^ zpvw-kCjlQarEtZPdtL}lN@=PV=N6h#f)(O3$Uj%d?=Q15nvF}W;ynIYl6#2)P#Z7b_j~aBQrod zRKqe#za#7obEM}p@pzZTrd=+)!&kDd$a$1vQq%XgSb1q412!JcjlYG92AI|$DjHjJ z7%hiLKVj@b!|>ss{ytbZ)~(J#ZjD}ib^-y@6yX`-Dub--Md{P2_)_y(nxU$^H62Su z4;cZwb@qgtukq(h;YNmqYiXGRaB1Z7sawj5J>HTsEbf;dMlpbt9EcUmd^-G>6x4|| zA{k+F2+9XA17itCB~}Q^g*6Vg7qVrC($ikcMPfeFw|k-a(=D zEYlqqZ{7?YSCGnak`4mae4cb)v%e46jl_nS2R8c^3;X=AK2j_R;VDa65)?Ui!A-zX z%1@y)bzgbl(uq9_sJ(HHI+SDoR&$HnKyplDt64CIuHv|Lhk^Ou~RW9eGLNgn(cQzF@&&sWSfit)HpeO z2-HOTOgB2fegb*O8R<14T5?cSLLIbW?36?t$@fJjBsSfQ#%%47F&i{@A?70Af&(>*t!|SMtG}Ni&805Q8vnof}>ka^A~d z;h@?XduD>l0c$OUaD66-Hp0k(zINC?1{WQIfpKAK@0deT{Y;TqAs*!fr;&otzIW7$ z$mSJ@cd)VWdkQU`!;0*@Ham_i`L(As{OLt!ZY!U+xpmdCzL0ksdb7KxC=_=MuJu4* zt~O8y8YKs)(lo0&7s(w$Q{sUB($J#yA_Gi6S2(hwmWIL;9;w!DP~&8ffbQ!PIa}D{KP)K~PYPrF zvou1I7?#3NT`FNekhdIW1DqI^5`0OC@>H$|t;Cq^CwZ1G23XS)HF^TQgMhGWlYyT2tiC z3@tT}l=Z~S#*;kx$4_o@TWhzC{IXI9AwD)t927}O>Io3J=QFa8cLmN~da2>2RtTt` zP1N3rUIj*t11&^zS1ZCKOX4U%805` zjel!>4J(>23<$W`D1=!aDH zXc#(K*d!Q-npMU=<2vYPPDLCOV=#g0h-R_ACKlD`@d+Jk(2k6w&~zcP%&8i3hVttik}#Gp#=!p&upl~9gs%uu zpyB@#{gaR1ws)A|Y}$2;GCssN#v){E_V&qAbBU>m%1n+96m+zI zl8LjL0!k^XMzr5XR1oy^#;%aBD8@My|B=jt-BP+4g=fO9a87L4q!1im)SGje6u~R5 z?Ebwse3D&c5n$gJY;68DjAV#X^aQE5qA+;R{k%@Ny4}06o*>NfQDy?Hk(u>eY#(Qc=+f$Z9Fv;ptyBM$kZ%kIAd> zI28MT2xdp(l95I&XF~hSHn;!P`uu8Hlh%A2$}A<;3r9Q{$WgB0!^V~hDtV}vvWy(T z0WmKS;DXX)AG982F~BS^VY^{20)+rmUbQw(iZVRDfPC)x$6q|MumZCjOw9NNG!n}H z>xcg11;6(fo0ld?Kx1k{VF5aHJTRqc>31qtJ);JjKzcEUvAc#tnUzOf3AThpKi$7Ib_>{UKu4$x3GJ6WL>C{5y=T!|nOihk)w ziJTd7?uOD^GuS4&uO0!9mhe?ZBt455!+dU{k1WvDk1@ZC?VK5(9{F@L$BdMR128-p zpIicnkb0Ok5^Bsu{S0t_l@R5K7&L`(YKpeKU7Q~dDQlg&0Ds{vB?u&RY6u$ULd&TK znyh}#eHJ0^AY3C-1Lq_na>7jvB(hAPB(y!8PH49 z1xbWO{AF|B#x0)x|9I6L1 z-QvrDUT_NPMXOlmg&c*K62z*uhN!6d2Qv|Ng`lDxSBrPh z=Y%I`1B(ZasiOiXonnlm>%(NIXWB+LL4Uo;U`e5o@7zKnhuvogKA^ms{sfhgQ@y|h z25COwreKLUyvpF%rb7&*VOc((`^-$8-=)tFzD&8WM~ltUsN-cb%U=L21j%!1r5^^? z^CoRM%_6^06ovxG1$|3BJ7Ql>X``b0$$aM}z%;e-=7bfi9(fQq6(BW6!P>NC`u2$f zhfH}58w(nZ)%}Ix5xOLKGS)rz-Kx#-lVr^)^XIOWZuZlbyni<0b*XQh%fAht+P2OW z@H%d}(WVNua;alPXEw}ym@M(A8C`0F8?;$o+G=_=v(j(s+~P2^9BCo1!Eq{DvBbcd ziejc2Q_4zCGh+MJJ1T8{kVgENBJ};s^7+S_?x2s6k>>0chR-?8!2Sv#h(pYKbOsWo zm`m*LCtQAlCjhh&#Cv3~R3^4Uvp-!-wqkrNCY?i`q^-<=T}ptR@}n8lJ2ne3@f-3m zd8*H5Gi{9e3E6g`%J?zF1@f=pkFu zTf+iIYd^~*Toxd981;xG$E3bswK2haLBn7g}Tj9v9w3aM0ct<0`gviaoFz)5;57i zYxRK7!^KE4T!f>f*gWGPEhma0DCt@$(wSd>>4Et}5&l)wF!uKn`0%5d>;`R?Hy2T- z3{1Y46`v8TYW*~h%(@F?5WuMJgFJ7bh21!i{YtD=hzda@9ndQiih zR)r$Dj$AmZK1s1evgcS2x_O)!{K#4@-519@tU#ysp2L_WV0D&)*#T7aT;j zG>|60l6N|}V5Z870)Fi%M75jHyJ{(1kPHk%3muUp*MiHS08~6+-bdGLi7dhT9gpUG znZg=VRHM_abPqmh-0J}gQxH^n88!s$B?EvV$115ya&(2Xx&+cL$*-3)yt)B99N8{_ ztPAl{=zFh`mq!Srx1NC8=vjeEn3RDr1TE22Fp*clRMFTKE`Wi&<0gR2XbG)|jU91O zRl1!c&*1?G_i_gEIe3X`GH3)%Q`lhOiM`^=Gigl8G$4-&7Y9Q=4`4&tN@0tqGxRZl zEQR_NxrC43N@-N?ewq^XjR+5vcP=IC+-bHvYfog&X*~Lb2~3OzZM1HeeGZ&Yhc-x3 zIHyylt!C6+Ln!%ukz-bUNRnye2+*Ua9DM}bmQ0EzG-|JN${=CD43;0>T3MuBsW>HK zbg+}sa99wYl>SiP4A#4Ld3n@auv}nd+p8oLs_Rxd6VY+HJbK7mztp3 z^C^YU+bmtI?h1}IivszI*p~Y%s9b+rEYoL|=L2J~nx$_Sv;{ZLA9B~@21qPDGFYLi zlUQyusQ_F*1hM!6Kg0gXp1(^xU3yj|l~Kwk*$;vq$ncl0j;4&NW`~~9CoaB;s7P4Y z3@0r5>1VEPWI{T`)%4aa^l|UIMyU`kWZ>$keevZAG~MWOI8~;V(7Y;#=D~+}&Y}&m zgCq*k`x2?wY7QTC&g&-tIdwbU?el z5LMbfVI<~rrGA(5gPs;1N&?DAC*)U#dLnp)efJBe0u zJK8v53+)w_2?;huR_4p829_YCec{TI{ZYe<%kksN3c53)Xy9S8oyFAJ=(5M$S7>l! z^Uots_Rms3A3DT8aPes}l3awl80cb+iRp0U;924lbBZ0sq#Ea=TF1(#R8LRaP5!<> zIVL8RA^9TXLOFZ069Vg0fyZV3G{887FRUvI$16D?fI;A6_9s?O7~snZhzakaNMVaE zJ>kncZDEnq+0h{L!MTXb9US%8%tM8gTi#YKZkoJyxw_@K!K^;lzKfh`-6eg&2YZaP8^V* zmkB}RA2%Oo@AM~1Ruo~UKDCTYq3EqgxLpR5T!HNm!3RP+(()qTz^Nh< zLukZpUZg$~H8q>Juau}&r9$vjzgyW=XQC4gS)!HJQOi-@J$c}Gd>Yk0x}biY z?;>7m@OE<4=B@66c2^>g1OSzQF{&vbhZ?HNb;Cc zQvh)hYD%)V_#`}dEiYs=j7#RVnm0=Ju$)8e* zmY#$peMilu;RE&F9$yZFK?4Kl+-zytDif&?{ErY8NN%gcn^lD97dnWj73UF6*J<_ zzY>dQ^wMhe!URT>G&M%I590NGVm(PtThF;cli$na_-$m1K$R5W*5}MozinRcn&Y%-UO#1;+aOFWNW+0_X4Z zg<^mM%ip1|MOM*gFF5}AN3zxo-jYo^A**vSyjat(WI(3-wI(aBX#-3ZYLg`@ zT3b4b>!dsPg&Bp7-05O0i0cI!ne<5O5VzR56+sJGACXtiX>w-)xtfoDpUcbH@~=DX zggR0x_x~+1M^X zlv=A=;zTm5Ffg5T!+T5jrht*t?99l%V`+emmy~{EHjF~!BW&Z6nG1KKK z%v~xaG^d!V%Ot)2*z&ioWcl_YO(nh9G;37nMF31;ZF9D9*gRmq^sIg6DH|>xn`XF$ zG$kI(_jw(r?5tYPayCrz4Xerw=@nYk$MH*KW3#@1_6AVB#%*$MLCs$vGbY-1vl`{h zAOhu6RZaWqq={x0n9l{BvQo_oT^Twbrp1N1RSQw2%<1MMw2>jI)l{bPvXT3=FvDx0 z!XdvUZ}kkxap{?9Pm_8%rujx2M^&snW(Iz0DaEOx9XA??g6Gy}86x4Fn)`kVn9ozh z{raWNgF`TNfTiLR3sAz2X#?Sexqf$UkUVVfOP=CZEl971Y9;!qkmzI<=(CfjhxgQi zVI5+sE)-tMXKi=+x>+2rM1TX+qwvcF75E+ojFLGB3XZ z)Z*3#5lm5i=xZ-wy2V}OARQzaU8|}KoRC;K1P-+&MucO@BvV$<{H_&f*oa##cB z%Sk)V7gV}$iD?jt<9O(i7K;*~SwjJBJvJ_miP`JO)214N;#4x_PXOxa+U}dUNu8v^ zVK(PqZxz0y9`HO_tGb2|RNisWjU)AWih-98GE|Z+(y+!d8a&h7@^`$H`pm&16vpJ6EjzY3?Ny3*VKI0hu?Grd zeAA8bo{RJO^!0q-FPGn+TNo*;1sK^y)k98_-^DA*Y}B(&!kg0)IG-+;%d;PM>1IUw zTUSnnHd!=8hkCai7@)dJX13=~vd}ZI+)i4CWfp3(CnKBy<+8lVr{SU-Bu=FC`!b>& zskYlLKk?b+1|5$E@xHEjmExm5XBcLDqrPD8lD<3_!Z1j&m-bjuh5ybjI^ND1=h*^l z|xRO!3?MN9d>#x(MZ+C`Y=@dUM9YhUKe2m(6e|oEij4ifa#`Q`s{DjCQi- z-3#J_;L3AA6hQ*#ixP6iundbxJUXci1!h&#T8R=s@5)lszA@XNW7GW+jIR|^&1|Ln zBwjf>qxx|M6G7NmSe1zq`yymQUg z&*7_o^5qZ)lWcSna!g=a&X?$kw4|)4s?$3vsYbO6-zJ)s0$eaeo5?_0YQk%-U7Z~C zLN9vitt^*~m1xSFP8pZfrS)Fofx`$X%buUa3pgM@t>1bX{5ZCcM?NU(pq#^9S!GMnR6Y}66;W0J=N4|kN!<4Hrk8LR0Ex!`w zFaB6j=fXe8yXoKnA{841vcAZ+D}VrY0a#q8&d@+zRVVX70DG&=?X1*#H=M>-0|ywD zvk5(@nI3K{-&{gn!XFA%WCAN1)aL62aiQYZt`XgluyW__oah65;u#4=`=uzX)g~Mp z>N!v-EHx?*s@F3>FL}J*5ATo5@58H?kIccEX&)4%FSV2+^lB4s(y@!gmN|b7a=dmi zWkv36n?Q?I8A(hkvnhSHdR6teqqTcY6!haW^jKcqwZl<_VvKr6?~Q9AFQ>BC+4xIqJO7$E$*tl}O0S?r&{_HZb7rG0$e-op z>iT}b`09_MP@}%^e{rl`Ck|)kO9eREw{J@RWM#CC@G_Fgx-MJsdDh)k`pU~V5BN5@ zT~_HmiV6pHPn6BXz(CO^zbCnF&vQOrU8RvPAOL(@zB4f3wA6%{S-ac+3!zxaOwcR! zm7|rkY8!|rbk(K;94iVH zVHpC5*#!l5Lm|uA@TzvP1Bn_`^=}ljOI0g(-oR?n*u7SuPBfSyD~;1)sjSVWfH257 zI41kLk$n6*2%$!~2nzWKAse807U1pN0)J^t5C5w)7dk=RJf0pf6PnLlwGbw296<|h zqQ*Zq(A_=kYpv4l6GQEim_a0+;T$k^*v;;u;e}StaJ^sxiF;gSbv=Bmh&DZKOW`U| zvJ9}7^gL{omU9l(eZE693zinPRKBL(8x2j8uw6Cj9&S}f$r{_EH@K0OZ6tU^OHCb#O&WXMQcpz(}bUXXCRGym^NpGh>NO;5tp zJIW}9C@^9hj$o>d{GlHmKdcf!KpO1=-u^?vlW4Dm3`ZRWe@!^q$7&cjDjwdr0St;^3Vz6{Ucr_&HRzF1lFMFSY+optFb3~2_5mLe_@@K9&SUb8!k)Ybel6h@X3IPJnO zsku>Y&`qJENY>W`3@{q%Q0|u(SP-=VT-5W!mA{KOz)UF^{>eac$VpVbIVD)u2Z7lx zx2C=XQ|ujoP`xm5e=V>>OmqUBIZ(Tky;PQKa!wUoQB6KlOn4s;S!6Ydpp{;=Tn?R} zx+p1=j%&5sBsVzBaIMtzXUem3A5{%XRlw2&dfbfX=ATcwDmvh*Rv@cpup<|OC29`H zK~<;4TDZFG`1UE1z9gbY&u*)oRo}zAgTDu#!0M^zW$9iE-R$$xX;>id|k_>9Nd@_xG{+A$gz>c=1+egP4J(NsdAMI|F&zQMSTH@j2UNvJ)r#b)l zqIf!9eWC2U>$(u!_Bj8r@cJ>_vbN+amNMURuAg7!#0r-?KR?cY%I8umeKJ0Sd|&=_ z2D^XWX3adG8Y6Jt7ZqZEiG_c)j{L|SI)HQEmyd&QA03k#`&JirEm2nm*Gy+ar=OW1 zbmAAsO?5Q}ZUtK>CJXC(r2pQ2T%J>YK>e;p<;StoSHkrTK&4JJh-BZZc8ls+0n#3v zm8T}}bZb8<4T+{Vu&y|b8}GRl+wPbCb1O*J59mE6UDJ_wKkjCwS9w%ETHk9GOIW6t# z5oudm7u}%KZlLwJkd=OMhcsEL1TUu{W38w4sHCg+fdl7WbvMCE52^R@A3>)70+x@| zWbHQ@V7{rd;<;-atzL;MfLY`^7J-Z}0(4cg9Ye;`2H9qpf_7)CSTxfu(3QtBU+3kBIcOUmC(xOtLoa5A+SO zn7HZR4`F0OmP@l4IlbbeU(@MOYNbuVK;i59dQ0cgclfz6h;P0LdXz@uR1!rMk~MP z!GF(VI3rIV7xj9E`5A8Agd8{Rvc@uOU9$F>bgV&`5fnAbQTROn!%e8#CnjF$z7!u- zp5bfn0sNa2({z>(N*~lFSSk^PTZm46B;ASgT>wR>jj?+6CL9}!-UQLaq*aSLs zD5;327otfemKS?J@V=nh79&A&RUmpX|3A0<|C`5=)>3R^Yt-7GY+70DA-ixq%gD4fg(86kNnh-Z z!vMg+4#RNNHQR7Q?Lf4((odFkE*spr`UY{Oq+t!cB(}AvT0Rn__ruR$Jp9V))tgZm zTqHtD`3=2qr)go5dryJnhU;y-mwyPCpvnQsxDRRWrcB&viGAJej9OI{F$yy9C0cdd zj82hSO;0O9(d{KT3(#;IT&9-B zG%e;|yEAT?Ch+2z=hnJX!>Z#G`7@C-RV!D%Xk*%_Q3Pg!kL~={vSDTHyxxzUFwA~> z7dvCt+Ig`DJ9eOcdiPCTyBrqHUJx;VWB^x-yK!s21U;6~bS?FU)wgPe=@S-YK~W^# zgz+ds8`XlbdsqYy0BfQ#4^n9C~o?eFd|ZveFSm+h=Iba=159T z?AU`k2(kDOHBFMj(Vry^`kfbr^E6Fqmg$be$u-onhYNUI4CUeLG>hng5E)s7n&V!y z26*E%!=NyB+aLGMkk6ZLoLfxLQI}z7X8-}#xGOt9OlQ(rpX)Jm7{vW zD;lRmVhn1EDg+W4o|3 z_d8%Yw2n_W(zs6fdazc@vj`Sw1YTyujdX>oTqvByquU9_Vug5H7#$tXFrc@C%Td(C z=f7wNvTMmzOopE#@46w}nl7C>AWzrz?b;qmSBMag@3E)4ELx+$~fw9QQ$ zP^RjyuzxApXq~zmgz=O|z^o?5U@fyuAU{Rs!Uel$a^NH#jiiV@rY<^yp+VWK6ZS5M ztBM3elr0)A^T?1UVq7Q`CrELwrW{CZW5daG*NqL8@iA<86Evo~swN*-TCxEf1xa%cp_ZR?kH?7YTCEjO_TGtux4QM%|{XTvoi z(1m-D*skPd&61Cq?f*IrZ;@0CvWB*N<_yT;N`$ItYlyM2OsSv&(ah)6d`-$ST#8Z} z5P!3lXlMo-ysef1aCg*^9x~pmuCJFO+H!wpr7H0$iog`@LBy_!Tp2s`!l}-Y7a-M< z$%xL;JH(gO+Lmn{zJoW|=jCX7|(?GuV+j2((LW#6F&>kCJ?c zRw~6A`DIpp@&jTAr4D=vfM0C`BF?S1jfX~ctPrvk`R)lA>0g42Kx>N*wS=H*lVSS> z^L`gG>x%=mCLi<_C@=!%<7VP$_4xiU)F$h+VO$B54YmA~sjvG?8? zZQE`>1F0-SKRan);WJJKPry+t&h$cT@Bb)d)-AcT_x}>D3ZVf0p9~piQx_LYJ9Fp% z5V0J!&A3fA1Yi0&e}*TWde_3b2==)a*+1E6t`C4IBAWwI|0L|iuBS&>GR94r4C2GY zYGx|4n$zd?C-WtndcVkcaL4J!##%TmtYzC_Lpz^eb#rV3A~GE9)rP?PG8E$S`@6ok ztCKWH0@BI|7$sO@ZKvao5OF$Ff#z?sH3#w)MJsGEBsX4X7!Ci5QUB|T<^<#VHCiz@ zTN2<}T#Pc!Fz#XbwvA@PiO@KKdz~#fx11LZp@HL#SmFBFuPLy)xvbN-B9i)sb$7P$ zuY|MY>xjqa@`3q)G8nNrEFut<^e3loRHxu##E-ehi5H&>>*&`p>Ns!nHMFsdv$WU% zHU-7g*5BG(pgu-!Jd!jJ1IDDD{IG&^NU+z|qanspj4U>3vg|aR`_lA$2j2u6kW%U} z0Acq+o0*J5F(f|>M_?OHY!dVC73+0zGG{SyILKMSzJ?f$DhIkCm1AH(Lv+YGw^ox- z11;@Bm!*CDkrJ}zYXnfgW)JnVs5MOlREw7fSfzp*C)o&OP)ofmgw=Z{er7^EA;TPh z@bN@rkuL;KF@C)hkWxlAfr$wm!N7^Nm=rrjtmwH!vPp`{?FqT_ zPQ2%D%4t8v)EOy{?_*sSjUah5+}3Vl@0$yIBahRXOU@0%;OU$7T7R~2Ja!>H35aXTfa#Xs z@UL*fr?d#FEfN)qSd_#51SE8{EFp)9;xA ztAQwf){m%W+(0zXdd0EQlGY&9-nxgBfApRL&OnqHv}S?7-md+cZ-)zZ3@jCq7^1=a z)Fi~MmMB)b>A}}jHy0%~WxjZC^T5%43#qLVo@xha6H1tJkGvgq2jcoMc9Oqt-fjIO zVL$hKLdQtj%>O`QQ8{oP`=okk(GnAJuffC=07Oqh+Zj)aRWcmqJ0KX=uHdG7{E}UC zX*GC!w3_m;6Y6(HSaUMCjvdTrSsmXn(g3q23Sk1UkDg!c1^z$fy+SxGAzu9Zql1+& z008`dEw!_Yr;X`<9>iBV+sd092>!j9pZGj}DQpa{Ha4Me4p%wX zDe=8OYSh|_R}?$LH=DeHrk4JnrMpxG)8X>7lVk6s|2}UXM0!8fopKSqBooBolih4z zANNOInzW;X>!l1C9rQ#@eLvmL^7HZJn!QVtFoA;%ty^+AqI>pm@$yW4g=%=McbbqI zd9cebl%@|Fe>h}Jofgv5A^CTsIQp&KK8uA{Ms(ryHHo%OYzb{3i*6_3ws zos<~Y_AP2w2$34#Uk+EMm_~S8vpDvkWKC@Vv{%+_29Tglo$so5tZ|;cJ zaVO@X>6aFo_x|9_NVZFVB=T6QcW&NJc*g@H^r{eKR^M=yjxM|9*Nc-WMf!Jyh~AH4 zRK&-DojEnLtv)*VyalHNyd8N}8s5xYX^l`z>xYF#&vqSNzG7nHvEQ9wB>NP|2!b$C zs90g7gC8#yo_`e)#^aKQQa}M9Ak%37&w&dBEr?ec66j9U`|6NCNkeBVDwnqWo7@?h^;bP*+MQ+dP5D}5HdS%Js7R4KyOX9A}V$mnv(EVd2dwjGW;+*x00Ie zMQNh3)K-#SEA{(>MDAwLH0`kl#L2CYGA_#TqrPdJT ziHQf!Vj0v36$gIkxRVIW?&`&;OaLgzD(!pO0S}NL)dvIV^u{vt`l&_i6Xa+0P^;L- z#(r1v^x2klT~G6bw)KqOw{po8lBbsyTfnhT3}&|mu!78i-H|OmNRlz@+#b<$1u7P|5r&A|0;n~7z}2{`OaW^ppUPiQ$GdrL!vLCE z`K;Kjk9`M#6oMtpPw}ov?D>VCXfwq{I>UFTNirNP&4H$;it|xEO3!hKhi;+qfJ=2i zOaU9ILSPA`{8#39y2$4Q*U`kl(Xx{rQHC3dnVwT-X0SulfVj)D1MicK-q-C4_1PdO zZUGmr$pHg#a;0hK9g=+)HFii1G^&Gm#L3E>Vt+2nAWP(dK%zSc?ST~7kN&TAuEQIy zu6xfIHCl+y=p{sgD5FOSQG(GDL@zOd(WAEnK@ib`K}Lz*5}naW5Hd;_j2c82BqCnz zn`9+#-uT}2TfaZxn_27LnOXOF&Yr!_J$IkI&v~=}YY`|Ch0We3#ypu_UdxvaiXO%4 zGx+Qo9S4OKp*MGV0l1%Dn(aVxUu|V49kan@*j@0>$tZa3@**p9ZMa-1kDrk7oRL;e@MkC=w$l_+ZAp1PCxvi;}5_+Xe5u_PlGS z_U>!5Q*19Hq=N#Qi6XhUv0^}M$fiePv;i=z6!X1M>3WWj@tojIc%1HZJfuD6|I3YF zzMlYrzn;~e`QejAEd{F^1xkhK%fx>(3tN~ZLV&~tDB4IHU7Ry23;+HHUl*szhQYYj z$ET1|qu*^su!_Zh_lyK&gWF|_tM!MifYI-U$7zQ{#lK$*EVgtg=Cb_m1NNK!V>tJA z@Vfvy%(_VQ|E90u`*b&cs|OL%{gH5>h!^Li@h`|fK6Cqe!swfbQt&yH!}oPl=aRSRQ7>%7 zILTi7OOwD`buxvDf%&x*`u7e$l6z97Z7PjtaWg+sKp)u=T$U->z1xsPNUrp%rUVA; zxK(`#Ml3Mtw`e`F47%{LsF>mPDVDDAn@n{x!BU2~i)(bk0dEN&48aR%W>I&SRLd<5Azekl}5yG|@nP=Wz`ztZtJ^Oy>c7A~w zFM@1mQp0=0(Am0OTB&a;?$o_ zo8{K5GD{;Hb#`TqCou&+u`J>fJOEQCfn3%XRQG4!tS>dIWm7smIjy*0Y*A_9EaNsB zYeWlg{;c5N?^ul4Y;<-OuwhR2{#xSTXu4dtVvtuHh=_f1qcbrpx}=Pf$^*HgBs)eq zcIEopyVK4YIRnL3_h_6O_mK_TO&heOPj8Tc&o{kR9DU=?!lM<+=j2ad;(Y$mQqHJv zNJGU4y;ovpg^CAyy{p?3jl|-OQ$N{hL474_wa8-0wCLIBj5CmRP=N56?_548PZE0O zQWHi|Yog@b?jyaIJxzqF`kKS(-KN^p#MvTRb7V3GLSpA#HZV+s}l7d0_HkC<93+DY7Q}e3%?FV~iB$ar7Nlk1n2LfUv#aK}UwLQWr9G7F61eQR(FImsVA2?`+uL+# z!NOJ`q&7}sCA{J-x^ghB*Xa(W1n^qrY5Mm{=ls3bdwe9AD6c%u)uFE`or@6A)t=%H zP*$S$P2+Yu>I2#kH(LdiDEJx$h_@Ib^A6$)?Xg8))oPa5V{H~VH0L&SC)G70M4R?p z(vBzIoc?PBnk7uuXoHJD3vm%B6;2KWC*J^dcX9O)vT<>@`>Ad9KMfF^>%tPubRG&b zgn!aHqRiVL?3j9lZP0i{?;3|!FRYUQMTnhdv++O`_ zG@G$SHZkH@Wpyu0+F^>iWPzfWnl+u`cF#SDBspy(G=-D&mEDNGINrE!&uvd(%w{kI zlI(;kkPO3E2suuMn4m9CJ}X>nfTna**9>^p`uBcxVvycbC*^ZW=Y{b$ldoUv`n10M zOuksi7DEe4;>qZ~2^3H6o2&@*Qrqs<#+WPC7-Mtl@V+S{d`V84Cst`#RQ9DOP`B%s zdd4qukZ%ieS}i8ZTr*wNrO{ay;b4oCiY_f{32$e1MSqNbMEANEyST$|!SUv?8mpF| z(_Cz^Jfe9N_|_vSI7_rK>aIV zhkH3&+qvViCqF6xX3j3TeY7X$MW-CEY>SR7*L{J6If!OFvf*2GhKA0;A-LV6qag&` z4gSG_lw|dUoeUfGR*)N)oNX;5r25mO(6S!y(kz0G3;MpZU^D*H*kED=`M*Lmp5{Bf2(=Df`Pl|Ij9fA^aZM+;wklLQwgP!!Al{L zJdy$LvCC1ntWXvC&?mP}KgoO&^_)>^@z*ujyQVmICje+?GHvhMXtI3j69;E%ZGmsy z%?sdu*FiqzZ|tn7OHx%hA32e8kwwns^LE`F&v?*b3+bADUkUa@ae%;+``Eu`hWDd3 zFQ=iZ0{P)#+XX@Ng#qapO8oPk z8vK?QU9(e0M|O7;WOr5UbM;jRm#MV|`NsK}P$sYh3R;zzs}Ot`fsWmArf0c1-hKmT zY;P^|ZHGhC7`VK>i3eUz7mF|`%CROG9!IYT8)!F)n@KdYG}jGl5H~rOs(uHYt%&wi z1A3rChh!a;UzEYdq4%zuy_cxOM#u-Y>U0jwk{(Xls7twN>8#jYK#Ud9aLqbnyhTTN z^ECqx$>sMfK7Og_UcNXhK3K0uu_?oXxV+v7xn1(=+43y%d*hO)*VA5S#wS7GaWVg?qfk>#vtaDdiR6R$6N0i#B zMvmdsW!(Z}?ans^LDgMhqcl+zX{A0*&mx2K)ikytGnO8i65S4~_TH4qiDtQv%JV%J zv>IN2W8_@jWX-|oHEM$@Zb=W^8{mAHRE|&ZsM!B z!XOr>Q5rC=d|SU!TMT(iTJa8UN5gRJb&$K^r~*jXk^oX-IN1Pe^Qhl6sxDq~Ei-vX zxO+*)z~{;hF;~C&IGDn)+?vP(7{KS!br7xSMa8>`rI+43#e2ZXq#y>}X=S4#SL=8c zN+@X4TUhY6-SY|)d&KIwoMc%eA&A1W2S!sVET;~Mg(iL+kV*?HN?X-<=E4X$cM!o1 z!`*w}e0>!)4hY~ThdT(M_>{RG@IdkCX<+!bxeP1!`E8+28h9Ju^RbF&zUkP+`GxyZPpGuF^bOVqZ`xu&9PtV~H z{eI!ji0Mro?*au!Ukb|IpmYg{!X5L~hu70<>9Z%&RS5Z~J)4R5Jo3Y%KG9U?hbwA8 zoLhmz=}dk}@I3nLm=nqCAf}~CYkK+|pev)WS7+&0WV$zat}bBiMSyIo>!u&QS` zgKZmt1Jd>;sbUZ$bD4ux{IFI!Gp=9VThVQNIu&C0>I=CT(gUv-Pay8pR7mLw=?Fxy zhCUmaPS~@c>;_WN2pgHdu)-G-g!khBe#*MS2M{6a<91H9KxzzmOJfJ!`s5$3Waut; z#4E*0eH@mzIx%}Y=%g9^xL=z=uiksGE51XnX$15%`21Bs9igk^+!qbtJfH&@NwTF~ zDv>~jd^15r-bc>sbo#0pc#k=Zsisx&NdW)@rbm&^4!E4JqC9a5dRQiABli%0z6}f2 zOSJ-slJzL;sDC17mk~|{OKM+(t#pi-p&Q941dFyNT5>4_7V|;a?5~d|Spc96o2wu2 z2I&uyX}82yBqKKfuRuK%ZF;Zfp)tLYz=!7ij3RRHuE8RCFtRzav&&y5@cS(qQ(Q-N z!_#y9uN?VT6e`&g#e+k@2lvhQ*7Ks?RFOo#5X;hHe>Rf1$I`_DVv~FW$Y6zjqi1QP zP!eRvM7K>0J1?1H6fss|ZjlTIFIcGG+iUJ0Cy=3tSQIddvgw6`q2(U@J1|a%O9f!b z5UVf-)o+PmRC>ofN1cp#tlpcXTtop+gr}bp)l1afrF_Smu-a+4Bi_#|kZJq+IbMLd z^ohfB`EmJT7id?1o(<>;!!Dcu=_zVyyZSR>&E`D&3q*C)H4|z|y~f`1Z8TQ!`InPZ zDj9jTRbDXj#r`q=EIAFx7e_VS6Y8 zOXSak$JD3R4?(AHGYa#K-6^Nxd}LG@uE`?WlLV=L+geXWRR0jcL(u*m{vVK7(f1Yi z1!Yx1mSO-^5Siv*#jc(wtslw5k|HW)fTzLJG;d<)N`^)QQ*Q6zSwQy2R2teTZSiD{ zWk)XZlHa#~NiFe(Cb16H zZO)=CcOFvQhkVtQD+O!#X`@9=roQY3xFTdf(U38e$AVUJ(pdXIKD<^T^Z5AoLC*b_ zN;2)$3(yzB#aR`#P0|*HdSbXfrydA5a!wHN zkYH+zNt=s$o)s)TO5mPLH5YXdtLPyma&PuI-6}>vRAtm$TOu0Ddd3>=XXQg(8mwKd zOv-o6Y)Y*u*fx2^wYct`^uCwruF>?+C@5M=kUElZQX$Plk2Uk$vEOK{$^Qs2Doqf1 zZmpE4VqrEsAg*t;mk4D^Ae!NM9&0Uvw3`H=h3}$mRbX+LB<+ix;{bm6JgyLM3L9_9~s=GQinpVDZZcziQJ)(?g5SLV>RFO3}KXFM&mrRCS%$-V6^ zC_pjwP}p&|I4o6qk%VKyebolqE_+-GwP)I24e0?VTHC28c&S-468mrxxVOzxaU(AP zL{4J4;Q{Rjfkwbr?X)!J$SN#|8iW|(URhG3exf9|mBW+jNx4Fg&nURFeu#N~tz}PB z%2hK0o~_2mT%H@#=a6)IpA;)4dhRJ-n9VR~2VpwwFLeC)B6E^{q%78{)R@LEJX84b zwJSU0-xfsQ2`)StaI1ovWONI9j~B(*y5e;LABIG6o=W$3^Cem9}$SFRB^zDY8WaV1MvoUiWTa3(WSe%xGma|-7amSl0{AsVMB|=L~zP9x( zv5@Mk)uBM>z6S|ZL-Y$wXn8}3riSWGi2qhSaUo|*i=c)^0@<-sS;7M%gVeyp4n~*B zcsU9aTQ@u&2U3;5`|ReKWPA~hBk}TT;0eKUenyU650uB$mK=iXGk2a$JFOFxXv}>n zG+`gVnTXW|wM4BxqHF|Kz+bp36g;0?B74{_cYSZ{AXKK;OM%t~%Rpvi%*Ik;2bE-Y zw2^JAzTEBp4hr5-ah+gD0|gXSZq0~m2}7ky`ash9=VxPacm~fNy z|C0VZ3qQN0?>F2-{3rbE0>85qXBSiarjV8WN%7C66=&gRYpuWGrV2mdXDY8}8P1jv ze>1#M{AIx31;w-AKND@gp#Z>)1_1D1X}7cRv)Pc}1U_0n+x{arau$E~vHu&7zV#FT pM-Xrp|L1W38w~)^8~?-npMyVClK|Jf001)F8;I+nil*Pc{Ri#3D9!)? literal 0 HcmV?d00001 diff --git a/test/regression/bsd_test/netx_bsd_aton_test.c b/test/regression/bsd_test/netx_bsd_aton_test.c new file mode 100644 index 00000000..6ac48238 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_aton_test.c @@ -0,0 +1,106 @@ +/* This NetX test concentrates on the basic BSD UDP non-blocking operation. */ +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif + +#define DEMO_STACK_SIZE 4096 + +static TX_THREAD ntest_0; +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); + +static ULONG error_counter; + +/* Define the ThreadX and NetX object control blocks... */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_aton_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + +} + +static void ntest_0_entry(ULONG thread_input) +{ + +struct in_addr in_val; +int status; + + printf("NetX Test: Basic BSD aton Test..........................."); + + status = inet_aton("11.10.10.10", &in_val); + if((status != 1) || (in_val.s_addr != htonl(0x0b0a0a0a))) + error_counter++; + + status = inet_aton("11.10.2570", &in_val); /* 2570 == 0x0a0a */ + if((status != 1) || (in_val.s_addr != htonl(0x0b0a0a0a))) + error_counter++; + + status = inet_aton("11.657930", &in_val); /* 657930 == 0x0a0a0a */ + if((status != 1) || (in_val.s_addr != htonl(0x0b0a0a0a))) + error_counter++; + + /* octal */ + status = inet_aton("013.012.012.012", &in_val); + if((status != 1) || (in_val.s_addr != htonl(0x0b0a0a0a))) + error_counter++; + + /* hex */ + status = inet_aton("0xb.0xa.0xa.0xa", &in_val); + if((status != 1) || (in_val.s_addr != htonl(0x0b0a0a0a))) + error_counter++; + + /* decimal, octal and hex */ + status = inet_aton("11.012.0xa.10", &in_val); + if((status != 1) || (in_val.s_addr != htonl(0x0b0a0a0a))) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_aton_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD aton Test...........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_getaddrinfo_test.c b/test/regression/bsd_test/netx_bsd_getaddrinfo_test.c new file mode 100644 index 00000000..2c89d554 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_getaddrinfo_test.c @@ -0,0 +1,1276 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef NX_BSD_ENABLE +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#include "nxd_dns.h" +#else +#include "nx_bsd.h" +#include "nx_dns.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +static char response_cname_www_baidu_com[100] = { +0x18, 0x03, 0x73, 0x33, 0xc1, 0xbd, 0xc8, 0x3a, +0x35, 0x60, 0x4b, 0x46, 0x08, 0x00, 0x45, 0x00, +0x00, 0x56, 0xa6, 0x10, 0x00, 0x00, 0x40, 0x11, +0x52, 0xcc, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8, +0x00, 0x69, 0x00, 0x35, 0xc7, 0x20, 0x00, 0x42, +0x1b, 0x3d, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, +0x77, 0x77, 0x05, 0x62, 0x61, 0x69, 0x64, 0x75, +0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x05, 0x00, +0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, +0x00, 0x01, 0xe7, 0x00, 0x0f, 0x03, 0x77, 0x77, +0x77, 0x01, 0x61, 0x06, 0x73, 0x68, 0x69, 0x66, +0x65, 0x6e, 0xc0, 0x16 }; + +static char response_a_www_baidu_com[132] = { +0x00, 0x15, 0x5d, 0x64, 0x17, 0x05, 0x8c, 0xec, /* ..]d.... */ +0x4b, 0x68, 0xd1, 0xfe, 0x08, 0x00, 0x45, 0x00, /* Kh....E. */ +0x00, 0x76, 0x63, 0x9e, 0x40, 0x00, 0x40, 0x11, /* .vc.@.@. */ +0x8d, 0x6d, 0xc0, 0xa8, 0x64, 0x02, 0xc0, 0xa8, /* .m..d... */ +0x64, 0x18, 0x00, 0x35, 0xc1, 0x9f, 0x00, 0x62, /* d..5...b */ +0x23, 0x29, 0x11, 0x95, 0x81, 0x80, 0x00, 0x01, /* #)...... */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, /* .......w */ +0x77, 0x77, 0x05, 0x62, 0x61, 0x69, 0x64, 0x75, /* ww.baidu */ +0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, /* .com.... */ +0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x02, 0x01, 0x00, 0x0f, 0x03, 0x77, 0x77, /* ......ww */ +0x77, 0x01, 0x61, 0x06, 0x73, 0x68, 0x69, 0x66, /* w.a.shif */ +0x65, 0x6e, 0xc0, 0x16, 0xc0, 0x2b, 0x00, 0x01, /* en...+.. */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, /* ..... .. */ +0x73, 0xef, 0xd2, 0x1b, 0xc0, 0x2b, 0x00, 0x01, /* s....+.. */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, /* ..... .. */ +0x73, 0xef, 0xd3, 0x70 /* s..p */ +}; + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +static NX_DNS client_dns; +static NX_UDP_SOCKET udp_socket; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 10 +#define DNS_START_OFFSET (14 + 20 + 8) +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static UINT response_sequence; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif +static char *send_buffer = "Hello World"; +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +#ifdef __PRODUCT_NETXDUO__ +static char large_msg[1000]; +#endif +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_getaddrinfo_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check UDP enable status. */ + if (status) + error_counter++; + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check BSD enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + if(status) + error_counter++; +} +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[NUM_CLIENTS]; +static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[NUM_CLIENTS]; +#ifdef FEATURE_NX_IPV6 +static ULONG stack_space6[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread6[NUM_CLIENTS]; +#endif +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +char buf[30]; +int sockaddr_len; +fd_set read_fds, write_fds, except_fds; +struct timeval wait_time; +#ifdef FEATURE_NX_IPV6 +struct sockaddr_in6 remote_address; +#else +struct sockaddr_in remote_address; +#endif + + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + if(message_id == 2) + { +#ifdef FEATURE_NX_IPV6 + sockaddr_len = sizeof(struct sockaddr_in6); +#else + sockaddr_len = sizeof(struct sockaddr_in); +#endif + ret = recvfrom(sockfd, (char*)buf, sizeof(buf), 0, (struct sockaddr*)&remote_address, &sockaddr_len); + + if(ret < 0) + error_counter++; + if(nx_bsd_socket_array[sockfd - 0x20].nx_bsd_socket_family == AF_INET) + { + if(sockaddr_len != sizeof(struct sockaddr_in)) + error_counter++; + if(((struct sockaddr_in*)&remote_address) -> sin_family != AF_INET) + error_counter++; + if(((struct sockaddr_in*)&remote_address) -> sin_addr.s_addr != htonl(0x01020305)) + error_counter++; + } +#ifdef FEATURE_NX_IPV6 + else if(nx_bsd_socket_array[sockfd - 0x20].nx_bsd_socket_family == AF_INET6) + { + if(sockaddr_len != sizeof(struct sockaddr_in6)) + error_counter++; + if((remote_address.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_address.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_address.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_address.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + } +#endif + } + else + { + + /* Peek message test. */ + ret = recv(sockfd, buf, sizeof(buf), MSG_PEEK); + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret)) + error_counter++; + + ret = recv(sockfd, buf, sizeof(buf), 0); + } + if(ret <= 0) + error_counter++; + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret)) + error_counter++; + + /* Invoke recvfrom with MSG_DONTWAIT flag. */ + ret = recvfrom(sockfd, (char*)buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*)&remote_address, &sockaddr_len); + if(ret >= 0) + error_counter++; + else if((errno != EWOULDBLOCK) || (errno != EAGAIN)) + error_counter++; + + /* Invoke recv with MSG_DONTWAIT flag. */ + ret = recv(sockfd, (char*)buf, sizeof(buf), MSG_DONTWAIT); + if(ret >= 0) + error_counter++; + else if((errno != EWOULDBLOCK) || (errno != EAGAIN)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0); + if(ret != (int)strlen(response[message_id & 3])) + error_counter++; + + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + +#ifdef __PRODUCT_NETXDUO__ + /* Invoke send with MSG_DONTWAIT flag. The message is larger than tx_window. Partial data should be sent. */ + ret = send(sockfd, large_msg, sizeof(large_msg), MSG_DONTWAIT); + if (ret <= 0) + error_counter++; +#endif + + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + FD_ZERO(&except_fds); + FD_SET(sockfd, &read_fds); + FD_SET(sockfd, &write_fds); + FD_SET(sockfd, &except_fds); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + wait_time.tv_sec = 1; + wait_time.tv_usec = 0; + select(sockfd + 1, &read_fds, &write_fds, &except_fds, &wait_time); + if((FD_ISSET(sockfd, &read_fds) && FD_ISSET(sockfd, &write_fds) && FD_ISSET(sockfd, &except_fds)) == 0) + error_counter++; + + tx_semaphore_put(&sema_0); + return; +} + + +static void test_tcp_client4(void) +{ +int sockfd; +struct sockaddr_in local_addr; +#ifdef FEATURE_NX_IPV6 +struct sockaddr_in6 local_addr6; +int port; +int sockfd1; +#endif +int bytes_sent; +int ret; +char buf; +struct addrinfo *server_info; + + if (getaddrinfo("1.2.3.5", "12", NX_NULL, &server_info) != 0) + { + error_counter++; + return; + } + + sockfd = socket(server_info -> ai_family, server_info -> ai_socktype, + server_info -> ai_protocol); + if(sockfd < 0) + error_counter++; + + if(connect(sockfd, server_info -> ai_addr, server_info -> ai_addrlen) < 0) + error_counter++; + + freeaddrinfo(server_info); + + bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0); + + if(bytes_sent != (int)strlen(send_buffer)) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Get the port bind to any. */ + port = nx_bsd_socket_array[sockfd - NX_BSD_SOCKFD_START].nx_bsd_socket_tcp_socket -> nx_tcp_socket_port; + + sockfd1 = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd1 < 0) + error_counter++; + + memset(&local_addr6, 0, sizeof(local_addr6)); + local_addr6.sin6_family = AF_INET6; + local_addr6.sin6_port = htons(port); + + /* Bind to the same port. */ + ret = bind(sockfd1, (struct sockaddr*)&local_addr6, sizeof(local_addr6)); + if(ret < 0) + error_counter++; + + ret = soc_close(sockfd1); + if(ret < 0) + error_counter++; +#endif + + /* Call recv before peer orderly shutdown. */ + ret = recv(sockfd, &buf, 1, 0); + if (ret != 0) + error_counter++; + + /* Make sure the other side gets the message. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + /* Call recv after peer orderly shutdown. */ + ret = recv(sockfd, &buf, 1, 0); + if (ret != 0) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +UINT status; +struct addrinfo hints, *server_info; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + if (getaddrinfo(NX_NULL, "12345", &hints, &server_info) != 0) + { + error_counter++; + return; + } + + sockfd = socket(server_info -> ai_family, server_info -> ai_socktype, + server_info -> ai_protocol); + if(sockfd < 0) + error_counter++; + + ret = bind(sockfd, server_info -> ai_addr, server_info -> ai_addrlen); + if(ret < 0) + error_counter++; + + freeaddrinfo(server_info); + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + address_length = sizeof(local_addr); + ret = getsockname(newsock, (struct sockaddr*)&local_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(local_addr)) + error_counter++; + else if(local_addr.sin_family != AF_INET) + error_counter++; + else if(local_addr.sin_port != htons(12345)) + error_counter++; + else if(local_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1, 2, 3, 4))) + error_counter++; + + address_length = sizeof(remote_addr); + ret = getpeername(newsock, (struct sockaddr*)&remote_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if(remote_addr.sin_family != AF_INET) + error_counter++; + else if(remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5))) + error_counter++; + + + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status != TX_SUCCESS) + error_counter++; + + tx_thread_relinquish(); + } + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + + +#ifdef FEATURE_NX_IPV6 +static void test_tcp_client6(void) +{ +int sockfd; +int bytes_sent; +int ret; +struct addrinfo *server_info; + + if (getaddrinfo("fe80::211:22ff:fe33:4457", "12", NX_NULL, &server_info) != 0) + { + error_counter++; + return; + } + + sockfd = socket(server_info -> ai_family, server_info -> ai_socktype, + server_info -> ai_protocol); + if(sockfd < 0) + error_counter++; + + if(connect(sockfd, server_info -> ai_addr, server_info -> ai_addrlen) < 0) + error_counter++; + + freeaddrinfo(server_info); + + bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0); + + if(bytes_sent != (INT)strlen(send_buffer)) + error_counter++; + + /* Make sure the other side gets the message. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +static void test_tcp_server6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +UINT status; +struct addrinfo hints, *server_info; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + + if (getaddrinfo(NX_NULL, "12346", &hints, &server_info) != 0) + { + error_counter++; + return; + } + + sockfd = socket(server_info -> ai_family, server_info -> ai_socktype, + server_info -> ai_protocol); + if(sockfd < 0) + error_counter++; + + ret = bind(sockfd, server_info -> ai_addr, server_info -> ai_addrlen); + if(ret < 0) + error_counter++; + + freeaddrinfo(server_info); + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + error_counter++; + + if(address_length != sizeof(struct sockaddr_in6)) + error_counter++; + + if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + address_length = sizeof(local_addr); + ret = getsockname(newsock, (struct sockaddr*)&local_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(local_addr)) + error_counter++; + else if(local_addr.sin6_family != AF_INET6) + error_counter++; + else if(local_addr.sin6_port != htons(12346)) + error_counter++; + else if((local_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip0.nxd_ip_address.v6[0])) || + (local_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip0.nxd_ip_address.v6[1])) || + (local_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip0.nxd_ip_address.v6[2])) || + (local_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip0.nxd_ip_address.v6[3]))) + error_counter++; + + address_length = sizeof(remote_addr); + ret = getpeername(newsock, (struct sockaddr*)&remote_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if(remote_addr.sin6_family != AF_INET6) + error_counter++; + else if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + + + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_thread6[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space6[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status) + error_counter++; + + tx_thread_relinquish(); + } + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + +#endif + +static void close_before_accept_test() +{ +int server_fd, client_fd; +int ret; +struct sockaddr_in remote_addr, local_addr; + + /* Setup server socket. */ + server_fd = socket(AF_INET, SOCK_STREAM, 0); + if(server_fd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(server_fd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(server_fd, 5); + if(ret < 0) + error_counter++; + + /* Setup client socket. */ + client_fd = socket(AF_INET, SOCK_STREAM, 0); + if(client_fd < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12345); + remote_addr.sin_addr.s_addr = htonl(0x01020304); + + if(connect(client_fd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0) + error_counter++; + + /* Close before calling accept. */ + soc_close(server_fd); + soc_close(client_fd); +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +int sockfd; +struct sockaddr_in remote_addr; +#ifdef FEATURE_NX_IPV6 +char mac_ip0[6]; +char mac_ip1[6]; +UINT status; +#endif +int ret; + + + printf("NetX Test: Basic BSD getaddrinfo Test...................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = (CHAR)(ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8); + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = (CHAR)(ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8); + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + + close_before_accept_test(); + + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + test_tcp_client4(); + + tx_semaphore_put(&sema_1); + test_tcp_server4(); + +#ifdef FEATURE_NX_IPV6 + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + test_tcp_client6(); + + tx_semaphore_put(&sema_1); + test_tcp_server6(); +#endif + + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + /* Now open another socket and attempt to connect to the correct remote + host but an unexpected port so we expect an unsuccessful connections. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) >= 0) + error_counter++; + if(errno != ECONNREFUSED) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + /* Now open another socket and attempt to connect to the an incorrect + remote host so we expect an unsuccessful connections. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020306); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) >= 0) + error_counter++; + + if(errno != ETIMEDOUT) + error_counter++; + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + /* After the previous failed connection, make sure we can still open a socket. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS]; +static void multiple_client4(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < NUM_CLIENTS; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[i]); + + + status += nx_tcp_socket_delete(&tcp_sockets[i]); + + if(status != NX_SUCCESS) + error_counter++; + } + + +} + + +#ifdef FEATURE_NX_IPV6 +static void multiple_client6(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nxd_tcp_client_socket_connect(&tcp_sockets[i], &ipv6_address_ip0, 12346, NX_IP_PERIODIC_RATE); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < NUM_CLIENTS; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i & 3])) + error_counter++; + else if(strncmp((char *)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE); + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + status = nx_tcp_client_socket_unbind(&tcp_sockets[i]); + status += nx_tcp_socket_delete(&tcp_sockets[i]); + + if(status != NX_SUCCESS) + error_counter++; + } + +} +#endif + +static void netx_tcp_server(void) +{ +NX_PACKET *packet_ptr; +UINT status; + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != strlen(send_buffer))) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, send_buffer, strlen(send_buffer))) + error_counter++; + + nx_packet_release(packet_ptr); + } + + tx_semaphore_put(&sema_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + nx_tcp_socket_delete(&server_socket); +} + +static UINT nx_dns_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, + USHORT transmit_id, UCHAR *data, UINT length) +{ +UINT status; +NX_PACKET *response_packet; +UCHAR *data_ptr; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the DNS response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, data + DNS_START_OFFSET, length - DNS_START_OFFSET); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = length - DNS_START_OFFSET; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Update the DNS transmit ID. */ + data_ptr = response_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + *data_ptr++ = (UCHAR)(transmit_id >> 8); + *data_ptr = (UCHAR)transmit_id; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(server_socket, response_packet, IP_ADDRESS(1, 2, 3, 4), port); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ +NX_PACKET *packet_ptr; +USHORT transmit_id; +UCHAR *data_ptr; +UINT port; + + nx_udp_socket_receive(socket_ptr, &packet_ptr, NX_NO_WAIT); + nx_udp_packet_info_extract(packet_ptr, NX_NULL ,NX_NULL, &port, NX_NULL); + + /* Get the DNS transmit ID. */ + data_ptr = packet_ptr -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + transmit_id = *data_ptr++; + transmit_id = (USHORT)((transmit_id << 8) | *data_ptr); + + nx_packet_release(packet_ptr); + + if (response_sequence == 0) + { + nx_dns_response_packet_send(socket_ptr, port, transmit_id, response_a_www_baidu_com, sizeof(response_a_www_baidu_com)); + } + else + { + nx_dns_response_packet_send(socket_ptr, port, transmit_id, response_cname_www_baidu_com, sizeof(response_cname_www_baidu_com)); + } + + response_sequence++; +} + +static void dns_test() +{ +struct addrinfo hints, *addrinfo; + + /* Initialize DNS client. */ + nx_dns_create(&client_dns, &ip_0, (UCHAR *)"DNS Client"); +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + nx_dns_packet_pool_set(&client_dns, &pool_0); +#endif + nx_dns_server_add(&client_dns, IP_ADDRESS(1, 2, 3, 5)); + + /* Create a UDP socket to respond DNS query. */ + nx_udp_socket_create(&ip_1, &udp_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + nx_udp_socket_bind(&udp_socket, 53, TX_WAIT_FOREVER); + nx_udp_socket_receive_notify(&udp_socket, receive_packet_function); + response_sequence = 0; + + /* Get CName by getaddrinfo. */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + if (getaddrinfo("www.baidu.com", "80", &hints, &addrinfo) != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + if (addrinfo -> ai_canonname == NX_NULL) + { + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES + if (strcmp(addrinfo -> ai_canonname, "www.a.shifen.com")) +#else + if (strcmp(addrinfo -> ai_canonname, "www.baidu.com")) +#endif + { + printf("ERROR!\n"); + test_control_return(1); + } + freeaddrinfo(addrinfo); + + nx_udp_socket_unbind(&udp_socket); + nx_udp_socket_delete(&udp_socket); + nx_dns_delete(&client_dns); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_BSD_ENABLE_DNS + dns_test(); +#endif + + tx_semaphore_put(&sema_0); + + netx_tcp_server(); + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + /* Simulate a multiple client conneting to the same server. */ + multiple_client4(); + +#ifdef FEATURE_NX_IPV6 + tx_semaphore_put(&sema_0); + netx_tcp_server(); + + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + multiple_client6(); +#endif + + /* Client finished. */ + tx_semaphore_put(&sema_0); +} + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#endif /* NX_BSD_ENABLE */ diff --git a/test/regression/bsd_test/netx_bsd_inet_addr_pton_test.c b/test/regression/bsd_test/netx_bsd_inet_addr_pton_test.c new file mode 100644 index 00000000..b0a1222f --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_inet_addr_pton_test.c @@ -0,0 +1,136 @@ +/* This NetX test concentrates on the basic BSD utility function, inet_addr and inet_pton which + both call inet_aton for converting addresses into a in_addr numeric format. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#include "nxd_bsd.h" + + +#define DEMO_STACK_SIZE 4096 + +static TX_THREAD ntest_0; +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); + +static ULONG error_counter; + + +/* Define the ThreadX and NetX object control blocks... */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_inet_addr_pton_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + +} + +static void ntest_0_entry(ULONG thread_input) +{ + +struct in_addr in_val; +UCHAR ipv4_addr_num1[4] = {0x1, 0x2, 0x3, 0x4}; + +CHAR *ipv4_addr_str1 = "1.2.3.4"; +CHAR *ipv4_addr_str2 = "1.2.3.g"; +UCHAR ipv4_addr[4]; +UINT status; + + + printf("NetX Test: Basic BSD inet_addr inet_pton Test............"); + + in_val.s_addr = inet_addr("10.10.10.10"); + + if((in_val.s_addr == 0xFFFFFFFF) || (in_val.s_addr != 0x0a0a0a0a)) + error_counter++; + + in_val.s_addr = inet_addr("10.10.2570"); /* 2570 == 0x0a0a */ + if((in_val.s_addr == 0xFFFFFFFF) || (in_val.s_addr != 0x0a0a0a0a)) + error_counter++; + + in_val.s_addr = inet_addr("10.657930"); /* 657930 == 0x0a0a0a */ + if((in_val.s_addr == 0xFFFFFFFF) || (in_val.s_addr != 0x0a0a0a0a)) + error_counter++; + + /* octal */ + in_val.s_addr = inet_addr("012.012.012.012"); + if((in_val.s_addr == 0xFFFFFFFF) || (in_val.s_addr != 0x0a0a0a0a)) + error_counter++; + + /* hex */ + in_val.s_addr = inet_addr("0xa.0xa.0xa.0xa"); + if((in_val.s_addr == 0xFFFFFFFF) || (in_val.s_addr != 0x0a0a0a0a)) + error_counter++; + + /* decimal, octal and hex */ + in_val.s_addr = inet_addr("10.012.0xa.10"); + if((in_val.s_addr == 0xFFFFFFFF) || (in_val.s_addr != 0x0a0a0a0a)) + error_counter++; + + /* Invalid IP address. */ + in_val.s_addr = inet_addr("10.10.10,10.10"); + if(in_val.s_addr != 0xFFFFFFFF) + error_counter++; + + /* Invalid IP address char */ + in_val.s_addr = inet_addr("10.10.1h"); + if(in_val.s_addr != 0xFFFFFFFF) + error_counter++; + + /* Invalid first character. */ + in_val.s_addr = inet_addr("a0.10.1h"); + if(in_val.s_addr != 0xFFFFFFFF) + error_counter++; + + status = inet_pton(AF_INET, ipv4_addr_str1, ipv4_addr); + if((status != 1) && (memcmp(ipv4_addr, ipv4_addr_num1, 4) != 0 )) + error_counter++; + + status = inet_pton(AF_INET, ipv4_addr_str2, ipv4_addr); + if(status != 0) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_inet_addr_pton_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: Basic BSD inet_addr inet_pton Test............N/A\n"); + test_control_return(3); +} + +#endif diff --git a/test/regression/bsd_test/netx_bsd_ioctl_nonblocking_test.c b/test/regression/bsd_test/netx_bsd_ioctl_nonblocking_test.c new file mode 100644 index 00000000..8a5b0839 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_ioctl_nonblocking_test.c @@ -0,0 +1,1369 @@ +/* This NetX test concentrates on the basic BSD non-blocking operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 10 + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif +static char *send_buffer = "Hello World"; +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_ioctl_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 4096, 1); + pointer = pointer + 4096; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 4096, 2); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + if(status != TX_SUCCESS) + error_counter++; +} + + +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[NUM_CLIENTS]; +static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static ULONG stack_blocking_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; + +#ifdef FEATURE_NX_IPV6 +static ULONG stack_space6[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread6[NUM_CLIENTS]; +#endif +static TX_THREAD helper_thread[NUM_CLIENTS]; +static TX_THREAD helper_blocking_thread[NUM_CLIENTS]; + +static VOID bsd_server_blocking_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +char buf[30]; + /* Note the socket is already in non-blocking mode. */ + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + + ret = recv(sockfd, buf, sizeof(buf), 0); + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id&3])) || strncmp(buf, requests[message_id&3], ret)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id&3], strlen(response[message_id&3]), 0); + if(ret != (int)strlen(response[message_id&3])) + error_counter++; + + /* Wait until client received. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + tx_semaphore_put(&sema_0); + return; + +} +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +fd_set read_fd, except_fd; +struct timeval tv; +char buf[30]; + /* Note the socket is already in non-blocking mode. */ + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + FD_ZERO(&except_fd); + FD_SET(sockfd, &except_fd); + + tv.tv_sec = 1; + tv.tv_usec = 0; + + ret = select(sockfd + 1, &read_fd, NULL, &except_fd, &tv); + if(ret < 0) + { + error_counter++; + return; + } + if(ret == 1) + { + /* Check for read_fd */ + if(FD_ISSET(sockfd, &read_fd)) + { + ret = recv(sockfd, buf, sizeof(buf), 0); + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id&3])) || strncmp(buf, requests[message_id&3], ret)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id&3], strlen(response[message_id&3]), 0); + if(ret != (int)strlen(response[message_id&3])) + error_counter++; + + /* Wait until client received. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + } + } + else error_counter++; + + tx_semaphore_put(&sema_0); + return; +} + +static void test_tcp_blocking_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +UINT status; +int ioctl_arg; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + /* Set the socket to non-blocking mode. */ + ioctl_arg = NX_TRUE; + if(ioctl(sockfd, FIONBIO, &ioctl_arg)) + error_counter++; + + /* Set the socket to blocking mode. */ + ioctl_arg = NX_FALSE; + if(ioctl(sockfd, FIONBIO, &ioctl_arg)) + error_counter++; + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + address_length = sizeof(local_addr); + ret = getsockname(newsock, (struct sockaddr*)&local_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(local_addr)) + error_counter++; + else if(local_addr.sin_family != AF_INET) + error_counter++; + else if(local_addr.sin_port != htons(12345)) + error_counter++; + else if(local_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1, 2, 3, 4))) + error_counter++; + + address_length = sizeof(remote_addr); + ret = getpeername(newsock, (struct sockaddr*)&remote_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if(remote_addr.sin_family != AF_INET) + error_counter++; + else if(remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5))) + error_counter++; + + + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_blocking_thread[i], "helper thread", bsd_server_blocking_helper_thread_entry, + i, stack_blocking_space[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status != TX_SUCCESS) + error_counter++; + + tx_thread_relinquish(); + } + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } + +} + + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +fd_set read_fd; +struct timeval tv; +int error, len; +int ioctl_arg = NX_TRUE; + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + /* Set the socket to non-blocking mode. */ + if(ioctl(sockfd, FIONBIO, &ioctl_arg)) + error_counter++; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + tv.tv_sec = 2; + tv.tv_usec = 0; + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + + if(ret != 1) + error_counter++; + else if(!FD_ISSET(sockfd, &read_fd)) + error_counter++; + + /* Check pending error. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + if(error_counter == 0) + { + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + if(newsock > 0) + { + if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + if(error_counter == 0) + { + + /* Set the new socket to non-blocking mode. */ + if(ioctl(sockfd, FIONBIO, &ioctl_arg)) + error_counter++; + else + { + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space[i], DEMO_STACK_SIZE, 2,2, TX_NO_TIME_SLICE, TX_AUTO_START); + continue; + } + } + } + ret = soc_close(newsock); + if(ret != 0) + error_counter++; + } + } + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + +#ifdef FEATURE_NX_IPV6 + +static void test_tcp_server6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +fd_set read_fd; +struct timeval tv; +int error, len; +int ioctl_arg = NX_TRUE; + + sockfd = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_family = AF_INET6; + local_addr.sin6_port = htons(12346); + + /* Set the socket to non-blocking mode. */ + if(ioctl(sockfd, FIONBIO, &ioctl_arg)) + error_counter++; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + tv.tv_sec = 2; + tv.tv_usec = 0; + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + + if(ret != 1) + error_counter++; + else if(!FD_ISSET(sockfd, &read_fd)) + error_counter++; + + /* Check pending error. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + if(error_counter == 0) + { + address_length = sizeof(remote_addr); + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + if(newsock > 0) + { + if(address_length != sizeof(struct sockaddr_in6)) + error_counter++; + else if(remote_addr.sin6_family != AF_INET6) + error_counter++; + else if((remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + if(error_counter == 0) + { + + /* Set the new socket to non-blocking mode. */ + if(ioctl(sockfd, FIONBIO, &ioctl_arg)) + error_counter++; + else + { + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + tx_thread_create(&helper_thread6[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space6[i], DEMO_STACK_SIZE, 2,2, TX_NO_TIME_SLICE, TX_AUTO_START); + continue; + } + } + } + ret = soc_close(newsock); + if(ret < 0) + error_counter++; + } + } + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} +#endif + + +static void test_tcp_client4(void) +{ +int sockfd; +struct sockaddr_in remote_addr; +int ret; +fd_set write_fd; +struct timeval tv; +int bytes_sent; +int error, len; +int ioctl_arg = NX_TRUE; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + /* Set the socket as non-blocking */ + if(ioctl(sockfd, FIONBIO, &ioctl_arg)) + error_counter++; + + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + { + /* Non blocking call, it shouldn't succeed. */ + error_counter++; + soc_close(sockfd); + return; + } + else + { + /* Make sure the errno is EINPROGRESS */ + if(errno != EINPROGRESS) + { + error_counter++; + return; + } + } + + /* Now select on the socket. */ + + /* Wait for one second. */ + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&write_fd); + FD_SET(sockfd, &write_fd); + + ret = select(FD_SETSIZE, NULL, &write_fd, NULL, &tv); + + /* If select returns, there should only be one socket in the write group being selected. */ + if(ret != 1) + error_counter++; + else if(!FD_ISSET(sockfd, &write_fd)) + error_counter++; + + /* Check pending error. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + if(error_counter == 0) + { + /* select successfully returns. So do connect call again. This connect call should return 0. */ + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret != 0) + { + error_counter++; + return; + } + + bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0); + + if(bytes_sent != (int)strlen(send_buffer)) + error_counter++; + + /* Make sure the other side gets the message. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + } +} + +#ifdef FEATURE_NX_IPV6 +static void test_tcp_client6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr; +int ret; +fd_set write_fd; +struct timeval tv; +int bytes_sent; +int error, len; +int ioctl_arg = NX_TRUE; + + sockfd = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + /* Set the socket as non-blocking */ + if(ioctl(sockfd, FIONBIO, &ioctl_arg)) + error_counter++; + + remote_addr.sin6_family = AF_INET6; + remote_addr.sin6_port = htons(12); + remote_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip1.nxd_ip_address.v6[0]); + remote_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip1.nxd_ip_address.v6[1]); + remote_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip1.nxd_ip_address.v6[2]); + remote_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip1.nxd_ip_address.v6[3]); + + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + { + /* Non blocking call, it shouldn't succeed. */ + error_counter++; + soc_close(sockfd); + return; + } + else + { + /* Make sure the errno is EINPROGRESS */ + if(errno != EINPROGRESS) + { + error_counter++; + return; + } + } + + /* Now select on the socket. */ + + /* Wait for one second. */ + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&write_fd); + FD_SET(sockfd, &write_fd); + + ret = select(sockfd + 1, NULL, &write_fd, NULL, &tv); + + /* If select returns, there should only be one socket in the write group being selected. */ + if(ret != 1) + error_counter++; + else if(!FD_ISSET(sockfd, &write_fd)) + error_counter++; + + /* Check pending error. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + if(error_counter == 0) + { + /* select successfully returns. So do connect call again. This connect call should return 0. */ + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret != 0) + { + error_counter++; + return; + } + + bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0); + + if(bytes_sent != (INT)strlen(send_buffer)) + error_counter++; + + /* Make sure the other side gets the message. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + } +} + +#endif /*FEATURE_NX_IPV6 */ +static void ntest_0_entry(ULONG thread_input) +{ +int retry; +int sockfd; +struct sockaddr_in remote_addr; +int ret; +fd_set read_fd, write_fd; +struct timeval tv; +int ioctl_arg = NX_TRUE; +#ifdef FEATURE_NX_IPV6 +UINT status; +char mac_ip0[6]; +char mac_ip1[6]; +#endif + printf("NetX Test: Basic BSD TCP Ioctl Non Blocking Connect Test."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + + /* Server run first. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + test_tcp_client4(); + + /* Wakeup client. */ + tx_semaphore_put(&sema_1); + + test_tcp_server4(); + +#ifdef FEATURE_NX_IPV6 + /* Server run first. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + test_tcp_client6(); + + /* Wakeup client. */ + tx_semaphore_put(&sema_1); + + test_tcp_server6(); +#endif + + /* Wakeup client. */ + tx_semaphore_put(&sema_1); + + /* blocking test. */ + test_tcp_blocking_server4(); + + /* Wait until client finish. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + + /* Now open another socket and attempt to connect to the correct remote + host but an unexpected port so we expect an unsuccessful connections. */ + retry = 0; + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + /* Set the socket as non-blocking */ + if(ioctl(sockfd, FIONBIO, &ioctl_arg)) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + { + /* Non blocking call, it shouldn't succeed. */ + error_counter++; + } + else + { + /* Make sure the errno is EINPROGRESS */ + if(errno != EINPROGRESS) + error_counter++; + } + + do + { + /* Wait for one second. */ + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + FD_ZERO(&write_fd); + FD_SET(sockfd, &write_fd); + + + ret = select(sockfd + 1, &read_fd, &write_fd, NULL, &tv); + + /* If select returns, there should only be one socket in the write group being selected. */ + if(ret == 0) + { + retry++; + if(retry == 31) + error_counter++; + } + else if(ret < 1) + { + error_counter++; + } + else if(FD_ISSET(sockfd, &write_fd)) + break; + }while(error_counter == 0); + + if(error_counter == 0) + { + /* select successfully returns. So do connect call again. This connect call should return 0. */ + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + error_counter++; + if(errno != ECONNREFUSED) + error_counter++; + } + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + + /* Now open another socket and attempt to connect to the an incorrect + remote host so we expect an unsuccessful connections. */ + retry = 0; + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + /* Set the socket as non-blocking */ + if(ioctl(sockfd, FIONBIO, &ioctl_arg)) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + { + /* Non blocking call, it shouldn't succeed. */ + error_counter++; + } + else + { + /* Make sure the errno is EINPROGRESS */ + if(errno != EINPROGRESS) + error_counter++; + } + + do + { + /* Wait for one second. */ + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + FD_ZERO(&write_fd); + FD_SET(sockfd, &write_fd); + + + ret = select(sockfd + 1, &read_fd, &write_fd, NULL, &tv); + + /* If select returns, there should only be one socket in the write group being selected. */ + if(ret == 0) + { + retry++; + if(retry == 31) + error_counter++; + } + else if(ret < 1) + { + error_counter++; + } + else if((FD_ISSET(sockfd, &write_fd))) + break; + }while(error_counter == 0); + + if(error_counter == 0) + { + /* select successfully returns. So do connect call again. This connect call should return 0. */ + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + error_counter++; + if(errno != ECONNREFUSED) + error_counter++; + } + + + + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + + test_control_return(0); + +} + +static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS]; +static void multiple_client4(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i&3], strlen(requests[i&3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < NUM_CLIENTS; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i&3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i&3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 0); +#ifdef NX_DISABLE_RESET_DISCONNECT + if((status != NX_SUCCESS) && (status != NX_NOT_CONNECTED)) + error_counter++; +#endif + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + { + status = nx_tcp_client_socket_unbind(&tcp_sockets[i]); + if(status != NX_SUCCESS) + error_counter ++; + } + + status = nx_tcp_socket_delete(&tcp_sockets[i]); + if(status != NX_SUCCESS) + error_counter ++; + + tx_semaphore_put(&sema_1); + } +} + + +#ifdef FEATURE_NX_IPV6 +static void multiple_client6(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nxd_tcp_client_socket_connect(&tcp_sockets[i], &ipv6_address_ip0, 12346, NX_IP_PERIODIC_RATE); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i&3], strlen(requests[i&3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < NUM_CLIENTS; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + + /* Wait all remote thread close first. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 0); +#ifdef NX_DISABLE_RESET_DISCONNECT + if((status != NX_SUCCESS) && (status != NX_NOT_CONNECTED)) + error_counter++; +#endif + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + { + status = nx_tcp_client_socket_unbind(&tcp_sockets[i]); + if(status != NX_SUCCESS) + error_counter ++; + } + + status = nx_tcp_socket_delete(&tcp_sockets[i]); + if(status != NX_SUCCESS) + error_counter ++; + } + + +} + +#endif + +static void netx_tcp_server(void) +{ + +UINT status; +NX_PACKET *packet_ptr; + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + return; + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length != strlen(send_buffer)) + error_counter++; + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, send_buffer, strlen(send_buffer))) + error_counter++; + + nx_packet_release(packet_ptr); + } + + tx_semaphore_put(&sema_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + nx_tcp_socket_delete(&server_socket); +} +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Wakeup client. */ + tx_semaphore_put(&sema_0); + + netx_tcp_server(); + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + multiple_client4(); + + /* Client finished. */ + tx_semaphore_put(&sema_0); + +#ifdef FEATURE_NX_IPV6 + /* Wakeup client. */ + tx_semaphore_put(&sema_0); + + netx_tcp_server(); + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + multiple_client6(); + + /* Client finished. */ + tx_semaphore_put(&sema_0); +#endif + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + multiple_client4(); + + /* Client finished. */ + tx_semaphore_put(&sema_0); +} + + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + return; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + return; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + return; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_ioctl_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Ioctl Non Blocking Connect Test.N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_multicast_test.c b/test/regression/bsd_test/netx_bsd_multicast_test.c new file mode 100644 index 00000000..3a7c8cfe --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_multicast_test.c @@ -0,0 +1,429 @@ +/* This NetX test concentrates on the basic BSD UDP non-blocking operation. */ +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nxd_bsd.h" +#else +#include "nx_ip.h" +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +#define MULTICAST_ADDRESS IP_ADDRESS(239, 1, 2, 3) +#define MULTICAST_TTL_VALUE 65 + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ + +#ifdef __PRODUCT_NETX__ +#define NX_IPV4_HEADER NX_IP_HEADER +#endif + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_multicast_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check UDP enable and BSD init status. */ + if (status) + error_counter++; +} + +static void test_udp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; +struct ip_mreq mreq; +UCHAR ttl; +int status; +int i; + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + memset(&mreq, 0, sizeof(struct ip_mreq)); + + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + mreq.imr_multiaddr.s_addr = htonl(MULTICAST_ADDRESS); + + status = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)); + if(status) + error_counter++; + + ttl = MULTICAST_TTL_VALUE; + status = setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); + if(status) + error_counter++; + + /* Make sure the address is recorded into the IGMP table. */ + error_counter++; + for(i = 0; i < NX_MAX_MULTICAST_GROUPS; i++) + { +#ifdef __PRODUCT_NETXDUO__ + if(ip_0.nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_count == 0) + continue; + + if((ip_0.nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_list == MULTICAST_ADDRESS) && + (ip_0.nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_interface_list == &(ip_0.nx_ip_interface[0]))) + { + error_counter--; + break; + } +#else + if(ip_0.nx_ip_igmp_join_count[i] == 0) + continue; + + if((ip_0.nx_ip_igmp_join_list[i] == MULTICAST_ADDRESS) && + (ip_0.nx_ip_igmp_join_interface_list[i] == &(ip_0.nx_ip_interface[0]))) + { + error_counter--; + break; + } +#endif + + } + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + + if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5))) || + (remote_addr.sin_port != htons(54321))) + error_counter++; + + /* Validate the data. */ + if((ret != (int)strlen(requests[0])) || strncmp(buf, requests[0], ret)) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (int)strlen(response[0])) + error_counter++; + + tx_thread_sleep(1); + + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + mreq.imr_multiaddr.s_addr = htonl(MULTICAST_ADDRESS); + status = setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)); + + if(status) + error_counter++; + + /* Make sure the address has been removed from the IGMP table. */ + for(i = 0; i < NX_MAX_MULTICAST_GROUPS; i++) + { +#ifdef __PRODUCT_NETXDUO__ + if(ip_0.nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_count == 0) + continue; + + if((ip_0.nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_list == MULTICAST_ADDRESS) && + (ip_0.nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_interface_list == &(ip_0.nx_ip_interface[0]))) + { + error_counter++; + break; + } +#else + if(ip_0.nx_ip_igmp_join_count[i] == 0) + continue; + + if((ip_0.nx_ip_igmp_join_list[i] == MULTICAST_ADDRESS) && + (ip_0.nx_ip_igmp_join_interface_list[i] == &(ip_0.nx_ip_interface[0]))) + { + error_counter++; + break; + } +#endif + } + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ + printf("NetX Test: Basic BSD Multicast Test......................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + test_udp_server4(); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +NX_IPV4_HEADER *ipv4_header_ptr; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Enable IGMP */ + status = nx_igmp_enable(&ip_1); + if(status) + error_counter++; + + /* Join the test IGMP group */ + if(nx_igmp_multicast_join(&ip_1, MULTICAST_ADDRESS)) + error_counter++; + + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Send a UDP packet */ + status = nx_udp_socket_send(&server_socket, packet_ptr, IP_ADDRESS(1,2,3,4), 12345); + if(status) + error_counter++; + + /* Ready to reaceive a message */ + status = nx_udp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0]))) + error_counter++; + + /* Verify the TTL value. */ +#ifdef __PRODUCT_NETXDUO__ + ipv4_header_ptr = (NX_IPV4_HEADER*)packet_ptr -> nx_packet_ip_header; +#else + ipv4_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr - 8 - 20); +#endif + if((ipv4_header_ptr -> nx_ip_header_word_2 >> 24) != MULTICAST_TTL_VALUE) + error_counter++; + + status = nx_udp_socket_unbind(&server_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&server_socket); + if(status) + error_counter++; + +} + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_multicast_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD Multicast Test......................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_ntoa_test.c b/test/regression/bsd_test/netx_bsd_ntoa_test.c new file mode 100644 index 00000000..78c59ad8 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_ntoa_test.c @@ -0,0 +1,123 @@ +/* This NetX test concentrates on inet_ntoa function. */ +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif + +#define DEMO_STACK_SIZE 4096 + +static TX_THREAD ntest_0; +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the ThreadX and NetX object control blocks... */ +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static ULONG error_counter; + +/* Define the ThreadX and NetX object control blocks... */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_ntoa_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 1024); + pointer = pointer + 1024; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, DEMO_STACK_SIZE, 1); + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + status = bsd_initialize(&ip_0, &pool_0, pointer, DEMO_STACK_SIZE, 2); + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; +} + +static void ntest_0_entry(ULONG thread_input) +{ + +struct in_addr in_val; +INT status; +ULONG addr; +CHAR *addr_str; +CHAR *ret; + + printf("NetX Test: Basic BSD ntoa Test..........................."); + + addr_str = "11.10.10.10"; + addr = htonl(0x0b0a0a0a); + status = inet_aton(addr_str, &in_val); + if ((status != 1) || (in_val.s_addr != addr)) + error_counter++; + + ret = inet_ntoa(in_val); + + if (ret == NX_NULL) + error_counter++; + else if (strcmp(ret, addr_str)) + error_counter++; + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_ntoa_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD ntoa Test...........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_ntop_test.c b/test/regression/bsd_test/netx_bsd_ntop_test.c new file mode 100644 index 00000000..e96f4cc7 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_ntop_test.c @@ -0,0 +1,143 @@ +/* This NetX test concentrates on the basic BSD UDP non-blocking operation. */ +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#include "nxd_bsd.h" + +#define DEMO_STACK_SIZE 4096 + +static TX_THREAD ntest_0; +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; + +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 10 + +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +static ULONG error_counter; + +/* Define the ThreadX and NetX object control blocks... */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_ntop_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 4096, 1); + pointer = pointer + 4096; + + /* Enable BSD */ + status = bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + +} + +static void ntest_0_entry(ULONG thread_input) +{ + +/* Network byte ordered IPv6 adddress. */ + +/* fe80::74ac:2217:530:5d7f */ +ULONG ipv6_addr1[] = {htonl(0xfe800000), htonl(0), htonl(0x74ac2217), htonl(0x5305d7f)}; +/* fe80::74ac:0:530:5d7f */ +ULONG ipv6_addr2[] = {htonl(0xfe800000), htonl(0), htonl(0x74ac0000), htonl(0x5305d7f)}; +/* ::ffff:1.2.3.4 */ +ULONG ipv6_addr3[] = {htonl(0), htonl(0), htonl(0xffff), htonl(0x01020304)}; +/* ::1.2.3.4 */ +ULONG ipv6_addr4[] = {htonl(0), htonl(0), htonl(0), htonl(0x01020304)}; +/* fe80:1232:af65:f3d2:2d28:af23:201:403*/ +ULONG ipv6_addr5[] = {htonl(0xfe801232), htonl(0xaf65f3d2), htonl(0x2d28af23), htonl(0x2010403)}; + + +/* Max Length = 46. "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255" */ +CHAR dst[46]; +const CHAR *rt_ptr; + + + printf("NetX Test: Basic BSD ntop Test..........................."); + + rt_ptr = inet_ntop(AF_INET6, ((VOID *)(&ipv6_addr1[0])), dst, 46); + if((rt_ptr == NX_NULL) || (strcmp(dst, "fe80::74ac:2217:530:5d7f") != 0)) + error_counter++; + + rt_ptr = inet_ntop(AF_INET6, (VOID *)(&ipv6_addr2[0]), dst, 46); + if((rt_ptr == NX_NULL) || (strcmp(dst, "fe80::74ac:0:530:5d7f") != 0)) + error_counter++; + + rt_ptr = inet_ntop(AF_INET6, (VOID *)(&ipv6_addr3[0]), dst, 46); + if((rt_ptr == NX_NULL) || (strcmp(dst, "::ffff:1.2.3.4") != 0)) + error_counter++; + + rt_ptr = inet_ntop(AF_INET6, (VOID *)(&ipv6_addr4[0]), dst, 46); + if((rt_ptr == NX_NULL) || (strcmp(dst, "::1.2.3.4") != 0)) + error_counter++; + + rt_ptr = inet_ntop(AF_INET6, (VOID *)(&ipv6_addr5[0]), dst, 46); + if((rt_ptr == NX_NULL) || (strcmp(dst, "fe80:1232:af65:f3d2:2d28:af23:201:403") != 0)) + error_counter++; + + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +#else +extern void test_control_return(UINT status); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_ntop_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Basic BSD ntop Test...........................N/A\n"); + test_control_return(3); +} + +#endif diff --git a/test/regression/bsd_test/netx_bsd_pton_test.c b/test/regression/bsd_test/netx_bsd_pton_test.c new file mode 100644 index 00000000..31b0ab8e --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_pton_test.c @@ -0,0 +1,141 @@ +/* This NetX test concentrates on the basic BSD UDP non-blocking operation. */ +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#include "nxd_bsd.h" + +#define DEMO_STACK_SIZE 4096 + +static TX_THREAD ntest_0; +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); + +static ULONG error_counter; + +/* Define the ThreadX and NetX object control blocks... */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_pton_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + +CHAR *ipv6_addr_str1 = "fe80::74ac:2217:530:5d7f"; +ULONG ipv6_addr_num1[] = {htonl(0xfe800000), htonl(0), htonl(0x74ac2217), htonl(0x05305d7f)}; + +CHAR *ipv6_addr_str2 = "fe80::74ac:0:530:5d7f"; +ULONG ipv6_addr_num2[] = {htonl(0xfe800000), htonl(0), htonl(0x74ac0000), htonl(0x05305d7f)}; + +CHAR *ipv6_addr_str3 = "::ffff:1.2.3.4"; +ULONG ipv6_addr_num3[] = {htonl(0), htonl(0), htonl(0xffff), htonl(0x01020304)}; + +CHAR *ipv6_addr_str4 = "::1.2.3.4"; +ULONG ipv6_addr_num4[] = {htonl(0), htonl(0), htonl(0), htonl(0x01020304)}; + +CHAR *ipv6_addr_str5 = "fe80::74gc:0:p30:5d7f"; + +CHAR *ipv6_addr_str6 = "2001:0000:0000:0003:0000:0000:0000:0053"; +CHAR *ipv6_addr_str6_1 = "2001:0:0:3::0053"; +ULONG ipv6_addr_num6[] = {htonl(0x20010000), htonl(3), htonl(0), htonl(0x53)}; + +CHAR *ipv4_addr_str1 = "1.2.3.4"; +ULONG ipv4_addr_num1[] = {htonl(0x01020304)}; + +CHAR *ipv4_addr_str2 = "1.2.3.g"; + +CHAR *ipv4_addr_str3 = "11.10.2570"; /* 2570 == 0x0a0a */ +ULONG ipv4_addr_num3[] = {htonl(0x0b0a0a0a)}; + +UCHAR ipv6_addr[16]; /* 16*8 == 128 */ +UCHAR ipv4_addr[4]; /* 4*8 == 32 */ + + + printf("NetX Test: Basic BSD pton Test..........................."); + + status = inet_pton(AF_INET6, ipv6_addr_str1, ipv6_addr); + if((status != 1) || (memcmp(ipv6_addr, ipv6_addr_num1, 16) != 0 )) + error_counter++; + + status = inet_pton(AF_INET6, ipv6_addr_str2, ipv6_addr); + if((status != 1) || (memcmp(ipv6_addr, ipv6_addr_num2, 16) != 0 )) + error_counter++; + + status = inet_pton(AF_INET6, ipv6_addr_str3, ipv6_addr); + if((status != 1) || (memcmp(ipv6_addr, ipv6_addr_num3, 16) != 0 )) + error_counter++; + + status = inet_pton(AF_INET6, ipv6_addr_str4, ipv6_addr); + if((status != 1) || (memcmp(ipv6_addr, ipv6_addr_num4, 16) != 0 )) + error_counter++; + + status = inet_pton(AF_INET6, ipv6_addr_str5, ipv6_addr); + if(status != 0) + error_counter++; + + status = inet_pton(AF_INET6, ipv6_addr_str6, ipv6_addr); + if((status != 1) || (memcmp(ipv6_addr, ipv6_addr_num6, 16) != 0 )) + error_counter++; + + status = inet_pton(AF_INET6, ipv6_addr_str6_1, ipv6_addr); + if((status != 1) || (memcmp(ipv6_addr, ipv6_addr_num6, 16) != 0 )) + error_counter++; + + status = inet_pton(AF_INET, ipv4_addr_str1, ipv4_addr); + if((status != 1) || (memcmp(ipv4_addr, ipv4_addr_num1, 4) != 0 )) + error_counter++; + + status = inet_pton(AF_INET, ipv4_addr_str2, ipv4_addr); + if(status != 0) + error_counter++; + + status = inet_pton(AF_INET, ipv4_addr_str3, ipv4_addr); + if((status != 1) || (memcmp(ipv4_addr, ipv4_addr_num3, 4) != 0 )) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +#else +extern void test_control_return(UINT status); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_pton_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Basic BSD pton Test...........................N/A\n"); + test_control_return(3); +} + +#endif diff --git a/test/regression/bsd_test/netx_bsd_raw_basic_blocking_test.c b/test/regression/bsd_test/netx_bsd_raw_basic_blocking_test.c new file mode 100644 index 00000000..aeb55049 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_raw_basic_blocking_test.c @@ -0,0 +1,472 @@ +/* This NetX test concentrates on the basic BSD RAW blocking operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#ifdef NX_BSD_ENABLE +#include "nxd_bsd.h" +#include "nx_icmpv6.h" +#define DEMO_STACK_SIZE 8192 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif /* FEATURE_NX_IPV6 */ +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +extern UINT _nxd_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, NXD_ADDRESS *destination_ip, ULONG protocol, UINT ttl, ULONG tos); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_basic_blocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable raw processing for both IP instances. */ + status += nx_ip_raw_packet_enable(&ip_0); + status += nx_ip_raw_packet_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check RAW enable and BSD init status. */ + if (status) + error_counter++; +} + +static void test_raw_server_ipv4(void) +{ +int sockfd; +struct sockaddr_in remote_addr; +struct sockaddr_ll sock_addr; +int ret; +char buf[30]; +int addrlen; + + + sockfd = socket(AF_INET, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + + if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5)))) + error_counter++; + + /* Validate the data. */ + if((ret != (int)(strlen(requests[0]) + 20)) || strncmp((buf + 20), requests[0], (ret - 20))) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (int)strlen(response[0])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +#ifdef NX_BSD_RAW_SUPPORT + /* Test raw packet type. */ + sockfd = socket(AF_PACKET, SOCK_RAW, 200); + if(sockfd < 0) + error_counter++; + + sock_addr.sll_family = AF_PACKET; + sock_addr.sll_ifindex = 0; + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&sock_addr, sizeof(sock_addr)); + if(ret != (int)strlen(response[0])) + error_counter++; + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; +#endif + + + /* Give the reciever a chance to receive the raw data. */ + tx_thread_sleep(2); + +} + +#ifdef FEATURE_NX_IPV6 +static void test_raw_server_ipv6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr; +int ret; +char buf[50]; +int addrlen; + + + sockfd = socket(AF_INET6, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in6)) + error_counter++; + + if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + + /* Validate the data. */ + if((ret != (INT)(strlen(requests[0]) )) || strncmp((buf ), requests[0], ret )) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (INT)strlen(response[0])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + /* Give the reciever a chance to receive the raw data. */ + tx_thread_sleep(2); + +} + +#endif + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +UINT status; +char mac_ip0[6]; +char mac_ip1[6]; +#endif + printf("NetX Test: Basic BSD Raw Blocking Test..................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + test_raw_server_ipv4(); + + /* Now open another socket and attempt to connect to the correct remote + host but an unexpected port so we expect an unsuccessful connections. */ +#if 0 + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; +#endif + + /* Allow the stateless autoaddress configuration/DAD to finish */ + tx_thread_sleep(3); + +#ifdef FEATURE_NX_IPV6 + test_raw_server_ipv6(); +#endif + + validate_bsd_structure(); + tx_thread_sleep(2); + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +NXD_ADDRESS dest_addr; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Send a RAW packet */ + dest_addr.nxd_ip_version = NX_IP_VERSION_V4; + dest_addr.nxd_ip_address.v4 = IP_ADDRESS(1,2,3,4); + status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &dest_addr, 100, 128, 0); + if(status) + error_counter++; + + error_counter++; + tx_thread_sleep(1); + /* Ready to reaceive a message */ + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0]))) + error_counter++; + else + error_counter--; + +#ifdef FEATURE_NX_IPV6 + /* Test IPv6 */ + tx_thread_sleep(5); + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &ipv6_address_ip0, 100, 128, 0); + if(status) + error_counter++; + + error_counter++; + tx_thread_sleep(1); + /* Ready to reaceive a message */ + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0]))) + error_counter++; + else + error_counter--; + +#endif +} + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } + +} + +#endif /* NX_BSD_ENABLE */ + +#else /* __PRODUCT_NETXDUO__ */ + +extern void test_control_return(UINT status); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_basic_blocking_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Basic BSD Raw Blocking Test...................N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/bsd_test/netx_bsd_raw_basic_nonblocking_test.c b/test/regression/bsd_test/netx_bsd_raw_basic_nonblocking_test.c new file mode 100644 index 00000000..ef8d098e --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_raw_basic_nonblocking_test.c @@ -0,0 +1,519 @@ +/* This NetX test concentrates on the basic BSD RAW non-blocking operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#ifdef NX_BSD_ENABLE +#include "nxd_bsd.h" +#include "nx_icmpv6.h" +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif /* FEATURE_NX_IPV6 */ +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ +extern UINT _nxd_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, NXD_ADDRESS *destination_ip, ULONG protocol, UINT ttl, ULONG tos); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_basic_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable raw processing for both IP instances. */ + status = nx_ip_raw_packet_enable(&ip_0); + status = nx_ip_raw_packet_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check RAW enable and BSD init status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + if(status != TX_SUCCESS) + error_counter++; +} + +static void test_raw_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr; +int ret; +char buf[30]; +fd_set read_fd; +struct timeval tv; +int addrlen; +int error, len; + + + sockfd = socket(AF_INET, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Set the socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret > 0) + error_counter++; + else + { + /* Check errno */ + if(errno != EWOULDBLOCK) + error_counter++; + } + + /* Select on the socket. */ + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + tv.tv_sec = 2; + tv.tv_usec = 0; + + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + if(ret != 1) + error_counter++; + + if(!FD_ISSET(sockfd, &read_fd)) + error_counter++; + + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); +#if 0 + if(error) + error_counter++; +#endif + + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret < 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + + if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5)))) + error_counter++; + + /* Validate the data. */ + if(((ret - 20) != (int)strlen(requests[0])) || strncmp((buf + 20), requests[0], (ret - 20))) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (int)strlen(response[0])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; +} + +#ifdef FEATURE_NX_IPV6 +static void test_raw_server_ipv6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr; +int ret; +char buf[50]; +int addrlen; +fd_set read_fd; +struct timeval tv; +int error, len; + + sockfd = socket(AF_INET6, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Set the socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret > 0) + error_counter++; + else + { + /* Check errno */ + if(errno != EWOULDBLOCK) + error_counter++; + } + + /* Select on the socket. */ + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + tv.tv_sec = 2; + tv.tv_usec = 0; + + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + if(ret != 1) + error_counter++; + + if(!FD_ISSET(sockfd, &read_fd)) + error_counter++; + + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); +#if 0 + if(error) + error_counter++; +#endif + + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in6)) + error_counter++; + + if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + + /* Validate the data. */ + if((ret != (INT)(strlen(requests[0]))) || strncmp(buf , requests[0], ret )) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (INT)strlen(response[0])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; +} + +#endif + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +char mac_ip0[6]; +char mac_ip1[6]; +UINT status; +#endif + + printf("NetX Test: Basic BSD RAW Non-Blocking Test..............."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + tx_semaphore_put(&sema_1); + + test_raw_server4(); + +#ifdef FEATURE_NX_IPV6 + tx_semaphore_put(&sema_1); + test_raw_server_ipv6(); +#endif + + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +NXD_ADDRESS dest_addr; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Send a RAW packet */ + dest_addr.nxd_ip_version = NX_IP_VERSION_V4; + dest_addr.nxd_ip_address.v4 = IP_ADDRESS(1,2,3,4); + status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &dest_addr, 100, 128, 0); + if(status) + error_counter++; + + /* Ready to reaceive a message */ + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, (char*)response[0], strlen(response[0]))) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Test IPv6 */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &ipv6_address_ip0, 100, 128, 0); + if(status) + error_counter++; + + /* Ready to reaceive a message */ + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char *)packet_ptr -> nx_packet_prepend_ptr, (char *)response[0], strlen(response[0]))) + error_counter++; + +#endif + tx_semaphore_put(&sema_0); + +} + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#endif /* NX_BSD_ENABLE */ + +#else /* __PRODUCT_NETXDUO__ */ + +extern void test_control_return(UINT status); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_basic_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Basic BSD RAW Non-Blocking Test...............N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/bsd_test/netx_bsd_raw_basic_rx_nohdr_blocking_test.c b/test/regression/bsd_test/netx_bsd_raw_basic_rx_nohdr_blocking_test.c new file mode 100644 index 00000000..34f765c2 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_raw_basic_rx_nohdr_blocking_test.c @@ -0,0 +1,469 @@ +/* This NetX test concentrates on the basic BSD RAW blocking operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#ifdef NX_BSD_ENABLE +#include "nxd_bsd.h" +#include "nx_icmpv6.h" +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif /* FEATURE_NX_IPV6 */ +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +extern UINT _nxd_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, NXD_ADDRESS *destination_ip, ULONG protocol, UINT ttl, ULONG tos); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_basic_rx_nohdr_blocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable raw processing for both IP instances. */ + status += nx_ip_raw_packet_enable(&ip_0); + status += nx_ip_raw_packet_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check RAW enable and BSD init status. */ + if (status) + error_counter++; +} + +static void test_raw_server_ipv4(void) +{ +int sockfd; +struct sockaddr_in remote_addr; +int ret; +char buf[30]; +int addrlen; +int option; + + sockfd = socket(AF_INET, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Set the RX_NO_HDR option. */ + option = 1; + + ret = setsockopt(sockfd, IPPROTO_IP, IP_RAW_RX_NO_HEADER, (void*)&option, sizeof(option)); + + if(ret != 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + + if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5)))) + error_counter++; + + /* Validate the data. */ + if((ret != (int)(strlen(requests[0]))) || strncmp((buf ), requests[0], (ret))) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (int)strlen(response[0])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + + /* Give the reciever a chance to receive the raw data. */ + tx_thread_sleep(2); + +} + +#ifdef FEATURE_NX_IPV6 +static void test_raw_server_ipv6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr; +int ret; +char buf[50]; +int addrlen; +int option; + + sockfd = socket(AF_INET6, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Set the RX_NO_HDR option. */ + option = 1; + + ret = setsockopt(sockfd, IPPROTO_IP, IP_RAW_RX_NO_HEADER, (void*)&option, sizeof(option)); + + if(ret != 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in6)) + error_counter++; + + if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + + /* Validate the data. */ + if((ret != (INT)(strlen(requests[0]))) || strncmp((buf), requests[0], ret)) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (INT)strlen(response[0])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + /* Give the reciever a chance to receive the raw data. */ + tx_thread_sleep(2); + +} + +#endif + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +UINT status; +char mac_ip0[6]; +char mac_ip1[6]; +#endif + printf("NetX Test: Basic BSD Raw Rx NoHdr Blocking Test.........."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + test_raw_server_ipv4(); + + /* Now open another socket and attempt to connect to the correct remote + host but an unexpected port so we expect an unsuccessful connections. */ +#if 0 + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; +#endif + + /* Allow the stateless autoaddress configuration/DAD to finish */ + tx_thread_sleep(3); + +#ifdef FEATURE_NX_IPV6 + test_raw_server_ipv6(); +#endif + + validate_bsd_structure(); + tx_thread_sleep(2); + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +NXD_ADDRESS dest_addr; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Send a RAW packet */ + dest_addr.nxd_ip_version = NX_IP_VERSION_V4; + dest_addr.nxd_ip_address.v4 = IP_ADDRESS(1,2,3,4); + status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &dest_addr, 100, 128, 0); + if(status) + error_counter++; + + error_counter++; + tx_thread_sleep(1); + /* Ready to reaceive a message */ + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0]))) + error_counter++; + else + error_counter--; + +#ifdef FEATURE_NX_IPV6 + /* Test IPv6 */ + tx_thread_sleep(5); + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &ipv6_address_ip0, 100, 128, 0); + if(status) + error_counter++; + + error_counter++; + tx_thread_sleep(1); + /* Ready to reaceive a message */ + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0]))) + error_counter++; + else + error_counter--; + +#endif +} + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } + +} + +#endif /* NX_BSD_ENABLE */ + +#else /* __PRODUCT_NETXDUO__ */ + +extern void test_control_return(UINT status); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_basic_rx_nohdr_blocking_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Basic BSD Raw Rx NoHdr Blocking Test..........N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/bsd_test/netx_bsd_raw_basic_rx_nohdr_nonblocking_test.c b/test/regression/bsd_test/netx_bsd_raw_basic_rx_nohdr_nonblocking_test.c new file mode 100644 index 00000000..445a5df4 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_raw_basic_rx_nohdr_nonblocking_test.c @@ -0,0 +1,542 @@ +/* This NetX test concentrates on the basic BSD RAW non-blocking operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#ifdef NX_BSD_ENABLE +#include "nxd_bsd.h" +#include "nx_icmpv6.h" +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif /* FEATURE_NX_IPV6 */ +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ +extern UINT _nxd_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, NXD_ADDRESS *destination_ip, ULONG protocol, UINT ttl, ULONG tos); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_basic_rx_nohdr_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable raw processing for both IP instances. */ + status = nx_ip_raw_packet_enable(&ip_0); + status = nx_ip_raw_packet_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check RAW enable and BSD init status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + if(status != TX_SUCCESS) + error_counter++; +} + +static void test_raw_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr; +int ret; +char buf[30]; +fd_set read_fd; +struct timeval tv; +int addrlen; +int option; +int error, len; + + sockfd = socket(AF_INET, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Set the RX_NO_HDR option. */ + option = 1; + + ret = setsockopt(sockfd, IPPROTO_IP, IP_RAW_RX_NO_HEADER, (void*)&option, sizeof(option)); + + if(ret != 0) + error_counter++; + /* Set the socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret > 0) + error_counter++; + else + { + /* Check errno */ + if(errno != EWOULDBLOCK) + error_counter++; + } + + /* Select on the socket. */ + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + tv.tv_sec = 2; + tv.tv_usec = 0; + + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + if(ret != 1) + error_counter++; + + if(!FD_ISSET(sockfd, &read_fd)) + error_counter++; + + /* Set the len. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret < 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + + if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5)))) + error_counter++; + + /* Validate the data. */ + if((ret != (int)strlen(requests[0])) || strncmp((buf ), requests[0], (ret))) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (int)strlen(response[0])) + error_counter++; + + + /* Close down the socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; +} + +#ifdef FEATURE_NX_IPV6 +static void test_raw_server_ipv6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr; +int ret; +char buf[50]; +int addrlen; +fd_set read_fd; +struct timeval tv; +int option; +int error, len; + + sockfd = socket(AF_INET6, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Set the socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + + /* Set the RX_NO_HDR option. */ + option = 1; + + ret = setsockopt(sockfd, IPPROTO_IP, IP_RAW_RX_NO_HEADER, (void*)&option, sizeof(option)); + + if(ret != 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret > 0) + error_counter++; + else + { + /* Check errno */ + if(errno != EWOULDBLOCK) + error_counter++; + } + + /* Select on the socket. */ + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + tv.tv_sec = 2; + tv.tv_usec = 0; + + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + if(ret != 1) + error_counter++; + + if(!FD_ISSET(sockfd, &read_fd)) + error_counter++; + + /* Set the len. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in6)) + error_counter++; + + if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + + /* Validate the data. */ + if((ret != (INT)(strlen(requests[0]))) || strncmp(buf, requests[0], ret)) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (INT)strlen(response[0])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; +} + +#endif + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +char mac_ip0[6]; +char mac_ip1[6]; +UINT status; +#endif + + printf("NetX Test: Basic BSD RAW RX NoHdr Non-Blocking Test......"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + tx_semaphore_put(&sema_1); + + test_raw_server4(); + +#ifdef FEATURE_NX_IPV6 + tx_semaphore_put(&sema_1); + test_raw_server_ipv6(); +#endif + + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +NXD_ADDRESS dest_addr; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Send a RAW packet */ + dest_addr.nxd_ip_version = NX_IP_VERSION_V4; + dest_addr.nxd_ip_address.v4 = IP_ADDRESS(1,2,3,4); + status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &dest_addr, 100, 128, 0); + if(status) + error_counter++; + + /* Ready to reaceive a message */ + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, (char*)response[0], strlen(response[0]))) + error_counter++; + else + error_counter--; + +#ifdef FEATURE_NX_IPV6 + /* Test IPv6 */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &ipv6_address_ip0, 100, 128, 0); + if(status) + error_counter++; + + error_counter++; + + /* Ready to reaceive a message */ + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char *)packet_ptr -> nx_packet_prepend_ptr, (char *)response[0], strlen(response[0]))) + error_counter++; + else + error_counter--; + +#endif + tx_semaphore_put(&sema_0); + +} + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#endif /* NX_BSD_ENABLE */ + +#else /* __PRODUCT_NETXDUO__ */ + +extern void test_control_return(UINT status); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_basic_rx_nohdr_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Basic BSD RAW RX NoHdr Non-Blocking Test......N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/bsd_test/netx_bsd_raw_bind_connect_test.c b/test/regression/bsd_test/netx_bsd_raw_bind_connect_test.c new file mode 100644 index 00000000..38ecb829 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_raw_bind_connect_test.c @@ -0,0 +1,533 @@ +/* This NetX test concentrates on the basic BSD RAW non-blocking bind to a specific address and connect + send operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#ifdef NX_BSD_ENABLE +#ifdef __PRODUCT_NETX__ +#include "nx_bsd.h" +#else +#include "nxd_bsd.h" +#endif + +#ifdef FEATURE_NX_IPV6 +#include "nx_ipv6.h" +#endif +#include "nx_ipv4.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +static TX_SEMAPHORE sema; +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0[3][3]; +static NXD_ADDRESS ipv6_address_ip1[3][3]; +static char *bsd6_msg[3][3] = {{"BSD6_MSG IF0 LLA", "BSD6_MSG IF0 GA0", "MSD6_MSG IF0 GA1"}, + {"BSD6_MSG IF1 LLA", "BSD6_MSG IF1 GA0", "MSD6_MSG IF1 GA1"}, + {"BSD6_MSG IF2 LLA", "BSD6_MSG IF2 GA0", "MSD6_MSG IF2 GA1"}}; +#endif /* FEATURE_NX_IPV6 */ +static char *bsd4_msg[3] = {"BSD4_MSG 0", "BSD4_MSG 1", "MSD4_MSG 2"}; + +static void validate_bsd_structure(void); + +#define IP0_IF0_V4_ADDR IP_ADDRESS(1,2,3,4) +#define IP0_IF1_V4_ADDR IP_ADDRESS(2,2,3,4) +#define IP0_IF2_V4_ADDR IP_ADDRESS(3,2,3,4) + +#define IP1_IF0_V4_ADDR IP_ADDRESS(1,2,3,5) +#define IP1_IF1_V4_ADDR IP_ADDRESS(2,2,3,5) +#define IP1_IF2_V4_ADDR IP_ADDRESS(3,2,3,5) + +#define ITERATIONS 100 +static ULONG ip0_address[3] = {IP0_IF0_V4_ADDR, IP0_IF1_V4_ADDR, IP0_IF2_V4_ADDR}; +static ULONG ip1_address[3] = {IP1_IF0_V4_ADDR, IP1_IF1_V4_ADDR, IP1_IF2_V4_ADDR}; +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_bind_connect_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP0_IF0_V4_ADDR, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Attach a 2nd interface */ + status += nx_ip_interface_attach(&ip_0, "ip_0_second", IP0_IF1_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_0, "ip_0_third", IP0_IF2_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP1_IF0_V4_ADDR, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_1, "ip_1_second", IP1_IF1_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1, "ip_1_third", IP1_IF2_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable RAW processing for both IP instances. */ + status = nx_ip_raw_packet_enable(&ip_0); + status += nx_ip_raw_packet_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check RAW enable and BSD init status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema, "test done", 0); + if (status) + error_counter++; +} + + + + +#ifdef FEATURE_NX_IPV6 +static void test_raw6_on_interface_address(int iface, int address) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int ret; + + + sockfd = socket(AF_INET6, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_port = htons(100); + local_addr.sin6_family = AF_INET6; + if(iface != 3) + { + local_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[0]); + local_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[1]); + local_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[2]); + local_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[3]); + } + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + remote_addr.sin6_family = AF_INET6; + remote_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip1[iface][address].nxd_ip_address.v6[0]); + remote_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip1[iface][address].nxd_ip_address.v6[1]); + remote_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip1[iface][address].nxd_ip_address.v6[2]); + remote_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip1[iface][address].nxd_ip_address.v6[3]); + + remote_addr.sin6_port = htons(100); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + + ret = send(sockfd, bsd6_msg[iface][address], strlen(bsd6_msg[iface][address]), 0); + if(ret != (INT)strlen(bsd6_msg[iface][address])) + error_counter++; + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + + +#endif /* FEATURE_NX_IPV6 */ + +static void test_raw4_on_interface(int i) +{ + +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int ret; + + + sockfd = socket(AF_INET, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(100); + local_addr.sin_addr.s_addr = htonl(ip0_address[i]); + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(100); + remote_addr.sin_addr.s_addr = htonl(ip1_address[i]); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + ret = send(sockfd, bsd4_msg[i], strlen(bsd4_msg[i]), 0); + if(ret != (int)strlen(bsd4_msg[i])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +static char mac_ip0[6]; +static char mac_ip1[6]; +int j; +int addr_index; +UINT status; +int i; +#endif +int iface; + + + printf("NetX Test: Basic BSD RAW Bind Connect Send Test.........."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + + for(i = 0; i < 3; i++) + { + mac_ip0[0] = (char)(ip_0.nx_ip_interface[i].nx_interface_physical_address_msw >> 8); + mac_ip0[1] = ip_0.nx_ip_interface[i].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = (char)(ip_1.nx_ip_interface[i].nx_interface_physical_address_msw >> 8); + mac_ip1[1] = ip_1.nx_ip_interface[i].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw & 0xff; + + for(j = 0; j < 3; j ++) + { + if(j == 0) + { + /* First set up IPv6 linklocal addresses. */ + ipv6_address_ip0[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0[i][j].nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0[i][j].nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0[i][j].nxd_ip_address.v6[2] = ((mac_ip0[0] | 0x2) << 24) | (mac_ip0[1] << 16) | (mac_ip0[2] << 8) | 0xFF; + ipv6_address_ip0[i][j].nxd_ip_address.v6[3] = (0xFE << 24) | ((mac_ip0[3] | 0x2) << 16) | (mac_ip0[4] << 8) | mac_ip0[5]; + + ipv6_address_ip1[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1[i][j].nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1[i][j].nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1[i][j].nxd_ip_address.v6[2] = + ((mac_ip1[0] | 0x2) << 24) | (mac_ip1[1] << 16) | (mac_ip1[2] << 8) | 0xFF; + ipv6_address_ip1[i][j].nxd_ip_address.v6[3] = + (0xFE << 24) | ((mac_ip1[3] | 0x2) << 16) | (mac_ip1[4] << 8) | mac_ip1[5]; + + status = nxd_ipv6_address_set(&ip_0, i, &ipv6_address_ip0[i][j], 10, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, i, &ipv6_address_ip1[i][j], 10, NX_NULL); + } + else + { + /* Global Adddress */ + ipv6_address_ip0[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0[i][j].nxd_ip_address.v6[0] = 0x20000000 + i; + ipv6_address_ip0[i][j].nxd_ip_address.v6[1] = j; + ipv6_address_ip0[i][j].nxd_ip_address.v6[2] = ipv6_address_ip0[i][0].nxd_ip_address.v6[2]; + ipv6_address_ip0[i][j].nxd_ip_address.v6[3] = ipv6_address_ip0[i][0].nxd_ip_address.v6[3]; + + ipv6_address_ip1[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1[i][j].nxd_ip_address.v6[0] = 0x20000000 + i; + ipv6_address_ip1[i][j].nxd_ip_address.v6[1] = j; + ipv6_address_ip1[i][j].nxd_ip_address.v6[2] = ipv6_address_ip1[i][0].nxd_ip_address.v6[2]; + ipv6_address_ip1[i][j].nxd_ip_address.v6[3] = ipv6_address_ip1[i][0].nxd_ip_address.v6[3]; + + + status = nxd_ipv6_address_set(&ip_0, i, &ipv6_address_ip0[i][j], 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, i, &ipv6_address_ip1[i][j], 64, NX_NULL); + } + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1[i][j].nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0[i][j].nxd_ip_address.v6, 0, mac_ip0); + } + + } + + + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + + + if(status) + error_counter++; +#endif + + /* Wait for the semaphore to signal the other party is ready. */ + tx_semaphore_get(&sema, 2 * NX_IP_PERIODIC_RATE); + + for(iface = 0; iface < 3; iface++) + { + test_raw4_on_interface(iface); + + tx_semaphore_get(&sema, 2 * NX_IP_PERIODIC_RATE); + +#ifdef FEATURE_NX_IPV6 + for(addr_index = 1; addr_index < 3; addr_index++) + { + + test_raw6_on_interface_address(iface, addr_index); + + tx_semaphore_get(&sema, 2 * NX_IP_PERIODIC_RATE); + } + +#endif + } + + + tx_semaphore_delete(&sema); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ +ULONG actual_status; +UINT status; +UINT iface; +NX_PACKET *packet_ptr; +NX_IPV4_HEADER *ipv4_header; +#ifdef FEATURE_NX_IPV6 +NX_IPV6_HEADER *ipv6_header; +UINT addr_index; +#endif + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + tx_semaphore_put(&sema); + + + for(iface = 0; iface < 3; iface++) + { + + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + error_counter++; + continue; + } + + ipv4_header = (NX_IPV4_HEADER*)packet_ptr -> nx_packet_ip_header; + if(ipv4_header -> nx_ip_header_source_ip != ip0_address[iface]) + error_counter++; + if((ipv4_header -> nx_ip_header_word_2 & 0x00FF0000) != (100 << 16)) + error_counter++; + if(ipv4_header -> nx_ip_header_destination_ip != ip1_address[iface]) + error_counter++; + if((packet_ptr -> nx_packet_length != strlen(bsd4_msg[iface])) || + (memcmp(packet_ptr -> nx_packet_prepend_ptr, bsd4_msg[iface], packet_ptr -> nx_packet_length))) + error_counter++; + + nx_packet_release(packet_ptr); + + tx_semaphore_put(&sema); + +#ifdef FEATURE_NX_IPV6 + for(addr_index = 1; addr_index < 3; addr_index++) + { + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, 1 * NX_IP_PERIODIC_RATE); + + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + ipv6_header = (NX_IPV6_HEADER*)packet_ptr -> nx_packet_ip_header; + + if((ipv6_header -> nx_ip_header_source_ip[0] != ipv6_address_ip0[iface][addr_index].nxd_ip_address.v6[0]) || + (ipv6_header -> nx_ip_header_source_ip[1] != ipv6_address_ip0[iface][addr_index].nxd_ip_address.v6[1]) || + (ipv6_header -> nx_ip_header_source_ip[2] != ipv6_address_ip0[iface][addr_index].nxd_ip_address.v6[2]) || + (ipv6_header -> nx_ip_header_source_ip[3] != ipv6_address_ip0[iface][addr_index].nxd_ip_address.v6[3])) + error_counter++; + if((ipv6_header -> nx_ip_header_destination_ip[0] != ipv6_address_ip1[iface][addr_index].nxd_ip_address.v6[0]) || + (ipv6_header -> nx_ip_header_destination_ip[1] != ipv6_address_ip1[iface][addr_index].nxd_ip_address.v6[1]) || + (ipv6_header -> nx_ip_header_destination_ip[2] != ipv6_address_ip1[iface][addr_index].nxd_ip_address.v6[2]) || + (ipv6_header -> nx_ip_header_destination_ip[3] != ipv6_address_ip1[iface][addr_index].nxd_ip_address.v6[3])) + error_counter++; + if((ipv6_header -> nx_ip_header_word_1 & 0x0000FF00) != (100 << 8)) + error_counter++; + + if((packet_ptr -> nx_packet_length != strlen(bsd6_msg[iface][addr_index])) || + (memcmp(packet_ptr -> nx_packet_prepend_ptr, bsd6_msg[iface][addr_index], packet_ptr -> nx_packet_length))) + error_counter++; + + nx_packet_release(packet_ptr); + + tx_semaphore_put(&sema); + } +#endif + } +} + +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#endif /* NX_BSD_ENABLE */ + +#else /* __PRODUCT_NETXDUO__ */ + +extern void test_control_return(UINT status); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_bind_connect_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Basic BSD RAW Bind Connect Send Test..........N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/bsd_test/netx_bsd_raw_ping_test.c b/test/regression/bsd_test/netx_bsd_raw_ping_test.c new file mode 100644 index 00000000..08493b7c --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_raw_ping_test.c @@ -0,0 +1,276 @@ +/* This NetX test concentrates on the basic BSD RAW Ping. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) && defined(NX_ENABLE_IP_RAW_PACKET_ALL_STACK) +#ifdef NX_BSD_ENABLE +#include "nxd_bsd.h" +#include "nx_icmpv6.h" +#define DEMO_STACK_SIZE 8192 +#define LOOP 100 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif /* FEATURE_NX_IPV6 */ +/* Echo request from 172.31.144.1 to 172.31.159.102. */ +static char echo_request[] = +"\x08\x00\x4d\x50\x00\x01\x00\x0b\x61\x62\x63\x64\x65\x66\x67\x68" \ +"\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x61" \ +"\x62\x63\x64\x65\x66\x67\x68\x69"; +/* Echo reply from 172.31.159.102 to 172.31.144.1. */ +static char echo_reply[] = +"\x00\x00\x55\x50\x00\x01\x00\x0b\x61\x62\x63\x64\x65\x66\x67\x68" \ +"\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x61" \ +"\x62\x63\x64\x65\x66\x67\x68\x69"; +static char receive_buffer[100]; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_ping_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * 32); + pointer = pointer + (256 + sizeof(NX_PACKET)) * 32; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(172, 31, 144, 1), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(172, 31, 159, 102), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status += nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Enable raw processing for both IP instances. */ + status += nx_ip_raw_packet_enable(&ip_0); + status += nx_ip_raw_packet_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check RAW enable and BSD init status. */ + if (status) + error_counter++; +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +int sockfd; +struct sockaddr_in remote_addr; +int ret; +int addrlen; +int option; +UINT i; +UINT original_threshold; + + printf("NetX Test: Basic BSD Raw Ping Test......................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + for (i = 0 ; (i < LOOP) && (error_counter == 0); i++) + { + sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + if(sockfd < 0) + error_counter++; + + option = 1; + ret = setsockopt(sockfd, IPPROTO_IP, IP_RAW_RX_NO_HEADER, (void*)&option, sizeof(option)); + if(ret != 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = 0; + remote_addr.sin_addr.s_addr = htonl(IP_ADDRESS(172, 31, 159, 102)); + + if (i == (LOOP >> 1)) + { + + /* Temporarily disable preemption. */ + tx_thread_preemption_change(tx_thread_identify(), 0, &original_threshold); + } + + /* Send echo request. */ + ret = sendto(sockfd, echo_request, sizeof(echo_request) - 1, 0, (struct sockaddr*)&remote_addr, + sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + if (i == (LOOP >> 1)) + { + + /* Special case: close socket before packet is received. */ + /* Close down the socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + /* Restore original preemption threshold. */ + tx_thread_preemption_change(tx_thread_identify(), original_threshold, &original_threshold); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + continue; + } + + /* Receive echo reply. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, receive_buffer, sizeof(receive_buffer), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(172, 31, 159, 102)))) + error_counter++; + + if ((ret != (sizeof(echo_reply) - 1)) || (memcmp(receive_buffer, echo_reply, ret))) + error_counter++; + + /* Close down the socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + validate_bsd_structure(); + tx_thread_sleep(2); + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } + +} + +#endif /* NX_BSD_ENABLE */ + +#else /* __PRODUCT_NETXDUO__ */ + +extern void test_control_return(UINT status); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_ping_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Basic BSD Raw Ping Test.......................N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/bsd_test/netx_bsd_raw_pppoe_test.c b/test/regression/bsd_test/netx_bsd_raw_pppoe_test.c new file mode 100644 index 00000000..c31905ec --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_raw_pppoe_test.c @@ -0,0 +1,560 @@ +/* This NetX test concentrates on the BSD RAW Packet blocking operation for PPPoE traffic. */ +/* This test case covers the following scenarios: + Be able to create socket_1 of PPPOE_SESS for receiving SESS traffice, + socket_2 for receiving PPPOE_DISC traffic + socket_3 for sending either PPPOE_DISC or PPPOE_SESS traffic. +*/ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined (__PRODUCT_NETXDUO__) && defined (NX_BSD_RAW_PPPOE_SUPPORT) && !defined(NX_DISABLE_IPV4) +#ifdef NX_BSD_ENABLE +#include "nxd_bsd.h" +#include "nx_icmpv6.h" +#define DEMO_STACK_SIZE 8192 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static TX_SEMAPHORE ntest1_sem; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); + +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char response[4][32] = {" Response1", " Response2", " Response3", " Response4"}; + +static char rcvBuffer[50]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_pppoe_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2,2,3,4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + + if (status) + error_counter++; + + + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable raw processing for both IP instances. */ + status += nx_ip_raw_packet_enable(&ip_0); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check RAW enable and BSD init status. */ + if (status) + error_counter++; + + tx_semaphore_create(&ntest1_sem, "ntest0 semaphore", 0); +} + + +static char mac_ip0_if0[6]; +static char mac_ip0_if1[6]; + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +struct sockaddr_ll sock_addr_if0; +struct sockaddr_ll sock_addr_if1; +int recv_bytes; +int i, n; +int fromAddr_len; +struct sockaddr_ll fromAddr; +int sock_sess0; +int sock_sess1; +int sock_disc0; +int sock_disc1; +int ioctl_arg; +USHORT type; + + + + printf("NetX Test: Basic BSD PPPoE SESS Blocking Test............"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + mac_ip0_if0[0] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8) & 0xFF; + mac_ip0_if0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0_if0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0_if0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0_if0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0_if0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip0_if1[0] = (ip_0.nx_ip_interface[1].nx_interface_physical_address_msw >> 8) & 0xFF; + mac_ip0_if1[1] = ip_0.nx_ip_interface[1].nx_interface_physical_address_msw & 0xFF; + mac_ip0_if1[2] = (ip_0.nx_ip_interface[1].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0_if1[3] = (ip_0.nx_ip_interface[1].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0_if1[4] = (ip_0.nx_ip_interface[1].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0_if1[5] = ip_0.nx_ip_interface[1].nx_interface_physical_address_lsw & 0xff; + + + /* Creaet sock_sess0 and sock_sess1 for PPPOE_SESS */ + sock_sess0 = socket(AF_PACKET, SOCK_RAW, ETHERTYPE_PPPOE_SESS); + sock_sess1 = socket(AF_PACKET, SOCK_RAW, ETHERTYPE_PPPOE_SESS); + /* Creaet sock_disc0 and sock_disc1 for PPPOE_SESS */ + sock_disc0 = socket(AF_PACKET, SOCK_RAW, ETHERTYPE_PPPOE_DISC); + sock_disc1 = socket(AF_PACKET, SOCK_RAW, ETHERTYPE_PPPOE_DISC); + + /* Validate the sockets. */ + if((sock_sess0 == 0) || (sock_sess1 == 0) || (sock_disc0 == 0) || (sock_disc1 == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* First test that the receiver is able to block on receiving a DISC or a SESS message. */ + sock_addr_if0.sll_family = AF_PACKET; + sock_addr_if0.sll_protocol = ETHERTYPE_PPPOE_SESS; + sock_addr_if0.sll_ifindex = 0; + + tx_semaphore_put(&ntest1_sem); + /* Expect ntest_1 to send one DISC to if0, one DISC to if1, one SESS to if0, one SESS to if1 */ + /* ntest_0 only receives data on recv_sess0 and recv_disc0 */ + + fromAddr_len = sizeof(fromAddr); + recv_bytes = recvfrom(sock_sess0, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes != (strlen("Request1") + 1 + 14)) + error_counter++; + type = (rcvBuffer[12] << 8) | rcvBuffer[13]; + if(type != ETHERTYPE_PPPOE_SESS) + error_counter++; + + if(strcmp(&rcvBuffer[14], "Request1")) + error_counter++; + + if(fromAddr_len != sizeof(struct sockaddr_ll)) + error_counter++; + + if((fromAddr.sll_family != AF_PACKET) || (fromAddr.sll_ifindex != 1)) + error_counter++; + + + + recv_bytes = recvfrom(sock_sess0, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes != (strlen("Request2") + 1 + 14)) + error_counter++; + type = (rcvBuffer[12] << 8) | rcvBuffer[13]; + if(type != ETHERTYPE_PPPOE_SESS) + error_counter++; + + if(strcmp(&rcvBuffer[14], "Request2")) + error_counter++; + + if(fromAddr_len != sizeof(struct sockaddr_ll)) + error_counter++; + + if((fromAddr.sll_family != AF_PACKET) || (fromAddr.sll_ifindex != 0)) + error_counter++; + + recv_bytes = recvfrom(sock_disc0, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes != (strlen("Request3") + 1 + 14)) + error_counter++; + type = (rcvBuffer[12] << 8) | rcvBuffer[13]; + if(type != ETHERTYPE_PPPOE_DISC) + error_counter++; + + if(strcmp(&rcvBuffer[14], "Request3")) + error_counter++; + + if(fromAddr_len != sizeof(struct sockaddr_ll)) + error_counter++; + + if((fromAddr.sll_family != AF_PACKET) || (fromAddr.sll_ifindex != 1)) + error_counter++; + + recv_bytes = recvfrom(sock_disc0, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes != (strlen("Request4") + 1 + 14)) + error_counter++; + type = (rcvBuffer[12] << 8) | rcvBuffer[13]; + if(type != ETHERTYPE_PPPOE_DISC) + error_counter++; + + if(strcmp(&rcvBuffer[14], "Request4")) + error_counter++; + + if(fromAddr_len != sizeof(struct sockaddr_ll)) + error_counter++; + + if((fromAddr.sll_family != AF_PACKET) || (fromAddr.sll_ifindex != 0)) + error_counter++; + + /* ntest_0 sends out SESS messages through sock_sess0 (if0) and sock_sess1 (if1). Verify that + ntest_0 is able to receive both messages on sock_sess0. */ + sock_addr_if0.sll_family = AF_PACKET; + sock_addr_if0.sll_ifindex = 0; + + /* Set up response[0] to be SESS packet, send through interface 0 */ + for(i = 0; i < 6; i++) + { + response[0][i] = mac_ip0_if1[i]; + response[0][i + 6] = mac_ip0_if0[i]; + } + response[0][12] = (ETHERTYPE_PPPOE_SESS >> 8); + response[0][13] = ETHERTYPE_PPPOE_SESS & 0xFF; + + n = sendto(sock_sess0, response[0], sizeof(response[0]), 0, (struct sockaddr*)&sock_addr_if0, sizeof(sock_addr_if0)); + if(n != sizeof(response[0])) + error_counter++; + + /* Set up response[1] to be SESS packet, send through interface 1 */ + for(i = 0; i < 6; i++) + { + response[1][i] = mac_ip0_if0[i]; + response[1][i + 6] = mac_ip0_if1[i]; + } + response[1][12] = (ETHERTYPE_PPPOE_SESS >> 8); + response[1][13] = ETHERTYPE_PPPOE_SESS & 0xFF; + + sock_addr_if1.sll_family = AF_PACKET; + sock_addr_if1.sll_protocol = ETHERTYPE_PPPOE_SESS; + sock_addr_if1.sll_ifindex = 1; + + n = sendto(sock_sess0, response[1], sizeof(response[1]), 0, (struct sockaddr*)&sock_addr_if1, sizeof(sock_addr_if1)); + if(n != sizeof(response[1])) + error_counter++; + + recv_bytes = recvfrom(sock_sess0, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes != sizeof(response[0])) + error_counter++; + type = (rcvBuffer[12] << 8) | rcvBuffer[13]; + if(type != ETHERTYPE_PPPOE_SESS) + error_counter++; + + if(strcmp(&rcvBuffer[14], "Response1")) + error_counter++; + + if(fromAddr_len != sizeof(struct sockaddr_ll)) + error_counter++; + + if((fromAddr.sll_family != AF_PACKET) || (fromAddr.sll_ifindex != 1)) + error_counter++; + + recv_bytes = recvfrom(sock_sess0, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes != sizeof(response[1])) + error_counter++; + type = (rcvBuffer[12] << 8) | rcvBuffer[13]; + if(type != ETHERTYPE_PPPOE_SESS) + error_counter++; + + if(strcmp(&rcvBuffer[14], "Response2")) + error_counter++; + + if(fromAddr_len != sizeof(struct sockaddr_ll)) + error_counter++; + + if((fromAddr.sll_family != AF_PACKET) || (fromAddr.sll_ifindex != 0)) + error_counter++; + + /* Set up response[2] to be DISC packet, send through interface 0 */ + for(i = 0; i < 6; i++) + { + response[2][i] = mac_ip0_if1[i]; + response[2][i + 6] = mac_ip0_if0[i]; + } + response[2][12] = (ETHERTYPE_PPPOE_DISC >> 8); + response[2][13] = ETHERTYPE_PPPOE_DISC & 0xFF; + + sock_addr_if0.sll_protocol = ETHERTYPE_PPPOE_DISC; + + n = sendto(sock_sess0, response[2], sizeof(response[2]), 0, (struct sockaddr*)&sock_addr_if0, sizeof(sock_addr_if0)); + if(n != sizeof(response[0])) + error_counter++; + + sock_addr_if0.sll_family = AF_PACKET; + sock_addr_if0.sll_ifindex = 1; + + /* Set up response[3] to be DISC packet, send through interface 1 */ + for(i = 0; i < 6; i++) + { + response[3][i] = mac_ip0_if0[i]; + response[3][i + 6] = mac_ip0_if1[i]; + } + response[3][12] = (ETHERTYPE_PPPOE_DISC >> 8); + response[3][13] = ETHERTYPE_PPPOE_DISC & 0xFF; + + sock_addr_if1.sll_protocol = ETHERTYPE_PPPOE_DISC; + + n = sendto(sock_sess0, response[3], sizeof(response[3]), 0, (struct sockaddr*)&sock_addr_if1, sizeof(sock_addr_if1)); + if(n != sizeof(response[3])) + error_counter++; + + recv_bytes = recvfrom(sock_disc0, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes != sizeof(response[2])) + error_counter++; + type = (rcvBuffer[12] << 8) | rcvBuffer[13]; + if(type != ETHERTYPE_PPPOE_DISC) + error_counter++; + + if(strcmp(&rcvBuffer[14], "Response3")) + error_counter++; + + if(fromAddr_len != sizeof(struct sockaddr_ll)) + error_counter++; + + if((fromAddr.sll_family != AF_PACKET) || (fromAddr.sll_ifindex != 1)) + error_counter++; + + recv_bytes = recvfrom(sock_disc0, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes != sizeof(response[3])) + error_counter++; + type = (rcvBuffer[12] << 8) | rcvBuffer[13]; + if(type != ETHERTYPE_PPPOE_DISC) + error_counter++; + + if(strcmp(&rcvBuffer[14], "Response4")) + error_counter++; + + if(fromAddr_len != sizeof(struct sockaddr_ll)) + error_counter++; + + if((fromAddr.sll_family != AF_PACKET) || (fromAddr.sll_ifindex != 0)) + error_counter++; + + + /* Set all sockets to be non-blocking */ + ioctl_arg = NX_TRUE; + if(ioctl(sock_sess0, FIONBIO, &ioctl_arg)) + error_counter++; + + if(ioctl(sock_sess1, FIONBIO, &ioctl_arg)) + error_counter++; + + if(ioctl(sock_disc0, FIONBIO, &ioctl_arg)) + error_counter++; + + if(ioctl(sock_disc1, FIONBIO, &ioctl_arg)) + error_counter++; + + /* Now try to receive from all these sockets and none of them should have any data available for read. */ + recv_bytes = recvfrom(sock_sess0, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes > 0) + error_counter++; + recv_bytes = recvfrom(sock_sess1, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes > 0) + error_counter++; + recv_bytes = recvfrom(sock_disc0, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes > 0) + error_counter++; + recv_bytes = recvfrom(sock_disc1, rcvBuffer, sizeof(rcvBuffer), 0, (struct sockaddr*)&fromAddr, &fromAddr_len); + if(recv_bytes > 0) + error_counter++; + + soc_close(sock_sess0); + soc_close(sock_sess1); + soc_close(sock_disc0); + soc_close(sock_disc1); + + validate_bsd_structure(); + tx_thread_sleep(2); + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { +#ifdef __PRODUCT_NETX__ + if(nx_bsd_socket_array[i].nx_bsd_socket_in_use) +#else + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) +#endif + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } + +} +static void ntest_1_packet_send(int msg_id, int if_id, int type) +{ +UINT status; +int i; +NX_PACKET *packet_ptr; +NX_IP_DRIVER driver_request; + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_NO_WAIT); + if(status) + { + error_counter++; + return; + } + + /* Construct the first message as SESS type, sent through interface 0 */ + for(i = 0; i < 6; i++) + { + if(if_id == 0) + { + packet_ptr -> nx_packet_prepend_ptr[i] = mac_ip0_if1[i]; + packet_ptr -> nx_packet_prepend_ptr[i + 6] = mac_ip0_if0[i]; + } + else + { + packet_ptr -> nx_packet_prepend_ptr[i] = mac_ip0_if0[i]; + packet_ptr -> nx_packet_prepend_ptr[i + 6] = mac_ip0_if1[i]; + } + } + packet_ptr -> nx_packet_prepend_ptr[12] = type >> 8; + packet_ptr -> nx_packet_prepend_ptr[13] = type & 0xFF; + memcpy(&packet_ptr -> nx_packet_prepend_ptr[14], requests[msg_id], (strlen(requests[msg_id]) + 1)); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + strlen(requests[msg_id]) + 14 + 1; + packet_ptr -> nx_packet_length = strlen(requests[msg_id]) + 14 + 1; + + + driver_request.nx_ip_driver_ptr = &ip_0; + driver_request.nx_ip_driver_command = NX_LINK_PACKET_PPPOE_SESS_SEND; + driver_request.nx_ip_driver_packet = packet_ptr; + driver_request.nx_ip_driver_interface = &(ip_0.nx_ip_interface[if_id]); + + (driver_request.nx_ip_driver_interface -> nx_interface_link_driver_entry)(&driver_request); + + return; +} + + +static void ntest_1_entry(ULONG thread_input) +{ + + + tx_semaphore_get(&ntest1_sem, NX_IP_PERIODIC_RATE); + + tx_thread_sleep(5); + + ntest_1_packet_send(0, 0, NX_LINK_PACKET_PPPOE_SESS_SEND); + ntest_1_packet_send(1, 1, NX_LINK_PACKET_PPPOE_SESS_SEND); + ntest_1_packet_send(2, 0, NX_LINK_PACKET_PPPOE_DISC_SEND); + ntest_1_packet_send(3, 1, NX_LINK_PACKET_PPPOE_DISC_SEND); + + +} + + +#endif /* NX_BSD_ENABLE */ + +#else /* __PRODUCT_NETXDUO__ */ + +extern void test_control_return(UINT status); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_pppoe_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Basic BSD Raw PPPOE Test......................N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/bsd_test/netx_bsd_raw_rx_nohdr_basic_blocking_test.c b/test/regression/bsd_test/netx_bsd_raw_rx_nohdr_basic_blocking_test.c new file mode 100644 index 00000000..58c67ca5 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_raw_rx_nohdr_basic_blocking_test.c @@ -0,0 +1,469 @@ +/* This NetX test concentrates on the basic BSD RAW blocking operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#ifdef NX_BSD_ENABLE +#include "nxd_bsd.h" +#include "nx_icmpv6.h" +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif /* FEATURE_NX_IPV6 */ +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +extern UINT _nxd_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, NXD_ADDRESS *destination_ip, ULONG protocol, UINT ttl, ULONG tos); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_rx_nohdr_basic_blocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable raw processing for both IP instances. */ + status += nx_ip_raw_packet_enable(&ip_0); + status += nx_ip_raw_packet_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check RAW enable and BSD init status. */ + if (status) + error_counter++; +} + +static void test_raw_server_ipv4(void) +{ +int sockfd; +struct sockaddr_in remote_addr; +int ret; +char buf[30]; +int addrlen; +int option; +int status; + sockfd = socket(AF_INET, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Set the RX_NO_HDR option. */ + option = 1; + + status = setsockopt(sockfd, IPPROTO_IP, IP_RAW_RX_NO_HEADER, (void*)&option, sizeof(option)); + + if(status != 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + + if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5)))) + error_counter++; + + /* Validate the data. */ + if((ret != (int)strlen(requests[0])) || strncmp(buf, requests[0], ret)) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (int)strlen(response[0])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + + /* Give the reciever a chance to receive the raw data. */ + tx_thread_sleep(2); + +} + +#ifdef FEATURE_NX_IPV6 +static void test_raw_server_ipv6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr; +int ret; +char buf[50]; +int addrlen; +int option; +int status; + sockfd = socket(AF_INET6, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Set the RX_NO_HDR option. */ + option = 1; + + status = setsockopt(sockfd, IPPROTO_IP, IP_RAW_RX_NO_HEADER, (void*)&option, sizeof(option)); + + if(status != 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in6)) + error_counter++; + + if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + + /* Validate the data. */ + if((ret != (INT)(strlen(requests[0]))) || (strncmp(buf, requests[0], ret))) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (INT)strlen(response[0])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + /* Give the reciever a chance to receive the raw data. */ + tx_thread_sleep(2); + +} + +#endif + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +UINT status; +char mac_ip0[6]; +char mac_ip1[6]; +#endif + printf("NetX Test: Basic BSD Raw Rx Nohdr Blocking Test.........."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + test_raw_server_ipv4(); + + /* Now open another socket and attempt to connect to the correct remote + host but an unexpected port so we expect an unsuccessful connections. */ +#if 0 + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; +#endif + + /* Allow the stateless autoaddress configuration/DAD to finish */ + tx_thread_sleep(3); + +#ifdef FEATURE_NX_IPV6 + test_raw_server_ipv6(); +#endif + + validate_bsd_structure(); + tx_thread_sleep(2); + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +NXD_ADDRESS dest_addr; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Send a RAW packet */ + dest_addr.nxd_ip_version = NX_IP_VERSION_V4; + dest_addr.nxd_ip_address.v4 = IP_ADDRESS(1,2,3,4); + status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &dest_addr, 100, 128, 0); + if(status) + error_counter++; + + error_counter++; + tx_thread_sleep(1); + /* Ready to reaceive a message */ + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0]))) + error_counter++; + else + error_counter--; + +#ifdef FEATURE_NX_IPV6 + /* Test IPv6 */ + tx_thread_sleep(5); + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &ipv6_address_ip0, 100, 128, 0); + if(status) + error_counter++; + + error_counter++; + tx_thread_sleep(1); + /* Ready to reaceive a message */ + status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0]))) + error_counter++; + else + error_counter--; + +#endif +} + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } + +} + +#endif /* NX_BSD_ENABLE */ + +#else /* __PRODUCT_NETXDUO__ */ + +extern void test_control_return(UINT status); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_rx_nohdr_basic_blocking_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Basic BSD Raw Rx Nohdr Blocking Test..........N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/bsd_test/netx_bsd_raw_tx_test.c b/test/regression/bsd_test/netx_bsd_raw_tx_test.c new file mode 100644 index 00000000..9e16bd2d --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_raw_tx_test.c @@ -0,0 +1,549 @@ +/* This NetX test concentrates on the basic BSD RAW non-blocking operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#ifdef NX_BSD_ENABLE +#include "nxd_bsd.h" +#include "nx_icmpv6.h" +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* The IPv6 packet assumes + src address fe80::f584:1fdb:425:a239 + dst address ff02::1:ffd6:5775 +*/ +char ipv6_packet[] = { +0x60, 0x00, +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x84, +0x1f, 0xdb, 0x04, 0x25, 0xa2, 0x39, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0xff, 0xd6, 0x57, 0x75, 0x87, 0x00, +0x39, 0xad, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x1a, +0x23, 0x6c, 0xab, 0xd6, 0x57, 0x75, 0x01, 0x01, +0x00, 0x1e, 0x8c, 0xd5, 0xd3, 0x1f }; + + +/* In this test case the source IP address must be +192.168.1.185, dest 157.56.52.38 +Source MAC 18:a9:05:cc:8f:16 +dst MAC 00:24:a5:b5:2c:58 +*/ +static char ipv4_packet[] = { +0x45, 0x00, +0x00, 0x3c, 0x3e, 0xa2, 0x00, 0x00, 0x80, 0x11, +0x68, 0x4f, 0xc0, 0xa8, 0x01, 0xb9, 0x9d, 0x38, +0x34, 0x26, 0x34, 0x4f, 0x9c, 0x64, 0x00, 0x28, +0xdc, 0x3e, 0xa6, 0x3e, 0x02, 0x00, 0x25, 0xbb, +0xa3, 0x96, 0x53, 0x4c, 0x32, 0x2f, 0x5d, 0x8d, +0x26, 0x51, 0x42, 0x0e, 0xf6, 0x5c, 0x6c, 0x96, +0x1c, 0x7d, 0x64, 0x3d, 0xd1, 0x86, 0xe5, 0x62, +0x67, 0x5b }; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif /* FEATURE_NX_IPV6 */ + +static int test_case = 0; +extern void (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void bsd_tx_packet_process_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +char data_buffer[100]; +ULONG ip_id; +ULONG checksum; + switch(test_case) + { + case 0: + if(packet_ptr -> nx_packet_length != sizeof(ipv4_packet)) + error_counter++; + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, + ipv4_packet, sizeof(ipv4_packet))) + error_counter++; + break; + + case 1: + if(packet_ptr -> nx_packet_length != sizeof(ipv4_packet)) + error_counter++; + memcpy(data_buffer, ipv4_packet, sizeof(ipv4_packet)); + ip_id = (packet_ptr -> nx_packet_prepend_ptr[4] << 8); + ip_id = (ip_id | (packet_ptr -> nx_packet_prepend_ptr[5])); + if(ip_id != ip_0.nx_ip_packet_id) + error_counter++; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, + (packet_ptr -> nx_packet_prepend_ptr[0] & 0xF) << 2, + NULL, NULL); + + checksum = ~checksum & NX_LOWER_16_MASK; + if(checksum) + error_counter++; + + data_buffer[4] = (ip_id & 0xFF00) >> 8; + data_buffer[5] = ip_id & 0xFF; + + data_buffer[10] = packet_ptr -> nx_packet_prepend_ptr[10]; + data_buffer[11] = packet_ptr -> nx_packet_prepend_ptr[11]; + + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, + data_buffer, sizeof(ipv4_packet))) + error_counter++; + break; + + case 2: + if(packet_ptr -> nx_packet_length != (sizeof(ipv4_packet) + 20)) + error_counter++; + if(memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, + ipv4_packet, sizeof(ipv4_packet))) + error_counter++; + break; + case 3: + if(packet_ptr -> nx_packet_length != (sizeof(ipv6_packet))) + error_counter++; + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, + ipv6_packet, sizeof(ipv6_packet))) + error_counter++; + break; + + case 4: + if(packet_ptr -> nx_packet_length != (sizeof(ipv6_packet) + 40)) + error_counter++; + if(memcmp(packet_ptr -> nx_packet_prepend_ptr + 40, + ipv6_packet, sizeof(ipv6_packet))) + error_counter++; + break; + + default: + error_counter++; + break; + + } + + nx_packet_release(packet_ptr); +} + +/* Define what the initial system looks like. */ +extern UINT _nxd_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, NXD_ADDRESS *destination_ip, ULONG protocol, UINT ttl, ULONG tos); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_tx_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192, 168, 1, 185), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Set up the gateway address */ + status = nx_ip_gateway_address_set(&ip_0, IP_ADDRESS(192, 168, 1, 1)); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable raw processing for both IP instances. */ + status = nx_ip_raw_packet_enable(&ip_0); + + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check RAW enable and BSD init status. */ + if (status) + error_counter++; +} + + +static char buffer[100]; +static void test_raw_ipv4_sendto(int hdrincl) +{ +int sockfd; +struct sockaddr_in remote_addr; +int ret; + + /* Create a raw socket. */ + sockfd = socket(AF_INET, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Set IP_HDRINCL */ + + ret = setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &hdrincl, sizeof(hdrincl)); + if(ret) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(5); + remote_addr.sin_addr.s_addr = htonl(IP_ADDRESS(1 ,2, 3, 4)); + + memcpy(buffer, ipv4_packet, sizeof(ipv4_packet)); + + if(hdrincl) + test_case = 0; + else + test_case = 2; + + ret = sendto(sockfd, buffer, sizeof(ipv4_packet), 0, (struct sockaddr*)&remote_addr, + sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + /* Test with sendto */ + if(hdrincl == 1) + { + + /* Clear the IP ID field, and make sure the stack is able to fill in the ID value. */ + buffer[4] = 0; + buffer[5] = 0; + + test_case = 1; + } + else + test_case = 2; + ret = sendto(sockfd, buffer, sizeof(ipv4_packet), 0, (struct sockaddr*)&remote_addr, + sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +#ifdef FEATURE_NX_IPV6 +static void test_raw_ipv6_sendto(int hdrincl) +{ +int sockfd; +struct sockaddr_in6 remote_addr; +int ret; + + /* Create a raw socket. */ + sockfd = socket(AF_INET6, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Set IP_HDRINCL */ + + ret = setsockopt(sockfd, IPPROTO_IP, IP_RAW_IPV6_HDRINCL, &hdrincl, sizeof(hdrincl)); + if(ret) + error_counter++; + + remote_addr.sin6_family = AF_INET6; + remote_addr.sin6_port = htons(5); + remote_addr.sin6_addr._S6_un._S6_u32[0] = htonl(0xff020000); + remote_addr.sin6_addr._S6_un._S6_u32[1] = htonl(0); + remote_addr.sin6_addr._S6_un._S6_u32[2] = htonl(0xf5841fdb); + remote_addr.sin6_addr._S6_un._S6_u32[3] = htonl(0x0425a239); + + if(hdrincl) + test_case = 3; + else + test_case = 4; + + ret = sendto(sockfd, ipv6_packet, sizeof(ipv6_packet), 0, (struct sockaddr*)&remote_addr, + sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +static void test_raw_ipv6_send(int hdrincl) +{ +int sockfd; +struct sockaddr_in6 remote_addr; +int ret; + + /* Create a raw socket. */ + sockfd = socket(AF_INET6, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + /* Set IP_HDRINCL */ + + ret = setsockopt(sockfd, IPPROTO_IP, IP_RAW_IPV6_HDRINCL, &hdrincl, sizeof(hdrincl)); + if(ret) + error_counter++; +#if 1 + remote_addr.sin6_family = AF_INET6; + remote_addr.sin6_port = htons(5); + remote_addr.sin6_addr._S6_un._S6_u32[0] = htonl(0xff020000); + remote_addr.sin6_addr._S6_un._S6_u32[1] = htonl(0); + remote_addr.sin6_addr._S6_un._S6_u32[2] = htonl(0xf5841fdb); + remote_addr.sin6_addr._S6_un._S6_u32[3] = htonl(0x0425a239); +#endif + if(hdrincl) + test_case = 3; + else + test_case = 4; + + ret = sendto(sockfd, ipv6_packet, sizeof(ipv6_packet), 0, (struct sockaddr*)&remote_addr, + sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} +#endif /* FEATURE_NX_IPV6 */ + +static void test_raw_ipv4_send(int hdrincl) +{ +int sockfd; +struct sockaddr_in remote_addr; +int ret; + + /* Create a raw socket. */ + sockfd = socket(AF_INET, SOCK_RAW, 100); + if(sockfd < 0) + error_counter++; + + ret = setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &hdrincl, sizeof(hdrincl)); + if(ret) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(5); + remote_addr.sin_addr.s_addr = htonl(IP_ADDRESS(1 ,2, 3, 4)); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + /* Clear the IP ID field, and make sure the stack is able to fill in the ID value. */ + memcpy(buffer, ipv4_packet, sizeof(ipv4_packet)); + if(hdrincl) + test_case = 0; + else + test_case = 2; + ret = send(sockfd, buffer, sizeof(ipv4_packet), 0); + if(ret < 0) + error_counter++; + + if(hdrincl == 1) + { + buffer[4] = 0; + buffer[5] = 0; + + test_case = 1; + } + else + test_case = 2; + ret = send(sockfd, buffer, sizeof(ipv4_packet), 0); + if(ret < 0) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +#ifdef FEATURE_NX_IPV6 +char mac_ip[6]; +#endif + + printf("NetX Test: Basic BSD RAW TX Test........................."); + + /* Populate the ARP table for the gateway address */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(192, 168, 1, 1), (0x00 << 8) | 0x24, + ((0xa5 << 24) | (0xb5 << 16) | (0x2c << 8) | 0x58)); + if(status) + error_counter++; + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 10, NX_NULL); + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0xf5841fdb; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0x0425a239; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip1, 10, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + + mac_ip[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip); + + if(status) + error_counter++; +#endif + + packet_process_callback = bsd_tx_packet_process_callback; + + test_raw_ipv4_sendto(1); + + test_raw_ipv4_send(1); + + test_raw_ipv4_sendto(0); + + test_raw_ipv4_send(0); + +#ifdef FEATURE_NX_IPV6 + test_raw_ipv6_sendto(1); + + test_raw_ipv6_send(1); + + test_raw_ipv6_sendto(0); + + test_raw_ipv6_send(0); +#endif + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#endif /* NX_BSD_ENABLE */ + +#else /* __PRODUCT_NETXDUO__ */ + +extern void test_control_return(UINT status); +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_raw_tx_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Basic BSD RAW TX Test.........................N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/bsd_test/netx_bsd_tcp_2nd_bind_test.c b/test/regression/bsd_test/netx_bsd_tcp_2nd_bind_test.c new file mode 100644 index 00000000..b524a257 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_2nd_bind_test.c @@ -0,0 +1,225 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +#define BSD_THREAD_PRIORITY 2 + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +#define PACKET_SIZE 256 +#define PACKET_POOL_SIZE ((PACKET_SIZE + sizeof(NX_PACKET)) * 2) + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_2nd_bind_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + if (status) + error_counter++; + + pointer += PACKET_POOL_SIZE; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + if (status) + error_counter++; + + /* Increment the free memory pointer. */ + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + if (status) + error_counter++; + + /* Increment the free memory pointer. */ + pointer = pointer + 1024; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + if (status) + error_counter++; + + /* Enable BSD */ + status = bsd_initialize(&ip_0, &pool_0, pointer, DEMO_STACK_SIZE, BSD_THREAD_PRIORITY); + /* Check TCP enable status. */ + if (status) + error_counter++; + + pointer += DEMO_STACK_SIZE; + +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +int sockfd1; +int sockfd2; + +struct sockaddr_in local_addr; + +int ret; + + + printf("NetX Test: Basic BSD TCP 2nd Bind Test..................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the first socket. */ + sockfd1 = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd1 < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd1, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + /* Bind the 2nd socket to the same port. */ + sockfd2 = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd2 < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd2, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret >= 0) + error_counter++; + else if(errno != EADDRINUSE) + error_counter++; + + ret = soc_close(sockfd1); + ret += soc_close(sockfd2); + + if(ret) + error_counter++; + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_2nd_bind_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP 2nd Bind Test...................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/bsd_test/netx_bsd_tcp_accept_blocking_test.c b/test/regression/bsd_test/netx_bsd_tcp_accept_blocking_test.c new file mode 100644 index 00000000..11117b9c --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_accept_blocking_test.c @@ -0,0 +1,515 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +static TX_SEMAPHORE sema_2; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS NX_BSD_MAX_SOCKETS +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_accept_blocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + status += tx_semaphore_create(&sema_2, "SEMA 2", 0); + if(status) + error_counter++; +} +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[NUM_CLIENTS]; +static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[NUM_CLIENTS]; + +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +char buf[30]; + + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + ret = recv(sockfd, buf, sizeof(buf), 0); + if(ret <= 0) + error_counter++; + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0); + if(ret != (int)strlen(response[message_id & 3])) + error_counter++; + + if((sockfd - NX_BSD_SOCKFD_START + 1) != (NUM_CLIENTS / 2)) + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + else + tx_semaphore_get(&sema_2, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + tx_semaphore_put(&sema_0); + return; +} + + + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +UINT status; +int accept_no_memory = 0; + + + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + { + if(i != (NUM_CLIENTS - 1)) + error_counter++; + else + { + if(errno != ENOMEM) + error_counter++; + else + { + accept_no_memory = 1; + tx_thread_sleep(10); + i--; + continue; + } + } + } + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status != TX_SUCCESS) + error_counter++; + + + tx_thread_relinquish(); + } + + if(accept_no_memory != 1) + error_counter++; + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ + + printf("NetX Test: Basic BSD TCP Accept Blocking Test............"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wakeup client. */ + tx_semaphore_put(&sema_1); + + test_tcp_server4(); + + /* Wait until client finish. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS]; +static void multiple_client4(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + + } + if(status != NX_SUCCESS) + error_counter++; + + /* Send messages to each server */ + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Receive messages. */ + + for(i = 0; i < NUM_CLIENTS - 1; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_2); + + /* Shutdown one socket (the one in the middle of the group. */ + status = nx_tcp_socket_disconnect(&tcp_sockets[NUM_CLIENTS/2], NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[NUM_CLIENTS/2].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[NUM_CLIENTS/2]); + + status += nx_tcp_socket_delete(&tcp_sockets[NUM_CLIENTS/2]); + if(status != NX_SUCCESS) + error_counter++; + + /* Now we should be able to try another connection */ + status = nx_tcp_client_socket_connect(&tcp_sockets[NUM_CLIENTS - 1], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + /* At this point, we anticpate the BSD system to run out of resource and is unable to make + this connection. */ + error_counter++; + } + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[(NUM_CLIENTS - 1) & 3], strlen(requests[(NUM_CLIENTS - 1) & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[NUM_CLIENTS - 1], packet_ptr, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + status = nx_tcp_socket_receive(&tcp_sockets[NUM_CLIENTS - 1], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[(NUM_CLIENTS - 1) & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[(NUM_CLIENTS - 1) & 3], packet_ptr -> nx_packet_length)) + error_counter++; + if(status == NX_SUCCESS) + nx_packet_release(packet_ptr); + + /* Wakeup server thread. */ + for(i = 0; i < NUM_CLIENTS - 2; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + tx_semaphore_put(&sema_2); + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + if(i == NUM_CLIENTS / 2) + continue; + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[i]); + + + status += nx_tcp_socket_delete(&tcp_sockets[i]); + + if(status != NX_SUCCESS) + error_counter++; + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + /* Simulate a multiple client conneting to the same server. */ + multiple_client4(); + + /* Client finished. */ + tx_semaphore_put(&sema_0); +} + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_accept_blocking_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Accept Blocking Test............N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_accept_blocking_timeout_test.c b/test/regression/bsd_test/netx_bsd_tcp_accept_blocking_timeout_test.c new file mode 100644 index 00000000..a039d49e --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_accept_blocking_timeout_test.c @@ -0,0 +1,549 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +static TX_SEMAPHORE sema_2; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS NX_BSD_MAX_SOCKETS +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_accept_blocking_timeout_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + status += tx_semaphore_create(&sema_2, "SEMA 2", 0); + if(status) + error_counter++; +} +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[NUM_CLIENTS]; +static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[NUM_CLIENTS]; + +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +char buf[30]; + + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + ret = recv(sockfd, buf, sizeof(buf), 0); + if(ret <= 0) + error_counter++; + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0); + if(ret != (int)strlen(response[message_id & 3])) + error_counter++; + + /* Wait until client received. */ + if((sockfd - NX_BSD_SOCKFD_START + 1) != (NUM_CLIENTS / 2)) + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + else + tx_semaphore_get(&sema_2, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + tx_semaphore_put(&sema_0); + return; +} + + + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +UINT status; +int accept_no_memory = 0; + + + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + { + if(i != (NUM_CLIENTS - 1)) + error_counter++; + else + { + if(errno != ENOMEM) + error_counter++; + else + { + accept_no_memory = 1; + tx_thread_sleep(10); + i--; + continue; + } + } + } + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status != TX_SUCCESS) + error_counter++; + + + tx_thread_relinquish(); + } + + if(accept_no_memory != 1) + error_counter++; + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ + + printf("NetX Test: Basic BSD TCP Accept Blocking Timeout Test...."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wakeup client. */ + tx_semaphore_put(&sema_1); + + test_tcp_server4(); + + /* Wait until client finish. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS]; +static void multiple_client4(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + + } + if(status != NX_SUCCESS) + error_counter++; + + /* Now we should be able to try another connection */ + status = nx_tcp_client_socket_connect(&tcp_sockets[NUM_CLIENTS - 1], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + if(status == NX_SUCCESS) + { + /* At this point, we anticpate the BSD system to run out of resource and is unable to make + this connection. */ + error_counter++; + } + else + { + /* Let's delete the socket. */ + if(tcp_sockets[NUM_CLIENTS - 1].nx_tcp_socket_bound_next) + { + status = nx_tcp_client_socket_unbind(&tcp_sockets[NUM_CLIENTS - 1]); + if(status) + error_counter++; + } + + status = nx_tcp_socket_delete(&tcp_sockets[NUM_CLIENTS - 1]); + + /* Recreate the socket. */ + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[NUM_CLIENTS - 1], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[NUM_CLIENTS - 1], NX_ANY_PORT, 0); + if(status) + error_counter++; + } + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Receive messages. */ + + for(i = 0; i < NUM_CLIENTS - 1; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_2); + + /* Shutdown one socket (the one in the middle of the group. */ + status = nx_tcp_socket_disconnect(&tcp_sockets[NUM_CLIENTS/2], NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[NUM_CLIENTS/2].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[NUM_CLIENTS/2]); + + status += nx_tcp_socket_delete(&tcp_sockets[NUM_CLIENTS/2]); + if(status != NX_SUCCESS) + error_counter++; + + /* Now we should be able to try another connection */ + status = nx_tcp_client_socket_connect(&tcp_sockets[NUM_CLIENTS - 1], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + /* At this point, we anticpate the BSD system to run out of resource and is unable to make + this connection. */ + error_counter++; + } + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[(NUM_CLIENTS - 1) & 3], strlen(requests[(NUM_CLIENTS - 1) & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[NUM_CLIENTS - 1], packet_ptr, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + status = nx_tcp_socket_receive(&tcp_sockets[NUM_CLIENTS - 1], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[(NUM_CLIENTS - 1) & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[(NUM_CLIENTS - 1) & 3], packet_ptr -> nx_packet_length)) + error_counter++; + if(status == NX_SUCCESS) + nx_packet_release(packet_ptr); + + /* Wakeup server thread. */ + for(i = 0; i < NUM_CLIENTS - 2; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + tx_semaphore_put(&sema_2); + + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + if(i == NUM_CLIENTS / 2) + continue; + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[i]); + + + status += nx_tcp_socket_delete(&tcp_sockets[i]); + + if(status != NX_SUCCESS) + error_counter++; + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + /* Simulate a multiple client conneting to the same server. */ + multiple_client4(); + + /* Client finished. */ + tx_semaphore_put(&sema_0); +} + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_accept_blocking_timeout_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Accept Blocking Timeout Test....N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_accept_nonblocking_test.c b/test/regression/bsd_test/netx_bsd_tcp_accept_nonblocking_test.c new file mode 100644 index 00000000..8a278eca --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_accept_nonblocking_test.c @@ -0,0 +1,579 @@ +/* This NetX test concentrates on the basic BSD non-blocking operation. */ +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +static TX_SEMAPHORE sema_2; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS NX_BSD_MAX_SOCKETS + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_accept_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 4096, 1); + pointer = pointer + 4096; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 4096, 2); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + status += tx_semaphore_create(&sema_2, "SEMA 2", 0); + if(status != TX_SUCCESS) + error_counter++; +} + + +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[NUM_CLIENTS]; +static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[NUM_CLIENTS]; + +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +fd_set read_fd; +struct timeval tv; +char buf[30]; + /* Note the socket is already in non-blocking mode. */ + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + tv.tv_sec = 1; + tv.tv_usec = 0; + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + if(ret < 0) + { + error_counter++; + return; + } + if(ret == 1) + { + /* Check for read_fd */ + if(FD_ISSET(sockfd, &read_fd)) + { + ret = recv(sockfd, buf, sizeof(buf), 0); + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0); + if(ret != (int)strlen(response[message_id & 3])) + error_counter++; + + /* Wait until client received. */ + if((sockfd - NX_BSD_SOCKFD_START + 1) != (NUM_CLIENTS / 2)) + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + else + tx_semaphore_get(&sema_2, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + } + } + else error_counter++; + + tx_semaphore_put(&sema_0); + return; +} + + + + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +fd_set read_fd; +struct timeval tv; +int accept_no_memory = 0; +int error, len; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + /* Set the socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + tv.tv_sec = 2; + tv.tv_usec = 0; + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + + if(ret != 1) + error_counter++; + else if(!FD_ISSET(sockfd, &read_fd)) + { + error_counter++; + } + + /* Check pending error. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + if(error_counter == 0) + { + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + if(newsock > 0) + { + if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + if(error_counter == 0) + { + + /* Set the new socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + else + { + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space[i], DEMO_STACK_SIZE, 2,2, TX_NO_TIME_SLICE, TX_AUTO_START); + continue; + } + } + } + else + { + if(i != (NUM_CLIENTS - 1)) + error_counter++; + else + { + if(errno != ENOMEM) + error_counter++; + else + { + accept_no_memory = 1; + tx_thread_sleep(10); + i--; + continue; + } + } + } + } + } + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + if(accept_no_memory != 1) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + +static void ntest_0_entry(ULONG thread_input) +{ + + printf("NetX Test: Basic BSD TCP Accept Nonblocking Test........."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wakeup client. */ + tx_semaphore_put(&sema_1); + + test_tcp_server4(); + + /* Wait until client finish. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + + test_control_return(0); + +} + +static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS]; +static void multiple_client4(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i&3], strlen(requests[i&3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i&3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i&3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_2); + + /* Shutdown one socket (the one in the middle of the group. */ + status = nx_tcp_socket_disconnect(&tcp_sockets[NUM_CLIENTS/2], NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[NUM_CLIENTS/2].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[NUM_CLIENTS/2]); + + status += nx_tcp_socket_delete(&tcp_sockets[NUM_CLIENTS/2]); + if(status != NX_SUCCESS) + error_counter++; + + /* Now we should be able to try another connection */ + status = nx_tcp_client_socket_connect(&tcp_sockets[NUM_CLIENTS - 1], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + /* At this point, we anticpate the BSD system to run out of resource and is unable to make + this connection. */ + error_counter++; + } + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[(NUM_CLIENTS - 1) & 3], strlen(requests[(NUM_CLIENTS - 1) & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[NUM_CLIENTS - 1], packet_ptr, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + status = nx_tcp_socket_receive(&tcp_sockets[NUM_CLIENTS - 1], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[(NUM_CLIENTS - 1) & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[(NUM_CLIENTS - 1) & 3], packet_ptr -> nx_packet_length)) + error_counter++; + if(status == NX_SUCCESS) + nx_packet_release(packet_ptr); + + /* Wakeup server thread. */ + for(i = 0; i < NUM_CLIENTS - 2; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + tx_semaphore_put(&sema_2); + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + if(i == NUM_CLIENTS / 2) + continue; + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE); + if((status == NX_SUCCESS) || (status == NX_NOT_CONNECTED) || (status == NX_DISCONNECT_FAILED)) + status = 0; + else + error_counter++; + if(tcp_sockets[i].nx_tcp_socket_bound_next) + { + status = nx_tcp_client_socket_unbind(&tcp_sockets[i]); + if(status) + error_counter++; + } + + status = nx_tcp_socket_delete(&tcp_sockets[i]); + + if(status != NX_SUCCESS) + error_counter ++; + + + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + multiple_client4(); + + /* Client finished. */ + tx_semaphore_put(&sema_0); + +} + + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + return; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + return; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + return; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_accept_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Accept Nonblocking Test.........N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_accept_nonblocking_timeout_test.c b/test/regression/bsd_test/netx_bsd_tcp_accept_nonblocking_timeout_test.c new file mode 100644 index 00000000..d3a76bab --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_accept_nonblocking_timeout_test.c @@ -0,0 +1,610 @@ +/* This NetX test concentrates on the basic BSD non-blocking operation. */ +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +static TX_SEMAPHORE sema_2; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS NX_BSD_MAX_SOCKETS + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_accept_nonblocking_timeout_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 4096, 1); + pointer = pointer + 4096; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 4096, 2); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + status += tx_semaphore_create(&sema_2, "SEMA 2", 0); + if(status != TX_SUCCESS) + error_counter++; +} + + +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[NUM_CLIENTS]; +static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[NUM_CLIENTS]; + +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +fd_set read_fd; +struct timeval tv; +char buf[30]; + /* Note the socket is already in non-blocking mode. */ + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + tv.tv_sec = 1; + tv.tv_usec = 0; + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + if(ret < 0) + { + error_counter++; + return; + } + if(ret == 1) + { + /* Check for read_fd */ + if(FD_ISSET(sockfd, &read_fd)) + { + ret = recv(sockfd, buf, sizeof(buf), 0); + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0); + if(ret != (int)strlen(response[message_id & 3])) + error_counter++; + + /* Wait until client received. */ + if((sockfd - NX_BSD_SOCKFD_START + 1) != (NUM_CLIENTS / 2)) + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + else + tx_semaphore_get(&sema_2, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + } + } + else error_counter++; + + tx_semaphore_put(&sema_0); + return; +} + + + + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +fd_set read_fd; +struct timeval tv; +int accept_no_memory = 0; +int error, len; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + /* Set the socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + tv.tv_sec = 2; + tv.tv_usec = 0; + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + + if(ret != 1) + error_counter++; + else if(!FD_ISSET(sockfd, &read_fd)) + { + error_counter++; + } + + /* Check pending error. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + if(error_counter == 0) + { + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + if(newsock > 0) + { + if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + if(error_counter == 0) + { + + /* Set the new socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + else + { + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space[i], DEMO_STACK_SIZE, 2,2, TX_NO_TIME_SLICE, TX_AUTO_START); + continue; + } + } + } + else + { + if(i != (NUM_CLIENTS - 1)) + error_counter++; + else + { + if(errno != ENOMEM) + error_counter++; + else + { + accept_no_memory = 1; + tx_thread_sleep(1); + i--; + continue; + } + } + } + } + } + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + if(accept_no_memory != 1) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + +static void ntest_0_entry(ULONG thread_input) +{ + + printf("NetX Test: Basic BSD TCP Accept Nonblocking timeout Test."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wakeup client. */ + tx_semaphore_put(&sema_1); + + test_tcp_server4(); + + /* Wait until client finish. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + + test_control_return(0); + +} + +static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS]; +static void multiple_client4(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + } + if(status != NX_SUCCESS) + error_counter++; + + + /* Now attempt to make another connection. We know this one would fail. */ + status = nx_tcp_client_socket_connect(&tcp_sockets[NUM_CLIENTS - 1], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE / 10); + if(status == NX_SUCCESS) + { + /* At this point, we anticpate the BSD system to run out of resource and is unable to make + this connection. */ + error_counter++; + } + else + { + /* Let's delete the socket. */ + if(tcp_sockets[NUM_CLIENTS - 1].nx_tcp_socket_bound_next) + { + status = nx_tcp_client_socket_unbind(&tcp_sockets[NUM_CLIENTS - 1]); + if(status) + error_counter++; + } + + status = nx_tcp_socket_delete(&tcp_sockets[NUM_CLIENTS - 1]); + + /* Recreate the socket. */ + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[NUM_CLIENTS - 1], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[NUM_CLIENTS - 1], NX_ANY_PORT, 0); + if(status) + error_counter++; + } + + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i&3], strlen(requests[i&3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, 1); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i&3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i&3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_2); + + /* Shutdown one socket (the one in the middle of the group. */ + status = nx_tcp_socket_disconnect(&tcp_sockets[NUM_CLIENTS/2], 2); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[NUM_CLIENTS/2].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[NUM_CLIENTS/2]); + + status += nx_tcp_socket_delete(&tcp_sockets[NUM_CLIENTS/2]); + if(status != NX_SUCCESS) + error_counter++; + + /* Now we should be able to try another connection */ + status = nx_tcp_client_socket_connect(&tcp_sockets[NUM_CLIENTS - 1], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + /* At this point, we anticpate the BSD system to run out of resource and is unable to make + this connection. */ + error_counter++; + } + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[(NUM_CLIENTS - 1) & 3], strlen(requests[(NUM_CLIENTS - 1) & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[NUM_CLIENTS - 1], packet_ptr, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + status = nx_tcp_socket_receive(&tcp_sockets[NUM_CLIENTS - 1], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[(NUM_CLIENTS - 1) & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[(NUM_CLIENTS - 1) & 3], packet_ptr -> nx_packet_length)) + error_counter++; + if(status == NX_SUCCESS) + nx_packet_release(packet_ptr); + + /* Wakeup server thread. */ + for(i = 0; i < NUM_CLIENTS - 2; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + tx_semaphore_put(&sema_2); + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + if(i == NUM_CLIENTS / 2) + continue; + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE); + if((status == NX_SUCCESS) || (status == NX_NOT_CONNECTED) || (status == NX_DISCONNECT_FAILED)) + status = 0; + else + error_counter++; + if(tcp_sockets[i].nx_tcp_socket_bound_next) + { + status = nx_tcp_client_socket_unbind(&tcp_sockets[i]); + if(status) + error_counter++; + } + + status = nx_tcp_socket_delete(&tcp_sockets[i]); + + if(status != NX_SUCCESS) + error_counter ++; + + + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + multiple_client4(); + + /* Client finished. */ + tx_semaphore_put(&sema_0); + +} + + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + return; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + return; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + return; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_accept_nonblocking_timeout_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Accept Nonblocking timeout Test.N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_accept_noselect_test.c b/test/regression/bsd_test/netx_bsd_tcp_accept_noselect_test.c new file mode 100644 index 00000000..23885de5 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_accept_noselect_test.c @@ -0,0 +1,583 @@ +/* This NetX test concentrates on the basic BSD non-blocking operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +static TX_SEMAPHORE sema_2; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS NX_BSD_MAX_SOCKETS + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_accept_noselect_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 4096, 1); + pointer = pointer + 4096; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 4096, 2); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + status += tx_semaphore_create(&sema_2, "SEMA 2", 0); + if(status) + error_counter++; +} + + +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[NUM_CLIENTS]; +static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[NUM_CLIENTS]; + +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +fd_set read_fd; +struct timeval tv; +char buf[30]; + /* Note the socket is already in non-blocking mode. */ + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + tv.tv_sec = 5; + tv.tv_usec = 0; + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + if(ret < 0) + { + error_counter++; + return; + } + if(ret == 1) + { + /* Check for read_fd */ + if(FD_ISSET(sockfd, &read_fd)) + { + ret = recv(sockfd, buf, sizeof(buf), 0); + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0); + if(ret != (int)strlen(response[message_id & 3])) + error_counter++; + + if((sockfd - NX_BSD_SOCKFD_START + 1) != (NUM_CLIENTS / 2)) + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + else + tx_semaphore_get(&sema_2, 5 * NX_IP_PERIODIC_RATE); + + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + } + } + else error_counter++; + + tx_semaphore_put(&sema_0); + return; +} + + + + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +int accept_no_memory = 0; +int not_accepted; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + /* Set the socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + + not_accepted = 1; + + while(not_accepted) + { + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + if(newsock > 0) + { + if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + if(error_counter == 0) + { + + /* Set the new socket to non-blocking mode. */ + if(fcntl(newsock, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + else + { + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space[i], DEMO_STACK_SIZE, 2,2, TX_NO_TIME_SLICE, TX_AUTO_START); + not_accepted = 0; + } + } + } + else if(errno == ENOMEM) + { + accept_no_memory = 1; + tx_thread_sleep(1); + } + else if(errno == EWOULDBLOCK) + { + tx_thread_sleep(1); + } + + } + } + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + if(accept_no_memory != 1) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + +static void ntest_0_entry(ULONG thread_input) +{ + + printf("NetX Test: Basic BSD TCP Accept No Select Test..........."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wakeup client. */ + tx_semaphore_put(&sema_1); + + test_tcp_server4(); + + /* Wait until client finish. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + + test_control_return(0); + +} + +static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS]; +static void multiple_client4(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + } + if(status != NX_SUCCESS) + error_counter++; + + + /* Now we should be able to try another connection. This one would fail. */ + status = nx_tcp_client_socket_connect(&tcp_sockets[NUM_CLIENTS - 1], IP_ADDRESS(1, 2, 3, 4), 12345, 1); + if(status == NX_SUCCESS) + { + /* At this point, we anticpate the BSD system to run out of resource and is unable to make + this connection. */ + error_counter++; + } + /* Disconnect and clean up this socket. */ + status = nx_tcp_socket_disconnect(&tcp_sockets[NUM_CLIENTS - 1], NX_IP_PERIODIC_RATE / 10); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[NUM_CLIENTS - 1].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[NUM_CLIENTS - 1]); + + status += nx_tcp_socket_delete(&tcp_sockets[NUM_CLIENTS - 1]); + if(status != NX_SUCCESS) + error_counter++; + + /* Recreate the socket. */ + status = nx_tcp_socket_create(&ip_1, &tcp_sockets[NUM_CLIENTS - 1], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[NUM_CLIENTS - 1], NX_ANY_PORT, 0); + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i&3], strlen(requests[i&3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE / 10); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < (NUM_CLIENTS - 1); i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i&3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i&3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_2); + + /* Shutdown one socket (the one in the middle of the group. */ + status = nx_tcp_socket_disconnect(&tcp_sockets[NUM_CLIENTS/2], NX_IP_PERIODIC_RATE / 10); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[NUM_CLIENTS/2].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[NUM_CLIENTS/2]); + + status += nx_tcp_socket_delete(&tcp_sockets[NUM_CLIENTS/2]); + if(status != NX_SUCCESS) + error_counter++; + + /* Now we should be able to try another connection */ + status = nx_tcp_client_socket_connect(&tcp_sockets[NUM_CLIENTS - 1], IP_ADDRESS(1, 2, 3, 4), 12345, TX_TIMER_TICKS_PER_SECOND); + if(status != NX_SUCCESS) + { + /* At this point, we anticpate the BSD system to run out of resource and is unable to make + this connection. */ + error_counter++; + } + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[(NUM_CLIENTS - 1) & 3], strlen(requests[(NUM_CLIENTS - 1) & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[NUM_CLIENTS - 1], packet_ptr, NX_IP_PERIODIC_RATE / 10); + if(status != NX_SUCCESS) + error_counter++; + + status = nx_tcp_socket_receive(&tcp_sockets[NUM_CLIENTS - 1], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[(NUM_CLIENTS - 1) & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[(NUM_CLIENTS - 1) & 3], packet_ptr -> nx_packet_length)) + error_counter++; + if(status != NX_SUCCESS) + nx_packet_release(packet_ptr); + + /* Wakeup server thread. */ + for(i = 0; i < NUM_CLIENTS - 2; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + tx_semaphore_put(&sema_2); + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + if(i == NUM_CLIENTS / 2) + continue; + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE); + if((status == NX_SUCCESS) || (status == NX_NOT_CONNECTED) || (status == NX_DISCONNECT_FAILED)) + status = 0; + else + error_counter++; + if(tcp_sockets[i].nx_tcp_socket_bound_next) + { + status = nx_tcp_client_socket_unbind(&tcp_sockets[i]); + if(status) + error_counter++; + } + + status = nx_tcp_socket_delete(&tcp_sockets[i]); + + if(status != NX_SUCCESS) + error_counter ++; + + + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + multiple_client4(); + + /* Client finished. */ + tx_semaphore_put(&sema_0); +} + + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + return; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + return; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + return; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_accept_noselect_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Accept No Select Test...........N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_basic_blocking_test.c b/test/regression/bsd_test/netx_bsd_tcp_basic_blocking_test.c new file mode 100644 index 00000000..49bba72a --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_basic_blocking_test.c @@ -0,0 +1,1101 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 10 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif +static char *send_buffer = "Hello World"; +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +#ifdef __PRODUCT_NETXDUO__ +static char large_msg[1000]; +#endif +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_basic_blocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + if(status) + error_counter++; +} +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[NUM_CLIENTS]; +static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[NUM_CLIENTS]; +#ifdef FEATURE_NX_IPV6 +static ULONG stack_space6[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread6[NUM_CLIENTS]; +#endif +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +char buf[30]; +int sockaddr_len; +fd_set read_fds, write_fds, except_fds; +struct timeval wait_time; +#ifdef FEATURE_NX_IPV6 +struct sockaddr_in6 remote_address; +#else +struct sockaddr_in remote_address; +#endif + + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + if(message_id == 2) + { +#ifdef FEATURE_NX_IPV6 + sockaddr_len = sizeof(struct sockaddr_in6); +#else + sockaddr_len = sizeof(struct sockaddr_in); +#endif + ret = recvfrom(sockfd, (char*)buf, sizeof(buf), 0, (struct sockaddr*)&remote_address, &sockaddr_len); + + if(ret < 0) + error_counter++; + if(nx_bsd_socket_array[sockfd - 0x20].nx_bsd_socket_family == AF_INET) + { + if(sockaddr_len != sizeof(struct sockaddr_in)) + error_counter++; + if(((struct sockaddr_in*)&remote_address) -> sin_family != AF_INET) + error_counter++; + if(((struct sockaddr_in*)&remote_address) -> sin_addr.s_addr != htonl(0x01020305)) + error_counter++; + } +#ifdef FEATURE_NX_IPV6 + else if(nx_bsd_socket_array[sockfd - 0x20].nx_bsd_socket_family == AF_INET6) + { + if(sockaddr_len != sizeof(struct sockaddr_in6)) + error_counter++; + if((remote_address.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_address.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_address.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_address.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + } +#endif + } + else + { + + /* Peek message test. */ + ret = recv(sockfd, buf, sizeof(buf), MSG_PEEK); + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret)) + error_counter++; + + ret = recv(sockfd, buf, sizeof(buf), 0); + } + if(ret <= 0) + error_counter++; + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret)) + error_counter++; + + /* Invoke recvfrom with MSG_DONTWAIT flag. */ + ret = recvfrom(sockfd, (char*)buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*)&remote_address, &sockaddr_len); + if(ret >= 0) + error_counter++; + else if((errno != EWOULDBLOCK) || (errno != EAGAIN)) + error_counter++; + + /* Invoke recv with MSG_DONTWAIT flag. */ + ret = recv(sockfd, (char*)buf, sizeof(buf), MSG_DONTWAIT); + if(ret >= 0) + error_counter++; + else if((errno != EWOULDBLOCK) || (errno != EAGAIN)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0); + if(ret != (int)strlen(response[message_id & 3])) + error_counter++; + + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + +#ifdef __PRODUCT_NETXDUO__ + /* Invoke send with MSG_DONTWAIT flag. The message is larger than tx_window. Partial data should be sent. */ + ret = send(sockfd, large_msg, sizeof(large_msg), MSG_DONTWAIT); + if (ret <= 0) + error_counter++; +#endif + + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + FD_ZERO(&except_fds); + FD_SET(sockfd, &read_fds); + FD_SET(sockfd, &write_fds); + FD_SET(sockfd, &except_fds); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + wait_time.tv_sec = 1; + wait_time.tv_usec = 0; + select(sockfd + 1, &read_fds, &write_fds, &except_fds, &wait_time); + if((FD_ISSET(sockfd, &read_fds) && FD_ISSET(sockfd, &write_fds) && FD_ISSET(sockfd, &except_fds)) == 0) + error_counter++; + + tx_semaphore_put(&sema_0); + return; +} + + +static void test_tcp_client4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +#ifdef FEATURE_NX_IPV6 +struct sockaddr_in6 local_addr6; +int port; +int sockfd1; +#endif +int bytes_sent; +int ret; +char buf; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = INADDR_ANY; + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0) + error_counter++; + + bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0); + + if(bytes_sent != (int)strlen(send_buffer)) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Get the port bind to any. */ + port = nx_bsd_socket_array[sockfd - NX_BSD_SOCKFD_START].nx_bsd_socket_tcp_socket -> nx_tcp_socket_port; + + sockfd1 = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd1 < 0) + error_counter++; + + memset(&local_addr6, 0, sizeof(local_addr6)); + local_addr6.sin6_family = AF_INET6; + local_addr6.sin6_port = htons(port); + + /* Bind to the same port. */ + ret = bind(sockfd1, (struct sockaddr*)&local_addr6, sizeof(local_addr6)); + if(ret < 0) + error_counter++; + + ret = soc_close(sockfd1); + if(ret < 0) + error_counter++; +#endif + + /* Call recv before peer orderly shutdown. */ + ret = recv(sockfd, &buf, 1, 0); + if (ret != 0) + error_counter++; + + /* Make sure the other side gets the message. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + /* Call recv after peer orderly shutdown. */ + ret = recv(sockfd, &buf, 1, 0); + if (ret != 0) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +UINT status; + + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + address_length = sizeof(local_addr); + ret = getsockname(newsock, (struct sockaddr*)&local_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(local_addr)) + error_counter++; + else if(local_addr.sin_family != AF_INET) + error_counter++; + else if(local_addr.sin_port != htons(12345)) + error_counter++; + else if(local_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1, 2, 3, 4))) + error_counter++; + + address_length = sizeof(remote_addr); + ret = getpeername(newsock, (struct sockaddr*)&remote_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if(remote_addr.sin_family != AF_INET) + error_counter++; + else if(remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5))) + error_counter++; + + + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status != TX_SUCCESS) + error_counter++; + + tx_thread_relinquish(); + } + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + + +#ifdef FEATURE_NX_IPV6 +static void test_tcp_client6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr; +int bytes_sent; +int ret; + + sockfd = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + + remote_addr.sin6_family = AF_INET6; + remote_addr.sin6_port = htons(12); + remote_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip1.nxd_ip_address.v6[0]); + remote_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip1.nxd_ip_address.v6[1]); + remote_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip1.nxd_ip_address.v6[2]); + remote_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip1.nxd_ip_address.v6[3]); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0) + error_counter++; + + bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0); + + if(bytes_sent != (INT)strlen(send_buffer)) + error_counter++; + + /* Make sure the other side gets the message. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +static void test_tcp_server6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +UINT status; + + sockfd = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_family = AF_INET6; + local_addr.sin6_port = htons(12346); + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + error_counter++; + + if(address_length != sizeof(struct sockaddr_in6)) + error_counter++; + + if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + address_length = sizeof(local_addr); + ret = getsockname(newsock, (struct sockaddr*)&local_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(local_addr)) + error_counter++; + else if(local_addr.sin6_family != AF_INET6) + error_counter++; + else if(local_addr.sin6_port != htons(12346)) + error_counter++; + else if((local_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip0.nxd_ip_address.v6[0])) || + (local_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip0.nxd_ip_address.v6[1])) || + (local_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip0.nxd_ip_address.v6[2])) || + (local_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip0.nxd_ip_address.v6[3]))) + error_counter++; + + address_length = sizeof(remote_addr); + ret = getpeername(newsock, (struct sockaddr*)&remote_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if(remote_addr.sin6_family != AF_INET6) + error_counter++; + else if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + + + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_thread6[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space6[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status) + error_counter++; + + tx_thread_relinquish(); + } + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + +#endif + +static void close_before_accept_test() +{ +int server_fd, client_fd; +int ret; +struct sockaddr_in remote_addr, local_addr; + + /* Setup server socket. */ + server_fd = socket(AF_INET, SOCK_STREAM, 0); + if(server_fd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(server_fd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(server_fd, 5); + if(ret < 0) + error_counter++; + + /* Setup client socket. */ + client_fd = socket(AF_INET, SOCK_STREAM, 0); + if(client_fd < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12345); + remote_addr.sin_addr.s_addr = htonl(0x01020304); + + if(connect(client_fd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0) + error_counter++; + + /* Close before calling accept. */ + soc_close(server_fd); + soc_close(client_fd); +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +int sockfd; +struct sockaddr_in remote_addr; +#ifdef FEATURE_NX_IPV6 +char mac_ip0[6]; +char mac_ip1[6]; +UINT status; +#endif +int ret; + + + printf("NetX Test: Basic BSD TCP Basic Blocking Test............."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = (CHAR)(ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8); + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = (CHAR)(ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8); + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + + close_before_accept_test(); + + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + test_tcp_client4(); + + tx_semaphore_put(&sema_1); + test_tcp_server4(); + +#ifdef FEATURE_NX_IPV6 + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + test_tcp_client6(); + + tx_semaphore_put(&sema_1); + test_tcp_server6(); +#endif + + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + /* Now open another socket and attempt to connect to the correct remote + host but an unexpected port so we expect an unsuccessful connections. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) >= 0) + error_counter++; + if(errno != ECONNREFUSED) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + /* Now open another socket and attempt to connect to the an incorrect + remote host so we expect an unsuccessful connections. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020306); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) >= 0) + error_counter++; + + if(errno != ETIMEDOUT) + error_counter++; + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + /* After the previous failed connection, make sure we can still open a socket. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS]; +static void multiple_client4(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < NUM_CLIENTS; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[i]); + + + status += nx_tcp_socket_delete(&tcp_sockets[i]); + + if(status != NX_SUCCESS) + error_counter++; + } + + +} + + +#ifdef FEATURE_NX_IPV6 +static void multiple_client6(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nxd_tcp_client_socket_connect(&tcp_sockets[i], &ipv6_address_ip0, 12346, NX_IP_PERIODIC_RATE); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < NUM_CLIENTS; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i & 3])) + error_counter++; + else if(strncmp((char *)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE); + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + status = nx_tcp_client_socket_unbind(&tcp_sockets[i]); + status += nx_tcp_socket_delete(&tcp_sockets[i]); + + if(status != NX_SUCCESS) + error_counter++; + } + +} +#endif + +static void netx_tcp_server(void) +{ +NX_PACKET *packet_ptr; +UINT status; + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != strlen(send_buffer))) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, send_buffer, strlen(send_buffer))) + error_counter++; + + nx_packet_release(packet_ptr); + } + + tx_semaphore_put(&sema_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + nx_tcp_socket_delete(&server_socket); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + tx_semaphore_put(&sema_0); + + netx_tcp_server(); + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + /* Simulate a multiple client conneting to the same server. */ + multiple_client4(); + +#ifdef FEATURE_NX_IPV6 + tx_semaphore_put(&sema_0); + netx_tcp_server(); + + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + multiple_client6(); +#endif + + /* Client finished. */ + tx_semaphore_put(&sema_0); +} + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_basic_blocking_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Basic Blocking Test.............N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_basic_nonblocking_test.c b/test/regression/bsd_test/netx_bsd_tcp_basic_nonblocking_test.c new file mode 100644 index 00000000..875d9811 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_basic_nonblocking_test.c @@ -0,0 +1,1222 @@ +/* This NetX test concentrates on the basic BSD non-blocking operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 10 + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif +static char *send_buffer = "Hello World"; +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_basic_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 4096, 1); + pointer = pointer + 4096; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 4096, 2); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + if(status != TX_SUCCESS) + error_counter++; +} + + +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[NUM_CLIENTS]; +static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[NUM_CLIENTS]; +#ifdef FEATURE_NX_IPV6 +static ULONG stack_space6[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread6[NUM_CLIENTS]; +#endif +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +fd_set read_fd; +struct timeval tv; +char buf[30]; + /* Note the socket is already in non-blocking mode. */ + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + tv.tv_sec = 1; + tv.tv_usec = 0; + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + if(ret < 0) + { + error_counter++; + return; + } + if(ret == 1) + { + /* Check for read_fd */ + if(FD_ISSET(sockfd, &read_fd)) + { + ret = recv(sockfd, buf, sizeof(buf), 0); + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id&3])) || strncmp(buf, requests[message_id&3], ret)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id&3], strlen(response[message_id&3]), 0); + if(ret != (int)strlen(response[message_id&3])) + error_counter++; + + /* Wait until remote disconnects. */ + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + tv.tv_sec = 3; + tv.tv_usec = 0; + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + if(ret != 1) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + } + } + else error_counter++; + + tx_semaphore_put(&sema_0); + return; +} + + + + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +fd_set read_fd; +struct timeval tv; +int error, len; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + /* Set the socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + tv.tv_sec = 2; + tv.tv_usec = 0; + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + + if(ret != 1) + error_counter++; + else if(!FD_ISSET(sockfd, &read_fd)) + error_counter++; + + /* Check pending error. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + if(error_counter == 0) + { + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + if(newsock > 0) + { + if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + if(error_counter == 0) + { + + /* Set the new socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + else + { + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space[i], DEMO_STACK_SIZE, 2,2, TX_NO_TIME_SLICE, TX_AUTO_START); + continue; + } + } + } + ret = soc_close(newsock); + if(ret != 0) + error_counter++; + } + } + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + +#ifdef FEATURE_NX_IPV6 + +static void test_tcp_server6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +fd_set read_fd; +struct timeval tv; +int error, len; + + sockfd = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_family = AF_INET6; + local_addr.sin6_port = htons(12346); + + /* Set the socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + tv.tv_sec = 2; + tv.tv_usec = 0; + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + + if(ret != 1) + error_counter++; + else if(!FD_ISSET(sockfd, &read_fd)) + error_counter++; + + /* Check pending error. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + if(error_counter == 0) + { + address_length = sizeof(remote_addr); + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + if(newsock > 0) + { + if(address_length != sizeof(struct sockaddr_in6)) + error_counter++; + else if(remote_addr.sin6_family != AF_INET6) + error_counter++; + else if((remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + if(error_counter == 0) + { + + /* Set the new socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + else + { + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + tx_thread_create(&helper_thread6[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space6[i], DEMO_STACK_SIZE, 2,2, TX_NO_TIME_SLICE, TX_AUTO_START); + continue; + } + } + } + ret = soc_close(newsock); + if(ret < 0) + error_counter++; + } + } + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} +#endif + + +static void test_tcp_client4(void) +{ +int sockfd; +struct sockaddr_in remote_addr; +int ret; +fd_set write_fd; +struct timeval tv; +int bytes_sent; +int error, len; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + /* Set the socket as non-blocking */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + { + /* Non blocking call, it shouldn't succeed. */ + error_counter++; + soc_close(sockfd); + return; + } + else + { + /* Make sure the errno is EINPROGRESS */ + if(errno != EINPROGRESS) + { + error_counter++; + return; + } + } + + /* Now select on the socket. */ + + /* Wait for one second. */ + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&write_fd); + FD_SET(sockfd, &write_fd); + + ret = select(FD_SETSIZE, NULL, &write_fd, NULL, &tv); + + /* If select returns, there should only be one socket in the write group being selected. */ + if(ret != 1) + error_counter++; + else if(!FD_ISSET(sockfd, &write_fd)) + error_counter++; + + /* Check pending error. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + if(error_counter == 0) + { + /* select successfully returns. So do connect call again. This connect call should return 0. */ + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret != 0) + { + error_counter++; + return; + } + + bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0); + + if(bytes_sent != (int)strlen(send_buffer)) + error_counter++; + + /* Make sure the other side gets the message. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + } +} + +#ifdef FEATURE_NX_IPV6 +static void test_tcp_client6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr; +int ret; +fd_set write_fd; +struct timeval tv; +int bytes_sent; +int error, len; + + sockfd = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + /* Set the socket as non-blocking */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + + remote_addr.sin6_family = AF_INET6; + remote_addr.sin6_port = htons(12); + remote_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip1.nxd_ip_address.v6[0]); + remote_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip1.nxd_ip_address.v6[1]); + remote_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip1.nxd_ip_address.v6[2]); + remote_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip1.nxd_ip_address.v6[3]); + + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + { + /* Non blocking call, it shouldn't succeed. */ + error_counter++; + soc_close(sockfd); + return; + } + else + { + /* Make sure the errno is EINPROGRESS */ + if(errno != EINPROGRESS) + { + error_counter++; + return; + } + } + + /* Now select on the socket. */ + + /* Wait for one second. */ + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&write_fd); + FD_SET(sockfd, &write_fd); + + ret = select(sockfd + 1, NULL, &write_fd, NULL, &tv); + + /* If select returns, there should only be one socket in the write group being selected. */ + if(ret != 1) + error_counter++; + else if(!FD_ISSET(sockfd, &write_fd)) + error_counter++; + + /* Check pending error. */ + len = sizeof(error); + getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len); + if(error) + error_counter++; + + if(error_counter == 0) + { + /* select successfully returns. So do connect call again. This connect call should return 0. */ + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret != 0) + { + error_counter++; + return; + } + + bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0); + + if(bytes_sent != (INT)strlen(send_buffer)) + error_counter++; + + /* Make sure the other side gets the message. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + } +} + +#endif /*FEATURE_NX_IPV6 */ +static void ntest_0_entry(ULONG thread_input) +{ +int retry; +int sockfd; +struct sockaddr_in remote_addr; +int ret; +fd_set read_fd, write_fd; +struct timeval tv; +#ifdef FEATURE_NX_IPV6 +UINT status; +char mac_ip0[6]; +char mac_ip1[6]; +#endif + printf("NetX Test: Basic BSD TCP Non Blocking Connect Test......."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + + /* Server run first. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + test_tcp_client4(); + + /* Wakeup client. */ + tx_semaphore_put(&sema_1); + + test_tcp_server4(); + +#ifdef FEATURE_NX_IPV6 + /* Server run first. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + test_tcp_client6(); + + /* Wakeup client. */ + tx_semaphore_put(&sema_1); + + test_tcp_server6(); +#endif + + /* Wait until client finish. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + + /* Now open another socket and attempt to connect to the correct remote + host but an unexpected port so we expect an unsuccessful connections. */ + retry = 0; + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + /* Set the socket as non-blocking */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + { + /* Non blocking call, it shouldn't succeed. */ + error_counter++; + } + else + { + /* Make sure the errno is EINPROGRESS */ + if(errno != EINPROGRESS) + error_counter++; + } + + do + { + /* Wait for one second. */ + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + FD_ZERO(&write_fd); + FD_SET(sockfd, &write_fd); + + + ret = select(sockfd + 1, &read_fd, &write_fd, NULL, &tv); + + /* If select returns, there should only be one socket in the write group being selected. */ + if(ret == 0) + { + retry++; + if(retry == 31) + error_counter++; + } + else if(ret < 1) + { + error_counter++; + } + else if(FD_ISSET(sockfd, &write_fd)) + break; + }while(error_counter == 0); + + if(error_counter == 0) + { + /* select successfully returns. So do connect call again. This connect call should return 0. */ + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + error_counter++; + if(errno != ECONNREFUSED) + error_counter++; + } + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + + /* Now open another socket and attempt to connect to the an incorrect + remote host so we expect an unsuccessful connections. */ + retry = 0; + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + /* Set the socket as non-blocking */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + { + /* Non blocking call, it shouldn't succeed. */ + error_counter++; + } + else + { + /* Make sure the errno is EINPROGRESS */ + if(errno != EINPROGRESS) + error_counter++; + } + + do + { + /* Wait for one second. */ + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + FD_ZERO(&write_fd); + FD_SET(sockfd, &write_fd); + + + ret = select(sockfd + 1, &read_fd, &write_fd, NULL, &tv); + + /* If select returns, there should only be one socket in the write group being selected. */ + if(ret == 0) + { + retry++; + if(retry == 31) + error_counter++; + } + else if(ret < 1) + { + error_counter++; + } + else if((FD_ISSET(sockfd, &write_fd))) + break; + }while(error_counter == 0); + + if(error_counter == 0) + { + /* select successfully returns. So do connect call again. This connect call should return 0. */ + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret >= 0) + error_counter++; + if(errno != ECONNREFUSED) + error_counter++; + } + + + + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + + test_control_return(0); + +} + +static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS]; +static void multiple_client4(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i&3], strlen(requests[i&3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < NUM_CLIENTS; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i&3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i&3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Wait all remote thread close first. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 0); +#ifdef NX_DISABLE_RESET_DISCONNECT + if((status != NX_SUCCESS) && (status != NX_NOT_CONNECTED)) + error_counter++; +#endif + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + { + status = nx_tcp_client_socket_unbind(&tcp_sockets[i]); + if(status != NX_SUCCESS) + error_counter ++; + } + + status = nx_tcp_socket_delete(&tcp_sockets[i]); + if(status != NX_SUCCESS) + error_counter ++; + + + } + + +} + + +#ifdef FEATURE_NX_IPV6 +static void multiple_client6(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nxd_tcp_client_socket_connect(&tcp_sockets[i], &ipv6_address_ip0, 12346, NX_IP_PERIODIC_RATE); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i&3], strlen(requests[i&3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < NUM_CLIENTS; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + + /* Wait all remote thread close first. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 0); +#ifdef NX_DISABLE_RESET_DISCONNECT + if((status != NX_SUCCESS) && (status != NX_NOT_CONNECTED)) + error_counter++; +#endif + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + { + status = nx_tcp_client_socket_unbind(&tcp_sockets[i]); + if(status != NX_SUCCESS) + error_counter ++; + } + + status = nx_tcp_socket_delete(&tcp_sockets[i]); + if(status != NX_SUCCESS) + error_counter ++; + } + + +} + +#endif + +static void netx_tcp_server(void) +{ + +UINT status; +NX_PACKET *packet_ptr; + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + return; + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length != strlen(send_buffer)) + error_counter++; + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, send_buffer, strlen(send_buffer))) + error_counter++; + + nx_packet_release(packet_ptr); + } + + tx_semaphore_put(&sema_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + nx_tcp_socket_delete(&server_socket); +} +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Wakeup client. */ + tx_semaphore_put(&sema_0); + + netx_tcp_server(); + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + multiple_client4(); + + /* Client finished. */ + tx_semaphore_put(&sema_0); + +#ifdef FEATURE_NX_IPV6 + /* Wakeup client. */ + tx_semaphore_put(&sema_0); + + netx_tcp_server(); + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + multiple_client6(); + + /* Client finished. */ + tx_semaphore_put(&sema_0); +#endif +} + + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + return; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + return; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + return; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_basic_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Non Blocking Connect Test.......N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_bind_test.c b/test/regression/bsd_test/netx_bsd_tcp_bind_test.c new file mode 100644 index 00000000..2ffd285a --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_bind_test.c @@ -0,0 +1,809 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 140 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; +static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[NUM_CLIENTS]; +static TX_SEMAPHORE server_done_sema, test_done_sema, sema_0; +static int test_case = 0; +/* Define thread prototypes. */ +static TX_MUTEX protection; +static int count; +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0[3][3]; +static NXD_ADDRESS ipv6_address_ip1[3][3]; +#endif +static char *requests = "Request1"; +static void validate_bsd_structure(void); +static VOID bsd_server_helper_thread_entry(ULONG thread_input); + +#define IP0_IF0_V4_ADDR IP_ADDRESS(1,2,3,4) +#define IP0_IF1_V4_ADDR IP_ADDRESS(2,2,3,4) +#define IP0_IF2_V4_ADDR IP_ADDRESS(3,2,3,4) + +#define IP1_IF0_V4_ADDR IP_ADDRESS(1,2,3,5) +#define IP1_IF1_V4_ADDR IP_ADDRESS(2,2,3,5) +#define IP1_IF2_V4_ADDR IP_ADDRESS(3,2,3,5) + +static ULONG ip0_address[3] = {IP0_IF0_V4_ADDR, IP0_IF1_V4_ADDR, IP0_IF2_V4_ADDR}; +static ULONG ip1_address[3] = {IP1_IF0_V4_ADDR, IP1_IF1_V4_ADDR, IP1_IF2_V4_ADDR}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_bind_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + memset(helper_thread, 0, sizeof(TX_THREAD) * NUM_CLIENTS); + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP0_IF0_V4_ADDR, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Attach a 2nd interface */ + status += nx_ip_interface_attach(&ip_0, "ip_0_second", IP0_IF1_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_0, "ip_0_third", IP0_IF2_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP1_IF0_V4_ADDR, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_1, "ip_1_second", IP1_IF1_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1, "ip_1_third", IP1_IF2_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + + if (status) + error_counter++; + + + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&server_done_sema, "server done", 0); + status += tx_semaphore_create(&test_done_sema, "test done", 0); + status += tx_semaphore_create(&sema_0, "SEMA 0", 0); + + if (status) + error_counter++; +} +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[NUM_CLIENTS]; + +#if 0 +static void test_tcp_server4_6_bind_synch(void) +{ +int thread_count, test_case_count, i; +UINT status = 0; + + switch(test_case) + { + case 0: thread_count = 5; test_case_count = 9; break; + case 1: thread_count = 5; test_case_count = 9; break; + case 2: thread_count = 4; test_case_count = 7; break; + case 3: thread_count = 4; test_case_count = 4; break; + case 4: thread_count = 3; break; + } + + /* Let all the server threads run. */ + for(i = 0; i < thread_count; i++) + tx_semaphore_put(&server_wait_sema); + + /* Let the client run. */ + tx_semaphore_put(&client_wait_sema); + + /* Wait for all tests to finish. */ + if(test_case != 4) + { + for(i = 0; i < test_case_count; i++) + { + status = tx_semaphore_get(&server_done_sema, 5 * NX_IP_PERIODIC_RATE); + if(status != TX_SUCCESS) + error_counter++; + + } + } +} +#endif +static VOID bsd_server4_helper_thread_test_2(ULONG param) +{ +int sockfd; +struct sockaddr_in remote_addr,local_addr; +int address_length; +int ret; +int newsock; +int index; +UINT status; +INT reuseaddr = 1; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + /* Test bind to port 0. */ + local_addr.sin_family = AF_INET; + local_addr.sin_port = 0; + local_addr.sin_addr.s_addr = INADDR_ANY; + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + address_length = sizeof(local_addr); + ret = getsockname(sockfd, (struct sockaddr*)&local_addr, &address_length); + if(ret < 0) + error_counter++; + + /* Check whether port is zero. */ + if (local_addr.sin_port == 0) + error_counter++; + soc_close(sockfd); + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(INT)); + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + if(param < 3) + local_addr.sin_addr.s_addr = htonl(ip0_address[param]); + else + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + + + while(1) + { + if((test_case == 1) && (param == 1)) + break; + if((test_case == 2) && (param == 3)) + break; + + if(test_case == 4) + break; + + address_length = sizeof(remote_addr); + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + if(newsock < 0) + error_counter++; + if(address_length != sizeof(remote_addr)) + error_counter++; + + if(param < 3) + if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(ip1_address[param]))) + error_counter++; + + if(newsock > 0) + { + tx_mutex_get(&protection, 5 * NX_IP_PERIODIC_RATE); + index = count; + count++; + tx_mutex_put(&protection); + client_data[index].sockfd = newsock; + client_data[index].message_id = 0xFFFF; + + status = tx_thread_create(&helper_thread[index], "helper thread", bsd_server_helper_thread_entry, + index, stack_space[index], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, + TX_AUTO_START); + if(status) + error_counter++; + } + } + if(soc_close(sockfd) < 0) + error_counter++; + + tx_semaphore_put(&server_done_sema); +} + +#ifdef FEATURE_NX_IPV6 +static VOID bsd_server6_helper_thread_test_2(ULONG param) +{ +int sockfd; +struct sockaddr_in6 remote_addr,local_addr; +int address_length; +int ret; +int newsock; +int if_index, addr_index, index; +INT reuseaddr = 1; + + sockfd = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(INT)); + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_family = AF_INET6; + local_addr.sin6_port = htons(12345); + if(param != 0xFF00) + { + if_index = param >> 8; + addr_index = param & 0xFF; + local_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip0[if_index][addr_index].nxd_ip_address.v6[0]); + local_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip0[if_index][addr_index].nxd_ip_address.v6[1]); + local_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip0[if_index][addr_index].nxd_ip_address.v6[2]); + local_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip0[if_index][addr_index].nxd_ip_address.v6[3]); + } + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + + + + while(1) + { + if((test_case == 3) && (param == 0xFF00)) + break; + + if(test_case == 4) + break; + + address_length = sizeof(remote_addr); + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + if(newsock < 0) + error_counter++; + if(address_length != sizeof(remote_addr)) + error_counter++; + + if(param != 0xFF00) + { + if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1[if_index][addr_index].nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1[if_index][addr_index].nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1[if_index][addr_index].nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1[if_index][addr_index].nxd_ip_address.v6[3]))) + error_counter++; + } + + if(newsock > 0) + { + + tx_mutex_get(&protection, 5 * NX_IP_PERIODIC_RATE); + index = count; + count++; + tx_mutex_put(&protection); + client_data[index].sockfd = newsock; + client_data[index].message_id = 0xFFFF; + + tx_thread_create(&helper_thread[index], "helper thread", bsd_server_helper_thread_entry, + index, stack_space[index], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, + TX_AUTO_START); + } + + } + if(soc_close(sockfd) < 0) + error_counter++; + + tx_semaphore_put(&server_done_sema); +} +#endif + +static VOID test_tcp_server4_6_bind(void) +{ +#ifdef FEATURE_NX_IPV6 +UINT status; +int index; + + tx_mutex_get(&protection, 5 * NX_IP_PERIODIC_RATE); + index = count; + count = count + 5; + tx_mutex_put(&protection); + + /* Create a thread that binds to the first IPv4 interface. */ + status = tx_thread_create(&helper_thread[index], (CHAR*)"IPv4 if0", bsd_server4_helper_thread_test_2, + 0, stack_space[index], DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Create a thread that binds to the 2nd IPv4 interface. */ + status += tx_thread_create(&helper_thread[index + 1], "IPv4 if1", bsd_server4_helper_thread_test_2, + 1, stack_space[index + 1], DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Create a thread that binds to the IPv4 INADDR_ANY */ + status += tx_thread_create(&helper_thread[index + 2], "IPv4 if_any", bsd_server4_helper_thread_test_2, + 3, stack_space[index + 2], DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Create a thread that binds to the 1st IPv6 address of the 2nd interface IPv6 address. */ + status += tx_thread_create(&helper_thread[index + 3], "IPv6 if0", bsd_server6_helper_thread_test_2, + 0x0101, stack_space[index + 3], DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Create a thread that binds to INADDR6_ANY */ + status += tx_thread_create(&helper_thread[index + 4], "IPv6 if_any", bsd_server6_helper_thread_test_2, + 0xFF00, stack_space[index + 4], DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + /* The first test is to make sure they can all make connections with only the ones they are assigned to. */ + if(status) + error_counter++; + +#if 0 + test_tcp_server4_6_bind_synch(); + + test_case = 1; /* Kill socket binds to the 2nd IPv4 interface. */ + + test_tcp_server4_6_bind_synch(); + + test_case = 2;/* Kill socket binds to IPv4 INADDR_ANY. */ + + test_tcp_server4_6_bind_synch(); + + test_case = 3; /* Kill socket binds to IPv6 INADDR_ANY */ + + /* Create a thread that binds to the IPv4 INADDR_ANY */ + status = tx_thread_create(&helper_thread[index + 2], "IPv4 if_any", bsd_server4_helper_thread_test_2, + 3, stack_space[index + 2], DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + + + test_tcp_server4_6_bind_synch(); + + + test_case = 4; /* Done. */ + test_tcp_server4_6_bind_synch(); + +#endif + tx_semaphore_get(&test_done_sema, 5 * NX_IP_PERIODIC_RATE); + +#endif + +} + +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +char buf[30]; + + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + + ret = recv(sockfd, buf, sizeof(buf), 0); + if(ret <= 0) + error_counter++; + + /* Validate the data. */ + if((ret != (int)strlen(requests)) || strncmp(buf, requests, ret)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, buf, ret, 0); + if(ret <= 0) + error_counter++; + + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + if(message_id == 0xFFFF) + tx_semaphore_put(&server_done_sema); + return; +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +char mac_ip0[6]; +char mac_ip1[6]; +UINT status; +int i,j; +#endif + + + tx_mutex_create(&protection, "test protection", TX_NO_INHERIT); + count = 0; + + + printf("NetX Test: Basic BSD TCP Bind Test......................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + + for(i = 0; i < 3; i++) + { + mac_ip0[0] = (char)(ip_0.nx_ip_interface[i].nx_interface_physical_address_msw >> 8); + mac_ip0[1] = ip_0.nx_ip_interface[i].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = (char)(ip_1.nx_ip_interface[i].nx_interface_physical_address_msw >> 8); + mac_ip1[1] = ip_1.nx_ip_interface[i].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw & 0xff; + + for(j = 0; j < 3; j ++) + { + if(j == 0) + { + /* First set up IPv6 linklocal addresses. */ + ipv6_address_ip0[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0[i][j].nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0[i][j].nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0[i][j].nxd_ip_address.v6[2] = ((mac_ip0[0] | 0x2) << 24) | (mac_ip0[1] << 16) | (mac_ip0[2] << 8) | 0xFF; + ipv6_address_ip0[i][j].nxd_ip_address.v6[3] = (0xFE << 24) | ((mac_ip0[3] | 0x2) << 16) | (mac_ip0[4] << 8) | mac_ip0[5]; + + ipv6_address_ip1[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1[i][j].nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1[i][j].nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1[i][j].nxd_ip_address.v6[2] = + ((mac_ip1[0] | 0x2) << 24) | (mac_ip1[1] << 16) | (mac_ip1[2] << 8) | 0xFF; + ipv6_address_ip1[i][j].nxd_ip_address.v6[3] = + (0xFE << 24) | ((mac_ip1[3] | 0x2) << 16) | (mac_ip1[4] << 8) | mac_ip1[5]; + + status = nxd_ipv6_address_set(&ip_0, i, &ipv6_address_ip0[i][j], 10, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, i, &ipv6_address_ip1[i][j], 10, NX_NULL); + } + else + { + /* Global Adddress */ + ipv6_address_ip0[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0[i][j].nxd_ip_address.v6[0] = 0x20000000 + i; + ipv6_address_ip0[i][j].nxd_ip_address.v6[1] = j; + ipv6_address_ip0[i][j].nxd_ip_address.v6[2] = ipv6_address_ip0[i][0].nxd_ip_address.v6[2]; + ipv6_address_ip0[i][j].nxd_ip_address.v6[3] = ipv6_address_ip0[i][0].nxd_ip_address.v6[3]; + + ipv6_address_ip1[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1[i][j].nxd_ip_address.v6[0] = 0x20000000 + i; + ipv6_address_ip1[i][j].nxd_ip_address.v6[1] = j; + ipv6_address_ip1[i][j].nxd_ip_address.v6[2] = ipv6_address_ip1[i][0].nxd_ip_address.v6[2]; + ipv6_address_ip1[i][j].nxd_ip_address.v6[3] = ipv6_address_ip1[i][0].nxd_ip_address.v6[3]; + + + status = nxd_ipv6_address_set(&ip_0, i, &ipv6_address_ip0[i][j], 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, i, &ipv6_address_ip1[i][j], 64, NX_NULL); + } + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1[i][j].nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0[i][j].nxd_ip_address.v6, 0, mac_ip0); + } + + } + + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + if(status) + error_counter++; + + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif + + tx_semaphore_put(&server_done_sema); + + test_tcp_server4_6_bind(); + + /* Done. */ + tx_semaphore_delete(&server_done_sema); + tx_semaphore_delete(&test_done_sema); + tx_semaphore_delete(&sema_0); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static NX_TCP_SOCKET tcp_sockets; +static void test_client_bind(void) +{ + +int i, j; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + + + for(i = 0; i < 3; i++) + { + for(j = 0; j < 3; j++) + { + status = nx_tcp_socket_create(&ip_1, &tcp_sockets, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets, NX_ANY_PORT, 0); + + if(status != NX_SUCCESS) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + if(j == 0) + status = nx_tcp_client_socket_connect(&tcp_sockets, ip0_address[i], 12345, NX_IP_PERIODIC_RATE / 5); + else + status = nxd_tcp_client_socket_connect(&tcp_sockets, &ipv6_address_ip0[i][j], 12345, NX_IP_PERIODIC_RATE / 5); +#else + status = nx_tcp_client_socket_connect(&tcp_sockets, ip0_address[i], 12345, NX_IP_PERIODIC_RATE / 5); +#endif + + if(status != NX_SUCCESS) + { + status = nx_tcp_client_socket_unbind(&tcp_sockets); + status += nx_tcp_socket_delete(&tcp_sockets); + + if(status) + error_counter++; + continue; + } + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests, strlen(requests), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets, packet_ptr, 2); + if(status != NX_SUCCESS) + error_counter++; +#if 0 + tx_thread_sleep(1); +#endif + status = nx_tcp_socket_receive(&tcp_sockets, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(requests)) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, requests, packet_ptr -> nx_packet_length)) + error_counter++; + if(status == NX_SUCCESS) + nx_packet_release(packet_ptr); + + tx_semaphore_put(&sema_0); + status = nx_tcp_socket_disconnect(&tcp_sockets, 1 * NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + if(tcp_sockets.nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets); + + + status += nx_tcp_socket_delete(&tcp_sockets); + + if(status != NX_SUCCESS) + error_counter++; + } + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +int i; +int index; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + tx_semaphore_get(&server_done_sema, TX_WAIT_FOREVER); + + /* Simulate a multiple client conneting to the same server. */ + test_client_bind(); + + for(i = 0; i < 9; i++) + tx_semaphore_get(&server_done_sema, 5 * NX_IP_PERIODIC_RATE); + + test_case = 1; /* Kill socket binds to the 2nd IPv4 interface. */ + test_client_bind(); + for(i = 0; i < 10; i++) + tx_semaphore_get(&server_done_sema, 5 * NX_IP_PERIODIC_RATE); + test_client_bind(); + for(i = 0; i < 9; i++) + tx_semaphore_get(&server_done_sema, 5 * NX_IP_PERIODIC_RATE); + + test_case = 2; /* Kill socket binds to IPv4 INADDR_ANY */ + test_client_bind(); + for(i = 0; i < 9; i++) + tx_semaphore_get(&server_done_sema, 5 * NX_IP_PERIODIC_RATE); + test_client_bind(); + for(i = 0; i < 7; i++) + tx_semaphore_get(&server_done_sema, 5 * NX_IP_PERIODIC_RATE); + + test_case = 3; /* Kill socket binds to IPv6 INADDR_ANY */ +#if 1 + tx_mutex_get(&protection, 5 * NX_IP_PERIODIC_RATE); + index = count; + count++; + tx_mutex_put(&protection); +#endif + status = tx_thread_create(&helper_thread[index], "IPv4 if_any", bsd_server4_helper_thread_test_2, + 3, stack_space[index], DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + test_client_bind(); + for(i = 0; i < 6; i++) + tx_semaphore_get(&server_done_sema, 5 * NX_IP_PERIODIC_RATE); + test_client_bind(); + for(i = 0; i < 4; i++) + tx_semaphore_get(&server_done_sema, 5 * NX_IP_PERIODIC_RATE); + test_case = 4; + test_client_bind(); + for(i = 0; i < 6; i++) + tx_semaphore_get(&server_done_sema, 5 * NX_IP_PERIODIC_RATE); + + tx_semaphore_put(&test_done_sema); + +} + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_bind_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Bind Test.......................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_blocking_bidirection_test.c b/test/regression/bsd_test/netx_bsd_tcp_blocking_bidirection_test.c new file mode 100644 index 00000000..386cc51a --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_blocking_bidirection_test.c @@ -0,0 +1,912 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 +#define NUM_MESSAGES 20 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 10 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif +static char *bsd_send_buffer = "From BSD Test"; +static char *netx_send_buffer = "From Native NetX Test"; +#ifdef FEATURE_NX_IPV6 +static char *bsd_send_buffer6 = "From BSD Test 6"; +static char *netx_send_buffer6 = "From Native NetX Test 6"; +#endif + +static void validate_bsd_structure(void); + +static char *bsd_transmit_v4_thread_stack; +static char *bsd_receive_v4_thread_stack; +static char *netx_transmit_v4_thread_stack; +static char *netx_receive_v4_thread_stack; + + +static TX_THREAD netx_transmit_v4_thread; +static TX_THREAD netx_receive_v4_thread; +static TX_THREAD bsd_transmit_v4_thread; +static TX_THREAD bsd_receive_v4_thread; + + + +#ifdef FEATURE_NX_IPV6 +static char *bsd_transmit_v6_thread_stack; +static char *bsd_receive_v6_thread_stack; +static char *netx_transmit_v6_thread_stack; +static char *netx_receive_v6_thread_stack; + +static TX_THREAD bsd_transmit_v6_thread; +static TX_THREAD bsd_receive_v6_thread; +static TX_THREAD netx_receive_v6_thread; +static TX_THREAD netx_transmit_v6_thread; +#endif + +static TX_SEMAPHORE bsd_sema; +static TX_SEMAPHORE netx_sema; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_blocking_bidirection_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + netx_transmit_v4_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + netx_receive_v4_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + bsd_transmit_v4_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + bsd_receive_v4_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + +#ifdef FEATURE_NX_IPV6 + netx_transmit_v6_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + netx_receive_v6_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + bsd_transmit_v6_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + bsd_receive_v6_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; +#endif +#if 0 + client4_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + client6_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; +#endif + status = tx_semaphore_create(&netx_sema, "test done", 0); + status += tx_semaphore_create(&bsd_sema, "test done", 0); + if(status != TX_SUCCESS) + error_counter++; +} + +static void transmit_entry(ULONG thread_input) +{ +int sockfd = thread_input; +int ret; +int i; + + for(i = 0; i < NUM_MESSAGES; i++) + { + + ret = send(sockfd, bsd_send_buffer, strlen(bsd_send_buffer), 0); + + if(ret != (int)strlen(bsd_send_buffer)) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 50); + } + + tx_semaphore_put(&bsd_sema); + +} + +static void receive_entry(ULONG thread_input) +{ +int sockfd = thread_input; +int ret; +int i; +char buffer[30]; + + for(i = 0; i < NUM_MESSAGES; i++) + { + + ret = recv(sockfd, buffer, sizeof(buffer), 0); + + if(ret != (int)strlen(netx_send_buffer)) + error_counter++; + else if(strncmp(buffer, netx_send_buffer, ret)) + error_counter++; + } + + tx_semaphore_put(&bsd_sema); + +} + +#ifdef FEATURE_NX_IPV6 +static void transmit6_entry(ULONG thread_input) +{ +int sockfd = thread_input; +int ret; +int i; + + for(i = 0; i < NUM_MESSAGES; i++) + { + + ret = send(sockfd, bsd_send_buffer6, strlen(bsd_send_buffer6), 0); + + if(ret != (INT)strlen(bsd_send_buffer6)) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 50); + } + + tx_semaphore_put(&bsd_sema); + +} + +static void receive6_entry(ULONG thread_input) +{ +int sockfd = thread_input; +int ret; +int i; +char buffer[30]; + + for(i = 0; i < NUM_MESSAGES; i++) + { + + ret = recv(sockfd, buffer, sizeof(buffer), 0); + + if(ret != (INT)strlen(netx_send_buffer6)) + error_counter++; + else if(strncmp(buffer, netx_send_buffer6, ret)) + error_counter++; + } + + tx_semaphore_put(&bsd_sema); + +} + +#endif + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +int sockfd; +struct sockaddr_in peer_address; +struct sockaddr_in local_address; +int addr_len; +int new_sock; +UINT status; +#ifdef FEATURE_NX_IPV6 +struct sockaddr_in6 local_address6; +struct sockaddr_in6 peer_address6; +char mac_ip0[6]; +char mac_ip1[6]; +int sockfd6; +int new_sock6; +INT reuseaddr = 1; +#endif +int ret; + + printf("NetX Test: Basic BSD TCP Blocking Bidirection Test......."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + + /* Set up TCP socket and connect to IPv4 server. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd <= 0) + error_counter++; + + peer_address.sin_family = AF_INET; + peer_address.sin_port = htons(12345); + peer_address.sin_addr.s_addr = htonl(IP_ADDRESS(1, 2, 3, 5)); + + if(connect(sockfd, (struct sockaddr*)&peer_address, sizeof(peer_address)) < 0) + error_counter++; + + /* Create a thread to handle IPv4 TCP receive */ + ret = tx_thread_create(&bsd_transmit_v4_thread, "transmit v4 thread", transmit_entry, sockfd, + bsd_transmit_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + ret += tx_thread_create(&bsd_receive_v4_thread, "receive v4 thread", receive_entry, sockfd, + bsd_receive_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + if(ret != TX_SUCCESS) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Set up TCP socket and connect to IPv6 server. */ + sockfd6 = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd6 <= 0) + error_counter++; + + peer_address6.sin6_family = AF_INET6; + peer_address6.sin6_port = htons(12345); + peer_address6.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip1.nxd_ip_address.v6[0]); + peer_address6.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip1.nxd_ip_address.v6[1]); + peer_address6.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip1.nxd_ip_address.v6[2]); + peer_address6.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip1.nxd_ip_address.v6[3]); + + if(connect(sockfd6, (struct sockaddr*)&peer_address6, sizeof(peer_address6)) < 0) + error_counter++; + + /* Create a thread to handle IPv6 TCP receive */ + ret = tx_thread_create(&bsd_transmit_v6_thread, "transmit v6 thread", transmit6_entry, sockfd6, + bsd_transmit_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + ret += tx_thread_create(&bsd_receive_v6_thread, "receive v6 thread", receive6_entry, sockfd6, + bsd_receive_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + if(ret != TX_SUCCESS) + error_counter++; + +#endif + + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + + /* Close down both sockets. */ +#ifdef FEATURE_NX_IPV6 + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + ret = soc_close(sockfd6); +#endif + ret += soc_close(sockfd); + if(ret) error_counter++; +#ifdef FEATURE_NX_IPV6 + tx_thread_delete(&bsd_transmit_v6_thread); + tx_thread_delete(&bsd_receive_v6_thread); +#endif + + tx_thread_delete(&bsd_transmit_v4_thread); + tx_thread_delete(&bsd_receive_v4_thread); + + /* Set up a TCP server socket and wait for IPv4 connection. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd <= 0) + error_counter++; + + local_address.sin_family = AF_INET; + local_address.sin_port = htons(12345); + local_address.sin_addr.s_addr = htonl(INADDR_ANY); + + if(bind(sockfd, (struct sockaddr*)&local_address, sizeof(local_address)) < 0) + error_counter++; + + if(listen(sockfd, 5) < 0) + error_counter++; + + addr_len = sizeof(peer_address); + new_sock = accept(sockfd, (struct sockaddr*)&peer_address, &addr_len); + if(new_sock < 0) + error_counter++; + /* Create a thread to handle IPv4 TCP receive */ + ret = tx_thread_create(&bsd_transmit_v4_thread, "transmit v4 thread", transmit_entry, new_sock, + bsd_transmit_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + ret += tx_thread_create(&bsd_receive_v4_thread, "receive v4 thread", receive_entry, new_sock, + bsd_receive_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + if(ret != TX_SUCCESS) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Set up a TCP server socket and wait for IPv6 connection. */ + sockfd6 = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd6 <= 0) + error_counter++; + setsockopt(sockfd6, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(INT)); + memset(&local_address6, 0, sizeof(local_address6)); + local_address6.sin6_family = AF_INET6; + local_address6.sin6_port = htons(12345); + if(bind(sockfd6, (struct sockaddr*)&local_address6, sizeof(local_address6)) < 0) + error_counter++; + + if(listen(sockfd6, 5) < 0) + error_counter++; + + addr_len = sizeof(peer_address6); + new_sock6 = accept(sockfd6, (struct sockaddr*)&peer_address6, &addr_len); + if(new_sock6 < 0) + error_counter++; + /* Create a thread to handle IPv4 TCP receive */ + ret = tx_thread_create(&bsd_transmit_v6_thread, "transmit v6 thread", transmit6_entry, new_sock6, + bsd_transmit_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + ret += tx_thread_create(&bsd_receive_v6_thread, "receive v6 thread", receive6_entry, new_sock6, + bsd_receive_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + if(ret != TX_SUCCESS) + error_counter++; +#endif + /* Wait for test to finish. */ + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + +#ifdef FEATURE_NX_IPV6 + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + ret = soc_close(sockfd6); + ret = soc_close(new_sock6); +#endif + ret = soc_close(sockfd); + ret = soc_close(new_sock); + +#ifdef FEATURE_NX_IPV6 + tx_thread_delete(&bsd_transmit_v6_thread); + tx_thread_delete(&bsd_receive_v6_thread); +#endif + + tx_thread_delete(&bsd_transmit_v4_thread); + tx_thread_delete(&bsd_receive_v4_thread); + + if(status) + error_counter++; + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void netx_transmit_v4_entry(ULONG param) +{ +NX_TCP_SOCKET *socket_ptr = (NX_TCP_SOCKET*)param; +int i; +NX_PACKET *packet_ptr; +ULONG status; + + for(i = 0; i < NUM_MESSAGES; i++) + { + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, netx_send_buffer, strlen(netx_send_buffer), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(socket_ptr, packet_ptr, NX_IP_PERIODIC_RATE); + + if(status != NX_SUCCESS) + error_counter++; + } + + tx_semaphore_put(&netx_sema); +} + +static void netx_receive_v4_entry(ULONG param) +{ +NX_TCP_SOCKET *socket_ptr = (NX_TCP_SOCKET*)param; +int i; +NX_PACKET *packet_ptr; +ULONG status; + + for(i = 0; i < NUM_MESSAGES; i++) + { + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(socket_ptr, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != strlen(bsd_send_buffer))) + error_counter++; + + if(status == NX_SUCCESS) + nx_packet_release(packet_ptr); + + } + + tx_semaphore_put(&netx_sema); +} + +#ifdef FEATURE_NX_IPV6 +static void netx_transmit_v6_entry(ULONG param) +{ +NX_TCP_SOCKET *socket_ptr = (NX_TCP_SOCKET*)param; +int i; +NX_PACKET *packet_ptr; +ULONG status; + + for(i = 0; i < NUM_MESSAGES; i++) + { + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, netx_send_buffer6, strlen(netx_send_buffer6), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(socket_ptr, packet_ptr, NX_IP_PERIODIC_RATE); + + if(status != NX_SUCCESS) + error_counter++; + } + + tx_semaphore_put(&netx_sema); +} + +static void netx_receive_v6_entry(ULONG param) +{ +NX_TCP_SOCKET *socket_ptr = (NX_TCP_SOCKET*)param; +int i; +NX_PACKET *packet_ptr; +ULONG status; + + for(i = 0; i < NUM_MESSAGES; i++) + { + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(socket_ptr, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Check for error. */ + if (packet_ptr -> nx_packet_length != strlen(bsd_send_buffer6)) + error_counter++; + else if(memcmp(packet_ptr -> nx_packet_prepend_ptr, bsd_send_buffer6, packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + + } + + tx_semaphore_put(&netx_sema); +} + +#endif +static void netx_tcp_server(void) +{ +NX_TCP_SOCKET server_socket4; +#ifdef FEATURE_NX_IPV6 +NX_TCP_SOCKET server_socket6; +#endif +UINT status; + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket4, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12345, &server_socket4, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket4, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + +#ifdef FEATURE_NX_IPV6 + status = nx_tcp_socket_create(&ip_1, &server_socket6, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + status += nx_tcp_server_socket_relisten(&ip_1, 12345, &server_socket6); + + /* Check for error. */ + if ((status == NX_SUCCESS) || (status == NX_CONNECTION_PENDING)) + { + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket6, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + } + else + error_counter++; + + status = tx_thread_create(&netx_transmit_v6_thread, "netx transmit v6 thread", netx_transmit_v6_entry, (ULONG)&server_socket6, + netx_transmit_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + status += tx_thread_create(&netx_receive_v6_thread, "netx receive v6 thread", netx_receive_v6_entry, (ULONG)&server_socket6, + netx_receive_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + if(status != TX_SUCCESS) + error_counter++; + +#endif + + status = tx_thread_create(&netx_transmit_v4_thread, "netx transmit v4 thread", netx_transmit_v4_entry, (ULONG)&server_socket4, + netx_transmit_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + status += tx_thread_create(&netx_receive_v4_thread, "netx receive v4 thread", netx_receive_v4_entry, (ULONG)&server_socket4, + netx_receive_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + if(status != TX_SUCCESS) + error_counter++; + + + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); + + /* Close down both sockets. */ +#ifdef FEATURE_NX_IPV6 + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); +#endif + +#ifdef FEATURE_NX_IPV6 + tx_thread_delete(&netx_transmit_v6_thread); + tx_thread_delete(&netx_receive_v6_thread); +#endif + + tx_thread_delete(&netx_transmit_v4_thread); + tx_thread_delete(&netx_receive_v4_thread); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket4, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket4); + + status += nx_tcp_socket_delete(&server_socket4); + /* Check for error. */ + if (status) + error_counter++; +#ifdef FEATURE_NX_IPV6 + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket6, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status != NX_SUCCESS) && (status != NX_DISCONNECT_FAILED)) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket6); + + /* Check for error. */ + if (status) + error_counter++; + + + nx_tcp_socket_delete(&server_socket6); +#endif + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12345); + + /* Check for error. */ + if (status) + error_counter++; + +} + +static void netx_tcp_client(void) +{ +NX_TCP_SOCKET client_socket4; +#ifdef FEATURE_NX_IPV6 +NX_TCP_SOCKET client_socket6; +#endif +UINT status; + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket4, "Client Socket 4", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + status += nx_tcp_client_socket_bind(&client_socket4, NX_ANY_PORT, 0); + status += nx_tcp_client_socket_connect(&client_socket4, IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + /* Check for error. */ + if (status) + error_counter++; + + +#ifdef FEATURE_NX_IPV6 + status = nx_tcp_socket_create(&ip_1, &client_socket6, "Client Socket 4", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + status += nx_tcp_client_socket_bind(&client_socket6, NX_ANY_PORT, 0); + + status += nxd_tcp_client_socket_connect(&client_socket6, &ipv6_address_ip0, 12345, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + status = tx_thread_create(&netx_transmit_v6_thread, "netx transmit v6 thread", netx_transmit_v6_entry, (ULONG)&client_socket6, + netx_transmit_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + status += tx_thread_create(&netx_receive_v6_thread, "netx receive v6 thread", netx_receive_v6_entry, (ULONG)&client_socket6, + netx_receive_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + if(status) + error_counter++; + +#endif + status = tx_thread_create(&netx_transmit_v4_thread, "netx transmit v4 thread", netx_transmit_v4_entry, (ULONG)&client_socket4, + netx_transmit_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + status += tx_thread_create(&netx_receive_v4_thread, "netx receive v4 thread", netx_receive_v4_entry, (ULONG)&client_socket4, + netx_receive_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + if(status != TX_SUCCESS) + error_counter++; + + +#ifdef FEATURE_NX_IPV6 + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); +#endif + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); + + status = nx_tcp_socket_disconnect(&client_socket4, NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(client_socket4.nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&client_socket4); + + + status += nx_tcp_socket_delete(&client_socket4); + + if(status != NX_SUCCESS) + error_counter++; +#ifdef FEATURE_NX_IPV6 + status = nx_tcp_socket_disconnect(&client_socket6, NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(client_socket6.nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&client_socket6); + + + status += nx_tcp_socket_delete(&client_socket6); + + if(status != NX_SUCCESS) + error_counter++; +#endif + + tx_semaphore_delete(&netx_sema); + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + + netx_tcp_server(); + + + netx_tcp_client(); + +} + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_blocking_bidirection_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Blocking Bidirection Test.......N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_clients_share_port_test.c b/test/regression/bsd_test/netx_bsd_tcp_clients_share_port_test.c new file mode 100644 index 00000000..6a5832a3 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_clients_share_port_test.c @@ -0,0 +1,855 @@ +/* This demoonstrates sharing a port between an IPv4 and IPv6 TCP client socket to send + and receive packets (e.g emulates a socket that can send/receive iPv4 and Ipv6 packets) + using a simulated Ethernet driver. */ + + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) && defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nxd_bsd.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_client6; +static TX_THREAD thread_server; +static TX_THREAD thread_server6; +static NX_PACKET_POOL bsd_pool; +static NX_IP bsd_ip_server; +static NX_IP bsd_ip_client; + +static UINT error_counter = 0; + +#define CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define SERVER_PORT 74 +#define SERVER6_PORT 76 +#define CLIENT_PORT 87 + +/* Define global data. */ + +static UINT ipv4_client_complete = NX_FALSE; +static UINT ipv6_client_complete = NX_FALSE; + +/* Define thread prototypes. */ + + +static VOID thread_client_entry(ULONG thread_input); +static VOID thread_client6_entry(ULONG thread_input); +static VOID thread_server_entry(ULONG thread_input); +static VOID thread_server6_entry(ULONG thread_input); +VOID _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_clients_share_port_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a BSD packet pool. */ + status = nx_packet_pool_create(&bsd_pool, "NetX BSD Packet Pool", 1516, pointer, 16384); + + pointer = pointer + 16384; + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /********************** Set up the Server IP instance **************************/ + + /* Create a thread for the IPv4 server. */ + status= tx_thread_create(&thread_server, "BSD App IPv4 Server", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + + /* Create a thread for IPv6 server. */ + status= tx_thread_create(&thread_server6, "BSD App IPv6 Server", thread_server6_entry, 0, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /* Create an IP instance for the BSD . */ + status = nx_ip_create(&bsd_ip_server, "NetX BSD IPv4 Server", SERVER_ADDRESS, 0xFFFFFF00UL, + &bsd_pool, _nx_ram_network_driver, pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&bsd_ip_server); + + /* Enable ARP and supply ARP cache memory for BSD */ + status += nx_arp_enable(&bsd_ip_server, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + { + error_counter++; + } + + + /********************** Set up the Client **************************/ + + + /* Create an IP instance for the BSD . */ + status = nx_ip_create(&bsd_ip_client, "NetX BSD IPv4 Client", CLIENT_ADDRESS, 0xFFFFFF00UL, + &bsd_pool, _nx_ram_network_driver, pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&bsd_ip_client); + + status = nx_icmp_enable(&bsd_ip_client); + /* Enable ARP and supply ARP cache memory for BSD */ + status += nx_arp_enable(&bsd_ip_client, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + { + error_counter++; + } + + + /* Create a thread for IPv4 client. */ + status= tx_thread_create(&thread_client, "BSD App IPpv4 Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /* Create a thread for IPv6 client. */ + status= tx_thread_create(&thread_client6, "BSD App IPv6 Client", thread_client6_entry, 0, + pointer, DEMO_STACK_SIZE, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + + /* Now initialize BSD IP. */ + status = bsd_initialize (&bsd_ip_client, &bsd_pool, pointer, 2048, 4); + + /* Check for BSD errors. */ + if (status) + { + error_counter++; + } + + pointer = pointer + 2048; + + return; +} + +/* Define the IPv4 server thread */ +void thread_server_entry(ULONG thread_input) +{ + +INT status; +ULONG actual_status; +NX_TCP_SOCKET server_ipv4_socket; +NX_PACKET *packet_rcv_ptr, *packet_ptr; +char *requests[2] = {"Request1", "Request2"}; +UINT ipv4_server_complete = NX_FALSE; + + /* Check status... */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(11); + } + + /* Wait for IPv6 get set up first. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + status = nx_ip_status_check(&bsd_ip_server, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(12); + } + + status = nx_tcp_socket_create(&bsd_ip_server, &server_ipv4_socket, "Server IPv4 Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 100, NX_NULL, NX_NULL); + + if (status ) + { + printf("ERROR!\n"); + test_control_return(13); + } + + status = nx_tcp_server_socket_listen(&bsd_ip_server, SERVER_PORT, &server_ipv4_socket, 5, NX_NULL); + + if (status ) + { + printf("ERROR!\n"); + test_control_return(14); + } + + status = nx_tcp_server_socket_accept(&server_ipv4_socket, 1000); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(15); + } + + while(!ipv4_server_complete) + { + + status = nx_tcp_socket_receive(&server_ipv4_socket, &packet_rcv_ptr, 500); + if(status != NX_SUCCESS) + { + if (status == NX_NOT_CONNECTED) + { + + ipv4_server_complete = NX_TRUE; + break; + } + + test_control_return(16); + error_counter++; + } + + else + { + + nx_packet_release(packet_rcv_ptr); + } + + status = nx_packet_allocate(&bsd_pool, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + if (status ) + { + + test_control_return(17); + error_counter++; + } + + status = nx_packet_data_append(packet_ptr, requests[0], strlen(requests[0]), + &bsd_pool, NX_NO_WAIT); + if (status ) + { + + test_control_return(18); + error_counter++; + } + + status = nx_tcp_socket_send(&server_ipv4_socket, packet_ptr, 100); + + if (status) + { + nx_packet_release(packet_ptr); + + + if (status == NX_NOT_CONNECTED) + { + ipv4_server_complete = NX_TRUE; + break; + } + + test_control_return(19); + error_counter++; + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 2); + } + + status = nx_tcp_socket_disconnect(&server_ipv4_socket, 200); + + if (status !=NX_SUCCESS) + { + test_control_return(20); + } + nx_tcp_socket_delete(&server_ipv4_socket); + + if (status !=NX_SUCCESS) + { + test_control_return(21); + } + /* All done */ + return; + +} + +/* Define the IPv6 server thread */ + +void thread_server6_entry(ULONG thread_input) +{ + +INT status; +ULONG actual_status; +NX_TCP_SOCKET server_ipv6_socket; +NX_PACKET *packet_rcv_ptr, *packet_ptr; +char *requests[2] = {"Request6_1", "Request6_2"}; +UINT ipv6_server_complete = NX_FALSE; +UINT address_index; +NXD_ADDRESS ip_address; + + + /* Check status... */ + if (error_counter) + { + printf("ERROR22!\n"); + test_control_return(22); + } + + printf("NetX Test: BSD TCP Client Socket Shared Port Test........"); + status = nx_ip_status_check(&bsd_ip_server, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + printf("ERROR23!\n"); + test_control_return(23); + } + + status = nxd_ipv6_enable(&bsd_ip_server); + + if((status != NX_SUCCESS) && (status != NX_ALREADY_ENABLED)) + { + printf("ERROR24!\n"); + test_control_return(24); + } + + /* Enable ICMPv6 */ + status = nxd_icmp_enable(&bsd_ip_server); + if(status) + { + printf("ERROR25!\n"); + test_control_return(25); + } + + /* This assumes we are using the primary network interface (index 0). */ + status = nxd_ipv6_address_set(&bsd_ip_server, 0, NX_NULL, 10, &address_index); + + if (status) + { + printf("ERROR26!\n"); + test_control_return(26); + } + + /* Set ip interface address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x20010db8; + ip_address.nxd_ip_address.v6[1] = 0x0000f101; + ip_address.nxd_ip_address.v6[2] = 0; + ip_address.nxd_ip_address.v6[3] = 0x101; + + + /* Set the host global IP address. We are assuming a 64 + bit prefix here but this can be any value (< 128). */ + status = nxd_ipv6_address_set(&bsd_ip_server, 0, &ip_address, 64, &address_index); + + if (status) + { + printf("ERROR27!\n"); + test_control_return(27); + } + + /* Wait for IPv6 stack to finish DAD process. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_create(&bsd_ip_server, &server_ipv6_socket, "Server IPv6 Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 100, NX_NULL, NX_NULL); + + if (status ) + { + printf("ERROR28!\n"); + test_control_return(28); + } + + status = nx_tcp_server_socket_listen(&bsd_ip_server, SERVER6_PORT, &server_ipv6_socket, 5, NX_NULL); + + if (status ) + { + printf("ERROR29!\n"); + test_control_return(29); + } + + status = nx_tcp_server_socket_accept(&server_ipv6_socket, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + printf("ERROR30!\n"); + test_control_return(30); + } + + while(!ipv6_server_complete) + { + + status = nx_tcp_socket_receive(&server_ipv6_socket, &packet_rcv_ptr, 500); + if(status != NX_SUCCESS) + { + if (status == NX_NOT_CONNECTED) + { + + ipv6_server_complete = NX_TRUE; + break; + } + + + printf("ERROR31!\n"); + test_control_return(31); + error_counter++; + } + + else + { + nx_packet_release(packet_rcv_ptr); + } + + status = nx_packet_allocate(&bsd_pool, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + if (status ) + { + + printf("ERROR32\n"); + test_control_return(32); + error_counter++; + } + + status = nx_packet_data_append(packet_ptr, requests[1], strlen(requests[1]), + &bsd_pool, NX_NO_WAIT); + if (status ) + { + + printf("ERROR33!\n"); + test_control_return(33); + error_counter++; + } + + status = nx_tcp_socket_send(&server_ipv6_socket, packet_ptr, 100); + + if (status) + { + nx_packet_release(packet_ptr); + + + if (status == NX_NOT_CONNECTED) + { + + ipv6_server_complete = NX_TRUE; + break; + } + + printf("ERROR34!\n"); + test_control_return(34); + error_counter++; + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 2); + } + + nx_tcp_socket_disconnect(&server_ipv6_socket, 200); + nx_tcp_socket_delete(&server_ipv6_socket); + + /* Wait for IPv4 to close down before closing down our server socket. */ + while (!ipv6_client_complete) + { + tx_thread_sleep(20); + } + + if(error_counter) + { + printf("ERROR35!\n"); + test_control_return(35); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the IPv6 Client thread. */ + +void thread_client6_entry(ULONG thread_input) +{ + +INT status; +ULONG actual_status; +INT sock6_tcp_client; +struct sockaddr_in6 echoServAddr6, echoClientAddr6; +UINT address_index; +NXD_ADDRESS ip_address; +CHAR Client_Rcv_Buffer[100]; +UINT loopcount = 0; + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 2); + + status = nx_ip_status_check(&bsd_ip_client, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + printf("ERROR36!\n"); + test_control_return(36); + } + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&bsd_ip_client); + if((status != NX_SUCCESS) && (status != NX_ALREADY_ENABLED)) + { + printf("ERROR37!\n"); + test_control_return(37); + } + + + /* Enable ICMPv6 */ + status = nxd_icmp_enable(&bsd_ip_client); + if(status) + { + printf("ERROR38!\n"); + test_control_return(38); + } + + /* This assumes we are using the primary network interface (index 0). */ + status = nxd_ipv6_address_set(&bsd_ip_client, 0, NX_NULL, 10, &address_index); + + /* Check status... */ + if (status != NX_SUCCESS) + { + printf("ERROR39!\n"); + test_control_return(39); + } + + + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x20010db8; + ip_address.nxd_ip_address.v6[1] = 0xf101; + ip_address.nxd_ip_address.v6[2] = 0; + ip_address.nxd_ip_address.v6[3] = 0x1235; + + + /* Set the host global IP address. We are assuming a 64 + bit prefix here but this can be any value (< 128). */ + status = nxd_ipv6_address_set(&bsd_ip_client, 0, &ip_address, 64, &address_index); + + if (status) + { + printf("ERROR40!\n"); + test_control_return(40); + } + + + /* Wait for IPv6 stack to finish DAD process. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + + echoClientAddr6.sin6_addr._S6_un._S6_u32[0] = htonl(0x20010db8); + echoClientAddr6.sin6_addr._S6_un._S6_u32[1] = htonl(0xf101); + echoClientAddr6.sin6_addr._S6_un._S6_u32[2] = 0x0; + echoClientAddr6.sin6_addr._S6_un._S6_u32[3] = htonl(0x1235); + echoClientAddr6.sin6_port = htons(CLIENT_PORT); + echoClientAddr6.sin6_family = AF_INET6; + + memset(&echoServAddr6, 0, sizeof(echoServAddr6)); + echoServAddr6.sin6_addr._S6_un._S6_u32[0] = htonl(0x20010db8); + echoServAddr6.sin6_addr._S6_un._S6_u32[1] = htonl(0xf101); + echoServAddr6.sin6_addr._S6_un._S6_u32[2] = 0x0; + echoServAddr6.sin6_addr._S6_un._S6_u32[3] = htonl(0x0101); + echoServAddr6.sin6_port = htons(SERVER6_PORT); + echoServAddr6.sin6_family = AF_INET6; + + + /* Now make client connections with the server. */ + while (!ipv6_client_complete) + { + + /* Create BSD TCP Socket */ + sock6_tcp_client = socket( AF_INET6, SOCK_STREAM, IPPROTO_TCP); + + if (sock6_tcp_client == ERROR) + { + printf("ERROR41!\n"); + test_control_return(41); + } + + status = bind (sock6_tcp_client, (struct sockaddr *) &echoClientAddr6, sizeof(echoClientAddr6)); + + if (status == ERROR) + { + printf("ERROR42!\n"); + test_control_return(42); + } + + /* Now connect this client to the server */ + status = connect(sock6_tcp_client, (struct sockaddr *)&echoServAddr6, sizeof(echoServAddr6)); + + /* Check for error. */ + if (status == ERROR) + { + printf("ERROR43!\n"); + test_control_return(43); + return; + + } + + /* Now receive the echoed packet from the server */ + while(loopcount < 5) + { + + send(sock6_tcp_client, "Hello", (strlen("Hello")+1), 0); + + memset(&Client_Rcv_Buffer[0], 0, 100); + status = recv(sock6_tcp_client, (VOID *)Client_Rcv_Buffer, 100, 0); + + if (status < 0) + { + + if (errno == EAGAIN) + { + continue; + } + else if (errno == ENOTCONN) + { + + break; + } + else + { + /* Another error has occurred.... */ + + + printf("ERROR44!\n"); + test_control_return(44); + error_counter++; + break; + } + + } + else if (status == 0) + { + + break; + } + + tx_thread_sleep(80 * NX_IP_PERIODIC_RATE / 100); + loopcount++; + } + + ipv6_client_complete = NX_TRUE; + + break; + } + + + /* close this client socket */ + status = soc_close(sock6_tcp_client); + + if (status != ERROR) + { + + printf("ERROR46!\n"); + test_control_return(45); + error_counter++; + } +} + + +/* Define the IPv4 Client thread. */ +void thread_client_entry(ULONG thread_input) +{ + +INT status; +UINT loopcount = 0; +ULONG actual_status; +INT sock_tcp_client; +struct sockaddr_in echoServAddr; +struct sockaddr_in echoClientAddr; +CHAR Client_Rcv_Buffer[100]; + + /* IPv4 waits for IPv6 DAD protocol */ + tx_thread_sleep(550 * NX_IP_PERIODIC_RATE / 100); + + status = nx_ip_status_check(&bsd_ip_client, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + printf("ERROR46a!\n"); + test_control_return(46); + } + + echoClientAddr.sin_family = AF_INET; + echoClientAddr.sin_port = htons(CLIENT_PORT); + echoClientAddr.sin_addr.s_addr = htonl(CLIENT_ADDRESS); + + memset(&echoServAddr, 0, sizeof(echoServAddr)); + echoServAddr.sin_family = AF_INET; + echoServAddr.sin_addr.s_addr = htonl(SERVER_ADDRESS); + echoServAddr.sin_port = htons(SERVER_PORT); + + /* Now make client connections with the server. */ + while (!ipv4_client_complete) + { + + /* Create BSD TCP Socket */ + sock_tcp_client = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (sock_tcp_client == -1) + { + printf("ERROR47!\n"); + test_control_return(47); + } + + status = bind (sock_tcp_client, (struct sockaddr *) &echoClientAddr, sizeof(echoClientAddr)); + + if (status < 0) + { + printf("ERROR%d!\n", errno); + test_control_return(48); + } + + /* Now connect this client to the server */ + status = connect(sock_tcp_client, (struct sockaddr *)&echoServAddr, sizeof(echoServAddr)); + + /* Check for error. */ + if (status != OK) + { + printf("ERROR49!\n"); + test_control_return(49); + } + + /* Now receive the echoed packet from the server */ + while(loopcount < 5) + { + + status = send(sock_tcp_client, "Hello from Client4", (strlen("Hello from Client4")+1), 0); + + if (status == ERROR) + { + + printf("ERROR50!\n"); + test_control_return(50); + error_counter++; + } + + memset(&Client_Rcv_Buffer[0], 0, 100); + status = recv(sock_tcp_client, (VOID *)Client_Rcv_Buffer, 100, 0); + + if (status < 0) + { + + if (errno == EAGAIN) + { + continue; + } + else if (errno == ENOTCONN) + { + break; + } + else + { + /* Another error has occurred.... */ + + printf("ERROR51!\n"); + test_control_return(51); + error_counter++; + break; + } + + } + else if (status == 0) + { + + break; + } + tx_thread_sleep(80 * NX_IP_PERIODIC_RATE / 100); + loopcount++; + } + + ipv4_client_complete = NX_TRUE; + } + + /* close this client socket */ + status = soc_close(sock_tcp_client); + + if (status == ERROR) + { + + printf("ERROR53!\n"); + test_control_return(53); + error_counter++; + } + + /* All done */ + return; +} +#else /* FEATURE_NX_IPV6 */ + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_clients_share_port_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: BSD TCP Client Socket Shared Port Test........N/A\n"); + + test_control_return(3); + +} + +#endif /* FEATURE_NX_IPV6 */ + + + + diff --git a/test/regression/bsd_test/netx_bsd_tcp_clients_shared_port_test.c b/test/regression/bsd_test/netx_bsd_tcp_clients_shared_port_test.c new file mode 100644 index 00000000..6ae1f9e0 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_clients_shared_port_test.c @@ -0,0 +1,585 @@ +/* This demonstrates sharing a port between an IPv4 and IPv6 TCP client socket to send + and receive packets (e.g emulates a socket that can send/receive iPv4 and Ipv6 packets) + using a simulated Ethernet driver. */ + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) && defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nxd_bsd.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; +static NX_PACKET_POOL bsd_pool; +static NX_IP bsd_server_ip; +static NX_IP bsd_client_ip; +static NX_TCP_SOCKET server_socket1; +static NX_TCP_SOCKET server_socket2; + +static UINT error_counter = 0; + +#define CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define CLIENT_PORT 87 + + +static char *requests[2] = {"Request1", "Request2"}; +static char *responses[2] = {"Response1", "Response2"}; +static UINT spin = NX_TRUE; + +/* Define thread prototypes. */ + +static VOID thread_client_entry(ULONG thread_input); +static VOID thread_server_entry(ULONG thread_input); +void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_clients_shared_port_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a BSD packet pool. */ + status = nx_packet_pool_create(&bsd_pool, "NetX BSD Packet Pool", 256, pointer, 16384); + + pointer = pointer + 16384; + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /********************** Set up the Server IP instance **************************/ + + /* Create a thread for server. */ + status= tx_thread_create(&thread_server, "BSD App Server", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /* Create an IP instance for the BSD Server. */ + status = nx_ip_create(&bsd_server_ip, "NetX BSD Server", SERVER_ADDRESS, 0xFFFFFF00UL, + &bsd_pool, _nx_ram_network_driver, pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&bsd_server_ip); + + /* Enable ARP and supply ARP cache memory for BSD Server Instance */ + status += nx_arp_enable(&bsd_server_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + { + error_counter++; + } + + pointer = pointer + 2048; + + /********************** Set up the Client IP instance **************************/ + + /* Create a thread for client. */ + status= tx_thread_create(&thread_client, "BSD App Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /* Create an IP instance for the BSD Client. */ + status = nx_ip_create(&bsd_client_ip, "NetX BSD Client", CLIENT_ADDRESS, 0xFFFFFF00UL, + &bsd_pool, _nx_ram_network_driver, pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&bsd_client_ip); + + /* Enable ARP and supply ARP cache memory for BSD Client Instance */ + status += nx_arp_enable(&bsd_client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + { + error_counter++; + } + + /* Now initialize BSD Client IP. */ + status = bsd_initialize (&bsd_client_ip, &bsd_pool, pointer, 2048, 4); + + /* Check for BSD errors. */ + if (status) + { + error_counter++; + } + + return; +} + + + +void thread_client_entry(ULONG thread_input) +{ + +INT status, sock_tcp_client, sock_tcp_client6; +struct sockaddr_in echoClientAddr; +struct sockaddr_in echoServAddr; +struct sockaddr_in localAddr; +struct sockaddr_in6 echoServAddr6; +struct sockaddr_in6 echoClientAddr6; +struct sockaddr_in6 localAddr6; +NXD_ADDRESS ip_address; +UINT address_index; +UINT loopcount = 0; +CHAR rcvBuffer[32]; +INT length; + + + printf("NetX Test: Basic BSD TCP Client Socket Shared Port Test............"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + memset(&echoClientAddr, 0, sizeof(echoClientAddr)); + + memset(&echoClientAddr6, 0, sizeof(echoClientAddr6)); + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&bsd_client_ip); + if(status) + { + printf("ERROR!\n"); + error_counter++; + } + + /* Enable ICMPv6 */ + status = nxd_icmp_enable(&bsd_client_ip); + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set ip_0 interface address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x20010db8; + ip_address.nxd_ip_address.v6[1] = 0xf101; + ip_address.nxd_ip_address.v6[2] = 0; + ip_address.nxd_ip_address.v6[3] = 0x1235; + + status = nxd_ipv6_address_set(&bsd_client_ip, 0, NX_NULL, 10, &address_index); + + status |= nxd_ipv6_address_set(&bsd_client_ip, 0, &ip_address, 64, &address_index); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for IPv6 stack to finish DAD process. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + echoClientAddr6.sin6_addr._S6_un._S6_u32[0] = htonl(0x20010db8); + echoClientAddr6.sin6_addr._S6_un._S6_u32[1] = htonl(0xf101); + echoClientAddr6.sin6_addr._S6_un._S6_u32[2] = 0x0; + echoClientAddr6.sin6_addr._S6_un._S6_u32[3] = htonl(0x1235); + echoClientAddr6.sin6_port = htons(CLIENT_PORT); + echoClientAddr6.sin6_family = AF_INET6; + + + echoServAddr6.sin6_addr._S6_un._S6_u32[0] = htonl(0x20010db8); + echoServAddr6.sin6_addr._S6_un._S6_u32[1] = htonl(0xf101); + echoServAddr6.sin6_addr._S6_un._S6_u32[2] = 0x0; + echoServAddr6.sin6_addr._S6_un._S6_u32[3] = htonl(0x1234); + echoServAddr6.sin6_port = htons(77); + echoServAddr6.sin6_family = AF_INET6; + + /* Create BSD TCP IPv6 Client Socket */ + sock_tcp_client6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + + if (sock_tcp_client6 == -1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create BSD TCP IPv4 Client Socket */ + sock_tcp_client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (sock_tcp_client == -1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + echoClientAddr.sin_family = AF_INET; + echoClientAddr.sin_port = htons(CLIENT_PORT); + echoClientAddr.sin_addr.s_addr = htonl(CLIENT_ADDRESS); + + + echoServAddr.sin_family = AF_INET; + echoServAddr.sin_port = htons(76); + echoServAddr.sin_addr.s_addr = htonl(SERVER_ADDRESS); + + /* Bind the IPv4 and IPv6 Client sockets. */ + status = bind (sock_tcp_client, (struct sockaddr *) &echoClientAddr, sizeof(echoClientAddr)); + status |= bind (sock_tcp_client6, (struct sockaddr *) &echoClientAddr6, sizeof(echoClientAddr6)); + if (status < 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now connect to TCP server socket. */ + status = connect(sock_tcp_client, (struct sockaddr *)&echoServAddr, sizeof(echoServAddr)); + if (status < 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + length = sizeof(localAddr); + status = getsockname(sock_tcp_client, (struct sockaddr *)&localAddr, &length); + if (localAddr.sin_port != htons(CLIENT_PORT)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = connect(sock_tcp_client6, (struct sockaddr *)&echoServAddr6, sizeof(echoServAddr6)); + if (status < 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + length = sizeof(localAddr6); + status = getsockname(sock_tcp_client6, (struct sockaddr *)&localAddr6, &length); + if (localAddr6.sin6_port != htons(CLIENT_PORT)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* All set to accept client connections */ + + /* Loop to handle IPv4 and IPv6 clients*/ + while(loopcount < 5) + { + + /* Send data to server connected to specified client. This demo assumes the + server will receive and send in order of server #1 and server #2. This is + ok since we only need to establish that BSD can emulate a socket that sends + and receives IPv4 packets. */ + status = send(sock_tcp_client, requests[0], strlen(requests[0]), 0); + + if (status == ERROR) + { + error_counter++; + } + + + /* Send data to server connected to specified client. */ + status = send(sock_tcp_client6, requests[1], strlen(requests[1]), 0); + + if (status == ERROR ) + { + error_counter++; + } + status = recv(sock_tcp_client, (VOID *)rcvBuffer, 32, 0); + if (status == ERROR) + { + error_counter++; + } + + status = recv(sock_tcp_client6, (VOID *)rcvBuffer, 32, 0); + if (status == ERROR) + { + error_counter++; + } + + loopcount++; + } + + /* Stop the Server thread. */ + spin = NX_FALSE; + + /* Close down our sockets. */ + soc_close(sock_tcp_client); + soc_close(sock_tcp_client6); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(loopcount != 5) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +/* Define the Server thread. */ + +void thread_server_entry(ULONG thread_input) +{ + +INT status; +NXD_ADDRESS server_ip_address; +UINT address_index; +NX_PACKET *packet_ptr4, *packet_ptr3, *packet_ptr2, *packet_ptr; + + + /* Allow Netx to initialize the driver. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE / 5); + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&bsd_server_ip); + if(status) + test_control_return(1); + + /* Enable ICMPv6 */ + status = nxd_icmp_enable(&bsd_server_ip); + if(status) + test_control_return(1); + + /* Set Client IPv6 interface address. */ + server_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + server_ip_address.nxd_ip_address.v6[0] = 0x20010db8; + server_ip_address.nxd_ip_address.v6[1] = 0x0000f101; + server_ip_address.nxd_ip_address.v6[2] = 0; + server_ip_address.nxd_ip_address.v6[3] = 0x1234; + + status = nxd_ipv6_address_set(&bsd_server_ip, 0, NX_NULL, 10, &address_index); + + status |= nxd_ipv6_address_set(&bsd_server_ip, 0, &server_ip_address, 64, &address_index); + if (status) + test_control_return(1); + + /* Time for duplicate address check. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set Server IPv6 interface address. */ + server_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + server_ip_address.nxd_ip_address.v6[0] = 0x20010db8; + server_ip_address.nxd_ip_address.v6[1] = 0x0000f101; + server_ip_address.nxd_ip_address.v6[2] = 0; + server_ip_address.nxd_ip_address.v6[3] = 0x1234; + + status = nx_tcp_socket_create(&bsd_server_ip, &server_socket1, "Server IPv4 Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 100, NX_NULL, NX_NULL); + + status += nx_tcp_socket_create(&bsd_server_ip, &server_socket2, "Server IPv6 Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 100, NX_NULL, NX_NULL); + + if (status ) + { + test_control_return(1); + } + + status = nx_tcp_server_socket_listen(&bsd_server_ip, 76, &server_socket1, 5, NX_NULL); + status += nx_tcp_server_socket_listen(&bsd_server_ip, 77, &server_socket2, 5, NX_NULL); + + if (status ) + { + test_control_return(1); + } + + status = nx_tcp_server_socket_accept(&server_socket1, 4 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_tcp_server_socket_accept(&server_socket2, 4 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + while(spin) + { + + status = nx_tcp_socket_receive(&server_socket1, &packet_ptr3, 4 * NX_IP_PERIODIC_RATE); + + /* Check if the Client terminated the connection. */ + if (spin!= NX_TRUE) + { + /* It did, so let's bail. */ + break; + } + + /* Otherwise we expect a packet. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + nx_packet_release(packet_ptr3); + } + + status = nx_tcp_socket_receive(&server_socket2, &packet_ptr4, 4 * NX_IP_PERIODIC_RATE); + + /* Check if the Client terminated the connection. */ + if (spin!= NX_TRUE) + { + /* It did, so let's bail. */ + break; + } + + /* Here we expect a packet. */ + if(status != NX_SUCCESS) + { + error_counter++; + } + else + { + nx_packet_release(packet_ptr4); + } + + status = nx_packet_allocate(&bsd_pool, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + if (status) + { + + /* No packets available. Abort! */ + + printf("ERROR!\n"); + test_control_return(1); + } + status = nx_packet_data_append(packet_ptr, responses[0], strlen(responses[0]), + &bsd_pool, NX_NO_WAIT); + if (status) + { + test_control_return(1); + } + + status = nx_packet_allocate(&bsd_pool, &packet_ptr2, NX_TCP_PACKET, NX_NO_WAIT); + if (status) + { + /* No packets available. Abort! */ + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(packet_ptr2, responses[1], strlen(responses[1]), + &bsd_pool, NX_NO_WAIT); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_tcp_socket_send(&server_socket1, packet_ptr, NX_IP_PERIODIC_RATE); + + if (status ) + { + error_counter++; + nx_packet_release(packet_ptr2); + } + + status = nx_tcp_socket_send(&server_socket2, packet_ptr2, NX_IP_PERIODIC_RATE); + + if (status ) + { + nx_packet_release(packet_ptr2); + error_counter++; + } + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + nx_tcp_socket_delete(&server_socket1); + nx_tcp_socket_delete(&server_socket2); + + /* All done */ + return; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_clients_shared_port_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Client Socket Shared Port Test............N/A"); + + test_control_return(3); + +} +#endif /* defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) */ + + + + diff --git a/test/regression/bsd_test/netx_bsd_tcp_disconnect_test.c b/test/regression/bsd_test/netx_bsd_tcp_disconnect_test.c new file mode 100644 index 00000000..5c95e666 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_disconnect_test.c @@ -0,0 +1,576 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 1024 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static TX_THREAD ntest_2; +static TX_THREAD ntest_3; +static TX_THREAD ntest_4; +static TX_THREAD ntest_5; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +#define BSD_THREAD_PRIORITY 2 +/* Define the counters used in the test application... */ +#define NUM_ITERATION 3000 +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (100) / 4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_2_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; + +static char *send_buffer = "Hello World"; +typedef struct helper_thread_block_struct +{ + ULONG stack_space[DEMO_STACK_SIZE / sizeof(ULONG)]; + TX_THREAD helper_thread; +} HELPER_THREAD_BLOCK; + +static HELPER_THREAD_BLOCK *helper_thread_block_ptr; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_disconnect_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 2, 2, 1, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 2, 2, 1, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Create the main thread. */ + tx_thread_create(&ntest_2, "client thread 1", ntest_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 2, 2, 1, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_3, "client thread 2", ntest_2_entry, 1, + pointer, DEMO_STACK_SIZE, + 2, 2, 1, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_4, "client thread 3", ntest_2_entry, 2, + pointer, DEMO_STACK_SIZE, + 2, 2, 1, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_5, "client thread 4", ntest_2_entry, 3, + pointer, DEMO_STACK_SIZE, + 2, 2, 1, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + helper_thread_block_ptr = (HELPER_THREAD_BLOCK*)pointer; + pointer += sizeof(HELPER_THREAD_BLOCK) * 10; + + memset(helper_thread_block_ptr, 0, sizeof(HELPER_THREAD_BLOCK) * 10); + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + if(status) + error_counter++; +} + +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd; +char buf[30]; + + sockfd = thread_input; + + /* Receive data from the client. */ + ret = recv(sockfd, buf, sizeof(buf), 0); + if(ret < 0) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + tx_semaphore_put(&sema_0); +} + + +static void test_tcp_client4(void) +{ +int sockfd; +struct sockaddr_in remote_addr; +int bytes_sent; +int ret; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + { + error_counter++; + return; + } + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0) + error_counter++; + else + { + bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0); + + if(bytes_sent != (int)strlen(send_buffer)) + error_counter++; + } + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i, j; +UINT status; +HELPER_THREAD_BLOCK *helper_thread_ptr; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + for(i = 0; i < 4; i++) + tx_semaphore_put(&sema_1); + + /* 3 iterations. */ + for(i = 0; i < NUM_ITERATION; i++) + { + address_length = sizeof(remote_addr); + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + error_counter++; + + if(address_length != sizeof(remote_addr)) + error_counter++; + + if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + + + for(j = 0; j < 10; j++) + { + helper_thread_ptr = (HELPER_THREAD_BLOCK *)((UINT)helper_thread_block_ptr + sizeof(HELPER_THREAD_BLOCK) * j); + + if((helper_thread_ptr -> helper_thread.tx_thread_id == 0) || + (helper_thread_ptr -> helper_thread.tx_thread_state == TX_COMPLETED)) + { + + if(helper_thread_ptr -> helper_thread.tx_thread_state == TX_COMPLETED) + { + tx_thread_delete(&(helper_thread_ptr -> helper_thread)); + } + status = tx_thread_create(&helper_thread_ptr -> helper_thread, "helper thread", bsd_server_helper_thread_entry, + newsock, &helper_thread_ptr -> stack_space[0], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status != TX_SUCCESS) + error_counter++; + + tx_thread_relinquish(); + break; + } + } + } + /* Close down the socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_ITERATION; i++) + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); +} + + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +int iterations = 0; +int i; + + + printf("NetX Test: Basic BSD TCP Disconnect Test................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + for(iterations = 0; iterations < NUM_ITERATION; iterations++) + { + test_tcp_client4(); + } + + tx_thread_resume(&ntest_2); + tx_thread_resume(&ntest_3); + tx_thread_resume(&ntest_4); + tx_thread_resume(&ntest_5); + + test_tcp_server4(); + + for(i = 0; i < 4; i++) + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static NX_TCP_SOCKET tcp_sockets[4]; +static void nx_client4(int thread_input) +{ +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[thread_input], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[thread_input], NX_ANY_PORT, 0); + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + status = nx_tcp_client_socket_connect(&tcp_sockets[thread_input], IP_ADDRESS(1, 2, 3, 4), 12345, 1 * NX_IP_PERIODIC_RATE); + + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + +#if 0 + tx_thread_sleep(10 * NX_IP_PERIODIC_RATE); +#endif + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, send_buffer, strlen(send_buffer), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[thread_input], packet_ptr, NX_IP_PERIODIC_RATE); + + + if(status != NX_SUCCESS) + error_counter++; +#if 0 + status = NX_SUCCESS; + + status = nx_tcp_socket_receive(&tcp_sockets[thread_input], &packet_ptr, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(send_buffer)) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, send_buffer, packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); +#endif + status = nx_tcp_socket_disconnect(&tcp_sockets[thread_input], 1 * NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[thread_input].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[thread_input]); + + + status += nx_tcp_socket_delete(&tcp_sockets[thread_input]); + + if(status != NX_SUCCESS) + error_counter++; +} +static NX_TCP_SOCKET server_socket; +static void netx_tcp_server(void) +{ + +NX_PACKET *packet_ptr; +UINT status; +int i; + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + for(i = 0; i < NUM_ITERATION; i++) + { + tx_semaphore_put(&sema_0); + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != strlen(send_buffer))) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, send_buffer, strlen(send_buffer))) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + if (status && (status != NX_CONNECTION_PENDING)) + error_counter++; + } + + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + nx_tcp_socket_delete(&server_socket); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + netx_tcp_server(); + +} + +static void ntest_2_entry(ULONG thread_input) +{ +int iterations = 0; + + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + /* Simulate a multiple client conneting to the same server. */ + for(iterations = 0; iterations < (NUM_ITERATION / 4); iterations++) + nx_client4(thread_input); + + tx_semaphore_put(&sema_0); +} + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_disconnect_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Disconnect Test.................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_fionread_test.c b/test/regression/bsd_test/netx_bsd_tcp_fionread_test.c new file mode 100644 index 00000000..52fd72cc --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_fionread_test.c @@ -0,0 +1,423 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS NX_BSD_MAX_SOCKETS +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +static char request[] = "Test_Request"; +static char response[] = "Test_Response"; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_fionread_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + if(status) + error_counter++; +} +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data; +static ULONG stack_space[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread; + +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +char buf[30] = {0}; +int size; + + sockfd = client_data.sockfd; + message_id = client_data.message_id; + + /* Receive data from the client. */ + ret = recv(sockfd, buf, 4, 0); + if(ret != 4) + error_counter++; + + ret = ioctl(sockfd, FIONREAD, &size); + if(ret) + error_counter++; + + ret = recv(sockfd, buf + 4, sizeof(buf) - 4, 0); + if(ret != size) + error_counter++; + + /* Validate the data. */ + if((ret + 4) != (int)strlen(request) || strncmp(buf, request, (ret + 4))) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response, strlen(response), 0); + if(ret != (int)strlen(response)) + error_counter++; + + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret) + error_counter++; + + tx_semaphore_put(&sema_0); + return; +} + + + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +UINT status; +int accept_no_memory = 0; + + + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret) + error_counter++; + + ret = listen(sockfd, 5); + if(ret) + error_counter++; + + address_length = sizeof(remote_addr); + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + { + error_counter++; + } + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + + /* Set the client data */ + client_data.sockfd = newsock; + client_data.message_id = 0; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_thread, "helper thread", bsd_server_helper_thread_entry, + 0, stack_space, DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status != TX_SUCCESS) + error_counter++; + + tx_thread_relinquish(); + + /* Close down the socket. */ + ret = soc_close(sockfd); + if(ret) + error_counter++; + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ + + printf("NetX Test: Basic BSD TCP FIONREAD Test..................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wakeup client. */ + tx_semaphore_put(&sema_1); + + test_tcp_server4(); + + /* Wait until client finish. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static NX_TCP_SOCKET tcp_socket; +static void multiple_client4(void) +{ + +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + + status = nx_tcp_socket_create(&ip_1, &tcp_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_socket, NX_ANY_PORT, 0); + + if(status != NX_SUCCESS) + error_counter++; + + status = nx_tcp_client_socket_connect(&tcp_socket, IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + + if(status != NX_SUCCESS) + error_counter++; + + /* Send messages to each server */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, request, strlen(request), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_socket, packet_ptr, NX_IP_PERIODIC_RATE); + + if(status != NX_SUCCESS) + error_counter++; + + /* Receive messages. */ + status = nx_tcp_socket_receive(&tcp_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response)) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response, packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + + /* Shutdown the socket. */ + status = nx_tcp_socket_disconnect(&tcp_socket, 1 * NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_socket.nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_socket); + + + status += nx_tcp_socket_delete(&tcp_socket); + + if(status != NX_SUCCESS) + error_counter++; +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + /* Simulate a multiple client conneting to the same server. */ + multiple_client4(); + + /* Client finished. */ + tx_semaphore_put(&sema_0); +} + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_fionread_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP FIONREAD Test...................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_getsockname_test.c b/test/regression/bsd_test/netx_bsd_tcp_getsockname_test.c new file mode 100644 index 00000000..559c3d3f --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_getsockname_test.c @@ -0,0 +1,454 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 1 +/* Define the counters used in the test application... */ +static void *server1_stack_area; +static void *server2_stack_area; +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_getsockname_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + server1_stack_area = pointer; + server2_stack_area = pointer + DEMO_STACK_SIZE; + pointer = (void*)((ULONG)server2_stack_area + DEMO_STACK_SIZE); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[4]; +static ULONG stack_space[4][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[4]; + +static TX_THREAD tcp_server1, tcp_server2; +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +char buf[30]; + + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + ret = recv(sockfd, buf, sizeof(buf), 0); + if(ret <= 0) + error_counter++; + + buf[ret] = 0; + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || (strncmp(buf, requests[message_id & 3], ret))) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0); + if(ret != (int)strlen(response[message_id & 3])) + error_counter++; + + tx_thread_sleep(1); + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + return; +} + +static NX_TCP_SOCKET client_socket; + +static void start_tcp_client4(int port) +{ +UINT status; +NX_PACKET *packet_ptr; + + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", NX_IP_NORMAL, + NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, 0); + if(status != NX_SUCCESS) + error_counter++; + + + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1,2,3,4), port, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + if(status) + error_counter++; + + if(port == 12345) + status = nx_packet_data_append(packet_ptr, requests[0], strlen(requests[0]), &pool_0, NX_NO_WAIT); + else + status = nx_packet_data_append(packet_ptr, requests[1], strlen(requests[1]), &pool_0, NX_NO_WAIT); + + if(status) + error_counter++; + + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + status = nx_tcp_socket_receive(&client_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + else if(port == 12345) + { + if((packet_ptr -> nx_packet_length != strlen(response[0])) || + (strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], packet_ptr -> nx_packet_length))) + error_counter++; + nx_packet_release(packet_ptr); + } + else + { + if((packet_ptr -> nx_packet_length != strlen(response[1])) || + (strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[1], packet_ptr -> nx_packet_length))) + error_counter++; + nx_packet_release(packet_ptr); + } + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + if(client_socket.nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&client_socket); + + status += nx_tcp_socket_delete(&client_socket); + if(status) + error_counter++; +} +static void tcp_server_entry(ULONG); +static void start_tcp_server4(void) +{ +UINT status; + status = tx_thread_create(&tcp_server1, "tcp server1", tcp_server_entry, 12345, + server1_stack_area, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, + TX_AUTO_START); +#if 1 + status += tx_thread_create(&tcp_server2, "tcp server2", tcp_server_entry, 12346, + server2_stack_area, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, + TX_AUTO_START); +#endif + if(status) + error_counter++; + +} + +static void tcp_server_entry(ULONG param) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i, j; +UINT status; +int port = (int)param; + + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(port); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + for(j = 0; j < 2; j++) + { + address_length = sizeof(remote_addr); + + if(port == 12345) + i = 0; + else + i = 1; + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + + /* Set the client data */ + client_data[j * 2 + i].sockfd = newsock; + client_data[j * 2 + i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_thread[j*2 + i], "helper thread", bsd_server_helper_thread_entry, + j * 2 + i, stack_space[j*2 + i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + + if(status != TX_SUCCESS) + error_counter++; + } + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +char mac_ip0[6]; +char mac_ip1[6]; +UINT status; +#endif + + + + printf("NetX Test: BSD TCP getsockname Test......................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + + start_tcp_server4(); + + tx_thread_sleep(2); + + start_tcp_client4(12345); + + start_tcp_client4(12346); + + start_tcp_client4(12345); + + start_tcp_client4(12346); + + tx_thread_sleep(10); + + validate_bsd_structure(); + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_getsockname_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: BSD TCP getsockname Test......................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_getsockname_without_bind_test.c b/test/regression/bsd_test/netx_bsd_tcp_getsockname_without_bind_test.c new file mode 100644 index 00000000..62752fbb --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_getsockname_without_bind_test.c @@ -0,0 +1,335 @@ +/* This NetX test verifies the issue report by JIRA: https://expresslogic.atlassian.net/projects/NETXDUO/issues/NETXDUO-223. */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 10 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; +static ULONG client_ip; +static ULONG client_port; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +static void validate_bsd_structure(void); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_getsockname_without_bind_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + +static void ntest_0_entry(ULONG thread_input) +{ +int ret; +int sockfd; +int address_length; +struct sockaddr_in remote_addr; +struct sockaddr_in local_addr; + + printf("NetX Test: Basic BSD TCP getsockname Without Bind Test..."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + /* Connect to port not listening. */ + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) >= 0) + error_counter++; + + address_length = sizeof(local_addr); + ret = getsockname(sockfd, (struct sockaddr*)&local_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(local_addr)) + error_counter++; + else if(local_addr.sin_family != AF_INET) + error_counter++; + else if(local_addr.sin_port == 0) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + /* Connect to port that is listening. */ + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0) + error_counter++; + + address_length = sizeof(local_addr); + ret = getsockname(sockfd, (struct sockaddr*)&local_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(local_addr)) + error_counter++; + else if(local_addr.sin_family != AF_INET) + error_counter++; + else if(local_addr.sin_port != htons(client_port)) + error_counter++; + else if(local_addr.sin_addr.s_addr != htonl(client_ip)) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + validate_bsd_structure(); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + status = nx_tcp_socket_peer_info_get(&server_socket, &client_ip, &client_port); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + nx_tcp_socket_delete(&server_socket); +} + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_getsockname_without_bind_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP getsockname Without Bind Test...N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_multiple_accept_test.c b/test/regression/bsd_test/netx_bsd_tcp_multiple_accept_test.c new file mode 100644 index 00000000..18a5a5fe --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_multiple_accept_test.c @@ -0,0 +1,552 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + +#define notify(v) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 1 +/* Define the counters used in the test application... */ +static void *server1_stack_area; +static void *server2_stack_area; +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; +static TX_SEMAPHORE session_start[4], session_end[4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_multiple_accept_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + { + notify(status); + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + { + notify(status); + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + { + notify(status); + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + { + notify(status); + error_counter++; + } + + server1_stack_area = pointer; + server2_stack_area = pointer + DEMO_STACK_SIZE; + pointer = (void*)((ULONG)server2_stack_area + DEMO_STACK_SIZE); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + status = tx_semaphore_create(&session_start[0], "0", 0); + status += tx_semaphore_create(&session_start[1], "1", 0); + status += tx_semaphore_create(&session_start[2], "2", 0); + status += tx_semaphore_create(&session_start[3], "3", 0); + status = tx_semaphore_create(&session_end[0], "4", 0); + status += tx_semaphore_create(&session_end[1], "5", 0); + status += tx_semaphore_create(&session_end[2], "6", 0); + status += tx_semaphore_create(&session_end[3], "7", 0); + if(status != TX_SUCCESS) + error_counter++; + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + { + notify(status); + error_counter++; + } +} +typedef struct client_info_struct +{ + int sockfd; + int message_id; + int port_number; +} client_info; + +static client_info client_data[4] = { + {0, 0, 12345}, + {0, 0, 12345}, + {0, 0, 12346}, + {0, 0, 12346}, +}; +static ULONG stack_space[4][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[4]; + +static TX_THREAD tcp_server1, tcp_server2; +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +char buf[30]; + + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + ret = recv(sockfd, buf, sizeof(buf), 0); + if (ret <= 0) + { + error_counter++; + } + + buf[ret] = 0; + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || (strncmp(buf, requests[message_id & 3], ret))) + { + error_counter++; + } + + /* Send a response back. */ + ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0); + if(ret != (int)strlen(response[message_id & 3])) + { + error_counter++; + } + + tx_semaphore_get(&session_end[thread_input], NX_WAIT_FOREVER); + ret = soc_close(sockfd); + if(ret < 0) + { + error_counter++; + } + + return; +} + +static NX_TCP_SOCKET client_socket; + +static void start_tcp_client4(int index) +{ +UINT status; +NX_PACKET *packet_ptr; + + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", NX_IP_NORMAL, + NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, 0); + if(status != NX_SUCCESS) + { + error_counter++; + } + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1,2,3,4), client_data[index].port_number, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + notify(status); + error_counter++; + } + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + if(status) + { + notify(status); + error_counter++; + } + + if(client_data[index].port_number == 12345) + status = nx_packet_data_append(packet_ptr, requests[0], strlen(requests[0]), &pool_0, NX_NO_WAIT); + else + status = nx_packet_data_append(packet_ptr, requests[1], strlen(requests[1]), &pool_0, NX_NO_WAIT); + + if(status) + { + notify(status); + error_counter++; + } + + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE); + + if(status) + { + notify(status); + error_counter++; + } + + status = nx_tcp_socket_receive(&client_socket, &packet_ptr, NX_WAIT_FOREVER); + if(status) + { + notify(status); + error_counter++; + } + else if(client_data[index].port_number == 12345) + { + if((packet_ptr -> nx_packet_length != strlen(response[0])) || + (strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], packet_ptr -> nx_packet_length))) + error_counter++; + nx_packet_release(packet_ptr); + } + else + { + if((packet_ptr -> nx_packet_length != strlen(response[1])) || + (strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[1], packet_ptr -> nx_packet_length))) + { + notify(status); + error_counter++; + } + + nx_packet_release(packet_ptr); + } + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + if(client_socket.nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&client_socket); + + tx_semaphore_put(&session_end[index]); + + status += nx_tcp_socket_delete(&client_socket); + if(status) + { + notify(status); + error_counter++; + } +} + +static void tcp_server_entry(ULONG); +static void start_tcp_server4(void) +{ +UINT status; + status = tx_thread_create(&tcp_server1, "tcp server1", tcp_server_entry, 12345, + server1_stack_area, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, + TX_AUTO_START); +#if 1 + status += tx_thread_create(&tcp_server2, "tcp server2", tcp_server_entry, 12346, + server2_stack_area, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, + TX_AUTO_START); +#endif + if(status) + { + notify(status); + error_counter++; + } + +} + +static void tcp_server_entry(ULONG param) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i, j, index; +UINT status; +int port = (int)param; + + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + { + notify(status); + error_counter++; + } + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(port); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + { + notify(status); + error_counter++; + } + + ret = listen(sockfd, 5); + if(ret < 0) + { + notify(status); + error_counter++; + } + + for(j = 0; j < 2; j++) + { + address_length = sizeof(remote_addr); + + if(port == 12345) + i = 0; + else + i = 1; + + index = 2 * i + j; + tx_semaphore_put(&session_start[index]); + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + { + notify(status); + error_counter++; + } + + if(address_length != sizeof(remote_addr)) + { + notify(status); + error_counter++; + } + + if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + { + notify(status); + error_counter++; + } + + /* Set the client data */ + client_data[index].sockfd = newsock; + client_data[index].message_id = i; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_thread[index], "helper thread", bsd_server_helper_thread_entry, + index, stack_space[index], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + + if(status != TX_SUCCESS) + { + notify(status); + error_counter++; + } + } + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + { + notify(status); + error_counter++; + } + +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +char mac_ip0[6]; +char mac_ip1[6]; +UINT status; +#endif + + + + printf("NetX Test: Basic BSD TCP Multiple Accept Test............"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + { + notify(status); + error_counter++; + } +#endif + + start_tcp_server4(); + + tx_semaphore_get(&session_start[0], NX_WAIT_FOREVER); + start_tcp_client4(0); + + tx_semaphore_get(&session_start[1], NX_WAIT_FOREVER); + start_tcp_client4(1); + + tx_semaphore_get(&session_start[2], NX_WAIT_FOREVER); + start_tcp_client4(2); + + tx_semaphore_get(&session_start[3], NX_WAIT_FOREVER); + start_tcp_client4(3); + + validate_bsd_structure(); + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_multiple_accept_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Multiple Accept Test............N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_rcvbuf_test.c b/test/regression/bsd_test/netx_bsd_tcp_rcvbuf_test.c new file mode 100644 index 00000000..773569f9 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_rcvbuf_test.c @@ -0,0 +1,1117 @@ +/* This NetX test concentrates on the basic BSD TCP window size when window scaling is used. + * JIRA: https://expresslogic.atlassian.net/browse/NETXDUO-284 */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) && defined(NX_ENABLE_TCP_WINDOW_SCALING) && defined(__PRODUCT_NETXDUO__) +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 10 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif +static char *send_buffer = "Hello World"; +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +#ifdef __PRODUCT_NETXDUO__ +static char large_msg[1000]; +#endif +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_rcvbuf_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + if(status) + error_counter++; +} +typedef struct client_info_struct +{ + int sockfd; + int message_id; +} client_info; + +static client_info client_data[NUM_CLIENTS]; +static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread[NUM_CLIENTS]; +#ifdef FEATURE_NX_IPV6 +static ULONG stack_space6[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_THREAD helper_thread6[NUM_CLIENTS]; +#endif +static VOID bsd_server_helper_thread_entry(ULONG thread_input) +{ +int ret; +int sockfd, message_id; +char buf[30]; +int sockaddr_len; +fd_set read_fds, write_fds, except_fds; +struct timeval wait_time; +#ifdef FEATURE_NX_IPV6 +struct sockaddr_in6 remote_address; +#else +struct sockaddr_in remote_address; +#endif + + sockfd = client_data[thread_input].sockfd; + message_id = client_data[thread_input].message_id; + /* Receive data from the client. */ + if(message_id == 2) + { +#ifdef FEATURE_NX_IPV6 + sockaddr_len = sizeof(struct sockaddr_in6); +#else + sockaddr_len = sizeof(struct sockaddr_in); +#endif + ret = recvfrom(sockfd, (char*)buf, sizeof(buf), 0, (struct sockaddr*)&remote_address, &sockaddr_len); + + if(ret < 0) + error_counter++; + if(nx_bsd_socket_array[sockfd - 0x20].nx_bsd_socket_family == AF_INET) + { + if(sockaddr_len != sizeof(struct sockaddr_in)) + error_counter++; + if(((struct sockaddr_in*)&remote_address) -> sin_family != AF_INET) + error_counter++; + if(((struct sockaddr_in*)&remote_address) -> sin_addr.s_addr != htonl(0x01020305)) + error_counter++; + } +#ifdef FEATURE_NX_IPV6 + else if(nx_bsd_socket_array[sockfd - 0x20].nx_bsd_socket_family == AF_INET6) + { + if(sockaddr_len != sizeof(struct sockaddr_in6)) + error_counter++; + if((remote_address.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_address.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_address.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_address.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + } +#endif + } + else + { + + /* Peek message test. */ + ret = recv(sockfd, buf, sizeof(buf), MSG_PEEK); + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret)) + error_counter++; + + ret = recv(sockfd, buf, sizeof(buf), 0); + } + if(ret <= 0) + error_counter++; + + /* Validate the data. */ + if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret)) + error_counter++; + + /* Invoke recvfrom with MSG_DONTWAIT flag. */ + ret = recvfrom(sockfd, (char*)buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*)&remote_address, &sockaddr_len); + if(ret >= 0) + error_counter++; + else if((errno != EWOULDBLOCK) || (errno != EAGAIN)) + error_counter++; + + /* Invoke recv with MSG_DONTWAIT flag. */ + ret = recv(sockfd, (char*)buf, sizeof(buf), MSG_DONTWAIT); + if(ret >= 0) + error_counter++; + else if((errno != EWOULDBLOCK) || (errno != EAGAIN)) + error_counter++; + + /* Send a response back. */ + ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0); + if(ret != (int)strlen(response[message_id & 3])) + error_counter++; + + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + +#ifdef __PRODUCT_NETXDUO__ + /* Invoke send with MSG_DONTWAIT flag. The message is larger than tx_window. Partial data should be sent. */ + ret = send(sockfd, large_msg, sizeof(large_msg), MSG_DONTWAIT); + if (ret <= 0) + error_counter++; +#endif + + FD_ZERO(&read_fds); + FD_ZERO(&write_fds); + FD_ZERO(&except_fds); + FD_SET(sockfd, &read_fds); + FD_SET(sockfd, &write_fds); + FD_SET(sockfd, &except_fds); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + wait_time.tv_sec = 1; + wait_time.tv_usec = 0; + select(sockfd + 1, &read_fds, &write_fds, &except_fds, &wait_time); + if((FD_ISSET(sockfd, &read_fds) && FD_ISSET(sockfd, &write_fds) && FD_ISSET(sockfd, &except_fds)) == 0) + error_counter++; + + tx_semaphore_put(&sema_0); + return; +} + + +static void test_tcp_client4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +#ifdef FEATURE_NX_IPV6 +struct sockaddr_in6 local_addr6; +int port; +int sockfd1; +#endif +int bytes_sent; +int ret; +char buf; +struct sock_winsize option; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = INADDR_ANY; + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0) + error_counter++; + + option.winsize = 0x10000; + if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &option, sizeof(option)) < 0) + error_counter++; + + bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0); + + if(bytes_sent != (int)strlen(send_buffer)) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Get the port bind to any. */ + port = nx_bsd_socket_array[sockfd - NX_BSD_SOCKFD_START].nx_bsd_socket_tcp_socket -> nx_tcp_socket_port; + + sockfd1 = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd1 < 0) + error_counter++; + + memset(&local_addr6, 0, sizeof(local_addr6)); + local_addr6.sin6_family = AF_INET6; + local_addr6.sin6_port = htons(port); + + /* Bind to the same port. */ + ret = bind(sockfd1, (struct sockaddr*)&local_addr6, sizeof(local_addr6)); + if(ret < 0) + error_counter++; + + ret = soc_close(sockfd1); + if(ret < 0) + error_counter++; +#endif + + /* Call recv before peer orderly shutdown. */ + ret = recv(sockfd, &buf, 1, 0); + if (ret != 0) + error_counter++; + + /* Make sure the other side gets the message. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + /* Call recv after peer orderly shutdown. */ + ret = recv(sockfd, &buf, 1, 0); + if (ret != 0) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +static void test_tcp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +UINT status; +struct sock_winsize option; + + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + option.winsize = 0x10000; + if(setsockopt(newsock, SOL_SOCKET, SO_RCVBUF, &option, sizeof(option)) < 0) + error_counter++; + + address_length = sizeof(local_addr); + ret = getsockname(newsock, (struct sockaddr*)&local_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(local_addr)) + error_counter++; + else if(local_addr.sin_family != AF_INET) + error_counter++; + else if(local_addr.sin_port != htons(12345)) + error_counter++; + else if(local_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1, 2, 3, 4))) + error_counter++; + + address_length = sizeof(remote_addr); + ret = getpeername(newsock, (struct sockaddr*)&remote_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if(remote_addr.sin_family != AF_INET) + error_counter++; + else if(remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5))) + error_counter++; + + + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status != TX_SUCCESS) + error_counter++; + + tx_thread_relinquish(); + } + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + + +#ifdef FEATURE_NX_IPV6 +static void test_tcp_client6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr; +int bytes_sent; +int ret; +struct sock_winsize option; + + sockfd = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + + remote_addr.sin6_family = AF_INET6; + remote_addr.sin6_port = htons(12); + remote_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip1.nxd_ip_address.v6[0]); + remote_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip1.nxd_ip_address.v6[1]); + remote_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip1.nxd_ip_address.v6[2]); + remote_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip1.nxd_ip_address.v6[3]); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0) + error_counter++; + + option.winsize = 0x10000; + if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &option, sizeof(option)) < 0) + error_counter++; + + bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0); + + if(bytes_sent != (INT)strlen(send_buffer)) + error_counter++; + + /* Make sure the other side gets the message. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +static void test_tcp_server6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int address_length; +int ret; +int newsock; +int i; +UINT status; +struct sock_winsize option; + + sockfd = socket(AF_INET6, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_family = AF_INET6; + local_addr.sin6_port = htons(12346); + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* 3 iterations. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + address_length = sizeof(remote_addr); + + newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length); + + if(newsock <= 0) + error_counter++; + + if(address_length != sizeof(struct sockaddr_in6)) + error_counter++; + + if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + option.winsize = 0x10000; + if(setsockopt(newsock, SOL_SOCKET, SO_RCVBUF, &option, sizeof(option)) < 0) + error_counter++; + + address_length = sizeof(local_addr); + ret = getsockname(newsock, (struct sockaddr*)&local_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(local_addr)) + error_counter++; + else if(local_addr.sin6_family != AF_INET6) + error_counter++; + else if(local_addr.sin6_port != htons(12346)) + error_counter++; + else if((local_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip0.nxd_ip_address.v6[0])) || + (local_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip0.nxd_ip_address.v6[1])) || + (local_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip0.nxd_ip_address.v6[2])) || + (local_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip0.nxd_ip_address.v6[3]))) + error_counter++; + + address_length = sizeof(remote_addr); + ret = getpeername(newsock, (struct sockaddr*)&remote_addr, &address_length); + if(ret < 0) + error_counter++; + else if(address_length != sizeof(remote_addr)) + error_counter++; + else if(remote_addr.sin6_family != AF_INET6) + error_counter++; + else if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + + + /* Set the client data */ + client_data[i].sockfd = newsock; + client_data[i].message_id = i; + + /* Create a helper thread to handle the new socket. */ + status = tx_thread_create(&helper_thread6[i], "helper thread", bsd_server_helper_thread_entry, + i, stack_space6[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status) + error_counter++; + + tx_thread_relinquish(); + } + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + } +} + +#endif + +static void close_before_accept_test() +{ +int server_fd, client_fd; +int ret; +struct sockaddr_in remote_addr, local_addr; + + /* Setup server socket. */ + server_fd = socket(AF_INET, SOCK_STREAM, 0); + if(server_fd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(server_fd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(server_fd, 5); + if(ret < 0) + error_counter++; + + /* Setup client socket. */ + client_fd = socket(AF_INET, SOCK_STREAM, 0); + if(client_fd < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12345); + remote_addr.sin_addr.s_addr = htonl(0x01020304); + + if(connect(client_fd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0) + error_counter++; + + /* Close before calling accept. */ + soc_close(server_fd); + soc_close(client_fd); +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +int sockfd; +struct sockaddr_in remote_addr; +#ifdef FEATURE_NX_IPV6 +char mac_ip0[6]; +char mac_ip1[6]; +UINT status; +#endif +int ret; + + + printf("NetX Test: Basic BSD TCP RCVBUF Test....................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = (CHAR)(ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8); + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = (CHAR)(ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8); + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + + close_before_accept_test(); + + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + test_tcp_client4(); + + tx_semaphore_put(&sema_1); + test_tcp_server4(); + +#ifdef FEATURE_NX_IPV6 + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + test_tcp_client6(); + + tx_semaphore_put(&sema_1); + test_tcp_server6(); +#endif + + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + /* Now open another socket and attempt to connect to the correct remote + host but an unexpected port so we expect an unsuccessful connections. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) >= 0) + error_counter++; + if(errno != ECONNREFUSED) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + /* Now open another socket and attempt to connect to the an incorrect + remote host so we expect an unsuccessful connections. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020306); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) >= 0) + error_counter++; + + if(errno != ETIMEDOUT) + error_counter++; + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + /* After the previous failed connection, make sure we can still open a socket. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS]; +static void multiple_client4(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE); + + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < NUM_CLIENTS; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + status = nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE); + if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED) + status = 0; + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + status += nx_tcp_client_socket_unbind(&tcp_sockets[i]); + + + status += nx_tcp_socket_delete(&tcp_sockets[i]); + + if(status != NX_SUCCESS) + error_counter++; + } + + +} + + +#ifdef FEATURE_NX_IPV6 +static void multiple_client6(void) +{ + +int i; +UINT status = NX_SUCCESS; +NX_PACKET *packet_ptr; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nxd_tcp_client_socket_connect(&tcp_sockets[i], &ipv6_address_ip0, 12346, NX_IP_PERIODIC_RATE); + } + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + + /* Send messages to each server */ + for(i = 0; i < NUM_CLIENTS; i++) + { + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]), + &pool_0, NX_NO_WAIT); + status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE); + + } + + if(status != NX_SUCCESS) + error_counter++; + + status = NX_SUCCESS; + /* Receive 3 messages. */ + + for(i = 0; i < NUM_CLIENTS; i++) + { + status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + continue; + } + + /* Validate the received data. */ + else if(packet_ptr -> nx_packet_length != strlen(response[i & 3])) + error_counter++; + else if(strncmp((char *)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length)) + error_counter++; + nx_packet_release(packet_ptr); + } + + for(i = 0; i < NUM_CLIENTS; i++) + { + + /* Wakeup server thread. */ + tx_semaphore_put(&sema_1); + } + + /* Shutdown the socket. */ + for(i = 0; i < NUM_CLIENTS; i++) + { + + nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE); + + if(tcp_sockets[i].nx_tcp_socket_bound_next) + status = nx_tcp_client_socket_unbind(&tcp_sockets[i]); + status += nx_tcp_socket_delete(&tcp_sockets[i]); + + if(status != NX_SUCCESS) + error_counter++; + } + +} +#endif + +static void netx_tcp_server(void) +{ +NX_PACKET *packet_ptr; +UINT status; + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != strlen(send_buffer))) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, send_buffer, strlen(send_buffer))) + error_counter++; + + nx_packet_release(packet_ptr); + } + + tx_semaphore_put(&sema_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + nx_tcp_socket_delete(&server_socket); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + tx_semaphore_put(&sema_0); + + netx_tcp_server(); + + /* Server run first. */ + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + + /* Simulate a multiple client conneting to the same server. */ + multiple_client4(); + +#ifdef FEATURE_NX_IPV6 + tx_semaphore_put(&sema_0); + netx_tcp_server(); + + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + multiple_client6(); +#endif + + /* Client finished. */ + tx_semaphore_put(&sema_0); +} + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_rcvbuf_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP RCVBUF Test.....................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_sendto_recvfrom_test.c b/test/regression/bsd_test/netx_bsd_tcp_sendto_recvfrom_test.c new file mode 100644 index 00000000..2d65b0c1 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_sendto_recvfrom_test.c @@ -0,0 +1,482 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE sema_0; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 10 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif +static char *send_buffer = "Hello World"; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_sendto_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + if(status) + error_counter++; +} + +static void test_tcp_client4(void) +{ +int sockfd; +struct sockaddr_in remote_addr; +int bytes_sent; +int ret; +char recv_buffer[30]; +int addr_len; + + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12); + remote_addr.sin_addr.s_addr = htonl(0x01020305); + + if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0) + error_counter++; + + /* 1st packet */ + bytes_sent = sendto(sockfd, send_buffer, strlen(send_buffer), 0, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + + if(bytes_sent != (int)strlen(send_buffer)) + error_counter++; + + addr_len = sizeof(remote_addr); + ret = recvfrom(sockfd, recv_buffer, sizeof(recv_buffer), 0, (struct sockaddr*)&remote_addr, &addr_len); + if((addr_len != sizeof(remote_addr)) || + (remote_addr.sin_family != AF_INET) || + (remote_addr.sin_port != htons(12)) || + (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + /* Do a send to with a truncated remote_addr. */ + bytes_sent = sendto(sockfd, send_buffer, strlen(send_buffer), 0, (struct sockaddr*)&remote_addr, sizeof(remote_addr) / 2); + + if(bytes_sent != (int)strlen(send_buffer)) + error_counter++; + + addr_len = sizeof(remote_addr); + ret = recvfrom(sockfd, recv_buffer, sizeof(recv_buffer), 0, (struct sockaddr*)&remote_addr, &addr_len); + if((addr_len != sizeof(remote_addr)) || + (remote_addr.sin_family != AF_INET) || + (remote_addr.sin_port != htons(12)) || + (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + + /* Do a send to with NULL remote_addr. */ + bytes_sent = sendto(sockfd, send_buffer, strlen(send_buffer), 0, (struct sockaddr*)NULL, sizeof(remote_addr) / 2); + + if(bytes_sent != (int)strlen(send_buffer)) + error_counter++; + + addr_len = sizeof(remote_addr); + ret = recvfrom(sockfd, recv_buffer, sizeof(recv_buffer), 0, (struct sockaddr*)&remote_addr, &addr_len); + if((addr_len != sizeof(remote_addr)) || + (remote_addr.sin_family != AF_INET) || + (remote_addr.sin_port != htons(12)) || + (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + + /* Do a send to with incorrect remote_addr. */ + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12); + remote_addr.sin_addr.s_addr = htonl(0x01020306); + bytes_sent = sendto(sockfd, send_buffer, strlen(send_buffer), 0, (struct sockaddr*)NULL, sizeof(remote_addr) ); + + if(bytes_sent != (int)strlen(send_buffer)) + error_counter++; + + addr_len = sizeof(remote_addr); + ret = recvfrom(sockfd, recv_buffer, sizeof(recv_buffer), 0, (struct sockaddr*)&remote_addr, &addr_len); + if((addr_len != sizeof(remote_addr)) || + (remote_addr.sin_family != AF_INET) || + (remote_addr.sin_port != htons(12)) || + (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + + /* Do a send to with incorrect remote port number. */ + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(13); + remote_addr.sin_addr.s_addr = htonl(0x01020306); + bytes_sent = sendto(sockfd, send_buffer, strlen(send_buffer), 0, (struct sockaddr*)NULL, sizeof(remote_addr) / 2); + + if(bytes_sent != (int)strlen(send_buffer)) + error_counter++; + + addr_len = sizeof(remote_addr); + ret = recvfrom(sockfd, recv_buffer, sizeof(recv_buffer), 0, (struct sockaddr*)&remote_addr, &addr_len); + if((addr_len != sizeof(remote_addr)) || + (remote_addr.sin_family != AF_INET) || + (remote_addr.sin_port != htons(12)) || + (remote_addr.sin_addr.s_addr != htonl(0x01020305))) + error_counter++; + + /* All done */ + + + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +char mac_ip0[6]; +char mac_ip1[6]; +UINT status; +#endif + + printf("NetX Test: Basic BSD TCP Sendto Recvfrom Test............"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + test_tcp_client4(); + +#ifdef FEATURE_NX_IPV6 + +#if 0 + test_tcp_client6(); +#endif + +#endif + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void netx_tcp_server(void) +{ +NX_PACKET *packet_ptr; +UINT status; +int i; + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + for(i = 0; i < 5; i++) + { + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != strlen(send_buffer))) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, send_buffer, strlen(send_buffer))) + error_counter++; + + status = nx_tcp_socket_send(&server_socket, packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + } + + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + nx_tcp_socket_delete(&server_socket); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + tx_semaphore_put(&sema_0); + + netx_tcp_server(); + +#ifdef FEATURE_NX_IPV6 +#if 0 + netx_tcp_server(); +#endif +#endif + + /* Client finished. */ + tx_semaphore_put(&sema_0); + +} + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_sendto_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Sendto Recvfrom Test............N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_servers_share_port_test.c b/test/regression/bsd_test/netx_bsd_tcp_servers_share_port_test.c new file mode 100644 index 00000000..290a1932 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_servers_share_port_test.c @@ -0,0 +1,927 @@ +/* This demoonstrates sharing a port between an IPv4 and IPv6 TCP server socket to send + and receive packets (e.g emulates a socket that can send/receive iPv4 and Ipv6 packets) + using a simulated Ethernet driver. */ + + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nxd_bsd.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_client6; +static TX_THREAD thread_server; +static TX_THREAD thread_server6; +static NX_PACKET_POOL bsd_pool; +static NX_IP bsd_ip_server; +static NX_IP bsd_ip_client; +static NX_TCP_SOCKET client_ipv6_socket; + +static UINT error_counter = 0; + +#define CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define SERVER_PORT 87 + +/* Define some global data. */ +static UINT ipv4_complete = NX_FALSE; + +/* Define thread prototypes. */ + + +static VOID thread_client_entry(ULONG thread_input); +static VOID thread_client6_entry(ULONG thread_input); +static VOID thread_server_entry(ULONG thread_input); +static VOID thread_server6_entry(ULONG thread_input); +VOID _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_servers_share_port_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a BSD packet pool. */ + status = nx_packet_pool_create(&bsd_pool, "NetX BSD Packet Pool", 1516, pointer, 16384); + + pointer = pointer + 16384; + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /********************** Set up the Server IP instance **************************/ + + /* Create a thread for the IPv4 server. */ + status= tx_thread_create(&thread_server, "BSD App IPv4 Server", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); /* jlc TX_AUTO_START */ + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + + /* Create a thread for IPv6 server. */ + status= tx_thread_create(&thread_server6, "BSD App IPv6 Server", thread_server6_entry, 0, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /* Create an IP instance for the BSD Server sockets. */ + status = nx_ip_create(&bsd_ip_server, "NetX BSD Server", SERVER_ADDRESS, 0xFFFFFF00UL, + &bsd_pool, _nx_ram_network_driver, pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&bsd_ip_server); + + /* Enable ARP and supply ARP cache memory for BSD */ + status += nx_arp_enable(&bsd_ip_server, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + { + error_counter++; + } + + /* Now initialize BSD IP. */ + status = bsd_initialize (&bsd_ip_server, &bsd_pool, pointer, 2048, 4); + + /* Check for BSD errors. */ + if (status) + { + error_counter++; + } + + pointer = pointer + 2048; + + /********************** Set up the Client **************************/ + + status = nx_ip_create(&bsd_ip_client, "NetX BSD Client", CLIENT_ADDRESS, 0xFFFFFF00UL, + &bsd_pool, _nx_ram_network_driver, pointer, DEMO_STACK_SIZE, 1); + + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + + /* Create a thread for IPv4 client. */ + status= tx_thread_create(&thread_client, "BSD App IPpv4 Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START);/* jlc TX_AUTO_START */ + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /* Create a thread for IPv6 client. */ + status= tx_thread_create(&thread_client6, "BSD App IPv6 Client", thread_client6_entry, 0, + pointer, DEMO_STACK_SIZE, + 16, 16, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&bsd_ip_client); + + /* Enable ARP and supply ARP cache memory for BSD */ + status += nx_arp_enable(&bsd_ip_client, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + { + error_counter++; + } + + return; +} + +/* Define the IPv4 server thread */ +void thread_server_entry(ULONG thread_input) +{ + +INT status, sock, sock_tcp_server; +ULONG actual_status; +INT Clientlen; +INT i; +UINT is_set = NX_FALSE; +struct sockaddr_in serverAddr; +struct sockaddr_in ClientAddr; +UINT ipv4_server_complete = NX_FALSE; +INT maxfd; +fd_set master_list, read_ready; +CHAR Server_Rcv_Buffer[100]; + + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); /* Don't let the IPv4 connection finish before IPv6 connection is created. */ + + status = nx_ip_status_check(&bsd_ip_server, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create BSD TCP Socket */ + sock_tcp_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (sock_tcp_server == -1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the server port and IP address */ + + memset(&serverAddr, 0, sizeof(serverAddr)); + serverAddr.sin_family = AF_INET; + serverAddr.sin_addr.s_addr = htonl(IP_ADDRESS(1,2,3,4)); + serverAddr.sin_port = htons(SERVER_PORT); + + /* Bind this server socket */ + status = bind (sock_tcp_server, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); + + if (status < 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + FD_ZERO(&master_list); + FD_ZERO(&read_ready); + FD_SET(sock_tcp_server,&master_list); + maxfd = sock_tcp_server; + + /* Now listen for any client connections for this server socket */ + status = listen (sock_tcp_server, 5); + if (status < 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* All set to accept client connections */ + /* Loop to create and establish server connections. */ + do + { + + read_ready = master_list; + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 5); /* Allow some time to other threads too */ + + /* Let the underlying TCP stack determine the timeout. */ + status = select(maxfd + 1, &read_ready, 0, 0, 0); + + if ( (status == ERROR) || (status == 0) ) + { + continue; + } + + /* Detected a connection request. */ + is_set = FD_ISSET(sock_tcp_server,&read_ready); + + if(is_set) + { + + Clientlen = sizeof(ClientAddr); + + sock = accept(sock_tcp_server,(struct sockaddr*)&ClientAddr, &Clientlen); + + /* Add this new connection to our master list */ + FD_SET(sock, &master_list); + + if ( sock > maxfd) + { + maxfd = sock; + } + + continue; + } + + /* Check the set of 'ready' sockets, e.g connected to remote host and waiting for + notice of packets received. */ + for (i = 0; i < (maxfd+1); i++) + { + + if (((i+ NX_BSD_SOCKFD_START) != sock_tcp_server) && + (FD_ISSET(i + NX_BSD_SOCKFD_START, &master_list)) && + (FD_ISSET(i + NX_BSD_SOCKFD_START, &read_ready))) + { + + while(1) + { + + status = recv(i + NX_BSD_SOCKFD_START, (VOID *)Server_Rcv_Buffer, 100, 0); + + if (status == ERROR) + { + /* This is a blocking socket. If no data is received, but the connection is still good, + the EAGAIN error is set. If it was a non blocking socket, the EWOULDBLOCK socket + error is set. */ + if (errno == EAGAIN) + { + continue; + } + else if (errno == ENOTCONN) + { + /* If the socket connection is terminated, the socket error will be ENOTCONN. */ + break; + } + else + { + /* Another error has occurred...probably an internal error of some kind + so best to terminate the connection. */ + error_counter++; + break; + } + } + else if (status == 0) + { + + /* If the socket connection is terminated, the socket error will be ENOTCONN. */ + break; + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + status = send(i + NX_BSD_SOCKFD_START, "Hello from IPv4\n", strlen("Hello from IPv4\n")+1, 0); + + if (status == ERROR) + { + if (errno == ENOTCONN) + { + + /* If the socket connection is terminated, the socket error will be ENOTCONN. */ + break; + } + else + { + + error_counter++; + break; + } + } + } + + /* Close this socket */ + status = soc_close(i+ NX_BSD_SOCKFD_START); + + if (status == ERROR) + { + + error_counter++; + } + + /* Indicate the IPv4 server socket is closed. */ + ipv4_server_complete = NX_TRUE; + break; + } + } + + /* Loop back to check any next client connection */ + } while(!ipv4_server_complete); + + /* Indicate the IPv4 connection is done. */ + ipv4_complete = NX_TRUE; + + /* Close down our server sockets. */ + status = soc_close(sock_tcp_server); + + if (status == ERROR) + { + + error_counter++; + } + +} + +/* Define the IPv6 server thread */ + +void thread_server6_entry(ULONG thread_input) +{ +INT status, sock6, sock6_tcp_server; +ULONG actual_status; +INT Clientlen; +INT i; +UINT is_set = NX_FALSE; +NXD_ADDRESS ip_address; +struct sockaddr_in6 serverAddr; +struct sockaddr_in6 ClientAddr; +UINT address_index; +UINT ipv6_complete = NX_FALSE; +INT maxfd; +fd_set master_list, read_ready; +CHAR Server_Rcv_Buffer[100]; + + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("NetX Test: BSD TCP Server Socket Shared Port Test........"); + + status = nx_ip_status_check(&bsd_ip_server, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&bsd_ip_server); + if((status != NX_SUCCESS) && (status != NX_ALREADY_ENABLED)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable ICMPv6 */ + status = nxd_icmp_enable(&bsd_ip_server); + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* This assumes we are using the primary network interface (index 0). */ + status = nxd_ipv6_address_set(&bsd_ip_server, 0, NX_NULL, 10, &address_index); + + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set ip interface address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x20010db8; + ip_address.nxd_ip_address.v6[1] = 0x0000f101; + ip_address.nxd_ip_address.v6[2] = 0; + ip_address.nxd_ip_address.v6[3] = 0x101; + + /* Set the host global IP address. We are assuming a 64 + bit prefix here but this can be any value (< 128). */ + status = nxd_ipv6_address_set(&bsd_ip_server, 0, &ip_address, 64, &address_index); + + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for IPv6 stack to finish DAD process. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create BSD TCP Socket */ + sock6_tcp_server = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + + if (sock6_tcp_server == -1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the server port and IP address */ + memset(&serverAddr, 0, sizeof(serverAddr)); + serverAddr.sin6_addr._S6_un._S6_u32[0] = htonl(0x20010db8); + serverAddr.sin6_addr._S6_un._S6_u32[1] = htonl(0xf101); + serverAddr.sin6_addr._S6_un._S6_u32[2] = 0x0; + serverAddr.sin6_addr._S6_un._S6_u32[3] = htonl(0x0101); + serverAddr.sin6_port = htons(SERVER_PORT); + serverAddr.sin6_family = AF_INET6; + + /* Bind this server socket */ + status = bind (sock6_tcp_server, (struct sockaddr *) &serverAddr, sizeof(serverAddr)); + + if (status < 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + FD_ZERO(&master_list); + FD_ZERO(&read_ready); + FD_SET(sock6_tcp_server,&master_list); + maxfd = sock6_tcp_server; + + /* Now listen for any client connections for this server socket */ + status = listen (sock6_tcp_server, 5); + if (status < 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* All set to accept client connections */ + is_set = NX_FALSE; + + /* Loop to create and establish server connections. */ + do + { + + read_ready = master_list; + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 5); /* Allow some time to other threads too */ + + /* Let the underlying TCP stack determine the timeout. */ + status = select(maxfd + 1, &read_ready, 0, 0, 0); + + if ( (status == ERROR) || (status == 0) ) + { + + continue; + } + + /* Detected a connection request. */ + is_set = FD_ISSET(sock6_tcp_server,&read_ready); + + if(is_set) + { + + Clientlen = sizeof(ClientAddr); + + sock6 = accept(sock6_tcp_server,(struct sockaddr*)&ClientAddr, &Clientlen); + + /* Add this new connection to our master list */ + FD_SET(sock6, &master_list); + + if ( sock6 > maxfd) + { + maxfd = sock6; + } + + continue; + } + + /* Check the set of 'ready' sockets, e.g connected to remote host and waiting for + notice of packets received. */ + for (i = 0; i < (maxfd+1); i++) + { + + if (((i+ NX_BSD_SOCKFD_START) != sock6_tcp_server) && + (FD_ISSET(i + NX_BSD_SOCKFD_START, &master_list)) && + (FD_ISSET(i + NX_BSD_SOCKFD_START, &read_ready))) + { + + while(1) + { + + memset(&Server_Rcv_Buffer[0], 0, 100); + status = recv(i + NX_BSD_SOCKFD_START, (VOID *)Server_Rcv_Buffer, 100, 0); + + if ((status == ERROR) || (status == 0)) + { + /* This is a blocking socket. If no data is received, but the connection is still good, + the EAGAIN error is set. If it was a non blocking socket, the EWOULDBLOCK socket + error is set. */ + if (errno == EAGAIN) + { + continue; + } + else if (errno == ENOTCONN) + { + /* If the socket connection is terminated, the socket error will be ENOTCONN. */ + break; + } + else if (status == 0) + { + + break; + } + + else + { + /* Another error has occurred...probably an internal error of some kind + so best to terminate the connection. */ + error_counter++; + break; + } + } + + status = send(i + NX_BSD_SOCKFD_START, "Hello\n", strlen("Hello\n")+1, 0); + + if (status == ERROR) + { + if (errno == ENOTCONN) + { + + /* If the socket connection is terminated, the socket error will be ENOTCONN. */ + break; + } + else + { + + error_counter++; + break; + } + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + } + + /* Close this socket */ + + status = soc_close(i+ NX_BSD_SOCKFD_START); + ipv6_complete = NX_TRUE; + + if (status == ERROR) + { + + error_counter++; + } + break; + } + + } + + /* Loop back to check any next client connection */ + } while (!ipv6_complete); + + status = soc_close(sock6_tcp_server); + + if (status == ERROR) + { + + error_counter++; + } + + /* Close down our server socket. */ + while (!ipv4_complete) + { + tx_thread_sleep(20); + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the IPv6 Client thread. */ + +void thread_client6_entry(ULONG thread_input) +{ + +INT status; +NXD_ADDRESS server_ip_address, ip_address; +NX_PACKET *packet_rcv_ptr, *packet_ptr; +UINT loopcount = 0; +char *requests[2] = {"Request1", "Request2"}; +UINT address_index; + + /* Allow Netx to initialize the driver, also let the server get set up first. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&bsd_ip_client); + if((status != NX_SUCCESS) && (status != NX_ALREADY_ENABLED)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable ICMPv6 */ + status = nxd_icmp_enable(&bsd_ip_client); + + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set ip interface address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x20010db8; + ip_address.nxd_ip_address.v6[1] = 0x0000f101; + ip_address.nxd_ip_address.v6[2] = 0; + ip_address.nxd_ip_address.v6[3] = 0x1235; + + /* Set the host global IP address. We are assuming a 64 + bit prefix here but this can be any value (< 128). */ + status = nxd_ipv6_address_set(&bsd_ip_client, 0, &ip_address, 64, &address_index); + + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Time for duplicate address check. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set Server IPv6 interface address. */ + server_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + server_ip_address.nxd_ip_address.v6[0] = 0x20010db8; + server_ip_address.nxd_ip_address.v6[1] = 0x0000f101; + server_ip_address.nxd_ip_address.v6[2] = 0; + server_ip_address.nxd_ip_address.v6[3] = 0x101; + + status += nx_tcp_socket_create(&bsd_ip_client, &client_ipv6_socket, "Client IPv6 Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 100, NX_NULL, NX_NULL); + + if (status ) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_tcp_client_socket_bind(&client_ipv6_socket, NX_ANY_PORT, 100); + + if (status ) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_tcp_client_socket_connect(&client_ipv6_socket, &server_ip_address, SERVER_PORT, 10 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + while(loopcount < 5) + { + + status = nx_packet_allocate(&bsd_pool, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + if (status ) + { + error_counter++; + } + + status = nx_packet_data_append(packet_ptr, requests[1], strlen(requests[1]), + &bsd_pool, NX_NO_WAIT); + if (status ) + { + error_counter++; + } + + status = nx_tcp_socket_send(&client_ipv6_socket, packet_ptr, NX_IP_PERIODIC_RATE); + + if (status) + { + nx_packet_release(packet_ptr); + error_counter++; + } + + status = nx_tcp_socket_receive(&client_ipv6_socket, &packet_rcv_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + + error_counter++; + } + else + { + nx_packet_release(packet_rcv_ptr); + } + + loopcount++; + tx_thread_sleep(NX_IP_PERIODIC_RATE / 2); + } + + nx_tcp_socket_disconnect(&client_ipv6_socket, 200); + nx_tcp_socket_delete(&client_ipv6_socket); + + /* All done */ + return; +} + + +/* Define the IPv4 Client thread. */ +void thread_client_entry(ULONG thread_input) +{ + +INT status; +UINT loopcount = 0; +ULONG actual_status; +INT sock_tcp_client; +struct sockaddr_in echoServAddr; +UINT ipv4_client_complete = NX_FALSE; +CHAR Client_Rcv_Buffer[100]; + + /* IPv4 waits for IPv6 DAD protocol */ + tx_thread_sleep(4 * NX_IP_PERIODIC_RATE); + + status = nx_ip_status_check(&bsd_ip_server, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + memset(&echoServAddr, 0, sizeof(echoServAddr)); + echoServAddr.sin_family = AF_INET; + echoServAddr.sin_addr.s_addr = htonl(IP_ADDRESS(1,2,3,4)); + echoServAddr.sin_port = htons(SERVER_PORT); + + /* Now make client connections with the server. */ + while (!ipv4_client_complete) + { + + /* Create BSD TCP Socket */ + sock_tcp_client = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (sock_tcp_client == -1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now connect this client to the server */ + status = connect(sock_tcp_client, (struct sockaddr *)&echoServAddr, sizeof(echoServAddr)); + + /* Check for error. */ + if (status != OK) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now receive the echoed packet from the server */ + while(loopcount < 5) + { + + + status = send(sock_tcp_client, "Hello from Client4", (strlen("Hello from Client4")+1), 0); + + if (status == ERROR) + { + error_counter++; + } + + memset(&Client_Rcv_Buffer[0], 0, 100); + status = recv(sock_tcp_client, (VOID *)Client_Rcv_Buffer, 100, 0); + + if (status < 0) + { + if (errno == EAGAIN) + { + continue; + } + else if (errno == ENOTCONN) + { + + break; + } + else + { + /* Another error has occurred.... */ + error_counter++; + break; + } + } + + loopcount++; + + } + + ipv4_client_complete = NX_TRUE; + + /* close this client socket */ + status = soc_close(sock_tcp_client); + + if (status == ERROR) + { + error_counter++; + } + + } + + /* All done */ + return; +} +#else /* FEATURE_NX_IPV6 */ + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_servers_share_port_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: BSD TCP Server Socket Shared Port Test.....N/A\n"); + + test_control_return(3); + +} + +#endif /* FEATURE_NX_IPV6 */ + + diff --git a/test/regression/bsd_test/netx_bsd_tcp_servers_shared_port_test.c b/test/regression/bsd_test/netx_bsd_tcp_servers_shared_port_test.c new file mode 100644 index 00000000..53bd15fc --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_servers_shared_port_test.c @@ -0,0 +1,598 @@ +/* This demoonstrates sharing a port between an IPv4 and IPv6 TCP server socket to send + and receive packets (e.g emulates a socket that can send/receive iPv4 and Ipv6 packets) + using a simulated Ethernet driver. */ + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) && defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nxd_bsd.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; +static NX_PACKET_POOL bsd_pool; +static NX_IP bsd_server_ip; +static NX_IP bsd_client_ip; +static NX_TCP_SOCKET client_socket1; +static NX_TCP_SOCKET client_socket2; + +static UINT error_counter = 0; + +#define CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define SERVER_PORT 87 + + +static char *requests[2] = {"Request1", "Request2"}; +static char *responses[2] = {"Response1", "Response2"}; +static UINT spin = NX_TRUE; + +/* Define thread prototypes. */ + +INT HandleClient(INT clientsock); +static VOID thread_client_entry(ULONG thread_input); +static VOID thread_server_entry(ULONG thread_input); +VOID _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_servers_shared_port_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a BSD packet pool. */ + status = nx_packet_pool_create(&bsd_pool, "NetX BSD Packet Pool", 1516, pointer, 16384); + + pointer = pointer + 16384; + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /********************** Set up the Server IP instance **************************/ + + /* Create a thread for server. */ + status= tx_thread_create(&thread_server, "BSD App Server", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /* Create an IP instance for the BSD Server. */ + status = nx_ip_create(&bsd_server_ip, "NetX BSD Server", SERVER_ADDRESS, 0xFFFFFF00UL, + &bsd_pool, _nx_ram_network_driver, pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&bsd_server_ip); + + /* Enable ARP and supply ARP cache memory for BSD Server Instance */ + status += nx_arp_enable(&bsd_server_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + { + error_counter++; + } + + /* Now initialize BSD Server IP. */ + status = bsd_initialize (&bsd_server_ip, &bsd_pool, pointer, 2048, 4); + + /* Check for BSD errors. */ + if (status) + { + error_counter++; + } + + pointer = pointer + 2048; + + /********************** Set up the Client IP instance **************************/ + + /* Create a thread for client. */ + status= tx_thread_create(&thread_client, "BSD App Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status!= NX_SUCCESS) + { + error_counter++; + } + + /* Create an IP instance for the BSD Client. */ + status = nx_ip_create(&bsd_client_ip, "NetX BSD Client", CLIENT_ADDRESS, 0xFFFFFF00UL, + &bsd_pool, _nx_ram_network_driver, pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&bsd_client_ip); + + /* Enable ARP and supply ARP cache memory for BSD Client Instance */ + status += nx_arp_enable(&bsd_client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + { + error_counter++; + } + + return; +} + + + +void thread_server_entry(ULONG thread_input) +{ + +INT hcstatus, sock, sock6, sock_tcp_server, sock_tcp_server6; +UINT status; +struct sockaddr_in6 echoServAddr6; +struct sockaddr_in echoServAddr; +INT Serverlen; +NXD_ADDRESS ip_address; +UINT address_index; +UINT loopcount = 0; +INT length; +struct sockaddr_in localAddr; +struct sockaddr_in6 localAddr6; + + + printf("NetX Test: Basic BSD TCP Server Socket Shared Port Test............"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 5); + + memset(&echoServAddr, 0, sizeof(echoServAddr)); + memset(&echoServAddr6, 0, sizeof(echoServAddr6)); + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&bsd_server_ip); + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable ICMPv6 */ + status = nxd_icmp_enable(&bsd_server_ip); + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set ip_0 interface address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x20010db8; + ip_address.nxd_ip_address.v6[1] = 0xf101; + ip_address.nxd_ip_address.v6[2] = 0; + ip_address.nxd_ip_address.v6[3] = 0x1234; + + status = nxd_ipv6_address_set(&bsd_server_ip, 0, NX_NULL, 10, &address_index); + + status |= nxd_ipv6_address_set(&bsd_server_ip, 0, &ip_address, 64, &address_index); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for IPv6 stack to finish DAD process. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create BSD TCP IPv6 Server Socket */ + sock_tcp_server6 = socket( AF_INET6, SOCK_STREAM, IPPROTO_TCP); + + if (sock_tcp_server6 == -1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + echoServAddr6.sin6_addr._S6_un._S6_u32[0] = htonl(0x20010db8); + echoServAddr6.sin6_addr._S6_un._S6_u32[1] = htonl(0xf101); + echoServAddr6.sin6_addr._S6_un._S6_u32[2] = 0x0; + echoServAddr6.sin6_addr._S6_un._S6_u32[3] = htonl(0x1234); + echoServAddr6.sin6_port = htons(SERVER_PORT); + echoServAddr6.sin6_family = AF_INET6; + + /* Create BSD TCP IPv4 Server Socket */ + sock_tcp_server = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (sock_tcp_server == -1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + echoServAddr.sin_family = AF_INET; + echoServAddr.sin_port = htons(SERVER_PORT); + echoServAddr.sin_addr.s_addr = htonl(SERVER_ADDRESS); + + /* Bind the IPv4 and IPv6 server sockets. */ + hcstatus = bind (sock_tcp_server, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)); + hcstatus |= bind (sock_tcp_server6, (struct sockaddr *) &echoServAddr6, sizeof(echoServAddr6)); + if (hcstatus < 0) + { + test_control_return(1); + } + + /* Now listen for any client connections for these server sockets. */ + hcstatus = listen (sock_tcp_server, 5); + if (hcstatus < 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + hcstatus = listen (sock_tcp_server6, 5); + if (hcstatus < 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* All set to accept client connections */ + + /* Loop to check for client connection requests. */ + /* This assumes the IPv4 Client socket makes a connectin request before the IPv6 socket. */ + + Serverlen = sizeof(echoServAddr); + sock = accept(sock_tcp_server, (struct sockaddr *)&echoServAddr, &Serverlen); + if ((sock == NX_SOC_ERROR) || (sock == NX_BSD_MAX_SOCKETS + NX_BSD_SOCKFD_START - 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + length = sizeof(localAddr); + getsockname(sock_tcp_server, (struct sockaddr *)&localAddr, &length); + if (localAddr.sin_port != htons(SERVER_PORT)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + Serverlen = sizeof(echoServAddr6); + sock6 = accept(sock_tcp_server6, (struct sockaddr *)&echoServAddr6, &Serverlen); + if ((sock6 == NX_SOC_ERROR) || (sock6 == NX_BSD_MAX_SOCKETS + NX_BSD_SOCKFD_START - 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + length = sizeof(localAddr6); + getsockname(sock_tcp_server6, (struct sockaddr *)&localAddr6, &length); + if (localAddr6.sin6_port != htons(SERVER_PORT)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Loop to send and receive IPv4 and IPv6 transmissions. */ + while(loopcount < 5) + { + + hcstatus = HandleClient(sock); + if (hcstatus == ERROR) + { + error_counter++; + } + + hcstatus = HandleClient(sock6); + if (hcstatus == ERROR) + { + error_counter++; + } + + loopcount++; + } + + /* Stop the client thread. */ + spin = NX_FALSE; + + /* Close down our server sockets. */ + soc_close(sock6); + soc_close(sock); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(loopcount != 5) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +/* Define the Client thread. */ + +void thread_client_entry(ULONG thread_input) +{ + +INT status; +NXD_ADDRESS client_ip_address, server_ip_address; +UINT address_index; +NX_PACKET *packet_ptr4, *packet_ptr3, *packet_ptr2, *packet_ptr; + + + /* Allow Netx to initialize the driver, also let the server get set up first. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&bsd_client_ip); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable ICMPv6 */ + status = nxd_icmp_enable(&bsd_client_ip); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Client IPv6 interface address. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + client_ip_address.nxd_ip_address.v6[0] = 0x20010db8; + client_ip_address.nxd_ip_address.v6[1] = 0x0000f101; + client_ip_address.nxd_ip_address.v6[2] = 0; + client_ip_address.nxd_ip_address.v6[3] = 0x1235; + + status = nxd_ipv6_address_set(&bsd_client_ip, 0, NX_NULL, 10, &address_index); + + status |= nxd_ipv6_address_set(&bsd_client_ip, 0, &client_ip_address, 64, &address_index); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Time for duplicate address check. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set Server IPv6 interface address. */ + server_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + server_ip_address.nxd_ip_address.v6[0] = 0x20010db8; + server_ip_address.nxd_ip_address.v6[1] = 0x0000f101; + server_ip_address.nxd_ip_address.v6[2] = 0; + server_ip_address.nxd_ip_address.v6[3] = 0x1234; + + status = nx_tcp_socket_create(&bsd_client_ip, &client_socket1, "Client IPv4 Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 100, NX_NULL, NX_NULL); + + status += nx_tcp_socket_create(&bsd_client_ip, &client_socket2, "Client IPv4 Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 100, NX_NULL, NX_NULL); + + if (status ) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_tcp_client_socket_bind(&client_socket1, NX_ANY_PORT, 100); + status += nx_tcp_client_socket_bind(&client_socket2, NX_ANY_PORT, 100); + + if (status ) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_tcp_client_socket_connect(&client_socket1, SERVER_ADDRESS, SERVER_PORT, 200); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_tcp_client_socket_connect(&client_socket2, &server_ip_address, SERVER_PORT, 300); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + while(spin) + { + + status = nx_packet_allocate(&bsd_pool, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + if (status ) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(packet_ptr, requests[0], strlen(requests[0]), + &bsd_pool, NX_NO_WAIT); + + if (status ) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_tcp_socket_send(&client_socket1, packet_ptr, 100); + + if (status ) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_allocate(&bsd_pool, &packet_ptr2, NX_TCP_PACKET, NX_NO_WAIT); + if (status ) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(packet_ptr2, requests[1], strlen(requests[1]), + &bsd_pool, NX_NO_WAIT); + if (status ) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + status = nx_tcp_socket_send(&client_socket2, packet_ptr2, 100); + + if (status) + { + nx_packet_release(packet_ptr2); + error_counter++; + } + + status = nx_tcp_socket_receive(&client_socket1, &packet_ptr3, 200); + if(status != NX_SUCCESS) + { + + error_counter++; + } + else + { + nx_packet_release(packet_ptr3); + } + + status = nx_tcp_socket_receive(&client_socket2, &packet_ptr4, 200); + if(status != NX_SUCCESS) + { + + error_counter++; + } + else + { + nx_packet_release(packet_ptr4); + } + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + nx_tcp_socket_delete(&client_socket1); + nx_tcp_socket_delete(&client_socket2); + + /* All done */ + return; +} + + +INT HandleClient(INT clientsock) +{ + +INT status; +CHAR rcvBuffer[32]; + + + status = recv(clientsock, (VOID *)rcvBuffer, 32, 0); + if (status == ERROR ) + { + return(ERROR); + } + + /* a zero return from a recv() call indicates client is terminated! */ + if (status == 0) + { + + return(ERROR); + } + + /* And echo the same data to the client */ + status = send(clientsock, responses[clientsock % 2], strlen(responses[clientsock % 2]), 0); + + if (status == ERROR ) + { + return(ERROR); + } + + return(NX_SUCCESS); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_servers_shared_port_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Server Socket Shared Port Test............N/A"); + + test_control_return(3); + +} +#endif /* defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) */ + + + + + diff --git a/test/regression/bsd_test/netx_bsd_tcp_two_blocking_test.c b/test/regression/bsd_test/netx_bsd_tcp_two_blocking_test.c new file mode 100644 index 00000000..2153f448 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_two_blocking_test.c @@ -0,0 +1,399 @@ +/* This NetX test concentrates on the basic BSD TCP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), recv(), soc_close(), setsockopt() */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define BSD_THREAD_PRIORITY 2 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +static int newsock_1; +static UCHAR loop; +static NX_TCP_SOCKET client_0, client_1; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static UCHAR packet_pool_area[(256 + sizeof(NX_PACKET)) * 16]; +static UCHAR recv_buff_0[32]; +static UCHAR recv_buff_1[32]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static char *send_buffer = "Hello World"; +/* Define what the initial system looks like. */ + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_two_blocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + loop = NX_TRUE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_256, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_256, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, pointer, DEMO_STACK_SIZE, BSD_THREAD_PRIORITY); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + if(status) + error_counter++; +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +int sockfd, newsock_0; +struct sockaddr_in local_addr; +int ret; +struct timeval time_0, time_1; + + + printf("NetX Test: Basic BSD TCP Two Blocking Test..............."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a server socket. */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + ret = listen(sockfd, 5); + if(ret < 0) + error_counter++; + + /* Let client thread start the connection. */ + tx_semaphore_put(&sema_1); + + /* Accept two connections. */ + newsock_0 = accept(sockfd, (struct sockaddr*)NX_NULL, 0); + if(newsock_0 < 0) + error_counter++; + else + { + +#if 0 + /* Set timeout to 3 seconds. */ + time_0.tv_sec = 3; + time_0.tv_usec = 0; +#else + /* Set timeout to 30 ticks. */ + time_0.tv_sec = 0; + time_0.tv_usec = 30 * NX_MICROSECOND_PER_CPU_TICK; +#endif + setsockopt(newsock_0, SOL_SOCKET, SO_RCVTIMEO, &time_0, sizeof(time_0)); + } + + + newsock_1 = accept(sockfd, (struct sockaddr*)NX_NULL, 0); + if(newsock_1 < 0) + error_counter++; + else + { + +#if 0 + /* Set timeout to 1 second. */ + time_1.tv_sec = 1; + time_1.tv_usec = 0; +#else + /* Set timeout to 10 ticks. */ + time_0.tv_sec = 0; + time_0.tv_usec = 10 * NX_MICROSECOND_PER_CPU_TICK; +#endif + setsockopt(newsock_1, SOL_SOCKET, SO_RCVTIMEO, &time_1, sizeof(time_1)); + } + + /* Let client thread loop send and recv. */ + tx_semaphore_put(&sema_1); + + /* Receive on socket 0. */ + ret = recv(newsock_0, recv_buff_0, sizeof(recv_buff_0), 0); + if((ret >= 0) || (errno != EAGAIN)) + error_counter++; + + /* Close down the server socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + /* Notify to end loop of thread 1. */ + loop = NX_FALSE; + tx_semaphore_get(&sema_0, 1 * NX_IP_PERIODIC_RATE); + + /* Close down the new socket 0. */ + ret = soc_close(newsock_0); + if(ret < 0) + error_counter++; + + /* Close down the new socket 1. */ + soc_close(newsock_1); + + /* Check bsd wrapper. */ + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_0, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Create a socket. */ + status += nx_tcp_socket_create(&ip_1, &client_1, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_0, 12, 1 * NX_IP_PERIODIC_RATE); + status += nx_tcp_client_socket_bind(&client_1, 13, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Wait for server thread first. */ + tx_semaphore_get(&sema_1, 1 * NX_IP_PERIODIC_RATE); + + status = nx_tcp_client_socket_connect(&client_0, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + status += nx_tcp_client_socket_connect(&client_1, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Loop sending and receiving. */ + tx_semaphore_get(&sema_1, 1 * NX_IP_PERIODIC_RATE); + while(loop) + { + + /* Send packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, send_buffer, strlen(send_buffer), &pool_0, NX_NO_WAIT); + status = nx_tcp_socket_send(&client_1, my_packet, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive data. */ + recv(newsock_1, recv_buff_1, sizeof(recv_buff_1), 0); + +#if 0 + /* Sleep 1 second. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); +#else + /* Sleep 100ms. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); +#endif + } + + nx_tcp_socket_disconnect(&client_0, 1); + nx_tcp_socket_disconnect(&client_1, 1); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_0); + status += nx_tcp_client_socket_unbind(&client_1); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_0); + status += nx_tcp_socket_delete(&client_1); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let server thread go on. */ + tx_semaphore_put(&sema_0); +} + +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_two_blocking_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP Two Blocking Test...............N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_tcp_udp_select_test.c b/test/regression/bsd_test/netx_bsd_tcp_udp_select_test.c new file mode 100644 index 00000000..ac30affe --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_tcp_udp_select_test.c @@ -0,0 +1,413 @@ +/* This NetX test concentrates on the basic BSD UDP non-blocking operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET udp_socket; +static NX_TCP_SOCKET tcp_socket; +static TX_SEMAPHORE sema_0; +static TX_SEMAPHORE sema_1; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +static char *requests[2] = {"Request1", "Request2"}; + +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_udp_select_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + status += nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, pointer, DEMO_STACK_SIZE, BSD_THREAD_PRIORITY); + + /* Check UDP enable and BSD init status. */ + if (status) + error_counter++; + pointer = pointer + DEMO_STACK_SIZE; + + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + status += tx_semaphore_create(&sema_1, "SEMA 1", 0); + if(status) + error_counter++; +} + + + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +struct sockaddr_in local_addr; +struct sockaddr_in peer_addr; +int peer_addr_len; +int tcp_sockfd, udp_sockfd, new_sockfd, nfd; +struct timeval tv; +fd_set readfd; +int n, i; +char buffer[20]; + + printf("NetX Test: Basic BSD TCP UDP Select Test................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + /* Open TCP socket. */ + tcp_sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(tcp_sockfd < 0) + error_counter++; + + if(bind(tcp_sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)) < 0) + error_counter++; + + if(listen(tcp_sockfd, 5) < 0) + error_counter++; + + udp_sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(udp_sockfd < 0) + error_counter++; + + if(bind(udp_sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)) < 0) + error_counter++; + + peer_addr_len = sizeof(peer_addr); + tx_semaphore_put(&sema_1); + new_sockfd = accept(tcp_sockfd, (struct sockaddr*)&peer_addr, &peer_addr_len); + + if(new_sockfd < 0) + error_counter++; + +#if 0 + /* Now sleep for a second */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); +#endif + + /* select on both sockets. */ + if(udp_sockfd < new_sockfd) + nfd = new_sockfd + 1; + else + nfd = udp_sockfd + 1; + + tv.tv_sec = 1; + tv.tv_usec = 0; + error_counter += 2; + + for(i = 0; i < 2;) + { + FD_ZERO(&readfd); + FD_SET(new_sockfd, &readfd); + FD_SET(udp_sockfd, &readfd); + n = select(nfd, &readfd, NULL, NULL, &tv); + + if(n <= 0) + { + error_counter++; + break; + } + i += n; + + if(FD_ISSET(new_sockfd, &readfd)) + { + n = recv(new_sockfd, buffer, sizeof(buffer), 0); + if(n < 0) + error_counter++; + else if(n != (int)strlen(requests[1])) + error_counter++; + else if(strncmp(buffer, requests[1], n)) + error_counter++; + else + error_counter--; + + } + if(FD_ISSET(udp_sockfd, &readfd)) + { + peer_addr_len = sizeof(peer_addr); + n = recvfrom(udp_sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&peer_addr, &peer_addr_len); + if(n < 0) + error_counter++; + else if(n != (int)strlen(requests[0])) + error_counter++; + else if(strncmp(buffer, requests[0], n)) + error_counter++; + else + error_counter--; + } + } + + soc_close(new_sockfd); + soc_close(tcp_sockfd); + soc_close(udp_sockfd); + + tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE); + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + status = nx_tcp_socket_create(&ip_1, &tcp_socket, "TCP Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + status += nx_tcp_client_socket_bind(&tcp_socket, NX_ANY_PORT, 0); + if(status != NX_SUCCESS) + error_counter++; + + + + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &udp_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + /* Check for error. */ + if (status) + error_counter++; + + tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE); + status = nx_tcp_client_socket_connect(&tcp_socket, IP_ADDRESS(1,2,3,4), 12345, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&udp_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Send a UDP packet */ + status = nx_udp_socket_send(&udp_socket, packet_ptr, IP_ADDRESS(1,2,3,4), 12345); + if(status) + error_counter++; + + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[1], strlen(requests[1])); + + packet_ptr -> nx_packet_length = strlen(requests[1]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + + /* Send a TCP packet */ + status = nx_tcp_socket_send(&tcp_socket, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_udp_socket_unbind(&udp_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&udp_socket); + if(status) + error_counter++; + + status = nx_tcp_socket_disconnect(&tcp_socket, 1 * NX_IP_PERIODIC_RATE); + status += nx_tcp_client_socket_unbind(&tcp_socket); + status += nx_tcp_socket_delete(&tcp_socket); + + if(status != NX_SUCCESS) + error_counter++; + + tx_semaphore_put(&sema_0); +} + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_tcp_udp_select_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD TCP UDP Select Test.................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_udp_basic_blocking_test.c b/test/regression/bsd_test/netx_bsd_udp_basic_blocking_test.c new file mode 100644 index 00000000..6538b691 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_udp_basic_blocking_test.c @@ -0,0 +1,501 @@ +/* This NetX test concentrates on the basic BSD UDP non-blocking operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif /* FEATURE_NX_IPV6 */ +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_basic_blocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check UDP enable and BSD init status. */ + if (status) + error_counter++; +} + +#ifdef FEATURE_NX_IPV6 +static void test_udp_server6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; + + + sockfd = socket(AF_INET6, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_family = AF_INET6; + local_addr.sin6_port = htons(12345); + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in6)) + error_counter++; + + if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3])) || + (remote_addr.sin6_port != htons(54321))) + error_counter++; + + /* Validate the data. */ + if((ret != (INT)strlen(requests[1])) || strncmp(buf, requests[1], ret)) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[1], strlen(response[1]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (INT)strlen(response[1])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} +#endif /* FEATURE_NX_IPV6 */ + +static void test_udp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; + + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + + if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + + if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5))) || + (remote_addr.sin_port != htons(54321))) + error_counter++; + + /* Validate the data. */ + if((ret != (int)strlen(requests[0])) || strncmp(buf, requests[0], ret)) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (int)strlen(response[0])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +char mac_ip0[6]; +char mac_ip1[6]; +UINT status; +#endif + + + printf("NetX Test: Basic BSD UDP Blocking Test..................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = (char)(ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8); + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = (char)(ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8); + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + test_udp_server4(); + + tx_thread_sleep(3); + +#ifdef FEATURE_NX_IPV6 + test_udp_server6(); +#endif + + + tx_thread_sleep(1); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Send a UDP packet */ + status = nx_udp_socket_send(&server_socket, packet_ptr, IP_ADDRESS(1,2,3,4), 12345); + if(status) + error_counter++; + + /* Ready to reaceive a message */ + status = nx_udp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0]))) + error_counter++; + + + status = nx_udp_socket_unbind(&server_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&server_socket); + if(status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + tx_thread_sleep(3); + + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[1], strlen(requests[1])); + + packet_ptr -> nx_packet_length = strlen(requests[1]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Send a UDP packet */ + status = nxd_udp_socket_send(&server_socket, packet_ptr, &ipv6_address_ip0, 12345); + if(status) + error_counter++; + + error_counter++; + /* Ready to reaceive a message */ + status = nx_udp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[1])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[1], strlen(response[1]))) + error_counter++; + else + error_counter--; + + status = nx_udp_socket_unbind(&server_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&server_socket); + if(status) + error_counter++; + +#endif + +} + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_basic_blocking_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD UDP Blocking Test...................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_udp_basic_nonblocking_test.c b/test/regression/bsd_test/netx_bsd_udp_basic_nonblocking_test.c new file mode 100644 index 00000000..26bd977d --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_udp_basic_nonblocking_test.c @@ -0,0 +1,568 @@ +/* This NetX test concentrates on the basic BSD UDP blocking operation. */ +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#ifdef FEATURE_NX_IPV6 +#include "nx_icmpv6.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); + +static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"}; +static char *response[4] = {"Response1", "Response2", "Response3", "Response4"}; +static void validate_bsd_structure(void); +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif /* FEATURE_NX_IPV6 */ +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_basic_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable udp processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check BSD init and udp enable status. */ + if (status) + error_counter++; +} + +#ifdef FEATURE_NX_IPV6 +static void test_udp_server6(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; +fd_set read_fd; +struct timeval tv; + + + sockfd = socket(AF_INET6, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_family = AF_INET6; + local_addr.sin6_port = htons(12345); + + /* Set the socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret > 0) + error_counter++; + else + { + /* Check errno */ + if(errno != EWOULDBLOCK) + error_counter++; + } + + /* Select on the socket. */ + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + tv.tv_sec = 2; + tv.tv_usec = 0; + + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + if(ret != 1) + error_counter++; + + if(!FD_ISSET(sockfd, &read_fd)) + error_counter++; + + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret < 0) + error_counter++; + + /* Call recvfrom again */ + if(addrlen != sizeof(struct sockaddr_in6)) + error_counter++; + + if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3])) || + (remote_addr.sin6_port != htons(54321))) + error_counter++; + + /* Validate the data. */ + if((ret != (INT)strlen(requests[1])) || strncmp(buf, requests[1], ret)) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[1], strlen(response[1]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (INT)strlen(response[1])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +#endif + + +static void test_udp_server4(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; +fd_set read_fd; +struct timeval tv; + + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + /* Set the socket to non-blocking mode. */ + if(fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret > 0) + error_counter++; + else + { + /* Check errno */ + if(errno != EWOULDBLOCK) + error_counter++; + } + + /* Select on the socket. */ + FD_ZERO(&read_fd); + FD_SET(sockfd, &read_fd); + + tv.tv_sec = 2; + tv.tv_usec = 0; + + + ret = select(sockfd + 1, &read_fd, NULL, NULL, &tv); + if(ret != 1) + error_counter++; + + if(!FD_ISSET(sockfd, &read_fd)) + error_counter++; + + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret < 0) + error_counter++; + + /* Call recvfrom again */ + if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + + if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5))) || + (remote_addr.sin_port != htons(54321))) + error_counter++; + + /* Validate the data. */ + if((ret != (int)strlen(requests[0])) || strncmp(buf, requests[0], ret)) + error_counter++; + + /* Send a response back. */ + ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (int)strlen(response[0])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +char mac_ip0[6]; +char mac_ip1[6]; +UINT status; +#endif + + printf("NetX Test: Basic BSD UDP Non-Blocking Test..............."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; +#endif + + test_udp_server4(); + + tx_thread_sleep(3); + +#ifdef FEATURE_NX_IPV6 + test_udp_server6(); +#endif + tx_thread_sleep(1); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0])); + + packet_ptr -> nx_packet_length = strlen(requests[0]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Send a UDP packet */ + status = nx_udp_socket_send(&server_socket, packet_ptr, IP_ADDRESS(1,2,3,4), 12345); + if(status) + error_counter++; + + /* Ready to reaceive a message */ + status = nx_udp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[0])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0]))) + error_counter++; + + + status = nx_udp_socket_unbind(&server_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&server_socket); + if(status) + error_counter++; + + +#ifdef FEATURE_NX_IPV6 + tx_thread_sleep(3); + + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[1], strlen(requests[1])); + + packet_ptr -> nx_packet_length = strlen(requests[1]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Send a UDP packet */ + status = nxd_udp_socket_send(&server_socket, packet_ptr, &ipv6_address_ip0, 12345); + if(status) + error_counter++; + + error_counter++; + /* Ready to reaceive a message */ + status = nx_udp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[1])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[1], strlen(response[1]))) + error_counter++; + else + error_counter--; + + status = nx_udp_socket_unbind(&server_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&server_socket); + if(status) + error_counter++; + +#endif + +} + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_basic_nonblocking_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD UDP Non-Blocking Test...............N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_udp_bind_connect_test.c b/test/regression/bsd_test/netx_bsd_udp_bind_connect_test.c new file mode 100644 index 00000000..aca76d19 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_udp_bind_connect_test.c @@ -0,0 +1,553 @@ +/* This NetX test concentrates on the basic BSD UDP non-blocking bind to a specific address and connect + send operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) + +#ifdef FEATURE_NX_IPV6 +#include "nx_ipv6.h" +#endif +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nx_ipv4.h" +#include "nxd_bsd.h" +#else +#include "nx_ip.h" +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +static TX_SEMAPHORE sema; +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0[3][3]; +static NXD_ADDRESS ipv6_address_ip1[3][3]; +static char *bsd6_msg[3][3] = {{"BSD6_MSG IF0 LLA", "BSD6_MSG IF0 GA0", "MSD6_MSG IF0 GA1"}, + {"BSD6_MSG IF1 LLA", "BSD6_MSG IF1 GA0", "MSD6_MSG IF1 GA1"}, + {"BSD6_MSG IF2 LLA", "BSD6_MSG IF2 GA0", "MSD6_MSG IF2 GA1"}}; +#endif /* FEATURE_NX_IPV6 */ +static char *bsd4_msg[3] = {"BSD4_MSG 0", "BSD4_MSG 1", "MSD4_MSG 2"}; + +static void validate_bsd_structure(void); + +#define IP0_IF0_V4_ADDR IP_ADDRESS(1,2,3,4) +#define IP0_IF1_V4_ADDR IP_ADDRESS(2,2,3,4) +#define IP0_IF2_V4_ADDR IP_ADDRESS(3,2,3,4) + +#define IP1_IF0_V4_ADDR IP_ADDRESS(1,2,3,5) +#define IP1_IF1_V4_ADDR IP_ADDRESS(2,2,3,5) +#define IP1_IF2_V4_ADDR IP_ADDRESS(3,2,3,5) + +#define ITERATIONS 100 +static ULONG ip0_address[3] = {IP0_IF0_V4_ADDR, IP0_IF1_V4_ADDR, IP0_IF2_V4_ADDR}; +static ULONG ip1_address[3] = {IP1_IF0_V4_ADDR, IP1_IF1_V4_ADDR, IP1_IF2_V4_ADDR}; +/* Define what the initial system looks like. */ + +#ifdef __PRODUCT_NETX__ +#define NX_IPV4_HEADER NX_IP_HEADER +#endif + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_bind_connect_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP0_IF0_V4_ADDR, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Attach a 2nd interface */ + status += nx_ip_interface_attach(&ip_0, "ip_0_second", IP0_IF1_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_0, "ip_0_third", IP0_IF2_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP1_IF0_V4_ADDR, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_1, "ip_1_second", IP1_IF1_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1, "ip_1_third", IP1_IF2_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check UDP enable and BSD init status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema, "test done", 0); + if (status) + error_counter++; +} + + + + +#ifdef FEATURE_NX_IPV6 +static void test_udp6_on_interface_address(int iface, int address) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int ret; + + + sockfd = socket(AF_INET6, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_port = htons(12345); + local_addr.sin6_family = AF_INET6; + if(iface != 3) + { + local_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[0]); + local_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[1]); + local_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[2]); + local_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[3]); + } + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + remote_addr.sin6_family = AF_INET6; + remote_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip1[iface][address].nxd_ip_address.v6[0]); + remote_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip1[iface][address].nxd_ip_address.v6[1]); + remote_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip1[iface][address].nxd_ip_address.v6[2]); + remote_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip1[iface][address].nxd_ip_address.v6[3]); + + remote_addr.sin6_port = htons(12346); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + + ret = send(sockfd, bsd6_msg[iface][address], strlen(bsd6_msg[iface][address]), 0); + if(ret != (INT)strlen(bsd6_msg[iface][address])) + error_counter++; + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + + +#endif /* FEATURE_NX_IPV6 */ + +static void test_udp4_on_interface(int i) +{ + +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int ret; + + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = htonl(ip0_address[i]); + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(12346); + remote_addr.sin_addr.s_addr = htonl(ip1_address[i]); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + ret = send(sockfd, bsd4_msg[i], strlen(bsd4_msg[i]), 0); + if(ret != (int)strlen(bsd4_msg[i])) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +static char mac_ip0[6]; +static char mac_ip1[6]; +int i,j; +UINT status; +int addr_index; +#endif +int iface; + + + printf("NetX Test: Basic BSD UDP Bind Connect Send Test.........."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + + for(i = 0; i < 3; i++) + { + mac_ip0[0] = (char)(ip_0.nx_ip_interface[i].nx_interface_physical_address_msw >> 8); + mac_ip0[1] = ip_0.nx_ip_interface[i].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = (char)(ip_1.nx_ip_interface[i].nx_interface_physical_address_msw >> 8); + mac_ip1[1] = ip_1.nx_ip_interface[i].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw & 0xff; + + for(j = 0; j < 3; j ++) + { + if(j == 0) + { + /* First set up IPv6 linklocal addresses. */ + ipv6_address_ip0[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0[i][j].nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0[i][j].nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0[i][j].nxd_ip_address.v6[2] = ((mac_ip0[0] | 0x2) << 24) | (mac_ip0[1] << 16) | (mac_ip0[2] << 8) | 0xFF; + ipv6_address_ip0[i][j].nxd_ip_address.v6[3] = (0xFE << 24) | ((mac_ip0[3] | 0x2) << 16) | (mac_ip0[4] << 8) | mac_ip0[5]; + + ipv6_address_ip1[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1[i][j].nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1[i][j].nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1[i][j].nxd_ip_address.v6[2] = + ((mac_ip1[0] | 0x2) << 24) | (mac_ip1[1] << 16) | (mac_ip1[2] << 8) | 0xFF; + ipv6_address_ip1[i][j].nxd_ip_address.v6[3] = + (0xFE << 24) | ((mac_ip1[3] | 0x2) << 16) | (mac_ip1[4] << 8) | mac_ip1[5]; + + status = nxd_ipv6_address_set(&ip_0, i, &ipv6_address_ip0[i][j], 10, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, i, &ipv6_address_ip1[i][j], 10, NX_NULL); + } + else + { + /* Global Adddress */ + ipv6_address_ip0[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0[i][j].nxd_ip_address.v6[0] = 0x20000000 + i; + ipv6_address_ip0[i][j].nxd_ip_address.v6[1] = j; + ipv6_address_ip0[i][j].nxd_ip_address.v6[2] = ipv6_address_ip0[i][0].nxd_ip_address.v6[2]; + ipv6_address_ip0[i][j].nxd_ip_address.v6[3] = ipv6_address_ip0[i][0].nxd_ip_address.v6[3]; + + ipv6_address_ip1[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1[i][j].nxd_ip_address.v6[0] = 0x20000000 + i; + ipv6_address_ip1[i][j].nxd_ip_address.v6[1] = j; + ipv6_address_ip1[i][j].nxd_ip_address.v6[2] = ipv6_address_ip1[i][0].nxd_ip_address.v6[2]; + ipv6_address_ip1[i][j].nxd_ip_address.v6[3] = ipv6_address_ip1[i][0].nxd_ip_address.v6[3]; + + + status = nxd_ipv6_address_set(&ip_0, i, &ipv6_address_ip0[i][j], 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, i, &ipv6_address_ip1[i][j], 64, NX_NULL); + } + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1[i][j].nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0[i][j].nxd_ip_address.v6, 0, mac_ip0); + } + + } + + + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + + + if(status) + error_counter++; +#endif + + /* Wait for the semaphore to signal the other party is ready. */ + tx_semaphore_get(&sema, 2 * NX_IP_PERIODIC_RATE); + + for(iface = 0; iface < 3; iface++) + { + test_udp4_on_interface(iface); + + tx_semaphore_get(&sema, 2 * NX_IP_PERIODIC_RATE); + +#ifdef FEATURE_NX_IPV6 + for(addr_index = 1; addr_index < 3; addr_index++) + { + + test_udp6_on_interface_address(iface, addr_index); + + tx_semaphore_get(&sema, 2 * NX_IP_PERIODIC_RATE); + } + +#endif + } + + + tx_semaphore_delete(&sema); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void ntest_1_entry(ULONG thread_input) +{ +ULONG actual_status; +UINT status; +UINT iface; +NX_PACKET *packet_ptr; +NX_UDP_SOCKET server_socket; +ULONG peer_ip; +UINT peer_port; +NX_IPV4_HEADER *ipv4_header; +#ifdef FEATURE_NX_IPV6 +NX_IPV6_HEADER *ipv6_header; +UINT addr_index; +NXD_ADDRESS peer6_ip; +#endif + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + if(status) + error_counter++; + + status = nx_udp_socket_bind(&server_socket, 12346, NX_WAIT_FOREVER); + + tx_semaphore_put(&sema); + + + for(iface = 0; iface < 3; iface++) + { + + status = nx_udp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + + /* Check status... */ + if (status != NX_SUCCESS) + error_counter++; + else + { +#ifdef __PRODUCT_NETXDUO__ + ipv4_header = (NX_IPV4_HEADER*)packet_ptr -> nx_packet_ip_header; +#else + ipv4_header = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr - 28); +#endif + status = nx_udp_source_extract(packet_ptr, &peer_ip, &peer_port); + if(status != NX_SUCCESS) + error_counter++; + if(peer_ip != ip0_address[iface]) + error_counter++; + if(peer_port != 12345) + error_counter++; + if(ipv4_header -> nx_ip_header_destination_ip != ip1_address[iface]) + error_counter++; + if((packet_ptr -> nx_packet_length != strlen(bsd4_msg[iface])) || + (memcmp(packet_ptr -> nx_packet_prepend_ptr, bsd4_msg[iface], packet_ptr -> nx_packet_length))) + error_counter++; + + nx_packet_release(packet_ptr); + } + + tx_semaphore_put(&sema); + +#ifdef FEATURE_NX_IPV6 + for(addr_index = 1; addr_index < 3; addr_index++) + { + status = nx_udp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + + if(status != NX_SUCCESS) + error_counter++; + else + { + ipv6_header = (NX_IPV6_HEADER*)packet_ptr -> nx_packet_ip_header; + status = nxd_udp_source_extract(packet_ptr, &peer6_ip, &peer_port); + if(status != NX_SUCCESS) + error_counter++; + if((peer6_ip.nxd_ip_version != NX_IP_VERSION_V6) || + (peer6_ip.nxd_ip_address.v6[0] != ipv6_address_ip0[iface][addr_index].nxd_ip_address.v6[0]) || + (peer6_ip.nxd_ip_address.v6[1] != ipv6_address_ip0[iface][addr_index].nxd_ip_address.v6[1]) || + (peer6_ip.nxd_ip_address.v6[2] != ipv6_address_ip0[iface][addr_index].nxd_ip_address.v6[2]) || + (peer6_ip.nxd_ip_address.v6[3] != ipv6_address_ip0[iface][addr_index].nxd_ip_address.v6[3])) + error_counter++; + if((ipv6_header -> nx_ip_header_destination_ip[0] != ipv6_address_ip1[iface][addr_index].nxd_ip_address.v6[0]) || + (ipv6_header -> nx_ip_header_destination_ip[1] != ipv6_address_ip1[iface][addr_index].nxd_ip_address.v6[1]) || + (ipv6_header -> nx_ip_header_destination_ip[2] != ipv6_address_ip1[iface][addr_index].nxd_ip_address.v6[2]) || + (ipv6_header -> nx_ip_header_destination_ip[3] != ipv6_address_ip1[iface][addr_index].nxd_ip_address.v6[3])) + error_counter++; + if(peer_port != 12345) + error_counter++; + + if((packet_ptr -> nx_packet_length != strlen(bsd6_msg[iface][addr_index])) || + (memcmp(packet_ptr -> nx_packet_prepend_ptr, bsd6_msg[iface][addr_index], packet_ptr -> nx_packet_length))) + error_counter++; + + nx_packet_release(packet_ptr); + + tx_semaphore_put(&sema); + } + } +#endif + } +} + +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_bind_connect_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD UDP Bind Connect Send Test..........N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_udp_bind_test.c b/test/regression/bsd_test/netx_bsd_udp_bind_test.c new file mode 100644 index 00000000..c8c41cfb --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_udp_bind_test.c @@ -0,0 +1,1268 @@ +/* This NetX test concentrates on the basic BSD UDP non-blocking operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) + +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static TX_SEMAPHORE netx_sema; +static TX_SEMAPHORE bsd_sema; + +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0[3][3]; +static NXD_ADDRESS ipv6_address_ip1[3][3]; +#endif /* FEATURE_NX_IPV6 */ +static char *requests[4] = {"Request1", "Request22", "Request333", "Request4444"}; +static char *response[4] = {"Response1", "Response22", "Response333", "Response4444"}; +static void validate_bsd_structure(void); + +#define IP0_IF0_V4_ADDR IP_ADDRESS(1,2,3,4) +#define IP0_IF1_V4_ADDR IP_ADDRESS(2,2,3,4) +#define IP0_IF2_V4_ADDR IP_ADDRESS(3,2,3,4) + +#define IP1_IF0_V4_ADDR IP_ADDRESS(1,2,3,5) +#define IP1_IF1_V4_ADDR IP_ADDRESS(2,2,3,5) +#define IP1_IF2_V4_ADDR IP_ADDRESS(3,2,3,5) + +#define ITERATIONS 100 +static ULONG ip0_address[3] = {IP0_IF0_V4_ADDR, IP0_IF1_V4_ADDR, IP0_IF2_V4_ADDR}; +static ULONG ip1_address[3] = {IP1_IF0_V4_ADDR, IP1_IF1_V4_ADDR, IP1_IF2_V4_ADDR}; +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_bind_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP0_IF0_V4_ADDR, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Attach a 2nd interface */ + status += nx_ip_interface_attach(&ip_0, "ip_0_second", IP0_IF1_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_0, "ip_0_third", IP0_IF2_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP1_IF0_V4_ADDR, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_1, "ip_1_second", IP1_IF1_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1, "ip_1_third", IP1_IF2_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check UDP enable and BSD init status. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&netx_sema, "NetX SEMA", 0); + status += tx_semaphore_create(&bsd_sema, "BSD SEMA", 0); + if(status != TX_SUCCESS) + error_counter++; + + + +} + +static int sent_msg_id; +static int sent_if; +#ifdef FEATURE_NX_IPV6 +static int sent_addr; +#endif + + +#ifdef FEATURE_NX_IPV6 +static void test_udp_server6_bind_to_ANY(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; +int message_count = 0; + + + sockfd = socket(AF_INET6, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_family = AF_INET6; + local_addr.sin6_port = htons(12345); + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + error_counter += (ITERATIONS * 2); + + while(message_count < ITERATIONS) + { + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + else if(addrlen != sizeof(struct sockaddr_in6)) + error_counter++; + else if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1[(message_count / 2) % 3][(message_count & 1) + 1].nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1[(message_count / 2) % 3][(message_count & 1) + 1].nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1[(message_count / 2) % 3][(message_count & 1) + 1].nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1[(message_count / 2) % 3][(message_count & 1) + 1].nxd_ip_address.v6[3])) || + (remote_addr.sin6_port != htons(54321))) + error_counter++; + /* Validate the data. */ + else if((ret != (INT)strlen(requests[message_count & 3])) || strncmp(buf, requests[message_count & 3], ret)) + error_counter++; + else + error_counter--; + + /* Send a response back. */ + ret = sendto(sockfd, response[message_count & 3], strlen(response[message_count & 3]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (INT)strlen(response[message_count & 3])) + error_counter++; + + message_count ++; + } + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +static void test_udp6_on_interface_address(int iface, int address, INT reuseaddr) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; + + + sockfd = socket(AF_INET6, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + if(reuseaddr) + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(INT)); + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_port = htons(12345); + local_addr.sin6_family = AF_INET6; + if(iface != 3) + { + local_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[0]); + local_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[1]); + local_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[2]); + local_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip0[iface][address].nxd_ip_address.v6[3]); + } + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + else if(addrlen != sizeof(struct sockaddr_in6)) + error_counter++; + else if((remote_addr.sin6_family != AF_INET6) || + (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1[sent_if][sent_addr].nxd_ip_address.v6[0])) || + (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1[sent_if][sent_addr].nxd_ip_address.v6[1])) || + (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1[sent_if][sent_addr].nxd_ip_address.v6[2])) || + (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1[sent_if][sent_addr].nxd_ip_address.v6[3])) || + (remote_addr.sin6_port != htons(54321))) + error_counter++; + /* Make sure the source and the dest are in the same prefix range. */ + else if((iface != 3) && + ((ntohl(remote_addr.sin6_addr._S6_un._S6_u32[0]) != ipv6_address_ip0[iface][address].nxd_ip_address.v6[0]) || + (ntohl(remote_addr.sin6_addr._S6_un._S6_u32[1]) != ipv6_address_ip0[iface][address].nxd_ip_address.v6[1]))) + error_counter++; + /* Validate the data. */ + else if((ret != (INT)strlen(requests[sent_msg_id])) || strncmp(buf, requests[sent_msg_id], ret)) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + + +#endif /* FEATURE_NX_IPV6 */ + +static void test_udp_server4_bind_to_ANY(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; +int message_count = 0; + + error_counter += (ITERATIONS * 2); + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + /* Test bind to port 0. */ + local_addr.sin_family = AF_INET; + local_addr.sin_port = 0; + local_addr.sin_addr.s_addr = INADDR_ANY; + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + addrlen = sizeof(local_addr); + ret = getsockname(sockfd, (struct sockaddr*)&local_addr, &addrlen); + if(ret < 0) + error_counter++; + + /* Check whether port is zero. */ + if (local_addr.sin_port == 0) + error_counter++; + soc_close(sockfd); + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + while(message_count < ITERATIONS) + { + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + else if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(ip1_address[message_count % 3])) || + (remote_addr.sin_port != htons(54321))) + error_counter++; + /* Validate the data. */ + else if((ret != (int)strlen(requests[message_count & 3])) || strncmp(buf, requests[message_count & 3], ret)) + error_counter++; + else + error_counter--; + + + /* Send a response back. */ + ret = sendto(sockfd, response[message_count & 3], strlen(response[message_count & 3]), 0, (struct sockaddr*)&remote_addr, addrlen); + if(ret != (int)strlen(response[message_count & 3])) + error_counter++; + message_count ++; + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 100); + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} + +static void test_udp_server4_bind_to_AF_INET(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; +int message_count = 0; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + while(message_count < 3) + { + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + else if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(ip1_address[sent_if])) || + (remote_addr.sin_port != htons(54321))) + error_counter++; + /* Validate the data. */ + else if((ret != (int)strlen(requests[sent_msg_id])) || strncmp(buf, requests[sent_msg_id], ret)) + error_counter++; + message_count++; + + } + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} +static TX_THREAD client_threads[3]; +static ULONG client_thread_stack_area[3][DEMO_STACK_SIZE / sizeof(ULONG)]; +static void test_udp4_on_interface(int i, INT reuseaddr); + +#ifdef FEATURE_NX_IPV6 +static void test_udp6_on_interface_address(int iface, int address, INT reuseaddr); +static VOID client6_thread_entry(ULONG param) +{ +INT reuseaddr = 1; + + if(param == 0) + test_udp6_on_interface_address((int)param, 1, reuseaddr); + else + test_udp6_on_interface_address((int)param, param, reuseaddr); + + + tx_semaphore_put(&bsd_sema); + +} +#endif + +static VOID client_thread_entry(ULONG param) +{ +INT reuseaddr = 1; + test_udp4_on_interface((int)param, reuseaddr); + + tx_semaphore_put(&bsd_sema); + +} + + + +static void test_udp_bind_to_three_interfaces(int if1, int if2, int if3) +{ +int i; +UINT status; + + /* Wait for the client to be ready. */ + status = tx_semaphore_put(&netx_sema); + + if(status != TX_SUCCESS) + error_counter++; + /* Create 3 threads, each binds to a different interface. */ + tx_thread_create(&client_threads[0], "client thread0", client_thread_entry, if1, + (CHAR*)client_thread_stack_area[0], DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + tx_thread_create(&client_threads[1], "client thread1", client_thread_entry, if2, + (CHAR*)client_thread_stack_area[1], DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + tx_thread_create(&client_threads[2], "client thread2", client_thread_entry, if3, + (CHAR*)client_thread_stack_area[2], DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Wait for all three threads to quite. */ + for(i = 0; i < 3; i++) + { + status = tx_semaphore_get(&bsd_sema, 2 * NX_IP_PERIODIC_RATE); + if(status == TX_NO_INSTANCE) + error_counter++; + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 50); + + for(i = 0; i < 3; i++) + status += tx_thread_delete(&client_threads[i]); + if(status) + error_counter++; + +} +#ifdef FEATURE_NX_IPV6 +static void test_udp_bind_to_ipv6_addresses(int if1, int if2, int if3) +{ +int i; +UINT status; + + + status = tx_semaphore_put(&netx_sema); + + if(status != TX_SUCCESS) + error_counter++; + /* Create 3 threads, each binds to a different interface. */ + tx_thread_create(&client_threads[0], "client thread0", client6_thread_entry, if1, + (CHAR*)client_thread_stack_area[0], DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + tx_thread_create(&client_threads[1], "client thread1", client6_thread_entry, if2, + (CHAR*)client_thread_stack_area[1], DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + tx_thread_create(&client_threads[2], "client thread1", client6_thread_entry, if3, + (CHAR*)client_thread_stack_area[2], DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Wait for all three threads to quite. */ + for(i = 0; i < 3; i++) + { + status = tx_semaphore_get(&bsd_sema, NX_IP_PERIODIC_RATE); + if(status == TX_NO_INSTANCE) + error_counter++; + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 50); + + for(i = 0; i < 3; i++) + status += tx_thread_delete(&client_threads[i]); + if(status) + error_counter++; + +} +#endif +static void test_udp4_on_interface(int i, INT reuseaddr) +{ + +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; + + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + if(reuseaddr) + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(INT)); + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + if(i == 3) + local_addr.sin_addr.s_addr = htonl(INADDR_ANY); + else + local_addr.sin_addr.s_addr = htonl(ip0_address[i]); + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + else if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(ip1_address[sent_if])) || + (remote_addr.sin_port != htons(54321))) + error_counter++; + /* Make sure the remote address and local address are on the same subnet*/ + else if((i < 3) && ((ntohl(remote_addr.sin_addr.s_addr) & 0xFFFFFF * NX_IP_PERIODIC_RATE) != (ip0_address[i] & 0xFFFFFF * NX_IP_PERIODIC_RATE))) + error_counter++; + /* Validate the data. */ + else if((ret != (int)strlen(requests[sent_msg_id])) || strncmp(buf, requests[sent_msg_id], ret)) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + +} +#define NUM_MESSAGES 5 +static void test_udp4_receive_multiple(int iface) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; +int packet_count; +UINT status; +NX_BSD_SOCKET *bsd_socket_ptr; + + status = tx_semaphore_put(&netx_sema); + + if(status != TX_SUCCESS) + error_counter++; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + if(iface == 3) + local_addr.sin_addr.s_addr = htonl(INADDR_ANY); + else + local_addr.sin_addr.s_addr = htonl(ip0_address[iface]); + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + /* Sleep for three tick, gives the client a chance to send 10 packets. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE / 20); + + packet_count = 0; + bsd_socket_ptr = &nx_bsd_socket_array[sockfd - NX_BSD_SOCKFD_START]; + while(bsd_socket_ptr -> nx_bsd_socket_received_packet) + { + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); + if(ret <= 0) + error_counter++; + else if(addrlen != sizeof(struct sockaddr_in)) + error_counter++; + else if((remote_addr.sin_family != AF_INET) || + (remote_addr.sin_addr.s_addr != htonl(ip1_address[iface])) || + (remote_addr.sin_port != htons(54321))) + error_counter++; + /* Make sure the remote address and local address are on the same subnet*/ + else if((iface < 3) && ((ntohl(remote_addr.sin_addr.s_addr) & 0xFFFFFF * NX_IP_PERIODIC_RATE) != (ip0_address[iface] & 0xFFFFFF * NX_IP_PERIODIC_RATE))) + error_counter++; + /* Validate the data. */ + else if((ret != (int)strlen(requests[packet_count & 3])) || strncmp(buf, requests[packet_count & 3], ret)) + error_counter++; + else + packet_count ++; + } + + if(packet_count != NUM_MESSAGES) + error_counter++; + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + + +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +static char mac_ip0[6]; +static char mac_ip1[6]; +int j; +UINT status; +#endif +int i; + +INT reuseaddr = 0; + + + printf("NetX Test: Basic BSD UDP Bind Test......................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + + for(i = 0; i < 3; i++) + { + mac_ip0[0] = (char)(ip_0.nx_ip_interface[i].nx_interface_physical_address_msw >> 8); + mac_ip0[1] = ip_0.nx_ip_interface[i].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = (char)(ip_1.nx_ip_interface[i].nx_interface_physical_address_msw >> 8); + mac_ip1[1] = ip_1.nx_ip_interface[i].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw & 0xff; + + for(j = 0; j < 3; j ++) + { + if(j == 0) + { + /* First set up IPv6 linklocal addresses. */ + ipv6_address_ip0[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0[i][j].nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0[i][j].nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0[i][j].nxd_ip_address.v6[2] = ((mac_ip0[0] | 0x2) << 24) | (mac_ip0[1] << 16) | (mac_ip0[2] << 8) | 0xFF; + ipv6_address_ip0[i][j].nxd_ip_address.v6[3] = (0xFE << 24) | ((mac_ip0[3] | 0x2) << 16) | (mac_ip0[4] << 8) | mac_ip0[5]; + + ipv6_address_ip1[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1[i][j].nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1[i][j].nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1[i][j].nxd_ip_address.v6[2] = + ((mac_ip1[0] | 0x2) << 24) | (mac_ip1[1] << 16) | (mac_ip1[2] << 8) | 0xFF; + ipv6_address_ip1[i][j].nxd_ip_address.v6[3] = + (0xFE << 24) | ((mac_ip1[3] | 0x2) << 16) | (mac_ip1[4] << 8) | mac_ip1[5]; + + status = nxd_ipv6_address_set(&ip_0, i, &ipv6_address_ip0[i][j], 10, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, i, &ipv6_address_ip1[i][j], 10, NX_NULL); + } + else + { + /* Global Adddress */ + ipv6_address_ip0[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0[i][j].nxd_ip_address.v6[0] = 0x20000000 + i; + ipv6_address_ip0[i][j].nxd_ip_address.v6[1] = j; + ipv6_address_ip0[i][j].nxd_ip_address.v6[2] = ipv6_address_ip0[i][0].nxd_ip_address.v6[2]; + ipv6_address_ip0[i][j].nxd_ip_address.v6[3] = ipv6_address_ip0[i][0].nxd_ip_address.v6[3]; + + ipv6_address_ip1[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1[i][j].nxd_ip_address.v6[0] = 0x20000000 + i; + ipv6_address_ip1[i][j].nxd_ip_address.v6[1] = j; + ipv6_address_ip1[i][j].nxd_ip_address.v6[2] = ipv6_address_ip1[i][0].nxd_ip_address.v6[2]; + ipv6_address_ip1[i][j].nxd_ip_address.v6[3] = ipv6_address_ip1[i][0].nxd_ip_address.v6[3]; + + + status = nxd_ipv6_address_set(&ip_0, i, &ipv6_address_ip0[i][j], 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, i, &ipv6_address_ip1[i][j], 64, NX_NULL); + } + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1[i][j].nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0[i][j].nxd_ip_address.v6, 0, mac_ip0); + } + + } + + + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + + + if(status) + error_counter++; +#endif + tx_semaphore_put(&netx_sema); + test_udp_server4_bind_to_ANY(); + +#ifdef FEATURE_NX_IPV6 + tx_semaphore_put(&netx_sema); + test_udp_server6_bind_to_ANY(); +#endif + + /* Make sure a bind to IPv4 Address Family won't received UDP sent to IPv6 address. */ + tx_semaphore_put(&netx_sema); + test_udp_server4_bind_to_AF_INET(); + +#ifdef FEATURE_NX_IPV6 + /* Make sure a bind to IPv6 Address Family won't received UDP sent to IPv4 address. */ + tx_semaphore_put(&netx_sema); + test_udp6_on_interface_address(3, 0, 0); +#endif + + /* Make sure a bind to interface 1 address does not receive UDP sent to interface2 and 3 addresses. */ + for(i = 0; i < 3; i++) + { + tx_semaphore_put(&netx_sema); + test_udp4_on_interface(i, reuseaddr); + +#ifdef FEATURE_NX_IPV6 + /* Make sure a bind to an IPv6 address does not receive UDP sent to another IPv6 address. */ + for(j = 1; j < 3; j++) + { + tx_semaphore_put(&netx_sema); + test_udp6_on_interface_address(i, j, 0); + } + + +#endif + } + + /* Test UDP sockets binding to address1, 2, 3 are able to receive packets according to their + binding information */ + test_udp_bind_to_three_interfaces(0, 1, 2); + + /* Test UDP sockets binding to address1, 3, and another bind to INADDR_ANY. + Traffic to address 1 goes to the INADDR_ANY bind. */ + test_udp_bind_to_three_interfaces(0, 2, 3); + + + /* Test UDP sockets binding to INADDR_ANY, address0, 3. + Traffic to address 1 goes to the INADDR_ANY bind. */ + test_udp_bind_to_three_interfaces(3, 2, 0); + + +#ifdef FEATURE_NX_IPV6 + /* Test UDP sockets binding to 3 different IPv6 addresses */ + test_udp_bind_to_ipv6_addresses(0, 1, 2); + + /* Test UDP sockets binding to 2 different IPv6 addresses and a 3rd one to INADDR_ANY + and be able to catch all. */ + test_udp_bind_to_ipv6_addresses(0, 1, 3); + + test_udp_bind_to_ipv6_addresses(3, 2, 0); + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + +#endif + + test_udp4_receive_multiple(1); + + tx_semaphore_delete(&bsd_sema); + tx_semaphore_delete(&netx_sema); + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +#ifdef FEATURE_NX_IPV6 +static void udp_client6_to_ANY(void) +{ + +UINT status; +NX_PACKET *packet_ptr; +int message_counter = 0; + + status = tx_semaphore_get(&netx_sema, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + while(message_counter < ITERATIONS) + { + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[message_counter & 3], strlen(requests[message_counter & 3])); + + packet_ptr -> nx_packet_length = strlen(requests[message_counter & 3]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Send a UDP packet */ + status = nxd_udp_socket_send(&server_socket, packet_ptr, &ipv6_address_ip0[(message_counter / 2) % 3][(message_counter & 1) + 1], 12345); + if(status) + error_counter++; + + /* Ready to reaceive a message */ + status = nx_udp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Validate the content. */ + if(packet_ptr -> nx_packet_length != strlen(response[message_counter & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[message_counter & 3], strlen(response[message_counter & 3]))) + error_counter++; + else + error_counter--; + nx_packet_release(packet_ptr); + message_counter ++; + } + status = nx_udp_socket_unbind(&server_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&server_socket); + if(status) + error_counter++; +} +#endif + +static void udp_client_to_AF_INET_AF_INET6(void) +{ + +UINT status; +NX_PACKET *packet_ptr; +int message_count = 0; +int i; +#ifdef FEATURE_NX_IPV6 +int j; +#endif + status = tx_semaphore_get(&netx_sema, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + for(i = 2; i >= 0; i--) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[message_count & 3], strlen(requests[message_count & 3])); + + packet_ptr -> nx_packet_length = strlen(requests[message_count & 3]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + sent_msg_id = message_count & 3; + sent_if = i; + /* Send a UDP packet */ + status = nx_udp_socket_send(&server_socket, packet_ptr, ip0_address[i], 12345); + if(status) + error_counter++; + + message_count ++; +#ifdef FEATURE_NX_IPV6 + + for(j = 0; j < 2; j++) + { + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[message_count & 3], strlen(requests[message_count & 3])); + + packet_ptr -> nx_packet_length = strlen(requests[message_count & 3]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + + /* Send a UDP packet */ + sent_msg_id = message_count & 3; + sent_if = i; + sent_addr = j + 1; + status = nxd_udp_socket_send(&server_socket, packet_ptr, &ipv6_address_ip0[i][j + 1], 12345); + if(status) + error_counter++; + message_count ++; + } +#endif + } + + status = nx_udp_socket_unbind(&server_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&server_socket); + if(status) + error_counter++; +} + + +static void udp_client4_to_ANY(void) +{ + +UINT status; +NX_PACKET *packet_ptr; +int message_count = 0; + + + status = tx_semaphore_get(&netx_sema, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + while(message_count < ITERATIONS) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[message_count & 3], strlen(requests[message_count & 3])); + + packet_ptr -> nx_packet_length = strlen(requests[message_count & 3]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + + /* Send a UDP packet */ + status = nx_udp_socket_send(&server_socket, packet_ptr, ip0_address[message_count % 3], 12345); + if(status) + error_counter++; + + /* Ready to reaceive a message */ + status = nx_udp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + if(status) + error_counter++; + /* Validate the content. */ + else if(packet_ptr -> nx_packet_length != strlen(response[message_count & 3])) + error_counter++; + else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[message_count & 3], strlen(response[message_count & 3]))) + error_counter++; + else + error_counter--; + nx_packet_release(packet_ptr); + + message_count ++; + } + + status = nx_udp_socket_unbind(&server_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&server_socket); + if(status) + error_counter++; + + +} + + + +static void udp_client4_to_interface(int iface) +{ + +UINT status; +NX_PACKET *packet_ptr; +int message_count = 0; + + status = tx_semaphore_get(&netx_sema, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + while(message_count < NUM_MESSAGES) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[message_count & 3], strlen(requests[message_count & 3])); + + packet_ptr -> nx_packet_length = strlen(requests[message_count & 3]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + + /* Send a UDP packet */ + status = nx_udp_socket_send(&server_socket, packet_ptr, ip0_address[iface], 12345); + if(status) + error_counter++; + + message_count ++; + } + + status = nx_udp_socket_unbind(&server_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&server_socket); + if(status) + error_counter++; + + +} + + + + + + +static void ntest_1_entry(ULONG thread_input) +{ +ULONG actual_status; +UINT status; +UINT i; +#ifdef FEATURE_NX_IPV6 +UINT j; +#endif + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + udp_client4_to_ANY(); + +#ifdef FEATURE_NX_IPV6 + + udp_client6_to_ANY(); + +#endif + + /* Make sure a bind to IPv4 Address Family won't received UDP sent to IPv6 address. */ + udp_client_to_AF_INET_AF_INET6(); + +#ifdef FEATURE_NX_IPV6 + + /* Make sure a bind to IPv6 Address Family won't received UDP sent to IPv4 address. */ + udp_client_to_AF_INET_AF_INET6(); +#endif + + /* Test UDP bind to 3 different interfaces, each with one IPv4, and 2 IPv6 GA. */ + /* So total there are 9 different addresses to test for. */ + for(i = 0; i < 3; i++) + { +#if 0 + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); +#endif + udp_client_to_AF_INET_AF_INET6(); + +#ifdef FEATURE_NX_IPV6 + + /* Make sure a bind to an IPv6 address does not receive UDP sent to another IPv6 address. */ + for(j = 1; j < 3; j++) + { +#if 0 + tx_semaphore_get(&netx_sema); +#endif + udp_client_to_AF_INET_AF_INET6(); + } + +#endif + } + + /* Start testing test_udp_bind_to_three_interfaces(0,1,2);*/ + udp_client_to_AF_INET_AF_INET6(); + + /* Start testing test_udp_bind_to_three_interfaces(0,2,3);*/ + udp_client_to_AF_INET_AF_INET6(); + + /* Start testing test_udp_bind_to_three_interfaces(3, 2,0);*/ + udp_client_to_AF_INET_AF_INET6(); + +#ifdef FEATURE_NX_IPV6 + /* Start testing test_udp_bind_to_ipv6_addresses */ + udp_client_to_AF_INET_AF_INET6(); + + /* Start testing test_udp_bind_to_ipv6_addresses */ + udp_client_to_AF_INET_AF_INET6(); + + + /* Start testing test_udp_bind_to_ipv6_addresses */ + udp_client_to_AF_INET_AF_INET6(); +#endif + udp_client4_to_interface(1); + +} + +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_bind_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD UDP Bind Test.......................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_udp_blocking_bidirection_test.c b/test/regression/bsd_test/netx_bsd_udp_blocking_bidirection_test.c new file mode 100644 index 00000000..5576e3be --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_udp_blocking_bidirection_test.c @@ -0,0 +1,680 @@ +/* This NetX test concentrates on the basic BSD UDP blocking operation. */ +/* The BSD APIs involved in this test are: socket(), connect(), send(), soc_close() */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 +#define NUM_MESSAGES 20 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 10 +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0; +static NXD_ADDRESS ipv6_address_ip1; +#endif +static char *bsd_send_buffer = "From BSD Test"; +static char *netx_send_buffer = "From Native NetX Test"; +#ifdef FEATURE_NX_IPV6 +static char *bsd_send_buffer6 = "From BSD Test 6"; +static char *netx_send_buffer6 = "From Native NetX Test 6"; +#endif + +static void validate_bsd_structure(void); + +static char *bsd_transmit_v4_thread_stack; +static char *bsd_receive_v4_thread_stack; +static char *netx_transmit_thread_stack; +static char *netx_receive_thread_stack; + + +static TX_THREAD netx_transmit_thread; +static TX_THREAD netx_receive_thread; +static TX_THREAD bsd_transmit_v4_thread; +static TX_THREAD bsd_receive_v4_thread; + + + +#ifdef FEATURE_NX_IPV6 +static char *bsd_transmit_v6_thread_stack; +static char *bsd_receive_v6_thread_stack; + +static TX_THREAD bsd_transmit_v6_thread; +static TX_THREAD bsd_receive_v6_thread; +#endif + +static TX_SEMAPHORE bsd_sema; +static TX_SEMAPHORE netx_sema; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_blocking_bidirection_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area)); + + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check UDP enable status. */ + if (status) + error_counter++; + + netx_transmit_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + netx_receive_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + + bsd_transmit_v4_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + bsd_receive_v4_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + +#ifdef FEATURE_NX_IPV6 + bsd_transmit_v6_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; + bsd_receive_v6_thread_stack = pointer; + pointer = pointer + DEMO_STACK_SIZE; +#endif + + status = tx_semaphore_create(&netx_sema, "NetX test done", 0); + status += tx_semaphore_create(&bsd_sema, "BSD test done", 0); + if(status != TX_SUCCESS) + error_counter++; +} + +static void transmit_entry(ULONG thread_input) +{ +int sockfd = thread_input; +int ret; +int i; +struct sockaddr_in peer_addr; + + + for(i = 0; i < NUM_MESSAGES; i++) + { + + peer_addr.sin_family = AF_INET; + peer_addr.sin_port = htons(12345); + peer_addr.sin_addr.s_addr = htonl(IP_ADDRESS(1, 2, 3, 5)); + + ret = sendto(sockfd, bsd_send_buffer, strlen(bsd_send_buffer), 0, (struct sockaddr*)&peer_addr, sizeof(peer_addr)); + + if(ret != (int)strlen(bsd_send_buffer)) + error_counter++; + + tx_thread_relinquish(); + } + + tx_semaphore_put(&bsd_sema); + +} + +static void receive_entry(ULONG thread_input) +{ +int sockfd = thread_input; +int ret; +int i; +char buffer[30]; +struct sockaddr_in peer_addr; +int peer_addr_len; + + + for(i = 0; i < NUM_MESSAGES; i++) + { + peer_addr_len = sizeof(peer_addr); + + ret = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&peer_addr, &peer_addr_len); + + if(peer_addr_len != sizeof(peer_addr)) + error_counter++; + else if((peer_addr.sin_family != AF_INET) || + (peer_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1, 2, 3, 5)))) + error_counter++; + + if(ret != (int)strlen(netx_send_buffer)) + error_counter++; + else if(strncmp(buffer, netx_send_buffer, ret)) + error_counter++; + + tx_thread_relinquish(); + } + + tx_semaphore_put(&bsd_sema); + +} + +#ifdef FEATURE_NX_IPV6 +static void transmit6_entry(ULONG thread_input) +{ +int sockfd = thread_input; +int ret; +int i; +struct sockaddr_in6 peer_address6; + + + + for(i = 0; i < NUM_MESSAGES; i++) + { + + peer_address6.sin6_family = AF_INET6; + peer_address6.sin6_port = htons(12345); + peer_address6.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip1.nxd_ip_address.v6[0]); + peer_address6.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip1.nxd_ip_address.v6[1]); + peer_address6.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip1.nxd_ip_address.v6[2]); + peer_address6.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip1.nxd_ip_address.v6[3]); + + ret = sendto(sockfd, bsd_send_buffer6, strlen(bsd_send_buffer6), 0, (struct sockaddr*)&peer_address6, sizeof(peer_address6)); + + if(ret != (INT)strlen(bsd_send_buffer6)) + error_counter++; + + tx_thread_relinquish(); + } + + tx_semaphore_put(&bsd_sema); + +} + +static void receive6_entry(ULONG thread_input) +{ +int sockfd = thread_input; +int ret; +int i; +char buffer[30]; +struct sockaddr_in6 peer_addr; +int peer_addr_len; + + for(i = 0; i < NUM_MESSAGES; i++) + { + peer_addr_len = sizeof(peer_addr); + + ret = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&peer_addr, &peer_addr_len); + + if(peer_addr_len != sizeof(peer_addr)) + error_counter++; + else if((peer_addr.sin6_family != AF_INET6) || + (peer_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) || + (peer_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) || + (peer_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) || + (peer_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3]))) + error_counter++; + + + if(ret != (INT)strlen(netx_send_buffer6)) + error_counter++; + else if(strncmp(buffer, netx_send_buffer6, ret)) + error_counter++; + + tx_thread_relinquish(); + } + + tx_semaphore_put(&bsd_sema); + +} + +#endif + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +int sockfd; +struct sockaddr_in local_addr; +UINT status; +#ifdef FEATURE_NX_IPV6 +struct sockaddr_in6 local_addr6; +char mac_ip0[6]; +char mac_ip1[6]; +int sockfd6; +INT reuseaddr = 1; +#endif +int ret; + + printf("NetX Test: Basic BSD UDP Blocking Bidirection Test......."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef FEATURE_NX_IPV6 + /* First set up IPv6 addresses. */ + ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456; + + ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL); + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8; + mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff; + + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0); + + if(status) + error_counter++; + + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif + tx_semaphore_put(&netx_sema); + + /* Set up UDP socket */ + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd <= 0) + error_counter++; + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + + tx_thread_sleep(20); + + /* Create a thread to handle IPv4 UDP receive */ + ret = tx_thread_create(&bsd_transmit_v4_thread, "transmit v4 thread", transmit_entry, sockfd, + bsd_transmit_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + ret += tx_thread_create(&bsd_receive_v4_thread, "receive v4 thread", receive_entry, sockfd, + bsd_receive_v4_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + if(ret != TX_SUCCESS) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Set up UDP socket */ + sockfd6 = socket(AF_INET6, SOCK_DGRAM, 0); + if(sockfd6 <= 0) + error_counter++; + + setsockopt(sockfd6, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(INT)); + memset(&local_addr6, 0, sizeof(local_addr6)); + local_addr6.sin6_family = AF_INET6; + local_addr6.sin6_port = htons(12345); + + ret = bind(sockfd6, (struct sockaddr*)&local_addr6, sizeof(local_addr6)); + if(ret) + error_counter++; + + /* Create a thread to handle IPv6 UDP receive */ + ret = tx_thread_create(&bsd_transmit_v6_thread, "transmit v6 thread", transmit6_entry, sockfd6, + bsd_transmit_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + ret += tx_thread_create(&bsd_receive_v6_thread, "receive v6 thread", receive6_entry, sockfd6, + bsd_receive_v6_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + if(ret != TX_SUCCESS) + error_counter++; + +#endif + + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + + /* Close down both sockets. */ +#ifdef FEATURE_NX_IPV6 + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + status = tx_semaphore_get(&bsd_sema, TX_WAIT_FOREVER); + ret = soc_close(sockfd6); +#endif + ret += soc_close(sockfd); + if(ret) + error_counter++; +#ifdef FEATURE_NX_IPV6 + tx_thread_delete(&bsd_transmit_v6_thread); + tx_thread_delete(&bsd_receive_v6_thread); +#endif + + tx_thread_delete(&bsd_transmit_v4_thread); + tx_thread_delete(&bsd_receive_v4_thread); + + if(status) + error_counter++; + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void netx_transmit_entry(ULONG param) +{ +NX_UDP_SOCKET *socket_ptr = (NX_UDP_SOCKET*)param; +int i; +NX_PACKET *packet_ptr; +ULONG status; + + + for(i = 0; i < NUM_MESSAGES; i++) + { + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, netx_send_buffer, strlen(netx_send_buffer), + &pool_0, NX_NO_WAIT); + status += nx_udp_socket_send(socket_ptr, packet_ptr, IP_ADDRESS(1,2,3,4), 12345); + + if(status != NX_SUCCESS) + error_counter++; +#ifdef FEATURE_NX_IPV6 + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(packet_ptr, netx_send_buffer6, strlen(netx_send_buffer6), + &pool_0, NX_NO_WAIT); + status += nxd_udp_socket_send(socket_ptr, packet_ptr, &ipv6_address_ip0, 12345); + + if(status != NX_SUCCESS) + error_counter++; +#endif + + tx_thread_relinquish(); + } + + tx_semaphore_put(&netx_sema); +} + +static void netx_receive_entry(ULONG param) +{ +NX_UDP_SOCKET *socket_ptr = (NX_UDP_SOCKET*)param; +int i; +NX_PACKET *packet_ptr; +ULONG status; +int num_messages; + + num_messages = NUM_MESSAGES; + +#ifdef FEATURE_NX_IPV6 + num_messages += NUM_MESSAGES; +#endif + + for(i = 0; i < num_messages; i++) + { + + /* Receive a UDP message from the socket. */ + status = nx_udp_socket_receive(socket_ptr, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + + if(status) + error_counter++; +#ifdef __PRODUCT_NETXDUO__ + else if(packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) +#endif + { + if(packet_ptr -> nx_packet_length != strlen(bsd_send_buffer)) + error_counter++; + else if(memcmp(packet_ptr -> nx_packet_prepend_ptr, bsd_send_buffer, packet_ptr -> nx_packet_length)) + error_counter++; + } +#ifdef FEATURE_NX_IPV6 + else if(packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) + { + if (packet_ptr -> nx_packet_length != strlen(bsd_send_buffer6)) + error_counter++; + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, bsd_send_buffer6, packet_ptr -> nx_packet_length)) + error_counter++; + } +#endif +#ifdef __PRODUCT_NETXDUO__ + else + error_counter++; +#endif + + nx_packet_release(packet_ptr); + + tx_thread_relinquish(); + } + + tx_semaphore_put(&netx_sema); +} + + + +static void netx_udp_test(void) +{ +NX_UDP_SOCKET udp_socket; +UINT status; + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &udp_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1 * NX_IP_PERIODIC_RATE); + + + /* Check for error. */ + if (status) + error_counter++; + + status = nx_udp_socket_bind(&udp_socket, 12345, NX_WAIT_FOREVER); + if(status) + error_counter++; + + tx_thread_sleep(20); + + status = tx_thread_create(&netx_transmit_thread, "netx transmit thread", netx_transmit_entry, (ULONG)&udp_socket, + netx_transmit_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + status += tx_thread_create(&netx_receive_thread, "netx receive thread", netx_receive_entry, (ULONG)&udp_socket, + netx_receive_thread_stack, DEMO_STACK_SIZE, 2, 2, 1, TX_AUTO_START); + + if(status != TX_SUCCESS) + error_counter++; + + + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); + + + tx_thread_delete(&netx_transmit_thread); + tx_thread_delete(&netx_receive_thread); + + /* Unaccept the server socket. */ + status = nx_udp_socket_unbind(&udp_socket); + + status += nx_udp_socket_delete(&udp_socket); + /* Check for error. */ + if (status) + error_counter++; + +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + + tx_semaphore_get(&netx_sema, TX_WAIT_FOREVER); + netx_udp_test(); + + +} + + +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_blocking_bidirection_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD UDP Blocking Bidirection Test.......N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/bsd_test/netx_bsd_udp_checksum_corrupt_test.c b/test/regression/bsd_test/netx_bsd_udp_checksum_corrupt_test.c new file mode 100644 index 00000000..a287b114 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_udp_checksum_corrupt_test.c @@ -0,0 +1,291 @@ +/* This NetX test concentrates on the BSD UDP socket reject packet with corrupted checksum. */ + + +#include "nx_api.h" +#ifdef NX_BSD_ENABLE +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif +#define DEMO_STACK_SIZE 4096 + +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 2 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +static char *requests = "Request"; +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +static VOID udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_checksum_corrupt_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check UDP enable and BSD init status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int ret; +char buf[30]; +int addrlen; + + printf("NetX Test: BSD UDP Checksum Corrupt Test................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + ip_0.nx_ip_udp_packet_receive = udp_packet_receive; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + /* Receive data from the client. */ + addrlen = sizeof(remote_addr); + ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen); +#if !defined(NX_ENABLE_INTERFACE_CAPABILITY) && !defined(NX_DISABLE_UDP_RX_CHECKSUM) + if(ret > 0) + error_counter++; +#endif + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; + + validate_bsd_structure(); +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + status = nx_packet_data_append(packet_ptr, requests, strlen(requests), + &pool_0, NX_WAIT_FOREVER); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Send a UDP packet */ + status = nx_udp_socket_send(&server_socket, packet_ptr, IP_ADDRESS(1,2,3,4), 12345); + if(status) + error_counter++; + + status = nx_udp_socket_unbind(&server_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&server_socket); + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +static VOID udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +USHORT checksum; + + udp_header_ptr = (NX_UDP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + checksum = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF; + checksum++; + if (checksum == 0) + checksum++; + udp_header_ptr -> nx_udp_header_word_1 = (udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000) | checksum; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#endif /* NX_BSD_ENABLE */ diff --git a/test/regression/bsd_test/netx_bsd_udp_connect_test.c b/test/regression/bsd_test/netx_bsd_udp_connect_test.c new file mode 100644 index 00000000..abf73212 --- /dev/null +++ b/test/regression/bsd_test/netx_bsd_udp_connect_test.c @@ -0,0 +1,563 @@ +/* This NetX test concentrates on the basic BSD UDP non-blocking operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(NX_BSD_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nx_icmpv6.h" +#include "nxd_bsd.h" +#else +#include "nx_bsd.h" +#endif + +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET server_socket; +static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)]; +#define BSD_THREAD_PRIORITY 2 +#define NUM_CLIENTS 20 +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void validate_bsd_structure(void); +extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS]; +extern TX_BLOCK_POOL nx_bsd_socket_block_pool; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_ip0[3][3]; +static NXD_ADDRESS ipv6_address_ip1[3][3]; +#endif /* FEATURE_NX_IPV6 */ +static char *requests_ipv4[3] = {"Request1_ipv4", "Request22_ipv4", "Request333_ipv4"}; +static char *response_ipv4[3] = {"Response1_ipv4", "Response22_ipv4", "Response333_ipv4"}; +#ifdef FEATURE_NX_IPV6 +static char *requests_ipv6[6] = {"Request1_ipv6", "Request22_ipv6", "Request333_ipv6", "Request4444_ipv6", "Request55555_ipv6", "Request666666_ipv6"}; +static char *response_ipv6[6] = {"Response1_ipv6", "Response22_ipv6", "Response333_ipv4", "Request4444_ipv6", "Request55555_ipv6", "Request666666_ipv6"}; +#endif +static void validate_bsd_structure(void); + +#define IP0_IF0_V4_ADDR IP_ADDRESS(1,2,3,4) +#define IP0_IF1_V4_ADDR IP_ADDRESS(2,2,3,4) +#define IP0_IF2_V4_ADDR IP_ADDRESS(3,2,3,4) + +#define IP1_IF0_V4_ADDR IP_ADDRESS(1,2,3,5) +#define IP1_IF1_V4_ADDR IP_ADDRESS(2,2,3,5) +#define IP1_IF2_V4_ADDR IP_ADDRESS(3,2,3,5) + +#define ITERATIONS 100 +static ULONG ip0_address[3] = {IP0_IF0_V4_ADDR, IP0_IF1_V4_ADDR, IP0_IF2_V4_ADDR}; +static ULONG ip1_address[3] = {IP1_IF0_V4_ADDR, IP1_IF1_V4_ADDR, IP1_IF2_V4_ADDR}; +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_connect_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2); + pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP0_IF0_V4_ADDR, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Attach a 2nd interface */ + status += nx_ip_interface_attach(&ip_0, "ip_0_second", IP0_IF1_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_0, "ip_0_third", IP0_IF2_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP1_IF0_V4_ADDR, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_1, "ip_1_second", IP1_IF1_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1, "ip_1_third", IP1_IF2_V4_ADDR, 0xFFFFFF00UL, _nx_ram_network_driver_256); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Enable BSD */ + status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY); + + /* Check UDP enable and BSD init status. */ + if (status) + error_counter++; +} + +static void test_udp4_connect(void) +{ +int sockfd; +struct sockaddr_in remote_addr, local_addr; +int ret; +char buf[30]; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + local_addr.sin_family = AF_INET; + local_addr.sin_port = htons(12345); + local_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + remote_addr.sin_family = AF_INET; + remote_addr.sin_port = htons(54321); + remote_addr.sin_addr.s_addr = htonl(ip1_address[1]); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + ret = recv(sockfd, buf, sizeof(buf), 0); + + if((ret != (int)strlen(requests_ipv4[1])) || (strncmp(buf, requests_ipv4[1], strlen(requests_ipv4[1])))) + error_counter++; + tx_thread_sleep(1); + ret = send(sockfd, response_ipv4[1], strlen(response_ipv4[1]), 0); + if(ret != (int)strlen(response_ipv4[1])) + error_counter++; + + + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; +} + +#ifdef FEATURE_NX_IPV6 +static void test_udp6_connect(void) +{ +int sockfd; +struct sockaddr_in6 remote_addr, local_addr; +int ret; +char buf[30]; + + sockfd = socket(AF_INET6, SOCK_DGRAM, 0); + if(sockfd < 0) + error_counter++; + + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin6_family = AF_INET6; + local_addr.sin6_port = htons(12345); + + + + ret = bind(sockfd, (struct sockaddr*)&local_addr, sizeof(local_addr)); + if(ret < 0) + error_counter++; + + remote_addr.sin6_family = AF_INET6; + remote_addr.sin6_port = htons(54321); + remote_addr.sin6_addr._S6_un._S6_u32[0] = htonl(ipv6_address_ip1[1][1].nxd_ip_address.v6[0]); + remote_addr.sin6_addr._S6_un._S6_u32[1] = htonl(ipv6_address_ip1[1][1].nxd_ip_address.v6[1]); + remote_addr.sin6_addr._S6_un._S6_u32[2] = htonl(ipv6_address_ip1[1][1].nxd_ip_address.v6[2]); + remote_addr.sin6_addr._S6_un._S6_u32[3] = htonl(ipv6_address_ip1[1][1].nxd_ip_address.v6[3]); + + ret = connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)); + if(ret < 0) + error_counter++; + + ret = recv(sockfd, buf, sizeof(buf), 0); + + if((ret != (INT)strlen(requests_ipv6[3])) || (strncmp(buf, requests_ipv6[3], strlen(requests_ipv6[3])))) + error_counter++; + + ret = send(sockfd, response_ipv6[3], strlen(response_ipv6[3]), 0); + if(ret != (INT)strlen(response_ipv6[3])) + error_counter++; + + /* Close downt he socket. */ + ret = soc_close(sockfd); + if(ret < 0) + error_counter++; +} +#endif +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#ifdef FEATURE_NX_IPV6 +static char mac_ip0[6]; +static char mac_ip1[6]; +UINT status; +int i,j; +#endif + + + printf("NetX Test: Basic BSD UDP Connect Test...................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + + for(i = 0; i < 3; i++) + { + mac_ip0[0] = (char)(ip_0.nx_ip_interface[i].nx_interface_physical_address_msw >> 8); + mac_ip0[1] = ip_0.nx_ip_interface[i].nx_interface_physical_address_msw & 0xFF; + mac_ip0[2] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip0[3] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip0[4] = (ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip0[5] = ip_0.nx_ip_interface[i].nx_interface_physical_address_lsw & 0xff; + + mac_ip1[0] = (char)(ip_1.nx_ip_interface[i].nx_interface_physical_address_msw >> 8); + mac_ip1[1] = ip_1.nx_ip_interface[i].nx_interface_physical_address_msw & 0xFF; + mac_ip1[2] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 24) & 0xff; + mac_ip1[3] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 16) & 0xff; + mac_ip1[4] = (ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw >> 8) & 0xff; + mac_ip1[5] = ip_1.nx_ip_interface[i].nx_interface_physical_address_lsw & 0xff; + + for(j = 0; j < 3; j ++) + { + if(j == 0) + { + /* First set up IPv6 linklocal addresses. */ + ipv6_address_ip0[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0[i][j].nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip0[i][j].nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip0[i][j].nxd_ip_address.v6[2] = ((mac_ip0[0] | 0x2) << 24) | (mac_ip0[1] << 16) | (mac_ip0[2] << 8) | 0xFF; + ipv6_address_ip0[i][j].nxd_ip_address.v6[3] = (0xFE << 24) | ((mac_ip0[3] | 0x2) << 16) | (mac_ip0[4] << 8) | mac_ip0[5]; + + ipv6_address_ip1[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1[i][j].nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_ip1[i][j].nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_ip1[i][j].nxd_ip_address.v6[2] = + ((mac_ip1[0] | 0x2) << 24) | (mac_ip1[1] << 16) | (mac_ip1[2] << 8) | 0xFF; + ipv6_address_ip1[i][j].nxd_ip_address.v6[3] = + (0xFE << 24) | ((mac_ip1[3] | 0x2) << 16) | (mac_ip1[4] << 8) | mac_ip1[5]; + + status = nxd_ipv6_address_set(&ip_0, i, &ipv6_address_ip0[i][j], 10, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, i, &ipv6_address_ip1[i][j], 10, NX_NULL); + } + else + { + /* Global Adddress */ + ipv6_address_ip0[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip0[i][j].nxd_ip_address.v6[0] = 0x20000000 + i; + ipv6_address_ip0[i][j].nxd_ip_address.v6[1] = j; + ipv6_address_ip0[i][j].nxd_ip_address.v6[2] = ipv6_address_ip0[i][0].nxd_ip_address.v6[2]; + ipv6_address_ip0[i][j].nxd_ip_address.v6[3] = ipv6_address_ip0[i][0].nxd_ip_address.v6[3]; + + ipv6_address_ip1[i][j].nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_ip1[i][j].nxd_ip_address.v6[0] = 0x20000000 + i; + ipv6_address_ip1[i][j].nxd_ip_address.v6[1] = j; + ipv6_address_ip1[i][j].nxd_ip_address.v6[2] = ipv6_address_ip1[i][0].nxd_ip_address.v6[2]; + ipv6_address_ip1[i][j].nxd_ip_address.v6[3] = ipv6_address_ip1[i][0].nxd_ip_address.v6[3]; + + + status = nxd_ipv6_address_set(&ip_0, i, &ipv6_address_ip0[i][j], 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, i, &ipv6_address_ip1[i][j], 64, NX_NULL); + } + status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1[i][j].nxd_ip_address.v6, 0, mac_ip1); + status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0[i][j].nxd_ip_address.v6, 0, mac_ip0); + } + + } + + + + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + + + if(status) + error_counter++; +#endif + + test_udp4_connect(); + tx_thread_sleep(3); + +#ifdef FEATURE_NX_IPV6 + + test_udp6_connect(); + + tx_thread_sleep(1); +#endif + + + validate_bsd_structure(); + + if(error_counter) + printf("ERROR!\n"); + else + printf("SUCCESS!\n"); + + if(error_counter) + test_control_return(1); + + test_control_return(0); +} + +static void udp_client_to_AF_INET_AF_INET6(int if_index, int addr_index, int test_case) +{ + +UINT status; +NX_PACKET *packet_ptr; +int i; +#ifdef FEATURE_NX_IPV6 +int j; +#endif + + /* Create a socket. */ + status = nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 10); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind to a UDP port. */ + status = nx_udp_socket_bind(&server_socket, 54321, NX_WAIT_FOREVER); + if(status) + error_counter++; + + for(i = 2; i >= 0; i--) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests_ipv4[i], strlen(requests_ipv4[i])); + + packet_ptr -> nx_packet_length = strlen(requests_ipv4[i]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + + /* Send a UDP packet */ + status = nx_udp_socket_send(&server_socket, packet_ptr, ip0_address[i], 12345); + if(status) + error_counter++; + + status = nx_udp_socket_receive(&server_socket, &packet_ptr, 3); + if((test_case == 0) && (if_index == i)) + { + if(status != NX_SUCCESS) + { + error_counter++; + } + else + { + if((packet_ptr -> nx_packet_length != strlen(response_ipv4[1])) || + (strncmp(response_ipv4[1], (char*)packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length))) + error_counter++; + } + } + else if(status == NX_SUCCESS) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + for(j = 0; j < 2; j++) + { + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Fill in the packet with data */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, requests_ipv6[i * 3 + j], strlen(requests_ipv6[i * 3 + j])); + + packet_ptr -> nx_packet_length = strlen(requests_ipv6[i * 3 + j]); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + + /* Send a UDP packet */ + status = nxd_udp_socket_send(&server_socket, packet_ptr, &ipv6_address_ip0[i][j + 1], 12345); + if(status) + error_counter++; + + status = nx_udp_socket_receive(&server_socket, &packet_ptr, 1); + if((if_index == i) && (j == addr_index)) + { + if(status != NX_SUCCESS) + { + error_counter++; + } + else + { + if((packet_ptr -> nx_packet_length != strlen(response_ipv6[3])) || + (strncmp(response_ipv6[3], (char*)packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length))) + error_counter++; + } + } + + else if(status == NX_SUCCESS) + error_counter++; + + + } +#endif + + } + + status = nx_udp_socket_unbind(&server_socket); + if(status) + error_counter++; + + status = nx_udp_socket_delete(&server_socket); + if(status) + error_counter++; + + + +} + + +static void ntest_1_entry(ULONG thread_input) +{ +ULONG actual_status; +UINT status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(3); + } + + tx_thread_sleep(1); + + udp_client_to_AF_INET_AF_INET6(1, 30, 0); + + tx_thread_sleep(2); + +#ifdef FEATURE_NX_IPV6 + udp_client_to_AF_INET_AF_INET6(1, 0, 1); +#endif + + +} + +static void validate_bsd_structure(void) +{ +int i; + /* Make sure every BSD socket should be free by now. */ + + for(i = 0; i < NX_BSD_MAX_SOCKETS; i++) + { + if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE) + { + error_counter++; + } + + if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket || + nx_bsd_socket_array[i].nx_bsd_socket_udp_socket) + { + error_counter++; + } + } + + /* Make sure all the NX SOCKET control blocks are released. */ + if(nx_bsd_socket_block_pool.tx_block_pool_available != + nx_bsd_socket_block_pool.tx_block_pool_total) + { + error_counter++; + } + + /* Make sure all the sockets are released */ + if(ip_0.nx_ip_tcp_created_sockets_ptr || + ip_0.nx_ip_udp_created_sockets_ptr) + { + error_counter++; + return; + } +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_bsd_udp_connect_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Basic BSD UDP Connect Test....................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/cloud_test/netx_cloud_api_test.c b/test/regression/cloud_test/netx_cloud_api_test.c new file mode 100644 index 00000000..f68b39f4 --- /dev/null +++ b/test/regression/cloud_test/netx_cloud_api_test.c @@ -0,0 +1,284 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && defined(__PRODUCT_NETXDUO__) +#include "nx_cloud.h" + +#define DEMO_STACK_SIZE 4096 + +static TX_THREAD test_thread; +static NX_CLOUD cloud; +static UCHAR cloud_stack[2048]; +static NX_CLOUD_MODULE cloud_module; + +/* Define module event. */ +#define NX_CLOUD_MODULE_EVENT 0x10000000u + +/* Define module own events. */ +#define NX_CLOUD_MODULE_EVENT_1 0x00000001 +#define NX_CLOUD_MODULE_EVENT_2 0x00000002 +#define NX_CLOUD_MODULE_EVENT_3 0x00000004 +#define NX_CLOUD_MODULE_EVENT_4 0x00000008 + +static void test_entry(ULONG thread_input); +static void cloud_module_event_process(VOID *module_ptr, ULONG common_events, ULONG module_own_events); + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_cloud_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&test_thread, "Test thread", test_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); +} + +void test_entry(ULONG thread_input) +{ + +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: Cloud API Test............................................"); + + /* nx_cloud_create. */ + status = nx_cloud_create(NX_NULL, "Cloud", cloud_stack, 2048, 3); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_create(&cloud, "Cloud", NX_NULL, 2048, 3); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_create(&cloud, "Cloud", cloud_stack, 0, 3); + + /* Check status. */ + if (status != NX_SIZE_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_create(&cloud, "Cloud", cloud_stack, 2048, TX_MAX_PRIORITIES); + + /* Check status. */ + if (status != NX_OPTION_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_create(&cloud, "Cloud", cloud_stack, 2048, 3); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* nx_cloud_module_register. */ + status = nx_cloud_module_register(NX_NULL, &cloud_module, "Module 1", (NX_CLOUD_COMMON_PERIODIC_EVENT | NX_CLOUD_MODULE_EVENT), cloud_module_event_process, (void *)(&cloud_module)); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_module_register(&cloud, NX_NULL, "Module 1", (NX_CLOUD_COMMON_PERIODIC_EVENT | NX_CLOUD_MODULE_EVENT), cloud_module_event_process, (void *)(&cloud_module)); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_module_register(&cloud, &cloud_module, "Module 1", 0, cloud_module_event_process, (void *)(&cloud_module)); + + /* Check status. */ + if (status != NX_CLOUD_MODULE_EVENT_INVALID) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_module_register(&cloud, &cloud_module, "Module 1", (NX_CLOUD_COMMON_PERIODIC_EVENT | NX_CLOUD_MODULE_EVENT), NX_NULL, (void *)(&cloud_module)); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_module_register(&cloud, &cloud_module, "Module 1", (NX_CLOUD_COMMON_PERIODIC_EVENT | NX_CLOUD_MODULE_EVENT), cloud_module_event_process, (void *)(&cloud_module)); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* nx_cloud_module_event_set. */ + status = nx_cloud_module_event_set(NX_NULL, NX_CLOUD_MODULE_EVENT_1); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_module_event_set(&cloud_module, 0); + + /* Check status. */ + if (status != NX_CLOUD_MODULE_EVENT_INVALID) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_module_event_set(&cloud_module, NX_CLOUD_MODULE_EVENT_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* nx_cloud_module_event_clear. */ + status = nx_cloud_module_event_clear(NX_NULL, NX_CLOUD_MODULE_EVENT_1); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_module_event_clear(&cloud_module, 0); + + /* Check status. */ + if (status != NX_CLOUD_MODULE_EVENT_INVALID) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_module_event_clear(&cloud_module, NX_CLOUD_MODULE_EVENT_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* nx_cloud_module_deregister. */ + status = nx_cloud_module_deregister(NX_NULL, &cloud_module); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_module_deregister(&cloud, NX_NULL); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_module_deregister(&cloud, &cloud_module); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* nx_cloud_delete. */ + status = nx_cloud_delete(NX_NULL); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_cloud_delete(&cloud); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void cloud_module_event_process(VOID *module_ptr, ULONG common_events, ULONG module_own_events) +{ +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_cloud_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Cloud API Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/cloud_test/netx_cloud_basic_test.c b/test/regression/cloud_test/netx_cloud_basic_test.c new file mode 100644 index 00000000..a6fbd696 --- /dev/null +++ b/test/regression/cloud_test/netx_cloud_basic_test.c @@ -0,0 +1,291 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT); + +#ifdef __PRODUCT_NETXDUO__ +#include "nx_cloud.h" + +#define DEMO_STACK_SIZE 4096 + +static TX_THREAD test_thread; +static NX_CLOUD cloud; +static UCHAR cloud_stack[2048]; +static NX_CLOUD_MODULE cloud_module; +static ULONG cloud_common_periodic_event = 0; +static ULONG cloud_module_event_1 = 0; +static ULONG cloud_module_event_2 = 0; +static ULONG cloud_module_event_3 = 0; +static ULONG cloud_module_event_4 = 0; + +/* Define module event. */ +#define NX_CLOUD_MODULE_EVENT 0x10000000u + +/* Define module own events. */ +#define NX_CLOUD_MODULE_EVENT_1 0x00000001 +#define NX_CLOUD_MODULE_EVENT_2 0x00000002 +#define NX_CLOUD_MODULE_EVENT_3 0x00000004 +#define NX_CLOUD_MODULE_EVENT_4 0x00000008 + +static void test_entry(ULONG thread_input); +static void cloud_module_event_process(VOID *module_ptr, ULONG common_events, ULONG module_own_events); + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_cloud_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&test_thread, "Test thread", test_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); +} + +void test_entry(ULONG thread_input) +{ + +UINT status; +ULONG start_time; +ULONG periodic_count; + + + /* Print out test information banner. */ + printf("NetX Test: Cloud Basic Test.........................................."); + + /* Create cloud. */ + status = nx_cloud_create(&cloud, "Cloud", cloud_stack, 2048, 3); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register cloud module. */ + status = nx_cloud_module_register(&cloud, &cloud_module, "Module 1", (NX_CLOUD_COMMON_PERIODIC_EVENT | NX_CLOUD_MODULE_EVENT), cloud_module_event_process, (void *)(&cloud_module)); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the time. */ + start_time = tx_time_get(); + + /* Set module event 1. */ + status = nx_cloud_module_event_set(&cloud_module, NX_CLOUD_MODULE_EVENT_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check events. */ + if ((cloud_module_event_1 != 1) || (cloud_module_event_2 != 0) || (cloud_module_event_3 != 0) || (cloud_module_event_4 != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set module event 1 and 2. */ + status = nx_cloud_module_event_set(&cloud_module, NX_CLOUD_MODULE_EVENT_1|NX_CLOUD_MODULE_EVENT_2); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check events. */ + if ((cloud_module_event_1 != 2) || (cloud_module_event_2 != 1) || (cloud_module_event_3 != 0) || (cloud_module_event_4 != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set module event 1 and 2 and 3. */ + status = nx_cloud_module_event_set(&cloud_module, NX_CLOUD_MODULE_EVENT_1|NX_CLOUD_MODULE_EVENT_2|NX_CLOUD_MODULE_EVENT_3); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check events. */ + if ((cloud_module_event_1 != 3) || (cloud_module_event_2 != 2) || (cloud_module_event_3 != 1) || (cloud_module_event_4 != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set module event 1 and 2 and 3 and 4. */ + status = nx_cloud_module_event_set(&cloud_module, NX_CLOUD_MODULE_EVENT_1|NX_CLOUD_MODULE_EVENT_2|NX_CLOUD_MODULE_EVENT_3|NX_CLOUD_MODULE_EVENT_4); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check events. */ + if ((cloud_module_event_1 != 4) || (cloud_module_event_2 != 3) || (cloud_module_event_3 != 2) || (cloud_module_event_4 != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set module 2 and 3 and 4. */ + status = nx_cloud_module_event_set(&cloud_module, NX_CLOUD_MODULE_EVENT_2|NX_CLOUD_MODULE_EVENT_3|NX_CLOUD_MODULE_EVENT_4); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check events. */ + if ((cloud_module_event_1 != 4) || (cloud_module_event_2 != 4) || (cloud_module_event_3 != 3) || (cloud_module_event_4 != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set module 3 and 4. */ + status = nx_cloud_module_event_set(&cloud_module, NX_CLOUD_MODULE_EVENT_3|NX_CLOUD_MODULE_EVENT_4); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check events. */ + if ((cloud_module_event_1 != 4) || (cloud_module_event_2 != 4) || (cloud_module_event_3 != 4) || (cloud_module_event_4 != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set 4. */ + status = nx_cloud_module_event_set(&cloud_module, NX_CLOUD_MODULE_EVENT_4); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check events. */ + if ((cloud_module_event_1 != 4) || (cloud_module_event_2 != 4) || (cloud_module_event_3 != 4) || (cloud_module_event_4 != 4)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for some periodic events. */ + tx_thread_sleep(500); + + /* Get periodic count. */ + periodic_count = (tx_time_get() - start_time) / NX_IP_PERIODIC_RATE; + + /* Check periodic events. */ + if (cloud_common_periodic_event != periodic_count) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deregister cloud module. */ + status = nx_cloud_module_deregister(&cloud, &cloud_module); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete cloud. */ + status = nx_cloud_delete(&cloud); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void cloud_module_event_process(VOID *module_ptr, ULONG common_events, ULONG module_own_events) +{ + + /* Process common_events. */ + if (common_events & NX_CLOUD_COMMON_PERIODIC_EVENT) + { + cloud_common_periodic_event++; + } + + /* Process module_own_events. */ + if (module_own_events & NX_CLOUD_MODULE_EVENT_1) + { + cloud_module_event_1++; + } + if (module_own_events & NX_CLOUD_MODULE_EVENT_2) + { + cloud_module_event_2++; + } + if (module_own_events & NX_CLOUD_MODULE_EVENT_3) + { + cloud_module_event_3++; + } + if (module_own_events & NX_CLOUD_MODULE_EVENT_4) + { + cloud_module_event_4++; + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_cloud_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Cloud Basic Test..........................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/cloud_test/netx_cloud_module_event_test.c b/test/regression/cloud_test/netx_cloud_module_event_test.c new file mode 100644 index 00000000..4475b46d --- /dev/null +++ b/test/regression/cloud_test/netx_cloud_module_event_test.c @@ -0,0 +1,287 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT); + +#ifdef __PRODUCT_NETXDUO__ +#include "nx_cloud.h" + +#define DEMO_STACK_SIZE 4096 + +static TX_THREAD test_thread; +static NX_CLOUD cloud; +static UCHAR cloud_stack[2048]; + +typedef struct NX_CLOUD_APP_STRUCT +{ + +NX_CLOUD_MODULE nx_cloud_module; +ULONG nx_cloud_module_event_periodic; +ULONG nx_cloud_module_event_1; +ULONG nx_cloud_module_event_2; +ULONG nx_cloud_module_event_3; +ULONG nx_cloud_module_event_4; +} NX_CLOUD_APP; + +static NX_CLOUD_APP cloud_module[3]; + +typedef struct MODULE_EVENT_STRUCT +{ +ULONG nx_cloud_module_event_1; +ULONG nx_cloud_module_event_2; +ULONG nx_cloud_module_event_3; +ULONG nx_cloud_module_event_4; +} MODULE_EVENT; + +static MODULE_EVENT module_event[3]; + +/* Define module event. */ +#define NX_CLOUD_MODULE_1_EVENT 0x10000000u +#define NX_CLOUD_MODULE_2_EVENT 0x20000000u +#define NX_CLOUD_MODULE_3_EVENT 0x40000000u + +/* Define module own events. */ +#define NX_CLOUD_MODULE_EVENT_1 0x00000001 +#define NX_CLOUD_MODULE_EVENT_2 0x00000002 +#define NX_CLOUD_MODULE_EVENT_3 0x00000004 +#define NX_CLOUD_MODULE_EVENT_4 0x00000008 + +static void test_entry(ULONG thread_input); +static void cloud_module_event_process(VOID *module_ptr, ULONG common_events, ULONG module_own_events); + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_cloud_module_event_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&test_thread, "Test thread", test_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); +} + +void test_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +UINT j; +UINT module_id; +ULONG module_own_events; +ULONG start_time; +ULONG periodic_count; + + + /* Print out test information banner. */ + printf("NetX Test: Cloud Module Event Test..................................."); + + /* Create cloud. */ + status = nx_cloud_create(&cloud, "Cloud", cloud_stack, 2048, 3); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register cloud module 1. */ + status = nx_cloud_module_register(&cloud, &cloud_module[0].nx_cloud_module, "Module 1", (NX_CLOUD_COMMON_PERIODIC_EVENT | NX_CLOUD_MODULE_1_EVENT), cloud_module_event_process, (void *)(&cloud_module[0])); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register cloud module 2. */ + status = nx_cloud_module_register(&cloud, &cloud_module[1].nx_cloud_module, "Module 2", NX_CLOUD_MODULE_1_EVENT, cloud_module_event_process, (void *)(&cloud_module[1])); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register cloud module 3. */ + status = nx_cloud_module_register(&cloud, &cloud_module[2].nx_cloud_module, "Module 3", (NX_CLOUD_COMMON_PERIODIC_EVENT|NX_CLOUD_MODULE_1_EVENT), cloud_module_event_process, (void *)(&cloud_module[2])); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the time. */ + start_time = tx_time_get(); + + /* Loop to set event. */ + for (i = 0; i < 100; i ++) + { + module_id = rand() % 3; + module_own_events = 0; + if(rand() % 2) + { + module_own_events |= NX_CLOUD_MODULE_EVENT_1; + module_event[module_id].nx_cloud_module_event_1 ++; + } + if(rand() % 2) + { + module_own_events |= NX_CLOUD_MODULE_EVENT_2; + module_event[module_id].nx_cloud_module_event_2 ++; + } + if(rand() % 2) + { + module_own_events |= NX_CLOUD_MODULE_EVENT_3; + module_event[module_id].nx_cloud_module_event_3 ++; + } + if(rand() % 2) + { + module_own_events |= NX_CLOUD_MODULE_EVENT_4; + module_event[module_id].nx_cloud_module_event_4 ++; + } + nx_cloud_module_event_set(&cloud_module[module_id].nx_cloud_module, module_own_events); + + /* Check modules event. */ + for (j = 0; j < 3; j++) + { + if ((cloud_module[j].nx_cloud_module_event_1 != module_event[j].nx_cloud_module_event_1) || + (cloud_module[j].nx_cloud_module_event_2 != module_event[j].nx_cloud_module_event_2) || + (cloud_module[j].nx_cloud_module_event_3 != module_event[j].nx_cloud_module_event_3) || + (cloud_module[j].nx_cloud_module_event_4 != module_event[j].nx_cloud_module_event_4)) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + tx_thread_sleep(10); + } + + /* Get periodic count. */ + periodic_count = (tx_time_get() - start_time) / NX_IP_PERIODIC_RATE; + + /* Check periodic events. */ + if ((cloud_module[0].nx_cloud_module_event_periodic != periodic_count) || + (cloud_module[1].nx_cloud_module_event_periodic != 0) || + (cloud_module[2].nx_cloud_module_event_periodic != periodic_count)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test module event clear. */ + nx_cloud_module_event_clear(&cloud_module[0].nx_cloud_module, NX_CLOUD_MODULE_EVENT_1); + if (cloud_module[0].nx_cloud_module_event_1 != module_event[0].nx_cloud_module_event_1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deregister cloud module 3. */ + status = nx_cloud_module_deregister(&cloud, &cloud_module[2].nx_cloud_module); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deregister cloud module 2. */ + status = nx_cloud_module_deregister(&cloud, &cloud_module[1].nx_cloud_module); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deregister cloud module 1. */ + status = nx_cloud_module_deregister(&cloud, &cloud_module[0].nx_cloud_module); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete cloud. */ + status = nx_cloud_delete(&cloud); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void cloud_module_event_process(VOID *module_ptr, ULONG common_events, ULONG module_own_events) +{ + +NX_CLOUD_APP *cloud_app = (NX_CLOUD_APP*) module_ptr; + + /* Process common_events. */ + if (common_events & NX_CLOUD_COMMON_PERIODIC_EVENT) + { + cloud_app -> nx_cloud_module_event_periodic++; + } + + /* Process module_own_events. */ + if (module_own_events & NX_CLOUD_MODULE_EVENT_1) + { + cloud_app -> nx_cloud_module_event_1++; + } + if (module_own_events & NX_CLOUD_MODULE_EVENT_2) + { + cloud_app -> nx_cloud_module_event_2++; + } + if (module_own_events & NX_CLOUD_MODULE_EVENT_3) + { + cloud_app -> nx_cloud_module_event_3++; + } + if (module_own_events & NX_CLOUD_MODULE_EVENT_4) + { + cloud_app -> nx_cloud_module_event_4++; + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_cloud_module_event_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Cloud Module Event Test...................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/cloud_test/netx_cloud_module_register_deregister_test.c b/test/regression/cloud_test/netx_cloud_module_register_deregister_test.c new file mode 100644 index 00000000..74e5fd4e --- /dev/null +++ b/test/regression/cloud_test/netx_cloud_module_register_deregister_test.c @@ -0,0 +1,227 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT); + +#ifdef __PRODUCT_NETXDUO__ +#include "nx_cloud.h" + +#define DEMO_STACK_SIZE 4096 + +static TX_THREAD test_thread; +static NX_CLOUD cloud; +static UCHAR cloud_stack[2048]; +static NX_CLOUD_MODULE cloud_module_1; +static NX_CLOUD_MODULE cloud_module_2; +static NX_CLOUD_MODULE cloud_module_3; +static NX_CLOUD_MODULE cloud_module_4; +static NX_CLOUD_MODULE cloud_module_5; + +/* Define module event. */ +#define NX_CLOUD_MODULE_1_EVENT 0x10000000u +#define NX_CLOUD_MODULE_2_EVENT 0x20000000u +#define NX_CLOUD_MODULE_3_EVENT 0x40000000u +#define NX_CLOUD_MODULE_4_EVENT 0x80000000u +#define NX_CLOUD_MODULE_5_EVENT 0x01000000u + +static void test_entry(ULONG thread_input); +static void cloud_module_event_process(VOID *module_ptr, ULONG common_events, ULONG module_own_events); + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_cloud_module_register_deregister_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&test_thread, "Test thread", test_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); +} + +void test_entry(ULONG thread_input) +{ + +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: Cloud Module Register And Deregister Test................."); + + /* Create cloud. */ + status = nx_cloud_create(&cloud, "Cloud", cloud_stack, 2048, 3); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register cloud module 1. */ + status = nx_cloud_module_register(&cloud, &cloud_module_1, "Module 1", NX_CLOUD_MODULE_1_EVENT, cloud_module_event_process, (void *)(&cloud_module_1)); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register cloud module 1 again. */ + status = nx_cloud_module_register(&cloud, &cloud_module_1, "Module 1", NX_CLOUD_MODULE_1_EVENT, cloud_module_event_process, (void *)(&cloud_module_1)); + + /* Check status. */ + if ((status != NX_CLOUD_MODULE_ALREADY_REGISTERED) || (cloud.nx_cloud_modules_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register cloud module 2. */ + status = nx_cloud_module_register(&cloud, &cloud_module_2, "Module 2", NX_CLOUD_MODULE_2_EVENT, cloud_module_event_process, (void *)(&cloud_module_2)); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register cloud module 3. */ + status = nx_cloud_module_register(&cloud, &cloud_module_3, "Module 3", NX_CLOUD_MODULE_3_EVENT, cloud_module_event_process, (void *)(&cloud_module_4)); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register cloud module 4. */ + status = nx_cloud_module_register(&cloud, &cloud_module_4, "Module 4", NX_CLOUD_MODULE_4_EVENT, cloud_module_event_process, (void *)(&cloud_module_4)); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 4)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deregister cloud module 5. */ + status = nx_cloud_module_deregister(&cloud, &cloud_module_5); + + /* Check status. */ + if ((status != NX_CLOUD_MODULE_NOT_REGISTERED) || (cloud.nx_cloud_modules_count != 4)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deregister cloud module 2. */ + status = nx_cloud_module_deregister(&cloud, &cloud_module_2); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register cloud module 2 again. */ + status = nx_cloud_module_register(&cloud, &cloud_module_2, "Module 2", NX_CLOUD_MODULE_1_EVENT, cloud_module_event_process, (void *)(&cloud_module_2)); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 4)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deregister cloud module 1. */ + status = nx_cloud_module_deregister(&cloud, &cloud_module_1); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deregister cloud module 4. */ + status = nx_cloud_module_deregister(&cloud, &cloud_module_4); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deregister cloud module 3. */ + status = nx_cloud_module_deregister(&cloud, &cloud_module_3); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deregister cloud module 2. */ + status = nx_cloud_module_deregister(&cloud, &cloud_module_2); + + /* Check status. */ + if ((status) || (cloud.nx_cloud_modules_count != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete cloud. */ + status = nx_cloud_delete(&cloud); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void cloud_module_event_process(VOID *module_ptr, ULONG common_events, ULONG module_own_events) +{ +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_cloud_module_register_deregister_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Cloud Module Register And Deregister Test.................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/dhcp_test/netx_dhcp_03_01_01_test.c b/test/regression/dhcp_test/netx_dhcp_03_01_01_test.c new file mode 100644 index 00000000..9f43d26e --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_03_01_01_test.c @@ -0,0 +1,380 @@ +/* The client broadcasts a DHCPREQUEST message that MUST include the "server identifier" option to indicate which server it has selected. + * rfc 2131, page 16, 3.1 Client-server interaction - allocating a network address + */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "netx_dhcp_clone_function.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_offer_flag; +static UINT server_id_flag; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_01_01_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 03_01_01 Test........................................"); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (server_id_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + dhcp_offer_flag = 0; + server_id_flag = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + + advanced_packet_process_callback = my_packet_process; + client_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +NX_UDP_HEADER *udp_header; +ULONG src_dst_port; +ULONG server_identifier; +ULONG message_type; + + udp_header = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent to server from client*/ + if(src_dst_port == 0x00440043) + { + + /* Make sure in selecting state and dhcpoffer has been received. */ + if((dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_SELECTING) && (dhcp_offer_flag != 0)) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPREQUEST) + { + + /* Get the server identifier type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_OPTION_DHCP_SERVER, + &server_identifier, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if server identifier equal the server ip address. */ + if(server_identifier == (NX_DHCP_SERVER_IP_ADDRESS_0)) + server_id_flag = 1; + else + error_counter++; + + advanced_packet_process_callback = NX_NULL; + } + } + } + + return NX_TRUE; + +} + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPOFFER. */ + if(message_type == NX_DHCP_TYPE_DHCPOFFER) + { + dhcp_offer_flag++; + + /* Restore the udp packet receiving function. */ + client_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_01_01_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 03_01_01 Test...................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_03_01_02_test.c b/test/regression/dhcp_test/netx_dhcp_03_01_02_test.c new file mode 100644 index 00000000..df3a819b --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_03_01_02_test.c @@ -0,0 +1,335 @@ +/* The 'request IP address' option MUST be set to the value of 'yiaddr' in the DHCPOFFER message from the server. + * rfc 2131, page 16, 3.1 Client-server interaction - allocating a network address + */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "netx_dhcp_clone_function.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT flag; +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_01_02_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 03_01_02 Test........................................"); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(3* NX_IP_PERIODIC_RATE); + + if((error_counter) || (flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + flag = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + + /* set the udp packet receive function to mine. */ + client_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + +} + + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; +ULONG yiaddr; +ULONG request_ip_addr; + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPOFFER. */ + if(message_type == NX_DHCP_TYPE_DHCPOFFER) + { + + /* Get the "request ip address" option value. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_IP_REQ, + &request_ip_addr, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Get yiaddr field value. */ + yiaddr = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 8 + NX_BOOTP_OFFSET_YOUR_IP), 4); + + /* Check wether they are equal. */ + if(request_ip_addr != yiaddr) + error_counter++; + else + flag = 1; + + /* Restore the udp packet receiving function. */ + client_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_01_02_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 03_01_02 Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_03_01_03_test.c b/test/regression/dhcp_test/netx_dhcp_03_01_03_test.c new file mode 100644 index 00000000..06d32685 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_03_01_03_test.c @@ -0,0 +1,404 @@ +/* The DHCPREQUEST message MUST use the same value in the DHCP message header's 'secs' field and be sent to the same IP + * broadcast address as the original DHCPDISCOVER message. + * rfc 2131, page 16, 3.1 Client-server interaction - allocating a network address + */ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_offer_flag; +static UINT flag; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_01_03_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 03_01_03 Test........................................"); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + dhcp_offer_flag = 0; + flag = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + + advanced_packet_process_callback = my_packet_process; + client_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +static ULONG dhcp_discover_bcd_addr; +static ULONG dhcp_discover_secs; +ULONG dhcp_request_bcd_addr; +ULONG dhcp_request_secs; +UINT status; +ULONG message_type; + +#ifdef __PRODUCT_NETXDUO__ +NX_IPV4_HEADER *ip_header; +#else +NX_IP_HEADER *ip_header; +#endif +NX_UDP_HEADER *udp_header; +ULONG src_dst_port; + + udp_header = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent to server from client*/ + if(src_dst_port == 0x00440043) + { + if(dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_INIT) + { +#ifdef __PRODUCT_NETXDUO__ + ip_header = (NX_IPV4_HEADER*)packet_ptr -> nx_packet_prepend_ptr; +#else + ip_header = (NX_IP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; +#endif + /* Get the destination ip address. */ + dhcp_discover_bcd_addr = ip_header -> nx_ip_header_destination_ip; + + /* Get secs field value. */ + dhcp_discover_secs = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_SECS), 2); + } + + /* Make sure in selecting state and dhcpoffer has been received. */ + else if((dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_SELECTING) && (dhcp_offer_flag != 0)) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPREQUEST) + { +#ifdef __PRODUCT_NETXDUO__ + ip_header = (NX_IPV4_HEADER*)packet_ptr -> nx_packet_prepend_ptr; +#else + ip_header = (NX_IP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; +#endif + /* Get the destination ip address. */ + dhcp_request_bcd_addr = ip_header -> nx_ip_header_destination_ip; + + /* Get secs field value. */ + dhcp_request_secs = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_SECS), 2); + + /* Check if the secs and broadcast address are the same as the original DHCPDISCOVER message. */ + if((dhcp_request_bcd_addr == dhcp_discover_bcd_addr) && (dhcp_request_secs == dhcp_discover_secs)) + flag = 1; + else + error_counter++; + + /* restore the callback to NULL. */ + advanced_packet_process_callback = NX_NULL; + } + } + } + + return NX_TRUE; + +} + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPOFFER. */ + if(message_type == NX_DHCP_TYPE_DHCPOFFER) + { + dhcp_offer_flag++; + + /* Restore the udp packet receiving function. */ + client_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_01_03_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 03_01_03 Test...................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_03_02_01_test.c b/test/regression/dhcp_test/netx_dhcp_03_02_01_test.c new file mode 100644 index 00000000..e81209b4 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_03_02_01_test.c @@ -0,0 +1,388 @@ +/* As the client has not received its network address, it MUST NOT fill in the 'ciaddr' field. And servers with knowledge of + * the client's configuration parameters respond with a DHCPACK message to the client. + * rfc 2131, page 18, 3.2 Client-server interaction - resuing a previously allocated network address + * + */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "netx_dhcp_clone_function.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +#define CLIENT_IP_ADDRESS IP_ADDRESS(10,0,0,10) + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_ack_flag; +static UINT flag; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_02_01_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 03_02_01 Test........................................"); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (flag == 0) || (dhcp_ack_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +ULONG requested_ip; +UINT skip_discover_message = NX_TRUE; + + dhcp_ack_flag = 0; + flag = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Set the client IP if the host is configured to do so. */ + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + + + advanced_packet_process_callback = my_packet_process; + client_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +ULONG message_type; +NX_UDP_HEADER *udp_header; +ULONG src_dst_port; +ULONG client_ip; + + udp_header = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent to server from client*/ + if(src_dst_port == 0x00440043) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPREQUEST) + { + + /* Get ciaddr value. */ + client_ip = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_CLIENT_IP), 4); + + /* Check if the 'coaddr' field is filled. */ + if(client_ip != 0) + error_counter++; + else + flag = 1; + + /* restore the callback to NULL. */ + advanced_packet_process_callback = NX_NULL; + } + } + + return NX_TRUE; + +} + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPOFFER. */ + if(message_type == NX_DHCP_TYPE_DHCPACK) + { + dhcp_ack_flag++; + + /* Restore the udp packet receiving function. */ + client_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_02_01_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 03_02_01 Test...................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_03_02_02_test.c b/test/regression/dhcp_test/netx_dhcp_03_02_02_test.c new file mode 100644 index 00000000..68bbb84d --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_03_02_02_test.c @@ -0,0 +1,395 @@ +/* If the client's request is invalid, servers SHOULD respond with a DHCPNAK message to the client. + * If 'giaddr' is 0x00 in the DHCPREQUEST message, the server MUST broacast the DHCPNAK message to the 0xffffffff broadcast address + * + * rfc 2131, page 19, 3.2 Client-server interaction - resuing a previously allocated network address + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_ip.h" +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +#define CLIENT_IP_ADDRESS IP_ADDRESS(100,0,0,10) + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_nak_flag; +static UINT dhcp_request_count; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_02_02_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 03_02_02 Test........................................"); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (dhcp_nak_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +ULONG requested_ip; +UINT skip_discover_message = NX_TRUE; + + dhcp_nak_flag = 0; + dhcp_request_count = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Set the client IP if the host is configured to do so. */ + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + + + advanced_packet_process_callback = my_packet_process; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +ULONG message_type; +NX_UDP_HEADER *udp_header; +ULONG src_dst_port; +ULONG gateway_ip; +#ifdef __PRODUCT_NETXDUO__ +NX_IPV4_HEADER *ip_header; +#else +NX_IP_HEADER *ip_header; +#endif +ULONG dst_addr; + + udp_header = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent to server from client*/ + if(src_dst_port == 0x00440043) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPREQUEST) + { + dhcp_request_count++; + + /* Get secs giaddr value. */ + gateway_ip = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_GATEWAY_IP), 4); + + if(gateway_ip != 0) + error_counter++; + + } + } + /* sent from server to client. */ + else if((src_dst_port == 0x00430044) && (dhcp_request_count == 1)) + { + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPNACK. */ + if(message_type == NX_DHCP_TYPE_DHCPNACK) + { + dhcp_nak_flag++; + +#ifdef __PRODUCT_NETXDUO__ + ip_header = (NX_IPV4_HEADER*)packet_ptr -> nx_packet_prepend_ptr; +#else + ip_header = (NX_IP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; +#endif + /* Get the destination ip address. */ + dst_addr = ip_header -> nx_ip_header_destination_ip; + + if(dst_addr != 0xffffffff) + error_counter++; + } + + /* restore the callback to NULL. */ + advanced_packet_process_callback = NX_NULL; + } + + return NX_TRUE; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_02_02_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 03_02_02 Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_03_02_03_test.c b/test/regression/dhcp_test/netx_dhcp_03_02_03_test.c new file mode 100644 index 00000000..100f8f84 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_03_02_03_test.c @@ -0,0 +1,380 @@ +/* If the client's request is invalid, servers SHOULD respond with a DHCPNAK message to the client. + * rfc 2131, page 18, 3.1 Client-server interaction - allocating a network address + */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "netx_dhcp_clone_function.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +#define CLIENT_IP_ADDRESS IP_ADDRESS(100,0,0,10) + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_nak_flag; +static UINT dhcp_request_count; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_02_03_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 03_02_03 Test........................................"); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (dhcp_nak_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +ULONG requested_ip; +UINT skip_discover_message = NX_TRUE; + + dhcp_nak_flag = 0; + dhcp_request_count = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Set the client IP if the host is configured to do so. */ + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + + + advanced_packet_process_callback = my_packet_process; + client_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +ULONG message_type; +NX_UDP_HEADER *udp_header; +ULONG src_dst_port; + + udp_header = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent to server from client*/ + if(src_dst_port == 0x00440043) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPREQUEST) + { + dhcp_request_count++; + + /* restore the callback to NULL. */ + advanced_packet_process_callback = NX_NULL; + } + } + + return NX_TRUE; + +} + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; + + if(dhcp_request_count == 1) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPNAK. */ + if(message_type == NX_DHCP_TYPE_DHCPNACK) + { + dhcp_nak_flag++; + + /* Restore the udp packet receiving function. */ + client_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_02_03_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 03_02_03 Test...................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_03_04_01_test.c b/test/regression/dhcp_test/netx_dhcp_03_04_01_test.c new file mode 100644 index 00000000..9fde4650 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_03_04_01_test.c @@ -0,0 +1,367 @@ +/* The servers SHOULD unicast the DHCPACK reply to the address given in the 'ciaddr' filed of the DHCPINFORM message. + * rfc 2131, page 20, 3.4 Obtaining parameters with externally configured network address + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_ip.h" +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +#define CLIENT_IP_ADDRESS IP_ADDRESS(10,0,0,11) + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_ack_flag; +static UINT dhcp_inform_count; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_04_01_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", CLIENT_IP_ADDRESS, 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 03_04_01 Test........................................"); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (dhcp_ack_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + dhcp_ack_flag = 0; + dhcp_inform_count = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if(status) + error_counter++; + + status = nx_dhcp_send_request(&dhcp_client, NX_DHCP_TYPE_DHCPINFORM); + if(status) + error_counter++; + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +ULONG message_type; +NX_UDP_HEADER *udp_header; +ULONG src_dst_port; + +static ULONG inform_ciaddr; +ULONG ack_dst_addr; + +#ifdef __PRODUCT_NETXDUO__ +NX_IPV4_HEADER *ip_header; +#else +NX_IP_HEADER *ip_header; +#endif + + udp_header = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent to server from client*/ + if(src_dst_port == 0x00440043) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPINFORM) + { + dhcp_inform_count++; + + /* Get ciaddr field value. */ + inform_ciaddr = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_CLIENT_IP), 4); + + } + } + /* Sent from server to client. */ + else if((src_dst_port == 0x00430044) && (dhcp_inform_count == 1)) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPNAK. */ + if(message_type == NX_DHCP_TYPE_DHCPACK) + { + dhcp_ack_flag++; + +#ifdef __PRODUCT_NETXDUO__ + ip_header = (NX_IPV4_HEADER*)packet_ptr -> nx_packet_prepend_ptr; +#else + ip_header = (NX_IP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; +#endif + /* Get the destination ip address. */ + ack_dst_addr = ip_header -> nx_ip_header_destination_ip; + + NX_CHANGE_ULONG_ENDIAN(ack_dst_addr); + + /* Check if Server unicast the DHCPACK to the address given in the 'ciaddr' field of the DHCPINFORM message. */ + if(ack_dst_addr != inform_ciaddr) + error_counter++; + + /* restore the callback to NULL. */ + advanced_packet_process_callback = NX_NULL; + } + + } + + return NX_TRUE; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_04_01_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 03_04_01 Test...................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_03_05_01_test.c b/test/regression/dhcp_test/netx_dhcp_03_05_01_test.c new file mode 100644 index 00000000..18abd865 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_03_05_01_test.c @@ -0,0 +1,349 @@ +/* If the client includes a list fo parameters in a DHCPDISCOVER message, it MUST include that list in any subsequent DHCPREQUEST messsages. + * rfc 2131, page 21, 3.5 Client parameters in DHCP + * + */ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#include "nx_ipv4.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_offer_flag; +static UINT dhcp_request_flag; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_05_01_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 03_05_01 Test........................................"); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + server_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (dhcp_request_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + dhcp_offer_flag = 0; + dhcp_request_flag = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; +static ULONG discover_parameters; +ULONG request_parameters; + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPOFFER. */ + if(message_type == NX_DHCP_TYPE_DHCPDISCOVER) + { + dhcp_offer_flag++; + + /* Get the dhcp parameters. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_OPTION_DHCP_PARAMETERS, + &discover_parameters, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + } + else if((message_type == NX_DHCP_TYPE_DHCPREQUEST) && (dhcp_offer_flag == 1)) + { + dhcp_request_flag++; + + /* Get the dhcp parameters. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_OPTION_DHCP_PARAMETERS, + &request_parameters, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + if(discover_parameters != request_parameters) + error_counter++; + + /* Restore the udp packet receiving function. */ + server_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_03_05_01_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 03_05_01 Test...................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_04_01_01_test.c b/test/regression/dhcp_test/netx_dhcp_04_01_01_test.c new file mode 100644 index 00000000..ec0ac539 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_04_01_01_test.c @@ -0,0 +1,353 @@ +/* A client that can't receive unicast IP datagrams until its protocol software has been configured with an IP address SHOULD set the BROADCAST + * bit in the 'flags' field to 1 in any DHCPDISCOVER or DHCPREQUEST messages that client sends. + * rfc 2131, page 25, 4.1 Constructing and sending DHCP messages + * + */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "netx_dhcp_clone_function.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT discover_flag; +static UINT request_flag; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_01_01_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 04_01_01 Test........................................"); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* set the udp packet receive function to mine. */ + server_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (discover_flag == 0) || (request_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + discover_flag = 0; + request_flag = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + +} + + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; +ULONG bcd_flag; + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPOFFER. */ + if(message_type == NX_DHCP_TYPE_DHCPDISCOVER) + { + /* Get flags field value. */ + bcd_flag = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 8 + NX_BOOTP_OFFSET_FLAGS), 2); + + /* Check wether BROADCAST bit is set to 1. */ + if((bcd_flag& 0x8000) != 0x8000) + error_counter++; + else + discover_flag = 1; + + } + /* Check if the message is a DHCPREQUEST. */ + else if((message_type == NX_DHCP_TYPE_DHCPREQUEST) && (discover_flag == 1)) + { + /* Get flags field value. */ + bcd_flag = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 8 + NX_BOOTP_OFFSET_FLAGS), 2); + + /* Check wether BROADCAST bit is set to 1. */ + if((bcd_flag& 0x8000) != 0x8000) + error_counter++; + else + request_flag = 1; + + /* Restore the udp packet receiving function. */ + server_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_01_01_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 04_01_01 Test...................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_04_03_02_01_test.c b/test/regression/dhcp_test/netx_dhcp_04_03_02_01_test.c new file mode 100644 index 00000000..ebadb095 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_04_03_02_01_test.c @@ -0,0 +1,392 @@ +/* ciaddr' MUST be zero, 'requested IP address' MUST be filled in with the yiaddr value from the chosen DHCPOFFER + * rfc 2131, page 31, 4.3.2 DHCPREQUEST message + * + */ +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "netx_dhcp_clone_function.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_offer_flag; +static UINT dhcp_request_flag; + +static ULONG yiaddr; +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_03_02_01_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 04_03_02_01 Test....................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (dhcp_request_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + dhcp_offer_flag = 0; + dhcp_request_flag = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + advanced_packet_process_callback = my_packet_process; + client_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +ULONG message_type; +NX_UDP_HEADER *udp_header; +ULONG src_dst_port; +ULONG ciaddr; +ULONG requested_ip_addr; + + udp_header = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent to server from client*/ + if(src_dst_port == 0x00440043) + { + /* Make sure in selecting state and dhcpoffer has been received. */ + if((dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_SELECTING) && (dhcp_offer_flag != 0)) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPREQUEST) + { + + dhcp_request_flag++; + + /* Get ciaddr field value. */ + ciaddr = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_CLIENT_IP), 4); + + /* ciaddr should be zero. */ + if(ciaddr != 0) + error_counter++; + + /* Get the requested ip address. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_OPTION_DHCP_IP_REQ, + &requested_ip_addr, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + if(requested_ip_addr != yiaddr) + error_counter++; + + /* restore the callback to NULL. */ + advanced_packet_process_callback = NX_NULL; + } + } + } + + return NX_TRUE; + +} + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPOFFER. */ + if(message_type == NX_DHCP_TYPE_DHCPOFFER) + { + dhcp_offer_flag++; + + /* Get yiaddr field value. */ + yiaddr = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 8 + NX_BOOTP_OFFSET_YOUR_IP), 4); + + /* Restore the udp packet receiving function. */ + client_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_03_02_01_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 04_03_02_01 Test................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_04_03_02_02_test.c b/test/regression/dhcp_test/netx_dhcp_04_03_02_02_test.c new file mode 100644 index 00000000..52b81450 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_04_03_02_02_test.c @@ -0,0 +1,603 @@ +/* DHCPREQUEST generated during RENEWING state: 'server identifier' MUST NOT be filled in, 'requested IP address' option MUST NOT + * be filled in, 'ciaddr' MUST be filled in with client's IP address. + * rfc 2131, page 32, 4.3.2 DHCPREQUEST message + * + */ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nx_ip.h" +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_request_flag; + +static ULONG ip_src_addr, ip_dest_addr; +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_03_02_02_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 04_03_02_02 Test....................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + server_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + /* Sleep 10s. */ + tx_thread_sleep(10 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (dhcp_request_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + dhcp_request_flag = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + advanced_packet_process_callback = my_packet_process; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Sleep 10s */ + tx_thread_sleep(10 * NX_IP_PERIODIC_RATE); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +ULONG message_type; +ULONG src_dst_port; +ULONG ciaddr; +ULONG requested_ip_addr; +ULONG server_identifier; +NX_UDP_HEADER *udp_header_ptr; +#ifdef __PRODUCT_NETXDUO__ +NX_IPV4_HEADER *ip_header; +#else +NX_IP_HEADER *ip_header; +#endif + + udp_header_ptr = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent to server from client*/ + if(src_dst_port == 0x00440043) + { + if(dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_INIT) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPDISCOVER) + { +#ifdef __PRODUCT_NETXDUO__ + ip_header = (NX_IPV4_HEADER*)packet_ptr -> nx_packet_prepend_ptr; +#else + ip_header = (NX_IP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; +#endif + /* Get the sourceand destination ip address. */ + ip_dest_addr = ip_header -> nx_ip_header_destination_ip; + ip_src_addr = ip_header -> nx_ip_header_source_ip; + + NX_CHANGE_ULONG_ENDIAN(ip_dest_addr); + NX_CHANGE_ULONG_ENDIAN(ip_src_addr); + } + + } + + /* Make sure in renewing state. */ + else if((dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_RENEWING)) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPREQUEST) + { + + dhcp_request_flag++; + + /* Get the server id. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_OPTION_DHCP_SERVER, + &server_identifier, (packet_ptr -> nx_packet_length - 20 - 8)); + + /* According to RFC, at this point, the 'server identifier' option MUST NOT be filled. */ + if((status != NX_OPTION_ERROR) || + ((status == NX_SUCCESS) && (server_identifier != 0))) + error_counter++; + + + /* Get the requested ip address. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_OPTION_DHCP_IP_REQ, + &requested_ip_addr, (packet_ptr -> nx_packet_length - 20 - 8)); + + /* According to RFC, at this point, the 'requested ip address' option MUST NOT be filled. */ + if((status != NX_OPTION_ERROR) || + ((status == NX_SUCCESS) && (requested_ip_addr != 0))) + error_counter++; + + /* Get ciaddr field value. */ + ciaddr = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_CLIENT_IP), 4); + + /* According to RFC, at this point , the ciaddr MUST be the client's ip address. */ + if(ciaddr != client_ip.nx_ip_address) + error_counter++; + + /* restore the callback to NULL. */ + advanced_packet_process_callback = NX_NULL; + } + } + } + + return NX_TRUE; + +} + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; +NX_UDP_HEADER *udp_header_ptr; +ULONG *requested_lease_time; +ULONG checksum; +#if !defined(__PRODUCT_NETXDUO__) +ULONG temp; +ULONG length; +UCHAR *word_ptr; +ULONG packet_length; +ULONG adjusted_packet_length; +NX_PACKET *current_packet; +UCHAR *pad_ptr; +#endif + + udp_header_ptr = (NX_UDP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPDISCOVER. */ + if(message_type == NX_DHCP_TYPE_DHCPDISCOVER) + { + /* change the requested lease time. Because NETX DHCP Client doesn't have an API to set requested lease time.*/ + /* change the lease time to 5s, so that we can get the RENEWING state early. */ + requested_lease_time = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 253); + *requested_lease_time = 0x05000000; +#ifdef __PRODUCT_NETXDUO__ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* compute the checksum. */ + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + &ip_src_addr, + &ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); +#else + + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* First calculate the checksum of the pseudo UDP header that includes the source IP + address, destination IP address, protocol word, and the UDP length. */ + temp = ip_src_addr;; + checksum = (temp >> NX_SHIFT_BY_16); + checksum += (temp & NX_LOWER_16_MASK); + checksum += (ip_dest_addr >> NX_SHIFT_BY_16); + checksum += (ip_dest_addr & NX_LOWER_16_MASK); + checksum += (NX_IP_UDP >> NX_SHIFT_BY_16); + checksum += packet_ptr -> nx_packet_length; + + /* Setup the length of the packet checksum. */ + length = packet_ptr -> nx_packet_length; + + /* Initialize the current packet to the input packet pointer. */ + current_packet = packet_ptr; + + /* Loop to calculate the packet's checksum. */ + while (length) + { + /* Calculate the current packet length. */ + packet_length = current_packet -> nx_packet_append_ptr - current_packet -> nx_packet_prepend_ptr; + + /* Make the adjusted packet length evenly divisible by sizeof(ULONG). */ + adjusted_packet_length = ((packet_length + (sizeof(ULONG) - 1))/sizeof(ULONG))*sizeof(ULONG); + + /* Determine if we need to add padding bytes. */ + if (packet_length < adjusted_packet_length) + { + + /* Calculate how many bytes we need to zero at the end of the packet. */ + temp = adjusted_packet_length - packet_length; + + /* Setup temporary pointer to the current packet's append pointer. */ + pad_ptr = current_packet -> nx_packet_append_ptr; + + /* Loop to pad current packet with 0s so we don't have to worry about a partial last word. */ + while(temp) + { + + /* Check for the end of the packet. */ + if (pad_ptr >= current_packet -> nx_packet_data_end) + break; + + /* Write a 0. */ + *pad_ptr++ = 0; + + /* Decrease the pad count. */ + temp--; + } + } + + + /* Setup the pointer to the start of the packet. */ + word_ptr = (UCHAR *) current_packet -> nx_packet_prepend_ptr; + + /* Now loop through the current packet to compute the checksum on this packet. */ + while (adjusted_packet_length) + { + + /* Pickup a whole ULONG. */ + temp = *((ULONG *) word_ptr); + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the long word in the message. */ + NX_CHANGE_ULONG_ENDIAN(temp); + + /* Add upper 16-bits into checksum. */ + checksum = checksum + (temp >> NX_SHIFT_BY_16); + + /* Add lower 16-bits into checksum. */ + checksum = checksum + (temp & NX_LOWER_16_MASK); + + /* Move the word pointer and decrease the length. */ + word_ptr = word_ptr + sizeof(ULONG); + adjusted_packet_length = adjusted_packet_length - sizeof(ULONG); + } + + /* Adjust the checksum length. */ + length = length - packet_length; + + /* Determine if we are at the end of the current packet. */ + if ((length) && (word_ptr >= (UCHAR *) current_packet -> nx_packet_append_ptr) && + (current_packet -> nx_packet_next)) + { + + /* We have crossed the packet boundary. Move to the next packet + structure. */ + current_packet = current_packet -> nx_packet_next; + + /* Setup the new word pointer. */ + word_ptr = (UCHAR *) current_packet -> nx_packet_prepend_ptr; + } + } + + /* Add in the carry bits into the checksum. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Do it again in case previous operation generates an overflow. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Place the packet in the second word of the UDP header. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | + (~checksum & NX_LOWER_16_MASK); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); +#endif + /* Restore the udp packet receiving function. */ + server_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_03_02_02_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 04_03_02_02 Test................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_04_03_02_03_test.c b/test/regression/dhcp_test/netx_dhcp_04_03_02_03_test.c new file mode 100644 index 00000000..74738aa7 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_04_03_02_03_test.c @@ -0,0 +1,640 @@ +/* DHCPREQUEST generated during REBINDING state: 'server identifier' MUST NOT be filled in, 'requested IP address' option MUST NOT + * be filled in, 'ciaddr' MUST be filled in with client's IP address. + * rfc 2131, page 32, 4.3.2 DHCPREQUEST message + * + */ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nx_ip.h" +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_ip.h" +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "nx_ram_network_driver_test_1500.h" +#include "netx_dhcp_clone_function.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_request_flag; +static UINT dhcp_renew_flag; + +static ULONG ip_src_addr, ip_dest_addr; +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_03_02_03_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 04_03_02_03 Test....................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + server_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + /* Sleep 20s. */ + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (dhcp_request_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + dhcp_request_flag = 0; + dhcp_renew_flag = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + advanced_packet_process_callback = my_packet_process; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Sleep 20s */ + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +ULONG message_type; +ULONG src_dst_port; +ULONG ciaddr; +ULONG requested_ip_addr; +ULONG server_identifier; +NX_UDP_HEADER *udp_header_ptr; +#ifdef __PRODUCT_NETXDUO__ +NX_IPV4_HEADER *ip_header; +#else +NX_IP_HEADER *ip_header; +#endif + + udp_header_ptr = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent to server from client*/ + if(src_dst_port == 0x00440043) + { + if(dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_INIT) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPDISCOVER) + { +#ifdef __PRODUCT_NETXDUO__ + ip_header = (NX_IPV4_HEADER*)packet_ptr -> nx_packet_prepend_ptr; +#else + ip_header = (NX_IP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; +#endif + /* Get the sourceand destination ip address. */ + ip_dest_addr = ip_header -> nx_ip_header_destination_ip; + ip_src_addr = ip_header -> nx_ip_header_source_ip; + } + + } + /* Rebinding state. */ + else if((dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_RENEWING)) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPREQUEST) + { + dhcp_renew_flag = 1; + } + + } + /* rebing state. */ + else if((dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_REBINDING)) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPREQUEST) + { + + dhcp_request_flag++; + + /* Get the server id. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_OPTION_DHCP_SERVER, + &server_identifier, (packet_ptr -> nx_packet_length - 20 - 8)); + + /* According to RFC, at this point, the 'server identifier' option MUST NOT be filled. */ + if((status != NX_OPTION_ERROR) || + ((status == NX_SUCCESS) && (server_identifier != 0))) + error_counter++; + + + /* Get the requested ip address. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_OPTION_DHCP_IP_REQ, + &requested_ip_addr, (packet_ptr -> nx_packet_length - 20 - 8)); + + /* According to RFC, at this point, the 'requested ip address' option MUST NOT be filled. */ + if((status != NX_OPTION_ERROR) || + ((status == NX_SUCCESS) && (requested_ip_addr != 0))) + error_counter++; + + /* Get ciaddr field value. */ + ciaddr = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_CLIENT_IP), 4); + + /* According to RFC, at this point , the ciaddr MUST be the client's ip address. */ + if(ciaddr != client_ip.nx_ip_address) + error_counter++; + + /* restore the callback to NULL. */ + advanced_packet_process_callback = NX_NULL; + } + } + } + /* server to client. */ + else if(src_dst_port == 0x00430044) + { + /* Make sure this is a ACK respond to the REQUEST sent at renewing state. */ + if(dhcp_renew_flag == 1) + { + /* drop the DHCPACK to let client go to rebing state. */ + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPACK) + { + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + } + } + + return NX_TRUE; + +} + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; +NX_UDP_HEADER *udp_header_ptr; +ULONG *requested_lease_time; +ULONG checksum; +#if !defined(__PRODUCT_NETXDUO__) +ULONG temp; +ULONG length; +UCHAR *word_ptr; +ULONG packet_length; +ULONG adjusted_packet_length; +NX_PACKET *current_packet; +UCHAR *pad_ptr; +#endif + + udp_header_ptr = (NX_UDP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPOFFER. */ + if(message_type == NX_DHCP_TYPE_DHCPDISCOVER) + { + /* change the requested lease time. Because NETX DHCP Client doesn't have an API to set requested lease time.*/ + /* change the lease time to 5s, so that we can get the RENEWING state early. */ + requested_lease_time = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 253); + *requested_lease_time = 0x05000000; + +#ifdef __PRODUCT_NETXDUO__ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* compute the checksum. */ + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + &ip_src_addr, + &ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + +#else + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* First calculate the checksum of the pseudo UDP header that includes the source IP + address, destination IP address, protocol word, and the UDP length. */ + temp = ip_src_addr; + checksum = (temp >> NX_SHIFT_BY_16); + checksum += (temp & NX_LOWER_16_MASK); + checksum += (ip_dest_addr >> NX_SHIFT_BY_16); + checksum += (ip_dest_addr & NX_LOWER_16_MASK); + checksum += (NX_IP_UDP >> NX_SHIFT_BY_16); + checksum += packet_ptr -> nx_packet_length; + + /* Setup the length of the packet checksum. */ + length = packet_ptr -> nx_packet_length; + + /* Initialize the current packet to the input packet pointer. */ + current_packet = packet_ptr; + + /* Loop to calculate the packet's checksum. */ + while (length) + { + /* Calculate the current packet length. */ + packet_length = current_packet -> nx_packet_append_ptr - current_packet -> nx_packet_prepend_ptr; + + /* Make the adjusted packet length evenly divisible by sizeof(ULONG). */ + adjusted_packet_length = ((packet_length + (sizeof(ULONG) - 1))/sizeof(ULONG))*sizeof(ULONG); + + /* Determine if we need to add padding bytes. */ + if (packet_length < adjusted_packet_length) + { + + /* Calculate how many bytes we need to zero at the end of the packet. */ + temp = adjusted_packet_length - packet_length; + + /* Setup temporary pointer to the current packet's append pointer. */ + pad_ptr = current_packet -> nx_packet_append_ptr; + + /* Loop to pad current packet with 0s so we don't have to worry about a partial last word. */ + while(temp) + { + + /* Check for the end of the packet. */ + if (pad_ptr >= current_packet -> nx_packet_data_end) + break; + + /* Write a 0. */ + *pad_ptr++ = 0; + + /* Decrease the pad count. */ + temp--; + } + } + + + /* Setup the pointer to the start of the packet. */ + word_ptr = (UCHAR *) current_packet -> nx_packet_prepend_ptr; + + /* Now loop through the current packet to compute the checksum on this packet. */ + while (adjusted_packet_length) + { + + /* Pickup a whole ULONG. */ + temp = *((ULONG *) word_ptr); + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the long word in the message. */ + NX_CHANGE_ULONG_ENDIAN(temp); + + /* Add upper 16-bits into checksum. */ + checksum = checksum + (temp >> NX_SHIFT_BY_16); + + /* Add lower 16-bits into checksum. */ + checksum = checksum + (temp & NX_LOWER_16_MASK); + + /* Move the word pointer and decrease the length. */ + word_ptr = word_ptr + sizeof(ULONG); + adjusted_packet_length = adjusted_packet_length - sizeof(ULONG); + } + + /* Adjust the checksum length. */ + length = length - packet_length; + + /* Determine if we are at the end of the current packet. */ + if ((length) && (word_ptr >= (UCHAR *) current_packet -> nx_packet_append_ptr) && + (current_packet -> nx_packet_next)) + { + + /* We have crossed the packet boundary. Move to the next packet + structure. */ + current_packet = current_packet -> nx_packet_next; + + /* Setup the new word pointer. */ + word_ptr = (UCHAR *) current_packet -> nx_packet_prepend_ptr; + } + } + + /* Add in the carry bits into the checksum. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Do it again in case previous operation generates an overflow. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Place the packet in the second word of the UDP header. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | + (~checksum & NX_LOWER_16_MASK); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); +#endif + /* Restore the udp packet receiving function. */ + server_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_03_02_03_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 04_03_02_03 Test................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_04_03_05_01_test.c b/test/regression/dhcp_test/netx_dhcp_04_03_05_01_test.c new file mode 100644 index 00000000..fce440a6 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_04_03_05_01_test.c @@ -0,0 +1,383 @@ +/* The server responds to a DHCPINFORM message by sending a DHCPACK + * message directly to the address given in the 'ciaddr' field of the + * DHCPINFORM message. The server MUST NOT send a lease expiration time + to the client and SHOULD NOT fill in 'yiaddr'. + * rfc 2131, page 33, 4.3.5 DHCPINFORM message + * + */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "netx_dhcp_clone_function.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_ack_flag; +static UINT dhcp_inform_count; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_03_05_01_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 04_03_05_01 Test....................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(10 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (dhcp_inform_count != 1) || (dhcp_ack_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + dhcp_ack_flag = 0; + dhcp_inform_count = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if(status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if(status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *)&status, 10 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process; + client_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Send DHCP Information message. */ + status = nx_dhcp_send_request(&dhcp_client, NX_DHCP_TYPE_DHCPINFORM); + if(status) + error_counter++; + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +ULONG message_type; +NX_UDP_HEADER *udp_header; +ULONG src_dst_port; + + + udp_header = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent to server from client*/ + if(src_dst_port == 0x00440043) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPINFORM) + { + dhcp_inform_count = 1; + + } + } + return NX_TRUE; + +} +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; +ULONG lease_time; +ULONG yiaddr; + + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPACK and INFORM has be sent. */ + if((message_type == NX_DHCP_TYPE_DHCPACK) && (dhcp_inform_count == 1)) + { + + dhcp_ack_flag = 1; + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + + /* Get the dhcp lease time. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_OPTION_DHCP_LEASE, + &lease_time, (packet_ptr -> nx_packet_length - 8)); + if((status != NX_OPTION_ERROR) || + ((status == NX_SUCCESS) && (lease_time != 0))) + error_counter++; + + /* Get yiaddr field value. */ + yiaddr = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_YOUR_IP), 4); + if(yiaddr != 0) + error_counter++; + + /* Restore the udp packet receiving function. */ + client_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_03_05_01_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 04_03_05_01 Test................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_04_04_01_01_test.c b/test/regression/dhcp_test/netx_dhcp_04_04_01_01_test.c new file mode 100644 index 00000000..caa75594 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_04_04_01_01_test.c @@ -0,0 +1,350 @@ +/* The client MUST include its hardware address in the 'chaddr' field + * rfc 2131, page 36, 4.4.1 Initialization and allocation of network address + */ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#include "nx_ipv4.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +extern ULONG simulated_address_msw; +extern ULONG simulated_address_lsw; + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_discover_flag; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_04_01_01_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 2); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 04_04_01_01 Test....................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (dhcp_discover_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + dhcp_discover_flag = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + advanced_packet_process_callback = my_packet_process; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + /* wait a bit. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + } while (status != NX_SUCCESS); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +ULONG message_type; +NX_UDP_HEADER *udp_header; +ULONG src_dst_port; +ULONG client_hd_addr_msw; +ULONG client_hd_addr_lsw; + + udp_header = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent to server from client*/ + if(src_dst_port == 0x00440043) + { + if(dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_INIT) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPDISCOVER) + { + + dhcp_discover_flag = 1; + + /* Get chaddr field value. */ + client_hd_addr_msw = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_CLIENT_HW), 2); + client_hd_addr_lsw = dhcp_get_data((packet_ptr -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_CLIENT_HW + 2), 4); + + if((client_hd_addr_msw != simulated_address_msw) || (client_hd_addr_lsw != simulated_address_lsw)) + error_counter++; + } + } + } + + return NX_TRUE; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_04_01_01_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 04_04_01_01 Test................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_04_04_01_02_test.c b/test/regression/dhcp_test/netx_dhcp_04_04_01_02_test.c new file mode 100644 index 00000000..fbe0b264 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_04_04_01_02_test.c @@ -0,0 +1,540 @@ +/* If the 'xid' of an arriving DHCPOFFER message does not match the 'xid' of the most recent DHCPDISCOVER message, + * the DHCPOFFER message must be silently discarded. + * rfc 2131, page 36, 4.4.1 Initialization and allocation of network address + */ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nx_ip.h" +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_ip.h" +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT dhcp_offer_flag; +static UINT dhcp_request_flag; + +static ULONG ip_src_addr, ip_dest_addr; +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_04_01_02_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP 04_04_01_02 Test....................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + error_counter++; + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + error_counter++; + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + error_counter++; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + error_counter++; + + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* After 5s, check the flags for error xid. */ + if((error_counter) || (dhcp_request_flag != 0) || (dhcp_offer_flag == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + dhcp_offer_flag = 0; + dhcp_request_flag = 0; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + advanced_packet_process_callback = my_packet_process; + client_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Wait for DHCP to assign the IP address. */ + do + { + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE); + + } while (status != NX_SUCCESS); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +ULONG src_dst_port; +ULONG message_type; +NX_UDP_HEADER *udp_header; + + udp_header = (NX_UDP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + src_dst_port = udp_header -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + /* client port 68(0x44), server port 67(0x43). packet sent from client to server*/ + if(src_dst_port == 0x00440043) + { + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 20 + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 20 - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPREQUEST. */ + if(message_type == NX_DHCP_TYPE_DHCPREQUEST) + { + + /* Update the counter. */ + dhcp_request_flag++; + } + } + + return NX_TRUE; + +} + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG *xid; +ULONG message_type; +ULONG checksum; +NX_UDP_HEADER *udp_header_ptr; +#ifdef __PRODUCT_NETXDUO__ +NX_IPV4_HEADER *ip_header; +#else +NX_IP_HEADER *ip_header; +#endif +#if !defined(__PRODUCT_NETXDUO__) +ULONG temp; +ULONG length; +UCHAR *word_ptr; +ULONG packet_length; +ULONG adjusted_packet_length; +NX_PACKET *current_packet; +UCHAR *pad_ptr; +#endif + + udp_header_ptr = (NX_UDP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + /* Get the dhcp message type. */ + status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE, + &message_type, (packet_ptr -> nx_packet_length - 8)); + if(status) + error_counter++; + + /* Check if the message is a DHCPOFFER. */ + if(message_type == NX_DHCP_TYPE_DHCPOFFER) + { + dhcp_offer_flag++; + +#ifdef __PRODUCT_NETXDUO__ + ip_header = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr - 20); +#else + ip_header = (NX_IP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr - 20); +#endif + + /* Get the source and destination ip address. */ + ip_dest_addr = ip_header->nx_ip_header_destination_ip; + ip_src_addr = ip_header->nx_ip_header_source_ip; + + /* Change the xid. */ + xid = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 12); + *xid = 0; + +#ifdef __PRODUCT_NETXDUO__ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* compute the checksum. */ + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + &ip_src_addr, + &ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + +#else + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* First calculate the checksum of the pseudo UDP header that includes the source IP + address, destination IP address, protocol word, and the UDP length. */ + temp = ip_src_addr; + checksum = (temp >> NX_SHIFT_BY_16); + checksum += (temp & NX_LOWER_16_MASK); + checksum += (ip_dest_addr >> NX_SHIFT_BY_16); + checksum += (ip_dest_addr & NX_LOWER_16_MASK); + checksum += (NX_IP_UDP >> NX_SHIFT_BY_16); + checksum += packet_ptr -> nx_packet_length; + + /* Setup the length of the packet checksum. */ + length = packet_ptr -> nx_packet_length; + + /* Initialize the current packet to the input packet pointer. */ + current_packet = packet_ptr; + + /* Loop to calculate the packet's checksum. */ + while (length) + { + /* Calculate the current packet length. */ + packet_length = current_packet -> nx_packet_append_ptr - current_packet -> nx_packet_prepend_ptr; + + /* Make the adjusted packet length evenly divisible by sizeof(ULONG). */ + adjusted_packet_length = ((packet_length + (sizeof(ULONG) - 1))/sizeof(ULONG))*sizeof(ULONG); + + /* Determine if we need to add padding bytes. */ + if (packet_length < adjusted_packet_length) + { + + /* Calculate how many bytes we need to zero at the end of the packet. */ + temp = adjusted_packet_length - packet_length; + + /* Setup temporary pointer to the current packet's append pointer. */ + pad_ptr = current_packet -> nx_packet_append_ptr; + + /* Loop to pad current packet with 0s so we don't have to worry about a partial last word. */ + while(temp) + { + + /* Check for the end of the packet. */ + if (pad_ptr >= current_packet -> nx_packet_data_end) + break; + + /* Write a 0. */ + *pad_ptr++ = 0; + + /* Decrease the pad count. */ + temp--; + } + } + + + /* Setup the pointer to the start of the packet. */ + word_ptr = (UCHAR *) current_packet -> nx_packet_prepend_ptr; + + /* Now loop through the current packet to compute the checksum on this packet. */ + while (adjusted_packet_length) + { + + /* Pickup a whole ULONG. */ + temp = *((ULONG *) word_ptr); + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the long word in the message. */ + NX_CHANGE_ULONG_ENDIAN(temp); + + /* Add upper 16-bits into checksum. */ + checksum = checksum + (temp >> NX_SHIFT_BY_16); + + /* Add lower 16-bits into checksum. */ + checksum = checksum + (temp & NX_LOWER_16_MASK); + + /* Move the word pointer and decrease the length. */ + word_ptr = word_ptr + sizeof(ULONG); + adjusted_packet_length = adjusted_packet_length - sizeof(ULONG); + } + + /* Adjust the checksum length. */ + length = length - packet_length; + + /* Determine if we are at the end of the current packet. */ + if ((length) && (word_ptr >= (UCHAR *) current_packet -> nx_packet_append_ptr) && + (current_packet -> nx_packet_next)) + { + + /* We have crossed the packet boundary. Move to the next packet + structure. */ + current_packet = current_packet -> nx_packet_next; + + /* Setup the new word pointer. */ + word_ptr = (UCHAR *) current_packet -> nx_packet_prepend_ptr; + } + } + + /* Add in the carry bits into the checksum. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Do it again in case previous operation generates an overflow. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Place the packet in the second word of the UDP header. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | + (~checksum & NX_LOWER_16_MASK); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); +#endif + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_04_04_01_02_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP 04_04_01_02 Test................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_basic_restore_test.c b/test/regression/dhcp_test/netx_dhcp_basic_restore_test.c new file mode 100644 index 00000000..39449b28 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_basic_restore_test.c @@ -0,0 +1,409 @@ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_DHCP_CLIENT_RESTORE_STATE) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_basic_restore_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Basic Restore Test..................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +UINT length; + + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UCHAR buffer[4]; +UINT buffer_size = 4; +ULONG *long_ptr; +NX_DHCP_CLIENT_RECORD client_record; +ULONG gateway_address = 0; +ULONG restore_gateway_address = 0xff; + + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Get the DNS Server address. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DNS_SVR, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the DNS address. */ + if (*long_ptr != NX_DHCP_DNS_SERVER_0) + error_counter++; + } + else + { + error_counter++; + } + + /* Get the lease time value. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DHCP_LEASE, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the lease time value. */ + if (*long_ptr != NX_DHCP_DEFAULT_LEASE_TIME) + error_counter++; + } + else + { + error_counter++; + } + + length = sizeof(message); + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + +#ifdef __PRODUCT_NETXDUO__ + /* Store the gateway address. */ + status = nx_ip_gateway_address_get(&client_ip, &gateway_address); + if (status) + error_counter++; +#endif + + /* Get the record for restoring. */ + status = nx_dhcp_client_get_record(&dhcp_client, &client_record); + if (status) + error_counter++; + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + +#ifdef __PRODUCT_NETXDUO__ + /* Check if gateway address is cleared. */ + status = nx_ip_gateway_address_get(&client_ip, &restore_gateway_address); + if (!status) + error_counter++; +#endif + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + + /* Resotr the client record. */ + status = nx_dhcp_client_restore_record(&dhcp_client, &client_record, 600); + if (status) + error_counter++; + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + +#ifdef __PRODUCT_NETXDUO__ + /* Check if the gateway address is retored. */ + status = nx_ip_gateway_address_get(&client_ip, &restore_gateway_address); + if (status || gateway_address != restore_gateway_address) + error_counter++; +#endif + + return; +} + + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + /* Increment state changes counter. */ + state_changes++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_basic_restore_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Basic Restore Test..............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_basic_test.c b/test/regression/dhcp_test/netx_dhcp_basic_test.c new file mode 100644 index 00000000..211ea524 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_basic_test.c @@ -0,0 +1,407 @@ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* If defined, the host requests a (previous) client IP address. */ +/* +#define REQUEST_CLIENT_IP +*/ + +/* If defined the client requests to jump to the boot state and skip the DISCOVER message. + If REQUEST_CLIENT_IP is not defined, this has no effect. */ +/* +#define SKIP_DISCOVER_MESSAGE +*/ + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_basic_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Basic Test..........................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +UINT length; + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) +static UINT packet_filter_extended(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT direction) +{ + if ((direction == NX_IP_PACKET_OUT) && + ((packet_ptr -> nx_packet_ip_header == NX_NULL) || + (packet_ptr -> nx_packet_ip_header_length == 0))) + { + error_counter++; + } + return(NX_SUCCESS); +} +#endif + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UCHAR buffer[4]; +UINT buffer_size = 4; +ULONG *long_ptr; + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +UINT skip_discover_message = NX_FALSE; +#endif + + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) + client_ip.nx_ip_packet_filter_extended = packet_filter_extended; +#endif + + /* Set the client IP if the host is configured to do so. */ +#ifdef REQUEST_CLIENT_IP + + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + +#endif + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Get the DNS Server address. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DNS_SVR, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the DNS address. */ + if (*long_ptr != NX_DHCP_DNS_SERVER_0) + error_counter++; + } + else + { + error_counter++; + } + + /* Get the lease time value. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DHCP_LEASE, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the lease time value. */ + if (*long_ptr != NX_DHCP_DEFAULT_LEASE_TIME) + error_counter++; + } + else + { + error_counter++; + } + + length = sizeof(message); + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + /* Increment state changes counter. */ + state_changes++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Basic Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_client_activate_interfaces_test.c b/test/regression/dhcp_test/netx_dhcp_client_activate_interfaces_test.c new file mode 100644 index 00000000..e6318731 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_activate_interfaces_test.c @@ -0,0 +1,871 @@ +/* Testing the multiple interface DHCP Client */ + +/* This is the DHCP Client that will run on both interfaces independently. + Required: NX_MAX_PHYSICAL_INTERFACES >= 2 and NX_DHCP_CLIENT_MAX_RECORDS >= 2. + There are two DHCP Client threads that independently activate the DHCP Client on + the primary or secondary interface. When they reach the bound state, each interface Client + deactivates the DHCP Client process and the DHCP Client goes back to the NOT STARTED state. + + There is one server thread handling DHCP Client messages on both interfaces. +*/ + + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +extern void test_control_return(UINT status); + +#if (NX_MAX_PHYSICAL_INTERFACES >= 2) && (NX_DHCP_CLIENT_MAX_RECORDS >=2) + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + +static ULONG dhcp_xid = 0; + + +/* Define the ThreadX, NetX object control blocks... */ + +static UINT state_changes = 0; +static NX_UDP_SOCKET server_socket; +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +/* Define the NetX FTP object control block. */ +static NX_DHCP dhcp_client; + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 2 +static DHCP_RESPONSE dhcp_response0[NUM_RESPONSES]; +static DHCP_RESPONSE dhcp_response1[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; + + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number, UINT iface_index); +static void dhcp_test_initialize(); +static void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state); + +extern void test_control_return(UINT); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size); + +/* Note that the network is 192.2.2.0 and the MAC address is 11 22 33 44 56 + because there are four entities (server 2 interfaces, client 2 interfaces + and the ram driver increases the MAC sequentially starting from + 11 22 33 44 56. */ + + +static char offer_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x02, 0x02, 0x01, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response0_size = 300; + +/* Frame (342 bytes) */ +static char ack_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response0_size = 300; + +static char offer_response1[300] = { + +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xF7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x01, 0x01, 0x01, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response1_size = 300; + +/* Frame (342 bytes) */ +static char ack_response1[300] = { + +//0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response1_size = 300; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_activate_interfaces_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the DHCP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server_thread, "Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + status = nx_ip_interface_attach(&server_ip, "Server Second interface", IP_ADDRESS(192,1,1,1), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + if (status) + error_counter++; + + + /* Set up the Client. */ + /* Create the main client thread. */ + status = tx_thread_create(&client_thread, "Client Thread", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 7*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 7*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, " Client IP ", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client Second interface", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; +} + + +/* Define the DHCP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT actual_status; + + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Activate Interfaces Test......................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + + /* Set the advanced callback to ensure broadcast packets are routed correctly. */ + advanced_packet_process_callback = my_dhcp_process_bc_callback; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Clear the unicast flag on all interfaces. */ + status = nx_dhcp_clear_broadcast_flag(&dhcp_client, NX_TRUE); + + /* Set the client IP if the host is configured to do so. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_interface_state_change1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start DHCP on all enabled interfaces (which at the moment is just the primary interface). */ + status = nx_dhcp_interface_start(&dhcp_client, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable DHCP feature on the second interface. */ + status = nx_dhcp_interface_enable(&dhcp_client, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start DHCP feature on the second interface. */ + status = nx_dhcp_interface_start(&dhcp_client, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check for address resolution for first interface. */ + status = nx_ip_interface_status_check(&client_ip, 0, NX_IP_ADDRESS_RESOLVED, (ULONG *)&actual_status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the record state. */ + if (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check for address resolution for second interface. */ + status = nx_ip_interface_status_check(&client_ip, 1, NX_IP_ADDRESS_RESOLVED, (ULONG *)&actual_status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the record state. */ + if (dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now stop the DHCP Client 0. */ + status = nx_dhcp_interface_disable(&dhcp_client, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Verify the DHCP CLient is not enabled on the primary interface. */ + if (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_NOT_STARTED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now stop the DHCP Client 0. */ + status = nx_dhcp_interface_disable(&dhcp_client, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Verify the DHCP CLient is not enabled on the primary interface. */ + if (dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_NOT_STARTED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check error_counter. */ + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +/* Define the Primary DHCP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i, j, k, pkt_number; + + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + i = 0; + j = 0; + k = 0; + pkt_number = 0; + + /* Wait for Client requests */ + while (i < (2 * NUM_RESPONSES)) + { + + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + UINT source_port; + ULONG source_ip_address; + UINT protocol; + UINT iface_index; + + /* Get the XID of DHCP message from DHCP Server. */ + dhcp_xid = dhcp_get_dhcp_data(my_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID, 4); + + + nx_udp_packet_info_extract(my_packet, &source_ip_address, &protocol, &source_port, &iface_index); + + /* Release the packet. */ + nx_packet_release(my_packet); + + if (iface_index == 0) + { + pkt_number = j; + + } + else + { + pkt_number = k; + + } + + status = nx_dhcp_response_packet_send(&server_socket, 68, pkt_number, iface_index); + + if (iface_index == 0) + j++; + else + k++; + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Advance the index for the next response. */ + i++; + } + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server_socket); +} + +static void dhcp_test_initialize() +{ + + + /* Set up server responses on the primary interface. */ + dhcp_response0[0].dhcp_response_pkt_data = &offer_response0[0]; + dhcp_response0[0].dhcp_response_pkt_size = offer_response0_size ; + + dhcp_response0[1].dhcp_response_pkt_data = &ack_response0[0]; + dhcp_response0[1].dhcp_response_pkt_size = ack_response0_size ; + + /* Set up server responses on the secondary interface. */ + dhcp_response1[0].dhcp_response_pkt_data = &offer_response1[0]; + dhcp_response1[0].dhcp_response_pkt_size = offer_response1_size ; + + dhcp_response1[1].dhcp_response_pkt_data = &ack_response1[0]; + dhcp_response1[1].dhcp_response_pkt_size = ack_response1_size ; + +} + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, UINT port, INT packet_number, UINT iface_index) +{ + +UINT status; +NX_PACKET *response_packet; +UCHAR *work_ptr; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS ip_address; +#else +ULONG ip_address; +NX_PACKET **response_packet_ptr_ptr; +#endif + +#ifdef __PRODUCT_NETXDUO__ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = 0xFFFFFFFF; +#else + ip_address = 0xFFFFFFFF; +#endif + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + if (iface_index == 0) + { + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response0[packet_number].dhcp_response_pkt_data, + dhcp_response0[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response0[packet_number].dhcp_response_pkt_size; + } + else if (iface_index == 1) + { + + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response1[packet_number].dhcp_response_pkt_data, + dhcp_response1[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response1[packet_number].dhcp_response_pkt_size; + } + + /* Now replace the XID in the server message with what we know is the Client XID. */ + work_ptr = (UCHAR *)(response_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID); + NX_CHANGE_ULONG_ENDIAN(dhcp_xid); + memcpy(work_ptr, (void const *)(&dhcp_xid), 4); + + + /* Adjust the write pointer. */ + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ +#ifdef __PRODUCT_NETXDUO__ + status = nxd_udp_socket_source_send(server_socket_ptr, response_packet, &ip_address, 68, iface_index); +#else + response_packet_ptr_ptr = &response_packet; + status = nx_udp_socket_interface_send(server_socket_ptr, *response_packet_ptr_ptr, ip_address, 68, iface_index); +#endif + + /* Check the status. */ + if (status) + { + + error_counter++; + + nx_packet_release(response_packet); + } + + return status; +} + +void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + state_changes++;; + return; +} + +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UCHAR *work_ptr; +UINT interface_index; +UINT packet_client_mac_lsw; +NX_PACKET *packet_copy; + + + /* Is this a DHCP packet e.g. not an ARP packet? */ + if (packet_ptr -> nx_packet_length < 200) + { + /* Maybe an ARP packet. let the RAM driver deal with it */ + return NX_TRUE; + } + + /* Set work_ptr. */ +#ifdef __PRODUCT_NETXDUO__ + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#else + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IP_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#endif + + /* Pickup the target MAC address in the DHCP message. */ + packet_client_mac_lsw = (((ULONG)work_ptr[2]) << 24) | + (((ULONG)work_ptr[3]) << 16) | + (((ULONG)work_ptr[4]) << 8) | + ((ULONG)work_ptr[5]); + + /* Determine what interface to use based on MAC address and which IP instance is sending the packet. */ + if (packet_client_mac_lsw == 0x22334458) + { + interface_index = 0; + } + else if (packet_client_mac_lsw == 0x22334459) + { + interface_index = 1; + } + else + /* Don't know what this packet is. Let DHCP Client handle it. */ + return NX_TRUE; + + /* Copy to a new packet and drop the original packet. */ + nx_packet_copy(packet_ptr, &packet_copy, &client_pool, NX_WAIT_FOREVER); + + /* Based on the packet mac address, set the packet interface based on the mac address */ + packet_copy -> nx_packet_ip_interface = &(ip_ptr -> nx_ip_interface[interface_index]); + + if (ip_ptr == &server_ip) + { + _nx_ip_packet_receive(&client_ip, packet_copy); + } + else + { + _nx_ip_packet_receive(&server_ip, packet_copy); + } + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + return NX_TRUE; + +} + +ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size) +{ + +ULONG value = 0; + + + /* Process the data retrieval request. */ + while (size-- > 0) + { + + /* Build return value. */ + value = (value << 8) | *data++; + } + + /* Return value. */ + return(value); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_activate_interfaces_test_application_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: DHCP Client Activate Interfaces Test......................N/A!\n"); + test_control_return(3); +} +#endif /* (NX_MAX_PHYSICAL_INTERFACES >= 2) && (NX_DHCP_CLIENT_MAX_RECORDS >=2) */ + + diff --git a/test/regression/dhcp_test/netx_dhcp_client_arp_probe_fail_multiple_interface_test.c b/test/regression/dhcp_test/netx_dhcp_client_arp_probe_fail_multiple_interface_test.c new file mode 100644 index 00000000..d2b83540 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_arp_probe_fail_multiple_interface_test.c @@ -0,0 +1,1033 @@ +/* Testing the multiple interface DHCP Client */ + +/* This is the DHCP Client that will run on both interfaces independently. + Required: NX_MAX_PHYSICAL_INTERFACES >= 2 and NX_DHCP_CLIENT_MAX_INTERFACES >= 2. + There are two DHCP Client threads that are switching from manual to DHCP CLient address + mode, and switch from activated to deactivated. There is one server thread checking + for DHCP Client messages on primary and secondary interfaces. +*/ + + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +#include "nx_arp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +#if (NX_MAX_PHYSICAL_INTERFACES >= 2) && (NX_DHCP_CLIENT_MAX_RECORDS >=2) + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + + + +/* Define the ThreadX, NetX object control blocks... */ + +static NX_UDP_SOCKET server_socket; +static TX_THREAD client_thread; +static TX_THREAD server_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server_ip; + +static UINT probe0 = NX_FALSE; +static UINT probe1 = NX_FALSE; +static UINT bound0 = NX_FALSE; +static UINT bound1 = NX_FALSE; +static UINT decline0 = NX_FALSE; +static UINT decline1 = NX_FALSE; + +/* Define the NetX DHCP object control block. */ +static NX_DHCP dhcp_client; +static ULONG dhcp_xid; + + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 2 +static DHCP_RESPONSE dhcp_response0[NUM_RESPONSES]; +static DHCP_RESPONSE dhcp_response1[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client_running = NX_TRUE; + + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number, UINT iface_index); +static void dhcp_test_initialize(); + +extern void test_control_return(UINT); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size); +static VOID dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state); +static UINT send_arp_reply(NX_IP *ip_ptr, UINT iface_index, ULONG probe_address); + + +/* Note that the network is 192.2.2.0 and the MAC address is 11 22 33 44 56 + because there are four entities (server 2 interfaces, client 2 interfaces + and the ram driver increases the MAC sequentially starting from + 11 22 33 44 56. */ + + +static char offer_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x02, 0x02, 0x01, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response0_size = 300; + +/* Frame (342 bytes) */ +static char ack_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response0_size = 300; + +static char offer_response1[300] = { + +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xF7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x01, 0x01, 0x01, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response1_size = 300; + +/* Frame (342 bytes) */ +static char ack_response1[300] = { + + +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response1_size = 300; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_arp_probe_fail_multiple_interface_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the DHCP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server_thread, "Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + status = nx_ip_interface_attach(&server_ip, "Server secondary IP", IP_ADDRESS(192,1,1,1), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + if (status) + error_counter++; + + /* Set up the Client. */ + + /* Create the main client thread. */ + status = tx_thread_create(&client_thread, "Client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 12*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 12*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, "Client IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client secondary IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp"); + + if (status) + error_counter++; + + /* Keep track of interface DHCP Client state changes. */ + status = nx_dhcp_interface_state_change_notify(&dhcp_client, dhcp_interface_state_change); + + if (status) + error_counter++; + + return; +} + + +/* Define the DHCP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT time_keeper; + + + tx_thread_sleep(10); + + status = nx_dhcp_interface_enable(&dhcp_client, 1); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start DHCP on all enabled interfaces. */ + status = nx_dhcp_start(&dhcp_client); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_NOT_STARTED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the Client to bind an ARP adddress, including the ARP probe test. */ + time_keeper = 0; + + while((dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_BOUND) && + (dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_BOUND)) + { + tx_thread_sleep(100); + time_keeper += 100; + if (time_keeper > 1000) + { + break; + } + } + + if ((probe0 != NX_TRUE) || (bound0 != NX_TRUE) || (decline0 == NX_TRUE)) + { + error_counter++; + } + + /* Now stop the DHCP Client 0. */ + nx_dhcp_interface_disable(&dhcp_client, 0); + + /* Verify the DHCP CLient is not enabled on the primary interface. */ + if (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_NOT_STARTED) + { + error_counter++; + } + + if (client_ip.nx_ip_interface[0].nx_interface_ip_address != 0x0) + { + error_counter++; + } + + /* Wait a bit for DHCP Client internally to decline the IP address. */ + tx_thread_sleep(30); + + if ((probe1 != NX_TRUE) || (decline1 != NX_TRUE) || (bound1 == NX_TRUE)) + { + error_counter++; + } + + if (client_ip.nx_ip_interface[1].nx_interface_ip_address != 0x0) + { + error_counter++; + } + + client_running = NX_FALSE; + +} + + +/* Define the DHCP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i, j, k, pkt_number; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Multiple Interface ARP Probe Fail Test......"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 0 Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + i = 0; + j = 0; + k = 0; + pkt_number = 0; + + /* Set the advanced callback to ensure broadcast packets are routed correctly. */ + advanced_packet_process_callback = my_dhcp_process_bc_callback; + + /* Wait for Client requests */ + while ( i < (2*NUM_RESPONSES)) + { + + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + UINT source_port; + ULONG source_ip_address; + UINT protocol; + UINT iface_index; + + /* Get the XID of DHCP message from DHCP Server. */ + dhcp_xid = dhcp_get_dhcp_data(my_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID, 4); + + nx_udp_packet_info_extract(my_packet, &source_ip_address, &protocol, &source_port, &iface_index); + + /* Release the packet. */ + nx_packet_release(my_packet); + + if (iface_index == 0) + { + pkt_number = j; + + } + else + { + pkt_number = k; + + } + + status = nx_dhcp_response_packet_send(&server_socket, 68, pkt_number, iface_index); + + if (iface_index == 0) + j++; + else + k++; + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Advance the index for the next response. */ + i++; + } + + /* Set up a scenario to respond to Client ARP Probes on interface 1 */ + while(dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_ADDRESS_PROBING) + tx_thread_sleep(20); + + /* While the DHCP Client is in probe mode, send a conflict response. */ + status = send_arp_reply(&server_ip, 1, dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_ip_address); + + /* Check status. */ + if (status) + { + error_counter++; + } + /* Should get one more message from the Client, a DECLINE message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + error_counter++; + } + + /* Wait for the client to terminate the connection. */ + while(client_running == NX_TRUE) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + +static void dhcp_test_initialize() +{ + + + /* Set up server responses on the primary interface. */ + dhcp_response0[0].dhcp_response_pkt_data = &offer_response0[0]; + dhcp_response0[0].dhcp_response_pkt_size = offer_response0_size ; + + dhcp_response0[1].dhcp_response_pkt_data = &ack_response0[0]; + dhcp_response0[1].dhcp_response_pkt_size = ack_response0_size ; + + /* Set up server responses on the secondary interface. */ + dhcp_response1[0].dhcp_response_pkt_data = &offer_response1[0]; + dhcp_response1[0].dhcp_response_pkt_size = offer_response1_size ; + + dhcp_response1[1].dhcp_response_pkt_data = &ack_response1[0]; + dhcp_response1[1].dhcp_response_pkt_size = ack_response1_size ; + +} + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, UINT port, INT packet_number, UINT iface_index) +{ + +UINT status; +NX_PACKET *response_packet; +UCHAR *work_ptr; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS ip_address; +#else +ULONG ip_address; +NX_PACKET **response_packet_ptr_ptr; +#endif + +#ifdef __PRODUCT_NETXDUO__ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = 0xFFFFFFFF; +#else + ip_address = 0xFFFFFFFF; +#endif + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + if (iface_index == 0) + { + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response0[packet_number].dhcp_response_pkt_data, + dhcp_response0[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response0[packet_number].dhcp_response_pkt_size; + } + else if (iface_index == 1) + { + + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response1[packet_number].dhcp_response_pkt_data, + dhcp_response1[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response1[packet_number].dhcp_response_pkt_size; + } + + /* Now replace the XID in the server message with what we know is the Client XID. */ + work_ptr = (UCHAR *)(response_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID); + NX_CHANGE_ULONG_ENDIAN(dhcp_xid); + memcpy(work_ptr, (void const *)(&dhcp_xid), 4); + + + /* Adjust the write pointer. */ + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ +#ifdef __PRODUCT_NETXDUO__ + status = nxd_udp_socket_source_send(server_socket_ptr, response_packet, &ip_address, 68, iface_index); +#else + response_packet_ptr_ptr = &response_packet; + status = nx_udp_socket_interface_send(server_socket_ptr, *response_packet_ptr_ptr, ip_address, 68, iface_index); +#endif + + /* Check the status. */ + if (status) + { + + error_counter++; + + nx_packet_release(response_packet); + } + + return status; +} + + +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + +UCHAR *work_ptr; +ULONG *message_ptr; +UINT interface_index; +UINT packet_client_mac_lsw; +ULONG sender_physical_lsw; +NX_PACKET *packet_copy; + + + /* Check if this is an IP or an ARP (smaller) packet. We don't know where the packet + prepend pointer is so assume anything less than 200 bytes is an ARP packet. */ + if (packet_ptr -> nx_packet_length < 200) + { + + message_ptr = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr); + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 3)); + + sender_physical_lsw = (*(message_ptr + 2) << 16) | (*(message_ptr + 3) >> 16); + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 3)); + + + /* Determine what interface to use based on MAC address and which IP instance is sending the packet. */ + if (sender_physical_lsw == 0x22334458) + { + interface_index = 0; + } + else if (sender_physical_lsw == 0x22334459) + { + interface_index = 1; + } + else + { + /* Don't know what this packet is. Let DHCP Client handle it. */ + return NX_TRUE; + } + } + else /* if (packet_type == MY_DRIVER_ETHERNET_IP) */ + { + + /* Set work_ptr. */ +#ifdef __PRODUCT_NETXDUO__ + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#else + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IP_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#endif + /* Pickup the target MAC address in the DHCP message. */ + packet_client_mac_lsw = (((ULONG)work_ptr[2]) << 24) | + (((ULONG)work_ptr[3]) << 16) | + (((ULONG)work_ptr[4]) << 8) | + ((ULONG)work_ptr[5]); + + /* Determine what interface to use based on MAC address and which IP instance is sending the packet. */ + if (packet_client_mac_lsw == 0x22334458) + { + interface_index = 0; + } + else if (packet_client_mac_lsw == 0x22334459) + { + interface_index = 1; + } + else + { + /* Don't know what this packet is. Let DHCP Client handle it. */ + return NX_TRUE; + } + } + + /* Copy to a new packet and drop the original packet. */ + nx_packet_copy(packet_ptr, &packet_copy, &client_pool, NX_WAIT_FOREVER); + + /* Based on the packet mac address, set the packet interface based on the mac address */ + packet_copy -> nx_packet_ip_interface = &(ip_ptr -> nx_ip_interface[interface_index]); + + if (packet_ptr -> nx_packet_length > 200) + { + + if (ip_ptr == &server_ip) + { + _nx_ip_packet_receive(&client_ip, packet_copy); + } + else + { + _nx_ip_packet_receive(&server_ip, packet_copy); + } + } + else + { + + if (ip_ptr == &server_ip) + { + _nx_arp_packet_receive(&client_ip, packet_copy); + } + else + { + _nx_arp_packet_receive(&server_ip, packet_copy); + } + } + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + return NX_TRUE; + +} + + +ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size) +{ + +ULONG value = 0; + + + /* Process the data retrieval request. */ + while (size-- > 0) + { + + /* Build return value. */ + value = (value << 8) | *data++; + } + + /* Return value. */ + return(value); +} + +VOID dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state) +{ + + if (iface_index == 0) + { + + if (new_state == NX_DHCP_STATE_ADDRESS_PROBING) + { + probe0 = NX_TRUE; + } + else if (new_state == NX_DHCP_STATE_BOUND) + { + bound0 = NX_TRUE; + } + else if (new_state == NX_DHCP_STATE_INIT) + { + /* Check if the Client has been reset to to INIT + after reaching the ARP probe state. This should not happen. */ + if (probe0 == NX_TRUE) + { + error_counter++; + } + } + } + else if (iface_index == 1) + { + + if (new_state == NX_DHCP_STATE_ADDRESS_PROBING) + { + probe1 = NX_TRUE; + } + else if (new_state == NX_DHCP_STATE_BOUND) + { + bound1 = NX_TRUE; + + /* This should not happen. */ + error_counter++; + } + else if (new_state == NX_DHCP_STATE_INIT) + { + /* Check if the Client has been reset to to INIT + after reaching the ARP probe state. */ + if (probe1 == NX_TRUE) + { + decline1 = NX_TRUE; + } + } + } + else + error_counter++; + + return; +} + + +UINT send_arp_reply(NX_IP *ip_ptr, UINT iface_index, ULONG probe_address) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG *message_ptr; +NX_IP_DRIVER driver_request; +NX_INTERFACE *nx_interface; +ULONG lsw, msw; + + + /* Allocate a packet to build the ARP message in. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &packet_ptr, NX_PHYSICAL_HEADER, NX_NO_WAIT); + if (status != NX_SUCCESS) + { + + /* Error getting packet, so just get out! */ + return status; + } + + /* Stamp the packet with the outgoing interface information, which is the server primary interface. */ + nx_interface = &(ip_ptr -> nx_ip_interface[iface_index]); + + /* Store the probe address on the Client. */ + client_ip.nx_ip_interface[iface_index].nx_interface_ip_probe_address = probe_address;; + //nx_interface -> nx_interface_ip_probe_address = probe_address; + + packet_ptr -> nx_packet_ip_interface = nx_interface; + + /* Build the ARP request packet. */ + + /* Setup the size of the ARP message. */ + packet_ptr -> nx_packet_length = NX_ARP_MESSAGE_SIZE; + + /* Setup the append pointer to the end of the message. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + NX_ARP_MESSAGE_SIZE; + + /* Setup the pointer to the message area. */ + message_ptr = (ULONG *) packet_ptr -> nx_packet_prepend_ptr; + + /* Write the Hardware type into the message. */ + *message_ptr = (ULONG)(NX_ARP_HARDWARE_TYPE << 16) | (NX_ARP_PROTOCOL_TYPE); + *(message_ptr + 1) = (ULONG)(NX_ARP_HARDWARE_SIZE << 24) | (NX_ARP_PROTOCOL_SIZE << 16) | + NX_ARP_OPTION_REQUEST; + + /* Sender mac address. Note this is a phone MAC address from 'another' host on the network. */ + msw = 0x000c; + lsw = 0xf17dcaa6; + + *(message_ptr+2) = (ULONG) (msw << 16) |(lsw >> 16); + /* Rest of sender mac address,upper bytes of sender address */ + *(message_ptr + 3) = (ULONG)((lsw << 16) | (probe_address >> 16)); + + /* Target mac address */ + msw = 0x11; + lsw = 0x22334458; + + *(message_ptr+4) = (probe_address /* sender IP address */ << 16) | (msw & NX_LOWER_16_MASK); + *(message_ptr+5) = lsw; + + /* Target address */ + *(message_ptr+6) = (ULONG) 0x0; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Send the ARP request to the driver. */ + driver_request.nx_ip_driver_ptr = ip_ptr; + driver_request.nx_ip_driver_command = NX_LINK_ARP_SEND; + driver_request.nx_ip_driver_packet = packet_ptr; + driver_request.nx_ip_driver_physical_address_msw = 0xFFFFUL; + driver_request.nx_ip_driver_physical_address_lsw = 0xFFFFFFFFUL; + driver_request.nx_ip_driver_interface = nx_interface; + (nx_interface -> nx_interface_link_driver_entry) (&driver_request); + + return NX_SUCCESS; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_arp_probe_fail_multiple_interface_test_application_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: DHCP Client Multiple Interface ARP Probe Fail Test........N/A\n"); + test_control_return(3); +} +#endif /* (NX_MAX_PHYSICAL_INTERFACES >= 2) && (NX_DHCP_CLIENT_MAX_RECORDS >=2) */ + + diff --git a/test/regression/dhcp_test/netx_dhcp_client_arpprobe_fail_multiple_interface.c b/test/regression/dhcp_test/netx_dhcp_client_arpprobe_fail_multiple_interface.c new file mode 100644 index 00000000..1d9e1917 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_arpprobe_fail_multiple_interface.c @@ -0,0 +1,1077 @@ +/* Testing the multiple interface DHCP Client */ + +/* This is the DHCP Client that will run on both interfaces independently. + Required: NX_MAX_PHYSICAL_INTERFACES = 2 and NX_DHCP_CLIENT_MAX_INTERFACES = 1. + There are two DHCP Client threads that are switching from manual to DHCP CLient address + mode, and switch from activated to deactivated. There is one server thread checking + for DHCP Client messages on primary and secondary interfaces. +*/ + + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT); +#ifndef NX_DISABLE_IPV4 +#include "nx_arp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + + + +/* Define the ThreadX, NetX object control blocks... */ + +static NX_UDP_SOCKET server0_socket; +static TX_THREAD client0_thread; +static TX_THREAD client1_thread; +static TX_THREAD server0_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server0_ip; + +static UINT probe0 = NX_FALSE; +static UINT probe1 = NX_FALSE; +static UINT bound0 = NX_FALSE; +static UINT bound1 = NX_FALSE; +static UINT decline0 = NX_FALSE; +static UINT decline1 = NX_FALSE; + +/* Define the NetX FTP object control block. */ +static NX_DHCP dhcp_client; +static ULONG dhcp_xid; + + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 2 +static DHCP_RESPONSE dhcp_response0[NUM_RESPONSES]; +static DHCP_RESPONSE dhcp_response1[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client0_running = NX_TRUE; +static UINT client1_running = NX_TRUE; + + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +static void server0_thread_entry(ULONG thread_input); +static void client0_thread_entry(ULONG thread_input); +static void client1_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number, UINT iface_index); +static void dhcp_test_initialize(); + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size); +static VOID dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state); +static UINT send_arp_reply(NX_IP *ip_ptr, UINT iface_index, ULONG probe_address); + + +/* Note that the network is 192.2.2.0 and the MAC address is 11 22 33 44 56 + because there are four entities (server 2 interfaces, client 2 interfaces + and the ram driver increases the MAC sequentially starting from + 11 22 33 44 56. */ + + +static char offer_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x02, 0x02, 0x01, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response0_size = 300; + +/* Frame (342 bytes) */ +static char ack_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response0_size = 300; + +static char offer_response1[300] = { + +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xF7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x01, 0x01, 0x01, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response1_size = 300; + +/* Frame (342 bytes) */ +static char ack_response1[300] = { + + +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response1_size = 300; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_arpprobe_fail_multiple_interface_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the DHCP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server0_thread, "Server 0 thread ", server0_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server0_ip, + "Server 0 IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + status = nx_ip_interface_attach(&server0_ip, "Server IP", IP_ADDRESS(192,1,1,1), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server0_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server0_ip); + + if (status) + error_counter++; + + /* Set up the Client. */ + + /* Create the main client thread. */ + status = tx_thread_create(&client0_thread, "Client 0", client0_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the secondary client thread. */ + status = tx_thread_create(&client1_thread, "Client 1", client1_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 12*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 12*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, "Client 0 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client 1 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + + if (status) + error_counter++; + + /* Keep track of interface DHCP Client state changes. */ + status = nx_dhcp_interface_state_change_notify(&dhcp_client, dhcp_interface_state_change); + + if (status) + error_counter++; + + return; +} + + +/* Define the DHCP client thread. */ + +void client0_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT time_keeper; + + + tx_thread_sleep(10); + + /* Start DHCP on all enabled interfaces (which at the moment is just the primary interface). */ + status = nx_dhcp_interface_start(&dhcp_client, 0); + if (status != NX_SUCCESS) + { + error_counter++; + } + + if (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_NOT_STARTED) + { + error_counter++; + } + + /* Wait for the Client to bind an ARP adddress, including the ARP probe test. */ + time_keeper = 0; + + while(dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + tx_thread_sleep(10); + time_keeper += 10; + if (time_keeper > 1000) + { + break; + } + } + + if ((probe0 != NX_TRUE) || (bound0 != NX_TRUE) || (decline0 == NX_TRUE)) + { + error_counter++; + } + + /* Now stop the DHCP Client 0. */ + nx_dhcp_interface_disable(&dhcp_client, 0); + + /* Verify the DHCP CLient is not enabled on the primary interface. */ + if (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_NOT_STARTED) + { + error_counter++; + } + + if (client_ip.nx_ip_interface[0].nx_interface_ip_address != 0x0) + { + error_counter++; + } + client0_running = NX_FALSE; + +} + +void client1_thread_entry(ULONG thread_input) +{ + +UINT status; + + + tx_thread_sleep(10); + + if (NX_DHCP_CLIENT_MAX_RECORDS != 2) + { + error_counter++; + } + + status = nx_dhcp_interface_enable(&dhcp_client, 1); + if (status != NX_SUCCESS) + { + + error_counter++; + } + + status = nx_dhcp_interface_start(&dhcp_client, 1); + + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + + UINT time_keeper = 0; + while(probe1 == NX_FALSE) + { + tx_thread_sleep(20); + time_keeper += 20; + if (time_keeper > 1000) + { + break; + } + } + + /* Wait a bit for DHCP Clien to decline the IP address. */ + tx_thread_sleep(50); + + if ((probe1 != NX_TRUE) || (decline1 != NX_TRUE) || (bound1 == NX_TRUE)) + { + error_counter++; + } + + } + + if (client_ip.nx_ip_interface[1].nx_interface_ip_address != 0x0) + { + error_counter++; + } + + client1_running = NX_FALSE; + +} + +/* Define the Primary DHCP server thread. */ +void server0_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i, j, k, pkt_number; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Multiple Interface ARP Probe Fail Test........"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server0_ip, &server0_socket, "Socket 0 Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server0_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + i = 0; + j = 0; + k = 0; + pkt_number = 0; + + /* Set the advanced callback to ensure broadcast packets are routed correctly. */ + advanced_packet_process_callback = my_dhcp_process_bc_callback; + + /* Wait for Client requests */ + while ( i < (2*NUM_RESPONSES)) + { + + status = nx_udp_socket_receive(&server0_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + UINT source_port; + ULONG source_ip_address; + UINT protocol; + UINT iface_index; + + /* Get the XID of DHCP message from DHCP Server. */ + dhcp_xid = dhcp_get_dhcp_data(my_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID, 4); + + nx_udp_packet_info_extract(my_packet, &source_ip_address, &protocol, &source_port, &iface_index); + + /* Release the packet. */ + nx_packet_release(my_packet); + + if (iface_index == 0) + { + pkt_number = j; + + } + else + { + pkt_number = k; + + } + + status = nx_dhcp_response_packet_send(&server0_socket, 68, pkt_number, iface_index); + + if (iface_index == 0) + j++; + else + k++; + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Advance the index for the next response. */ + i++; + } + + /* Set up a scenario to respond to Client ARP Probes on interface 1 */ + while(dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_ADDRESS_PROBING) + tx_thread_sleep(20); + + /* While the DHCP Client is in probe mode, send a conflict response. */ + status = send_arp_reply(&server0_ip, 1, dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_ip_address); + + /* Check status. */ + if (status) + { + error_counter++; + } + /* Should get one more message from the Client, a DECLINE message. */ + status = nx_udp_socket_receive(&server0_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + error_counter++; + } + + /* Wait for the client to terminate the connection. */ + while((client0_running == NX_TRUE) || (client1_running == NX_TRUE)) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server0_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + +static void dhcp_test_initialize() +{ + + + /* Set up server responses on the primary interface. */ + dhcp_response0[0].dhcp_response_pkt_data = &offer_response0[0]; + dhcp_response0[0].dhcp_response_pkt_size = offer_response0_size ; + + dhcp_response0[1].dhcp_response_pkt_data = &ack_response0[0]; + dhcp_response0[1].dhcp_response_pkt_size = ack_response0_size ; + + /* Set up server responses on the secondary interface. */ + dhcp_response1[0].dhcp_response_pkt_data = &offer_response1[0]; + dhcp_response1[0].dhcp_response_pkt_size = offer_response1_size ; + + dhcp_response1[1].dhcp_response_pkt_data = &ack_response1[0]; + dhcp_response1[1].dhcp_response_pkt_size = ack_response1_size ; + +} + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, UINT port, INT packet_number, UINT iface_index) +{ + +UINT status; +NX_PACKET *response_packet; +UCHAR *work_ptr; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS ip_address; +#else +ULONG ip_address; +NX_PACKET **response_packet_ptr_ptr; +#endif + +#ifdef __PRODUCT_NETXDUO__ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = 0xFFFFFFFF; +#else + ip_address = 0xFFFFFFFF; +#endif + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + if (iface_index == 0) + { + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response0[packet_number].dhcp_response_pkt_data, + dhcp_response0[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response0[packet_number].dhcp_response_pkt_size; + } + else if (iface_index == 1) + { + + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response1[packet_number].dhcp_response_pkt_data, + dhcp_response1[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response1[packet_number].dhcp_response_pkt_size; + } + + /* Now replace the XID in the server message with what we know is the Client XID. */ + work_ptr = (UCHAR *)(response_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID); + NX_CHANGE_ULONG_ENDIAN(dhcp_xid); + memcpy(work_ptr, (void const *)(&dhcp_xid), 4); + + + /* Adjust the write pointer. */ + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ +#ifdef __PRODUCT_NETXDUO__ + status = nxd_udp_socket_source_send(server_socket_ptr, response_packet, &ip_address, 68, iface_index); +#else + response_packet_ptr_ptr = &response_packet; + status = nx_udp_socket_interface_send(server_socket_ptr, *response_packet_ptr_ptr, ip_address, 68, iface_index); +#endif + + /* Check the status. */ + if (status) + { + + error_counter++; + + nx_packet_release(response_packet); + } + + return status; +} + + +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + +UCHAR *work_ptr; +ULONG *message_ptr; +UINT interface_index; +UINT packet_client_mac_lsw; +ULONG sender_physical_lsw; +NX_PACKET *packet_copy; + + + /* Check if this is an IP or an ARP (smaller) packet. We don't know where the packet + prepend pointer is so assume anything less than 200 bytes is an ARP packet. */ + if (packet_ptr -> nx_packet_length < 200) + { + + message_ptr = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr); + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 3)); + + sender_physical_lsw = (*(message_ptr + 2) << 16) | (*(message_ptr + 3) >> 16); + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 3)); + + + /* Determine what interface to use based on MAC address and which IP instance is sending the packet. */ + if (sender_physical_lsw == 0x22334458) + { + interface_index = 0; + } + else if (sender_physical_lsw == 0x22334459) + { + interface_index = 1; + } + else + { + /* Don't know what this packet is. Let DHCP Client handle it. */ + return NX_TRUE; + } + } + else /* if (packet_type == MY_DRIVER_ETHERNET_IP) */ + { + + /* Set work_ptr. */ +#ifdef __PRODUCT_NETXDUO__ + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#else + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IP_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#endif + /* Pickup the target MAC address in the DHCP message. */ + packet_client_mac_lsw = (((ULONG)work_ptr[2]) << 24) | + (((ULONG)work_ptr[3]) << 16) | + (((ULONG)work_ptr[4]) << 8) | + ((ULONG)work_ptr[5]); + + /* Determine what interface to use based on MAC address and which IP instance is sending the packet. */ + if (packet_client_mac_lsw == 0x22334458) + { + interface_index = 0; + } + else if (packet_client_mac_lsw == 0x22334459) + { + interface_index = 1; + } + else + { + /* Don't know what this packet is. Let DHCP Client handle it. */ + return NX_TRUE; + } + } + + /* Copy to a new packet and drop the original packet. */ + nx_packet_copy(packet_ptr, &packet_copy, &client_pool, NX_WAIT_FOREVER); + + /* Based on the packet mac address, set the packet interface based on the mac address */ + packet_copy -> nx_packet_ip_interface = &(ip_ptr -> nx_ip_interface[interface_index]); + + if (packet_ptr -> nx_packet_length > 200) + { + + if (ip_ptr == &server0_ip) + { + _nx_ip_packet_receive(&client_ip, packet_copy); + } + else + { + _nx_ip_packet_receive(&server0_ip, packet_copy); + } + } + else + { + + if (ip_ptr == &server0_ip) + { + _nx_arp_packet_receive(&client_ip, packet_copy); + } + else + { + _nx_arp_packet_receive(&server0_ip, packet_copy); + } + } + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + return NX_TRUE; + +} + + +ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size) +{ + +ULONG value = 0; + + + /* Process the data retrieval request. */ + while (size-- > 0) + { + + /* Build return value. */ + value = (value << 8) | *data++; + } + + /* Return value. */ + return(value); +} + +VOID dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state) +{ + + if (iface_index == 0) + { + + if (new_state == NX_DHCP_STATE_ADDRESS_PROBING) + { + probe0 = NX_TRUE; + } + else if (new_state == NX_DHCP_STATE_BOUND) + { + bound0 = NX_TRUE; + } + else if (new_state == NX_DHCP_STATE_INIT) + { + /* Check if the Client has been reset to to INIT + after reaching the ARP probe state. This should not happen. */ + if (probe0 == NX_TRUE) + { + error_counter++; + } + } + } + else if (iface_index == 1) + { + + if (new_state == NX_DHCP_STATE_ADDRESS_PROBING) + { + probe1 = NX_TRUE; + } + else if (new_state == NX_DHCP_STATE_BOUND) + { + bound1 = NX_TRUE; + + /* This should not happen. */ + error_counter++; + } + else if (new_state == NX_DHCP_STATE_INIT) + { + /* Check if the Client has been reset to to INIT + after reaching the ARP probe state. */ + if (probe1 == NX_TRUE) + { + decline1 = NX_TRUE; + } + } + } + else + error_counter++; + + return; +} + + +UINT send_arp_reply(NX_IP *ip_ptr, UINT iface_index, ULONG probe_address) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG *message_ptr; +NX_IP_DRIVER driver_request; +NX_INTERFACE *nx_interface; +ULONG lsw, msw; + + + /* Allocate a packet to build the ARP message in. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &packet_ptr, NX_PHYSICAL_HEADER, NX_NO_WAIT); + if (status != NX_SUCCESS) + { + + /* Error getting packet, so just get out! */ + return status; + } + + /* Stamp the packet with the outgoing interface information, which is the server primary interface. */ + nx_interface = &(ip_ptr -> nx_ip_interface[iface_index]); + + /* Store the probe address on the Client. */ + client_ip.nx_ip_interface[iface_index].nx_interface_ip_probe_address = probe_address;; + //nx_interface -> nx_interface_ip_probe_address = probe_address; + + packet_ptr -> nx_packet_ip_interface = nx_interface; + + /* Build the ARP request packet. */ + + /* Setup the size of the ARP message. */ + packet_ptr -> nx_packet_length = NX_ARP_MESSAGE_SIZE; + + /* Setup the append pointer to the end of the message. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + NX_ARP_MESSAGE_SIZE; + + /* Setup the pointer to the message area. */ + message_ptr = (ULONG *) packet_ptr -> nx_packet_prepend_ptr; + + /* Write the Hardware type into the message. */ + *message_ptr = (ULONG)(NX_ARP_HARDWARE_TYPE << 16) | (NX_ARP_PROTOCOL_TYPE); + *(message_ptr + 1) = (ULONG)(NX_ARP_HARDWARE_SIZE << 24) | (NX_ARP_PROTOCOL_SIZE << 16) | + NX_ARP_OPTION_REQUEST; + + /* Sender mac address. Note this is a phone MAC address from 'another' host on the network. */ + msw = 0x000c; + lsw = 0xf17dcaa6; + + *(message_ptr+2) = (ULONG) (msw << 16) |(lsw >> 16); + /* Rest of sender mac address,upper bytes of sender address */ + *(message_ptr + 3) = (ULONG)((lsw << 16) | (probe_address >> 16)); + + /* Target mac address */ + msw = 0x11; + lsw = 0x22334458; + + *(message_ptr+4) = (probe_address /* sender IP address */ << 16) | (msw & NX_LOWER_16_MASK); + *(message_ptr+5) = lsw; + + /* Target address */ + *(message_ptr+6) = (ULONG) 0x0; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Send the ARP request to the driver. */ + driver_request.nx_ip_driver_ptr = ip_ptr; + driver_request.nx_ip_driver_command = NX_LINK_ARP_SEND; + driver_request.nx_ip_driver_packet = packet_ptr; + driver_request.nx_ip_driver_physical_address_msw = 0xFFFFUL; + driver_request.nx_ip_driver_physical_address_lsw = 0xFFFFFFFFUL; + driver_request.nx_ip_driver_interface = nx_interface; + (nx_interface -> nx_interface_link_driver_entry) (&driver_request); + + return NX_SUCCESS; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_arpprobe_fail_multiple_interface_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: DHCP Client Multiple Interface ARP Probe Fail Test..........N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_client_arpprobe_fails.c b/test/regression/dhcp_test/netx_dhcp_client_arpprobe_fails.c new file mode 100644 index 00000000..8ab50348 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_arpprobe_fails.c @@ -0,0 +1,702 @@ +/* Testing the multiple interface DHCP Client */ + +/* Test with NX_DHCP_CLIENT_SEND_ARP_PROBE enabled on the DHCP Client. Only using + one interface at present. To get this to work with a RAM driver, the 'DHCP server' + assigns its own address to the DHCP Client. When the Client sends the ARP probe + the server will automatically respond. On receiving this ARP message, the Client + IP stores it in its table. On the next expiration between sending probes, the Client + checks the ARP table, finds this entry and declares the IP address is not unique. + It sends a DECLINE message and start again in the INIT state. */ + + // jlc to do + // need to add a way to confirm DECLINE is sent e.g. add declines_recvd to the struct? + // need a way to 'stop' the client test. Right now it spins endlessly. + // test on NetX DUo 5.11 with the new ARP send probe/handle conflict logic + + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + +/* Define the ThreadX, NetX object control blocks... */ + +NX_UDP_SOCKET server_socket; +TX_THREAD client_thread; +TX_THREAD server_thread; +NX_PACKET_POOL client_pool; +NX_PACKET_POOL server_pool; +NX_IP client_ip; +NX_IP server_ip; + + +/* Define the NetX FTP object control block. */ +NX_DHCP dhcp_client; + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 3 +static DHCP_RESPONSE dhcp_response[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client_running = NX_FALSE; +static UINT state_changes[2] = {0,0}; +static UINT renews[2] = {0,0}; +static UINT rebinds[2] = {0,0}; +static UINT bounds[2] = {0,0}; + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +void server_thread_entry(ULONG thread_input); +void client_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number); +static void dhcp_test_initialize(); +static UINT send_arp_reply(NX_DHCP *dhcp_ptr, UINT iface_index); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); +static void dhcp_interface_state_change0(NX_DHCP *dhcp_ptr, UCHAR new_state); +static void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state); + +extern void test_control_return(UINT); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +static char offer_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x31, 0x9D, /* {.....T. */ +0x58, 0xAD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0x01, 0xc0, 0x02, /* ........ 192.2.2.1*/ +//0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ '192.2.2.247*/ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x02, 0x02, 0x01, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response_size = 300; + +/* Frame (342 bytes) */ +static char ack_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x31, 0x9D, /* {.....T. */ +0x58, 0xAD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0x01, 0xc0, 0x02, /* ........ */ +//0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response_size = 300; + +// this isn't used but just leave it here. +static char arp_response[60] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x57, // dest +0x00, 0x0c, 0xf1, 0x7d, 0xca, 0xa6, // source +0x08, 0x06, +0x00, 0x01, +0x08, 0x00, +0x06, 0x04, 0x00, 0x02, +0x00, 0x0c, 0xf1, 0x7d, 0xca, 0xa6, // source mac - who cares, someone else +0xc0, 0x02, 0x02, 0xF7, // source IP - node who owns IP address already +0x00, 0x11, 0x22, 0x33, 0x44, 0x57, // target mac - dhcp client mac +0x00, 0x00, 0x00, 0x0, // target IP - should be zeroes? +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .\...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + +static int arp_response_size = 60; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_cilent_arpprobe_fails_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the FTP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server_thread, "Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, + pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + if (status) + error_counter++; + + + /* Set up the Client. */ + + /* Create the main client thread. */ + status = tx_thread_create(&client_thread, "Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 25*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 25*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + + return; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + + + /* Let the server set up. */ + tx_thread_sleep(30); + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +UINT skip_discover_message = NX_FALSE; +#endif + + tx_thread_sleep(20); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + if (status) + error_counter++; + + /* Set the client IP if the host is configured to do so. */ +#ifdef REQUEST_CLIENT_IP + + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + +#endif + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + status = nx_dhcp_interface_state_change_notify(&dhcp_client, 0, dhcp_interface_state_change0); + if (status) + error_counter++; + status = nx_dhcp_interface_state_change_notify(&dhcp_client, 1, dhcp_interface_state_change1); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + while(client_running == NX_FALSE) + { + tx_thread_sleep(100); + } + + // jlc add status_interface check on IP address + // then wait for ****; + // if declines != 1; error + // if state != INIT/SELECTING error + +} + + +/* Define the helper FTP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client ARP Probe Multiple Interface Test1............\n"); // jlc remove the \n + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + i = 0; + + /* Wait for Client requests */ + while ( i < NUM_RESPONSES) + { + + if (i <= 1) + { + + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + else + { + printf("\nRECVd %dth packet\n", i); + + /* Release the packet. */ + nx_packet_release(my_packet); + + printf("Server sending response back. \n"); + status = nx_dhcp_response_packet_send(&server_socket, 68, i); + } + } + else + { + + /* Wait for the dhcp client to start the ARP probe process. */ + while (dhcp_client.nx_dhcp_interface[0].nx_dhcp_probe_count == 0) + tx_thread_sleep(10); + printf("Owner should send the Probe reply\n"); + } + + /* Check status. */ + if (status) + { + + printf("ERROR8!\n"); + error_counter++; + } + + + /* Advance the index for the next response. */ + i++; + } + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + /* Should get one more message from the Client, a DECLINE message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + + + printf("All done, waiting for client to go away\n"); + + /* Wait for the client to terminate the connection. */ + while(client_running != NX_TRUE) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +static void dhcp_test_initialize() +{ + + +/* Download data responses */ + dhcp_response[0].dhcp_response_pkt_data = &offer_response[0]; + dhcp_response[0].dhcp_response_pkt_size = offer_response_size ; + + dhcp_response[1].dhcp_response_pkt_data = &ack_response[0]; + dhcp_response[1].dhcp_response_pkt_size = ack_response_size ; + + dhcp_response[2].dhcp_response_pkt_data = &arp_response[0]; + dhcp_response[2].dhcp_response_pkt_size = arp_response_size ; + +} + + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + printf("Sending %dth response\n", packet_number); + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data, + dhcp_response[packet_number].dhcp_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ + status = nx_udp_socket_send(server_socket, response_packet, 0xFFFFFFFF, 68); + + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} + +UINT send_arp_reply(NX_DHCP *dhcp_ptr, UINT iface_index) +{ + +UINT status; +NX_PACKET *request_ptr; +ULONG *message_ptr; +NX_IP_DRIVER driver_request; +NX_IP *ip_ptr; +NX_INTERFACE *dhcp_interface; +ULONG lsw, msw, sender_ip_address; + + ip_ptr = dhcp_ptr -> nx_dhcp_ip_ptr; + + /* Allocate a packet to build the ARP message in. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &request_ptr, NX_PHYSICAL_HEADER, NX_NO_WAIT); + if (status != NX_SUCCESS) + { + + /* Error getting packet, so just get out! */ + return status; + } + /* Stamp the packet with the outgoing interface information. */ + dhcp_interface = &(ip_ptr -> nx_ip_interface[iface_index]); + request_ptr -> nx_packet_ip_interface = dhcp_interface; + + /* Build the ARP request packet. */ + + /* Setup the size of the ARP message. */ + request_ptr -> nx_packet_length = 28; + + /* Setup the append pointer to the end of the message. */ + request_ptr -> nx_packet_append_ptr = request_ptr -> nx_packet_prepend_ptr + 28; + + /* Setup the pointer to the message area. */ + message_ptr = (ULONG *) request_ptr -> nx_packet_prepend_ptr; + + /* Write the Hardware type into the message. */ + *message_ptr = (ULONG) (1 << 16) | (0x08); + *(message_ptr+1) = (ULONG) (6 << 24) | (4 << 16) | 2; + /* Sender mac address */ + msw = 0x0c; + lsw = 0xf17dcaa6; + *(message_ptr+2) = (ULONG) (msw << 16) |(lsw >> 16); + + /* Rest of sender mac address and sender IP address */ + sender_ip_address = dhcp_ptr -> nx_dhcp_interface[iface_index].nx_dhcp_ip_address; + *(message_ptr+3) = (ULONG) ((lsw << 16) | (sender_ip_address >> 16)); + + /* Target mac address */ + msw = 0x11; + lsw = 0x22334457; + *(message_ptr+4) = (msw << 16) |(lsw >> 16); + *(message_ptr+4) = (sender_ip_address << 16) | (msw & NX_LOWER_16_MASK); + *(message_ptr+5) = lsw; + + /* Target address */ + *(message_ptr+6) = (ULONG) 0x0; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Send the ARP request to the driver. */ + driver_request.nx_ip_driver_ptr = ip_ptr; + driver_request.nx_ip_driver_command = NX_LINK_ARP_SEND; + driver_request.nx_ip_driver_packet = request_ptr; + driver_request.nx_ip_driver_physical_address_msw = 0xFFFFUL; + driver_request.nx_ip_driver_physical_address_lsw = 0xFFFFFFFFUL; + driver_request.nx_ip_driver_interface = dhcp_interface; + (dhcp_interface -> nx_interface_link_driver_entry) (&driver_request); + + return NX_SUCCESS; +} + +// jlc this does not get called. Is that correct behavior? +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + dhcp_interface_state_change0(dhcp_ptr, new_state); +} + +void dhcp_interface_state_change0(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + +UINT dhcp_state; + + dhcp_state = (UINT)new_state; + + + /* Increment state changes counter. */ + state_changes[0]++; + + if (dhcp_state == NX_DHCP_STATE_RENEWING) + { + renews[0]++; + } + else if (dhcp_state == NX_DHCP_STATE_REBINDING) + { + rebinds[0]++; + } + else if (dhcp_state == NX_DHCP_STATE_BOUND) + { + bounds[0]++; + } + + return; +} + + +void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + +UINT dhcp_state; + + dhcp_state = (UINT)new_state; + + + /* Increment state changes counter. */ + state_changes[1]++; + + if (dhcp_state == NX_DHCP_STATE_RENEWING) + { + renews[1]++; + } + else if (dhcp_state == NX_DHCP_STATE_REBINDING) + { + rebinds[1]++; + } + else if (dhcp_state == NX_DHCP_STATE_BOUND) + { + bounds[1]++; + } + + return; +} + + diff --git a/test/regression/dhcp_test/netx_dhcp_client_arpprobe_multiple_interface.c b/test/regression/dhcp_test/netx_dhcp_client_arpprobe_multiple_interface.c new file mode 100644 index 00000000..90366e09 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_arpprobe_multiple_interface.c @@ -0,0 +1,950 @@ +/* Testing the multiple interface DHCP Client */ + +/* This is the DHCP Client that will run on both interfaces independently. + Required: NX_MAX_PHYSICAL_INTERFACES = 2 and NX_DHCP_CLIENT_MAX_INTERFACES = 1. + There are two DHCP Client threads that are switching from manual to DHCP CLient address + mode, and switch from activated to deactivated. There is one server thread checking + for DHCP Client messages on primary and secondary interfaces. +*/ + + + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT); +#ifndef NX_DISABLE_IPV4 +#include "nx_arp.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + + + +/* Define the ThreadX, NetX object control blocks... */ + +static NX_UDP_SOCKET server0_socket; +static TX_THREAD client0_thread; +static TX_THREAD client1_thread; +static TX_THREAD server0_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server0_ip; + +static UINT probe0 = NX_FALSE; +static UINT probe1 = NX_FALSE; +static UINT bound0 = NX_FALSE; +static UINT bound1 = NX_FALSE; + +/* Define the NetX FTP object control block. */ +static NX_DHCP dhcp_client; +static ULONG dhcp_xid; + + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 2 +static DHCP_RESPONSE dhcp_response0[NUM_RESPONSES]; +static DHCP_RESPONSE dhcp_response1[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client0_running = NX_TRUE; +static UINT client1_running = NX_TRUE; + + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +static void server0_thread_entry(ULONG thread_input); +static void client0_thread_entry(ULONG thread_input); +static void client1_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number, UINT iface_index); +static void dhcp_test_initialize(); + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size); +static VOID dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state); + + +/* Note that the network is 192.2.2.0 and the MAC address is 11 22 33 44 56 + because there are four entities (server 2 interfaces, client 2 interfaces + and the ram driver increases the MAC sequentially starting from + 11 22 33 44 56. */ + + +static char offer_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x02, 0x02, 0x01, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response0_size = 300; + +/* Frame (342 bytes) */ +static char ack_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response0_size = 300; + +static char offer_response1[300] = { + +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xF7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x01, 0x01, 0x01, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response1_size = 300; + +/* Frame (342 bytes) */ +static char ack_response1[300] = { + +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response1_size = 300; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_arpprobe_multiple_interface_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the DHCP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server0_thread, "Server 0 thread ", server0_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server0_ip, + "Server 0 IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + status = nx_ip_interface_attach(&server0_ip, "Server IP", IP_ADDRESS(192,1,1,1), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server0_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server0_ip); + + if (status) + error_counter++; + + /* Set up the Client. */ + + /* Create the main client thread. */ + status = tx_thread_create(&client0_thread, "Client 0", client0_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the secondary client thread. */ + status = tx_thread_create(&client1_thread, "Client 1", client1_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 12*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 12*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, "Client 0 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client 1 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + + if (status) + error_counter++; + + /* Keep track of interface DHCP Client state changes. */ + status = nx_dhcp_interface_state_change_notify(&dhcp_client, dhcp_interface_state_change); + + if (status) + error_counter++; + + return; +} + + +/* Define the DHCP client thread. */ + +void client0_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT time_keeper; + + + tx_thread_sleep(10); + + /* Start DHCP on all enabled interfaces (which at the moment is just the primary interface). */ + status = nx_dhcp_interface_start(&dhcp_client, 0); + if (status != NX_SUCCESS) + { + error_counter++; + } + + if (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_NOT_STARTED) + { + error_counter++; + } + + /* Wait for the Client to bind an ARP adddress, including the ARP probe test. */ + time_keeper = 0; + + while(dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + tx_thread_sleep(10); + time_keeper += 10; + if (time_keeper > 1000) + { + break; + } + } + + if ((probe0 != NX_TRUE) || (bound0 != NX_TRUE)) + { + error_counter++; + } + + /* Now stop the DHCP Client 0. */ + nx_dhcp_interface_disable(&dhcp_client, 0); + + /* Verify the DHCP CLient is not enabled on the primary interface. */ + if (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_NOT_STARTED) + { + error_counter++; + } + + if (client_ip.nx_ip_interface[0].nx_interface_ip_address != 0x0) + { + error_counter++; + } + client0_running = NX_FALSE; + +} + +void client1_thread_entry(ULONG thread_input) +{ + +UINT status; + + + tx_thread_sleep(10); + + if (NX_DHCP_CLIENT_MAX_RECORDS != 2) + { + error_counter++; + } + + status = nx_dhcp_interface_enable(&dhcp_client, 1); + if (status != NX_SUCCESS) + { + + error_counter++; + } + + status = nx_dhcp_interface_start(&dhcp_client, 1); + + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + + UINT time_keeper = 0; + while(dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + tx_thread_sleep(20); + time_keeper += 20; + if (time_keeper > 1000) + { + break; + } + } + + if ((probe1 != NX_TRUE) || (bound1 != NX_TRUE)) + { + error_counter++; + } + + /* Now disable DHCP Client 1 activity. This reinitializes the Client too. */ + status = nx_dhcp_interface_disable(&dhcp_client, 1); + if (status) + { + error_counter++; + } + } + + if (dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_NOT_STARTED) + { + error_counter++; + } + + if (client_ip.nx_ip_interface[1].nx_interface_ip_address != 0x0) + { + error_counter++; + } + client1_running = NX_FALSE; +} + +/* Define the Primary DHCP server thread. */ +void server0_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i, j, k, pkt_number; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Multiple Interface ARP Probe Test............."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server0_ip, &server0_socket, "Socket 0 Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server0_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + i = 0; + j = 0; + k = 0; + pkt_number = 0; + + /* Set the advanced callback to ensure broadcast packets are routed correctly. */ + advanced_packet_process_callback = my_dhcp_process_bc_callback; + + /* Wait for Client requests */ + while ( i < (2*NUM_RESPONSES)) + { + + status = nx_udp_socket_receive(&server0_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + UINT source_port; + ULONG source_ip_address; + UINT protocol; + UINT iface_index; + + /* Get the XID of DHCP message from DHCP Server. */ + dhcp_xid = dhcp_get_dhcp_data(my_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID, 4); + + nx_udp_packet_info_extract(my_packet, &source_ip_address, &protocol, &source_port, &iface_index); + + /* Release the packet. */ + nx_packet_release(my_packet); + + if (iface_index == 0) + { + pkt_number = j; + + } + else + { + pkt_number = k; + + } + + status = nx_dhcp_response_packet_send(&server0_socket, 68, pkt_number, iface_index); + + if (iface_index == 0) + j++; + else + k++; + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Advance the index for the next response. */ + i++; + } + + /* Wait for the client to terminate the connection. */ + while((client0_running == NX_TRUE) || (client1_running == NX_TRUE)) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server0_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + +static void dhcp_test_initialize() +{ + + + /* Set up server responses on the primary interface. */ + dhcp_response0[0].dhcp_response_pkt_data = &offer_response0[0]; + dhcp_response0[0].dhcp_response_pkt_size = offer_response0_size ; + + dhcp_response0[1].dhcp_response_pkt_data = &ack_response0[0]; + dhcp_response0[1].dhcp_response_pkt_size = ack_response0_size ; + + /* Set up server responses on the secondary interface. */ + dhcp_response1[0].dhcp_response_pkt_data = &offer_response1[0]; + dhcp_response1[0].dhcp_response_pkt_size = offer_response1_size ; + + dhcp_response1[1].dhcp_response_pkt_data = &ack_response1[0]; + dhcp_response1[1].dhcp_response_pkt_size = ack_response1_size ; + +} + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, UINT port, INT packet_number, UINT iface_index) +{ + +UINT status; +NX_PACKET *response_packet; +UCHAR *work_ptr; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS ip_address; +#else +ULONG ip_address; +NX_PACKET **response_packet_ptr_ptr; +#endif + +#ifdef __PRODUCT_NETXDUO__ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = 0xFFFFFFFF; +#else + ip_address = 0xFFFFFFFF; +#endif + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + if (iface_index == 0) + { + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response0[packet_number].dhcp_response_pkt_data, + dhcp_response0[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response0[packet_number].dhcp_response_pkt_size; + } + else if (iface_index == 1) + { + + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response1[packet_number].dhcp_response_pkt_data, + dhcp_response1[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response1[packet_number].dhcp_response_pkt_size; + } + + /* Now replace the XID in the server message with what we know is the Client XID. */ + work_ptr = (UCHAR *)(response_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID); + NX_CHANGE_ULONG_ENDIAN(dhcp_xid); + memcpy(work_ptr, (void const *)(&dhcp_xid), 4); + + + /* Adjust the write pointer. */ + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ +#ifdef __PRODUCT_NETXDUO__ + status = nxd_udp_socket_source_send(server_socket_ptr, response_packet, &ip_address, 68, iface_index); +#else + response_packet_ptr_ptr = &response_packet; + status = nx_udp_socket_interface_send(server_socket_ptr, *response_packet_ptr_ptr, ip_address, 68, iface_index); +#endif + + /* Check the status. */ + if (status) + { + + error_counter++; + + nx_packet_release(response_packet); + } + + return status; +} + + +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + +UCHAR *work_ptr; +ULONG *message_ptr; +UINT interface_index; +UINT packet_client_mac_lsw; +ULONG sender_physical_lsw; +NX_PACKET *packet_copy; + + + /* Check if this is an IP or an ARP (smaller) packet. We don't know where the packet + prepend pointer is so assume anything less than 200 bytes is an ARP packet. */ + if (packet_ptr -> nx_packet_length < 200) + { + + message_ptr = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr); + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 3)); + + sender_physical_lsw = (*(message_ptr + 2) << 16) | (*(message_ptr + 3) >> 16); + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 3)); + + + /* Determine what interface to use based on MAC address and which IP instance is sending the packet. */ + if (sender_physical_lsw == 0x22334458) + { + interface_index = 0; + } + else if (sender_physical_lsw == 0x22334459) + { + interface_index = 1; + } + else + { + /* Don't know what this packet is. Let DHCP Client handle it. */ + return NX_TRUE; + } + } + else /* if (packet_type == MY_DRIVER_ETHERNET_IP) */ + { + + /* Set work_ptr. */ +#ifdef __PRODUCT_NETXDUO__ + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#else + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IP_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#endif + /* Pickup the target MAC address in the DHCP message. */ + packet_client_mac_lsw = (((ULONG)work_ptr[2]) << 24) | + (((ULONG)work_ptr[3]) << 16) | + (((ULONG)work_ptr[4]) << 8) | + ((ULONG)work_ptr[5]); + + /* Determine what interface to use based on MAC address and which IP instance is sending the packet. */ + if (packet_client_mac_lsw == 0x22334458) + { + interface_index = 0; + } + else if (packet_client_mac_lsw == 0x22334459) + { + interface_index = 1; + } + else + { + /* Don't know what this packet is. Let DHCP Client handle it. */ + return NX_TRUE; + } + } + + /* Copy to a new packet and drop the original packet. */ + nx_packet_copy(packet_ptr, &packet_copy, &client_pool, NX_WAIT_FOREVER); + + /* Based on the packet mac address, set the packet interface based on the mac address */ + packet_copy -> nx_packet_ip_interface = &(ip_ptr -> nx_ip_interface[interface_index]); + + if (packet_ptr -> nx_packet_length > 200) + { + + if (ip_ptr == &server0_ip) + { + _nx_ip_packet_receive(&client_ip, packet_copy); + } + else + { + _nx_ip_packet_receive(&server0_ip, packet_copy); + } + } + else + { + + if (ip_ptr == &server0_ip) + { + _nx_arp_packet_receive(&client_ip, packet_copy); + } + else + { + _nx_arp_packet_receive(&server0_ip, packet_copy); + } + } + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + return NX_TRUE; + +} + +ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size) +{ + +ULONG value = 0; + + + /* Process the data retrieval request. */ + while (size-- > 0) + { + + /* Build return value. */ + value = (value << 8) | *data++; + } + + /* Return value. */ + return(value); +} + +VOID dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state) +{ + + if (iface_index == 0) + { + + if (new_state == NX_DHCP_STATE_ADDRESS_PROBING) + { + probe0 = NX_TRUE; + } + else if (new_state == NX_DHCP_STATE_BOUND) + { + bound0 = NX_TRUE; + } + } + else if (iface_index == 1) + { + + if (new_state == NX_DHCP_STATE_ADDRESS_PROBING) + { + probe1 = NX_TRUE; + } + else if (new_state == NX_DHCP_STATE_BOUND) + { + bound1 = NX_TRUE; + } + } + else + error_counter++; + + return; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_arpprobe_multiple_interface_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: DHCP Client Multiple Interface ARP Probe Test...............N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_client_arpprobe_multiple_interface_test.c b/test/regression/dhcp_test/netx_dhcp_client_arpprobe_multiple_interface_test.c new file mode 100644 index 00000000..b1bdbd19 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_arpprobe_multiple_interface_test.c @@ -0,0 +1,949 @@ +/* Testing the multiple interface DHCP Client */ + +/* This is the DHCP Client that will run on both interfaces independently. + Required: NX_MAX_PHYSICAL_INTERFACES = 2 and NX_DHCP_CLIENT_MAX_INTERFACES = 1. + There are two DHCP Client threads that are switching from manual to DHCP CLient address + mode, and switch from activated to deactivated. There is one server thread checking + for DHCP Client messages on primary and secondary interfaces. +*/ + + + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT); +#ifndef NX_DISABLE_IPV4 +#include "nx_arp.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + + + +/* Define the ThreadX, NetX object control blocks... */ + +static NX_UDP_SOCKET server0_socket; +static TX_THREAD client0_thread; +static TX_THREAD client1_thread; +static TX_THREAD server0_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server0_ip; + +static UINT probe0 = NX_FALSE; +static UINT probe1 = NX_FALSE; +static UINT bound0 = NX_FALSE; +static UINT bound1 = NX_FALSE; + +/* Define the NetX FTP object control block. */ +static NX_DHCP dhcp_client; +static ULONG dhcp_xid; + + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 2 +static DHCP_RESPONSE dhcp_response0[NUM_RESPONSES]; +static DHCP_RESPONSE dhcp_response1[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client0_running = NX_TRUE; +static UINT client1_running = NX_TRUE; + + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +static void server0_thread_entry(ULONG thread_input); +static void client0_thread_entry(ULONG thread_input); +static void client1_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number, UINT iface_index); +static void dhcp_test_initialize(); + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size); +static VOID dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state); + + +/* Note that the network is 192.2.2.0 and the MAC address is 11 22 33 44 56 + because there are four entities (server 2 interfaces, client 2 interfaces + and the ram driver increases the MAC sequentially starting from + 11 22 33 44 56. */ + + +static char offer_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x02, 0x02, 0x01, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response0_size = 300; + +/* Frame (342 bytes) */ +static char ack_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response0_size = 300; + +static char offer_response1[300] = { + +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xF7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x01, 0x01, 0x01, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response1_size = 300; + +/* Frame (342 bytes) */ +static char ack_response1[300] = { + +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response1_size = 300; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_arpprobe_multiple_interface_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the DHCP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server0_thread, "Server 0 thread ", server0_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server0_ip, + "Server 0 IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + status = nx_ip_interface_attach(&server0_ip, "Server IP", IP_ADDRESS(192,1,1,1), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server0_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server0_ip); + + if (status) + error_counter++; + + /* Set up the Client. */ + + /* Create the main client thread. */ + status = tx_thread_create(&client0_thread, "Client 0", client0_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the secondary client thread. */ + status = tx_thread_create(&client1_thread, "Client 1", client1_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 12*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 12*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, "Client 0 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client 1 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + + if (status) + error_counter++; + + /* Keep track of interface DHCP Client state changes. */ + status = nx_dhcp_interface_state_change_notify(&dhcp_client, dhcp_interface_state_change); + + if (status) + error_counter++; + + return; +} + + +/* Define the DHCP client thread. */ + +void client0_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT time_keeper; + + + tx_thread_sleep(10); + + /* Start DHCP on all enabled interfaces (which at the moment is just the primary interface). */ + status = nx_dhcp_interface_start(&dhcp_client, 0); + if (status != NX_SUCCESS) + { + error_counter++; + } + + if (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_NOT_STARTED) + { + error_counter++; + } + + /* Wait for the Client to bind an ARP adddress, including the ARP probe test. */ + time_keeper = 0; + + while(dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + tx_thread_sleep(10); + time_keeper += 10; + if (time_keeper > 1000) + { + break; + } + } + + if ((probe0 != NX_TRUE) || (bound0 != NX_TRUE)) + { + error_counter++; + } + + /* Now stop the DHCP Client 0. */ + nx_dhcp_interface_disable(&dhcp_client, 0); + + /* Verify the DHCP CLient is not enabled on the primary interface. */ + if (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_NOT_STARTED) + { + error_counter++; + } + + if (client_ip.nx_ip_interface[0].nx_interface_ip_address != 0x0) + { + error_counter++; + } + client0_running = NX_FALSE; + +} + +void client1_thread_entry(ULONG thread_input) +{ + +UINT status; + + + tx_thread_sleep(10); + + if (NX_DHCP_CLIENT_MAX_RECORDS != 2) + { + error_counter++; + } + + status = nx_dhcp_interface_enable(&dhcp_client, 1); + if (status != NX_SUCCESS) + { + + error_counter++; + } + + status = nx_dhcp_interface_start(&dhcp_client, 1); + + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + + UINT time_keeper = 0; + while(dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + tx_thread_sleep(20); + time_keeper += 20; + if (time_keeper > 1000) + { + break; + } + } + + if ((probe1 != NX_TRUE) || (bound1 != NX_TRUE)) + { + error_counter++; + } + + /* Now disable DHCP Client 1 activity. This reinitializes the Client too. */ + status = nx_dhcp_interface_disable(&dhcp_client, 1); + if (status) + { + error_counter++; + } + } + + if (dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_NOT_STARTED) + { + error_counter++; + } + + if (client_ip.nx_ip_interface[1].nx_interface_ip_address != 0x0) + { + error_counter++; + } + client1_running = NX_FALSE; +} + +/* Define the Primary DHCP server thread. */ +void server0_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i, j, k, pkt_number; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Multiple Interface ARP Probe Test............."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server0_ip, &server0_socket, "Socket 0 Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server0_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + i = 0; + j = 0; + k = 0; + pkt_number = 0; + + /* Set the advanced callback to ensure broadcast packets are routed correctly. */ + advanced_packet_process_callback = my_dhcp_process_bc_callback; + + /* Wait for Client requests */ + while ( i < (2*NUM_RESPONSES)) + { + + status = nx_udp_socket_receive(&server0_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + UINT source_port; + ULONG source_ip_address; + UINT protocol; + UINT iface_index; + + /* Get the XID of DHCP message from DHCP Server. */ + dhcp_xid = dhcp_get_dhcp_data(my_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID, 4); + + nx_udp_packet_info_extract(my_packet, &source_ip_address, &protocol, &source_port, &iface_index); + + /* Release the packet. */ + nx_packet_release(my_packet); + + if (iface_index == 0) + { + pkt_number = j; + + } + else + { + pkt_number = k; + + } + + status = nx_dhcp_response_packet_send(&server0_socket, 68, pkt_number, iface_index); + + if (iface_index == 0) + j++; + else + k++; + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Advance the index for the next response. */ + i++; + } + + /* Wait for the client to terminate the connection. */ + while((client0_running == NX_TRUE) || (client1_running == NX_TRUE)) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server0_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + +static void dhcp_test_initialize() +{ + + + /* Set up server responses on the primary interface. */ + dhcp_response0[0].dhcp_response_pkt_data = &offer_response0[0]; + dhcp_response0[0].dhcp_response_pkt_size = offer_response0_size ; + + dhcp_response0[1].dhcp_response_pkt_data = &ack_response0[0]; + dhcp_response0[1].dhcp_response_pkt_size = ack_response0_size ; + + /* Set up server responses on the secondary interface. */ + dhcp_response1[0].dhcp_response_pkt_data = &offer_response1[0]; + dhcp_response1[0].dhcp_response_pkt_size = offer_response1_size ; + + dhcp_response1[1].dhcp_response_pkt_data = &ack_response1[0]; + dhcp_response1[1].dhcp_response_pkt_size = ack_response1_size ; + +} + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, UINT port, INT packet_number, UINT iface_index) +{ + +UINT status; +NX_PACKET *response_packet; +UCHAR *work_ptr; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS ip_address; +#else +ULONG ip_address; +NX_PACKET **response_packet_ptr_ptr; +#endif + +#ifdef __PRODUCT_NETXDUO__ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = 0xFFFFFFFF; +#else + ip_address = 0xFFFFFFFF; +#endif + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + if (iface_index == 0) + { + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response0[packet_number].dhcp_response_pkt_data, + dhcp_response0[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response0[packet_number].dhcp_response_pkt_size; + } + else if (iface_index == 1) + { + + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response1[packet_number].dhcp_response_pkt_data, + dhcp_response1[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response1[packet_number].dhcp_response_pkt_size; + } + + /* Now replace the XID in the server message with what we know is the Client XID. */ + work_ptr = (UCHAR *)(response_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID); + NX_CHANGE_ULONG_ENDIAN(dhcp_xid); + memcpy(work_ptr, (void const *)(&dhcp_xid), 4); + + + /* Adjust the write pointer. */ + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ +#ifdef __PRODUCT_NETXDUO__ + status = nxd_udp_socket_source_send(server_socket_ptr, response_packet, &ip_address, 68, iface_index); +#else + response_packet_ptr_ptr = &response_packet; + status = nx_udp_socket_interface_send(server_socket_ptr, *response_packet_ptr_ptr, ip_address, 68, iface_index); +#endif + + /* Check the status. */ + if (status) + { + + error_counter++; + + nx_packet_release(response_packet); + } + + return status; +} + + +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + +UCHAR *work_ptr; +ULONG *message_ptr; +UINT interface_index; +UINT packet_client_mac_lsw; +ULONG sender_physical_lsw; +NX_PACKET *packet_copy; + + + /* Check if this is an IP or an ARP (smaller) packet. We don't know where the packet + prepend pointer is so assume anything less than 200 bytes is an ARP packet. */ + if (packet_ptr -> nx_packet_length < 200) + { + + message_ptr = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr); + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 3)); + + sender_physical_lsw = (*(message_ptr + 2) << 16) | (*(message_ptr + 3) >> 16); + + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr + 3)); + + + /* Determine what interface to use based on MAC address and which IP instance is sending the packet. */ + if (sender_physical_lsw == 0x22334458) + { + interface_index = 0; + } + else if (sender_physical_lsw == 0x22334459) + { + interface_index = 1; + } + else + { + /* Don't know what this packet is. Let DHCP Client handle it. */ + return NX_TRUE; + } + } + else /* if (packet_type == MY_DRIVER_ETHERNET_IP) */ + { + + /* Set work_ptr. */ +#ifdef __PRODUCT_NETXDUO__ + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#else + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IP_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#endif + /* Pickup the target MAC address in the DHCP message. */ + packet_client_mac_lsw = (((ULONG)work_ptr[2]) << 24) | + (((ULONG)work_ptr[3]) << 16) | + (((ULONG)work_ptr[4]) << 8) | + ((ULONG)work_ptr[5]); + + /* Determine what interface to use based on MAC address and which IP instance is sending the packet. */ + if (packet_client_mac_lsw == 0x22334458) + { + interface_index = 0; + } + else if (packet_client_mac_lsw == 0x22334459) + { + interface_index = 1; + } + else + { + /* Don't know what this packet is. Let DHCP Client handle it. */ + return NX_TRUE; + } + } + + /* Copy to a new packet and drop the original packet. */ + nx_packet_copy(packet_ptr, &packet_copy, &client_pool, NX_WAIT_FOREVER); + + /* Based on the packet mac address, set the packet interface based on the mac address */ + packet_copy -> nx_packet_ip_interface = &(ip_ptr -> nx_ip_interface[interface_index]); + + if (packet_ptr -> nx_packet_length > 200) + { + + if (ip_ptr == &server0_ip) + { + _nx_ip_packet_receive(&client_ip, packet_copy); + } + else + { + _nx_ip_packet_receive(&server0_ip, packet_copy); + } + } + else + { + + if (ip_ptr == &server0_ip) + { + _nx_arp_packet_receive(&client_ip, packet_copy); + } + else + { + _nx_arp_packet_receive(&server0_ip, packet_copy); + } + } + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + return NX_TRUE; + +} + +ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size) +{ + +ULONG value = 0; + + + /* Process the data retrieval request. */ + while (size-- > 0) + { + + /* Build return value. */ + value = (value << 8) | *data++; + } + + /* Return value. */ + return(value); +} + +VOID dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state) +{ + + if (iface_index == 0) + { + + if (new_state == NX_DHCP_STATE_ADDRESS_PROBING) + { + probe0 = NX_TRUE; + } + else if (new_state == NX_DHCP_STATE_BOUND) + { + bound0 = NX_TRUE; + } + } + else if (iface_index == 1) + { + + if (new_state == NX_DHCP_STATE_ADDRESS_PROBING) + { + probe1 = NX_TRUE; + } + else if (new_state == NX_DHCP_STATE_BOUND) + { + bound1 = NX_TRUE; + } + } + else + error_counter++; + + return; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_arpprobe_multiple_interface_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: DHCP Client Multiple Interface ARP Probe Test...............N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_client_arpprobe_succeeds.c b/test/regression/dhcp_test/netx_dhcp_client_arpprobe_succeeds.c new file mode 100644 index 00000000..60a65219 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_arpprobe_succeeds.c @@ -0,0 +1,614 @@ +/* Testing the multiple interface DHCP Client. NX_DHCP_CLIENT_MAX_RECORDS should be set to 2. */ + +/* Test with NX_DHCP_CLIENT_SEND_ARP_PROBE enabled on the DHCP Client. Only using + interface 1 at present (primary interface is disabled for DHCP). The Client sends + three ARP probes without a conflict response ARP packet. It proceeds to the BOUND state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +#define DEMO_STACK_SIZE 2098 +#define PACKET_PAYLOAD 1518 + +/* Define the ThreadX, NetX object control blocks... */ + +NX_UDP_SOCKET server_socket; +TX_THREAD client_thread; +TX_THREAD server_thread; +NX_PACKET_POOL client_pool; +NX_PACKET_POOL server_pool; +NX_IP client_ip; +NX_IP server_ip; + + +/* Define the NetX DHCP object control block. */ +NX_DHCP dhcp_client; + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 2 +static DHCP_RESPONSE dhcp_response[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client_running = NX_TRUE; + +static UINT state_changes[2] = {0,0}; +static UINT bounds[2] = {0,0}; + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +void server_thread_entry(ULONG thread_input); +void client_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number, UINT iface_index); +static void dhcp_test_initialize(); +static void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state); +extern void test_control_return(UINT); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +static char offer_response[300] = { +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xf0, 0x1c, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xb4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ '192.2.2.247*/ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x02, 0x02, 0x01, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response_size = 300; + +/* Frame (342 bytes) */ +static char ack_response[300] = { + +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xf0, 0x1c, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xb4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response_size = 300; + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_cilent_arpprobe_succeeds_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the FTP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server_thread, "Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, + pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the main client thread. */ + status = tx_thread_create(&client_thread, "Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 5*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 5*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, "Client 0 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client 1 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; + +} + +/* Define the DHCP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT time_keeper = 0; + + /* Let the server set up. */ + tx_thread_sleep(10); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + if (status) + error_counter++; + + /* Register state change variable. */ + status = nx_dhcp_interface_enable(&dhcp_client, 1); + status |= nx_dhcp_interface_disable(&dhcp_client, 0); + if (status) + error_counter++; + + status = nx_dhcp_interface_state_change_notify(&dhcp_client, dhcp_interface_state_change1); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_interface_start(&dhcp_client, 1); + if (status) + error_counter++; + + /* Put an upper limit on wait for achieving the bound state. */ + while((dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_BOUND) && + (time_keeper < 1000)) + { + time_keeper += 100; + tx_thread_sleep(100); + } + + if (dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + error_counter++; + } + + if (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_NOT_STARTED) + { + error_counter++; + } + + client_running = NX_FALSE; + + return; +} + + +/* Define the helper DHCP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client ARP Probe Multiple Interface Test............."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + i = 0; + + /* Set the advanced callback to ensure broadcast packets are routed correctly. */ + advanced_packet_process_callback = my_dhcp_process_bc_callback; + + /* Wait for Client requests */ + while ( i < NUM_RESPONSES) + { + + if (i <= 1) + { + + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + error_counter++; + } + else + { + /* Release the packet. */ + nx_packet_release(my_packet); + + status = nx_dhcp_response_packet_send(&server_socket, 68, i, 0); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + } + else + { + + /* Wait for the dhcp client to start the ARP probe process. */ + while (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_probe_count == 0) + tx_thread_sleep(10); + + } + + /* Advance the index for the next response. */ + i++; + } + + /* Wait for the client to terminate the connection. */ + while(client_running == NX_TRUE) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +static void dhcp_test_initialize() +{ + + /* Set up server responses */ + dhcp_response[0].dhcp_response_pkt_data = &offer_response[0]; + dhcp_response[0].dhcp_response_pkt_size = offer_response_size ; + + dhcp_response[1].dhcp_response_pkt_data = &ack_response[0]; + dhcp_response[1].dhcp_response_pkt_size = ack_response_size ; +} + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, UINT port, INT packet_number, UINT iface_index) +{ +UINT status; +NX_PACKET *response_packet; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS ip_address; +#else +ULONG ip_address; +NX_PACKET **response_packet_ptr_ptr; +#endif + + +#ifdef __PRODUCT_NETXDUO__ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = 0xFFFFFFFF; + +#else + ip_address = 0xFFFFFFFF; +#endif + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data, + dhcp_response[packet_number].dhcp_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ +#ifdef __PRODUCT_NETXDUO__ + status = nxd_udp_socket_source_send(server_socket_ptr, response_packet, &ip_address, 68, iface_index); + +#else + + response_packet_ptr_ptr = &response_packet; + + status = nx_udp_socket_interface_send(server_socket_ptr, *response_packet_ptr_ptr, ip_address, 68, iface_index); +#endif + /* Check the status. */ + if (status) + { + nx_packet_release(response_packet); + error_counter++; + } + + return status; +} + + +void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state) +{ + +UINT dhcp_state; + + dhcp_state = (UINT)new_state; + + + /* Increment state changes counter. */ + state_changes[1]++; + + if (dhcp_state == NX_DHCP_STATE_BOUND) + { + bounds[1]++; + } + + return; +} + + +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UCHAR *work_ptr; +UINT interface_index; +UINT packet_client_mac_lsw; +NX_PACKET *packet_copy; + + + /* Is this a DHCP packet e.g. not an ARP packet? */ + if (packet_ptr -> nx_packet_length < 200) + { + /* Maybe an ARP packet. let the RAM driver deal with it */ + return NX_TRUE; + } + + /* Set work_ptr. */ +#ifdef __PRODUCT_NETXDUO__ + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#else + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IP_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#endif + + /* Pickup the target MAC address in the DHCP message. */ + packet_client_mac_lsw = (((ULONG)work_ptr[2]) << 24) | + (((ULONG)work_ptr[3]) << 16) | + (((ULONG)work_ptr[4]) << 8) | + ((ULONG)work_ptr[5]); + + /* Determine what interface to use based on MAC address and which IP instance is sending the packet. */ + if (ip_ptr == &client_ip) + { + if (packet_client_mac_lsw == 0x22334457) + { + interface_index = 0; + } + else if (packet_client_mac_lsw == 0x22334458) + { + interface_index = 1; + } + else + /* Don't know what this packet is. Let DHCP Client handle it. */ + return NX_TRUE; + } + + /* Copy to a new packet and drop the original packet. */ + nx_packet_copy(packet_ptr, &packet_copy, &client_pool, NX_WAIT_FOREVER); + + /* Based on the IP instance and packet mac address, set the packet interface */ + + if (ip_ptr == &server_ip) + { + + packet_copy -> nx_packet_ip_interface = &(client_ip.nx_ip_interface[1]); + _nx_ip_packet_receive(&client_ip, packet_copy); + } + else + { + + packet_copy -> nx_packet_ip_interface = &(ip_ptr -> nx_ip_interface[interface_index]); + + _nx_ip_packet_receive(&server_ip, packet_copy); + } + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + return NX_TRUE; + +} + + diff --git a/test/regression/dhcp_test/netx_dhcp_client_decline_test.c b/test/regression/dhcp_test/netx_dhcp_client_decline_test.c new file mode 100644 index 00000000..846fc74c --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_decline_test.c @@ -0,0 +1,999 @@ +/* Testing the multiple interface DHCP Client */ + +/* This is the DHCP Client that will run on both interfaces independently. + Interface 0 stays bound; interface 1 declines the IP address and tries + again at the INIT state to get a unique IP address. + + Required: NX_MAX_PHYSICAL_INTERFACES >= 2 and NX_DHCP_CLIENT_MAX_INTERFACES >= 2. + Also NX_DHCP_CLIENT_SEND_ARP_PROBE must be enabled. Requires longer timeout in regression + test netxtestcontrol. + + There is one server thread handling DHCP Client messages on both interfaces. +*/ + + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + + +#if (NX_MAX_PHYSICAL_INTERFACES >= 2) && (NX_DHCP_CLIENT_MAX_RECORDS >=2) + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + +static ULONG dhcp_xid = 0; +static UINT bound0 = NX_FALSE; +static UINT arp_probe0 = NX_FALSE; +static UINT init0 = NX_FALSE; + + +/* Define the ThreadX, NetX object control blocks... */ + +static UINT state_changes = 0; +static NX_UDP_SOCKET server_socket; +static TX_THREAD client_thread; +static TX_THREAD server_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +/* Define the NetX FTP object control block. */ +static NX_DHCP dhcp_client; + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define DHCP0_NUM_RESPONSES 4 +#define DHCP1_NUM_RESPONSES 2 +static DHCP_RESPONSE dhcp_response0[DHCP0_NUM_RESPONSES]; +static DHCP_RESPONSE dhcp_response1[DHCP1_NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client_running = NX_TRUE; + + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number, UINT iface_index); +static void dhcp_test_initialize(); +static void dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state); + +extern void test_control_return(UINT); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size); + +/* Note that the network is 192.2.2.0 and the MAC address is 11 22 33 44 56 + because there are four entities (server 2 interfaces, client 2 interfaces + and the ram driver increases the MAC sequentially starting from + 11 22 33 44 56. */ + + +static char offer_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x02, 0x02, 0x01, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response0_size = 300; + +/* Frame (342 bytes) */ +static char ack_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response0_size = 300; + +static char offer_response1[300] = { + +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xF7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x01, 0x01, 0x01, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response1_size = 300; + +/* Frame (342 bytes) */ +static char ack_response1[300] = { + +//0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#ifdef __PRODUCT_NETXDUO__ +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, 0xF0, 0x1D, +#else +0x02, 0x01, 0x06, 0x00, 0x08, 0x0d, 0xB4, 0x55, +#endif +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response1_size = 300; + +static char second_offer_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x02, 0x02, 0x01, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int second_offer_response0_size = 300; + +/* Frame (342 bytes) */ +static char second_ack_response0[300] = { + +0x02, 0x01, 0x06, 0x00, 0x13, 0xae, 0x1c, 0xeb, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int second_ack_response0_size = 300; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_decline_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the DHCP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server_thread, "Server Thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + status = nx_ip_interface_attach(&server_ip, "Server IP", IP_ADDRESS(192,1,1,1), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + if (status) + error_counter++; + + /* Set up the Client. */ + + /* Create the main client thread. */ + status = tx_thread_create(&client_thread, "Client Thread", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 7*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 7*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, "Client IP ", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client 1 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + if (status) + error_counter++; + + return; +} + + +/* Define the DHCP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT time_keeper; + + + tx_thread_sleep(10); + + /* Register state change variable. */ + status = nx_dhcp_interface_state_change_notify(&dhcp_client, dhcp_interface_state_change); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_dhcp_interface_enable(&dhcp_client, 1); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start DHCP on all interfaces. */ + status = nx_dhcp_start(&dhcp_client); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if ((dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state == NX_DHCP_STATE_NOT_STARTED) || + (dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state == NX_DHCP_STATE_NOT_STARTED))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + time_keeper = 0; + + /* Wait for the ARP probe state... */ + while(!arp_probe0) + { + + /* SHould not go directly to the BOUND state. */ + if (bound0) + { + printf("ERROR5!\n"); + test_control_return(1); + + } + + tx_thread_sleep(15); + time_keeper += 15; + if (time_keeper > 2000) + { + break; + } + } + + /* If it is in the ARP probe state, decline the IP address independently of the DHCP CLient*/ + if (arp_probe0) + { + + status = nx_dhcp_interface_decline(&dhcp_client, 0); + + if (status == NX_SUCCESS) + { + + /* Wait for the decline action to reset the DHCP CLient. */ + tx_thread_sleep(20); + + if (!init0) + { + printf("ERROR3!\n"); + test_control_return(1); + } + else + { + + /* Now wait for the DHCP Client to be bound. */ + time_keeper = 0; + while(!bound0) + { + tx_thread_sleep(100); + time_keeper += 100; + if (time_keeper > 2000) + { + break; + } + } + + if (bound0 != NX_TRUE) + { + printf("ERROR2!\n"); + test_control_return(1); + } + } + } + } + else + { + printf("ERROR1!\n"); + test_control_return(1); + } + + + time_keeper = 0; + + while(dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + tx_thread_sleep(100); + time_keeper += 100; + if (time_keeper > 1500) + { + break; + } + } + + if (dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + printf("ERROR4!\n"); + test_control_return(1); + } + + /* Now disable DHCP Client 1 activity. This reinitializes the Client too. */ + status = nx_dhcp_interface_disable(&dhcp_client, 1); + if (status) + { + printf("ERROR7!\n"); + test_control_return(1); + } + + client_running = NX_FALSE; + +} + + +/* Define the Primary DHCP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i, j, k, pkt_number; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Decline Test.................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR6!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 0 Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + i = 0; + j = 0; + k = 0; + pkt_number = 0; + + /* Set the advanced callback to ensure broadcast packets are routed correctly. */ + advanced_packet_process_callback = my_dhcp_process_bc_callback; + + /* Wait for Client requests */ + while ( i < (DHCP0_NUM_RESPONSES + DHCP1_NUM_RESPONSES + 1)) + { + + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + UINT source_port; + ULONG source_ip_address; + UINT protocol; + UINT iface_index; + + /* Get the XID of DHCP message from DHCP Server. */ + dhcp_xid = dhcp_get_dhcp_data(my_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID, 4); + + nx_udp_packet_info_extract(my_packet, &source_ip_address, &protocol, &source_port, &iface_index); + + /* Release the packet. */ + nx_packet_release(my_packet); + + if (iface_index == 0) + { + pkt_number = j; + + } + else + { + pkt_number = k; + } + + + /* This is the decline message. The server + does not respond to this. */ + if ((iface_index == 0) && (j == 2) && (i == 4)) + { + i++; + continue; + } + + status = nx_dhcp_response_packet_send(&server_socket, 68, pkt_number, iface_index); + + /* Check status. */ + if (status) + { + error_counter++; + } + + if (iface_index == 0) + j++; + else + k++; + } + /* Advance the index for the next response. */ + i++; + } + + /* Wait for the client to terminate the connection. */ + while(client_running == NX_TRUE) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR5!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + +static void dhcp_test_initialize() +{ + + + /* Set up server responses on the primary interface. */ + dhcp_response0[0].dhcp_response_pkt_data = &offer_response0[0]; + dhcp_response0[0].dhcp_response_pkt_size = offer_response0_size ; + + dhcp_response0[1].dhcp_response_pkt_data = &ack_response0[0]; + dhcp_response0[1].dhcp_response_pkt_size = ack_response0_size ; + + dhcp_response0[2].dhcp_response_pkt_data = &second_offer_response0[0]; + dhcp_response0[2].dhcp_response_pkt_size = second_offer_response0_size ; + + dhcp_response0[3].dhcp_response_pkt_data = &second_ack_response0[0]; + dhcp_response0[3].dhcp_response_pkt_size = second_ack_response0_size ; + + + /* Set up server responses on the secondary interface. */ + dhcp_response1[0].dhcp_response_pkt_data = &offer_response1[0]; + dhcp_response1[0].dhcp_response_pkt_size = offer_response1_size ; + + dhcp_response1[1].dhcp_response_pkt_data = &ack_response1[0]; + dhcp_response1[1].dhcp_response_pkt_size = ack_response1_size ; + +} + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, UINT port, INT packet_number, UINT iface_index) +{ + +UINT status; +NX_PACKET *response_packet; +UCHAR *work_ptr; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS ip_address; +#else +ULONG ip_address; +NX_PACKET **response_packet_ptr_ptr; +#endif + +#ifdef __PRODUCT_NETXDUO__ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = 0xFFFFFFFF; +#else + ip_address = 0xFFFFFFFF; +#endif + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + if (iface_index == 0) + { + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response0[packet_number].dhcp_response_pkt_data, + dhcp_response0[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response0[packet_number].dhcp_response_pkt_size; + } + else if (iface_index == 1) + { + + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response1[packet_number].dhcp_response_pkt_data, + dhcp_response1[packet_number].dhcp_response_pkt_size); + + response_packet -> nx_packet_length = dhcp_response1[packet_number].dhcp_response_pkt_size; + } + + /* Now replace the XID in the server message with what we know is the Client XID. */ + work_ptr = (UCHAR *)(response_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID); + NX_CHANGE_ULONG_ENDIAN(dhcp_xid); + memcpy(work_ptr, (void const *)(&dhcp_xid), 4); + + + /* Adjust the write pointer. */ + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ +#ifdef __PRODUCT_NETXDUO__ + status = nxd_udp_socket_source_send(server_socket_ptr, response_packet, &ip_address, 68, iface_index); +#else + response_packet_ptr_ptr = &response_packet; + status = nx_udp_socket_interface_send(server_socket_ptr, *response_packet_ptr_ptr, ip_address, 68, iface_index); +#endif + + /* Check the status. */ + if (status) + { + + error_counter++; + + nx_packet_release(response_packet); + } + + return status; +} + +void dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state) +{ + + if (iface_index == 0) + { + + if (new_state == NX_DHCP_STATE_ADDRESS_PROBING) + { + arp_probe0 = NX_TRUE; + } + else if ((arp_probe0 == NX_TRUE) && (new_state== NX_DHCP_STATE_INIT)) + { + init0 = NX_TRUE; + } + else if (new_state == NX_DHCP_STATE_BOUND) + { + bound0 = NX_TRUE; + } + } + + state_changes++; + + return; +} + +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UCHAR *work_ptr; +UINT interface_index; +UINT packet_client_mac_lsw; +NX_PACKET *packet_copy; + + + /* Is this a DHCP packet e.g. not an ARP packet? */ + if (packet_ptr -> nx_packet_length < 200) + { + /* Maybe an ARP packet. let the RAM driver deal with it */ + return NX_TRUE; + } + + /* Set work_ptr. */ +#ifdef __PRODUCT_NETXDUO__ + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#else + work_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IP_HEADER) + sizeof(NX_UDP_HEADER) +NX_BOOTP_OFFSET_CLIENT_HW; +#endif + /* Pickup the target MAC address in the DHCP message. */ + packet_client_mac_lsw = (((ULONG)work_ptr[2]) << 24) | + (((ULONG)work_ptr[3]) << 16) | + (((ULONG)work_ptr[4]) << 8) | + ((ULONG)work_ptr[5]); + + /* Determine what interface to use based on MAC address and which IP instance is sending the packet. */ + if (packet_client_mac_lsw == 0x22334458) + { + interface_index = 0; + } + else if (packet_client_mac_lsw == 0x22334459) + { + interface_index = 1; + } + else + /* Don't know what this packet is. Let DHCP Client handle it. */ + return NX_TRUE; + + /* Copy to a new packet and drop the original packet. */ + nx_packet_copy(packet_ptr, &packet_copy, &client_pool, NX_WAIT_FOREVER); + + /* Based on the packet mac address, set the packet interface based on the mac address */ + packet_copy -> nx_packet_ip_interface = &(ip_ptr -> nx_ip_interface[interface_index]); + + if (ip_ptr == &server_ip) + { + _nx_ip_packet_receive(&client_ip, packet_copy); + } + else + { + _nx_ip_packet_receive(&server_ip, packet_copy); + } + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + return NX_TRUE; + +} + +ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size) +{ + +ULONG value = 0; + + + /* Process the data retrieval request. */ + while (size-- > 0) + { + + /* Build return value. */ + value = (value << 8) | *data++; + } + + /* Return value. */ + return(value); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_decline_test_application_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: DHCP Client Decline Test..................................N/A!\n"); + test_control_return(3); +} +#endif /* (NX_MAX_PHYSICAL_INTERFACES >= 2) && (NX_DHCP_CLIENT_MAX_RECORDS >=2) */ + + + diff --git a/test/regression/dhcp_test/netx_dhcp_client_interface_0_only_test.c b/test/regression/dhcp_test/netx_dhcp_client_interface_0_only_test.c new file mode 100644 index 00000000..075cf74e --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_interface_0_only_test.c @@ -0,0 +1,561 @@ +/* Testing the multiple interface DHCP Client */ + +/* This is a test of the default DHCP Client configuration; one interface (primary interface) is configured. + Required: NX_MAX_PHYSICAL_INTERFACES and NX_DHCP_CLIENT_MAX_INTERFACES = 1. */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + +//#define REQUEST_CLIENT_IP +#ifdef REQUEST_CLIENT_IP +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,1,1,66) +UINT skip_discover_message = NX_TRUE; +#endif + +/* Define the ThreadX, NetX object control blocks... */ + +NX_UDP_SOCKET server_socket; +TX_THREAD client_thread; +TX_THREAD server_thread; +NX_PACKET_POOL client_pool; +NX_PACKET_POOL server_pool; +NX_IP client_ip; +NX_IP server_ip; + + +/* Define the NetX FTP object control block. */ +NX_DHCP dhcp_client; + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 2 +static DHCP_RESPONSE dhcp_response[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client_running = NX_FALSE; + + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +void server_thread_entry(ULONG thread_input); +void client_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number); +static void dhcp_test_initialize(); +static void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state); + +extern void test_control_return(UINT); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +static char offer_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x31, 0x9d, /* {.....T. */ +0x58, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +#ifdef REQUEST_CLIENT_IP +0x00, 0x00, 0xc0, 0x01, 0x01, 0x43, 0xc0, 0x01, /* ........ */ +#else +0x00, 0x00, 0xc0, 0x01, 0x01, 0xF7, 0xc0, 0x01, /* ........ */ +#endif +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x01, 0x01, 0x01, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response_size = 300; + +/* Frame (342 bytes) */ +static char ack_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x31, 0x9d, /* {.....T. */ +0x58, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +#ifdef REQUEST_CLIENT_IP +0x00, 0x00, 0xc0, 0x01, 0x01, 0x43, 0xc0, 0x01, /* ........ */ +#else +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +#endif +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response_size = 300; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_interface_0_only_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the DHCP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server_thread, "Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, + pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(192,1,1,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + if (status) + error_counter++; + + + /* Set up the Client. */ + + /* Create the main client thread. */ + status = tx_thread_create(&client_thread, "Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 25*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 25*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, " Client0 IP Instance", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client1 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; +} + + +/* Define the DHCP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +#endif + + tx_thread_sleep(20); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + if (status) + error_counter++; + + + status = nx_dhcp_clear_broadcast_flag(&dhcp_client, NX_TRUE); + + /* Set the client IP if the host is configured to do so. */ + if (status) + error_counter++; + +#ifdef REQUEST_CLIENT_IP + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + +#endif + + /* Register state change variable. */ + //status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_interface_state_change1); + //if (status) + // error_counter++; + + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + while(dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + tx_thread_sleep(100); + } + + status = nx_dhcp_stop(&dhcp_client); + if (status) + error_counter++; + + tx_thread_sleep(20); + + status = nx_ip_address_set(&client_ip, IP_ADDRESS(192,1,1,99), 0xFFFFFF00); + if (status) + error_counter++; +} + + +/* Define the helper DHCP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Interface 0 Only Test.........................\n"); // jlc remove the \n + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + i = 0; + + /* Wait for Client requests */ + while ( i < NUM_RESPONSES) + { + +#ifdef REQUEST_CLIENT_IP + if (skip_discover_message == NX_TRUE) + { + i = 1; + } +#endif + + if (i <= 1) + { + + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + else + { + printf("\nRECVd %dth packet\n", i); + + /* Release the packet. */ + nx_packet_release(my_packet); + + printf("Server sending response back. \n"); + status = nx_dhcp_response_packet_send(&server_socket, 68, i); + } + } + else + { + +#ifdef NX_DHCP_CLIENT_SEND_ARP_PROBE + /* Wait for the dhcp client to start the ARP probe process. */ + while (dhcp_client.nx_dhcp_interface[1].nx_dhcp_probe_count == 0) + tx_thread_sleep(10); +#endif + + printf("No one should send a Probe reply\n"); + } + + /* Check status. */ + if (status) + { + + printf("ERROR8!\n"); + error_counter++; + } + + + /* Advance the index for the next response. */ + i++; + } + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + /* Should get one more message from the Client, a DECLINE message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + + + printf("All done, waiting for client to go away\n"); + + /* Wait for the client to terminate the connection. */ + while(client_running != NX_TRUE) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +static void dhcp_test_initialize() +{ + + +/* Download data responses */ + dhcp_response[0].dhcp_response_pkt_data = &offer_response[0]; + dhcp_response[0].dhcp_response_pkt_size = offer_response_size ; + + dhcp_response[1].dhcp_response_pkt_data = &ack_response[0]; + dhcp_response[1].dhcp_response_pkt_size = ack_response_size ; +} + + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; +NXD_ADDRESS ip_address; + + + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = 0xFFFFFFFF; + + printf("Sending %dth response\n", packet_number); + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data, + dhcp_response[packet_number].dhcp_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ + status = nxd_udp_socket_source_send(server_socket_ptr, response_packet, &ip_address, 68, 0); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} + +UINT state_changes = 0; +void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + state_changes++; + + return; +} + + diff --git a/test/regression/dhcp_test/netx_dhcp_client_interface_1_only_test.c b/test/regression/dhcp_test/netx_dhcp_client_interface_1_only_test.c new file mode 100644 index 00000000..82427832 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_interface_1_only_test.c @@ -0,0 +1,595 @@ +/* Testing the multiple interface DHCP Client */ + +/* This is a test of the DHCP Client running on only one interface (secondary interface). + Required: NX_MAX_PHYSICAL_INTERFACES >= 2 NX_DHCP_CLIENT_MAX_INTERFACES = 1. */ + + + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + +#define REQUEST_CLIENT_IP +#ifdef REQUEST_CLIENT_IP +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,1,1,66) +UINT skip_discover_message = NX_TRUE; +#endif + +/* Define the ThreadX, NetX object control blocks... */ + +NX_UDP_SOCKET server_socket; +TX_THREAD client_thread; +TX_THREAD server_thread; +NX_PACKET_POOL client_pool; +NX_PACKET_POOL server_pool; +NX_IP client_ip; +NX_IP server_ip; + + +/* Define the NetX DHCP object control block. */ +NX_DHCP dhcp_client; + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 2 +static DHCP_RESPONSE dhcp_response[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client_running = NX_FALSE; + + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +void server_thread_entry(ULONG thread_input); +void client_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number); +static void dhcp_test_initialize(); +static void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state); + +extern void test_control_return(UINT); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +static char offer_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, /* {.....T. */ +0xF0, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +#ifdef REQUEST_CLIENT_IP +0x00, 0x00, 0xc0, 0x01, 0x01, 0x43, 0xc0, 0x01, /* ........ */ +#else +0x00, 0x00, 0xc0, 0x01, 0x01, 0xF7, 0xc0, 0x01, /* ........ */ +#endif +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x01, 0x01, 0x01, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response_size = 300; + +/* Frame (342 bytes) */ +static char ack_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, /* {.....T. */ +0xF0, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +#ifdef REQUEST_CLIENT_IP +0x00, 0x00, 0xc0, 0x01, 0x01, 0x43, 0xc0, 0x01, /* ........ */ +#else +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +#endif +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response_size = 300; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_cilent_interface_1_only_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the DHCP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server_thread, "Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, + pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&server_ip, "Client1 IP", IP_ADDRESS(192,1,1,1), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + if (status) + error_counter++; + + + /* Set up the Client. */ + + /* Create the main client thread. */ + status = tx_thread_create(&client_thread, "Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 25*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 25*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, " Client0 IP Instance", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client1 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; +} + + +/* Define the DHCP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +#endif + + tx_thread_sleep(20); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + if (status) + error_counter++; + + status = nx_dhcp_clear_broadcast_flag(&dhcp_client, NX_TRUE); + + /* Set the client IP if the host is configured to do so. */ + if (status) + error_counter++; + +#ifdef REQUEST_CLIENT_IP + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + +#endif + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_interface_state_change1); + if (status) + error_counter++; + + /* Note that we call this after setting the request IP, stage change notify and clear broadcast services. + DHCP CLient defaults these to the primary interface unless the dhcp interface has been set. + If this host is configured for multiple interfaces, this call will reset these attributes on + both interfaces. */ + status = nx_dhcp_set_interface_index(&dhcp_client, 1); + if (status) + error_counter++; + + /* Try using the multi-interface method to start the client. */ + status = _nx_dhcp_multi_interface_start(&dhcp_client); + if (status != NX_DHCP_NOT_FOR_SINGLE_INTERFACES) + error_counter++; + + /* Start the DHCP Client using the single DHCP Client interface method. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + while(dhcp_client.nx_dhcp_interface[1].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + tx_thread_sleep(100); + } + + /* This should release the IP address for the secondary interface. */ + nx_dhcp_release(&dhcp_client); + + /* Try to use the multiple interface method to stop the Client. */ + status = nx_dhcp_client_interface_deactivate(&dhcp_client, 1); + if (status != NX_DHCP_NOT_FOR_SINGLE_INTERFACES) + { + error_counter++; + } + + status = nx_dhcp_stop(&dhcp_client); + + tx_thread_sleep(40); + + /* Manually set IP address on secondary interface */ + status = nx_ip_interface_address_set(&client_ip, 1, IP_ADDRESS(192,1,1,66), 0xFFFFFF00); + if (status) + error_counter++; + +} + + +/* Define the helper DHCP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Interface 1 Only Test...........................\n"); // jlc remove the \n + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + i = 0; + + /* Wait for Client requests */ + while ( i < NUM_RESPONSES) + { + +#ifdef REQUEST_CLIENT_IP + if (skip_discover_message == NX_TRUE) + { + i = 1; + } +#endif + if (i <= 1) + { + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + else + { + printf("\nRECVd %dth packet\n", i); + + /* Release the packet. */ + nx_packet_release(my_packet); + + printf("Server sending response back. \n"); + status = nx_dhcp_response_packet_send(&server_socket, 68, i); + } + } + else + { + +#ifdef NX_DHCP_CLIENT_SEND_ARP_PROBE + /* Wait for the dhcp client to start the ARP probe process. */ + while (dhcp_client.nx_dhcp_interface[1].nx_dhcp_probe_count == 0) + tx_thread_sleep(10); +#endif + + printf("No one should send a Probe reply\n"); + } + + /* Check status. */ + if (status) + { + + printf("ERROR8!\n"); + error_counter++; + } + + + /* Advance the index for the next response. */ + i++; + } + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + /* Should get one more message from the Client, a DECLINE message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + + + printf("All done, waiting for client to go away\n"); + + /* Wait for the client to terminate the connection. */ + while(client_running != NX_TRUE) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +static void dhcp_test_initialize() +{ + + +/* Download data responses */ + dhcp_response[0].dhcp_response_pkt_data = &offer_response[0]; + dhcp_response[0].dhcp_response_pkt_size = offer_response_size ; + + dhcp_response[1].dhcp_response_pkt_data = &ack_response[0]; + dhcp_response[1].dhcp_response_pkt_size = ack_response_size ; + + +} + + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; +NXD_ADDRESS ip_address; + + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = 0xFFFFFFFF; + + + printf("Sending %dth response\n", packet_number); + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data, + dhcp_response[packet_number].dhcp_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ + status = nxd_udp_socket_source_send(server_socket_ptr, response_packet, &ip_address, 68, 1); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} + +void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + +//UINT dhcp_state; + + //dhcp_state = (UINT)new_state; + + + return; +} + + diff --git a/test/regression/dhcp_test/netx_dhcp_client_interface_order_test.c b/test/regression/dhcp_test/netx_dhcp_client_interface_order_test.c new file mode 100644 index 00000000..d10ea65c --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_interface_order_test.c @@ -0,0 +1,260 @@ +/* Testing the multiple interface DHCP Client */ + +/* This is the DHCP Client that will run on both interfaces independently. + Required: NX_MAX_PHYSICAL_INTERFACES >= 2 and NX_DHCP_CLIENT_MAX_RECORDS >= 2. + There are two DHCP Client threads that independently activate the DHCP Client on + the primary or secondary interface. When they reach the bound state, each interface Client + deactivates the DHCP Client process and the DHCP Client goes back to the NOT STARTED state. + + There is one server thread handling DHCP Client messages on both interfaces. +*/ + + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +extern void test_control_return(UINT status); + +#if (NX_MAX_PHYSICAL_INTERFACES >= 2) && (NX_DHCP_CLIENT_MAX_RECORDS >=2) + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + + +/* Define the ThreadX, NetX object control blocks... */ + +static UINT state_changes = 0; +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; + + +/* Define the NetX FTP object control block. */ +static NX_DHCP dhcp_client; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT discover_counter = 0; + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); +static void client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_interface_order_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the Client. */ + /* Create the main client thread. */ + status = tx_thread_create(&client_thread, "Client Thread", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 7*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 7*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, " Client IP ", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); +} + + +/* Define the DHCP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Interface Order Test.........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the advanced callback to ensure broadcast packets are routed correctly. */ + advanced_packet_process_callback = my_dhcp_process_bc_callback; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Clear the unicast flag on all interfaces. */ + status = nx_dhcp_clear_broadcast_flag(&dhcp_client, NX_TRUE); + + /* Set the client IP if the host is configured to do so. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable DHCP feature on the second interface. */ + status = nx_dhcp_interface_disable(&dhcp_client, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable DHCP feature on the second interface. */ + status = nx_dhcp_interface_enable(&dhcp_client, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable DHCP feature on the second interface. */ + status = nx_dhcp_interface_enable(&dhcp_client, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start DHCP feature on the second interface. */ + status = nx_dhcp_interface_start(&dhcp_client, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for Discover. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Check error_counter. */ + if ((error_counter) || (discover_counter == 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_dhcp_process_bc_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + + /* Is this a DHCP packet e.g. not an ARP packet? */ + if (packet_ptr -> nx_packet_length < 200) + { + /* Maybe an ARP packet. let the RAM driver deal with it */ + return NX_TRUE; + } + + /* Check the interface index. */ + if (packet_ptr -> nx_packet_ip_interface != &ip_ptr -> nx_ip_interface[0]) + error_counter++; + + /* Update the counter. */ + discover_counter++; + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + return NX_TRUE; + +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_interface_order_test_application_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: DHCP Client Interface Order Test..........................N/A!\n"); + test_control_return(3); +} +#endif /* (NX_MAX_PHYSICAL_INTERFACES >= 2) && (NX_DHCP_CLIENT_MAX_RECORDS >=2) */ + + diff --git a/test/regression/dhcp_test/netx_dhcp_client_ip_mutex_test.c b/test/regression/dhcp_test/netx_dhcp_client_ip_mutex_test.c new file mode 100644 index 00000000..317a7133 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_ip_mutex_test.c @@ -0,0 +1,192 @@ +/* Testing the multiple interface DHCP Client */ + +/* This is the DHCP Client that will run on both interfaces independently. + Interface 0 stays bound; interface 1 declines the IP address and tries + again at the INIT state to get a unique IP address. + + Required: NX_MAX_PHYSICAL_INTERFACES >= 2 and NX_DHCP_CLIENT_MAX_INTERFACES >= 2. + Also NX_DHCP_CLIENT_SEND_ARP_PROBE must be enabled. Requires longer timeout in regression + test netxtestcontrol. + + There is one server thread handling DHCP Client messages on both interfaces. +*/ + + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE (NX_PACKET_SIZE * 8) + +/* Define the ThreadX, NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; + + +/* Define the NetX FTP object control block. */ +static NX_DHCP dhcp_client; + +/* Define the counters used in the demo application... */ +static UINT error_counter = 0; + +/* Replace the 'ram' driver with your Ethernet driver. */ +static void client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(NX_IP_DRIVER *driver_req_ptr); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_ip_mutex_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0x00, &client_pool, _nx_ram_network_driver_256, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + status += nx_udp_enable(&client_ip); + status += nx_icmp_enable(&client_ip); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; +} + + +/* Define the DHCP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + + printf("NetX Test: DHCP Client IP Mutex Test................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Start DHCP on all interfaces. */ + status = nx_dhcp_start(&dhcp_client); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for sending the first discovery message. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + +#ifndef NX_DISABLE_UDP_INFO + /* Check if send out discovery message. */ + if (client_ip.nx_ip_udp_packets_sent == 0) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_UDP_INFO */ + + /* Check if DHCP Thread did not release the IP mutex. */ + if (client_ip.nx_ip_protection.tx_mutex_owner == &dhcp_client.nx_dhcp_thread) + { + error_counter++; + } + + /* Release the mutex again before call test_control_cleanup */ + dhcp_client.nx_dhcp_thread.tx_thread_owned_mutex_list = NX_NULL; + client_ip.nx_ip_protection.tx_mutex_owner = &client_thread; + tx_mutex_put(&client_ip.nx_ip_protection); + + /* Check for error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_ip_mutex_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client IP Mutex Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_client_ntp_option_test.c b/test/regression/dhcp_test/netx_dhcp_client_ntp_option_test.c new file mode 100644 index 00000000..2c7fea20 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_ntp_option_test.c @@ -0,0 +1,537 @@ +/* The DHCPREQUEST message MUST use the same value in the DHCP message header's 'secs' field and be sent to the same IP + * broadcast address as the original DHCPDISCOVER message. + * rfc 2131, page 16, 3.1 Client-server interaction - allocating a network address + */ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_UDP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT test_done = NX_FALSE; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, INT packet_number); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +typedef struct DHCP_RESPONSE_STRUCT +{ + UCHAR *dhcp_response_pkt_data; + UINT dhcp_response_pkt_size; +} DHCP_RESPONSE; + +static DHCP_RESPONSE dhcp_response[2]; + +/* Frame (342 bytes) */ +static unsigned char offer[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xb0, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x36, 0x04, 0xc0, /* Sc5..6.. */ +0xa8, 0x02, 0x01, 0x33, 0x04, 0x00, 0x00, 0x1b, /* ...3.... */ +0xfe, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ........ */ +0x04, 0xc0, 0xa8, 0x02, 0x01, 0x06, 0x04, 0xc0, /* ........ */ +0xa8, 0x02, 0x01, 0x2a, 0x04, 0x7c, 0x6c, 0x14, /* ...*.|l. */ +0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static unsigned char ack[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xad, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x36, 0x04, 0xc0, /* Sc5..6.. */ +0xa8, 0x02, 0x01, 0x33, 0x04, 0x00, 0x00, 0x1b, /* ...3.... */ +0xfe, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ........ */ +0x04, 0xc0, 0xa8, 0x02, 0x01, 0x06, 0x04, 0xc0, /* ........ */ +0xa8, 0x02, 0x01, 0x2a, 0x04, 0x7c, 0x6c, 0x14, /* ...*.|l. */ +0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_ntp_option_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i = 0; +UINT index; +NX_PACKET *my_packet; +UCHAR *option_ptr; +UINT option_size; + + printf("NetX Test: DHCP Client NTP Option test..............................."); + +#ifdef __PRODUCT_NETXDUO__ + /* Update the MAC address. */ + status = nx_ip_interface_physical_address_set(&server_ip, 0, 0x00000015, 0x5d021e0f, NX_TRUE); + + /* Check for errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +#else + server_ip.nx_ip_interface[0].nx_interface_physical_address_msw = 0x00000015; + server_ip.nx_ip_interface[0].nx_interface_physical_address_lsw = 0x5d021e0f; +#endif + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + dhcp_response[0].dhcp_response_pkt_data = (char*)offer; + dhcp_response[0].dhcp_response_pkt_size = sizeof(offer); + dhcp_response[1].dhcp_response_pkt_data = ack; + dhcp_response[1].dhcp_response_pkt_size = sizeof(ack); + + /* Wait for Client requests (DISCOVER and REQEUST). */ + for (i = 0; i < 2; i++) + { + + /* Receive DHCP message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Check if there is NTP in parameter request list. */ + option_ptr = dhcp_search_buffer(my_packet -> nx_packet_prepend_ptr, NX_DHCP_OPTION_DHCP_PARAMETERS, my_packet -> nx_packet_length); + + /* Check if found the parameter request option. */ + if (option_ptr == NX_NULL) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + option_size = (UINT)*option_ptr; + option_ptr++; + + /* Check if there is NTP. */ + for (index = 0; index < option_size; index ++) + { + if (*(option_ptr + index) == NX_DHCP_OPTION_NTP_SVR) + { + break; + } + } + + if (index >= option_size) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send response. */ + status = nx_dhcp_response_packet_send(&server_socket, i); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + } + + /* Wait for test done. */ + while(test_done == NX_FALSE) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +ULONG ntp_server_address; +UINT ntp_server_address_size = 4; + +#ifdef __PRODUCT_NETXDUO__ + /* Update the MAC address. */ + status = nx_ip_interface_physical_address_set(&client_ip, 0, 0x00000011, 0x22334457, NX_TRUE); + + /* Check for errors. */ + if (status) + { + error_counter++; + } +#else + client_ip.nx_ip_interface[0].nx_interface_physical_address_msw = 0x00000011; + client_ip.nx_ip_interface[0].nx_interface_physical_address_lsw = 0x22334457; +#endif + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + { + error_counter++; + } + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Request NTP. */ + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_NTP_SVR); + if (status) + { + error_counter++; + } + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + { + error_counter++; + } + + /* Wait for DHCP to assign the IP address. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Retrieve NTP server address. */ + status = nx_dhcp_interface_user_option_retrieve(&dhcp_client, 0, NX_DHCP_OPTION_NTP_SVR, (UCHAR *)(&ntp_server_address), + &ntp_server_address_size); + + /* Check status. */ + if ((status) || (ntp_server_address_size != 4) || (ntp_server_address != IP_ADDRESS(124, 108, 20, 1))) + { + error_counter++; + } + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + test_done = NX_TRUE; + + return; +} + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data + (14 + 20 + 8), + dhcp_response[packet_number].dhcp_response_pkt_size - (14 + 20 + 8)); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size - (14 + 20 + 8); + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Fake the transaction id. */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_xid = 0x2233446f; + + /* Send the packet. */ + status = nx_udp_socket_send(server_socket_ptr, response_packet, IP_ADDRESS(255, 255, 255, 255), NX_DHCP_CLIENT_UDP_PORT); + + /* Check the status. */ + if (status) + { + nx_packet_release(response_packet); + } + + return status; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_ntp_option_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client NTP Option test...............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_client_nxe_api_test.c b/test/regression/dhcp_test/netx_dhcp_client_nxe_api_test.c new file mode 100644 index 00000000..75d98b5b --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_nxe_api_test.c @@ -0,0 +1,299 @@ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) +static NX_IP ip_0; +static NX_DHCP dhcp_client; +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +ULONG stack_area[100]; + +static void error_checking_test(void); +extern volatile ULONG _tx_thread_system_state; +extern TX_THREAD *_tx_thread_current_ptr; +extern TX_THREAD _tx_timer_thread; + +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + +static CHAR *pointer; + + printf("NetX Test: DHCP Client Error Checking Test.........................."); + + /* Create an IP instance for the DHCP Client. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + nx_ip_create(&ip_0, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1024, pointer, 2048, 1); + + + _tx_thread_system_state = 0; + error_checking_test(); + _tx_thread_system_state = 1; + error_checking_test(); + _tx_thread_system_state = 0; + _tx_thread_current_ptr = TX_NULL; + error_checking_test(); + _tx_thread_current_ptr = &_tx_timer_thread; + error_checking_test(); + + printf("SUCCESS!\n"); + test_control_return(0); + +} + +static void error_checking_test(void) +{ + + +UINT status; +UCHAR buf[4]; +ULONG val_ulong; + + /* Test _nxe_dhcp_create */ + _nxe_dhcp_create(0, 0, NX_NULL); + ip_0.nx_ip_id = 0; + _nxe_dhcp_create(0, &ip_0, NX_NULL); + ip_0.nx_ip_id = NX_IP_ID; + _nxe_dhcp_create(0, &ip_0, NX_NULL); + + + /* Test _nxe_dhcp_clear_broadcast_flag */ + _nxe_dhcp_clear_broadcast_flag(NX_NULL, 0); + + /* Test _nxe_dhcp_interface_clear_broadcast_flag */ + _nxe_dhcp_interface_clear_broadcast_flag(NX_NULL, 0, 0); + _nxe_dhcp_interface_clear_broadcast_flag(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES, 0); + + + /* Test _nxe_dhcp_packet_pool_set */ + _nxe_dhcp_packet_pool_set(&dhcp_client, NX_NULL); + _nxe_dhcp_packet_pool_set(NX_NULL, NX_NULL); + pool_1.nx_packet_pool_payload_size = 0; + _nxe_dhcp_packet_pool_set(&dhcp_client, &pool_1); + + /* Test _nxe_dhcp_reinitialize */ + _nxe_dhcp_reinitialize(NX_NULL); + + /* Test _nxe_dhcp_interface_reinitialize */ + _nxe_dhcp_interface_reinitialize(NX_NULL, 0); + _nxe_dhcp_interface_reinitialize(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES); + + /* This one shall fail at "NX_THREADS_ONLY_CALLER_CHECKING */ + _nxe_dhcp_interface_reinitialize(&dhcp_client, 0); + + /* Test _nxe_dhcp_request_client_ip */ + _nxe_dhcp_request_client_ip(NX_NULL, 0, 0); + _nxe_dhcp_request_client_ip(&dhcp_client, NX_BOOTP_NO_ADDRESS, 0); + + /* Test _nxe_dhcp_interface_request_client_ip */ + _nxe_dhcp_interface_request_client_ip(NX_NULL, 0, 0, 0); + _nxe_dhcp_interface_request_client_ip(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES, 0, 0); + + /* Test _nxe_dhcp_delete */ + _nxe_dhcp_delete(NX_NULL); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_delete(&dhcp_client); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_delete(&dhcp_client); + + /* Test _nxe_dhcp_force_renew */ + _nxe_dhcp_force_renew(NX_NULL); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_force_renew(&dhcp_client); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_force_renew(&dhcp_client); + + /* Test _nxe_dhcp_interface_force_renew */ + _nxe_dhcp_interface_force_renew(NX_NULL, 0); + _nxe_dhcp_interface_force_renew(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES); + + /* Test _nxe_dhcp_decline */ + _nxe_dhcp_decline(NX_NULL); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_decline(&dhcp_client); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_decline(&dhcp_client); + + + /* Test _nxe_dhcp_interface_decline */ + _nxe_dhcp_interface_decline(NX_NULL, 0); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_interface_decline(&dhcp_client, 0); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_interface_decline(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES); + _nxe_dhcp_interface_decline(&dhcp_client, 0); + + /* Test _nxe_dhcp_release */ + _nxe_dhcp_release(NX_NULL); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_release(&dhcp_client); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_release(&dhcp_client); + + /* _nxe_dhcp_interface_release */ + _nxe_dhcp_interface_release(NX_NULL, 0); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_interface_release(&dhcp_client, 0); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_interface_release(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES); + _nxe_dhcp_interface_release(&dhcp_client, 0); + + /* Test _nxe_dhcp_start */ + _nxe_dhcp_start(NX_NULL); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_start(&dhcp_client); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_start(&dhcp_client); + + /* Test _nxe_dhcp_interface_start */ + _nxe_dhcp_interface_start(NX_NULL, 0); + _nxe_dhcp_interface_start(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES); + _nxe_dhcp_interface_start(&dhcp_client, 0); + + /* Test _nxe_dhcp_interface_enable */ + _nxe_dhcp_interface_enable(NX_NULL, 0); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_interface_enable(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES); + + + /* Test _nxe_dhcp_interface_disable */ + _nxe_dhcp_interface_disable(NX_NULL, 0); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_interface_disable(&dhcp_client, 0); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_interface_disable(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES); + + /* Test _nxe_dhcp_state_change_notify */ + _nxe_dhcp_state_change_notify(NX_NULL, NX_NULL); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_state_change_notify(&dhcp_client, NX_NULL); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_state_change_notify(&dhcp_client, NX_NULL); + + /* _nxe_dhcp_interface_state_change_notify */ + _nxe_dhcp_interface_state_change_notify(NX_NULL, NX_NULL); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_interface_state_change_notify(&dhcp_client, NX_NULL); + + /* Test _nxe_dhcp_stop */ +// nx_dhcp_create(&dhcp_client, &ip_0, "dhcp_client"); + _nxe_dhcp_stop(NX_NULL); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_stop(&dhcp_client); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_stop(&dhcp_client); +// nx_dhcp_delete(&dhcp_client); + + + /* Test _nxe_dhcp_interface_stop */ + _nxe_dhcp_interface_stop(NX_NULL, 0); + _nxe_dhcp_interface_stop(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES); + _nxe_dhcp_interface_stop(&dhcp_client, 0); + + /* Test _nxe_dhcp_user_option_retrieve */ + _nxe_dhcp_user_option_retrieve(NX_NULL, 0, NX_NULL, NX_NULL); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_user_option_retrieve(&dhcp_client, 0, NX_NULL, NX_NULL); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_user_option_retrieve(&dhcp_client, 0, NX_NULL, NX_NULL); + _nxe_dhcp_user_option_retrieve(&dhcp_client, 0, buf, NX_NULL); + status = sizeof(buf); + _nxe_dhcp_user_option_retrieve(&dhcp_client, 0, buf, &status); + + /* Test _nxe_dhcp_user_option_request */ + _nxe_dhcp_user_option_request(NX_NULL, 0); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_user_option_request(&dhcp_client, 0); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_user_option_request(&dhcp_client, 0); + + /* Test _nxe_dhcp_interface_user_option_retrieve */ + _nxe_dhcp_interface_user_option_retrieve(NX_NULL, 0, 0, NX_NULL, NX_NULL); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_interface_user_option_retrieve(&dhcp_client, 0, 0, NX_NULL, NX_NULL); + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + _nxe_dhcp_interface_user_option_retrieve(&dhcp_client, 0, 0, NX_NULL, NX_NULL); + _nxe_dhcp_interface_user_option_retrieve(&dhcp_client, 0, 0, buf, NX_NULL); + _nxe_dhcp_interface_user_option_retrieve(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES, 0, buf, &status); + _nxe_dhcp_interface_user_option_retrieve(&dhcp_client, 0, 0, buf, &status); + + /* Test _nxe_dhcp_user_option_convert */ + _nxe_dhcp_user_option_convert(NX_NULL); + + /* Test _nxe_dhcp_user_option_add_callback_set */ + _nxe_dhcp_user_option_add_callback_set(NX_NULL, NX_NULL); + dhcp_client.nx_dhcp_id = 0; + _nxe_dhcp_user_option_add_callback_set(&dhcp_client, NX_NULL); + + /* Test _nxe_dhcp_server_address_get */ + _nxe_dhcp_server_address_get(NX_NULL, NX_NULL); + _nxe_dhcp_server_address_get(&dhcp_client, NX_NULL); + _nxe_dhcp_server_address_get(&dhcp_client, &val_ulong); + + /* Test _nxe_dhcp_interface_server_address_get */ + _nxe_dhcp_interface_server_address_get(NX_NULL, 0, NX_NULL); + _nxe_dhcp_interface_server_address_get(&dhcp_client, 0, NX_NULL); + _nxe_dhcp_interface_server_address_get(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES, &val_ulong); + _nxe_dhcp_interface_server_address_get(&dhcp_client, 0, &val_ulong); + + + /* Test _nxe_dhcp_set_interface_index */ + _nxe_dhcp_set_interface_index(NX_NULL, 0); + _nxe_dhcp_set_interface_index(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES); + + /* Test _nxe_dhcp_send_request */ + _nxe_dhcp_send_request(NX_NULL, 0); + _nxe_dhcp_send_request(&dhcp_client, 0); + _nxe_dhcp_send_request(&dhcp_client, NX_DHCP_TYPE_DHCPFORCERENEW + 1); + + /* Test _nxe_dhcp_interface_send_request*/ + nx_dhcp_interface_send_request(NX_NULL, 0, 0); + nx_dhcp_interface_send_request(&dhcp_client, NX_MAX_PHYSICAL_INTERFACES + 1, 0); + nx_dhcp_interface_send_request(&dhcp_client, 0, 0); + + dhcp_client.nx_dhcp_id = NX_DHCP_ID; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + +static CHAR *pointer; + + printf("NetX Test: DHCP Client Error Checking Test..........................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_client_parameter_request_test.c b/test/regression/dhcp_test/netx_dhcp_client_parameter_request_test.c new file mode 100644 index 00000000..7fd08e0c --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_parameter_request_test.c @@ -0,0 +1,390 @@ +/* The DHCPREQUEST message MUST use the same value in the DHCP message header's 'secs' field and be sent to the same IP + * broadcast address as the original DHCPDISCOVER message. + * rfc 2131, page 16, 3.1 Client-server interaction - allocating a network address + */ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_UDP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; +static UINT test_done = NX_FALSE; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_parameter_request_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i = 0; +UINT index; +NX_PACKET *my_packet; +UCHAR *option_ptr; +UINT option_size; + + printf("NetX Test: DHCP Client Parameter Request Test........................"); + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive DHCP message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Check if there is NTP in parameter request list. */ + option_ptr = dhcp_search_buffer(my_packet -> nx_packet_prepend_ptr, NX_DHCP_OPTION_DHCP_PARAMETERS, my_packet -> nx_packet_length); + + /* Check if found the parameter request option. */ + if (option_ptr == NX_NULL) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + option_size = (UINT)*option_ptr; + option_ptr++; + + /* Check if option size is correct. */ + if (option_size != 3 + NX_DHCP_CLIENT_MAX_USER_REQUEST_PARAMETER) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the default option. */ + if ((*(option_ptr) != NX_DHCP_OPTION_SUBNET_MASK) || + (*(option_ptr + 1) != NX_DHCP_OPTION_GATEWAYS) || + (*(option_ptr + 2) != NX_DHCP_OPTION_DNS_SVR)) + { + printf("ERROR!\n"); + test_control_return(1); + } + option_ptr += 3; + + /* Check the user option. */ + for (index = 0; index < NX_DHCP_CLIENT_MAX_USER_REQUEST_PARAMETER; index ++) + { + if (*(option_ptr + index) != NX_DHCP_OPTION_NTP_SVR + index) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + } + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Wait for test done. */ + while(test_done == NX_FALSE) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + { + error_counter++; + } + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Add default option: subnet mask. */ + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_SUBNET_MASK); + if (status != NX_DUPLICATED_ENTRY) + { + error_counter++; + } + + /* Add default option: gateway. */ + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_GATEWAYS); + if (status != NX_DUPLICATED_ENTRY) + { + error_counter++; + } + + /* Add default option: dns. */ + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_DNS_SVR); + if (status != NX_DUPLICATED_ENTRY) + { + error_counter++; + } + + /* Try to add NTP server option. */ + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_NTP_SVR); + if (status) + { + error_counter++; + } + + /* Try to add NTP server option again. */ + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_NTP_SVR); + if (status != NX_DUPLICATED_ENTRY) + { + error_counter++; + } + + /* Loop to fill in the array. */ + for (i = 0; i < NX_DHCP_CLIENT_MAX_USER_REQUEST_PARAMETER - 1; i++) + { + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_NTP_SVR + i + 1); + if (status) + { + error_counter++; + } + } + + /* Try to add one more. */ + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_NTP_SVR + i + 1); + if (status != NX_NO_MORE_ENTRIES) + { + error_counter++; + } + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + { + error_counter++; + } + + /* Let client sends out at least one message. */ + while(dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_discoveries_sent == 0) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + test_done = NX_TRUE; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_parameter_request_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Parameter Request Test........................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_client_secondary_interface_test.c b/test/regression/dhcp_test/netx_dhcp_client_secondary_interface_test.c new file mode 100644 index 00000000..c94b6180 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_secondary_interface_test.c @@ -0,0 +1,609 @@ +/* Testing the multiple interface DHCP Client */ + +/* This test checks that the DHCP Client can run on the secondary interface, + only using the nx_dhcp_set_interface_index for backward compatibility. + + Set MAX PHYSICAL INTERFACES to 2, NX_DHCP_CLIENT_MAX_INTERFACES to 1 + and run the demo. + */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + + +extern void test_control_return(UINT); + + +#if (NX_MAX_PHYSICAL_INTERFACES >= 2) + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + + +/* Define the ThreadX, NetX object control blocks... */ + +static NX_UDP_SOCKET server_socket; +static TX_THREAD client_thread; +static TX_THREAD server_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +/* Define the NetX FTP object control block. */ +static NX_DHCP dhcp_client; +static UINT bound0 = NX_FALSE; +static UINT bound1 = NX_FALSE; + +static ULONG dhcp_xid = 0; + + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 2 +static DHCP_RESPONSE dhcp_response[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client_running = NX_TRUE; + + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number); +static void dhcp_test_initialize(); +static void dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state); +static ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size); + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +/* Note that the network is 192.2.2.0 and the MAC address is 11 22 33 44 56 + because there are four entities (server 2 interfaces, client 2 interfaces + and the ram driver increases the MAC sequentially starting from + 11 22 33 44 56. */ +static char offer_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, /* {.....T. */ +0xF0, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x01, 0x01, 0x01, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response_size = 300; + +/* Frame (342 bytes) */ +static char ack_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, /* {.....T. */ +0xF0, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +//0x00, 0x00, 0xc0, 0x02, 0x02, 0x01, 0xc0, 0x02, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response_size = 300; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_secondary_interface_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the FTP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server_thread, "Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", PACKET_PAYLOAD, + pointer , PACKET_PAYLOAD*6); + + pointer = pointer + (PACKET_PAYLOAD*6); + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&server_ip, "Client1 IP", IP_ADDRESS(192,1,1,1), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + if (status) + error_counter++; + + + /* Set up the Client. */ + + /* Create the main client thread. */ + status = tx_thread_create(&client_thread, "Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 10*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 10*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, " Client0 IP Instance", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client1 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; + +} + +/* Define the DHCP client thread. */ + +static void client_thread_entry(ULONG thread_input) +{ + +UINT status, actual_status; +UINT time_keeper = 0; + + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 5); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Register state change callbacks. */ + status = nx_dhcp_interface_state_change_notify(&dhcp_client, dhcp_interface_state_change); + if (status) + error_counter++; + + /* Only interface 1 should be active! */ + status = nx_dhcp_set_interface_index(&dhcp_client, 1); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + while(bound1 != NX_TRUE) + { + + time_keeper += 100; + tx_thread_sleep(NX_IP_PERIODIC_RATE); + if (time_keeper >= 1000) + { + error_counter++; + break; + } + } + + if ((bound1 != NX_TRUE) || (bound0 == NX_TRUE)) + { + error_counter++; + } + + /* Verify interface 0 does not have a valid IP address. */ + status = nx_ip_interface_status_check(&client_ip, 0, NX_IP_ADDRESS_RESOLVED, (ULONG *) &actual_status, NX_NO_WAIT); + + if (status == NX_SUCCESS) + { + error_counter++; + } + + /* Verify interface 1 has a valid IP address. */ + status = nx_ip_interface_status_check(&client_ip, 1, NX_IP_ADDRESS_RESOLVED, (ULONG *) &actual_status, NX_NO_WAIT); + + if (status != NX_SUCCESS) + { + error_counter++; + } + + client_running = NX_FALSE; + nx_dhcp_release(&dhcp_client); + +} + + +/* Define the helper FTP server thread. */ +static void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Secondary Interface Test......................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + i = 0; + + /* Wait for Client requests */ + while ( i < NUM_RESPONSES) + { + + if (i <= 1) + { + + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + error_counter++; + } + else + { + + dhcp_xid = dhcp_get_dhcp_data(my_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID, 4); + + /* Release the packet. */ + nx_packet_release(my_packet); + + status = nx_dhcp_response_packet_send(&server_socket, 68, i); + } + } + + /* Check status. */ + if (status) + { + + error_counter++; + } + + + /* Advance the index for the next response. */ + i++; + } + + /* Check status. */ + if (status) + { + + error_counter++; + } + + /* Should get one more message from the Client, a DECLINE message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + error_counter++; + } + + /* Wait for the client thread to terminate. */ + while(client_running == NX_TRUE) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +static void dhcp_test_initialize() +{ + + +/* Download data responses */ + dhcp_response[0].dhcp_response_pkt_data = &offer_response[0]; + dhcp_response[0].dhcp_response_pkt_size = offer_response_size ; + + dhcp_response[1].dhcp_response_pkt_data = &ack_response[0]; + dhcp_response[1].dhcp_response_pkt_size = ack_response_size ; +} + + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; +UCHAR *work_ptr; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data, + dhcp_response[packet_number].dhcp_response_pkt_size); + + + /* Now replace the XID in the server message with what we know is the Client XID. */ + work_ptr = (UCHAR *)(response_packet -> nx_packet_prepend_ptr + NX_BOOTP_OFFSET_XID); + NX_CHANGE_ULONG_ENDIAN(dhcp_xid); + memcpy(work_ptr, (void const *)(&dhcp_xid), 4); + + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + + /* Send the packet with the correct port. */ + status = nx_udp_socket_interface_send(server_socket_ptr, response_packet, 0xFFFFFFFF, 68, 1); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} + +static void dhcp_interface_state_change(NX_DHCP *dhcp_ptr, UINT iface_index, UCHAR new_state) +{ + + if (iface_index == 0) + { + if (new_state == NX_DHCP_STATE_BOUND) + { + bound0 = NX_TRUE; + } + } + else + { + if (new_state == NX_DHCP_STATE_BOUND) + { + bound1 = NX_TRUE; + } + + } + return; +} + + +static ULONG dhcp_get_dhcp_data(UCHAR *data, UINT size) +{ + +ULONG value = 0; + + + /* Process the data retrieval request. */ + while (size-- > 0) + { + + /* Build return value. */ + value = (value << 8) | *data++; + } + + /* Return value. */ + return(value); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_secondary_interface_test_application_define(void * first_unused_memory) +#endif +{ + + printf("NetX Test: DHCP Client Secondary Interface Test......................N/A!\n"); + test_control_return(3); +} +#endif /* (NX_MAX_PHYSICAL_INTERFACES >= 2) */ + + + + + + + diff --git a/test/regression/dhcp_test/netx_dhcp_client_send_with_zero_source_address_test.c b/test/regression/dhcp_test/netx_dhcp_client_send_with_zero_source_address_test.c new file mode 100644 index 00000000..f521c999 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_send_with_zero_source_address_test.c @@ -0,0 +1,217 @@ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "tx_timer.h" +#include "tx_thread.h" +#include "tx_mutex.h" +#include "tx_event_flags.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* If defined, the host requests a (previous) client IP address. */ +/* +#define REQUEST_CLIENT_IP +*/ + +/* If defined the client requests to jump to the boot state and skip the DISCOVER message. + If REQUEST_CLIENT_IP is not defined, this has no effect. */ +/* +#define SKIP_DISCOVER_MESSAGE +*/ + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; +static NX_DHCP dhcp_client2; +static NX_DHCP dhcp_client3; +static ULONG dhcp_your_address = 0; +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_send_with_zero_source_address_test_applicaiton_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + return; +} + +static UINT dhcp_user_option_add_with_long_length(NX_DHCP *dhcp_ptr, UINT iface_index, UINT message_type, UCHAR *user_option_ptr, UINT *user_option_length) +{ + *user_option_length = 1100; + + return NX_TRUE; +} + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) +static UINT packet_filter_extended(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT direction) +{ + if ((direction == NX_IP_PACKET_OUT) && + ((packet_ptr -> nx_packet_ip_header == NX_NULL) || + (packet_ptr -> nx_packet_ip_header_length == 0))) + { + error_counter++; + } + return(NX_SUCCESS); +} +#endif + +/* Define the test threads. */ +void client_thread_entry(ULONG thread_input) +{ +UINT status; +ULONG i; + + printf("NetX Test: DHCP Client Send with Zero Source Address Test........................................"); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) + client_ip.nx_ip_packet_filter_extended = packet_filter_extended; +#endif + +#ifdef REQUEST_CLIENT_IP + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + + nx_dhcp_start(&dhcp_client); +#endif + + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REQUESTING; + + /* test _nx_dhcp_client_send_with_zero_source_address*/ + client_ip.nx_ip_interface[0].nx_interface_valid = NX_FALSE; + client_ip.nx_ip_interface[0].nx_interface_link_up = NX_FALSE; + nx_dhcp_interface_send_request(&dhcp_client, 0, NX_DHCP_TYPE_DHCPDISCOVER); + client_ip.nx_ip_interface[0].nx_interface_valid = NX_TRUE; + nx_dhcp_interface_send_request(&dhcp_client, 0, NX_DHCP_TYPE_DHCPDISCOVER); + dhcp_client.nx_dhcp_ip_ptr->nx_ip_id = NX_IP_ID; + nx_ip_fragment_enable(dhcp_client.nx_dhcp_ip_ptr); + client_ip.nx_ip_interface[0].nx_interface_link_up = NX_TRUE; + client_ip.nx_ip_interface[0].nx_interface_link_up = NX_TRUE; + nx_dhcp_user_option_add_callback_set(&dhcp_client, dhcp_user_option_add_with_long_length); + nx_dhcp_interface_send_request(&dhcp_client, 0, NX_DHCP_TYPE_DHCPDISCOVER); + dhcp_client.nx_dhcp_socket.nx_udp_socket_fragment_enable = NX_FRAGMENT_OKAY; + nx_dhcp_interface_send_request(&dhcp_client, 0, NX_DHCP_TYPE_DHCPDISCOVER); + dhcp_client.nx_dhcp_socket.nx_udp_socket_fragment_enable = NX_DONT_FRAGMENT; + + /* Use this for loop to test the corner case when the computed checksum is 0 + in function _nx_dhcp_client_send_with_zero_source_address */ + for (i = 0; i < 60000; i++) + { + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_ip_address = i; + nx_dhcp_interface_send_request(&dhcp_client, 0, NX_DHCP_TYPE_DHCPDISCOVER); + } + + nx_dhcp_interface_stop(&dhcp_client, 0); + nx_dhcp_delete(&dhcp_client); + + printf("SUCCESS!\n"); + test_control_return(0); + return; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_send_with_zero_source_address_test_applicaiton_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Client Send with Zero Source Address Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_client_server_source_port_test.c b/test/regression/dhcp_test/netx_dhcp_client_server_source_port_test.c new file mode 100644 index 00000000..51ef54a6 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_server_source_port_test.c @@ -0,0 +1,414 @@ +/* This NetX test concentrates on the DHCP operation to verify the DHCP server source port + is excluded from DHCP Client validation checks. Further the NetX /NetX Duo packet processing + should forward packets for the UDP socket bound to 68 without requiring the source port + be 67. */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ +static void client_thread_entry(ULONG thread_input); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *, ULONG, UINT, ULONG *, ULONG *); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* DCHP Unicast Interaction Message. */ + + +/* Frame (342 bytes) DHCP Offer. The server source port is modified from 67 to 83 in the OFFER + and REPLY packets for testing purposed. */ +static const unsigned char pkt2[342] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x50, /* .."3DV.P */ +0x56, 0x39, 0xf6, 0x3d, 0x08, 0x00, 0x45, 0x10, /* V9.=..E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x25, 0x79, 0x0a, 0x00, 0x00, 0x01, 0x0a, 0x00, /* %y...... */ +0x00, 0x1c, 0x00, 0x53, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xdb, 0x11, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .!...."3 */ +0x44, 0x6e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, /* Dn...... */ +0x00, 0x00, 0x0a, 0x00, 0x00, 0x1c, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x00, 0x00, 0x00, 0x00, /* "3DV.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x36, 0x04, 0x0a, /* Sc5..6.. */ +0x00, 0x00, 0x01, 0x33, 0x04, 0x00, 0x00, 0x01, /* ...3.... */ +0x2c, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ,....... */ +0x04, 0x0a, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Frame (342 bytes) DHCP ACK */ +static const unsigned char pkt4[342] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x50, /* .."3DV.P */ +0x56, 0x39, 0xf6, 0x3d, 0x08, 0x00, 0x45, 0x10, /* V9.=..E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x25, 0x79, 0x0a, 0x00, 0x00, 0x01, 0x0a, 0x00, /* %y...... */ +0x00, 0x1c, 0x00, 0x53, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xd8, 0x10, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* . ...."3 */ +0x44, 0x6e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, /* Dn...... */ +0x00, 0x00, 0x0a, 0x00, 0x00, 0x1c, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x00, 0x00, 0x00, 0x00, /* "3DV.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x36, 0x04, 0x0a, /* Sc5..6.. */ +0x00, 0x00, 0x01, 0x33, 0x04, 0x00, 0x00, 0x01, /* ...3.... */ +0x2c, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ,....... */ +0x04, 0x0a, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +ULONG dhcp_get_data_local(UCHAR *data, UINT size) +{ + +ULONG value = 0; + + + /* Process the data retrieval request. */ + while (size-- > 0) + { + + /* Build return value. */ + value = (value << 8) | *data++; + } + + /* Return value. */ + return(value); +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_server_source_port_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +ULONG client_ip_address; +ULONG client_ip_network_mask; + + + printf("NetX Test: DHCP Client Server Source Port Test......................."); + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Clear the broadcast flag. */ + status = nx_dhcp_clear_broadcast_flag(&dhcp_client, NX_TRUE); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IP address. */ + status = nx_ip_address_get(&client_ip, &client_ip_address, &client_ip_network_mask); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IP address. */ + if ((client_ip_address != IP_ADDRESS(10, 0, 0, 28)) || + (client_ip_network_mask != IP_ADDRESS(255, 255, 255, 0))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Stopping the DHCP client. */ + status = nx_dhcp_stop(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* All done. Return resources to NetX and ThreadX. */ + status = nx_dhcp_delete(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +UINT status; +ULONG dhcp_xid; +NX_PACKET *my_packet; + + /* Is this a DHCP packet e.g. not an ARP packet? */ + if (packet_ptr -> nx_packet_length < 328) + { + /* Maybe an ARP packet. let the RAM driver deal with it */ + return NX_TRUE; + } + + /* Update the packet counter. */ + packet_counter ++; + + /* Check the packet counter. */ + if (packet_counter == 1) + { + + /* Receive the DHCP Discover message. */ + + /* Send DHCP Offer message. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet, 0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return NX_TRUE; + } + + /* Write the DHCP Offer message. */ + my_packet -> nx_packet_length = sizeof(pkt2) - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt2 + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + } + else if (packet_counter == 2) + { + + /* Receive the DHCP Request message, */ + + /* Send DHCP ACK message. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet, 0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return NX_TRUE; + } + + /* Write the DHCP ACK message. */ + my_packet -> nx_packet_length = sizeof(pkt4) - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt4 + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + } + + /* Get the XID of DHCP message from DHCP Server. */ + dhcp_xid = dhcp_get_data_local(my_packet -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_XID, 4); + + /* Replace the XID. */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_xid = dhcp_xid; + + /* Receive the packet. */ + _nx_ip_packet_deferred_receive(ip_ptr, my_packet); + + return NX_TRUE; +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_server_source_port_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Server Source Port Test.......................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_client_special_attributes_test.c b/test/regression/dhcp_test/netx_dhcp_client_special_attributes_test.c new file mode 100644 index 00000000..e3168c3c --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_special_attributes_test.c @@ -0,0 +1,586 @@ +/* Testing the multiple interface DHCP Client */ + +/* Test the DHCP CLient with 2 physical interfaces, set NX_DHCP_CLIENT_MAX_INTERFACES = 1 + and run the demo. It sets several attributes (request IP, skip discovery message, + set state change callback, before setting the interface to 1. The DHCP Client should + transfer those attributes to the new active interface, and clear them on the old interface.*/ + + // jlc to do + // confirm BOUND state is achieved + // test on a real network to verify probe timeouts are correct. + // need a way to 'stop' the client test. Right now it spins endlessly. + + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + +#define REQUEST_CLIENT_IP +#ifdef REQUEST_CLIENT_IP +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,1,1,66) +#endif + +/* Define the ThreadX, NetX object control blocks... */ + +NX_UDP_SOCKET server_socket; +TX_THREAD client_thread; +TX_THREAD server_thread; +NX_PACKET_POOL client_pool; +NX_PACKET_POOL server_pool; +NX_IP client_ip; +NX_IP server_ip; + + +/* Define the NetX FTP object control block. */ +NX_DHCP dhcp_client; + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 2 +static DHCP_RESPONSE dhcp_response[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client_running = NX_FALSE; + + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +void server_thread_entry(ULONG thread_input); +void client_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, INT packet_number); +static void dhcp_test_initialize(); +static void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state); + +extern void test_control_return(UINT); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +/* Note that the network is 192.2.2.0 and the MAC address is 11 22 33 44 56 + because there are four entities (server 2 interfaces, client 2 interfaces + and the ram driver increases the MAC sequentially starting from + 11 22 33 44 56. */ +static char offer_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, /* {.....T. */ +0xF0, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +#ifdef REQUEST_CLIENT_IP +0x00, 0x00, 0xc0, 0x01, 0x01, 0x43, 0xc0, 0x01, /* ........ */ +#else +0x00, 0x00, 0xc0, 0x01, 0x01, 0xF7, 0xc0, 0x01, /* ........ */ +#endif +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x01, 0x01, 0x01, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response_size = 300; + +/* Frame (342 bytes) */ +static char ack_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, /* {.....T. */ +0xF0, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +#ifdef REQUEST_CLIENT_IP +0x00, 0x00, 0xc0, 0x01, 0x01, 0x43, 0xc0, 0x01, /* ........ */ +#else +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +#endif +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response_size = 300; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_cilent_special_attributes_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the DHCP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server_thread, "Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, + pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&server_ip, "Client1 IP", IP_ADDRESS(192,1,1,1), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + if (status) + error_counter++; + + + /* Set up the Client. */ + + /* Create the main client thread. */ + status = tx_thread_create(&client_thread, "Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 25*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 25*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, " Client0 IP Instance", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client1 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + + return; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +UINT skip_discover_message = NX_FALSE; +#endif + + tx_thread_sleep(20); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + if (status) + error_counter++; + + + status = nx_dhcp_clear_broadcast_flag(&dhcp_client, NX_TRUE); + + /* Set the client IP if the host is configured to do so. */ + if (status) + error_counter++; + +#ifdef REQUEST_CLIENT_IP + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + +#endif + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_interface_state_change1); + if (status) + error_counter++; + + /* Note that we call this after setting the stage change notify and clear broadcast service. + DHCP CLient defaults these to the primary interface unless the dhcp interface has been set. + If this host is configured for multiple interfaces, this call will reset these attributes on + both interfaces. */ + status = nx_dhcp_set_interface_index(&dhcp_client, 1); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + while(dhcp_client.nx_dhcp_interface[1].nx_dhcp_state != NX_DHCP_STATE_BOUND) + { + tx_thread_sleep(100); + } + + nx_dhcp_release(&dhcp_client); + + // jlc add status_interface check on IP address + // then wait for ****; + // if declines != 1; error + // if state != INIT/SELECTING error + +} + + +/* Define the helper FTP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client ARP Probe Multiple Interface Test1............\n"); // jlc remove the \n + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + i = 0; + + /* Wait for Client requests */ + while ( i < NUM_RESPONSES) + { + + if (i <= 1) + { + + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + else + { + printf("\nRECVd %dth packet\n", i); + + /* Release the packet. */ + nx_packet_release(my_packet); + + printf("Server sending response back. \n"); + status = nx_dhcp_response_packet_send(&server_socket, 68, i); + } + } + else + { + +#ifdef NX_DHCP_CLIENT_SEND_ARP_PROBE + /* Wait for the dhcp client to start the ARP probe process. */ + while (dhcp_client.nx_dhcp_interface[1].nx_dhcp_probe_count == 0) + tx_thread_sleep(10); +#endif + + printf("No one should send a Probe reply\n"); + } + + /* Check status. */ + if (status) + { + + printf("ERROR8!\n"); + error_counter++; + } + + + /* Advance the index for the next response. */ + i++; + } + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + /* Should get one more message from the Client, a DECLINE message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERRO7R!\n"); + error_counter++; + } + + + printf("All done, waiting for client to go away\n"); + + /* Wait for the client to terminate the connection. */ + while(client_running != NX_TRUE) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +static void dhcp_test_initialize() +{ + + +/* Download data responses */ + dhcp_response[0].dhcp_response_pkt_data = &offer_response[0]; + dhcp_response[0].dhcp_response_pkt_size = offer_response_size ; + + dhcp_response[1].dhcp_response_pkt_data = &ack_response[0]; + dhcp_response[1].dhcp_response_pkt_size = ack_response_size ; + + +} + + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; +NXD_ADDRESS ip_address; + + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = 0xFFFFFFFF; + + + printf("Sending %dth response\n", packet_number); + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data, + dhcp_response[packet_number].dhcp_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ + status = nxd_udp_socket_source_send(server_socket_ptr, response_packet, &ip_address, 68, 1); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} + +void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + +//UINT dhcp_state; + + //dhcp_state = (UINT)new_state; + + + return; +} + + diff --git a/test/regression/dhcp_test/netx_dhcp_client_two_interfaces.c b/test/regression/dhcp_test/netx_dhcp_client_two_interfaces.c new file mode 100644 index 00000000..194e17a3 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_client_two_interfaces.c @@ -0,0 +1,858 @@ +/* Test the DHCP CLient with 2 physical interfaces, set NX_DHCP_CLIENT_MAX_INTERFACES = 2 + and run the demo. Note because of limitations of the ram driver there is some + code in nx_dhcp_received_data_process in the nxd_dhcp_client.c to switch + packets that should be stamped for the secondary interface. Note to that DHCP Client + is modified in nx_dhcp_start() to set the XID arbitrarily. This simply facilitates + using the server responses (using "C arrays" from a real packet trace).*/ + + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + + +#define DEMO_STACK_SIZE 4096 +#define PACKET_PAYLOAD 1518 + +extern NX_PACKET *packet_copy; // jlc ram testing + +/* Define the ThreadX, NetX object control blocks... */ + +NX_UDP_SOCKET server_socket0; +TX_THREAD server_thread0; +TX_THREAD client_thread0; +NX_PACKET_POOL client_pool; +NX_PACKET_POOL server_pool; +NX_IP client_ip; +NX_IP server_ip0; + + +/* Define the NetX FTP object control block. */ +NX_DHCP dhcp_client; + +typedef struct DHCP_RESPONSE_STRUCT +{ + char *dhcp_response_pkt_data; + int dhcp_response_pkt_size; +} DHCP_RESPONSE; + +#define NUM_RESPONSES 7 // offer, ack, ack for renew for both interfaces + // set to 7 to include an additional ack for rebind request on interface 0 +static DHCP_RESPONSE dhcp_response[NUM_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client_running = NX_FALSE; +static UINT state_changes[2] = {0,0}; +static UINT renews[2] = {0,0}; +static UINT rebinds[2] = {0,0}; +static UINT bounds[2] = {0,0}; + +#define SERVER_PORT 67 + + +/* Replace the 'ram' driver with your Ethernet driver. */ +extern VOID nx_driver_ram_driver(NX_IP_DRIVER*); + +void server0_thread_entry(ULONG thread_input); +void client0_thread_entry(ULONG thread_input); + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *socket_ptr, UINT port, INT packet_number, UINT iface_index); +static void dhcp_test_initialize(); + +static void dhcp_interface_state_change0(NX_DHCP *dhcp_ptr, UCHAR new_state); +static void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state); + +extern void test_control_return(UINT); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +char offer_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x31, 0x9D, /* {.....T. */ +0x58, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x02, 0x02, 0x01, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response_size = 300; + +/* Frame (342 bytes) */ +char ack_response[300] = { + +0x02, 0x01, 0x06, 0x00, 0x31, 0x9D, /* {.....T. */ +0x58, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf7, 0xc0, 0x02, /* ........ */ +0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response_size = 300; + + +/* Frame (342 bytes) */ +static char renew_response[300] = { + + +0x02, 0x01, 0x06, 0x00, 0x31, 0x9D, /* :.....T. */ +0x58, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf8, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x05, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int renew_response_size = 300; + +/* Frame (342 bytes) */ +static char rebind_response[300] = { + + +0x02, 0x01, 0x06, 0x00, 0x31, 0x9D, /* g.....T. */ +0x58, 0xA2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0xf9, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x07, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x02, 0x02, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x02, 0x02, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x02, 0x02, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; +static int rebind_response_size = 300; + + +/* Responses from server on interface 1 */ + +char offer_response1[300] = { + +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, /* {.....T. */ +0xf0, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x01, 0x04, 0xff, /* Sc5..... */ +0xff, 0xff, 0x00, 0x3a, 0x04, 0x00, 0x06, 0xac, /* ...:.... */ +0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, 0x0a, 0x33, /* .;.....3 */ +0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, 0x04, 0xc0, /* ...Y06.. */ +0x01, 0x01, 0x01, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int offer_response1_size = 300; + +/* Frame (342 bytes) */ +char ack_response1[300] = { + +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, /* {.....T. */ +0xf0, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf7, 0xc0, 0x01, /* ........ */ +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x06, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int ack_response1_size = 300; + + +/* Frame (342 bytes) */ +static char renew_response1[300] = { + + +0x02, 0x01, 0x06, 0x00, 0x2a, 0x3e, /* :.....T. */ +0xf0, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x01, 0x01, 0xf8, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x59, 0x00, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x3a, 0x04, 0x00, /* Sc5..:.. */ +0x05, 0xac, 0x98, 0x3b, 0x04, 0x00, 0x0b, 0xae, /* ...;.... */ +0x0a, 0x33, 0x04, 0x00, 0x0d, 0x59, 0x30, 0x36, /* .3...Y06 */ +0x04, 0xc0, 0x01, 0x01, 0x01, 0x01, 0x04, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x03, 0x04, 0xc0, 0x01, 0x01, /* ........ */ +0x01, 0x06, 0x04, 0xc0, 0x01, 0x01, 0x01, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int renew_response1_size = 300; + + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_cilent_two_interface_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the FTP Server. */ + + /* Create the main server thread. */ + status = tx_thread_create(&server_thread0, "Server0 thread ", server0_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 700, pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip0, + "Server IP", + IP_ADDRESS(192,2,2,1), + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + status = nx_ip_interface_attach(&server_ip0, "Server1 interface", IP_ADDRESS(192,1,1,1), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip0); + if (status) + error_counter++; + + /* Set up the Client. */ + + /* Create the main client thread. */ + status = tx_thread_create(&client_thread0, "Client thread ", client0_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a packet pool for the client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", PACKET_PAYLOAD, pointer, 25*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 25*PACKET_PAYLOAD; + + /* Create an IP instance for the client. */ + status = nx_ip_create(&client_ip, "Client0 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&client_ip, "Client1 IP", IP_ADDRESS(0,0,0,0), 0xFFFFFF00UL, _nx_ram_network_driver_1024); + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Enable ARP and supply ARP cache memory for the Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable UDP for client IP instance. */ + nx_udp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; + +} + +/* Define the main DHCP client thread. */ +void client0_thread_entry(ULONG thread_input) +{ + +UINT status; + + tx_thread_sleep(20); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp0"); + if (status) + error_counter++; + + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; + + /* Register state change variable. */ + status = nx_dhcp_interface_state_change_notify(&dhcp_client, 0, dhcp_interface_state_change0); + if (status) + error_counter++; + + + /* Register state change variable. */ + status = nx_dhcp_interface_state_change_notify(&dhcp_client, 1, dhcp_interface_state_change1); + if (status) + error_counter++; + + printf("Start the client\n\n"); + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + while(client_running == NX_FALSE) + { + tx_thread_sleep(100); + } + + // jlc add status_interface check on IP address + // then wait for ****; if renews[0] != 1; error + // then wait for expire, and ***; if rebounds != 1 error + +} + +/* Define the helper DHCP server thread on interface 0. */ +void server0_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i, j, k; + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client Two Interface Test............................\n"); // jlc remove the \n + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip0, &server_socket0, "Server0 socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_udp_socket_bind(&server_socket0, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + dhcp_test_initialize(); + i = 0; + j = 4; // index into array of responses to send from interface server 1 + k = 0; // count of packets received on interface 1 + + /* Wait for Client requests */ + //while (i < 3) // Reduce this to see client packet retransmissions + while (i < NUM_RESPONSES) // jlc this let's the DHCP protocol complete. + { + + status = nx_udp_socket_receive(&server_socket0, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERRO7R on 0!\n"); + error_counter++; + } + else + { + + ULONG source_ip_address; + UINT protocol; + UINT source_port; + UINT iface_index; + + UCHAR *work_ptr = my_packet -> nx_packet_prepend_ptr + 4; + ULONG *id = (ULONG *)work_ptr; + + NX_CHANGE_ULONG_ENDIAN(*id); + + status = nx_udp_packet_info_extract(my_packet, &source_ip_address, &protocol, &source_port, &iface_index); + + if ((iface_index == 1) && (*id != 0x2a3ef01d)) + { + /* This packet is really intended for the server on the primary interface. */ + my_packet -> nx_packet_ip_interface = &(server_ip0.nx_ip_interface[0]); + iface_index = 0; + } + else if ((iface_index == 0) && (*id != 0x319d58a2)) + { + /* This packet is really intended for server on secondary interface. */ + my_packet -> nx_packet_ip_interface = &(server_ip0.nx_ip_interface[1]); + iface_index = 1; + } + + /* Is this packet from the client on interface 1? */ + if (*id == 0x2a3ef01d) + { + +// do this silliness to drop server packets +if (i != 1) +{ +////////// + + /* Yes, make sure to send it out on interface 1. */ + printf("Server 1 got %dth packet. Send %d packet back\n", k, j-4); + status = nx_dhcp_response_packet_send(&server_socket0, 68, j, 1); +} + j++; + k++; + + } + else + { +if (i != 1) +{ + printf("Server 0 got %dth packet\n", i); + status = nx_dhcp_response_packet_send(&server_socket0, 68, i, 0); +} + i++; + } + nx_packet_release(my_packet); + } + } + + printf("0: All done, waiting for client 0 to go away\n"); + + /* Wait for the client to terminate the connection. */ + while(client_running != NX_TRUE) + tx_thread_sleep(20); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&server_socket0); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + + + +static void dhcp_test_initialize() +{ + + +/* Download data responses */ + dhcp_response[0].dhcp_response_pkt_data = &offer_response[0]; + dhcp_response[0].dhcp_response_pkt_size = offer_response_size ; + + dhcp_response[1].dhcp_response_pkt_data = &ack_response[0]; + dhcp_response[1].dhcp_response_pkt_size = ack_response_size ; + + dhcp_response[2].dhcp_response_pkt_data = &renew_response[0]; + dhcp_response[2].dhcp_response_pkt_size = renew_response_size ; + + dhcp_response[3].dhcp_response_pkt_data = &rebind_response[0]; + dhcp_response[3].dhcp_response_pkt_size = rebind_response_size ; + + /* Server on second interface */ + + dhcp_response[4].dhcp_response_pkt_data = &offer_response1[0]; + dhcp_response[4].dhcp_response_pkt_size = offer_response1_size ; + + dhcp_response[5].dhcp_response_pkt_data = &ack_response1[0]; + dhcp_response[5].dhcp_response_pkt_size = ack_response1_size ; + + dhcp_response[6].dhcp_response_pkt_data = &renew_response1[0]; + dhcp_response[6].dhcp_response_pkt_size = renew_response1_size ; + +} + + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket0, UINT port, INT packet_number, UINT iface_index) +{ +UINT status; +NX_PACKET *response_packet; +UINT local_index; + + local_index = packet_number; + if (iface_index == 1) + { + local_index = packet_number - 4; + } + printf("Server %d sends %dth response\n", iface_index, local_index); + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data, + dhcp_response[packet_number].dhcp_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + if (iface_index == 0) + { + + + /* Set driver callback function. */ + //advanced_packet_process_callback = advanced_packet_process; + + /* Send the packet with the correct port. */ + status = nx_udp_socket_send(server_socket0, response_packet, 0xFFFFFFFF, 68); + } + else + { + + /* Send the packet with the correct port. */ + //status = nx_udp_socket_send(&server_socket1, response_packet, 0xFFFFFFFF, 68); + NXD_ADDRESS temp; + temp.nxd_ip_version = NX_IP_VERSION_V4; + temp.nxd_ip_address.v4 = 0xFFFFFFFF; + status = nxd_udp_socket_source_send(server_socket0, response_packet, &temp, 68, 1); + } + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} + + +void dhcp_interface_state_change0(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + +UINT dhcp_state; + + dhcp_state = (UINT)new_state; + + + /* Increment state changes counter. */ + state_changes[0]++; + + if (dhcp_state == NX_DHCP_STATE_RENEWING) + { + renews[0]++; + } + else if (dhcp_state == NX_DHCP_STATE_REBINDING) + { + rebinds[0]++; + } + else if (dhcp_state == NX_DHCP_STATE_BOUND) + { + bounds[0]++; + } + + return; +} + + +void dhcp_interface_state_change1(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + +UINT dhcp_state; + + dhcp_state = (UINT)new_state; + + + /* Increment state changes counter. */ + state_changes[1]++; + + if (dhcp_state == NX_DHCP_STATE_RENEWING) + { + renews[1]++; + } + else if (dhcp_state == NX_DHCP_STATE_REBINDING) + { + rebinds[1]++; + } + else if (dhcp_state == NX_DHCP_STATE_BOUND) + { + bounds[1]++; + } + + return; +} + diff --git a/test/regression/dhcp_test/netx_dhcp_clone_function.c b/test/regression/dhcp_test/netx_dhcp_clone_function.c new file mode 100644 index 00000000..b681df35 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_clone_function.c @@ -0,0 +1,125 @@ + +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + + +UINT dhcp_get_option_value(UCHAR *bootp_message, UINT option, ULONG *value, UINT length) +{ + +UCHAR *data; + + + /* Find the option. */ + if ((option != NX_DHCP_OPTION_PAD) && (option != NX_DHCP_OPTION_END)) + { + + /* Search the buffer for the option. */ + data = dhcp_search_buffer(bootp_message, option, length); + + /* Check to see if the option was found. */ + if (data != NX_NULL) + { + + /* Check for the proper size. */ + if (*data > 4) + { + + /* Check for the gateway option. */ + if (option == NX_DHCP_OPTION_GATEWAYS) + { + + /* Pickup the first gateway address. */ + *value = dhcp_get_data(data + 1, 4); + + /* For now, just disregard any additional gateway addresses. */ + return(NX_SUCCESS); + } + else + { + + /* Invalid size, return error. */ + return(NX_SIZE_ERROR); + } + } + else + { + + /* Get the actual value. */ + *value = dhcp_get_data(data + 1, *data); + return(NX_SUCCESS); + } + } + } + + /* Return an error if not found. */ + return(NX_OPTION_ERROR); +} +UCHAR *dhcp_search_buffer(UCHAR *bootp_message, UINT option, UINT length) +{ + +UCHAR *data; +UINT i; + + + /* Setup buffer pointer. */ + data = &bootp_message[NX_BOOTP_OFFSET_OPTIONS]; + i = NX_BOOTP_OFFSET_OPTIONS; + + /* Search as long as there are valid options. */ + while (i < length) + { + + /* Simply skip any padding */ + if (*data == NX_DHCP_OPTION_PAD) + { + + data++; + i++; + } + + /* On a match, return a pointer to the size. */ + else if (*data == option) + { + + /* Return a pointer to the option size byte. */ + return(data + 1); + } + + /* Otherwise skip the option by adding the size to the pointer. */ + else + { + + UINT size = *(++data); + + /* skip the data plus the size byte */ + data += size + 1; + i += size + 1; + } + } + + /* Return NULL to indicate the option was not found. */ + return(NX_NULL); +} +ULONG dhcp_get_data(UCHAR *data, UINT size) +{ + +ULONG value = 0; + + + /* Process the data retrieval request. */ + while (size-- > 0) + { + + /* Build return value. */ + value = (value << 8) | *data++; + } + + /* Return value. */ + return(value); +} diff --git a/test/regression/dhcp_test/netx_dhcp_clone_function.h b/test/regression/dhcp_test/netx_dhcp_clone_function.h new file mode 100644 index 00000000..2695be88 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_clone_function.h @@ -0,0 +1,6 @@ +#include "nx_api.h" + +/* Declare the function. */ +UINT dhcp_get_option_value(UCHAR *bootp_message, UINT option, ULONG *value, UINT length); +UCHAR *dhcp_search_buffer(UCHAR *bootp_message, UINT option, UINT length); +ULONG dhcp_get_data(UCHAR *data, UINT size); diff --git a/test/regression/dhcp_test/netx_dhcp_coverage_test.c b/test/regression/dhcp_test/netx_dhcp_coverage_test.c new file mode 100644 index 00000000..418228a8 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_coverage_test.c @@ -0,0 +1,907 @@ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#include "tx_timer.h" +#include "tx_thread.h" +#include "tx_mutex.h" +#include "tx_event_flags.h" + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +#define DHCP_TEST_LONG_NAME "dhcp_client_make_the_string_length_exceed_255_to_test_the_corner_case_in_function \ + netx_dhcp_send_request_internal__________________________________________________ \ + _________________________________________________________________________________ \ + _________________________________________________________________________________ \ + _________________________________________________________________________________ \ + _________________________________________________________________________________ \ + _________________________________________________________________________________ \ + _________________________________________________________________________________" + +#define NX_DHCP_OPTION_ARP_TIMEOUT 35 + +/* If defined, the host requests a (previous) client IP address. */ +/* +#define REQUEST_CLIENT_IP +*/ + +/* If defined the client requests to jump to the boot state and skip the DISCOVER message. + If REQUEST_CLIENT_IP is not defined, this has no effect. */ +/* +#define SKIP_DISCOVER_MESSAGE +*/ + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; +static NX_DHCP dhcp_client2; +static NX_DHCP dhcp_client3; +static ULONG dhcp_your_address = 0; + +/* Frame (342 bytes) */ +static unsigned char option_message[60] = { +0x35, 0x01, 0x02, /* DHCP message type */ +0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet Mask */ +0x36, 0x04, 0xe0, 0xa8, 0x02, 0x01, /* Server identifier */ +0x33, 0x04, 0xff, 0xff, 0xff, 0xff, /* IP address lease time */ +0x03, 0x04, 0xc0, 0x02, 0x00, 0x00, /* Router/gateway */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* DNS server */ +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* NTP server */ +0x3a, 0x04, 0xff, 0xff, 0xff, 0xff, /* Renewal time */ +0x3b, 0x04, 0xff, 0xff, 0xff, 0xff, /* Rebind time */ +0x23, 0x04, 0x00, 0x00, 0x01, 0x02, /* ........ */ +0xff, 0x00, 0x00 +}; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +extern VOID _nx_dhcp_packet_process(NX_DHCP *dhcp_ptr, NX_DHCP_INTERFACE_RECORD *interface_record, NX_PACKET *packet_ptr); +extern UINT _nx_dhcp_packet_pool_set(NX_DHCP *dhcp_ptr, NX_PACKET_POOL *packet_pool_ptr); +extern UINT _nx_dhcp_decline(NX_DHCP *dhcp_ptr); +/* Define thread prototypes. */ + +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_coverage_test_applicaiton_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + return; +} + +static void state_change_cb(NX_DHCP *dhcp_ptr, UCHAR state) +{ + return; +} + +static UINT dhcp_user_option_add_with_false_return(NX_DHCP *dhcp_ptr, UINT iface_index, UINT message_type, UCHAR *user_option_ptr, UINT *user_option_length) +{ + return NX_FALSE; +} + +static UINT dhcp_user_option_add(NX_DHCP *dhcp_ptr, UINT iface_index, UINT message_type, UCHAR *user_option_ptr, UINT *user_option_length) +{ + *user_option_length = 301; + + return NX_TRUE; +} + +static void interface_state_change_cb(NX_DHCP *dhcp_ptr, UINT iface, UCHAR state) +{ + return; +} + +static NX_PACKET * create_dhcp_packet(int length) +{ + NX_PACKET* packet_ptr; +#ifdef __PRODUCT_NETXDUO__ + nx_packet_allocate(&client_pool, &packet_ptr, NX_IPv4_UDP_PACKET, NX_NO_WAIT); +#else + nx_packet_allocate(&client_pool, &packet_ptr, NX_UDP_PACKET, NX_NO_WAIT); +#endif +#ifdef __PRODUCT_NETXDUO__ + packet_ptr->nx_packet_ip_version = NX_IP_VERSION_V4; +#endif + packet_ptr->nx_packet_queue_next = NX_NULL; + packet_ptr->nx_packet_length = length; +#ifdef __PRODUCT_NETXDUO__ + packet_ptr->nx_packet_address.nx_packet_interface_ptr = &client_ip.nx_ip_interface[0]; +#else + packet_ptr->nx_packet_ip_interface = &client_ip.nx_ip_interface[0]; +#endif +#ifdef __PRODUCT_NETXDUO__ + packet_ptr->nx_packet_ip_header = packet_ptr->nx_packet_prepend_ptr - sizeof(NX_IPV4_HEADER); +#endif + packet_ptr->nx_packet_append_ptr += packet_ptr->nx_packet_length; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_XID] = ((dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_xid) >> 24) & 0xFF; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_XID + 1] = ((dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_xid) >> 16) & 0xFF; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_XID + 2] = ((dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_xid) >> 8) & 0xFF; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_XID + 3] = (dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_xid) & 0xFF; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_CLIENT_HW] = 0; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_CLIENT_HW + 1] = 0x11; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_CLIENT_HW + 2] = 0x22; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_CLIENT_HW + 3] = 0x33; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_CLIENT_HW + 4] = 0x44; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_CLIENT_HW + 5] = 0x56; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_YOUR_IP] = dhcp_your_address >> 24; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_YOUR_IP + 1] = (dhcp_your_address >> 16) & 0xFF ; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_YOUR_IP + 2] = (dhcp_your_address >> 8) & 0xFF; + packet_ptr->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_YOUR_IP + 3] = dhcp_your_address & 0xFF; + + dhcp_client.nx_dhcp_socket.nx_udp_socket_receive_head = packet_ptr; + dhcp_client.nx_dhcp_socket.nx_udp_socket_receive_count++; + packet_ptr->nx_packet_prepend_ptr -=8; + packet_ptr->nx_packet_length += 8; + return(packet_ptr); + +} + +static NX_PACKET * build_dhcp_packet(int length, UCHAR option_type, UCHAR val_len, UCHAR val) +{ + NX_PACKET *my_packet; + + my_packet = create_dhcp_packet(length); + my_packet->nx_packet_prepend_ptr[8+NX_BOOTP_OFFSET_OPTIONS]=option_type; + my_packet->nx_packet_prepend_ptr[8+NX_BOOTP_OFFSET_OPTIONS+1]=val_len; + my_packet->nx_packet_prepend_ptr[8+NX_BOOTP_OFFSET_OPTIONS+2]=val; + + return(my_packet); +} + +extern VOID _nx_dhcp_timeout_process(NX_DHCP* dhcp_ptr); +extern TX_THREAD _tx_timer_thread; +/* Define the test threads. */ +void client_thread_entry(ULONG thread_input) +{ +ULONG current_system_state; +TX_THREAD *current_thread_ptr; +UCHAR buffer[4]; +UINT buffer_size = 4; +ULONG long_val; +ULONG payload_size = 0; + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +#endif + +TX_TIMER *timer_ptr; +TX_MUTEX *mutex_ptr; +TX_THREAD *thread_ptr; +TX_EVENT_FLAGS_GROUP *event_flags; +NX_PACKET *my_packet = NX_NULL; + printf("NetX Test: DHCP coverage Test........................................"); + + /* Force timer create to fail. */ + timer_ptr = _tx_timer_created_ptr; + _tx_timer_created_ptr = &dhcp_client.nx_dhcp_timer; + _tx_timer_created_count++; + + /* Create the DHCP instance. */ + nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + + /* Restore the timer structure. */ + _tx_timer_created_ptr = timer_ptr; + _tx_timer_created_count--; + + /* Force mutex create to fail. */ + mutex_ptr = _tx_mutex_created_ptr; + _tx_mutex_created_ptr = &dhcp_client.nx_dhcp_mutex; + _tx_mutex_created_count++; + /* Create the DHCP instance. */ + nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + + /* Restore mutex. */ + _tx_mutex_created_ptr = mutex_ptr; + _tx_mutex_created_count--; + + /* Force Thread create to fail.*/ + thread_ptr = _tx_thread_created_ptr; + _tx_thread_created_ptr = &dhcp_client.nx_dhcp_thread; + _tx_thread_created_count++; + /* Create the DHCP instance. */ + nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + + /* Restore thread list. */ + _tx_thread_created_ptr = thread_ptr; + _tx_thread_created_count--; + + /* Force event flag create to fail */ + event_flags = _tx_event_flags_created_ptr; + _tx_event_flags_created_count ++; + _tx_event_flags_created_ptr = &dhcp_client.nx_dhcp_events; + nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + + + /* Restore event flasg */ + _tx_event_flags_created_ptr = event_flags; + _tx_event_flags_created_count--; + + nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + /* Test nx_dhcp_interface_clear_broadcast_flag */ + nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_interface_clear_broadcast_flag(&dhcp_client, 0, 0); + + /* Enable one record */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_interface_index = 0; + nx_dhcp_interface_clear_broadcast_flag(&dhcp_client, 0, 0); + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + /* Cover _nx_dhcp_packet_pool_set */ + nx_dhcp_packet_pool_set(&dhcp_client, NX_NULL); + _nx_dhcp_packet_pool_set(&dhcp_client, NX_NULL); + nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); +#endif + + /* Cover _nxe_dhcp_reinitialize */ + nx_dhcp_reinitialize(&dhcp_client); + + /* Cover nx_dhcp_interface_reinitialize */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_interface_reinitialize(&dhcp_client, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + nx_dhcp_interface_reinitialize(&dhcp_client, 0); + + + /* Cover nx_dhcp_(interface_)request_client_ip */ + nx_dhcp_request_client_ip(&dhcp_client, 1, 0); + nx_dhcp_interface_request_client_ip(&dhcp_client, 0, 1, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_request_client_ip(&dhcp_client, 1, 0); + nx_dhcp_interface_request_client_ip(&dhcp_client, 0, 1, 0); + + + /* Cover nx_dhcp_force_renew */ + dhcp_client.nx_dhcp_id = NX_DHCP_ID; + nx_dhcp_force_renew(&dhcp_client); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + nx_dhcp_force_renew(&dhcp_client); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND; + nx_dhcp_force_renew(&dhcp_client); + + /* Cover nx_dhcp_interface_force_renew */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_interface_force_renew(&dhcp_client, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND - 1; + nx_dhcp_interface_force_renew(&dhcp_client, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND; + dhcp_client.nx_dhcp_state_change_callback = state_change_cb; + dhcp_client.nx_dhcp_interface_state_change_callback = interface_state_change_cb; + nx_dhcp_interface_force_renew(&dhcp_client, 0); + + /* Cover _nx_dhcp_update_renewal_timeout through calling nx_dhcp_interface_force_renew */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_rebind_time = 8000; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_renewal_time = 1000; + nx_dhcp_interface_force_renew(&dhcp_client, 0); + + /* Cover the static function _nx_dhcp_send_request_interval through calling API functions */ + payload_size = dhcp_client.nx_dhcp_packet_pool_ptr->nx_packet_pool_payload_size; + dhcp_client.nx_dhcp_packet_pool_ptr->nx_packet_pool_payload_size = 0; + nx_dhcp_interface_force_renew(&dhcp_client, 0); + dhcp_client.nx_dhcp_packet_pool_ptr->nx_packet_pool_payload_size = payload_size; + dhcp_client.nx_dhcp_name = DHCP_TEST_LONG_NAME; + nx_dhcp_interface_force_renew(&dhcp_client, 0); + dhcp_client.nx_dhcp_name = "dhcp_client"; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_ip_address = NX_BOOTP_BC_ADDRESS; + nx_dhcp_interface_force_renew(&dhcp_client, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_server_ip = NX_BOOTP_BC_ADDRESS; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND; + nx_dhcp_send_request(&dhcp_client, NX_DHCP_TYPE_DHCPREQUEST); + dhcp_client.nx_dhcp_name = NULL; + nx_dhcp_send_request(&dhcp_client, NX_DHCP_TYPE_DHCPINFORM); + dhcp_client.nx_dhcp_name = DHCP_TEST_LONG_NAME; + nx_dhcp_send_request(&dhcp_client, NX_DHCP_TYPE_DHCPINFORM); + nx_dhcp_user_option_add_callback_set(&dhcp_client, dhcp_user_option_add_with_false_return); + nx_dhcp_send_request(&dhcp_client, NX_DHCP_TYPE_DHCPINFORM); + dhcp_client.nx_dhcp_name = DHCP_TEST_LONG_NAME; + nx_dhcp_send_request(&dhcp_client, NX_DHCP_TYPE_DHCPDISCOVER); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_ip_address = 1; + nx_dhcp_decline(&dhcp_client); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_ip_address = NX_BOOTP_BC_ADDRESS; + nx_dhcp_decline(&dhcp_client); + nx_dhcp_user_option_add_callback_set(&dhcp_client, dhcp_user_option_add); + nx_dhcp_send_request(&dhcp_client, NX_DHCP_TYPE_DHCPINFORM); + + /* Cover nx_dhcp_decline */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_decline(&dhcp_client); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND - 1; + nx_dhcp_decline(&dhcp_client); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND; + nx_dhcp_decline(&dhcp_client); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_interface_decline(&dhcp_client, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND - 1; + nx_dhcp_interface_decline(&dhcp_client, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND; + dhcp_client.nx_dhcp_state_change_callback = NX_NULL; + dhcp_client.nx_dhcp_interface_state_change_callback = NX_NULL; + nx_dhcp_interface_decline(&dhcp_client, 0); + + /* Test _nx_dhcp_release */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND - 1; + nx_dhcp_release(&dhcp_client); + + /* Test nx_dhcp_interface_start */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_interface_start(&dhcp_client, 0); + + /* Test nx_dhcp_interface_release */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_interface_release(&dhcp_client, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND - 1; + nx_dhcp_interface_release(&dhcp_client, 0); + dhcp_client.nx_dhcp_state_change_callback = state_change_cb; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND; + nx_dhcp_interface_release(&dhcp_client, 0); + + /* Test nx_dhcp_interface_stop */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_interface_stop(&dhcp_client, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_NOT_STARTED; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + nx_dhcp_interface_stop(&dhcp_client, 0); + + /* Test nx_dhcp_user_option_retrieve*/ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + buffer_size = sizeof(buffer); + nx_dhcp_user_option_retrieve(&dhcp_client, 0, buffer, &buffer_size); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND - 1; + buffer_size = sizeof(buffer); + nx_dhcp_interface_user_option_retrieve(&dhcp_client, 0, 0, buffer, &buffer_size); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND - 1; + buffer_size = sizeof(buffer); + nx_dhcp_interface_user_option_retrieve(&dhcp_client, 0, 0, buffer, &buffer_size); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + nx_dhcp_interface_user_option_retrieve(&dhcp_client, 0, 0, buffer, &buffer_size); + buffer_size = 1; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_options_size = 4; + nx_dhcp_interface_user_option_retrieve(&dhcp_client, 0, 0, buffer, &buffer_size); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_options_buffer[0] = 1; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_options_buffer[1] = 2; + nx_dhcp_interface_user_option_retrieve(&dhcp_client, 0, 1, buffer, &buffer_size); + buffer_size = 4; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_options_buffer[0] = 0xFF; + nx_dhcp_interface_user_option_retrieve(&dhcp_client, 0, 0xFF, buffer, &buffer_size); + + /* Test _nx_dhcp_search_buffer through nx_dhcp_interface_user_option_retrieve */ + dhcp_client.nx_dhcp_interface_record->nx_dhcp_options_buffer[0] = 1; + dhcp_client.nx_dhcp_interface_record->nx_dhcp_options_buffer[1] = 5; + dhcp_client.nx_dhcp_interface_record->nx_dhcp_options_size = 4; + nx_dhcp_interface_user_option_retrieve(&dhcp_client, 0, 1, buffer, &buffer_size); + memcpy(dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_options_buffer, option_message, 60); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_options_size = 60; + nx_dhcp_interface_user_option_retrieve(&dhcp_client, 0, NX_DHCP_OPTION_ARP_TIMEOUT, buffer, &buffer_size); + + /* Test _nx_dhcp_interface_disable*/ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_interface_disable(&dhcp_client, 0); + + /* Test _nx_dhcp_user_option_retrieve*/ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND - 1; + nx_dhcp_user_option_retrieve(&dhcp_client, 0, NX_NULL, NX_NULL); + + /* Test nx_dhcp_user_option_convert*/ + long_val = nx_dhcp_user_option_convert(buffer); + + /* Test nx_dhcp_send_request*/ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_send_request(&dhcp_client, 1); + + /* Test nx_dhcp_interface_send_request*/ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_interface_send_request(&dhcp_client, 0, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + nx_dhcp_interface_send_request(&dhcp_client, 0, NX_DHCP_TYPE_DHCPRELEASE); + nx_dhcp_interface_send_request(&dhcp_client, 0, NX_DHCP_TYPE_DHCPDECLINE); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_NOT_STARTED; + nx_dhcp_interface_send_request(&dhcp_client, 0, NX_DHCP_TYPE_DHCPACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND; + nx_dhcp_interface_send_request(&dhcp_client, 0, NX_DHCP_TYPE_DHCPACK); + + /*Test nx_dhcp_server_address_get*/ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_server_address_get(&dhcp_client, &long_val); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND; + nx_dhcp_server_address_get(&dhcp_client, &long_val); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND - 1; + nx_dhcp_server_address_get(&dhcp_client, &long_val); + + /* Test nx_dhcp_interface_server_address_get*/ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + nx_dhcp_interface_server_address_get(&dhcp_client, 0, &long_val); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND; + nx_dhcp_interface_server_address_get(&dhcp_client, 0, &long_val); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOUND - 1; + nx_dhcp_interface_server_address_get(&dhcp_client, 0, &long_val); + + /* Test DHCP delete */ + current_system_state = _tx_thread_system_state; + _tx_thread_system_state = 1; + nx_dhcp_delete(&dhcp_client); + _tx_thread_system_state = current_system_state; + current_thread_ptr = _tx_thread_current_ptr; + _tx_thread_current_ptr = TX_NULL; + nx_dhcp_delete(&dhcp_client); + _tx_thread_current_ptr = &_tx_timer_thread; + nx_dhcp_delete(&dhcp_client); + _tx_thread_current_ptr = current_thread_ptr; + nx_dhcp_delete(&dhcp_client); + + nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + nx_dhcp_create(&dhcp_client2, &client_ip, "dhcp_client2"); + nx_dhcp_create(&dhcp_client3, &client_ip, "dhcp_client3"); + + nx_dhcp_delete(&dhcp_client); + nx_dhcp_delete(&dhcp_client2); + nx_dhcp_delete(&dhcp_client3); + + + current_system_state = _tx_thread_system_state; + _tx_thread_system_state = 1; + nx_dhcp_force_renew(&dhcp_client); + _tx_thread_system_state = current_system_state; + current_thread_ptr = _tx_thread_current_ptr; + _tx_thread_current_ptr = TX_NULL; + nx_dhcp_force_renew(&dhcp_client); + _tx_thread_current_ptr = &_tx_timer_thread; + nx_dhcp_force_renew(&dhcp_client); + _tx_thread_current_ptr = current_thread_ptr; + nx_dhcp_force_renew(&dhcp_client); + nx_dhcp_delete(&dhcp_client); + nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + /* Force nx_dhcp_start to fail. */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_FALSE; + + /* Start the DHCP Client. */ + nx_dhcp_start(&dhcp_client); + + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_BOOT; + /* Start the DHCP Client. */ + nx_dhcp_start(&dhcp_client); + + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = 0; + dhcp_client.nx_dhcp_socket.nx_udp_socket_bind_in_progress = _tx_thread_current_ptr; + /* Start the DHCP Client. */ + nx_dhcp_start(&dhcp_client); + dhcp_client.nx_dhcp_socket.nx_udp_socket_bind_in_progress = TX_NULL; + dhcp_client.nx_dhcp_thread.tx_thread_id = 0; + nx_dhcp_start(&dhcp_client); + dhcp_client.nx_dhcp_thread.tx_thread_id = TX_THREAD_ID; + dhcp_client.nx_dhcp_timer.tx_timer_id = 0; + nx_dhcp_start(&dhcp_client); + dhcp_client.nx_dhcp_timer.tx_timer_id = TX_TIMER_ID; + nx_dhcp_delete(&dhcp_client); + + nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + + /* Test nx_dhcp_interface_enable */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_interface_index = 0; + nx_dhcp_interface_enable(&dhcp_client, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_interface_index = 1; +#if(NX_MAX_PHYSICAL_INTERFACES > 1) + dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[1].nx_dhcp_interface_index = 2; +#endif + nx_dhcp_interface_enable(&dhcp_client, 0); + nx_dhcp_delete(&dhcp_client); + + /* Test nx_dhcp_packet_process */ + nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + nx_dhcp_start(&dhcp_client); + dhcp_client.nx_dhcp_socket.nx_udp_socket_disable_checksum = NX_TRUE; + +#ifndef NX_ENABLE_INTERFACE_CAPABILITY + /* Inject a packet that causes nx_udp_packet_info_extract() to fail. */ + my_packet = create_dhcp_packet(30); +#ifdef __PRODUCT_NETXDUO__ + my_packet->nx_packet_ip_version = 0; +#endif + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + /* Now test nx_dhcp_packet_process, test failures on the 1st check. */ + my_packet = create_dhcp_packet(30); +#ifdef __PRODUCT_NETXDUO__ + my_packet->nx_packet_ip_version = NX_IP_VERSION_V4; +#endif + dhcp_client.nx_dhcp_socket.nx_udp_socket_receive_head = my_packet; + dhcp_client.nx_dhcp_socket.nx_udp_socket_receive_count++; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); +#endif + + /* Attempt to cause the DHCP internal packet allocate to fail.*/ + { + UINT status; + NX_PACKET* packet1, * packet2, * packet3, * packet4, * packet5; +#ifdef __PRODUCT_NETXDUO__ + status = nx_packet_allocate(dhcp_client.nx_dhcp_packet_pool_ptr, &packet1, NX_IPv4_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_allocate(dhcp_client.nx_dhcp_packet_pool_ptr, &packet2, NX_IPv4_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_allocate(dhcp_client.nx_dhcp_packet_pool_ptr, &packet3, NX_IPv4_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_allocate(dhcp_client.nx_dhcp_packet_pool_ptr, &packet4, NX_IPv4_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_allocate(dhcp_client.nx_dhcp_packet_pool_ptr, &packet5, NX_IPv4_UDP_PACKET, NX_NO_WAIT); +#else + status = nx_packet_allocate(dhcp_client.nx_dhcp_packet_pool_ptr, &packet1, NX_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_allocate(dhcp_client.nx_dhcp_packet_pool_ptr, &packet2, NX_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_allocate(dhcp_client.nx_dhcp_packet_pool_ptr, &packet3, NX_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_allocate(dhcp_client.nx_dhcp_packet_pool_ptr, &packet4, NX_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_allocate(dhcp_client.nx_dhcp_packet_pool_ptr, &packet5, NX_UDP_PACKET, NX_NO_WAIT); +#endif + + my_packet = create_dhcp_packet(1000); + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + nx_packet_release(packet1); nx_packet_release(packet2); nx_packet_release(packet3); nx_packet_release(packet4); nx_packet_release(packet5); + + } + + /* Attemp to send a bigger packet to test the case incoming packet bigger than DHCP packets.*/ + my_packet = create_dhcp_packet(1000); + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + my_packet = create_dhcp_packet(400); + my_packet->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_CLIENT_HW + 1] = 2; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + my_packet = create_dhcp_packet(400); + my_packet->nx_packet_prepend_ptr[NX_BOOTP_OFFSET_CLIENT_HW + 5] = 0x55; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + { + build_dhcp_packet(400, 0, 0, 0); + /* intentionally set incorrect state.*/ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_ADDRESS_PROBING + 1; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + } + { + build_dhcp_packet(400, 0, 0, 0); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_SELECTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + } + { + + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPOFFER+1); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_SELECTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + } + { + + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPOFFER); + dhcp_your_address = 0; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_SELECTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + + dhcp_your_address = 0xFFFFFFFF; + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPOFFER); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_SELECTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + dhcp_your_address = 0x7F010001; + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPOFFER); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_SELECTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + dhcp_your_address = 0x80010001; + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPOFFER); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_SELECTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + dhcp_your_address = 0xC0010100; + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPOFFER); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_SELECTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + } + { + + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_SERVER, 1, NX_DHCP_TYPE_DHCPOFFER); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REBINDING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + dhcp_your_address = 0; + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REBINDING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + dhcp_your_address = 0x10203040; + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REBINDING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPNACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REBINDING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPRELEASE); + + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REBINDING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + } + + { + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_SERVER, 1, NX_DHCP_TYPE_DHCPOFFER); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_RENEWING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + dhcp_your_address = 0; + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_RENEWING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + dhcp_your_address = 0x10203040; + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_RENEWING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPNACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_RENEWING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPRELEASE); + + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_RENEWING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + } + + { + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_SERVER, 1, NX_DHCP_TYPE_DHCPOFFER); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REQUESTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + dhcp_your_address = 0; + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REQUESTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + dhcp_your_address = 0x10203040; + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REQUESTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPNACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REQUESTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPRELEASE); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REQUESTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPNACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REQUESTING; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_timeout = 1; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + + + build_dhcp_packet(400, NX_DHCP_OPTION_DHCP_TYPE, 1, NX_DHCP_TYPE_DHCPNACK); + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_state = NX_DHCP_STATE_REQUESTING; + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_renewal_time = NX_IP_PERIODIC_RATE + 1; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_RECEIVE_EVENT, TX_OR); + tx_thread_sleep(1); + } + + { + NX_DHCP_INTERFACE_RECORD *interface_record = &dhcp_client.nx_dhcp_interface_record[0]; + + interface_record->nx_dhcp_record_valid = NX_TRUE; + interface_record->nx_dhcp_timeout = 1; + interface_record->nx_dhcp_state = NX_DHCP_STATE_INIT; + interface_record->nx_dhcp_ip_address = 1; + interface_record->nx_dhcp_skip_discovery = NX_FALSE; + interface_record->nx_dhcp_rtr_interval = 1; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_TIMER_EVENT, TX_OR); + tx_thread_sleep(1); + + interface_record->nx_dhcp_record_valid = NX_TRUE; + interface_record->nx_dhcp_timeout = 1; + interface_record->nx_dhcp_state = NX_DHCP_STATE_SELECTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_TIMER_EVENT, TX_OR); + tx_thread_sleep(1); + + + interface_record->nx_dhcp_record_valid = NX_TRUE; + interface_record->nx_dhcp_timeout = 1; + interface_record->nx_dhcp_state = NX_DHCP_STATE_REQUESTING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_TIMER_EVENT, TX_OR); + tx_thread_sleep(1); + + interface_record->nx_dhcp_record_valid = NX_TRUE; + interface_record->nx_dhcp_timeout = 1; + interface_record->nx_dhcp_state = NX_DHCP_STATE_ADDRESS_PROBING; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_TIMER_EVENT, TX_OR); + tx_thread_sleep(1); + + interface_record->nx_dhcp_record_valid = NX_TRUE; + interface_record->nx_dhcp_timeout = 1; + interface_record->nx_dhcp_state = NX_DHCP_STATE_RENEWING; + interface_record->nx_dhcp_rtr_interval = 2; + interface_record->nx_dhcp_renewal_remain_time = 1; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_TIMER_EVENT, TX_OR); + tx_thread_sleep(1); + + interface_record->nx_dhcp_record_valid = NX_TRUE; + interface_record->nx_dhcp_timeout = 1; + interface_record->nx_dhcp_state = NX_DHCP_STATE_RENEWING; + interface_record->nx_dhcp_rtr_interval = 2; + interface_record->nx_dhcp_renewal_remain_time = 7; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_TIMER_EVENT, TX_OR); + tx_thread_sleep(1); + + interface_record->nx_dhcp_record_valid = NX_TRUE; + interface_record->nx_dhcp_timeout = 1; + interface_record->nx_dhcp_state = NX_DHCP_STATE_REBINDING; + interface_record->nx_dhcp_rtr_interval = 2; + interface_record->nx_dhcp_rebind_remain_time = 1; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_TIMER_EVENT, TX_OR); + tx_thread_sleep(1); + + interface_record->nx_dhcp_record_valid = NX_TRUE; + interface_record->nx_dhcp_timeout = 1; + interface_record->nx_dhcp_state = NX_DHCP_STATE_REBINDING; + interface_record->nx_dhcp_rtr_interval = 2; + interface_record->nx_dhcp_rebind_remain_time = 10; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_TIMER_EVENT, TX_OR); + tx_thread_sleep(1); + + interface_record->nx_dhcp_record_valid = NX_TRUE; + interface_record->nx_dhcp_timeout = 1; + interface_record->nx_dhcp_state = 0xFF; + interface_record->nx_dhcp_rtr_interval = 2; + interface_record->nx_dhcp_renewal_remain_time = 3; + tx_event_flags_set(&dhcp_client.nx_dhcp_events, NX_DHCP_CLIENT_TIMER_EVENT, TX_OR); + tx_thread_sleep(1); + + } + + printf("SUCCESS!\n"); + test_control_return(0); + return; +} + + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + /* Increment state changes counter. */ + state_changes++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_coverage_test_applicaiton_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Coverage Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_delete_test.c b/test/regression/dhcp_test/netx_dhcp_delete_test.c new file mode 100644 index 00000000..18990056 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_delete_test.c @@ -0,0 +1,425 @@ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* If defined, the host requests a (previous) client IP address. */ +/* +#define REQUEST_CLIENT_IP +*/ + +/* If defined the client requests to jump to the boot state and skip the DISCOVER message. + If REQUEST_CLIENT_IP is not defined, this has no effect. */ +/* +#define SKIP_DISCOVER_MESSAGE +*/ + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static NX_IP client_dummy1_ip; +static NX_DHCP dhcp_client_dummy1; +static NX_IP client_dummy2_ip; +static NX_DHCP dhcp_client_dummy2; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_delete_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Delete Test..........................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +UINT length; + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) +static UINT packet_filter_extended(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT direction) +{ + if ((direction == NX_IP_PACKET_OUT) && + ((packet_ptr -> nx_packet_ip_header == NX_NULL) || + (packet_ptr -> nx_packet_ip_header_length == 0))) + { + error_counter++; + } + return(NX_SUCCESS); +} +#endif + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UCHAR buffer[4]; +UINT buffer_size = 4; +ULONG *long_ptr; + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +UINT skip_discover_message = NX_FALSE; +#endif + + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + + /* Create 2 Dummy DHCP instances to test the corner case of _nx_dhcp_delete */ + client_dummy1_ip.nx_ip_id = NX_IP_ID; + status = nx_dhcp_create(&dhcp_client_dummy1, &client_dummy1_ip, "dhcp_client_dummy1"); + if (status) + error_counter++; + client_dummy2_ip.nx_ip_id = NX_IP_ID; + status = nx_dhcp_create(&dhcp_client_dummy2, &client_dummy2_ip, "dhcp_client_dummy2"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) + client_ip.nx_ip_packet_filter_extended = packet_filter_extended; +#endif + + /* Set the client IP if the host is configured to do so. */ +#ifdef REQUEST_CLIENT_IP + + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + +#endif + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Get the DNS Server address. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DNS_SVR, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the DNS address. */ + if (*long_ptr != NX_DHCP_DNS_SERVER_0) + error_counter++; + } + else + { + error_counter++; + } + + /* Get the lease time value. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DHCP_LEASE, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the lease time value. */ + if (*long_ptr != NX_DHCP_DEFAULT_LEASE_TIME) + error_counter++; + } + else + { + error_counter++; + } + + length = sizeof(message); + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* Set the value to test the corner case when _nx_dhcp_created_ptr != dhcp_ptr and dhcp_previous -> nx_dhcp_created_next */ + dhcp_client_dummy1.nx_dhcp_created_next = NX_NULL; + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + /* Increment state changes counter. */ + state_changes++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_delete_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Delete Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_enable_test.c b/test/regression/dhcp_test/netx_dhcp_enable_test.c new file mode 100644 index 00000000..c380f18b --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_enable_test.c @@ -0,0 +1,419 @@ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* If defined, the host requests a (previous) client IP address. */ +/* +#define REQUEST_CLIENT_IP +*/ + +/* If defined the client requests to jump to the boot state and skip the DISCOVER message. + If REQUEST_CLIENT_IP is not defined, this has no effect. */ +/* +#define SKIP_DISCOVER_MESSAGE +*/ + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_enable_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Enable Test..........................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +UINT length; + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) +static UINT packet_filter_extended(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT direction) +{ + if ((direction == NX_IP_PACKET_OUT) && + ((packet_ptr -> nx_packet_ip_header == NX_NULL) || + (packet_ptr -> nx_packet_ip_header_length == 0))) + { + error_counter++; + } + return(NX_SUCCESS); +} +#endif + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UCHAR buffer[4]; +UINT buffer_size = 4; +ULONG *long_ptr; + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +UINT skip_discover_message = NX_FALSE; +#endif + + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) + client_ip.nx_ip_packet_filter_extended = packet_filter_extended; +#endif + + /* Set the client IP if the host is configured to do so. */ +#ifdef REQUEST_CLIENT_IP + + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + +#endif + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Get the DNS Server address. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DNS_SVR, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the DNS address. */ + if (*long_ptr != NX_DHCP_DNS_SERVER_0) + error_counter++; + } + else + { + error_counter++; + } + + /* Get the lease time value. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DHCP_LEASE, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the lease time value. */ + if (*long_ptr != NX_DHCP_DEFAULT_LEASE_TIME) + error_counter++; + } + else + { + error_counter++; + } + + length = sizeof(message); + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Now stop the DHCP Client 0. */ + status = nx_dhcp_interface_disable(&dhcp_client, 0); + if (status) + error_counter++; + + for (UINT i = 0; i < NX_DHCP_CLIENT_MAX_RECORDS; i++) + { + dhcp_client.nx_dhcp_interface_record[i].nx_dhcp_record_valid = NX_TRUE; + dhcp_client.nx_dhcp_interface_record[i].nx_dhcp_interface_index = 1; + } + nx_dhcp_interface_enable(&dhcp_client, 0); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + /* Increment state changes counter. */ + state_changes++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_enable_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Enable Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_extract_information_test.c b/test/regression/dhcp_test/netx_dhcp_extract_information_test.c new file mode 100644 index 00000000..d4f0f781 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_extract_information_test.c @@ -0,0 +1,1034 @@ +/* The DHCPREQUEST message MUST use the same value in the DHCP message header's 'secs' field and be sent to the same IP + * broadcast address as the original DHCPDISCOVER message. + * rfc 2131, page 16, 3.1 Client-server interaction - allocating a network address + */ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +#define DHCP_RESPONSE_TEST_CASE_NUM 11 + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_UDP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT test_done = NX_FALSE; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, INT packet_number); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +typedef struct DHCP_RESPONSE_STRUCT +{ + UCHAR *dhcp_response_pkt_data; + UINT dhcp_response_pkt_size; +} DHCP_RESPONSE; + +static DHCP_RESPONSE dhcp_response[DHCP_RESPONSE_TEST_CASE_NUM]; + +/* Frame (342 bytes) */ +static unsigned char first_bad_offer[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xb0, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x63, 0x82, 0x53, 0x63, /* Magic cookie */ +0x35, 0x01, 0x02, /* DHCP message type */ +0x01, 0x04, 0x00, 0x00, 0x00, 0x00, /* Subnet Mask */ +0x36, 0x04, 0x00, 0x00, 0x00, 0x00, /* Server identifier */ +0x33, 0x04, 0xff, 0xff, 0xff, 0xff, /* IP address lease time */ +0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* Router */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* DNS server */ +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* NTP server */ +0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static unsigned char second_bad_offer[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xb0, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x63, 0x82, 0x53, 0x63, /* Magic cookie */ +0x35, 0x01, 0x02, /* DHCP message type */ +0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet Mask */ +0x36, 0x04, 0xe0, 0xa8, 0x02, 0x01, /* Server identifier */ +0x33, 0x04, 0xff, 0xff, 0xff, 0xff, /* IP address lease time */ +0x03, 0x04, 0xc0, 0x02, 0x00, 0x00, /* Router/gateway */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* DNS server */ +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* NTP server */ +0x3a, 0x04, 0xff, 0xff, 0xff, 0xff, /* Renewal time */ +0x3b, 0x04, 0xff, 0xff, 0xff, 0xff, /* Rebind time */ +0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00 +}; + +/* Frame (665 bytes) */ +static unsigned char first_good_offer[665] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xb0, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x63, 0x82, 0x53, 0x63, /* Magic cookie */ +0x35, 0x01, 0x02, /* DHCP message type */ +0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet Mask */ +0x36, 0x04, 0x80, 0xa8, 0x02, 0x01, /* Server identifier */ +0x33, 0x04, 0xff, 0xff, 0xff, 0xff, /* IP address lease time */ +0x03, 0x04, 0xc0, 0x01, 0x00, 0x00, /* Router/gateway */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* DNS server */ +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* NTP server */ +0x3a, 0x04, 0xff, 0xff, 0xff, 0xff, /* Renewal time */ +0x3b, 0x04, 0x00, 0xff, 0xff, 0xff, /* Rebind time */ +0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +}; + +/* Frame (342 bytes) */ +static unsigned char first_ack[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xad, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ......c. */ +0x63, 0x82, 0x53, 0x63, /* ........ */ +0x35, 0x01, 0x05, /* ........ */ +0x36, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* Server identifier */ +0x33, 0x04, 0x00, 0x00, 0x1b, 0xfe, /* IP address lease time */ +0x01, 0x04, 0xff, 0xff, 0xff, 0x00, +0x03, 0x04, 0x80, 0x01, 0x00, 0x00, /* Router/gateway */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* ........ */ +0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static unsigned char second_good_offer[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xb0, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x63, 0x82, 0x53, 0x63, /* Magic cookie */ +0x35, 0x01, 0x02, /* DHCP message type */ +0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet Mask */ +0x36, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* Server identifier */ +0x33, 0x04, 0x00, 0x00, 0x00, 0x01, /* IP address lease time */ +0x03, 0x04, 0xe0, 0x01, 0x00, 0x00, /* Router/gateway */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* DNS server */ +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* NTP server */ +0x3a, 0x04, 0x00, 0x00, 0xff, 0xff, /* Renewal time */ +0x3b, 0x04, 0xff, 0xff, 0xff, 0xff, /* Rebind time */ +0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00 +}; + +/* Frame (342 bytes) */ +static unsigned char second_ack[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xad, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ......c. */ +0x63, 0x82, 0x53, 0x63, /* ........ */ +0x35, 0x01, 0x05, /* ........ */ +0x36, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* Server identifier */ +0x33, 0x04, 0x00, 0x00, 0x1b, 0xfe, /* IP address lease time */ +0x01, 0x04, 0xff, 0xff, 0xff, 0x00, +0x03, 0x04, 0x00, 0x00, 0x00, 0x00, /* Router/gateway */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* ........ */ +0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static unsigned char third_good_offer[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xb0, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x63, 0x82, 0x53, 0x63, /* Magic cookie */ +0x35, 0x01, 0x02, /* DHCP message type */ +0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet Mask */ +0x36, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* Server identifier */ +0x33, 0x04, 0x00, 0x00, 0xff, 0xff, /* IP address lease time */ +0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* Router */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* DNS server */ +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* NTP server */ +0x3b, 0x04, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static unsigned char third_ack[665] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xad, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ......c. */ +0x63, 0x82, 0x53, 0x63, /* ........ */ +0x35, 0x01, 0x05, /* ........ */ +0x36, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* Server identifier */ +0x33, 0x04, 0x00, 0x00, 0x1b, 0xfe, /* IP address lease time */ +0x01, 0x04, 0xff, 0xff, 0xff, 0x00, +0x03, 0x04, 0xe0, 0x01, 0x02, 0x03, /* Router/gateway */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* ........ */ +0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +}; + +/* Frame (342 bytes) */ +static unsigned char offer[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xb0, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x63, 0x82, 0x53, 0x63, /* Magic cookie */ +0x35, 0x01, 0x02, /* DHCP message type */ +0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet Mask */ +0x36, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* Server identifier */ +0x33, 0x04, 0xff, 0xff, 0xff, 0xff, /* IP address lease time */ +0x03, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* Router */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* DNS server */ +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* NTP server */ +0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static unsigned char ack[665] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xad, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ......c. */ +0x63, 0x82, 0x53, 0x63, /* ........ */ +0x35, 0x01, 0x05, /* ........ */ +0x36, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* Server identifier */ +0x33, 0x04, 0x00, 0x00, 0x1b, 0xfe, /* IP address lease time */ +0x01, 0x04, 0xff, 0xff, 0xff, 0x00, +0x03, 0x04, 0xc0, 0x01, 0x02, 0x03, /* Router/gateway */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* ........ */ +0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_extract_information_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i = 0; +UINT index; +NX_PACKET *my_packet; +UCHAR *option_ptr; +UINT option_size; + + printf("NetX Test: DHCP Extract Information test..............................."); + +#ifdef __PRODUCT_NETXDUO__ + /* Update the MAC address. */ + status = nx_ip_interface_physical_address_set(&server_ip, 0, 0x00000015, 0x5d021e0f, NX_TRUE); + + /* Check for errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +#else + server_ip.nx_ip_interface[0].nx_interface_physical_address_msw = 0x00000015; + server_ip.nx_ip_interface[0].nx_interface_physical_address_lsw = 0x5d021e0f; +#endif + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + dhcp_response[0].dhcp_response_pkt_data = (char*)first_bad_offer; + dhcp_response[0].dhcp_response_pkt_size = sizeof(first_bad_offer); + dhcp_response[1].dhcp_response_pkt_data = (char*)second_bad_offer; + dhcp_response[1].dhcp_response_pkt_size = sizeof(second_bad_offer); + dhcp_response[2].dhcp_response_pkt_data = (char*)first_good_offer; + dhcp_response[2].dhcp_response_pkt_size = sizeof(first_good_offer); + dhcp_response[3].dhcp_response_pkt_data = first_ack; + dhcp_response[3].dhcp_response_pkt_size = sizeof(first_ack); + dhcp_response[4].dhcp_response_pkt_data = (char*)second_good_offer; + dhcp_response[4].dhcp_response_pkt_size = sizeof(second_good_offer); + dhcp_response[5].dhcp_response_pkt_data = second_ack; + dhcp_response[5].dhcp_response_pkt_size = sizeof(second_ack); + dhcp_response[6].dhcp_response_pkt_data = (char*)third_good_offer; + dhcp_response[6].dhcp_response_pkt_size = sizeof(third_good_offer); + dhcp_response[7].dhcp_response_pkt_data = (char*)third_good_offer; + dhcp_response[7].dhcp_response_pkt_size = sizeof(third_good_offer); + dhcp_response[8].dhcp_response_pkt_data = third_ack; + dhcp_response[8].dhcp_response_pkt_size = sizeof(third_ack); + dhcp_response[9].dhcp_response_pkt_data = (char*)offer; + dhcp_response[9].dhcp_response_pkt_size = sizeof(offer); + dhcp_response[10].dhcp_response_pkt_data = ack; + dhcp_response[10].dhcp_response_pkt_size = sizeof(ack); + + /* Wait for Client requests (DISCOVER and REQEUST). */ + for (i = 0; i < DHCP_RESPONSE_TEST_CASE_NUM; i++) + { + + /* Receive DHCP message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send response. */ + status = nx_dhcp_response_packet_send(&server_socket, i); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + } + + /* Wait for test done. */ + while(test_done == NX_FALSE) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i = 0; +ULONG ntp_server_address; +UINT ntp_server_address_size = 4; + +#ifdef __PRODUCT_NETXDUO__ + /* Update the MAC address. */ + status = nx_ip_interface_physical_address_set(&client_ip, 0, 0x00000011, 0x22334457, NX_TRUE); + + /* Check for errors. */ + if (status) + { + error_counter++; + } +#else + client_ip.nx_ip_interface[0].nx_interface_physical_address_msw = 0x00000011; + client_ip.nx_ip_interface[0].nx_interface_physical_address_lsw = 0x22334457; +#endif + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + { + error_counter++; + } + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + for (i = 0; i < DHCP_RESPONSE_TEST_CASE_NUM-4; i++) + { + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + { + error_counter++; + } + + tx_thread_sleep(8 * NX_IP_PERIODIC_RATE); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + } + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + test_done = NX_TRUE; + + return; +} + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data + (14 + 20 + 8), + dhcp_response[packet_number].dhcp_response_pkt_size - (14 + 20 + 8)); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size - (14 + 20 + 8); + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Fake the transaction id. */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_xid = 0x2233446f; + + /* Send the packet. */ + status = nx_udp_socket_send(server_socket_ptr, response_packet, IP_ADDRESS(255, 255, 255, 255), NX_DHCP_CLIENT_UDP_PORT); + + /* Check the status. */ + if (status) + { + nx_packet_release(response_packet); + } + + return status; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_extract_information_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DHCP extract information test...............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_get_option_value_test.c b/test/regression/dhcp_test/netx_dhcp_get_option_value_test.c new file mode 100644 index 00000000..8a42ddc5 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_get_option_value_test.c @@ -0,0 +1,544 @@ +/* The DHCPREQUEST message MUST use the same value in the DHCP message header's 'secs' field and be sent to the same IP + * broadcast address as the original DHCPDISCOVER message. + * rfc 2131, page 16, 3.1 Client-server interaction - allocating a network address + */ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_UDP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT test_done = NX_FALSE; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, INT packet_number); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +typedef struct DHCP_RESPONSE_STRUCT +{ + UCHAR *dhcp_response_pkt_data; + UINT dhcp_response_pkt_size; +} DHCP_RESPONSE; + +static DHCP_RESPONSE dhcp_response[2]; + +/* Frame (342 bytes) */ +static unsigned char offer[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xb0, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ......c. */ +0x63, 0x82, 0x53, 0x63, /* Magic cookie */ +0x35, 0x01, 0x02, 0x00, /* ........ */ +0x36, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* ........ */ +0x33, 0x04, 0x00, 0x00, 0x1b, 0xfe, /* ........ */ +0x01, 0x05, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, /* ........ */ +0x03, 0x05, 0xc0, 0xa8, 0x02, 0x01, 0x00, 0x00, /* Gateway with addtional addresses */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* DNS server with too long address */ +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, +0x00, 0xff, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* Frame (342 bytes) */ +static unsigned char ack[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xad, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ......c. */ +0x63, 0x82, 0x53, 0x63, +0x00, +0x35, 0x01, 0x05, 0x36, 0x04, 0xc0, +0xa8, 0x02, 0x01, 0x33, 0x04, 0x00, 0x00, 0x1b, /* ........ */ +0xfe, +0x01, 0x05, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, /* ........ */ +0x03, 0x05, 0xc0, 0xa8, 0x02, 0x01, 0x00, 0x00, /* Gateway with addtional addresses */ +0x06, 0x04, 0xc0, 0xa8, 0x02, 0x01, /* DNS server with too long address */ +0x2a, 0x04, 0x7c, 0x6c, 0x14, 0x01, /* ........ */ +0x00, 0xff, /* End */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_get_option_value_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i = 0; +UINT index; +NX_PACKET *my_packet; +UCHAR *option_ptr; +UINT option_size; + + printf("NetX Test: DHCP get option value test..............................."); + +#ifdef __PRODUCT_NETXDUO__ + /* Update the MAC address. */ + status = nx_ip_interface_physical_address_set(&server_ip, 0, 0x00000015, 0x5d021e0f, NX_TRUE); + + /* Check for errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +#else + server_ip.nx_ip_interface[0].nx_interface_physical_address_msw = 0x00000015; + server_ip.nx_ip_interface[0].nx_interface_physical_address_lsw = 0x5d021e0f; +#endif + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + dhcp_response[0].dhcp_response_pkt_data = (char*)offer; + dhcp_response[0].dhcp_response_pkt_size = sizeof(offer); + dhcp_response[1].dhcp_response_pkt_data = ack; + dhcp_response[1].dhcp_response_pkt_size = sizeof(ack); + + /* Wait for Client requests (DISCOVER and REQEUST). */ + for (i = 0; i < 2; i++) + { + + /* Receive DHCP message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Check if there is NTP in parameter request list. */ + option_ptr = dhcp_search_buffer(my_packet -> nx_packet_prepend_ptr, NX_DHCP_OPTION_DHCP_PARAMETERS, my_packet -> nx_packet_length); + + /* Check if found the parameter request option. */ + if (option_ptr == NX_NULL) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + option_size = (UINT)*option_ptr; + option_ptr++; + + /* Check if there is NTP. */ + for (index = 0; index < option_size; index ++) + { + if (*(option_ptr + index) == NX_DHCP_OPTION_NTP_SVR) + { + break; + } + } + + if (index >= option_size) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send response. */ + status = nx_dhcp_response_packet_send(&server_socket, i); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + } + + /* Wait for test done. */ + while(test_done == NX_FALSE) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +ULONG ntp_server_address; +UINT ntp_server_address_size = 4; + +#ifdef __PRODUCT_NETXDUO__ + /* Update the MAC address. */ + status = nx_ip_interface_physical_address_set(&client_ip, 0, 0x00000011, 0x22334457, NX_TRUE); + + /* Check for errors. */ + if (status) + { + error_counter++; + } +#else + client_ip.nx_ip_interface[0].nx_interface_physical_address_msw = 0x00000011; + client_ip.nx_ip_interface[0].nx_interface_physical_address_lsw = 0x22334457; +#endif + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + { + error_counter++; + } + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Request NTP. */ + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_NTP_SVR); + if (status) + { + error_counter++; + } + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + { + error_counter++; + } + + /* Wait for DHCP to assign the IP address. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Retrieve NTP server address. */ + status = nx_dhcp_interface_user_option_retrieve(&dhcp_client, 0, NX_DHCP_OPTION_NTP_SVR, (UCHAR *)(&ntp_server_address), + &ntp_server_address_size); + + /* Check status. */ + if ((status) || (ntp_server_address_size != 4) || (ntp_server_address != IP_ADDRESS(124, 108, 20, 1))) + { + error_counter++; + } + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + test_done = NX_TRUE; + + return; +} + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data + (14 + 20 + 8), + dhcp_response[packet_number].dhcp_response_pkt_size - (14 + 20 + 8)); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size - (14 + 20 + 8); + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Fake the transaction id. */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_xid = 0x2233446f; + + /* Send the packet. */ + status = nx_udp_socket_send(server_socket_ptr, response_packet, IP_ADDRESS(255, 255, 255, 255), NX_DHCP_CLIENT_UDP_PORT); + + /* Check the status. */ + if (status) + { + nx_packet_release(response_packet); + } + + return status; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_get_option_value_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DHCP get option value test...............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_multiple_instances_test.c b/test/regression/dhcp_test/netx_dhcp_multiple_instances_test.c new file mode 100644 index 00000000..358108f7 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_multiple_instances_test.c @@ -0,0 +1,525 @@ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE (NX_PACKET_SIZE * 8) + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +#define NX_DHCP_SERVER_IP_ADDRESS_1 IP_ADDRESS(192,168,0,1) +#define START_IP_ADDRESS_LIST_1 IP_ADDRESS(192,168,0,10) +#define END_IP_ADDRESS_LIST_1 IP_ADDRESS(192,168,0,19) + +#define NX_DHCP_SUBNET_MASK_1 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_1 IP_ADDRESS(192,168,0,1) +#define NX_DHCP_DNS_SERVER_1 IP_ADDRESS(192,168,0,1) + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool_0; +static NX_PACKET_POOL client_pool_1; +static NX_IP client_ip_0; +static NX_IP client_ip_1; +static NX_DHCP dhcp_client_0; +static NX_DHCP dhcp_client_1; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool_0; +static NX_PACKET_POOL server_pool_1; +static NX_IP server_ip_0; +static NX_IP server_ip_1; +static NX_DHCP_SERVER dhcp_server_0; +static NX_DHCP_SERVER dhcp_server_1; + +static ULONG client_pool_stack_0[NX_PACKET_POOL_SIZE / sizeof(ULONG)]; +static ULONG client_pool_stack_1[NX_PACKET_POOL_SIZE / sizeof(ULONG)]; + +static ULONG server_pool_stack_0[NX_PACKET_POOL_SIZE / sizeof(ULONG)]; +static ULONG server_pool_stack_1[NX_PACKET_POOL_SIZE / sizeof(ULONG)]; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void my_udp_packet_receive(NX_IP* ip_ptr, NX_PACKET* packet_ptr); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT* driver_req); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_multiple_instances_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool0. */ + status = nx_packet_pool_create(&client_pool_0, "NetX Main Packet Pool", 1024, client_pool_stack_0, sizeof(client_pool_stack_0)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the client packet pool1. */ + status = nx_packet_pool_create(&client_pool_1, "NetX Main Packet Pool", 1024, client_pool_stack_1, sizeof(client_pool_stack_1)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool0. */ + status = nx_packet_pool_create(&server_pool_0, "NetX Main Packet Pool", 1024, server_pool_stack_0, sizeof(server_pool_stack_0)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool1. */ + status = nx_packet_pool_create(&server_pool_1, "NetX Main Packet Pool", 1024, server_pool_stack_1, sizeof(server_pool_stack_1)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip_0, "DHCP Client 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool_0, _nx_ram_network_driver_512, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip_1, "DHCP Client 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool_1, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip_0, "DHCP Server 0", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool_0, _nx_ram_network_driver_512, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip_1, "DHCP Server 1", NX_DHCP_SERVER_IP_ADDRESS_1, 0xFFFFFF00UL, &server_pool_1, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip_1, (void*)pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip_1, (void*)pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip_0); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip_0); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip_0); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip_1); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip_0); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip_1); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT addresses_added; + + printf("NetX Test: NetX DHCP Multiple Instances Test........................."); + + /* Change udp receive function to my routine. */ + client_ip_0.nx_ip_udp_packet_receive = my_udp_packet_receive; + client_ip_1.nx_ip_udp_packet_receive = my_udp_packet_receive; + server_ip_0.nx_ip_udp_packet_receive = my_udp_packet_receive; + server_ip_1.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Create the DHCP Server 0. */ + status = nx_dhcp_server_create(&dhcp_server_0, &server_ip_0, pointer, DEMO_STACK_SIZE, + "DHCP Server 0", &server_pool_0); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server_0, 0, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server_0, 0, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server_0); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + /* Create the DHCP Server 1. */ + status = nx_dhcp_server_create(&dhcp_server_1, &server_ip_1, pointer, DEMO_STACK_SIZE, + "DHCP Server 1", &server_pool_1); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server_1, 0, START_IP_ADDRESS_LIST_1, + END_IP_ADDRESS_LIST_1, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server_1, 0, NX_DHCP_SUBNET_MASK_1, + NX_DHCP_DEFAULT_GATEWAY_1, NX_DHCP_DNS_SERVER_1); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server_1); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +UINT length; + + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG ip_address_0; +ULONG network_address_0; +ULONG ip_address_1; +ULONG network_address_1; + + /* Create the DHCP instance 0. */ + status = nx_dhcp_create(&dhcp_client_0, &client_ip_0, "dhcp_client_0"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client_0, &client_pool_0); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Start the DHCP Client 0. */ + status = nx_dhcp_start(&dhcp_client_0); + if (status) + error_counter++; + + /* Create the DHCP instance 1. */ + status = nx_dhcp_create(&dhcp_client_1, &client_ip_1, "dhcp_client_1"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client_1, &client_pool_1); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Start the DHCP Client 1. */ + status = nx_dhcp_start(&dhcp_client_1); + if (status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip_0, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip_1, NX_IP_ADDRESS_RESOLVED, (ULONG*)&status, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Check the IP address. */ + status = nx_ip_address_get(&client_ip_0, &ip_address_0, &network_address_0); + status += nx_ip_address_get(&client_ip_1, &ip_address_1, &network_address_1); + + /* Check status. */ + if ((status) || (ip_address_0 != START_IP_ADDRESS_LIST_0) || (ip_address_1 != START_IP_ADDRESS_LIST_1)) + error_counter++; + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip_0, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, sizeof(message), &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip_1, NX_DHCP_SERVER_IP_ADDRESS_1, (CHAR*)message, sizeof(message), &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Clean up. */ + nx_dhcp_stop(&dhcp_client_0); + nx_dhcp_delete(&dhcp_client_0); + nx_dhcp_stop(&dhcp_client_1); + nx_dhcp_delete(&dhcp_client_1); + + return; +} + +static void my_udp_packet_receive(NX_IP* ip_ptr, NX_PACKET* packet_ptr) +{ +UCHAR* source_address_ptr; +ULONG source_address_msw; +ULONG source_address_lsw; + + /* Get the source mac address. */ + source_address_ptr = packet_ptr->nx_packet_prepend_ptr - 20 - 8; + source_address_msw = ((*source_address_ptr) << 8) | (*(source_address_ptr + 1)); + source_address_lsw = (*(source_address_ptr + 2) << 24) | (*(source_address_ptr + 3) << 16) | (*(source_address_ptr + 4) << 8) | (*(source_address_ptr + 5)); + + /* Rules: + client_ip_0 only receives data from server_ip_0; + server_ip_1 only receives data from client_ip_0; + client_ip_1 only receives data from server_ip_1; + server_ip_1 only receives data from client_ip_1; + */ + + if (((ip_ptr == &client_ip_0) && + ((source_address_msw == server_ip_0.nx_ip_interface[0].nx_interface_physical_address_msw) && + ((source_address_lsw == server_ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw)))) || + ((ip_ptr == &server_ip_0) && + ((source_address_msw == client_ip_0.nx_ip_interface[0].nx_interface_physical_address_msw) && + ((source_address_lsw == client_ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw)))) || + ((ip_ptr == &client_ip_1) && + ((source_address_msw == server_ip_1.nx_ip_interface[0].nx_interface_physical_address_msw) && + ((source_address_lsw == server_ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw)))) || + ((ip_ptr == &server_ip_1) && + ((source_address_msw == client_ip_1.nx_ip_interface[0].nx_interface_physical_address_msw) && + ((source_address_lsw == client_ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw))))) + { + _nx_udp_packet_receive(ip_ptr, packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_multiple_instances_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Multiple Instances Test.........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_packet_process_test.c b/test/regression/dhcp_test/netx_dhcp_packet_process_test.c new file mode 100644 index 00000000..347903ab --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_packet_process_test.c @@ -0,0 +1,459 @@ +/* The DHCPREQUEST message MUST use the same value in the DHCP message header's 'secs' field and be sent to the same IP + * broadcast address as the original DHCPDISCOVER message. + * rfc 2131, page 16, 3.1 Client-server interaction - allocating a network address + */ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_UDP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT test_done = NX_FALSE; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, INT packet_number); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +typedef struct DHCP_RESPONSE_STRUCT +{ + UCHAR *dhcp_response_pkt_data; + UINT dhcp_response_pkt_size; +} DHCP_RESPONSE; + +static DHCP_RESPONSE dhcp_response[3]; + +/* Frame (342 bytes) */ +static unsigned char offer[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xb0, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Do...... */ +0x00, 0x00, 0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x36, 0x04, 0xc0, /* Sc5..6.. */ +0xa8, 0x02, 0x01, 0x33, 0x04, 0x00, 0x00, 0x1b, /* ...3.... */ +0xfe, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ........ */ +0x04, 0xc0, 0xa8, 0x02, 0x01, 0x06, 0x04, 0xc0, /* ........ */ +0xa8, 0x02, 0x01, 0x2a, 0x04, 0x7c, 0x6c, 0x14, /* ...*.|l. */ +0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_ntp_option_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i = 0; +UINT index; +NX_PACKET *my_packet; +UCHAR *option_ptr; +UINT option_size; + + printf("NetX Test: DHCP Client NTP Option test..............................."); + +#ifdef __PRODUCT_NETXDUO__ + /* Update the MAC address. */ + status = nx_ip_interface_physical_address_set(&server_ip, 0, 0x00000015, 0x5d021e0f, NX_TRUE); + + /* Check for errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +#else + server_ip.nx_ip_interface[0].nx_interface_physical_address_msw = 0x00000015; + server_ip.nx_ip_interface[0].nx_interface_physical_address_lsw = 0x5d021e0f; +#endif + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + dhcp_response[0].dhcp_response_pkt_data = (char*)offer; + dhcp_response[0].dhcp_response_pkt_size = sizeof(offer); + dhcp_response[1].dhcp_response_pkt_data = offer; + dhcp_response[1].dhcp_response_pkt_size = sizeof(offer); + dhcp_response[2].dhcp_response_pkt_data = offer; + dhcp_response[2].dhcp_response_pkt_size = sizeof(offer); + + /* Wait for Client requests (DISCOVER and REQEUST). */ + for (i = 0; i < 3; i++) + { + + /* Receive DHCP message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send response. */ + status = nx_dhcp_response_packet_send(&server_socket, i); + + switch (i) + { + case 0: + client_pool.nx_packet_pool_available = NX_FALSE; + break; + case 1: + client_pool.nx_packet_pool_available = NX_TRUE; + dhcp_client.nx_dhcp_ip_ptr->nx_ip_interface[0].nx_interface_physical_address_msw = 17; + dhcp_client.nx_dhcp_ip_ptr->nx_ip_interface[0].nx_interface_physical_address_lsw = 123456; + break; + case 2: + dhcp_client.nx_dhcp_ip_ptr->nx_ip_interface[0].nx_interface_physical_address_msw = 18; + break; + default: + break; + } + + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Wait for test done. */ + while(test_done == NX_FALSE) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i = 0; +ULONG ntp_server_address; +UINT ntp_server_address_size = 4; + +#ifdef __PRODUCT_NETXDUO__ + /* Update the MAC address. */ + status = nx_ip_interface_physical_address_set(&client_ip, 0, 0x00000011, 0x22334457, NX_TRUE); + + /* Check for errors. */ + if (status) + { + error_counter++; + } +#else + client_ip.nx_ip_interface[0].nx_interface_physical_address_msw = 0x00000011; + client_ip.nx_ip_interface[0].nx_interface_physical_address_lsw = 0x22334457; +#endif + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + { + error_counter++; + } + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Request NTP. */ + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_NTP_SVR); + if (status) + { + error_counter++; + } + + for (i = 0; i < 2; i++) + { + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + { + error_counter++; + } + + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + } + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + test_done = NX_TRUE; + + return; +} + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data + (14 + 20 + 8), + dhcp_response[packet_number].dhcp_response_pkt_size - (14 + 20 + 8)); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size - (14 + 20 + 8); + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Fake the transaction id. */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_xid = 0x2233446f; + + /* Send the packet. */ + status = nx_udp_socket_send(server_socket_ptr, response_packet, IP_ADDRESS(255, 255, 255, 255), NX_DHCP_CLIENT_UDP_PORT); + + /* Check the status. */ + if (status) + { + nx_packet_release(response_packet); + } + + return status; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_client_ntp_option_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DHCP Client NTP Option test...............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_reinitialize_test.c b/test/regression/dhcp_test/netx_dhcp_reinitialize_test.c new file mode 100644 index 00000000..631a8cff --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_reinitialize_test.c @@ -0,0 +1,425 @@ +/* The test in this file references the test in netx_dhcp_basic_test.c + The introduced difference by this file is to test the special case when the + gateway ip addressed is cleared before calling nx_dhcp_interface_reinitialize, + purposing to meet the 100% coverage for _nx_dhcp_interface_reinitialize +*/ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* If defined, the host requests a (previous) client IP address. */ +/* +#define REQUEST_CLIENT_IP +*/ + +/* If defined the client requests to jump to the boot state and skip the DISCOVER message. + If REQUEST_CLIENT_IP is not defined, this has no effect. */ +/* +#define SKIP_DISCOVER_MESSAGE +*/ + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_reinitialize_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Reinitialize Test..........................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +UINT length; + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) +static UINT packet_filter_extended(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT direction) +{ + if ((direction == NX_IP_PACKET_OUT) && + ((packet_ptr -> nx_packet_ip_header == NX_NULL) || + (packet_ptr -> nx_packet_ip_header_length == 0))) + { + error_counter++; + } + return(NX_SUCCESS); +} +#endif + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UCHAR buffer[4]; +UINT buffer_size = 4; +ULONG *long_ptr; + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +UINT skip_discover_message = NX_FALSE; +#endif + + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) + client_ip.nx_ip_packet_filter_extended = packet_filter_extended; +#endif + + /* Set the client IP if the host is configured to do so. */ +#ifdef REQUEST_CLIENT_IP + + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + +#endif + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Change the value to test the corner case for the static function _nx_dhcp_update_timeout */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_rtr_interval = 6500; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Get the DNS Server address. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DNS_SVR, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the DNS address. */ + if (*long_ptr != NX_DHCP_DNS_SERVER_0) + error_counter++; + } + else + { + error_counter++; + } + + /* Get the lease time value. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DHCP_LEASE, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the lease time value. */ + if (*long_ptr != NX_DHCP_DEFAULT_LEASE_TIME) + error_counter++; + } + else + { + error_counter++; + } + + length = sizeof(message); + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* Call function nx_ip_gateway_address_clear to test the special case when + the return status of nx_ip_gateway_address_get becomes not NX_SUCCESS*/ + tx_thread_sleep(NX_IP_PERIODIC_RATE); +#ifdef __PRODUCT_NETXDUO__ + nx_ip_gateway_address_clear(dhcp_client.nx_dhcp_ip_ptr); +#else + nx_ip_gateway_address_set(dhcp_client.nx_dhcp_ip_ptr, 0UL); +#endif + nx_dhcp_reinitialize(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + /* Increment state changes counter. */ + state_changes++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_reinitialize_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Reinitialize Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_release_test.c b/test/regression/dhcp_test/netx_dhcp_release_test.c new file mode 100644 index 00000000..544b4952 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_release_test.c @@ -0,0 +1,419 @@ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* If defined, the host requests a (previous) client IP address. */ +/* +#define REQUEST_CLIENT_IP +*/ + +/* If defined the client requests to jump to the boot state and skip the DISCOVER message. + If REQUEST_CLIENT_IP is not defined, this has no effect. */ +/* +#define SKIP_DISCOVER_MESSAGE +*/ + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_release_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +static void interface_state_change_cb(NX_DHCP *dhcp_ptr, UINT iface, UCHAR state) +{ + /* Change the state to test the corner case for _nx_dhcp_interface_release */ + dhcp_ptr->nx_dhcp_interface_record->nx_dhcp_state = NX_DHCP_STATE_FORCERENEW; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Release Test..........................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +UINT length; + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) +static UINT packet_filter_extended(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT direction) +{ + if ((direction == NX_IP_PACKET_OUT) && + ((packet_ptr -> nx_packet_ip_header == NX_NULL) || + (packet_ptr -> nx_packet_ip_header_length == 0))) + { + error_counter++; + } + return(NX_SUCCESS); +} +#endif + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UCHAR buffer[4]; +UINT buffer_size = 4; +ULONG *long_ptr; + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +UINT skip_discover_message = NX_FALSE; +#endif + + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) + client_ip.nx_ip_packet_filter_extended = packet_filter_extended; +#endif + + /* Set the client IP if the host is configured to do so. */ +#ifdef REQUEST_CLIENT_IP + + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + +#endif + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Get the DNS Server address. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DNS_SVR, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the DNS address. */ + if (*long_ptr != NX_DHCP_DNS_SERVER_0) + error_counter++; + } + else + { + error_counter++; + } + + /* Get the lease time value. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DHCP_LEASE, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the lease time value. */ + if (*long_ptr != NX_DHCP_DEFAULT_LEASE_TIME) + error_counter++; + } + else + { + error_counter++; + } + + length = sizeof(message); + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Test the corner case when the state is changed by the callback function */ + dhcp_client.nx_dhcp_interface_state_change_callback = interface_state_change_cb; + nx_dhcp_release(&dhcp_client); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + /* Increment state changes counter. */ + state_changes++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_release_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Release Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_send_request_internal_test.c b/test/regression/dhcp_test/netx_dhcp_send_request_internal_test.c new file mode 100644 index 00000000..1301b012 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_send_request_internal_test.c @@ -0,0 +1,615 @@ +/* The DHCPREQUEST message MUST use the same value in the DHCP message header's 'secs' field and be sent to the same IP + * broadcast address as the original DHCPDISCOVER message. + * rfc 2131, page 16, 3.1 Client-server interaction - allocating a network address + */ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_dhcp_clone_function.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_ipv4.h" +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +#define SERVER_RESPONSE_NUM 3 + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_UDP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +static UINT test_done = NX_FALSE; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, INT packet_number); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +typedef struct DHCP_RESPONSE_STRUCT +{ + UCHAR *dhcp_response_pkt_data; + UINT dhcp_response_pkt_size; +} DHCP_RESPONSE; + +static DHCP_RESPONSE dhcp_response[SERVER_RESPONSE_NUM]; + +/* Frame (342 bytes) */ +static unsigned char offer1[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xb0, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, /* ........ */ +0xc0, 0xa8, 0x02, 0xc5, /* ciaddr */ +0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x36, 0x04, 0xa8, /* Sc5..6.. */ +0x02, 0x01, 0x05, 0x33, 0x04, 0x00, 0x00, 0x1b, /* ...3.... */ +0xfe, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ........ */ +0x04, 0xa8, 0x02, 0x01, 0x02, 0x3a, 0x04, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x3b, 0x04, 0x00, 0x00, 0x01, /* ...*.|l. */ +0x02, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static unsigned char offer2[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ].....E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* v....... */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xb0, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, /* ........ */ +0xc0, 0xa8, 0x02, 0xc5, /* ciaddr */ +0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* "3DW.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x36, 0x04, 0xa8, /* Sc5..6.. */ +0x02, 0x01, 0x05, 0x33, 0x04, 0x00, 0x00, 0x1b, /* ...3.... */ +0xfe, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ........ */ +0x04, 0xa8, 0x02, 0x01, 0x02, 0x06, 0x04, 0xc0, /* ........ */ +0xa8, 0x02, 0x01, 0x2a, 0x04, 0x7c, 0x6c, 0x14, /* ...*.|l. */ +0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static unsigned char ack[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x15, /* ........ */ +0x5d, 0x02, 0x1e, 0x0f, 0x08, 0x00, 0x45, 0x10, /* ........ */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* ........ */ +0x76, 0xec, 0xc0, 0xa8, 0x02, 0x01, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ........ */ +0xad, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* ........ */ +0x44, 0x6f, 0x00, 0x00, 0x80, 0x00, /* ........ */ +0xc0, 0xa8, 0x02, 0xc5, /* ciaddr */ +0xc0, 0xa8, 0x02, 0xc5, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x36, 0x04, 0xff, /* Sc5..6.. */ +0xff, 0xff, 0xff, 0x33, 0x04, 0x00, 0x00, 0x1b, /* ...3.... */ +0xfe, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ........ */ +0x04, 0xff, 0xff, 0xff, 0x00, 0x06, 0x04, 0xc0, /* ........ */ +0xa8, 0x02, 0x01, 0x2a, 0x04, 0x7c, 0x6c, 0x14, /* ...*.|l. */ +0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_send_request_internal_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i = 0; +UINT index; +NX_PACKET *my_packet; +UCHAR *option_ptr; +UINT option_size; + + printf("NetX Test: DHCP send request internal test..............................."); + +#ifdef __PRODUCT_NETXDUO__ + /* Update the MAC address. */ + status = nx_ip_interface_physical_address_set(&server_ip, 0, 0x00000015, 0x5d021e0f, NX_TRUE); + + /* Check for errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +#else + server_ip.nx_ip_interface[0].nx_interface_physical_address_msw = 0x00000015; + server_ip.nx_ip_interface[0].nx_interface_physical_address_lsw = 0x5d021e0f; +#endif + + /* Create a socket as the server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&server_socket, NX_DHCP_SERVER_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + dhcp_response[0].dhcp_response_pkt_data = (char*)offer1; + dhcp_response[0].dhcp_response_pkt_size = sizeof(offer1); + dhcp_response[1].dhcp_response_pkt_data = (char*)offer2; + dhcp_response[1].dhcp_response_pkt_size = sizeof(offer2); + dhcp_response[2].dhcp_response_pkt_data = ack; + dhcp_response[2].dhcp_response_pkt_size = sizeof(ack); + + /* Wait for Client requests (DISCOVER and REQEUST). */ + for (i = 0; i < SERVER_RESPONSE_NUM; i++) + { + + /* Receive DHCP message. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 1000); + + /* Check status. */ + if (status) + { + // printf("ERROR!\n"); + // test_control_return(1); + } + else + { + + /* Check if there is NTP in parameter request list. */ + option_ptr = dhcp_search_buffer(my_packet -> nx_packet_prepend_ptr, NX_DHCP_OPTION_DHCP_PARAMETERS, my_packet -> nx_packet_length); + + /* Check if found the parameter request option. */ + if (option_ptr == NX_NULL) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + option_size = (UINT)*option_ptr; + option_ptr++; + + /* Check if there is NTP. */ + for (index = 0; index < option_size; index ++) + { + if (*(option_ptr + index) == NX_DHCP_OPTION_NTP_SVR) + { + break; + } + } + + if (index >= option_size) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send response. */ + status = nx_dhcp_response_packet_send(&server_socket, i); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + } + + /* Wait for test done. */ + while(test_done == NX_FALSE) + { + tx_thread_sleep(100); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +ULONG ntp_server_address; +UINT ntp_server_address_size = 4; + +#ifdef __PRODUCT_NETXDUO__ + /* Update the MAC address. */ + status = nx_ip_interface_physical_address_set(&client_ip, 0, 0x00000011, 0x22334457, NX_TRUE); + + /* Check for errors. */ + if (status) + { + error_counter++; + } +#else + client_ip.nx_ip_interface[0].nx_interface_physical_address_msw = 0x00000011; + client_ip.nx_ip_interface[0].nx_interface_physical_address_lsw = 0x22334457; +#endif + + /* Create the DHCP instance. for the test with NULL dhcp name */ + status = nx_dhcp_create(&dhcp_client, &client_ip, NULL); + if (status) + { + error_counter++; + } + + /* Set the ip address to NX_BOOTP_BC_ADDRESS to test the corner case */ + dhcp_client.nx_dhcp_interface_record->nx_dhcp_ip_address = NX_BOOTP_BC_ADDRESS; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Request NTP. */ + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_NTP_SVR); + if (status) + { + error_counter++; + } + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + { + error_counter++; + } + + tx_thread_sleep(500); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + /* Create the DHCP instance. for the test with a normal short name */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "Short DHCP Name"); + if (status) + { + error_counter++; + } + + /* Set the ip address to NX_BOOTP_BC_ADDRESS to test the corner case */ + dhcp_client.nx_dhcp_interface_record->nx_dhcp_ip_address = NX_BOOTP_BC_ADDRESS; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Request NTP. */ + status = nx_dhcp_user_option_request(&dhcp_client, NX_DHCP_OPTION_NTP_SVR); + if (status) + { + error_counter++; + } + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + { + error_counter++; + } + + tx_thread_sleep(500); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + test_done = NX_TRUE; + + return; +} + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *server_socket_ptr, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, dhcp_response[packet_number].dhcp_response_pkt_data + (14 + 20 + 8), + dhcp_response[packet_number].dhcp_response_pkt_size - (14 + 20 + 8)); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dhcp_response[packet_number].dhcp_response_pkt_size - (14 + 20 + 8); + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Fake the transaction id. */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_xid = 0x2233446f; + + /* Send the packet. */ + status = nx_udp_socket_send(server_socket_ptr, response_packet, IP_ADDRESS(255, 255, 255, 255), NX_DHCP_CLIENT_UDP_PORT); + + /* Check the status. */ + if (status) + { + nx_packet_release(response_packet); + } + + return status; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_send_request_internal_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DHCP send request internal test...............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_server_improper_term_test.c b/test/regression/dhcp_test/netx_dhcp_server_improper_term_test.c new file mode 100644 index 00000000..53d0bcd2 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_server_improper_term_test.c @@ -0,0 +1,518 @@ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,2) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,5) + + +typedef struct DHCP_TEST_STRUCT +{ + char *dhcp_test_pkt_data; + int dhcp_test_pkt_size; +} DHCP_TEST; + +#define CLIENT_MSG_COUNT 2 +static DHCP_TEST dhcp_test[CLIENT_MSG_COUNT]; +UINT client_complete = NX_FALSE; + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; +static NX_UDP_SOCKET client_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *client_socket, UINT packet_number); +static void dhcp_test_initialize(); + +/* Frame (366 bytes) */ +static char discover[366] = { +0x01, 0x01, /* .C.4.... */ +0x06, 0x00, 0x42, 0x2a, 0x4c, 0xf5, 0x00, 0x00, /* ..B*L... */ +0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x80, 0x86, 0xf2, 0x83, 0x15, 0xd5, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, /* ..c.Sc5. */ +0x01, 0x3d, 0x07, 0x01, 0x80, 0x86, 0xf2, 0x83, /* .=...... */ +0x15, 0xd5, 0x0c, 0x06, 0x57, 0x59, 0x2d, 0x50, /* ....WY-P */ +0x53, 0x54, 0x3c, 0x08, 0x4d, 0x53, 0x46, 0x54, /* ST<.MSFT */ +0x20, 0x35, 0x2e, 0x30, 0x37, 0x0c, 0x01, 0x0f, /* 5.07... */ +0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, 0x21, 0x79, /* ..,./.!y */ +0xf9, 0x2b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, /* .+...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static int discover_size = 304; + +/* Frame (385 bytes) */ +static char request[385] = { +0x01, 0x01, /* .C.GO... */ +0x06, 0x00, 0x42, 0x2a, 0x4c, 0xf5, 0x04, 0x00, /* ..B*L... */ +0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x80, 0x86, 0xf2, 0x83, 0x15, 0xd5, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, /* ..c.Sc5. */ +0x03, 0x3d, 0x07, 0x01, 0x80, 0x86, 0xf2, 0x83, /* .=...... */ +0x15, 0xd5, 0x32, 0x04, 0x0a, 0x00, 0x00, 0x02, /* ..2..... */ +0x36, 0x04, 0x0a, 0x00, 0x00, 0x01, 0x0c, 0x06, /* 6....... */ +0x57, 0x59, 0x2d, 0x50, 0x53, 0x54, 0x51, 0x14, /* WY-PSTQ. */ +0x00, 0x00, 0x00, 0x57, 0x59, 0x2d, 0x50, 0x53, /* ...WY-PS */ +0x54, 0x2e, 0x66, 0x63, 0x69, 0x2e, 0x73, 0x6d, /* T.fci.sm */ +0x69, 0x2e, 0x61, 0x64, 0x3c, 0x08, 0x4d, 0x53, /* i.ad<.MS */ +0x46, 0x54, 0x20, 0x35, 0x2e, 0x30, 0x37, 0x0c, /* FT 5.07. */ +0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, /* ....,./. */ +0x21, 0x79, 0xf9, 0x2b, 0x00, 0x00, 0x00, 0x01, /* !y.+.... */ +0x00 /* . */ +}; + +static int request_size = 323; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_server_improper_term_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, + _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, + _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Server Improper Termination Test....................."); + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 4) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + while(!client_complete) + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Check that the server did not receive a valid request */ + if (dhcp_server.nx_dhcp_requests_received > 0) + { + error_counter++; + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + + +/* This thread task simulates DHCP Client sending requests. */ +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT i; +ULONG actual_status; +UINT status; + + + /* Check for earlier errors. */ + if(error_counter) + { + client_complete = NX_TRUE; + return; + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 4 seconds to finish DAD. */ + tx_thread_sleep(4 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Load up the Client messages. */ + dhcp_test_initialize(); + + status = nx_udp_socket_create(&client_ip, &client_socket, "Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&client_socket, 68, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Act as the DHCP Client to send DHCP discover and request packets. */ + for (i = 0; i < CLIENT_MSG_COUNT; i++ ) + { + + /* Send the DHCP client packet. */ + status = nx_dhcp_response_packet_send(&client_socket, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&client_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + if (i == 1) + { + + /* This is correct. The Client should not get a message because the server rejected the request packet. */ + } + else /* i == 0*/ + { + /* There should be a response to the discovery message, so this is an error. */ + error_counter++; + continue; + } + + } + else + { + nx_packet_release(my_packet); + } + + } + + status = nx_udp_socket_unbind(&client_socket); + + /* Delete the UDP socket. */ + status |= nx_udp_socket_delete(&client_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + client_complete = NX_TRUE; +} + + +static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *client_socket, UINT packet_number) +{ + +UINT status; +NX_PACKET *client_packet; + + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&client_pool, &client_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return status; + } + + memset(client_packet -> nx_packet_prepend_ptr, 0, (client_packet -> nx_packet_data_end - client_packet -> nx_packet_prepend_ptr)); + + /* Write the DHCP Client messages into the packet payload! */ + memcpy(client_packet -> nx_packet_prepend_ptr, + dhcp_test[packet_number].dhcp_test_pkt_data, + dhcp_test[packet_number].dhcp_test_pkt_size); + + /* Adjust the write pointer. */ + client_packet -> nx_packet_length = dhcp_test[packet_number].dhcp_test_pkt_size; + client_packet -> nx_packet_append_ptr = client_packet -> nx_packet_prepend_ptr + client_packet -> nx_packet_length; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(client_socket, client_packet, IP_ADDRESS(255,255,255,255), 67); + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(client_packet); + } + + return status; +} + +static void dhcp_test_initialize() +{ + dhcp_test[0].dhcp_test_pkt_data = &discover[0]; + dhcp_test[0].dhcp_test_pkt_size = discover_size; + dhcp_test[1].dhcp_test_pkt_data = &request[0]; + dhcp_test[1].dhcp_test_pkt_size = request_size; + + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_server_improper_term_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Server Improper Termination Test................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_server_options_test.c b/test/regression/dhcp_test/netx_dhcp_server_options_test.c new file mode 100644 index 00000000..fbd510be --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_server_options_test.c @@ -0,0 +1,391 @@ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_DISABLE_UDP_RX_CHECKSUM) +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(192, 168, 3, 8) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(192, 168, 3, 11) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(192, 168, 3,20) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(192, 168, 3, 8) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(192, 168, 3, 8) + +/* Define the ThreadX and NetX object control blocks... */ +static NX_PACKET_POOL client_pool; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG resposner_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + + + +/* Frame (342 bytes) DHCP DISCOVER Read overflow. */ +static const unsigned char pkt1[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x08, 0x00, 0x45, 0x00, /* ...i..E. */ +0x01, 0x48, 0x00, 0x01, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x39, 0xa5, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* 9....... */ +0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, /* ...D.C.4 */ +0x83, 0x9e, 0x01, 0x01, 0x06, 0x00, 0x00, 0xf6, /* ........ */ +0x16, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x00, 0x00, 0x00, 0x00, /* ...i.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x37, 0x3c, 0x00, 0x00, 0x00, 0x00, /* Sc5..=.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .P...i.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* CW-9WDPJ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* V1-GA1<. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MSFT 5.0 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 7.....,. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* /.!y.+.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Frame (342 bytes) DHCP DISCOVER Write overflow. */ +static const unsigned char pkt2[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x08, 0x00, 0x45, 0x00, /* ...i..E. */ +0x01, 0x48, 0x00, 0x01, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x39, 0xa5, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* 9....... */ +0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, /* ...D.C.4 */ +0x83, 0x9e, 0x01, 0x01, 0x06, 0x00, 0x00, 0xf6, /* ........ */ +0x16, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x00, 0x00, 0x00, 0x00, /* ...i.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x37, 0x14, 0x35, 0x35, 0x35, 0x35, /* Sc5..=.. */ +0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, /* .P...i.. */ +0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, /* CW-9WDPJ */ +0x56, 0x31, 0x2d, 0x47, 0x41, 0x31, 0x3c, 0x08, /* V1-GA1<. */ +0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30, /* MSFT 5.0 */ +0x37, 0x0c, 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e, /* 7.....,. */ +0x2f, 0x1f, 0x21, 0x79, 0xf9, 0x2b, 0xff, 0x00, /* /.!y.+.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) DHCP DISCOVER Endless loop. */ +static const unsigned char pkt3[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x08, 0x00, 0x45, 0x00, /* ...i..E. */ +0x01, 0x48, 0x00, 0x01, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x39, 0xa5, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* 9....... */ +0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, /* ...D.C.4 */ +0x83, 0x9e, 0x01, 0x01, 0x06, 0x00, 0x00, 0xf6, /* ........ */ +0x16, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x00, 0x00, 0x00, 0x00, /* ...i.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x37, 0x01, 0x37, 0x3d, 0x07, 0x01, /* Sc5..=.. */ +0x00, 0x50, 0xb6, 0x07, 0xa1, 0x69, 0x0c, 0x0e, /* .P...i.. */ +0x43, 0x57, 0x2d, 0x39, 0x57, 0x44, 0x50, 0x4a, /* CW-9WDPJ */ +0x56, 0x31, 0x2d, 0x47, 0x41, 0x31, 0x3c, 0x08, /* V1-GA1<. */ +0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30, /* MSFT 5.0 */ +0x37, 0x0c, 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e, /* 7.....,. */ +0x2f, 0x1f, 0x21, 0x79, 0xf9, 0x2b, 0xff, 0x00, /* /.!y.+.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static const UCHAR *test_packet[] = {pkt1, pkt2, pkt3}; +static UINT test_packet_size[] = {sizeof(pkt1), sizeof(pkt2), sizeof(pkt3)}; +static UINT test_count = sizeof(test_packet_size) / sizeof(UINT); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_server_options_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + memset(pointer, 53, NX_PACKET_POOL_SIZE); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; +NX_PACKET *my_packet; +UINT i; + + printf("NetX Test: DHCP Server Options Test.................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + for (i = 0; i < test_count; i++) + { + /* Send the DHCP DISCOVER packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if (status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet->nx_packet_prepend_ptr, &test_packet[i][14], test_packet_size[i] - 14); + my_packet->nx_packet_length = test_packet_size[i] - 14; + my_packet->nx_packet_append_ptr = my_packet->nx_packet_prepend_ptr + test_packet_size[i] - 14; + + /* Directly receive the DHCP DISCOVER packet. */ + _nx_ip_packet_deferred_receive(&server_ip, my_packet); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + if ((i == 0) && (dhcp_server.client_records[0].nx_dhcp_client_option_count)) + { + error_counter++; + } + + if ((i == 1) && (dhcp_server.client_records[1].nx_dhcp_client_state == 53)) + { + error_counter++; + } + + nx_dhcp_clear_client_record(&dhcp_server, &(dhcp_server.client_records[0])); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_server_options_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: DHCP Server Options Test..................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_server_second_interface_test.c b/test/regression/dhcp_test/netx_dhcp_server_second_interface_test.c new file mode 100644 index 00000000..e57740ef --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_server_second_interface_test.c @@ -0,0 +1,552 @@ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) && (NX_MAX_PHYSICAL_INTERFACES >= 2) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(1,0,0,1) +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) + +#define NX_DHCP_SERVER_IP_ADDRESS_1 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_1 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_1 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_1 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_1 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_1 IP_ADDRESS(10,0,0,1) + +#define NX_DHCP_INTERFACE_INDEX 1 + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; +static CHAR offer_packet = NX_FALSE; +static CHAR ack_packet = NX_FALSE; +static CHAR test_done = NX_FALSE; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Note that the MAC address of Client is 00:11:22:33:44:56. + the MAC address of Server is 00:11:22:33:44:57. */ + +/* Frame (342 bytes) */ +static const unsigned char pkt1[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x01, 0x48, 0x00, 0x01, 0x40, 0x00, 0x80, 0x11, /* .H..@... */ +0xf9, 0xa4, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, /* ...D.C.4 */ +0x59, 0x2a, 0x01, 0x01, 0x06, 0x00, 0x22, 0x33, /* Y*...."3 */ +0x44, 0x6e, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Dn...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x00, 0x00, 0x00, 0x00, /* "3DV.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x01, 0x33, 0x04, 0xff, /* Sc5..3.. */ +0xff, 0xff, 0xff, 0x0c, 0x0b, 0x64, 0x68, 0x63, /* .....dhc */ +0x70, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, /* p_client */ +0x37, 0x03, 0x01, 0x03, 0x06, 0xff, 0x00, 0x00, /* 7....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static const unsigned char pkt2[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x48, 0x00, 0x01, 0x40, 0x00, 0x80, 0x11, /* .H..@... */ +0xef, 0xa3, 0x0a, 0x00, 0x00, 0x01, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xbd, 0x6f, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .o...."3 */ +0x44, 0x6e, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Dn...... */ +0x00, 0x00, 0x0a, 0x00, 0x00, 0x0a, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x00, 0x00, 0x00, 0x00, /* "3DV.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x36, 0x04, 0x0a, /* Sc5..6.. */ +0x00, 0x00, 0x01, 0x01, 0x04, 0xff, 0xff, 0xff, /* ........ */ +0x00, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x01, 0x06, /* ........ */ +0x04, 0x0a, 0x00, 0x00, 0x01, 0x33, 0x04, 0x00, /* .....3.. */ +0x00, 0x27, 0x10, 0x3a, 0x04, 0x00, 0x00, 0x13, /* .'.:.... */ +0x88, 0x3b, 0x04, 0x00, 0x00, 0x22, 0x2e, 0xff, /* .;...".. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static const unsigned char pkt3[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x01, 0x48, 0x00, 0x02, 0x40, 0x00, 0x80, 0x11, /* .H..@... */ +0xf9, 0xa3, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, /* ...D.C.4 */ +0xdf, 0x49, 0x01, 0x01, 0x06, 0x00, 0x22, 0x33, /* .I...."3 */ +0x44, 0x6e, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Dn...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x00, 0x00, 0x00, 0x00, /* "3DV.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x03, 0x0c, 0x0b, 0x64, /* Sc5....d */ +0x68, 0x63, 0x70, 0x5f, 0x63, 0x6c, 0x69, 0x65, /* hcp_clie */ +0x6e, 0x74, 0x32, 0x04, 0x0a, 0x00, 0x00, 0x0a, /* nt2..... */ +0x36, 0x04, 0x0a, 0x00, 0x00, 0x01, 0x37, 0x03, /* 6.....7. */ +0x01, 0x03, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static const unsigned char pkt4[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x48, 0x00, 0x02, 0x40, 0x00, 0x80, 0x11, /* .H..@... */ +0xef, 0xa2, 0x0a, 0x00, 0x00, 0x01, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xba, 0x6f, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .o...."3 */ +0x44, 0x6e, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* Dn...... */ +0x00, 0x00, 0x0a, 0x00, 0x00, 0x0a, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x00, 0x00, 0x00, 0x00, /* "3DV.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x36, 0x04, 0x0a, /* Sc5..6.. */ +0x00, 0x00, 0x01, 0x01, 0x04, 0xff, 0xff, 0xff, /* ........ */ +0x00, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x01, 0x06, /* ........ */ +0x04, 0x0a, 0x00, 0x00, 0x01, 0x33, 0x04, 0x00, /* .....3.. */ +0x00, 0x27, 0x10, 0x3a, 0x04, 0x00, 0x00, 0x13, /* .'.:.... */ +0x88, 0x3b, 0x04, 0x00, 0x00, 0x22, 0x2e, 0xff, /* .;...".. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_server_second_interface_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, NX_DHCP_SUBNET_MASK_0, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Attach the second interface. */ + status = nx_ip_interface_attach(&server_ip, "DHCP Server Secondary Interface", NX_DHCP_SERVER_IP_ADDRESS_1, NX_DHCP_SUBNET_MASK_1, _nx_ram_network_driver_1500); + + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT addresses_added; + + NX_PARAMETER_NOT_USED(thread_input); + + printf("NetX Test: NetX DHCP Server Second Interface Test...................."); + + advanced_packet_process_callback = my_packet_process; + +#ifdef __PRODUCT_NETXDUO__ + /* Update the MAC address. */ + status = nx_ip_interface_physical_address_set(&server_ip, 0, 0x00000011, 0x22334455, NX_TRUE); + status += nx_ip_interface_physical_address_set(&server_ip, 1, 0x00000011, 0x22334457, NX_TRUE); + + /* Check for errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +#else + server_ip.nx_ip_interface[0].nx_interface_physical_address_msw = 0x00000011; + server_ip.nx_ip_interface[0].nx_interface_physical_address_lsw = 0x22334455; + + server_ip.nx_ip_interface[1].nx_interface_physical_address_msw = 0x00000011; + server_ip.nx_ip_interface[1].nx_interface_physical_address_lsw = 0x22334457; + +#endif + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Load the assignable DHCP IP addresses. */ + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, NX_DHCP_INTERFACE_INDEX, START_IP_ADDRESS_LIST_1, + END_IP_ADDRESS_LIST_1, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, NX_DHCP_INTERFACE_INDEX, NX_DHCP_SUBNET_MASK_1, + NX_DHCP_DEFAULT_GATEWAY_1, NX_DHCP_DNS_SERVER_1); + + /* Check for errors setting network parameters. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if ((error_counter != 0) || (offer_packet != NX_TRUE) || (ack_packet != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *discover_packet; + + NX_PARAMETER_NOT_USED(thread_input); + + /* Allocate a Discover packet. */ + status = nx_packet_allocate(&server_pool, &discover_packet, NX_UDP_PACKET, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Append the data. */ + status = nx_packet_data_append(discover_packet, (void *)&pkt1[14], (sizeof(pkt1) - 14), &server_pool, NX_NO_WAIT); + + if (status) + { + error_counter++; + } + + /* Set the interface. */ + discover_packet -> nx_packet_ip_interface = &server_ip.nx_ip_interface[1]; + + /* Call API to receive the packet. */ + _nx_ip_packet_receive(&server_ip, discover_packet); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +NX_PACKET *request_packet; + + NX_PARAMETER_NOT_USED(ip_ptr); + NX_PARAMETER_NOT_USED(operation_ptr); + NX_PARAMETER_NOT_USED(delay_ptr); + + /* Check the packet interface. */ + if (packet_ptr -> nx_packet_ip_interface == &server_ip.nx_ip_interface[1]) + { + + /* Check the offer_packet flag. */ + if (offer_packet == NX_FALSE) + { + + /* Compare the packet. */ + if ((packet_ptr -> nx_packet_length == sizeof(pkt2) - 14) && + (memcmp(packet_ptr -> nx_packet_prepend_ptr, &pkt2[14], packet_ptr -> nx_packet_length) == 0)) + { + offer_packet = NX_TRUE; + + /* Allocate a Request packet. */ + status = nx_packet_allocate(&server_pool, &request_packet, NX_UDP_PACKET, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Append the data. */ + status = nx_packet_data_append(request_packet, (void *)&pkt3[14], sizeof(pkt3) - 14, &server_pool, NX_NO_WAIT); + + if (status) + { + error_counter++; + } + + /* Set the interface. */ + request_packet -> nx_packet_ip_interface = &server_ip.nx_ip_interface[1]; + + /* Call API to receive the packet. */ + _nx_ip_packet_receive(&server_ip, request_packet); + } + } + else + { + + /* Compare the packet. */ + if ((packet_ptr -> nx_packet_length == sizeof(pkt4) - 14) && + (memcmp(packet_ptr -> nx_packet_prepend_ptr, &pkt4[14], packet_ptr -> nx_packet_length) == 0)) + { + ack_packet = NX_TRUE; + } + } + } + + nx_packet_release(packet_ptr); + return NX_FALSE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_server_second_interface_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Server Second Interface Test....................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_server_small_packet_payload_test.c b/test/regression/dhcp_test/netx_dhcp_server_small_packet_payload_test.c new file mode 100644 index 00000000..cda5e1ee --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_server_small_packet_payload_test.c @@ -0,0 +1,327 @@ +/* In _nx_dhcp_server_packet_process(), the orginal logic is to check the incoming packet length, update the incoming packet length, then copy the incomping packet data. + It will casue out of bound write. */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 +#define NX_SERVER_PACKET_SIZE NX_DHCP_MINIMUM_PACKET_PAYLOAD +#define NX_SERVER_PACKET_POOL_SIZE ((NX_DHCP_MINIMUM_PACKET_PAYLOAD + sizeof(NX_PACKET)) * 2) + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* If defined, the host requests a (previous) client IP address. */ +/* +#define REQUEST_CLIENT_IP +*/ + +/* If defined the client requests to jump to the boot state and skip the DISCOVER message. + If REQUEST_CLIENT_IP is not defined, this has no effect. */ +/* +#define SKIP_DISCOVER_MESSAGE +*/ + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static ULONG server_pool_stack[NX_SERVER_PACKET_POOL_SIZE / sizeof(ULONG)]; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); +static UINT dhcp_user_option_add(NX_DHCP *dhcp_ptr, UINT iface_index, UINT message_type, UCHAR *user_option_ptr, UINT *user_option_length); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_server_small_packet_payload_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", NX_SERVER_PACKET_SIZE, (UCHAR *)server_pool_stack, sizeof(server_pool_stack)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Server Small Packet Payload.........................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + /* Let's DHCP server receive one packet packet. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check if the memory of server ip is over overwritten. */ + if ((server_ip.nx_ip_id != NX_IP_ID)) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + /* Set callback function to add user options. */ + status = nx_dhcp_user_option_add_callback_set(&dhcp_client, dhcp_user_option_add); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Let's DHCP client send one packet. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + +/* In DHCP client, data size is 267, then fill in more data: NX_BOOT_BUFFER_SIZE - 267 - 1 (END Option) */ +UINT dhcp_user_option_add(NX_DHCP *dhcp_ptr, UINT iface_index, UINT message_type, UCHAR *user_option_ptr, UINT *user_option_length) +{ + + /* Update the option length. */ + *user_option_length = NX_BOOT_BUFFER_SIZE - 267 - 1; + return(NX_TRUE); +} + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + /* Increment state changes counter. */ + state_changes++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_server_small_packet_payload_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DHCP Server Small Packet Payload..........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_server_test.c b/test/regression/dhcp_test/netx_dhcp_server_test.c new file mode 100644 index 00000000..e8aecf6e --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_server_test.c @@ -0,0 +1,525 @@ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_UDP_TX_CHECKSUM) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(192, 168, 3, 8) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(192, 168, 3, 11) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(192, 168, 3,20) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(192, 168, 3, 8) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(192, 168, 3, 8) + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG resposner_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Frame (342 bytes) DHCP DISCOVER */ +static const unsigned char pkt1[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x08, 0x00, 0x45, 0x00, /* ...i..E. */ +0x01, 0x48, 0x00, 0x01, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x39, 0xa5, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* 9....... */ +0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, /* ...D.C.4 */ +0x83, 0x9e, 0x01, 0x01, 0x06, 0x00, 0x00, 0xf6, /* ........ */ +0x16, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x00, 0x00, 0x00, 0x00, /* ...i.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x01, 0x3d, 0x07, 0x01, /* Sc5..=.. */ +0x00, 0x50, 0xb6, 0x07, 0xa1, 0x69, 0x0c, 0x0e, /* .P...i.. */ +0x43, 0x57, 0x2d, 0x39, 0x57, 0x44, 0x50, 0x4a, /* CW-9WDPJ */ +0x56, 0x31, 0x2d, 0x47, 0x41, 0x31, 0x3c, 0x08, /* V1-GA1<. */ +0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30, /* MSFT 5.0 */ +0x37, 0x0c, 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e, /* 7.....,. */ +0x2f, 0x1f, 0x21, 0x79, 0xf9, 0x2b, 0xff, 0x00, /* /.!y.+.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) DHCP OFFER */ +static const unsigned char pkt2[342] = { +0x00, 0x50, 0xb6, 0x07, 0xa1, 0x69, 0x00, 0x08, /* .P...i.. */ +0xee, 0x03, 0x6a, 0xc6, 0x08, 0x00, 0x45, 0x00, /* ..j...E. */ +0x01, 0x48, 0x00, 0x01, 0x40, 0x00, 0x80, 0x11, /* .H..@... */ +0x72, 0x40, 0xc0, 0xa8, 0x03, 0x08, 0xc0, 0xa8, /* r@...... */ +0x03, 0x0b, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0x54, 0xf8, 0x02, 0x01, 0x06, 0x00, 0x00, 0xf6, /* T....... */ +0x16, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0xa8, 0x03, 0x0b, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x00, 0x00, 0x00, 0x00, /* ...i.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x36, 0x04, 0xc0, /* Sc5..6.. */ +0xa8, 0x03, 0x08, 0x01, 0x04, 0xff, 0xff, 0xff, /* ........ */ +0x00, 0x03, 0x04, 0xc0, 0xa8, 0x03, 0x08, 0x06, /* ........ */ +0x04, 0xc0, 0xa8, 0x03, 0x08, 0x33, 0x04, 0x00, /* .....3.. */ +0x00, 0x27, 0x10, 0x3a, 0x04, 0x00, 0x00, 0x13, /* .'.:.... */ +0x88, 0x3b, 0x04, 0x00, 0x00, 0x22, 0x2e, 0xff, /* .;...".. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (379 bytes) DHCP REQUEST */ +static const unsigned char pkt3[379] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x08, 0x00, 0x45, 0x00, /* ...i..E. */ +0x01, 0x6d, 0x00, 0x02, 0x00, 0x00, 0x80, 0x11, /* .m...... */ +0x39, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* 9....... */ +0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x59, /* ...D.C.Y */ +0x4d, 0x72, 0x01, 0x01, 0x06, 0x00, 0x00, 0xf6, /* Mr...... */ +0x16, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x00, 0x00, 0x00, 0x00, /* ...i.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x03, 0x3d, 0x07, 0x01, /* Sc5..=.. */ +0x00, 0x50, 0xb6, 0x07, 0xa1, 0x69, 0x32, 0x04, /* .P...i2. */ +0xc0, 0xa8, 0x03, 0x0b, 0x36, 0x04, 0xc0, 0xa8, /* ....6... */ +0x03, 0x08, 0x0c, 0x0e, 0x43, 0x57, 0x2d, 0x39, /* ....CW-9 */ +0x57, 0x44, 0x50, 0x4a, 0x56, 0x31, 0x2d, 0x47, /* WDPJV1-G */ +0x41, 0x31, 0x51, 0x1e, 0x00, 0x00, 0x00, 0x43, /* A1Q....C */ +0x57, 0x2d, 0x39, 0x57, 0x44, 0x50, 0x4a, 0x56, /* W-9WDPJV */ +0x31, 0x2d, 0x47, 0x41, 0x31, 0x2e, 0x54, 0x54, /* 1-GA1.TT */ +0x50, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2e, 0x63, /* PGroup.c */ +0x6f, 0x6d, 0x3c, 0x08, 0x4d, 0x53, 0x46, 0x54, /* om<.MSFT */ +0x20, 0x35, 0x2e, 0x30, 0x37, 0x0c, 0x01, 0x0f, /* 5.07... */ +0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, 0x21, 0x79, /* ..,./.!y */ +0xf9, 0x2b, 0xff /* .+. */ +}; + +/* Frame (342 bytes) DHCP ACK */ +static const unsigned char pkt4[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x08, /* ........ */ +0xee, 0x03, 0x6a, 0xc6, 0x08, 0x00, 0x45, 0x00, /* ..j...E. */ +0x01, 0x48, 0x00, 0x02, 0x40, 0x00, 0x80, 0x11, /* .H..@... */ +0x72, 0x3f, 0xc0, 0xa8, 0x03, 0x08, 0xc0, 0xa8, /* r?...... */ +0x03, 0x0b, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0x51, 0xf8, 0x02, 0x01, 0x06, 0x00, 0x00, 0xf6, /* Q....... */ +0x16, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0xa8, 0x03, 0x0b, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0xb6, 0x07, 0xa1, 0x69, 0x00, 0x00, 0x00, 0x00, /* ...i.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x36, 0x04, 0xc0, /* Sc5..6.. */ +0xa8, 0x03, 0x08, 0x01, 0x04, 0xff, 0xff, 0xff, /* ........ */ +0x00, 0x03, 0x04, 0xc0, 0xa8, 0x03, 0x08, 0x06, /* ........ */ +0x04, 0xc0, 0xa8, 0x03, 0x08, 0x33, 0x04, 0x00, /* .....3.. */ +0x00, 0x27, 0x10, 0x3a, 0x04, 0x00, 0x00, 0x13, /* .'.:.... */ +0x88, 0x3b, 0x04, 0x00, 0x00, 0x22, 0x2e, 0xff, /* .;...".. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_server_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Server Test.........................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if ((error_counter) || (resposner_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Send the DHCP DISCOVER packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Set the callback function to process the DHCP Message packet. */ + advanced_packet_process_callback = my_packet_process; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + my_packet -> nx_packet_length = sizeof(pkt1) - 14; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + sizeof(pkt1) - 14; + + /* Directly receive the DHCP DISCOVER packet. */ + _nx_ip_packet_deferred_receive(&server_ip, my_packet); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +NX_PACKET *my_packet; + + if ((ip_ptr == &server_ip) && (packet_ptr ->nx_packet_length >= 300)) + { + + resposner_counter ++; + + if (resposner_counter == 1) + { + + /* Check the DHCP OFFER. */ +#ifdef NX_ENABLE_IP_ID_RANDOMIZATION + /* Skip IP id when it is random. */ + if (memcmp(packet_ptr ->nx_packet_prepend_ptr, &pkt2[14], 4) || + memcmp(packet_ptr ->nx_packet_prepend_ptr + 6, &pkt2[20], 4) || + memcmp(packet_ptr ->nx_packet_prepend_ptr + 12, &pkt2[26], sizeof(pkt2) - 26)) +#else + if (memcmp(packet_ptr ->nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) -14)) +#endif + error_counter ++; + + /* Send the DHCP REQUEST. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt3[14], sizeof(pkt3) - 14); + my_packet -> nx_packet_length = sizeof(pkt3) - 14; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + sizeof(pkt3) - 14; + + /* Directly receive the DHCP REQUEST packet. */ + _nx_ip_packet_deferred_receive(&server_ip, my_packet); + } + else if (resposner_counter == 2) + { + + /* Check the DHCP ACK. */ +#ifdef NX_ENABLE_IP_ID_RANDOMIZATION + /* Skip IP id when it is random. */ + if (memcmp(packet_ptr -> nx_packet_prepend_ptr, &pkt4[14], 4) || + memcmp(packet_ptr -> nx_packet_prepend_ptr + 6, &pkt4[20], 4) || + memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, &pkt4[26], sizeof(pkt4) - 26)) +#else + if (memcmp(packet_ptr -> nx_packet_prepend_ptr, &pkt4[14], sizeof(pkt4) -14)) +#endif + error_counter ++; + } ; + } + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_server_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: DHCP Server Test..........................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_skip_discover_test.c b/test/regression/dhcp_test/netx_dhcp_skip_discover_test.c new file mode 100644 index 00000000..172e6783 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_skip_discover_test.c @@ -0,0 +1,398 @@ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "netx_dhcp_clone_function.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) +#define CLIENT_IP_ADDRESS IP_ADDRESS(10,0,0,15) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* If defined, the host requests a (previous) client IP address. */ + +#define REQUEST_CLIENT_IP + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); +static VOID my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_skip_discover_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Skip Discover Test..................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Change the pointer function to check user options. */ + server_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +UINT length; + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UCHAR buffer[4]; +UINT buffer_size = 4; +ULONG *long_ptr; +ULONG requested_ip; +UINT skip_discover_message = NX_TRUE; + + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Set the client IP if the host is configured to do so. */ + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Get the DNS Server address. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DNS_SVR, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the DNS address. */ + if (*long_ptr != NX_DHCP_DNS_SERVER_0) + error_counter++; + } + else + { + error_counter++; + } + + /* Get the lease time value. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DHCP_LEASE, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the lease time value. */ + if (*long_ptr != NX_DHCP_DEFAULT_LEASE_TIME) + error_counter++; + } + else + { + error_counter++; + } + + length = sizeof(message); + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + +VOID my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UCHAR *server_id = NX_NULL; + + /* Search the Class ID option. */ + server_id = dhcp_search_buffer((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_OPTION_DHCP_SERVER, (packet_ptr -> nx_packet_length - 8)); + + /* Check if have the Class ID option. */ + if (server_id != NX_NULL) + error_counter++; + + /* Call the actual function to receive the UDP packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + /* Increment state changes counter. */ + state_changes++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_skip_discover_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Skip Discover Test..............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_start_test.c b/test/regression/dhcp_test/netx_dhcp_start_test.c new file mode 100644 index 00000000..219a75a4 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_start_test.c @@ -0,0 +1,419 @@ +/* This test reference the netx_dhcp_basic_test.c, with extra test on the corner + of function _nx_dhcp_interface_start which checks that condition when the + return status of tx_thread_resume is TX_SUSPEND_LIFTED */ + +#include "tx_api.h" +#include "nx_api.h" +#include "tx_thread.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* If defined, the host requests a (previous) client IP address. */ +/* +#define REQUEST_CLIENT_IP +*/ + +/* If defined the client requests to jump to the boot state and skip the DISCOVER message. + If REQUEST_CLIENT_IP is not defined, this has no effect. */ +/* +#define SKIP_DISCOVER_MESSAGE +*/ + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_start_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Start Test..........................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +UINT length; + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) +static UINT packet_filter_extended(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT direction) +{ + if ((direction == NX_IP_PACKET_OUT) && + ((packet_ptr -> nx_packet_ip_header == NX_NULL) || + (packet_ptr -> nx_packet_ip_header_length == 0))) + { + error_counter++; + } + return(NX_SUCCESS); +} +#endif + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UCHAR buffer[4]; +UINT buffer_size = 4; +ULONG *long_ptr; + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +UINT skip_discover_message = NX_FALSE; +#endif + + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) + client_ip.nx_ip_packet_filter_extended = packet_filter_extended; +#endif + + /* Set the client IP if the host is configured to do so. */ +#ifdef REQUEST_CLIENT_IP + + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + +#endif + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + /* Force the return status of tx_thread_resume to be TX_SUSPEND_LIFTED, which + is a corner case tested in function _nx_dhcp_interface_start */ + dhcp_client.nx_dhcp_thread.tx_thread_delayed_suspend = TX_TRUE; + dhcp_client.nx_dhcp_thread.tx_thread_state = TX_SLEEP; + status = nx_dhcp_start(&dhcp_client); + dhcp_client.nx_dhcp_thread.tx_thread_delayed_suspend = TX_FALSE; + dhcp_client.nx_dhcp_thread.tx_thread_state = TX_READY; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Get the DNS Server address. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DNS_SVR, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the DNS address. */ + if (*long_ptr != NX_DHCP_DNS_SERVER_0) + error_counter++; + } + else + { + error_counter++; + } + + /* Get the lease time value. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DHCP_LEASE, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the lease time value. */ + if (*long_ptr != NX_DHCP_DEFAULT_LEASE_TIME) + error_counter++; + } + else + { + error_counter++; + } + + length = sizeof(message); + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + /* Increment state changes counter. */ + state_changes++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_start_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Start Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_stop_test.c b/test/regression/dhcp_test/netx_dhcp_stop_test.c new file mode 100644 index 00000000..0768c2d5 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_stop_test.c @@ -0,0 +1,419 @@ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + +/* If defined, the host requests a (previous) client IP address. */ +/* +#define REQUEST_CLIENT_IP +*/ + +/* If defined the client requests to jump to the boot state and skip the DISCOVER message. + If REQUEST_CLIENT_IP is not defined, this has no effect. */ +/* +#define SKIP_DISCOVER_MESSAGE +*/ + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_stop_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +static void interface_state_change_cb(NX_DHCP *dhcp_ptr, UINT iface, UCHAR state) +{ + /* change the state to cover the corner case in _nx_dhcp_interface_stop */ + dhcp_ptr->nx_dhcp_interface_record->nx_dhcp_state = NX_DHCP_STATE_FORCERENEW; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + printf("NetX Test: DHCP Stop Test..........................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +UINT length; + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) +static UINT packet_filter_extended(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT direction) +{ + if ((direction == NX_IP_PACKET_OUT) && + ((packet_ptr -> nx_packet_ip_header == NX_NULL) || + (packet_ptr -> nx_packet_ip_header_length == 0))) + { + error_counter++; + } + return(NX_SUCCESS); +} +#endif + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UCHAR buffer[4]; +UINT buffer_size = 4; +ULONG *long_ptr; + +#ifdef REQUEST_CLIENT_IP +ULONG requested_ip; +UINT skip_discover_message = NX_FALSE; +#endif + + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_IP_PACKET_FILTER) + client_ip.nx_ip_packet_filter_extended = packet_filter_extended; +#endif + + /* Set the client IP if the host is configured to do so. */ +#ifdef REQUEST_CLIENT_IP + + requested_ip = (ULONG)CLIENT_IP_ADDRESS; + + /* Request a specific IP address using the DHCP client address option. */ + status = nx_dhcp_request_client_ip(&dhcp_client, requested_ip, skip_discover_message); + if (status) + error_counter++; + +#endif + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Get the DNS Server address. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DNS_SVR, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the DNS address. */ + if (*long_ptr != NX_DHCP_DNS_SERVER_0) + error_counter++; + } + else + { + error_counter++; + } + + /* Get the lease time value. */ + status = nx_dhcp_user_option_retrieve(&dhcp_client, NX_DHCP_OPTION_DHCP_LEASE, buffer, &buffer_size); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + /* Set the pointer. */ + long_ptr = (ULONG *)(buffer); + + /* Check the lease time value. */ + if (*long_ptr != NX_DHCP_DEFAULT_LEASE_TIME) + error_counter++; + } + else + { + error_counter++; + } + + length = sizeof(message); + + /* Send pings to another host on the network... */ + status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Set the callback to test the corner case in function _nx_dhcp_interface_stop + when nx_dhcp_interface_state_change_callback is available */ + dhcp_client.nx_dhcp_interface_state_change_callback = interface_state_change_cb; + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + /* Increment state changes counter. */ + state_changes++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_stop_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Stop Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcp_unicast_test.c b/test/regression/dhcp_test/netx_dhcp_unicast_test.c new file mode 100644 index 00000000..e1c34f40 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_unicast_test.c @@ -0,0 +1,486 @@ +/* This NetX test concentrates on the DHCP Unicast operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#else +#include "nx_dhcp.h" +#endif +#include "netx_dhcp_clone_function.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ +static void client_thread_entry(ULONG thread_input); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *, ULONG, UINT, ULONG *, ULONG *); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* DCHP Unicast Interaction Message. */ + +#if 0 +/* Frame (342 bytes) DHCP Discover */ +static const unsigned char pkt1[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x01, 0x48, 0x00, 0x01, 0x40, 0x00, 0x80, 0x11, /* .H..@... */ +0xf9, 0xa4, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, /* ...D.C.4 */ +0x37, 0x87, 0x01, 0x01, 0x06, 0x00, 0x22, 0x33, /* 7....."3 */ +0x44, 0x6e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, /* Dn...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x00, 0x00, 0x00, 0x00, /* "3DV.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x01, 0x33, 0x04, 0xff, /* Sc5..3.. */ +0xff, 0xff, 0xff, 0x0c, 0x10, 0x4e, 0x65, 0x74, /* .....Net */ +0x58, 0x5f, 0x44, 0x48, 0x43, 0x50, 0x5f, 0x43, /* X_DHCP_C */ +0x6c, 0x69, 0x65, 0x6e, 0x74, 0x37, 0x03, 0x01, /* lient7.. */ +0x03, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; +#endif + +/* Frame (342 bytes) DHCP Offer*/ +static const unsigned char pkt2[342] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x50, /* .."3DV.P */ +0x56, 0x39, 0xf6, 0x3d, 0x08, 0x00, 0x45, 0x10, /* V9.=..E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x25, 0x79, 0x0a, 0x00, 0x00, 0x01, 0x0a, 0x00, /* %y...... */ +0x00, 0x1c, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xdb, 0x21, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .!...."3 */ +0x44, 0x6e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, /* Dn...... */ +0x00, 0x00, 0x0a, 0x00, 0x00, 0x1c, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x00, 0x00, 0x00, 0x00, /* "3DV.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x36, 0x04, 0x0a, /* Sc5..6.. */ +0x00, 0x00, 0x01, 0x33, 0x04, 0x00, 0x00, 0x01, /* ...3.... */ +0x2c, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ,....... */ +0x04, 0x0a, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +#if 0 +/* Frame (342 bytes) DHCP Request */ +static const unsigned char pkt3[342] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x01, 0x48, 0x00, 0x02, 0x40, 0x00, 0x80, 0x11, /* .H..@... */ +0xf9, 0xa3, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0x00, 0x44, 0x00, 0x43, 0x01, 0x34, /* ...D.C.4 */ +0x14, 0x3d, 0x01, 0x01, 0x06, 0x00, 0x22, 0x33, /* .=...."3 */ +0x44, 0x6e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, /* Dn...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x00, 0x00, 0x00, 0x00, /* "3DV.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x03, 0x0c, 0x10, 0x4e, /* Sc5....N */ +0x65, 0x74, 0x58, 0x5f, 0x44, 0x48, 0x43, 0x50, /* etX_DHCP */ +0x5f, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x32, /* _Client2 */ +0x04, 0x0a, 0x00, 0x00, 0x1c, 0x36, 0x04, 0x0a, /* .....6.. */ +0x00, 0x00, 0x01, 0x37, 0x03, 0x01, 0x03, 0x06, /* ...7.... */ +0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; +#endif + +/* Frame (342 bytes) DHCP Offer */ +static const unsigned char pkt4[342] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x50, /* .."3DV.P */ +0x56, 0x39, 0xf6, 0x3d, 0x08, 0x00, 0x45, 0x10, /* V9.=..E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x25, 0x79, 0x0a, 0x00, 0x00, 0x01, 0x0a, 0x00, /* %y...... */ +0x00, 0x1c, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xd8, 0x20, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* . ...."3 */ +0x44, 0x6e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, /* Dn...... */ +0x00, 0x00, 0x0a, 0x00, 0x00, 0x1c, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x00, 0x00, 0x00, 0x00, /* "3DV.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x36, 0x04, 0x0a, /* Sc5..6.. */ +0x00, 0x00, 0x01, 0x33, 0x04, 0x00, 0x00, 0x01, /* ...3.... */ +0x2c, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ,....... */ +0x04, 0x0a, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_unicast_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +ULONG client_ip_address; +ULONG client_ip_network_mask; + + + printf("NetX Test: DHCP Unicast Test........................................."); + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Clear the broadcast flag. */ + status = nx_dhcp_clear_broadcast_flag(&dhcp_client, NX_TRUE); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IP address. */ + status = nx_ip_address_get(&client_ip, &client_ip_address, &client_ip_network_mask); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IP address. */ + if ((client_ip_address != IP_ADDRESS(10, 0, 0, 28)) || + (client_ip_network_mask != IP_ADDRESS(255, 255, 255, 0))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Stopping the DHCP client. */ + status = nx_dhcp_stop(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* All done. Return resources to NetX and ThreadX. */ + status = nx_dhcp_delete(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +UINT status; +ULONG dhcp_xid; +NX_PACKET *my_packet; + + /* Is this a DHCP packet e.g. not an ARP packet? */ + if (packet_ptr -> nx_packet_length < 328) + { + /* Maybe an ARP packet. let the RAM driver deal with it */ + return NX_TRUE; + } + + /* Update the packet counter. */ + packet_counter ++; + + /* Check the packet counter. */ + if (packet_counter == 1) + { + + /* Receive the DHCP Discover message. */ + + /* Send DHCP Offer message. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet, 0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return NX_TRUE; + } + + /* Write the DHCP Offer message. */ + my_packet -> nx_packet_length = sizeof(pkt2) - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt2 + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + } + else if (packet_counter == 2) + { + + /* Receive the DHCP Request message, */ + + /* Send DHCP ACK message. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet, 0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return NX_TRUE; + } + + /* Write the DHCP ACK message. */ + my_packet -> nx_packet_length = sizeof(pkt4) - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt4 + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + } + + /* Get the XID of DHCP message from DHCP Server. */ + dhcp_xid = dhcp_get_data(my_packet -> nx_packet_prepend_ptr + 20 + 8 + NX_BOOTP_OFFSET_XID, 4); + + /* Replace the XID. */ + dhcp_client.nx_dhcp_interface_record[0].nx_dhcp_xid = dhcp_xid; + + /* Receive the packet. */ + _nx_ip_packet_deferred_receive(ip_ptr, my_packet); + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_unicast_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCP Unicast Test....................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcp_user_option_add_test.c b/test/regression/dhcp_test/netx_dhcp_user_option_add_test.c new file mode 100644 index 00000000..dd440a60 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcp_user_option_add_test.c @@ -0,0 +1,393 @@ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcp_client.h" +#include "nxd_dhcp_server.h" +#else +#include "nx_dhcp.h" +#include "nx_dhcp_server.h" +#endif +#include "netx_dhcp_clone_function.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +#define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1) +#define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10) +#define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19) + +#define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0) +#define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1) +#define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1) + + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_DHCP dhcp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCP_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG state_changes; +static ULONG error_counter; +static CHAR *pointer; + +static UCHAR message[50] = "My Ping Request!" ; + + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state); +static UINT dhcp_user_option_add(NX_DHCP *dhcp_ptr, UINT iface_index, UINT message_type, UCHAR *user_option_ptr, UINT *user_option_length); +static VOID my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_user_option_add_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the client thread. */ + tx_thread_create(&client_thread, "thread client", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the client packet pool. */ + status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Client. */ + status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for DHCP Server IP. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&client_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nx_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index; +UINT addresses_added; + + NX_PARAMETER_NOT_USED(thread_input); + + printf("NetX Test: DHCP User Option Add Test................................."); + + /* Create the DHCP Server. */ + status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, + "DHCP Server", &server_pool); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors creating the DHCP Server. */ + if (status) + error_counter++; + + /* Load the assignable DHCP IP addresses for the first interface. */ + iface_index = 0; + + status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0, + END_IP_ADDRESS_LIST_0, &addresses_added); + + /* Check for errors creating the list. */ + if (status) + { + error_counter++; + } + + /* Verify all the addresses were added to the list. */ + if (addresses_added != 10) + { + error_counter++; + } + + status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0, + NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0); + + /* Check for errors setting network parameters. */ + if (status) + { + error_counter++; + } + + /* Change the pointer function to check user options. */ + server_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start DHCP Server task. */ + status = nx_dhcp_server_start(&dhcp_server); + + /* Check for errors starting up the DHCP server. */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +UINT length; + + +/* Define the test threads. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + NX_PARAMETER_NOT_USED(thread_input); + + /* Create the DHCP instance. */ + status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client"); + if (status) + error_counter++; + +#ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL + status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool); + if (status) + error_counter++; +#endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Register state change variable. */ + status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change); + if (status) + error_counter++; + + /* Set callback function to add user options. */ + status = nx_dhcp_user_option_add_callback_set(&dhcp_client, dhcp_user_option_add); + if (status) + error_counter++; + + /* Start the DHCP Client. */ + status = nx_dhcp_start(&dhcp_client); + if (status) + error_counter++; + + /* Check for address resolution. */ + status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Send pings to another host on the network. */ + status = nx_icmp_ping(&client_ip, NX_DHCP_SERVER_IP_ADDRESS_0, (CHAR *)message, length, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Stopping the DHCP client. */ + nx_dhcp_stop(&dhcp_client); + + /* All done. Return resources to NetX and ThreadX. */ + nx_dhcp_delete(&dhcp_client); + + return; +} + + +void dhcp_state_change(NX_DHCP *dhcp_ptr, UCHAR new_state) +{ + + NX_PARAMETER_NOT_USED(dhcp_ptr); + NX_PARAMETER_NOT_USED(new_state); + + /* Increment state changes counter. */ + state_changes++; + + return; +} + +UINT dhcp_user_option_add(NX_DHCP *dhcp_ptr, UINT iface_index, UINT message_type, UCHAR *user_option_ptr, UINT *user_option_length) +{ + +CHAR vendor_class_id[] = "VENDORINFO"; /* Vendor Information. */ + + NX_PARAMETER_NOT_USED(dhcp_ptr); + NX_PARAMETER_NOT_USED(iface_index); + NX_PARAMETER_NOT_USED(message_type); + + /* Application can check if add options into the packet by iface_index and message_type. + message_type are defined in header file, such as: NX_DHCP_TYPE_DHCPDISCOVER. */ + + /* Add Vendor Class ID option refer to RFC2132. */ + + /* Check if have enough space for this option. */ + if (*user_option_length < (strlen(vendor_class_id) + 2)) + return(NX_FALSE); + + /* Set the option code. */ + *user_option_ptr = 60; + + /* Set the option length. */ + *(user_option_ptr + 1) = (UCHAR)strlen(vendor_class_id); + + /* Set the option value (Vendor class id). */ + memcpy((user_option_ptr + 2), vendor_class_id, strlen(vendor_class_id)); + + /* Update the option length. */ + *user_option_length = (strlen(vendor_class_id) + 2); + return(NX_TRUE); +} + +VOID my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UCHAR *vendor_class_id = NX_NULL; + + /* Search the Class ID option. */ + vendor_class_id = dhcp_search_buffer((packet_ptr -> nx_packet_prepend_ptr + 8), 60, (packet_ptr -> nx_packet_length - 8)); + + /* Check if have the Class ID option. */ + if (vendor_class_id == NX_NULL) + error_counter++; + + /* Skip the length. */ + vendor_class_id++; + + /* Check the class id. */ + if(memcmp(vendor_class_id, "VENDORINFO", 10)) + error_counter++; + + /* Call the actual function to receive the UDP packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcp_user_option_add_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DHCP User Option Add Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcpv6_basic_test.c b/test/regression/dhcp_test/netx_dhcpv6_basic_test.c new file mode 100644 index 00000000..aaa20681 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcpv6_basic_test.c @@ -0,0 +1,567 @@ +/* This is a small demo of the NetX Duo DHCPv6 Client and Server for the high-performance + NetX Duo stack. */ + +#include +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_FRAGMENTATION) +#include "nxd_dhcpv6_client.h" +#include "nxd_dhcpv6_server.h" + +#define DEMO_STACK_SIZE 2048 +#define NX_DHCPV6_THREAD_STACK_SIZE 2048 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE (NX_PACKET_SIZE * 8) + +/* Define the ThreadX and NetX object control blocks... */ + +static NX_PACKET_POOL pool_0; +static TX_THREAD thread_client; +static TX_THREAD thread_server; +static NX_IP client_ip; +static NX_IP server_ip; + +/* Define the Client and Server instances. */ + +static NX_DHCPV6 dhcp_client; +static NX_DHCPV6_SERVER dhcp_server; + +/* Define the error counter used in the demo application... */ +static ULONG error_counter; +static CHAR *pointer; + +static NXD_ADDRESS server_address; +static NXD_ADDRESS dns_ipv6_address; +static NXD_ADDRESS start_ipv6_address; +static NXD_ADDRESS end_ipv6_address; + + +/* Define thread prototypes. */ + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +extern void _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); + + +/* Define some DHCPv6 parameters. */ + +#define DHCPV6_IANA_ID 0xC0DEDBAD +#define DHCPV6_T1 NX_DHCPV6_INFINITE_LEASE +#define DHCPV6_T2 NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_REFERRED_LIFETIME NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_VALID_LIFETIME NX_DHCPV6_INFINITE_LEASE + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_basic_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the Client thread. */ + status = tx_thread_create(&thread_client, "Client thread", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create the Server thread. */ + status = tx_thread_create(&thread_server, "Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create a Client IP instance. */ + status = nx_ip_create(&client_ip, "Client IP", IP_ADDRESS(0, 0, 0, 0), + 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create a Server IP instance. */ + status = nx_ip_create(&server_ip, "Server IP", IP_ADDRESS(1, 2, 3, 4), + 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic for sending DHCPv6 messages. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the IPv6 services. */ + status = nxd_ipv6_enable(&client_ip); + status += nxd_ipv6_enable(&server_ip); + + /* Check for IPv6 enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the ICMPv6 services. */ + status = nxd_icmp_enable(&client_ip); + status += nxd_icmp_enable(&server_ip); + + /* Check for ICMP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the fragment feature. */ + status = nx_ip_fragment_enable(&client_ip); + status += nx_ip_fragment_enable(&server_ip); + + /* Check for ICMP enable errors. */ + if (status) + { + error_counter++; + } +} + +/* Define the Client host application thread. */ + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS ipv6_address; +NXD_ADDRESS dns_address; +ULONG prefix_length; +UINT interface_index; +ULONG T1, T2, preferred_lifetime, valid_lifetime; +UINT address_count; +UINT address_index; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: DHCPv6 Basic Test........................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Establish the link local address for the host. The RAM driver creates + a virtual MAC address of 0x1122334456. */ + status = nxd_ipv6_address_set(&client_ip, 0, NX_NULL, 10, NULL); + + /* Let NetX Duo and the network driver get initialized. Also give the server time to get set up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create the DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &client_ip, "DHCPv6 Client", &pool_0, pointer, NX_DHCPV6_THREAD_STACK_SIZE, + NX_NULL, NX_NULL); + pointer = pointer + NX_DHCPV6_THREAD_STACK_SIZE; + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. + + Note that if this host had already been assigned in IPv6 lease, it + would have to use the assigned T1 and T2 values in loading the DHCPv6 + client with an IANA block. + */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, DHCPV6_T1, DHCPV6_T2); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Starting up the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* If the host also want to get the option message, set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Now, the host send the solicit message to get the IPv6 address and other options from the DHCPv6 server. */ + status = nx_dhcpv6_request_solicit(&dhcp_client); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for get the IPv6 address and do the duplicate address detection. */ + tx_thread_sleep(6 * NX_IP_PERIODIC_RATE); + + /* Get the valid IPv6 address count which the DHCPv6 server assigned . */ + status = nx_dhcpv6_get_valid_ip_address_count(&dhcp_client, &address_count); + + /* Check for errors. */ + if ((status) || (address_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address, preferred lifetime and valid lifetime according to the address index. */ + address_index = 0; + status = nx_dhcpv6_get_valid_ip_address_lease_time(&dhcp_client, address_index, &ipv6_address, &preferred_lifetime, &valid_lifetime); + + /* Check for errors. */ + if ((status) || (address_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by DHCPv6 API. */ + status = nx_dhcpv6_get_IP_address(&dhcp_client, &ipv6_address); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address. */ + if ((ipv6_address.nxd_ip_version != start_ipv6_address.nxd_ip_version) || + (ipv6_address.nxd_ip_address.v6[0] != start_ipv6_address.nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != start_ipv6_address.nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != start_ipv6_address.nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != start_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by NetX Duo API. */ + status = nxd_ipv6_address_get(&client_ip, 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IPv6 address. */ + if ((prefix_length != 64) || (interface_index != 0) || + (ipv6_address.nxd_ip_version != start_ipv6_address.nxd_ip_version) || + (ipv6_address.nxd_ip_address.v6[0] != start_ipv6_address.nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != start_ipv6_address.nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != start_ipv6_address.nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != start_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get IP address lease time. + Note, This API only applies to one IA. */ + status = nx_dhcpv6_get_lease_time_data(&dhcp_client, &T1, &T2, &preferred_lifetime, &valid_lifetime); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the value. */ + if ((T1 != NX_DHCPV6_DEFAULT_T1_TIME) || + (T2 != NX_DHCPV6_DEFAULT_T2_TIME) || + (preferred_lifetime != NX_DHCPV6_DEFAULT_PREFERRED_TIME) || + (valid_lifetime != NX_DHCPV6_DEFAULT_VALID_TIME)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the DNS Server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_address); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IPv6 DNS address. */ + if ((dns_address.nxd_ip_version != dns_ipv6_address.nxd_ip_version) || + (dns_address.nxd_ip_address.v6[0] != dns_ipv6_address.nxd_ip_address.v6[0]) || + (dns_address.nxd_ip_address.v6[1] != dns_ipv6_address.nxd_ip_address.v6[1]) || + (dns_address.nxd_ip_address.v6[2] != dns_ipv6_address.nxd_ip_address.v6[2]) || + (dns_address.nxd_ip_address.v6[3] != dns_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping the DHCPv6 Server. */ + status = nxd_icmp_ping(&client_ip, &server_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the address. */ + status = nx_dhcpv6_request_release(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for release the IPv6 address. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Get the IPv6 address by DHCPv6 API. */ + status = nx_dhcpv6_get_IP_address(&dhcp_client, &ipv6_address); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by NetX Duo API. */ + status = nxd_ipv6_address_get(&client_ip, 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Stop the Client task. */ + status = nx_dhcpv6_stop(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the DHCPv6 client. */ + status = nx_dhcpv6_client_delete(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successfully. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the test server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +ULONG duid_time; +UINT addresses_added; + + /* Set the IPv6 address of DHCPv6 Server. */ + server_address.nxd_ip_version = NX_IP_VERSION_V6 ; + server_address.nxd_ip_address.v6[0] = 0x20010db8; + server_address.nxd_ip_address.v6[1] = 0xf101; + server_address.nxd_ip_address.v6[2] = 0x00000000; + server_address.nxd_ip_address.v6[3] = 0x00000101; + + /* Set the link local and global addresses. */ + status = nxd_ipv6_address_set(&server_ip, 0, NX_NULL, 10, NULL); + status += nxd_ipv6_address_set(&server_ip, 0, &server_address, 64, NULL); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Validate the link local and global addresses. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create the DHCPv6 Server. */ + status = nx_dhcpv6_server_create(&dhcp_server, &server_ip, "DHCPv6 Server", &pool_0, pointer, NX_DHCPV6_SERVER_THREAD_STACK_SIZE, NX_NULL, NX_NULL); + pointer += NX_DHCPV6_SERVER_THREAD_STACK_SIZE; + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set up the DNS IPv6 server address. */ + dns_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + dns_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + dns_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + dns_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + dns_ipv6_address.nxd_ip_address.v6[3] = 0x00000107; + + status = nx_dhcpv6_create_dns_address(&dhcp_server, &dns_ipv6_address); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Note: For DUID types that do not require time, the 'duid_time' input can be left at zero. + The DUID_TYPE and HW_TYPE are configurable options that are user defined in nx_dhcpv6_server.h. */ + + /* Set the DUID time as the start of the millenium. */ + duid_time = SECONDS_SINCE_JAN_1_2000_MOD_32; + status = nx_dhcpv6_set_server_duid(&dhcp_server, + NX_DHCPV6_SERVER_DUID_TYPE, NX_DHCPV6_SERVER_HW_TYPE, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_msw, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_lsw, + duid_time); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 start address. */ + start_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + start_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + start_ipv6_address.nxd_ip_address.v6[1] = 0x00000f101; + start_ipv6_address.nxd_ip_address.v6[2] = 0x0; + start_ipv6_address.nxd_ip_address.v6[3] = 0x00000110; + + /* Set the IPv6 end address. */ + end_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + end_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + end_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + end_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + end_ipv6_address.nxd_ip_address.v6[3] = 0x00000120; + + /* Set the IPv6 address range. */ + status = nx_dhcpv6_create_ip_address_range(&dhcp_server, &start_ipv6_address, &end_ipv6_address, &addresses_added); + + /* Check for errors. */ + if ((status) || (addresses_added != 16)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the NetX DHCPv6 server! */ + status = nx_dhcpv6_server_start(&dhcp_server); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_basic_test_application_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: DHCPv6 Basic Test.........................................N/A\n"); + test_control_return(3); +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/dhcp_test/netx_dhcpv6_client_process_server_duid_test.c b/test/regression/dhcp_test/netx_dhcpv6_client_process_server_duid_test.c new file mode 100644 index 00000000..180aa242 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcpv6_client_process_server_duid_test.c @@ -0,0 +1,399 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#ifdef FEATURE_NX_IPV6 +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + +#define DEMO_STACK_SIZE 2048 +#define DHCPV6_IANA_ID 0xc0dedbad + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static CHAR *pointer; +static ULONG error_counter; + +static UCHAR solicit = NX_FALSE; +static UCHAR request = NX_FALSE; +static ULONG server_identifier; +static ULONG server_identifier_length; +static ULONG server_duid_type; +static ULONG server_hardware_type; +static ULONG server_msw; +static ULONG server_lsw; + +/* Define thread prototypes. */ + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT _nx_dhcpv6_utility_get_block_option_length(UCHAR *buffer_ptr, ULONG *option, ULONG *length); + +/* Frame (118 bytes) Solicit */ +static unsigned char pkt1[118] = { +0x33, 0x33, 0x00, 0x01, 0x00, 0x02, 0x00, 0x80, /* 33...... */ +0xa3, 0xc7, 0x1c, 0xf6, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x40, 0x11, 0x40, 0xfe, 0x80, /* ...@.@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, /* ........ */ +0xa3, 0xff, 0xfe, 0xc7, 0x1c, 0xf6, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, /* ......." */ +0x02, 0x23, 0x00, 0x40, 0xc2, 0x19, 0x01, 0xdc, /* .#.@.... */ +0x5d, 0x45, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, /* ]E...... */ +0x00, 0x01, 0x5a, 0xcd, 0x54, 0xc7, 0x00, 0x80, /* ..Z.T... */ +0xa3, 0xc7, 0x1c, 0xf6, 0x00, 0x03, 0x00, 0x0c, /* ........ */ +0xc0, 0xde, 0xdb, 0xad, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, /* ........ */ +0x0c, 0x1c, 0x00, 0x06, 0x00, 0x08, 0x00, 0x17, /* ........ */ +0x00, 0x1f, 0x00, 0x29, 0x00, 0x18 /* ...).. */ +}; + +/* Frame (178 bytes) Advertise */ +static unsigned char pkt2[178] = { +0x00, 0x80, 0xa3, 0xc7, 0x1c, 0xf6, 0xec, 0x08, /* ........ */ +0x6b, 0x93, 0x70, 0xde, 0x86, 0xdd, 0x60, 0x00, /* k.p...`. */ +0x00, 0x00, 0x00, 0x7c, 0x11, 0x40, 0xfe, 0x80, /* ...|.@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x08, /* ........ */ +0x6b, 0xff, 0xfe, 0x93, 0x70, 0xde, 0xfe, 0x80, /* k...p... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, /* ........ */ +0xa3, 0xff, 0xfe, 0xc7, 0x1c, 0xf6, 0xd3, 0x98, /* ........ */ +0x02, 0x22, 0x00, 0x7c, 0xd9, 0x80, 0x02, 0xdc, /* .".|.... */ +0x5d, 0x45, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, /* ]E...... */ +0x00, 0x01, 0x5a, 0xcd, 0x54, 0xc7, 0x00, 0x80, /* ..Z.T... */ +0xa3, 0xc7, 0x1c, 0xf6, 0x00, 0x02, 0x00, 0x0a, /* ........ */ +0x00, 0x03, 0x00, 0x01, 0xec, 0x08, 0x6b, 0x93, /* ......k. */ +0x70, 0xde, 0x00, 0x03, 0x00, 0x28, 0xc0, 0xde, /* p....(.. */ +0xdb, 0xad, 0x00, 0x00, 0xa8, 0xc0, 0x00, 0x01, /* ........ */ +0x0e, 0x00, 0x00, 0x05, 0x00, 0x18, 0x12, 0x34, /* .......4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, /* ........ */ +0x51, 0x80, 0x00, 0x01, 0x51, 0x80, 0x00, 0x17, /* Q...Q... */ +0x00, 0x20, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* . .4.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02 /* .. */ +}; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_client_process_server_duid_test_application_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: DHCPv6 Client Process Server Duid Test...................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the new physical address. */ + status = nx_ip_interface_physical_address_set(&ip_0, 0, 0x00000080, 0xa3c71cf6, NX_TRUE); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, NX_DHCPV6_HW_TYPE_IEEE_802, 0x5acd54c7); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the DNS Server option. */ + status = nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the SNTP Server option. */ + status = nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the Time Zone option. */ + status = nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the Domain Search List option. */ + status = nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the call back function. */ + packet_process_callback = my_packet_process; + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Request the IPv6 address. */ + status = nx_dhcpv6_request_solicit(&dhcp_client); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for Advertise. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Check the error counter. */ + if ((error_counter) || (solicit != NX_TRUE) || (request != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG received_message_type; +NX_PACKET *response_packet; +UINT status; +NX_IPV6_HEADER *ip_header; + + /* Update the prepend to point DHCPv6 message, IPv6 header, UDP header. */ + packet_ptr -> nx_packet_prepend_ptr += (40 + 8); + + /* Extract the message type which should be the first byte. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr, 1, &received_message_type); + + /* Check for an illegal message type. */ + if ((received_message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) && (solicit == NX_FALSE)) + { + + solicit = NX_TRUE; + + /* Send DHCPv6 Server Advertise response. */ + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_RECEIVE_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + + /* Relase the packet. */ + nx_packet_release(packet_ptr); + return(NX_FALSE); + } + + response_packet -> nx_packet_prepend_ptr += 2; + response_packet -> nx_packet_append_ptr += 2; + + /* Write the DHCPv6 Server response messages into the packet payload! */ + status = nx_packet_data_append(response_packet, pkt2, sizeof(pkt2), &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + error_counter++; + nx_packet_release(packet_ptr); + nx_packet_release(response_packet); + return(NX_FALSE); + } + + /* Set the packet version. */ + response_packet -> nx_packet_ip_version = NX_IP_VERSION_V6; + + /* Set the IP header pointer. */ + response_packet -> nx_packet_ip_header = response_packet -> nx_packet_prepend_ptr + 14; + ip_header = (NX_IPV6_HEADER *)(response_packet -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + + /* Update the data pointer UDP + DHCPv6 message. */ + response_packet -> nx_packet_prepend_ptr += 54; + response_packet -> nx_packet_length -= 54; + + /* Set the packet interface. */ + response_packet -> nx_packet_address.nx_packet_ipv6_address_ptr = &ip_0.nx_ipv6_address[0]; + + dhcp_client.nx_dhcpv6_message_hdr.nx_message_xid = 0xdc5d45; + + /* Receive the DHCPv6 Server response. */ + _nx_udp_packet_receive(ip_ptr, response_packet); + + } + else if((received_message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) && (request == NX_FALSE)) + { + + /* Skip the DHCPv6 header. Type and Transaction ID. */ + packet_ptr -> nx_packet_prepend_ptr += 4; + + /* Skip the Client Identifier. */ + packet_ptr -> nx_packet_prepend_ptr += 18; + + /* Skip the Elapsed time. */ + packet_ptr -> nx_packet_prepend_ptr += 6; + + /* Extract the server identifier. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr, 2, &server_identifier); + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 2, 2, &server_identifier_length); + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 4, 2, &server_duid_type); + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 6, 2, &server_hardware_type); + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 2, &server_msw); + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 10, 4, &server_lsw); + + /* Check the server identifier. */ + if ((server_identifier == 2) && (server_identifier_length == 10) && + (server_duid_type == 3) && (server_hardware_type == 1) && + (server_msw == 0x0000ec08) && (server_lsw == 0x6b9370de)) + request = NX_TRUE; + } + + /* Relase the packet. */ + nx_packet_release(packet_ptr); + + return(NX_FALSE); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_client_process_server_duid_test_application_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: DHCPv6 Client Process Server Duid Test....................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcpv6_extended_api_test.c b/test/regression/dhcp_test/netx_dhcpv6_extended_api_test.c new file mode 100644 index 00000000..0d1bf9a3 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcpv6_extended_api_test.c @@ -0,0 +1,592 @@ +/* This is a small demo of the NetX Duo DHCPv6 Client and Server for the high-performance + NetX Duo stack. */ + +#include +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_FRAGMENTATION) +#include "nxd_dhcpv6_client.h" +#include "nxd_dhcpv6_server.h" + +#define DEMO_STACK_SIZE 2048 +#define NX_DHCPV6_THREAD_STACK_SIZE 2048 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE (NX_PACKET_SIZE * 8) + +/* Define the ThreadX and NetX object control blocks... */ + +static NX_PACKET_POOL pool_0; +static TX_THREAD thread_client; +static TX_THREAD thread_server; +static NX_IP client_ip; +static NX_IP server_ip; + +/* Define the Client and Server instances. */ + +static NX_DHCPV6 dhcp_client; +static NX_DHCPV6_SERVER dhcp_server; + +/* Define the error counter used in the demo application... */ +static ULONG error_counter; +static CHAR *pointer; + +static NXD_ADDRESS server_address; +static NXD_ADDRESS dns_ipv6_address; +static NXD_ADDRESS start_ipv6_address; +static NXD_ADDRESS end_ipv6_address; +static ULONG handler_extended_counter; + + +/* Define thread prototypes. */ + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +extern void _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); +static void dhcpv6_option_request_handler_extended(struct NX_DHCPV6_SERVER_STRUCT* dhcpv6_server_ptr, UINT option_request, UCHAR* buffer_ptr, UINT* index, UINT buffer_size); + + +/* Define some DHCPv6 parameters. */ + +#define DHCPV6_IANA_ID 0xC0DEDBAD +#define DHCPV6_T1 NX_DHCPV6_INFINITE_LEASE +#define DHCPV6_T2 NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_REFERRED_LIFETIME NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_VALID_LIFETIME NX_DHCPV6_INFINITE_LEASE + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_extended_api_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the Client thread. */ + status = tx_thread_create(&thread_client, "Client thread", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create the Server thread. */ + status = tx_thread_create(&thread_server, "Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create a Client IP instance. */ + status = nx_ip_create(&client_ip, "Client IP", IP_ADDRESS(0, 0, 0, 0), + 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create a Server IP instance. */ + status = nx_ip_create(&server_ip, "Server IP", IP_ADDRESS(1, 2, 3, 4), + 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic for sending DHCPv6 messages. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the IPv6 services. */ + status = nxd_ipv6_enable(&client_ip); + status += nxd_ipv6_enable(&server_ip); + + /* Check for IPv6 enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the ICMPv6 services. */ + status = nxd_icmp_enable(&client_ip); + status += nxd_icmp_enable(&server_ip); + + /* Check for ICMP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the fragment feature. */ + status = nx_ip_fragment_enable(&client_ip); + status += nx_ip_fragment_enable(&server_ip); + + /* Check for ICMP enable errors. */ + if (status) + { + error_counter++; + } +} + +/* Define the Client host application thread. */ + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS ipv6_address; +NXD_ADDRESS dns_address; +ULONG prefix_length; +UINT interface_index; +ULONG T1, T2, preferred_lifetime, valid_lifetime; +UINT address_count; +UINT address_index; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: DHCPv6 Extended API Test.................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Establish the link local address for the host. The RAM driver creates + a virtual MAC address of 0x1122334456. */ + status = nxd_ipv6_address_set(&client_ip, 0, NX_NULL, 10, NULL); + + /* Let NetX Duo and the network driver get initialized. Also give the server time to get set up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create the DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &client_ip, "DHCPv6 Client", &pool_0, pointer, NX_DHCPV6_THREAD_STACK_SIZE, + NX_NULL, NX_NULL); + pointer = pointer + NX_DHCPV6_THREAD_STACK_SIZE; + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. + + Note that if this host had already been assigned in IPv6 lease, it + would have to use the assigned T1 and T2 values in loading the DHCPv6 + client with an IANA block. + */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, DHCPV6_T1, DHCPV6_T2); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Starting up the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* If the host also want to get the option message, set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Now, the host send the solicit message to get the IPv6 address and other options from the DHCPv6 server. */ + status = nx_dhcpv6_request_solicit(&dhcp_client); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for get the IPv6 address and do the duplicate address detection. */ + tx_thread_sleep(6 * NX_IP_PERIODIC_RATE); + + /* Get the valid IPv6 address count which the DHCPv6 server assigned . */ + status = nx_dhcpv6_get_valid_ip_address_count(&dhcp_client, &address_count); + + /* Check for errors. */ + if ((status) || (address_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address, preferred lifetime and valid lifetime according to the address index. */ + address_index = 0; + status = nx_dhcpv6_get_valid_ip_address_lease_time(&dhcp_client, address_index, &ipv6_address, &preferred_lifetime, &valid_lifetime); + + /* Check for errors. */ + if ((status) || (address_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by DHCPv6 API. */ + status = nx_dhcpv6_get_IP_address(&dhcp_client, &ipv6_address); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address. */ + if ((ipv6_address.nxd_ip_version != start_ipv6_address.nxd_ip_version) || + (ipv6_address.nxd_ip_address.v6[0] != start_ipv6_address.nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != start_ipv6_address.nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != start_ipv6_address.nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != start_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by NetX Duo API. */ + status = nxd_ipv6_address_get(&client_ip, 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IPv6 address. */ + if ((prefix_length != 64) || (interface_index != 0) || + (ipv6_address.nxd_ip_version != start_ipv6_address.nxd_ip_version) || + (ipv6_address.nxd_ip_address.v6[0] != start_ipv6_address.nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != start_ipv6_address.nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != start_ipv6_address.nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != start_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get IP address lease time. + Note, This API only applies to one IA. */ + status = nx_dhcpv6_get_lease_time_data(&dhcp_client, &T1, &T2, &preferred_lifetime, &valid_lifetime); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the value. */ + if ((T1 != NX_DHCPV6_DEFAULT_T1_TIME) || + (T2 != NX_DHCPV6_DEFAULT_T2_TIME) || + (preferred_lifetime != NX_DHCPV6_DEFAULT_PREFERRED_TIME) || + (valid_lifetime != NX_DHCPV6_DEFAULT_VALID_TIME)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the DNS Server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_address); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IPv6 DNS address. */ + if ((dns_address.nxd_ip_version != dns_ipv6_address.nxd_ip_version) || + (dns_address.nxd_ip_address.v6[0] != dns_ipv6_address.nxd_ip_address.v6[0]) || + (dns_address.nxd_ip_address.v6[1] != dns_ipv6_address.nxd_ip_address.v6[1]) || + (dns_address.nxd_ip_address.v6[2] != dns_ipv6_address.nxd_ip_address.v6[2]) || + (dns_address.nxd_ip_address.v6[3] != dns_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping the DHCPv6 Server. */ + status = nxd_icmp_ping(&client_ip, &server_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the address. */ + status = nx_dhcpv6_request_release(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for release the IPv6 address. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Get the IPv6 address by DHCPv6 API. */ + status = nx_dhcpv6_get_IP_address(&dhcp_client, &ipv6_address); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by NetX Duo API. */ + status = nxd_ipv6_address_get(&client_ip, 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Stop the Client task. */ + status = nx_dhcpv6_stop(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the DHCPv6 client. */ + status = nx_dhcpv6_client_delete(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if (!handler_extended_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successfully. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the test server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +ULONG duid_time; +UINT addresses_added; + + /* Set the IPv6 address of DHCPv6 Server. */ + server_address.nxd_ip_version = NX_IP_VERSION_V6 ; + server_address.nxd_ip_address.v6[0] = 0x20010db8; + server_address.nxd_ip_address.v6[1] = 0xf101; + server_address.nxd_ip_address.v6[2] = 0x00000000; + server_address.nxd_ip_address.v6[3] = 0x00000101; + + /* Set the link local and global addresses. */ + status = nxd_ipv6_address_set(&server_ip, 0, NX_NULL, 10, NULL); + status += nxd_ipv6_address_set(&server_ip, 0, &server_address, 64, NULL); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Validate the link local and global addresses. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create the DHCPv6 Server. */ + status = nx_dhcpv6_server_create(&dhcp_server, &server_ip, "DHCPv6 Server", &pool_0, pointer, NX_DHCPV6_SERVER_THREAD_STACK_SIZE, NX_NULL, NX_NULL); + pointer += NX_DHCPV6_SERVER_THREAD_STACK_SIZE; + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set extended hanlder for option request. */ + status = nx_dhcpv6_server_option_request_handler_set(&dhcp_server, dhcpv6_option_request_handler_extended); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set up the DNS IPv6 server address. */ + dns_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + dns_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + dns_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + dns_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + dns_ipv6_address.nxd_ip_address.v6[3] = 0x00000107; + + status = nx_dhcpv6_create_dns_address(&dhcp_server, &dns_ipv6_address); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Note: For DUID types that do not require time, the 'duid_time' input can be left at zero. + The DUID_TYPE and HW_TYPE are configurable options that are user defined in nx_dhcpv6_server.h. */ + + /* Set the DUID time as the start of the millenium. */ + duid_time = SECONDS_SINCE_JAN_1_2000_MOD_32; + status = nx_dhcpv6_set_server_duid(&dhcp_server, + NX_DHCPV6_SERVER_DUID_TYPE, NX_DHCPV6_SERVER_HW_TYPE, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_msw, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_lsw, + duid_time); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 start address. */ + start_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + start_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + start_ipv6_address.nxd_ip_address.v6[1] = 0x00000f101; + start_ipv6_address.nxd_ip_address.v6[2] = 0x0; + start_ipv6_address.nxd_ip_address.v6[3] = 0x00000110; + + /* Set the IPv6 end address. */ + end_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + end_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + end_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + end_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + end_ipv6_address.nxd_ip_address.v6[3] = 0x00000120; + + /* Set the IPv6 address range. */ + status = nx_dhcpv6_create_ip_address_range(&dhcp_server, &start_ipv6_address, &end_ipv6_address, &addresses_added); + + /* Check for errors. */ + if ((status) || (addresses_added != 16)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the NetX DHCPv6 server! */ + status = nx_dhcpv6_server_start(&dhcp_server); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void dhcpv6_option_request_handler_extended(struct NX_DHCPV6_SERVER_STRUCT* dhcpv6_server_ptr, UINT option_request, UCHAR* buffer_ptr, UINT* index, UINT buffer_size) +{ + handler_extended_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_extended_api_test_application_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: DHCPv6 Extended API Test..................................N/A\n"); + test_control_return(3); +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/dhcp_test/netx_dhcpv6_packet_loss_test.c b/test/regression/dhcp_test/netx_dhcpv6_packet_loss_test.c new file mode 100644 index 00000000..ee785198 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcpv6_packet_loss_test.c @@ -0,0 +1,1106 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if defined (FEATURE_NX_IPV6) && defined(NX_ENABLE_INTERFACE_CAPABILITY) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + +#define DEMO_STACK_SIZE 2048 +#define DHCPV6_IANA_ID 0x165c19da + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static CHAR *pointer; +static ULONG error_counter; + +static UCHAR bound_flag = NX_FALSE; +static UCHAR renew_flag = NX_FALSE; + +/* Define thread prototypes. */ + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static VOID dhcpv6_server_packet_response(UINT transaction_id, UINT packet_index); +static VOID dhcpv6_state_change_notify(NX_DHCPV6 *dhcpv6_ptr, UINT old_state, UINT new_state); + +#if 0 + /* Frame (130 bytes) */ +static const unsigned char pkt1[130] = { +0x33, 0x33, 0x00, 0x01, 0x00, 0x02, 0xaa, 0xab, /* 33...... */ +0xac, 0x6e, 0x57, 0xdd, 0x86, 0xdd, 0x60, 0x00, /* .nW...`. */ +0x00, 0x00, 0x00, 0x4c, 0x11, 0x40, 0xfe, 0x80, /* ...L.@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0xff, 0x02, /* ...nW... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, /* ......." */ +0x02, 0x23, 0x00, 0x4c, 0x15, 0x8e, 0x01, 0xcb, /* .#.L.... */ +0x5d, 0x95, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, /* ]....... */ +0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, 0xaa, 0xab, /* .....&.. */ +0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, 0x00, 0x0c, /* .nW..... */ +0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, 0x00, 0x00, /* .\...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x27, 0x00, 0x0c, 0x00, 0x09, /* ...'.... */ +0x4d, 0x79, 0x2d, 0x44, 0x65, 0x76, 0x69, 0x63, /* My-Devic */ +0x65, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x17, /* e....... */ +0x00, 0x27 /* .' */ +}; +#endif + +/* Frame (198 bytes) */ +static const unsigned char pkt2[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x50, /* ...nW..P */ +0xda, 0xc6, 0x5a, 0x48, 0x86, 0xdd, 0x60, 0x00, /* ..ZH..`. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0x40, 0x12, 0x34, /* .....@.4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x80, 0xb1, 0x02, 0xcb, /* ."...... */ +0x5d, 0x95, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ]....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt3[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x1f, /* ...nW... */ +0x9e, 0x5b, 0x74, 0x02, 0x86, 0xdd, 0x6e, 0x00, /* .[t...n. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, /* ........ */ +0x9e, 0xff, 0xfe, 0x5b, 0x74, 0x02, 0xfe, 0x80, /* ...[t... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x81, 0xe5, 0x02, 0xcb, /* ."...... */ +0x5d, 0x95, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ]....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +#if 0 +/* Frame (176 bytes) */ +static const unsigned char pkt4[176] = { +0x33, 0x33, 0x00, 0x01, 0x00, 0x02, 0xaa, 0xab, /* 33...... */ +0xac, 0x6e, 0x57, 0xdd, 0x86, 0xdd, 0x60, 0x00, /* .nW...`. */ +0x00, 0x00, 0x00, 0x7a, 0x11, 0x40, 0xfe, 0x80, /* ...z.@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0xff, 0x02, /* ...nW... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, /* ......." */ +0x02, 0x23, 0x00, 0x7a, 0x84, 0x9b, 0x03, 0x22, /* .#.z..." */ +0x2c, 0x93, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, /* ,....... */ +0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, 0xaa, 0xab, /* .....&.. */ +0xac, 0x6e, 0x57, 0xdd, 0x00, 0x08, 0x00, 0x02, /* .nW..... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x03, 0x00, 0x28, /* k..z...( */ +0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, 0x00, 0x1e, /* .\...... */ +0x00, 0x00, 0x00, 0x30, 0x00, 0x05, 0x00, 0x18, /* ...0.... */ +0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .4...... */ +0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, 0xaf, 0x72, /* .Z...|.r */ +0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x78, /* ...<...x */ +0x00, 0x27, 0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, /* .'....My */ +0x2d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, /* -Device. */ +0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x27 /* .......' */ +}; +#endif + +/* Frame (198 bytes) */ +static const unsigned char pkt5[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x50, /* ...nW..P */ +0xda, 0xc6, 0x5a, 0x48, 0x86, 0xdd, 0x60, 0x00, /* ..ZH..`. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0x40, 0x12, 0x34, /* .....@.4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0xad, 0x5c, 0x07, 0x22, /* ."...\." */ +0x2c, 0x93, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ,....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt6[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x1f, /* ...nW... */ +0x9e, 0x5b, 0x74, 0x02, 0x86, 0xdd, 0x6e, 0x00, /* .[t...n. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, /* ........ */ +0x9e, 0xff, 0xfe, 0x5b, 0x74, 0x02, 0xfe, 0x80, /* ...[t... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0xae, 0x90, 0x07, 0x22, /* ."....." */ +0x2c, 0x93, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ,....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +#if 0 +/* Frame (176 bytes) */ +static const unsigned char pkt7[176] = { +0x33, 0x33, 0x00, 0x01, 0x00, 0x02, 0xaa, 0xab, /* 33...... */ +0xac, 0x6e, 0x57, 0xdd, 0x86, 0xdd, 0x60, 0x00, /* .nW...`. */ +0x00, 0x00, 0x00, 0x7a, 0x11, 0x40, 0xfe, 0x80, /* ...z.@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0xff, 0x02, /* ...nW... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, /* ......." */ +0x02, 0x23, 0x00, 0x7a, 0xf9, 0x6f, 0x05, 0x2f, /* .#.z.o./ */ +0xb5, 0xb1, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, 0xaa, 0xab, /* .....&.. */ +0xac, 0x6e, 0x57, 0xdd, 0x00, 0x08, 0x00, 0x02, /* .nW..... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x03, 0x00, 0x28, /* k..z...( */ +0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, 0x00, 0x1e, /* .\...... */ +0x00, 0x00, 0x00, 0x30, 0x00, 0x05, 0x00, 0x18, /* ...0.... */ +0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .4...... */ +0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, 0xaf, 0x72, /* .Z...|.r */ +0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x78, /* ...<...x */ +0x00, 0x27, 0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, /* .'....My */ +0x2d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, /* -Device. */ +0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x27 /* .......' */ +}; +#endif + +/* Frame (198 bytes) */ +static const unsigned char pkt8[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x50, /* ...nW..P */ +0xda, 0xc6, 0x5a, 0x48, 0x86, 0xdd, 0x60, 0x00, /* ..ZH..`. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0x40, 0x12, 0x34, /* .....@.4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x24, 0x31, 0x07, 0x2f, /* ."..$1./ */ +0xb5, 0xb1, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt9[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x1f, /* ...nW... */ +0x9e, 0x5b, 0x74, 0x02, 0x86, 0xdd, 0x6e, 0x00, /* .[t...n. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, /* ........ */ +0x9e, 0xff, 0xfe, 0x5b, 0x74, 0x02, 0xfe, 0x80, /* ...[t... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x25, 0x65, 0x07, 0x2f, /* ."..%e./ */ +0xb5, 0xb1, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +#if 0 +/* Frame (176 bytes) */ +static const unsigned char pkt10[176] = { +0x33, 0x33, 0x00, 0x01, 0x00, 0x02, 0xaa, 0xab, /* 33...... */ +0xac, 0x6e, 0x57, 0xdd, 0x86, 0xdd, 0x60, 0x00, /* .nW...`. */ +0x00, 0x00, 0x00, 0x7a, 0x11, 0x40, 0xfe, 0x80, /* ...z.@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0xff, 0x02, /* ...nW... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, /* ......." */ +0x02, 0x23, 0x00, 0x7a, 0xf9, 0x6f, 0x05, 0x2f, /* .#.z.o./ */ +0xb5, 0xb1, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, 0xaa, 0xab, /* .....&.. */ +0xac, 0x6e, 0x57, 0xdd, 0x00, 0x08, 0x00, 0x02, /* .nW..... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x03, 0x00, 0x28, /* k..z...( */ +0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, 0x00, 0x1e, /* .\...... */ +0x00, 0x00, 0x00, 0x30, 0x00, 0x05, 0x00, 0x18, /* ...0.... */ +0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .4...... */ +0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, 0xaf, 0x72, /* .Z...|.r */ +0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x78, /* ...<...x */ +0x00, 0x27, 0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, /* .'....My */ +0x2d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, /* -Device. */ +0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x27 /* .......' */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt11[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x50, /* ...nW..P */ +0xda, 0xc6, 0x5a, 0x48, 0x86, 0xdd, 0x60, 0x00, /* ..ZH..`. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0x40, 0x12, 0x34, /* .....@.4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x24, 0x31, 0x07, 0x2f, /* ."..$1./ */ +0xb5, 0xb1, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt12[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x1f, /* ...nW... */ +0x9e, 0x5b, 0x74, 0x02, 0x86, 0xdd, 0x6e, 0x00, /* .[t...n. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, /* ........ */ +0x9e, 0xff, 0xfe, 0x5b, 0x74, 0x02, 0xfe, 0x80, /* ...[t... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x25, 0x65, 0x07, 0x2f, /* ."..%e./ */ +0xb5, 0xb1, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (176 bytes) */ +static const unsigned char pkt13[176] = { +0x33, 0x33, 0x00, 0x01, 0x00, 0x02, 0xaa, 0xab, /* 33...... */ +0xac, 0x6e, 0x57, 0xdd, 0x86, 0xdd, 0x60, 0x00, /* .nW...`. */ +0x00, 0x00, 0x00, 0x7a, 0x11, 0x40, 0xfe, 0x80, /* ...z.@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0xff, 0x02, /* ...nW... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, /* ......." */ +0x02, 0x23, 0x00, 0x7a, 0x68, 0xf3, 0x05, 0x76, /* .#.zh..v */ +0x45, 0xe7, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, 0xaa, 0xab, /* .....&.. */ +0xac, 0x6e, 0x57, 0xdd, 0x00, 0x08, 0x00, 0x02, /* .nW..... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x03, 0x00, 0x28, /* k..z...( */ +0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, 0x00, 0x1e, /* .\...... */ +0x00, 0x00, 0x00, 0x30, 0x00, 0x05, 0x00, 0x18, /* ...0.... */ +0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .4...... */ +0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, 0xaf, 0x72, /* .Z...|.r */ +0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x78, /* ...<...x */ +0x00, 0x27, 0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, /* .'....My */ +0x2d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, /* -Device. */ +0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x27 /* .......' */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt14[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x50, /* ...nW..P */ +0xda, 0xc6, 0x5a, 0x48, 0x86, 0xdd, 0x60, 0x00, /* ..ZH..`. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0x40, 0x12, 0x34, /* .....@.4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x93, 0xb4, 0x07, 0x76, /* .".....v */ +0x45, 0xe7, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt15[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x1f, /* ...nW... */ +0x9e, 0x5b, 0x74, 0x02, 0x86, 0xdd, 0x6e, 0x00, /* .[t...n. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, /* ........ */ +0x9e, 0xff, 0xfe, 0x5b, 0x74, 0x02, 0xfe, 0x80, /* ...[t... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x94, 0xe8, 0x07, 0x76, /* .".....v */ +0x45, 0xe7, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (176 bytes) */ +static const unsigned char pkt16[176] = { +0x33, 0x33, 0x00, 0x01, 0x00, 0x02, 0xaa, 0xab, /* 33...... */ +0xac, 0x6e, 0x57, 0xdd, 0x86, 0xdd, 0x60, 0x00, /* .nW...`. */ +0x00, 0x00, 0x00, 0x7a, 0x11, 0x40, 0xfe, 0x80, /* ...z.@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0xff, 0x02, /* ...nW... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, /* ......." */ +0x02, 0x23, 0x00, 0x7a, 0x68, 0xf3, 0x05, 0x76, /* .#.zh..v */ +0x45, 0xe7, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, 0xaa, 0xab, /* .....&.. */ +0xac, 0x6e, 0x57, 0xdd, 0x00, 0x08, 0x00, 0x02, /* .nW..... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x03, 0x00, 0x28, /* k..z...( */ +0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, 0x00, 0x1e, /* .\...... */ +0x00, 0x00, 0x00, 0x30, 0x00, 0x05, 0x00, 0x18, /* ...0.... */ +0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .4...... */ +0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, 0xaf, 0x72, /* .Z...|.r */ +0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x78, /* ...<...x */ +0x00, 0x27, 0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, /* .'....My */ +0x2d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, /* -Device. */ +0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x27 /* .......' */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt17[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x50, /* ...nW..P */ +0xda, 0xc6, 0x5a, 0x48, 0x86, 0xdd, 0x60, 0x00, /* ..ZH..`. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0x40, 0x12, 0x34, /* .....@.4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x93, 0xb4, 0x07, 0x76, /* .".....v */ +0x45, 0xe7, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt18[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x1f, /* ...nW... */ +0x9e, 0x5b, 0x74, 0x02, 0x86, 0xdd, 0x6e, 0x00, /* .[t...n. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, /* ........ */ +0x9e, 0xff, 0xfe, 0x5b, 0x74, 0x02, 0xfe, 0x80, /* ...[t... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x94, 0xe8, 0x07, 0x76, /* .".....v */ +0x45, 0xe7, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (176 bytes) */ +static const unsigned char pkt19[176] = { +0x33, 0x33, 0x00, 0x01, 0x00, 0x02, 0xaa, 0xab, /* 33...... */ +0xac, 0x6e, 0x57, 0xdd, 0x86, 0xdd, 0x60, 0x00, /* .nW...`. */ +0x00, 0x00, 0x00, 0x7a, 0x11, 0x40, 0xfe, 0x80, /* ...z.@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0xff, 0x02, /* ...nW... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, /* ......." */ +0x02, 0x23, 0x00, 0x7a, 0x68, 0xf3, 0x05, 0x76, /* .#.zh..v */ +0x45, 0xe7, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, 0xaa, 0xab, /* .....&.. */ +0xac, 0x6e, 0x57, 0xdd, 0x00, 0x08, 0x00, 0x02, /* .nW..... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x03, 0x00, 0x28, /* k..z...( */ +0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, 0x00, 0x1e, /* .\...... */ +0x00, 0x00, 0x00, 0x30, 0x00, 0x05, 0x00, 0x18, /* ...0.... */ +0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .4...... */ +0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, 0xaf, 0x72, /* .Z...|.r */ +0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x78, /* ...<...x */ +0x00, 0x27, 0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, /* .'....My */ +0x2d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, /* -Device. */ +0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x27 /* .......' */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt20[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x50, /* ...nW..P */ +0xda, 0xc6, 0x5a, 0x48, 0x86, 0xdd, 0x60, 0x00, /* ..ZH..`. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0x40, 0x12, 0x34, /* .....@.4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x93, 0xb4, 0x07, 0x76, /* .".....v */ +0x45, 0xe7, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt21[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x1f, /* ...nW... */ +0x9e, 0x5b, 0x74, 0x02, 0x86, 0xdd, 0x6e, 0x00, /* .[t...n. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, /* ........ */ +0x9e, 0xff, 0xfe, 0x5b, 0x74, 0x02, 0xfe, 0x80, /* ...[t... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x94, 0xe8, 0x07, 0x76, /* .".....v */ +0x45, 0xe7, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (176 bytes) */ +static const unsigned char pkt22[176] = { +0x33, 0x33, 0x00, 0x01, 0x00, 0x02, 0xaa, 0xab, /* 33...... */ +0xac, 0x6e, 0x57, 0xdd, 0x86, 0xdd, 0x60, 0x00, /* .nW...`. */ +0x00, 0x00, 0x00, 0x7a, 0x11, 0x40, 0xfe, 0x80, /* ...z.@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0xff, 0x02, /* ...nW... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, /* ......." */ +0x02, 0x23, 0x00, 0x7a, 0x68, 0xf3, 0x05, 0x76, /* .#.zh..v */ +0x45, 0xe7, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, 0xaa, 0xab, /* .....&.. */ +0xac, 0x6e, 0x57, 0xdd, 0x00, 0x08, 0x00, 0x02, /* .nW..... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x03, 0x00, 0x28, /* k..z...( */ +0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, 0x00, 0x1e, /* .\...... */ +0x00, 0x00, 0x00, 0x30, 0x00, 0x05, 0x00, 0x18, /* ...0.... */ +0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .4...... */ +0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, 0xaf, 0x72, /* .Z...|.r */ +0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x78, /* ...<...x */ +0x00, 0x27, 0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, /* .'....My */ +0x2d, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x00, /* -Device. */ +0x00, 0x06, 0x00, 0x04, 0x00, 0x17, 0x00, 0x27 /* .......' */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt23[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x50, /* ...nW..P */ +0xda, 0xc6, 0x5a, 0x48, 0x86, 0xdd, 0x60, 0x00, /* ..ZH..`. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0x40, 0x12, 0x34, /* .....@.4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x93, 0xb4, 0x07, 0x76, /* .".....v */ +0x45, 0xe7, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; + +/* Frame (198 bytes) */ +static const unsigned char pkt24[198] = { +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x1f, /* ...nW... */ +0x9e, 0x5b, 0x74, 0x02, 0x86, 0xdd, 0x6e, 0x00, /* .[t...n. */ +0x00, 0x00, 0x00, 0x90, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, /* ........ */ +0x9e, 0xff, 0xfe, 0x5b, 0x74, 0x02, 0xfe, 0x80, /* ...[t... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xab, /* ........ */ +0xac, 0xff, 0xfe, 0x6e, 0x57, 0xdd, 0x02, 0x23, /* ...nW..# */ +0x02, 0x22, 0x00, 0x90, 0x94, 0xe8, 0x07, 0x76, /* .".....v */ +0x45, 0xe7, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, /* E....... */ +0x00, 0x01, 0x0f, 0xf4, 0x76, 0x42, 0x00, 0x09, /* ....vB.. */ +0x6b, 0x07, 0xa3, 0x7a, 0x00, 0x01, 0x00, 0x0e, /* k..z.... */ +0x00, 0x01, 0x00, 0x01, 0x99, 0x0a, 0xb5, 0x26, /* .......& */ +0xaa, 0xab, 0xac, 0x6e, 0x57, 0xdd, 0x00, 0x03, /* ...nW... */ +0x00, 0x28, 0x16, 0x5c, 0x19, 0xda, 0x00, 0x00, /* .(.\.... */ +0x00, 0x1e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x05, /* .....0.. */ +0x00, 0x18, 0x12, 0x34, 0x00, 0x00, 0x00, 0x00, /* ...4.... */ +0x00, 0x00, 0x0b, 0x5a, 0xbe, 0xb5, 0x9e, 0x7c, /* ...Z...| */ +0xaf, 0x72, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, /* .r...<.. */ +0x00, 0x78, 0x00, 0x17, 0x00, 0x20, 0x12, 0x34, /* .x... .4 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xab, 0xcd, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x27, /* .......' */ +0x00, 0x0c, 0x00, 0x09, 0x4d, 0x79, 0x2d, 0x44, /* ....My-D */ +0x65, 0x76, 0x69, 0x63, 0x65, 0x00 /* evice. */ +}; +#endif + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_packet_loss_test_application_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: DHCPv6 Packet Loss Test..................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the new physical address. */ + status = nx_ip_interface_physical_address_set(&ip_0, 0, 0x0000aaab, 0xac6e57dd, NX_TRUE); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, dhcpv6_state_change_notify, NX_NULL); + pointer += 2048; + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, NX_DHCPV6_HW_TYPE_IEEE_802, 0x990ab526); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the DNS Server option. */ + status = nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the DHCPv6 Client FQDN option. + operation: NX_DHCPV6_CLIENT_DESIRES_UPDATE_AAAA_RR DHCPv6 Client choose to updating the FQDN-to-IPv6 address mapping for FQDN and address(es) used by the client. + NX_DHCPV6_CLIENT_DESIRES_SERVER_DO_DNS_UPDATE DHCPv6 Client choose to updating the FQDN-to-IPv6 address mapping for FQDN and address(es) used by the client to the server. + NX_DHCPV6_CLIENT_DESIRES_NO_SERVER_DNS_UPDATE DHCPv6 Client choose to request that the server perform no DNS updatest on its behalf. */ + status = nx_dhcpv6_request_option_FQDN(&dhcp_client, "DHCPv6-Client", NX_DHCPV6_CLIENT_DESIRES_UPDATE_AAAA_RR); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the call back function. */ + packet_process_callback = my_packet_process; + + /* Check the available packet. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Request the IPv6 address. */ + status = nx_dhcpv6_request_solicit(&dhcp_client); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 40s to detect requesting and renewing operation. */ + tx_thread_sleep(40 * NX_IP_PERIODIC_RATE); + + /* Check the available packet. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the error counter. */ + if ((error_counter) || (bound_flag != NX_TRUE) || (renew_flag != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +ULONG received_message_type; +ULONG transaction_id; + + /* Update the prepend to point DHCPv6 message, IPv6 header, UDP header. */ + packet_ptr -> nx_packet_prepend_ptr += (40 + 8); + + /* Extract the message type which should be the first byte. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr, 1, &received_message_type); + + /* Parse the transaction ID. */ + _nx_dhcpv6_utility_get_data((packet_ptr -> nx_packet_prepend_ptr + 1), 3, &transaction_id); + + /* Check for an illegal message type. */ + if (received_message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + + /* Send DHCPv6 Server Advertise response. */ + dhcpv6_server_packet_response(transaction_id, 2); + dhcpv6_server_packet_response(transaction_id, 3); + + } + else if(received_message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Send DHCPv6 Server Reply response. */ + dhcpv6_server_packet_response(transaction_id, 5); + dhcpv6_server_packet_response(transaction_id, 6); + } + else if (received_message_type == NX_DHCPV6_MESSAGE_TYPE_RENEW) + { + /* Send DHCPv6 Server Reply response. */ + dhcpv6_server_packet_response(transaction_id, 8); + dhcpv6_server_packet_response(transaction_id, 9); + } + + /* Relase the packet. */ + nx_packet_release(packet_ptr); + + /* Return success. */ + return(NX_SUCCESS); +} +static VOID dhcpv6_server_packet_response(UINT transaction_id, UINT packet_index) +{ +UINT status; +NX_PACKET *response_packet; +UCHAR *data_ptr; +UINT data_size; +UINT offset; +ULONG message_type; +ULONG message_word; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Check the index. */ + if (packet_index == 2) + { + data_ptr = (UCHAR *)pkt2; + } + else if (packet_index == 3) + { + data_ptr = (UCHAR *)pkt3; + } + else if (packet_index == 5) + { + data_ptr = (UCHAR *)pkt5; + } + else if (packet_index == 6) + { + data_ptr = (UCHAR *)pkt6; + } + else if (packet_index == 8) + { + data_ptr = (UCHAR *)pkt8; + } + else if (packet_index == 9) + { + data_ptr = (UCHAR *)pkt9; + } + else + { + + error_counter ++; + return; + } + + /* Set the data size. */ + data_size = 198; + + /* Set the offset(physical header + IPv6 header). */ + offset = 14 + 40; + + /* Write the DHCPv6 Server response messages into the packet payload! */ + status = nx_packet_data_append(response_packet, data_ptr, data_size, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the packet version. */ + response_packet -> nx_packet_ip_version = NX_IP_VERSION_V6; + + /* Set the IP header pointer. */ + response_packet -> nx_packet_ip_header = response_packet -> nx_packet_prepend_ptr + 14; + + /* Update the data pointer tp UDP + DHCPv6 message. */ + response_packet -> nx_packet_prepend_ptr += offset; + response_packet -> nx_packet_length -= offset; + + /* Extract the message type which should be the first byte. */ + _nx_dhcpv6_utility_get_data(response_packet -> nx_packet_prepend_ptr + 8, 1, &message_type); + + /* Clear memory to make the message header. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add the message type and transaction ID as the DHCPv6 header fields. */ + message_word = ((ULONG)message_type << 24); + + /* Set the transaction ID. */ + message_word |= (((ULONG)(0x0ffffff)) & (transaction_id)); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Copy the message header to the packet buffer. */ + memcpy(response_packet -> nx_packet_prepend_ptr + 8, &message_word, 4); + + /* Set the packet interface. */ + response_packet -> nx_packet_address.nx_packet_ipv6_address_ptr = &ip_0.nx_ipv6_address[0]; + + /* Set the interface capablility flag to disable the UDP checksum check, (simplify operation)*/ + ip_0.nx_ipv6_address[0].nxd_ipv6_address_attached -> nx_interface_capability_flag |= NX_INTERFACE_CAPABILITY_UDP_RX_CHECKSUM; + + /* Receive the DHCPv6 Server response. */ + _nx_udp_packet_receive(&ip_0, response_packet); + + return; +} +/* This is the notification from the DHCPv6 Client task that it has changed + state in the DHCPv6 protocol, for example getting assigned an IPv6 lease and + achieving the bound state or an IPv6 lease expires and being reset to + the init state. +*/ +static VOID dhcpv6_state_change_notify(NX_DHCPV6 *dhcpv6_ptr, UINT old_state, UINT new_state) +{ + + + /* Check if the Client has been assigned an IPv6 lease. */ + if ((old_state == NX_DHCPV6_STATE_SENDING_REQUEST) && (new_state == NX_DHCPV6_STATE_BOUND_TO_ADDRESS)) + { + + /* Update the flag. */ + bound_flag = NX_TRUE; + + /* Check the available packet. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + error_counter++; + } + } + + /* Check if the Client has been assigned an IPv6 lease. */ + if ((old_state == NX_DHCPV6_STATE_SENDING_RENEW) && (new_state == NX_DHCPV6_STATE_BOUND_TO_ADDRESS)) + { + + /* Update the flag. */ + renew_flag = NX_TRUE; + + /* Check the available packet. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + error_counter++; + } + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_packet_loss_test_application_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: DHCPv6 Packet Loss Test...................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/dhcp_test/netx_dhcpv6_server_ia_options_test.c b/test/regression/dhcp_test/netx_dhcpv6_server_ia_options_test.c new file mode 100644 index 00000000..7a8e7cfe --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcpv6_server_ia_options_test.c @@ -0,0 +1,699 @@ +/* This tests dhcpv6 server process ia options from the client. */ + +#include +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_udp.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_FRAGMENTATION) +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" +#include "nxd_dhcpv6_server.h" + +#define DEMO_STACK_SIZE 2048 +#define NX_DHCPV6_THREAD_STACK_SIZE 2048 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE (NX_PACKET_SIZE * 8) + +/* Define the ThreadX and NetX object control blocks... */ + +static NX_PACKET_POOL pool_0; +static TX_THREAD thread_client; +static TX_THREAD thread_server; +static NX_IP client_ip; +static NX_IP server_ip; + +/* Define the Client and Server instances. */ + +static NX_DHCPV6 dhcp_client; +static NX_DHCPV6_SERVER dhcp_server; + +/* Define the error counter used in the demo application... */ +static ULONG error_counter; +static CHAR *pointer; + +static NXD_ADDRESS server_address; +static NXD_ADDRESS dns_ipv6_address; +static NXD_ADDRESS start_ipv6_address; +static NXD_ADDRESS end_ipv6_address; + + +/* Define thread prototypes. */ + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +/* Optionally substitute your Ethernet driver here. */ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define some DHCPv6 parameters. */ + +#define DHCPV6_IANA_ID 0xC0DEDBAD +#define DHCPV6_T1 NX_DHCPV6_INFINITE_LEASE +#define DHCPV6_T2 NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_REFERRED_LIFETIME NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_VALID_LIFETIME NX_DHCPV6_INFINITE_LEASE + +#define TEST_VALID_LIFETIME 0x1770 +#define TEST_PREFERRED_LIFETIME 0x0BB8 + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_server_ia_options_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the Client thread. */ + status = tx_thread_create(&thread_client, "Client thread", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create the Server thread. */ + status = tx_thread_create(&thread_server, "Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create a Client IP instance. */ + status = nx_ip_create(&client_ip, "Client IP", IP_ADDRESS(0, 0, 0, 0), + 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create a Server IP instance. */ + status = nx_ip_create(&server_ip, "Server IP", IP_ADDRESS(1, 2, 3, 4), + 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic for sending DHCPv6 messages. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the IPv6 services. */ + status = nxd_ipv6_enable(&client_ip); + status += nxd_ipv6_enable(&server_ip); + + /* Check for IPv6 enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the ICMPv6 services. */ + status = nxd_icmp_enable(&client_ip); + status += nxd_icmp_enable(&server_ip); + + /* Check for ICMP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the fragment feature. */ + status = nx_ip_fragment_enable(&client_ip); + status += nx_ip_fragment_enable(&server_ip); + + /* Check for ICMP enable errors. */ + if (status) + { + error_counter++; + } +} + +/* Define the Client host application thread. */ + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS ipv6_address; +NXD_ADDRESS dns_address; +ULONG prefix_length; +UINT interface_index; +ULONG T1, T2, preferred_lifetime, valid_lifetime; +UINT address_count; +UINT address_index; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: DHCPv6 Server IA Options Test........................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Establish the link local address for the host. The RAM driver creates + a virtual MAC address of 0x1122334456. */ + status = nxd_ipv6_address_set(&client_ip, 0, NX_NULL, 10, NULL); + + /* Let NetX Duo and the network driver get initialized. Also give the server time to get set up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create the DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &client_ip, "DHCPv6 Client", &pool_0, pointer, NX_DHCPV6_THREAD_STACK_SIZE, + NX_NULL, NX_NULL); + pointer = pointer + NX_DHCPV6_THREAD_STACK_SIZE; + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. + + Note that if this host had already been assigned in IPv6 lease, it + would have to use the assigned T1 and T2 values in loading the DHCPv6 + client with an IANA block. + */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, DHCPV6_T1, DHCPV6_T2); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Starting up the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* If the host also want to get the option message, set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Set the callback function to process the Message packet from DHCPv6 Server. */ + advanced_packet_process_callback = my_packet_process; + + /* Now, the host send the solicit message to get the IPv6 address and other options from the DHCPv6 server. */ + status = nx_dhcpv6_request_solicit(&dhcp_client); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for get the IPv6 address and do the duplicate address detection. */ + tx_thread_sleep(6 * NX_IP_PERIODIC_RATE); + + /* Get the valid IPv6 address count which the DHCPv6 server assigned . */ + status = nx_dhcpv6_get_valid_ip_address_count(&dhcp_client, &address_count); + + /* Check for errors. */ + if ((status) || (address_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address, preferred lifetime and valid lifetime according to the address index. */ + address_index = 0; + status = nx_dhcpv6_get_valid_ip_address_lease_time(&dhcp_client, address_index, &ipv6_address, &preferred_lifetime, &valid_lifetime); + + /* Check for errors. */ + if ((status) || (address_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by DHCPv6 API. */ + status = nx_dhcpv6_get_IP_address(&dhcp_client, &ipv6_address); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address. */ + if ((ipv6_address.nxd_ip_version != start_ipv6_address.nxd_ip_version) || + (ipv6_address.nxd_ip_address.v6[0] != start_ipv6_address.nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != start_ipv6_address.nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != start_ipv6_address.nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != start_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by NetX Duo API. */ + status = nxd_ipv6_address_get(&client_ip, 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IPv6 address. */ + if ((prefix_length != 64) || (interface_index != 0) || + (ipv6_address.nxd_ip_version != start_ipv6_address.nxd_ip_version) || + (ipv6_address.nxd_ip_address.v6[0] != start_ipv6_address.nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != start_ipv6_address.nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != start_ipv6_address.nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != start_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get IP address lease time. + Note, This API only applies to one IA. */ + status = nx_dhcpv6_get_lease_time_data(&dhcp_client, &T1, &T2, &preferred_lifetime, &valid_lifetime); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the value. */ + if ((T1 != NX_DHCPV6_DEFAULT_T1_TIME) || + (T2 != NX_DHCPV6_DEFAULT_T2_TIME) || + (preferred_lifetime != NX_DHCPV6_DEFAULT_PREFERRED_TIME) || + (valid_lifetime != NX_DHCPV6_DEFAULT_VALID_TIME)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the DNS Server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_address); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IPv6 DNS address. */ + if ((dns_address.nxd_ip_version != dns_ipv6_address.nxd_ip_version) || + (dns_address.nxd_ip_address.v6[0] != dns_ipv6_address.nxd_ip_address.v6[0]) || + (dns_address.nxd_ip_address.v6[1] != dns_ipv6_address.nxd_ip_address.v6[1]) || + (dns_address.nxd_ip_address.v6[2] != dns_ipv6_address.nxd_ip_address.v6[2]) || + (dns_address.nxd_ip_address.v6[3] != dns_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now, send the confirm message. */ + status = nx_dhcpv6_request_confirm(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for release the IPv6 address. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE * 6); + + /* Release the address. */ + status = nx_dhcpv6_request_release(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for release the IPv6 address. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Get the IPv6 address by DHCPv6 API. */ + status = nx_dhcpv6_get_IP_address(&dhcp_client, &ipv6_address); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by NetX Duo API. */ + status = nxd_ipv6_address_get(&client_ip, 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Stop the Client task. */ + status = nx_dhcpv6_stop(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the DHCPv6 client. */ + status = nx_dhcpv6_client_delete(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successfully. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the test server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +ULONG duid_time; +UINT addresses_added; + + /* Set the IPv6 address of DHCPv6 Server. */ + server_address.nxd_ip_version = NX_IP_VERSION_V6 ; + server_address.nxd_ip_address.v6[0] = 0x20010db8; + server_address.nxd_ip_address.v6[1] = 0xf101; + server_address.nxd_ip_address.v6[2] = 0x00000000; + server_address.nxd_ip_address.v6[3] = 0x00000101; + + /* Set the link local and global addresses. */ + status = nxd_ipv6_address_set(&server_ip, 0, NX_NULL, 10, NULL); + status += nxd_ipv6_address_set(&server_ip, 0, &server_address, 64, NULL); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Validate the link local and global addresses. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create the DHCPv6 Server. */ + status = nx_dhcpv6_server_create(&dhcp_server, &server_ip, "DHCPv6 Server", &pool_0, pointer, NX_DHCPV6_SERVER_THREAD_STACK_SIZE, NX_NULL, NX_NULL); + pointer += NX_DHCPV6_SERVER_THREAD_STACK_SIZE; + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set up the DNS IPv6 server address. */ + dns_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + dns_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + dns_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + dns_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + dns_ipv6_address.nxd_ip_address.v6[3] = 0x00000107; + + status = nx_dhcpv6_create_dns_address(&dhcp_server, &dns_ipv6_address); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Note: For DUID types that do not require time, the 'duid_time' input can be left at zero. + The DUID_TYPE and HW_TYPE are configurable options that are user defined in nx_dhcpv6_server.h. */ + + /* Set the DUID time as the start of the millenium. */ + duid_time = SECONDS_SINCE_JAN_1_2000_MOD_32; + status = nx_dhcpv6_set_server_duid(&dhcp_server, + NX_DHCPV6_SERVER_DUID_TYPE, NX_DHCPV6_SERVER_HW_TYPE, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_msw, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_lsw, + duid_time); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 start address. */ + start_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + start_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + start_ipv6_address.nxd_ip_address.v6[1] = 0x00000f101; + start_ipv6_address.nxd_ip_address.v6[2] = 0x0; + start_ipv6_address.nxd_ip_address.v6[3] = 0x00000110; + + /* Set the IPv6 end address. */ + end_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + end_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + end_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + end_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + end_ipv6_address.nxd_ip_address.v6[3] = 0x00000120; + + /* Set the IPv6 address range. */ + status = nx_dhcpv6_create_ip_address_range(&dhcp_server, &start_ipv6_address, &end_ipv6_address, &addresses_added); + + /* Check for errors. */ + if ((status) || (addresses_added != 16)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + server_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start the NetX DHCPv6 server! */ + status = nx_dhcpv6_server_start(&dhcp_server); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UCHAR message_type; +UCHAR reserved[3]; +static UINT confirm_sent = NX_FALSE; + + + /* Check the IP. */ + if (ip_ptr == &client_ip) + { + + /* Get the message type. */ + message_type = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 8); + + /* Check if it is CONFIRM message from DHCPv6 client. */ + if (message_type == NX_DHCPV6_MESSAGE_TYPE_CONFIRM) + { + confirm_sent = NX_TRUE; + } + } + if (ip_ptr == &server_ip) + { + + /* Get the message type. */ + message_type = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 8); + + /* Check if it is REPLY message from DHCPv6 server. */ + if (message_type == NX_DHCPV6_MESSAGE_TYPE_REPLY) + { + if (confirm_sent == NX_TRUE) + { + confirm_sent = NX_FALSE; + + if (dhcp_server.nx_dhcpv6_clients[0].nx_dhcpv6_ia.nx_valid_lifetime == TEST_VALID_LIFETIME) + { + return(NX_FALSE); + } + + if (dhcp_server.nx_dhcpv6_clients[0].nx_dhcpv6_ia.nx_preferred_lifetime == TEST_PREFERRED_LIFETIME) + { + return(NX_FALSE); + } + } + } + } + + return(NX_TRUE); +} + +void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +ULONG message_type; +NX_UDP_HEADER *udp_header_ptr; +ULONG *requested_lease_time; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG *ip_src_addr = NX_NULL; +ULONG *ip_dest_addr = NX_NULL; + + + udp_header_ptr = (NX_UDP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + /* Get the message type. */ + message_type = *(packet_ptr -> nx_packet_prepend_ptr + 8); + + /* Check if the message is a CONFIRM. */ + if (message_type == NX_DHCPV6_MESSAGE_TYPE_CONFIRM) + { + + /* Force change the valid lifetime and preferred lifetime. */ + *(packet_ptr -> nx_packet_prepend_ptr + 74) = 0x0B; + *(packet_ptr -> nx_packet_prepend_ptr + 75) = 0xB8; + *(packet_ptr -> nx_packet_prepend_ptr + 78) = 0x17; + *(packet_ptr -> nx_packet_prepend_ptr + 79) = 0x70; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* compute the checksum. */ + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Restore the udp packet receiving function. */ + server_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } + + /* Let server receives the packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_server_ia_options_test_application_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: DHCPv6 Server IA Options Test...............................N/A\n"); + test_control_return(3); +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/dhcp_test/netx_dhcpv6_server_iana_test.c b/test/regression/dhcp_test/netx_dhcpv6_server_iana_test.c new file mode 100644 index 00000000..ea845ee9 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcpv6_server_iana_test.c @@ -0,0 +1,352 @@ +/* Verify DHCPv6 Server can correctly process IANA option in DHCPv6 Solicit message. */ + +/* Procedure + 1.Memset the packet pool. + 2.Create DHCPv6 Server. + 3.Inject DHCPv6 Solicit message. + 4.Check if receive DHCPv6 Advertise message from DHCPv6 Server. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#ifdef FEATURE_NX_IPV6 +#include "nxd_dhcpv6_server.h" + + +#define DEMO_STACK_SIZE 4096 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8 + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_DHCPV6_SERVER dhcp_server; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UCHAR advertise_message_count = 0; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void server_thread_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define some DHCPv6 parameters. */ + +#define DHCPV6_IANA_ID 0xC0DEDBAD +#define DHCPV6_T1 NX_DHCPV6_INFINITE_LEASE +#define DHCPV6_T2 NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_REFERRED_LIFETIME NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_VALID_LIFETIME NX_DHCPV6_INFINITE_LEASE + +static NXD_ADDRESS server_address; +static NXD_ADDRESS dns_ipv6_address; +static NXD_ADDRESS start_ipv6_address; +static NXD_ADDRESS end_ipv6_address; +static ULONG client_address[4]; +static CHAR mac[6]; + + +/* Frame (342 bytes) DHCPv6 Solicit, IANA is filled in the last option. */ +static const unsigned char pkt1[118] = { +0x33, 0x33, 0x00, 0x01, 0x00, 0x02, 0x08, 0x00, /* 33...... */ +0x27, 0xdf, 0x0b, 0xb2, 0x86, 0xdd, 0x60, 0x0c, /* '.....`. */ +0x28, 0xf6, 0x00, 0x40, 0x11, 0x01, 0xfe, 0x80, /* (..@.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, /* ........ */ +0x27, 0xff, 0xfe, 0xdf, 0x0b, 0xb2, 0xff, 0x02, /* '....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x22, /* ......." */ +0x02, 0x23, 0x00, 0x40, 0xb2, 0x37, 0x01, 0xdd, /* .#.@.7.. */ +0xf3, 0x3a, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, /* .:...... */ +0x00, 0x01, 0x20, 0xec, 0x65, 0xde, 0x08, 0x00, /* .. .e... */ +0x27, 0xdf, 0x0b, 0xb2, 0x00, 0x06, 0x00, 0x08, /* '....... */ +0x00, 0x17, 0x00, 0x18, 0x00, 0x27, 0x00, 0x1f, /* .....'.. */ +0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, /* ........ */ +0x00, 0x0c, 0x27, 0xdf, 0x0b, 0xb2, 0x00, 0x00, /* ..'..... */ +0x0e, 0x10, 0x00, 0x00, 0x15, 0x18 /* ...... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_server_iana_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "thread server", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Clear the memory value. */ + memset(pointer, 0, NX_PACKET_POOL_SIZE); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance for the DHCP Server. */ + status = nx_ip_create(&server_ip, "DHCP Server", IP_ADDRESS(10, 0, 0, 1), 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable the IPv6 services. */ + status = nxd_ipv6_enable(&server_ip); + + /* Check for IPv6 enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP. */ + status = nxd_icmp_enable(&server_ip); + + /* Check for errors. */ + if (status) + error_counter++; + + return; +} + +/* Define the test threads. */ + +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +ULONG duid_time; +UINT addresses_added; +NX_PACKET *my_packet; + + printf("NetX Test: NetX DHCPv6 Server IANA Test.............................."); + + /* Set the IPv6 address of DHCPv6 Server. */ + server_address.nxd_ip_version = NX_IP_VERSION_V6 ; + server_address.nxd_ip_address.v6[0] = 0x20010db8; + server_address.nxd_ip_address.v6[1] = 0xf101; + server_address.nxd_ip_address.v6[2] = 0x00000000; + server_address.nxd_ip_address.v6[3] = 0x00000101; + + /* Set the link local and global addresses. */ + status = nxd_ipv6_address_set(&server_ip, 0, NX_NULL, 10, NULL); + status += nxd_ipv6_address_set(&server_ip, 0, &server_address, 64, NULL); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the ND Cache for DHCPv6 Client. */ + client_address[0] = 0xfe800000; + client_address[1] = 0x00000000; + client_address[2] = 0x0a0027ff; + client_address[3] = 0xfedf0bb2; + mac[0] = 0x08; + mac[1] = 0x00; + mac[2] = 0x27; + mac[3] = 0xdf; + mac[4] = 0x0b; + mac[5] = 0xb2; + status = nxd_nd_cache_entry_set(&server_ip, client_address, 0, mac); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Validate the link local and global addresses. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create the DHCPv6 Server. */ + status = nx_dhcpv6_server_create(&dhcp_server, &server_ip, "DHCPv6 Server", &server_pool, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set up the DNS IPv6 server address. */ + dns_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + dns_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + dns_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + dns_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + dns_ipv6_address.nxd_ip_address.v6[3] = 0x00000107; + + status = nx_dhcpv6_create_dns_address(&dhcp_server, &dns_ipv6_address); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Note: For DUID types that do not require time, the 'duid_time' input can be left at zero. + The DUID_TYPE and HW_TYPE are configurable options that are user defined in nx_dhcpv6_server.h. */ + + /* Set the DUID time as the start of the millenium. */ + duid_time = SECONDS_SINCE_JAN_1_2000_MOD_32; + status = nx_dhcpv6_set_server_duid(&dhcp_server, + NX_DHCPV6_SERVER_DUID_TYPE, NX_DHCPV6_SERVER_HW_TYPE, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_msw, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_lsw, + duid_time); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 start address. */ + start_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + start_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + start_ipv6_address.nxd_ip_address.v6[1] = 0x00000f101; + start_ipv6_address.nxd_ip_address.v6[2] = 0x0; + start_ipv6_address.nxd_ip_address.v6[3] = 0x00000110; + + /* Set the IPv6 end address. */ + end_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + end_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + end_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + end_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + end_ipv6_address.nxd_ip_address.v6[3] = 0x00000120; + + /* Set the IPv6 address range. */ + status = nx_dhcpv6_create_ip_address_range(&dhcp_server, &start_ipv6_address, &end_ipv6_address, &addresses_added); + + /* Check for errors. */ + if ((status) || (addresses_added != 16)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the NetX DHCPv6 server! */ + status = nx_dhcpv6_server_start(&dhcp_server); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the DHCP DISCOVER packet. */ + status = nx_packet_allocate(&server_pool, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Set the callback function to process the Message packet from DHCPv6 Server. */ + advanced_packet_process_callback = my_packet_process; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + my_packet -> nx_packet_length = sizeof(pkt1) - 14; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + sizeof(pkt1) - 14; + + /* Directly receive the DHCP DISCOVER packet. */ + _nx_ip_packet_deferred_receive(&server_ip, my_packet); + + /* Check if receive the advertise message. */ + if (advertise_message_count != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successfully. */ + printf("SUCCESS!\n"); + test_control_return(0); + + return; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UCHAR message_type; + + + /* Check the IP. */ + if (ip_ptr == &server_ip) + { + + /* Get the message type. */ + message_type = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 8); + + /* Check if it is Advertise message from DHCPv6 Server. */ + if (message_type == NX_DHCPV6_MESSAGE_TYPE_ADVERTISE) + { + + /* Yes, receive the advertise message. */ + advertise_message_count ++; + } + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_server_iana_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NetX DHCPv6 Server IANA Test..............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dhcp_test/netx_dhcpv6_server_process_repeated_msgs_test.c b/test/regression/dhcp_test/netx_dhcpv6_server_process_repeated_msgs_test.c new file mode 100644 index 00000000..01ffde00 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcpv6_server_process_repeated_msgs_test.c @@ -0,0 +1,771 @@ +/* This is a small demo of the NetX Duo DHCPv6 Client and Server for the high-performance + NetX Duo stack. */ + +#include +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_udp.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_FRAGMENTATION) +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" +#include "nxd_dhcpv6_server.h" + +#define DEMO_STACK_SIZE 2048 +#define NX_DHCPV6_THREAD_STACK_SIZE 2048 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE (NX_PACKET_SIZE * 8) + +/* Define the ThreadX and NetX object control blocks... */ + +static NX_PACKET_POOL pool_0; +static TX_THREAD thread_client; +static TX_THREAD thread_server; +static NX_IP client_ip; +static NX_IP server_ip; + +/* Define the Client and Server instances. */ + +static NX_DHCPV6 dhcp_client; +static NX_DHCPV6_SERVER dhcp_server; + +/* Define the error counter used in the demo application... */ +static ULONG error_counter; +static CHAR *pointer; +static UCHAR advertise_message_count = 0; +static UCHAR reply_message_count = 0; + +static NXD_ADDRESS server_address; +static NXD_ADDRESS dns_ipv6_address; +static NXD_ADDRESS start_ipv6_address; +static NXD_ADDRESS end_ipv6_address; + +static UCHAR client_xid[3] = {0, 0, 0}; +static UCHAR server_xid[3] = {0, 0, 0}; + + +/* Define thread prototypes. */ + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +/******** Optionally substitute your Ethernet driver here. ***********/ + +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define some DHCPv6 parameters. */ + +#define DHCPV6_IANA_ID 0xC0DEDBAD +#define DHCPV6_T1 NX_DHCPV6_INFINITE_LEASE +#define DHCPV6_T2 NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_REFERRED_LIFETIME NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_VALID_LIFETIME NX_DHCPV6_INFINITE_LEASE + +/* Define the cycle times for repeating the test. */ +#define TEST_REPEATING_CYCLE 2 + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_server_process_repeated_msg_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the Client thread. */ + status = tx_thread_create(&thread_client, "Client thread", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create the Server thread. */ + status = tx_thread_create(&thread_server, "Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create a Client IP instance. */ + status = nx_ip_create(&client_ip, "Client IP", IP_ADDRESS(0, 0, 0, 0), + 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create a Server IP instance. */ + status = nx_ip_create(&server_ip, "Server IP", IP_ADDRESS(1, 2, 3, 4), + 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic for sending DHCPv6 messages. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the IPv6 services. */ + status = nxd_ipv6_enable(&client_ip); + status += nxd_ipv6_enable(&server_ip); + + /* Check for IPv6 enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the ICMPv6 services. */ + status = nxd_icmp_enable(&client_ip); + status += nxd_icmp_enable(&server_ip); + + /* Check for ICMP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the fragment feature. */ + status = nx_ip_fragment_enable(&client_ip); + status += nx_ip_fragment_enable(&server_ip); + + /* Check for ICMP enable errors. */ + if (status) + { + error_counter++; + } +} + +/* Define the Client host application thread. */ + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS ipv6_address; +NXD_ADDRESS dns_address; +ULONG prefix_length; +UINT interface_index; +ULONG T1, T2, preferred_lifetime, valid_lifetime; +UINT address_count; +UINT address_index; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: DHCPv6 Server Process Repeated Msg Test........................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Establish the link local address for the host. The RAM driver creates + a virtual MAC address of 0x1122334456. */ + status = nxd_ipv6_address_set(&client_ip, 0, NX_NULL, 10, NULL); + + /* Let NetX Duo and the network driver get initialized. Also give the server time to get set up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create the DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &client_ip, "DHCPv6 Client", &pool_0, pointer, NX_DHCPV6_THREAD_STACK_SIZE, + NX_NULL, NX_NULL); + pointer = pointer + NX_DHCPV6_THREAD_STACK_SIZE; + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. + + Note that if this host had already been assigned in IPv6 lease, it + would have to use the assigned T1 and T2 values in loading the DHCPv6 + client with an IANA block. + */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, DHCPV6_T1, DHCPV6_T2); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Starting up the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* If the host also want to get the option message, set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Set the callback function to process the Message packet from DHCPv6 Server. */ + advanced_packet_process_callback = my_packet_process; + + /* Now, the host send the solicit message to get the IPv6 address and other options from the DHCPv6 server. */ + status = nx_dhcpv6_request_solicit(&dhcp_client); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for get the IPv6 address and do the duplicate address detection. */ + tx_thread_sleep(6 * NX_IP_PERIODIC_RATE); + + /* Get the valid IPv6 address count which the DHCPv6 server assigned . */ + status = nx_dhcpv6_get_valid_ip_address_count(&dhcp_client, &address_count); + + /* Check for errors. */ + if ((status) || (address_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address, preferred lifetime and valid lifetime according to the address index. */ + address_index = 0; + status = nx_dhcpv6_get_valid_ip_address_lease_time(&dhcp_client, address_index, &ipv6_address, &preferred_lifetime, &valid_lifetime); + + /* Check for errors. */ + if ((status) || (address_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by DHCPv6 API. */ + status = nx_dhcpv6_get_IP_address(&dhcp_client, &ipv6_address); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address. */ + if ((ipv6_address.nxd_ip_version != start_ipv6_address.nxd_ip_version) || + (ipv6_address.nxd_ip_address.v6[0] != start_ipv6_address.nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != start_ipv6_address.nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != start_ipv6_address.nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != start_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by NetX Duo API. */ + status = nxd_ipv6_address_get(&client_ip, 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IPv6 address. */ + if ((prefix_length != 64) || (interface_index != 0) || + (ipv6_address.nxd_ip_version != start_ipv6_address.nxd_ip_version) || + (ipv6_address.nxd_ip_address.v6[0] != start_ipv6_address.nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != start_ipv6_address.nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != start_ipv6_address.nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != start_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get IP address lease time. + Note, This API only applies to one IA. */ + status = nx_dhcpv6_get_lease_time_data(&dhcp_client, &T1, &T2, &preferred_lifetime, &valid_lifetime); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the value. */ + if ((T1 != NX_DHCPV6_DEFAULT_T1_TIME) || + (T2 != NX_DHCPV6_DEFAULT_T2_TIME) || + (preferred_lifetime != NX_DHCPV6_DEFAULT_PREFERRED_TIME) || + (valid_lifetime != NX_DHCPV6_DEFAULT_VALID_TIME)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the DNS Server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_address); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IPv6 DNS address. */ + if ((dns_address.nxd_ip_version != dns_ipv6_address.nxd_ip_version) || + (dns_address.nxd_ip_address.v6[0] != dns_ipv6_address.nxd_ip_address.v6[0]) || + (dns_address.nxd_ip_address.v6[1] != dns_ipv6_address.nxd_ip_address.v6[1]) || + (dns_address.nxd_ip_address.v6[2] != dns_ipv6_address.nxd_ip_address.v6[2]) || + (dns_address.nxd_ip_address.v6[3] != dns_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + for (UINT i = 0; i < TEST_REPEATING_CYCLE; i++) + { + + /* Now, send the confirm message multiple-times. */ + status = nx_dhcpv6_request_confirm(&dhcp_client); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for get the IPv6 address and do the duplicate address detection. */ + tx_thread_sleep(10 * NX_IP_PERIODIC_RATE); + } + + /* Check reply message count so far: */ + if (reply_message_count != 3) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the address. */ + status = nx_dhcpv6_request_release(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for release the IPv6 address. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Get the IPv6 address by DHCPv6 API. */ + status = nx_dhcpv6_get_IP_address(&dhcp_client, &ipv6_address); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by NetX Duo API. */ + status = nxd_ipv6_address_get(&client_ip, 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Stop the Client task. */ + status = nx_dhcpv6_stop(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the DHCPv6 client. */ + status = nx_dhcpv6_client_delete(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successfully. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the test server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +ULONG duid_time; +UINT addresses_added; + + /* Set the IPv6 address of DHCPv6 Server. */ + server_address.nxd_ip_version = NX_IP_VERSION_V6 ; + server_address.nxd_ip_address.v6[0] = 0x20010db8; + server_address.nxd_ip_address.v6[1] = 0xf101; + server_address.nxd_ip_address.v6[2] = 0x00000000; + server_address.nxd_ip_address.v6[3] = 0x00000101; + + /* Set the link local and global addresses. */ + status = nxd_ipv6_address_set(&server_ip, 0, NX_NULL, 10, NULL); + status += nxd_ipv6_address_set(&server_ip, 0, &server_address, 64, NULL); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Validate the link local and global addresses. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create the DHCPv6 Server. */ + status = nx_dhcpv6_server_create(&dhcp_server, &server_ip, "DHCPv6 Server", &pool_0, pointer, NX_DHCPV6_SERVER_THREAD_STACK_SIZE, NX_NULL, NX_NULL); + pointer += NX_DHCPV6_SERVER_THREAD_STACK_SIZE; + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set up the DNS IPv6 server address. */ + dns_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + dns_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + dns_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + dns_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + dns_ipv6_address.nxd_ip_address.v6[3] = 0x00000107; + + status = nx_dhcpv6_create_dns_address(&dhcp_server, &dns_ipv6_address); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Note: For DUID types that do not require time, the 'duid_time' input can be left at zero. + The DUID_TYPE and HW_TYPE are configurable options that are user defined in nx_dhcpv6_server.h. */ + + /* Set the DUID time as the start of the millenium. */ + duid_time = SECONDS_SINCE_JAN_1_2000_MOD_32; + status = nx_dhcpv6_set_server_duid(&dhcp_server, + NX_DHCPV6_SERVER_DUID_TYPE, NX_DHCPV6_SERVER_HW_TYPE, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_msw, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_lsw, + duid_time); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 start address. */ + start_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + start_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + start_ipv6_address.nxd_ip_address.v6[1] = 0x00000f101; + start_ipv6_address.nxd_ip_address.v6[2] = 0x0; + start_ipv6_address.nxd_ip_address.v6[3] = 0x00000110; + + /* Set the IPv6 end address. */ + end_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + end_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + end_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + end_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + end_ipv6_address.nxd_ip_address.v6[3] = 0x00000120; + + /* Set the IPv6 address range. */ + status = nx_dhcpv6_create_ip_address_range(&dhcp_server, &start_ipv6_address, &end_ipv6_address, &addresses_added); + + /* Check for errors. */ + if ((status) || (addresses_added != 16)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the NetX DHCPv6 server! */ + status = nx_dhcpv6_server_start(&dhcp_server); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UCHAR message_type; +static UCHAR last_client_message_type; +static UCHAR confirm_msg_cnt = 0; +NX_UDP_HEADER *udp_header_ptr; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; + + + /* Get the message type. */ + message_type = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 8); + switch (message_type) + { + + case NX_DHCPV6_MESSAGE_TYPE_SOLICIT: + case NX_DHCPV6_MESSAGE_TYPE_REQUEST: + case NX_DHCPV6_MESSAGE_TYPE_RELEASE: + { + if (ip_ptr != &client_ip) + { + return(NX_FALSE); + } + + /* Store the message type for server reply message to know. */ + last_client_message_type = message_type; + + /* Get the xid. */ + client_xid[0] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 9); + client_xid[1] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 10); + client_xid[2] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 11); + + break; + } + + case NX_DHCPV6_MESSAGE_TYPE_CONFIRM: + { + if (ip_ptr != &client_ip) + { + return(NX_FALSE); + } + + /* Store the message type for server reply message to know. */ + last_client_message_type = message_type; + + /* Get the xid. */ + client_xid[0] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 9); + client_xid[1] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 10); + client_xid[2] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 11); + + /* Increase the sent confirm msg number, and hack the second msg. */ + confirm_msg_cnt++; + if (confirm_msg_cnt == 2) + { + + // /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Modify the elapse time. */ + *(packet_ptr -> nx_packet_prepend_ptr + 8 + 26) = 0x01; + *(packet_ptr -> nx_packet_prepend_ptr + 8 + 27) = 0x02; + + /* Compute the checksum. */ + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + break; + } + + /* Check if it is Advertise message from DHCPv6 Server. */ + case NX_DHCPV6_MESSAGE_TYPE_ADVERTISE: + { + if (ip_ptr != &server_ip) + { + return(NX_FALSE); + } + + /* Get the xid. */ + server_xid[0] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 9); + server_xid[1] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 10); + server_xid[2] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 11); + + /* Compare the server xid with previous client xid. */ + if (memcmp(client_xid, server_xid, 3)) + { + return(NX_FALSE); + } + + /* Yes, add the count for advertise message. */ + advertise_message_count++; + break; + } + + case NX_DHCPV6_MESSAGE_TYPE_REPLY: + { + if (ip_ptr != &server_ip) + { + return(NX_FALSE); + } + + /* Get the xid. */ + server_xid[0] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 9); + server_xid[1] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 10); + server_xid[2] = *(packet_ptr -> nx_packet_prepend_ptr + 40 + 11); + + /* Compare the server xid with previous client xid. */ + if (memcmp(client_xid, server_xid, 3)) + { + return(NX_FALSE); + } + + if (last_client_message_type == NX_DHCPV6_MESSAGE_TYPE_CONFIRM) + { + if (confirm_msg_cnt >= 2) + { + if (dhcp_server.nx_dhcpv6_clients[0].nx_dhcpv6_elapsed_time.nx_session_time == 0) + { + return(NX_FALSE); + } + } + } + + /* Yes, add the count for next time to send reply message. */ + reply_message_count++; + break; + } + + default: + { + break; + } + } + + return(NX_TRUE); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_server_process_repeated_msg_test_application_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: DHCPv6 Server Process Repeated Msg Test.........................................N/A\n"); + test_control_return(3); +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/dhcp_test/netx_dhcpv6_user_option_add_test.c b/test/regression/dhcp_test/netx_dhcpv6_user_option_add_test.c new file mode 100644 index 00000000..b2d8ef91 --- /dev/null +++ b/test/regression/dhcp_test/netx_dhcpv6_user_option_add_test.c @@ -0,0 +1,710 @@ +/* This tests adding user class option. */ + +#include +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_FRAGMENTATION) +#include "nxd_dhcpv6_client.h" +#include "nxd_dhcpv6_server.h" + +#define DEMO_STACK_SIZE 2048 +#define NX_DHCPV6_THREAD_STACK_SIZE 2048 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE (NX_PACKET_SIZE * 8) + +/* Define the ThreadX and NetX object control blocks... */ + +static NX_PACKET_POOL pool_0; +static TX_THREAD thread_client; +static TX_THREAD thread_server; +static NX_IP client_ip; +static NX_IP server_ip; + +/* Define the Client and Server instances. */ + +static NX_DHCPV6 dhcp_client; +static NX_DHCPV6_SERVER dhcp_server; + +/* Define the error counter used in the demo application... */ +static ULONG error_counter; +static CHAR *pointer; + +static NXD_ADDRESS server_address; +static NXD_ADDRESS dns_ipv6_address; +static NXD_ADDRESS start_ipv6_address; +static NXD_ADDRESS end_ipv6_address; + + +/* Define thread prototypes. */ + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +extern void _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); +extern VOID _nx_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define some DHCPv6 parameters. */ + +#define DHCPV6_IANA_ID 0xC0DEDBAD +#define DHCPV6_T1 NX_DHCPV6_INFINITE_LEASE +#define DHCPV6_T2 NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_REFERRED_LIFETIME NX_DHCPV6_INFINITE_LEASE +#define NX_DHCPV6_VALID_LIFETIME NX_DHCPV6_INFINITE_LEASE + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_user_option_add_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the Client thread. */ + status = tx_thread_create(&thread_client, "Client thread", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create the Server thread. */ + status = tx_thread_create(&thread_server, "Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create a Client IP instance. */ + status = nx_ip_create(&client_ip, "Client IP", IP_ADDRESS(0, 0, 0, 0), + 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create a Server IP instance. */ + status = nx_ip_create(&server_ip, "Server IP", IP_ADDRESS(1, 2, 3, 4), + 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic for sending DHCPv6 messages. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the IPv6 services. */ + status = nxd_ipv6_enable(&client_ip); + status += nxd_ipv6_enable(&server_ip); + + /* Check for IPv6 enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the ICMPv6 services. */ + status = nxd_icmp_enable(&client_ip); + status += nxd_icmp_enable(&server_ip); + + /* Check for ICMP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable the fragment feature. */ + status = nx_ip_fragment_enable(&client_ip); + status += nx_ip_fragment_enable(&server_ip); + + /* Check for ICMP enable errors. */ + if (status) + { + error_counter++; + } +} + + +static CHAR user_class[] = "USERCLASS"; +static UINT user_class_len = sizeof(user_class) - 1; +static USHORT user_class_code = 15; + +UINT dhcpv6_user_option_add(NX_DHCPV6 *dhcpv6_ptr, UINT interface_index, UINT message_type, UCHAR *user_option_ptr, UINT *user_option_length) +{ + + NX_PARAMETER_NOT_USED(dhcpv6_ptr); + NX_PARAMETER_NOT_USED(interface_index); + NX_PARAMETER_NOT_USED(message_type); + + /* Application can check if add options into the packet by interface_index and message_type. + message_type are defined in header file, such as: NX_DHCPV6_MESSAGE_TYPE_SOLICIT. */ + + /* Add user class option refer to RFC8415. */ + /* The format of the User Class option is: + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | OPTION_USER_CLASS | option-len | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . . + . user-class-data . + . . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + The data area of the User Class option MUST contain one or more + instances of user-class-data information. Each instance of + user-class-data is formatted as follows: + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+ + | user-class-len | opaque-data | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+ + + The user-class-len field is 2 octets long and specifies the length of + the opaque user-class-data in network byte order. + */ + + /* Check if have enough space for this option. */ + if (*user_option_length < (user_class_len + 6)) + return(NX_FALSE); + + /* Set the option code. */ + *user_option_ptr = (UCHAR)(user_class_code >> 8); + *(user_option_ptr + 1) = (UCHAR)user_class_code; + + /* Set the option length. */ + *(user_option_ptr + 2) = (UCHAR)((user_class_len + 2) >> 8); + *(user_option_ptr + 3) = (UCHAR)(user_class_len + 2); + + /* Set the user class length, which is the total length of the user class data filed. */ + *(user_option_ptr + 4) = (UCHAR)((user_class_len + 2) >> 8); + *(user_option_ptr + 5) = (UCHAR)(user_class_len + 2); + + /* Set the option value. */ + memcpy((user_option_ptr + 6), user_class, user_class_len); + + /* Update the option length. */ + *user_option_length = (user_class_len + 6); + return(NX_TRUE); +} + +VOID my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +UCHAR *user_class_ptr = NX_NULL; +UCHAR *dhcpv6_option_ptr = NX_NULL; +UINT index, status; +ULONG option_length = 0, option_code = 0; + + /* Update index to the options. */ + index = 8 + 4; + dhcpv6_option_ptr = packet_ptr -> nx_packet_prepend_ptr + index; + + /* Search the user class option. */ + while (index + 4 <= packet_ptr -> nx_packet_length) + { + + /* Get the option code and length of data of the current option block. */ + status = _nx_dhcpv6_utility_get_block_option_length(dhcpv6_option_ptr, &option_code, &option_length); + + /* Check that the block data is valid. */ + if (status != NX_SUCCESS) + { + error_counter++; + break; + } + + /* Check if option data is in the packet. */ + if ((dhcpv6_option_ptr + 4 + option_length) > packet_ptr -> nx_packet_append_ptr) + { + error_counter++; + break; + } + + if (option_code == user_class_code) + { + user_class_ptr = dhcpv6_option_ptr; + break; + } + + /* Move to the next top level option. */ + dhcpv6_option_ptr += option_length + 4; + + /* Keep track of how far into the packet we have parsed. */ + index += option_length + 4; + } + + /* Check if have the user class option. */ + if (user_class_ptr == NX_NULL || option_length != (user_class_len + 2)) + { + error_counter++; + } + else + { + /* Skip the option header. */ + user_class_ptr += 4; + + /* Check the user class length. */ + status = _nx_dhcpv6_utility_get_data(user_class_ptr, 2, &option_length); + if (status || (option_length != (user_class_len + 2))) + error_counter++; + + /* Skip the user class length filed. */ + user_class_ptr += 2; + + /* Check the user class option. */ + if(memcmp(user_class_ptr, user_class, user_class_len)) + error_counter++; + } + + /* Call the actual function to receive the UDP packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} + +/* Define the Client host application thread. */ + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS ipv6_address; +NXD_ADDRESS dns_address; +ULONG prefix_length; +UINT interface_index; +ULONG T1, T2, preferred_lifetime, valid_lifetime; +UINT address_count; +UINT address_index; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: DHCPv6 User Option Add Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Establish the link local address for the host. The RAM driver creates + a virtual MAC address of 0x1122334456. */ + status = nxd_ipv6_address_set(&client_ip, 0, NX_NULL, 10, NULL); + + /* Let NetX Duo and the network driver get initialized. Also give the server time to get set up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create the DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &client_ip, "DHCPv6 Client", &pool_0, pointer, NX_DHCPV6_THREAD_STACK_SIZE, + NX_NULL, NX_NULL); + pointer = pointer + NX_DHCPV6_THREAD_STACK_SIZE; + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. + + Note that if this host had already been assigned in IPv6 lease, it + would have to use the assigned T1 and T2 values in loading the DHCPv6 + client with an IANA block. + */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, DHCPV6_T1, DHCPV6_T2); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set callback function to add user options. */ + status = nx_dhcpv6_user_option_add_callback_set(&dhcp_client, dhcpv6_user_option_add); + if (status) + error_counter++; + + /* Starting up the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* If the host also want to get the option message, set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Now, the host send the solicit message to get the IPv6 address and other options from the DHCPv6 server. */ + status = nx_dhcpv6_request_solicit(&dhcp_client); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for get the IPv6 address and do the duplicate address detection. */ + tx_thread_sleep(6 * NX_IP_PERIODIC_RATE); + + /* Get the valid IPv6 address count which the DHCPv6 server assigned . */ + status = nx_dhcpv6_get_valid_ip_address_count(&dhcp_client, &address_count); + + /* Check for errors. */ + if ((status) || (address_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address, preferred lifetime and valid lifetime according to the address index. */ + address_index = 0; + status = nx_dhcpv6_get_valid_ip_address_lease_time(&dhcp_client, address_index, &ipv6_address, &preferred_lifetime, &valid_lifetime); + + /* Check for errors. */ + if ((status) || + (preferred_lifetime != NX_DHCPV6_DEFAULT_PREFERRED_TIME) || + (valid_lifetime != NX_DHCPV6_DEFAULT_VALID_TIME)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by DHCPv6 API. */ + status = nx_dhcpv6_get_IP_address(&dhcp_client, &ipv6_address); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address. */ + if ((ipv6_address.nxd_ip_version != start_ipv6_address.nxd_ip_version) || + (ipv6_address.nxd_ip_address.v6[0] != start_ipv6_address.nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != start_ipv6_address.nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != start_ipv6_address.nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != start_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by NetX Duo API. */ + status = nxd_ipv6_address_get(&client_ip, 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IPv6 address. */ + if ((prefix_length != 64) || (interface_index != 0) || + (ipv6_address.nxd_ip_version != start_ipv6_address.nxd_ip_version) || + (ipv6_address.nxd_ip_address.v6[0] != start_ipv6_address.nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != start_ipv6_address.nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != start_ipv6_address.nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != start_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get IP address lease time. + Note, This API only applies to one IA. */ + status = nx_dhcpv6_get_lease_time_data(&dhcp_client, &T1, &T2, &preferred_lifetime, &valid_lifetime); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the value. */ + if ((T1 != NX_DHCPV6_DEFAULT_T1_TIME) || + (T2 != NX_DHCPV6_DEFAULT_T2_TIME) || + (preferred_lifetime != NX_DHCPV6_DEFAULT_PREFERRED_TIME) || + (valid_lifetime != NX_DHCPV6_DEFAULT_VALID_TIME)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the DNS Server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_address); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the IPv6 DNS address. */ + if ((dns_address.nxd_ip_version != dns_ipv6_address.nxd_ip_version) || + (dns_address.nxd_ip_address.v6[0] != dns_ipv6_address.nxd_ip_address.v6[0]) || + (dns_address.nxd_ip_address.v6[1] != dns_ipv6_address.nxd_ip_address.v6[1]) || + (dns_address.nxd_ip_address.v6[2] != dns_ipv6_address.nxd_ip_address.v6[2]) || + (dns_address.nxd_ip_address.v6[3] != dns_ipv6_address.nxd_ip_address.v6[3])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping the DHCPv6 Server. */ + status = nxd_icmp_ping(&client_ip, &server_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the address. */ + status = nx_dhcpv6_request_release(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for release the IPv6 address. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Get the IPv6 address by DHCPv6 API. */ + status = nx_dhcpv6_get_IP_address(&dhcp_client, &ipv6_address); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address by NetX Duo API. */ + status = nxd_ipv6_address_get(&client_ip, 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Stop the Client task. */ + status = nx_dhcpv6_stop(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the DHCPv6 client. */ + status = nx_dhcpv6_client_delete(&dhcp_client); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successfully. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the test server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +ULONG duid_time; +UINT addresses_added; + + /* Set the IPv6 address of DHCPv6 Server. */ + server_address.nxd_ip_version = NX_IP_VERSION_V6 ; + server_address.nxd_ip_address.v6[0] = 0x20010db8; + server_address.nxd_ip_address.v6[1] = 0xf101; + server_address.nxd_ip_address.v6[2] = 0x00000000; + server_address.nxd_ip_address.v6[3] = 0x00000101; + + /* Set the link local and global addresses. */ + status = nxd_ipv6_address_set(&server_ip, 0, NX_NULL, 10, NULL); + status += nxd_ipv6_address_set(&server_ip, 0, &server_address, 64, NULL); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Validate the link local and global addresses. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create the DHCPv6 Server. */ + status = nx_dhcpv6_server_create(&dhcp_server, &server_ip, "DHCPv6 Server", &pool_0, pointer, NX_DHCPV6_SERVER_THREAD_STACK_SIZE, NX_NULL, NX_NULL); + pointer += NX_DHCPV6_SERVER_THREAD_STACK_SIZE; + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set up the DNS IPv6 server address. */ + dns_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + dns_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + dns_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + dns_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + dns_ipv6_address.nxd_ip_address.v6[3] = 0x00000107; + + status = nx_dhcpv6_create_dns_address(&dhcp_server, &dns_ipv6_address); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Note: For DUID types that do not require time, the 'duid_time' input can be left at zero. + The DUID_TYPE and HW_TYPE are configurable options that are user defined in nx_dhcpv6_server.h. */ + + /* Set the DUID time as the start of the millenium. */ + duid_time = SECONDS_SINCE_JAN_1_2000_MOD_32; + status = nx_dhcpv6_set_server_duid(&dhcp_server, + NX_DHCPV6_SERVER_DUID_TYPE, NX_DHCPV6_SERVER_HW_TYPE, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_msw, + dhcp_server.nx_dhcpv6_ip_ptr -> nx_ip_arp_physical_address_lsw, + duid_time); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 start address. */ + start_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + start_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + start_ipv6_address.nxd_ip_address.v6[1] = 0x00000f101; + start_ipv6_address.nxd_ip_address.v6[2] = 0x0; + start_ipv6_address.nxd_ip_address.v6[3] = 0x00000110; + + /* Set the IPv6 end address. */ + end_ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + end_ipv6_address.nxd_ip_address.v6[0] = 0x20010db8; + end_ipv6_address.nxd_ip_address.v6[1] = 0x0000f101; + end_ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + end_ipv6_address.nxd_ip_address.v6[3] = 0x00000120; + + /* Set the IPv6 address range. */ + status = nx_dhcpv6_create_ip_address_range(&dhcp_server, &start_ipv6_address, &end_ipv6_address, &addresses_added); + + /* Check for errors. */ + if ((status) || (addresses_added != 16)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Change the pointer function to check user options. */ + server_ip.nx_ip_udp_packet_receive = my_udp_packet_receive; + + /* Start the NetX DHCPv6 server! */ + status = nx_dhcpv6_server_start(&dhcp_server); + + /* Check for errors. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dhcpv6_user_option_add_test_application_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: DHCPv6 User Option Add Test...............................N/A\n"); + test_control_return(3); +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/dns_test/netx_dns_abnormal_packet_test.c b/test/regression/dns_test/netx_dns_abnormal_packet_test.c new file mode 100644 index 00000000..26c0dce0 --- /dev/null +++ b/test/regression/dns_test/netx_dns_abnormal_packet_test.c @@ -0,0 +1,533 @@ +/* This NetX test reading overflow when processing abnormal packet. */ + +/* Invalid name string */ +static unsigned char invalid_response_0[] = { +0x1C, 0x1A, 0xDF, 0xB0, 0x2F, 0x0A, 0x74, 0xB6, +0xB6, 0x40, 0x93, 0x2D, 0x08, 0x00, 0x45, 0x00, +0x00, 0x69, 0x72, 0x5D, 0x00, 0x00, 0x40, 0x11, +0x80, 0xA6, 0xC0, 0xA8, 0x01, 0xFE, 0xC0, 0xA8, +0x04, 0x32, 0x00, 0x35, 0xC8, 0xE1, 0x00, 0x55, +0x4C, 0x59, 0x88, 0xCC, 0x81, 0x80, 0x00, 0x01, +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63, +0x6C, 0x69, 0x65, 0x6E, 0x74, 0x73, 0x34, 0x06, +0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63, +0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01, 0xC0, +0x0C, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, +0xC3, 0x00, 0x0C, 0x37, 0x63, 0x6C, 0x69, 0x65, +0x6E, 0x74, 0x73, 0x01, 0x6C, 0xC0, 0x15, 0xC0, +0x31, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, +0x2C, 0x00, 0x04, 0xAC, 0xD9, 0x03, 0xCE +}; + +/* Invalid name string */ +static unsigned char invalid_response_1[] = { +0x1C, 0x1A, 0xDF, 0xB0, 0x2F, 0x0A, 0x74, 0xB6, +0xB6, 0x40, 0x93, 0x2D, 0x08, 0x00, 0x45, 0x00, +0x00, 0x69, 0x72, 0x5D, 0x00, 0x00, 0x40, 0x11, +0x80, 0xA6, 0xC0, 0xA8, 0x01, 0xFE, 0xC0, 0xA8, +0x04, 0x32, 0x00, 0x35, 0xC8, 0xE1, 0x00, 0x55, +0x4C, 0x59, 0x88, 0xCC, 0x81, 0x80, 0x00, 0x01, +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63, +0x6C, 0x69, 0x65, 0x6E, 0x74, 0x73, 0x34, 0x06, +0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63, +0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01, 0xC0, +0x0C, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, +0xC3, 0x00, 0x0C, 0x37, 0x63, 0x6C, 0x69, 0x65, +0x6E, 0x74, 0x73, 0x01, 0x6C, 0xC0, 0x15, 0xC0, +0x4C, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, +0x2C, 0x00, 0x04, 0xAC, 0xD9, 0x03, 0xC0 +}; + +/* Invalid name string */ +static unsigned char invalid_response_2[] = { +0x1C, 0x1A, 0xDF, 0xB0, 0x2F, 0x0A, 0x74, 0xB6, +0xB6, 0x40, 0x93, 0x2D, 0x08, 0x00, 0x45, 0x00, +0x00, 0x69, 0x72, 0x5D, 0x00, 0x00, 0x40, 0x11, +0x80, 0xA6, 0xC0, 0xA8, 0x01, 0xFE, 0xC0, 0xA8, +0x04, 0x32, 0x00, 0x35, 0xC8, 0xE1, 0x00, 0x55, +0x4C, 0x59, 0x88, 0xCC, 0x81, 0x80, 0x00, 0x01, +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63, +0x6C, 0x69, 0x65, 0x6E, 0x74, 0x73, 0x34, 0x06, +0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63, +0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01, 0xC0, +0x0C, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, +0xC3, 0x00, 0x0C, 0x37, 0x63, 0x6C, 0x69, 0x65, +0x6E, 0x74, 0x73, 0x01, 0x6C, 0xC0, 0x15, 0xC0, +0x4B, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, +0x2C, 0x00, 0x04, 0xAC, 0xD9, 0x01, 0x01 +}; + +/* Invalid IP address */ +static unsigned char invalid_response_3[] = +{ +0x1C, 0x1A, 0xDF, 0xB0, 0x2F, 0x0A, 0x74, 0xB6, +0xB6, 0x40, 0x93, 0x2D, 0x08, 0x00, 0x45, 0x00, +0x00, 0x69, 0x72, 0x5D, 0x00, 0x00, 0x40, 0x11, +0x80, 0xA6, 0xC0, 0xA8, 0x01, 0xFE, 0xC0, 0xA8, +0x04, 0x32, 0x00, 0x35, 0xC8, 0xE1, 0x00, 0x55, +0x4C, 0x59, 0x88, 0xCC, 0x81, 0x80, 0x00, 0x01, +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63, +0x6C, 0x69, 0x65, 0x6E, 0x74, 0x73, 0x34, 0x06, +0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63, +0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01, 0xC0, +0x0C, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, +0xC3, 0x00, 0x0C, 0x07, 0x63, 0x6C, 0x69, 0x65, +0x6E, 0x74, 0x73, 0x01, 0x6C, 0xC0, 0x15, 0xC0, +0x31, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, +0x2C, 0x00, 0x04, 0xAC, 0xD9, 0x03 +}; + +/* Valid response */ +static unsigned char valid_response[] = +{ +0x1C, 0x1A, 0xDF, 0xB0, 0x2F, 0x0A, 0x74, 0xB6, +0xB6, 0x40, 0x93, 0x2D, 0x08, 0x00, 0x45, 0x00, +0x00, 0x69, 0x72, 0x5D, 0x00, 0x00, 0x40, 0x11, +0x80, 0xA6, 0xC0, 0xA8, 0x01, 0xFE, 0xC0, 0xA8, +0x04, 0x32, 0x00, 0x35, 0xC8, 0xE1, 0x00, 0x55, +0x4C, 0x59, 0x88, 0xCC, 0x81, 0x80, 0x00, 0x01, +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63, +0x6C, 0x69, 0x65, 0x6E, 0x74, 0x73, 0x34, 0x06, +0x67, 0x6F, 0x6F, 0x67, 0x6C, 0x65, 0x03, 0x63, +0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01, 0xC0, +0x0C, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, +0xC3, 0x00, 0x0C, 0x07, 0x63, 0x6C, 0x69, 0x65, +0x6E, 0x74, 0x73, 0x01, 0x6C, 0xC0, 0x15, 0xC0, +0x31, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, +0x2C, 0x00, 0x04, 0xAC, 0xD9, 0x03, 0xCE +}; + +static unsigned char invalid_response_txt[] = +{ +0x18, 0x03, 0x73, 0x33, 0xc1, 0xbd, 0xc8, 0x3a, +0x35, 0x60, 0x4b, 0x46, 0x08, 0x00, 0x45, 0x00, +0x00, 0x96, 0xc1, 0xa0, 0x00, 0x00, 0x40, 0x11, +0x36, 0xfc, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8, +0x00, 0x69, 0x00, 0x35, 0xc1, 0x8b, 0x00, 0x82, +0xec, 0x71, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, +0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, +0x6d, 0x00, 0x00, 0x10, 0x00, 0x01, 0xc0, 0x0c, +0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, +0x00, 0x52, 0x52, 0x76, 0x3d, 0x73, 0x70, 0x66, +0x31, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, +0x65, 0x3a, 0x5f, 0x6e, 0x65, 0x74, 0x62, 0x6c, +0x6f, 0x63, 0x6b, 0x73, 0x2e, 0x67, 0x6f, 0x6f, +0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x20, +0x69, 0x70, 0x34, 0x3a, 0x32, 0x31, 0x36, 0x2e, +0x37, 0x33, 0x2e, 0x39, 0x33, 0x2e, 0x37, 0x30, +0x2f, 0x33, 0x31, 0x20, 0x69, 0x70, 0x34, 0x3a, +0x32, 0x31, 0x36, 0x2e, 0x37, 0x33, 0x2e, 0x39, +0x33, 0x2e, 0x37, 0x32, 0x2f, 0x33, 0x31, 0x20, +0x7e, 0x61, 0x6c, 0x6c +}; + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dns.h" +#else +#include "nx_dns.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP client_ip; +static NX_IP server_ip; + +static NX_UDP_SOCKET server_socket; +static NX_DNS client_dns; + + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL +NX_PACKET_POOL client_pool; +#endif + +static UCHAR pool_buffer[8192] = {0}; +static UCHAR record_buffer[500]; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +#define DNS_START_OFFSET (14 + 20 + 8) + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the DNS main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pool_buffer, 8192); + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Create the packet pool for the DNS Client to send packets. + + If the DNS Client is configured for letting the host application create + the DNS packet pool, (see NX_DNS_CLIENT_USER_CREATE_PACKET_POOL option), see + nx_dns_create() for guidelines on packet payload size and pool size. + packet traffic for NetX Duo processes. + */ + status = nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", NX_DNS_PACKET_PAYLOAD, pointer, NX_DNS_PACKET_POOL_SIZE); + + pointer = pointer + NX_DNS_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + return; +#endif + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "NetX IP Instance 0", IP_ADDRESS(192, 168, 100, 98), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "NetX IP Instance 1", IP_ADDRESS(192, 168, 100, 2), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +ULONG host_ip_address; +UINT i; +UINT test_num; + + /* Print out some test information banners. */ + printf("NetX Test: DNS Abnormal Packet Test.................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a DNS instance for the Client. Note this function will create + the DNS Client packet pool for creating DNS message packets intended + for querying its DNS server. */ + status = nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client"); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Is the DNS client configured for the host application to create the pecket pool? */ +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Yes, use the packet pool created above which has appropriate payload size + for DNS messages. */ + status = nx_dns_packet_pool_set(&client_dns, &client_pool); + + /* Check for set DNS packet pool error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Add an IPv4 server address to the Client list. */ + status = nx_dns_server_add(&client_dns, IP_ADDRESS(192, 168, 100, 2)); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + client_dns.nx_dns_retries = 1; + +#ifdef NX_DNS_CACHE_ENABLE + test_num = 4; +#else + test_num = 1; +#endif + + for (i = 0; i < test_num; i++) + { + status = nx_dns_host_by_name_get(&client_dns, (UCHAR *)"berkeley.edu", &host_ip_address, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status == NX_SUCCESS) + { + error_counter++; + } + } + +#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES + status = nx_dns_host_text_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], sizeof(record_buffer), NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status == NX_SUCCESS) + { + error_counter++; + } +#endif + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT port; +USHORT nx_dns_transmit_id; +UCHAR *data_ptr; +NX_PACKET *response_packet; +UCHAR *invalid_responses[] = +{ +#ifdef NX_DNS_CACHE_ENABLE + invalid_response_0, + invalid_response_1, + invalid_response_2, +#endif + invalid_response_3, +#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES + invalid_response_txt, +#endif +}; +UINT invalid_responses_len[] = +{ +#ifdef NX_DNS_CACHE_ENABLE + sizeof(invalid_response_0), + sizeof(invalid_response_1), + sizeof(invalid_response_2), +#endif + sizeof(invalid_response_3), +#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES + sizeof(invalid_response_txt), +#endif +}; +UCHAR *response_ptr; +UINT response_len; +UINT i; +UINT test_num = sizeof(invalid_responses_len) / sizeof(UINT); + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&server_socket, 53, TX_WAIT_FOREVER); + + + /* Act as the DNS server to receive the DNS query and send the DNS response. */ + + for (i = 0; i < test_num; i ++) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS client UDP port. */ + status = nx_udp_packet_info_extract(my_packet, NX_NULL, NX_NULL, &port, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS transmit ID. */ + if (i == 1) + { + client_dns.nx_dns_transmit_id = 0xc00c; + nx_dns_transmit_id = client_dns.nx_dns_transmit_id; + } + else + { + data_ptr = my_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + nx_dns_transmit_id = *data_ptr++; + nx_dns_transmit_id = (USHORT)((nx_dns_transmit_id << 8) | *data_ptr); + } + + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send the DNS response packet. */ + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + response_ptr = invalid_responses[i]; + response_len = invalid_responses_len[i]; + + /* Write the DNS response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, response_ptr + DNS_START_OFFSET, response_len - DNS_START_OFFSET); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = response_len - DNS_START_OFFSET; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Update the DNS transmit ID. */ + data_ptr = response_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + *data_ptr++ = (UCHAR)(nx_dns_transmit_id >> 8); + *data_ptr = (UCHAR)nx_dns_transmit_id; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(&server_socket, response_packet, IP_ADDRESS(192, 168, 100, 98), port); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + return; + } + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Let the DNS threads execute. */ + tx_thread_relinquish(); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_abnormal_packet_test_application_define(void *first_unused_memory) +#endif + +{ + + /* Print out test information banner. */ + printf("NetX Test: DNS Abnormal Packet Test..................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/dns_test/netx_dns_coverage_test.c b/test/regression/dns_test/netx_dns_coverage_test.c new file mode 100644 index 00000000..a8d10499 --- /dev/null +++ b/test/regression/dns_test/netx_dns_coverage_test.c @@ -0,0 +1,146 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#include "tx_mutex.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dns.h" +#else +#include "nx_dns.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) +#define validate_expected_status(status,expected_status) if (expected_status != status) {printf("%s,%d: ERROR!",__FILE__, __LINE__);test_control_return(1);} + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD client_thread; +static NX_IP client_ip; +static NX_DNS client_dns; +static NX_PACKET_POOL pool_0; +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL +NX_PACKET_POOL client_pool; +#endif +static TX_MUTEX *mutex_ptr; + +#define DNS_SERVER_ADDRESS IP_ADDRESS(10,0,0,1) + +static CHAR *pointer; +static UINT status; +static ULONG error_counter = 0; + +/* Define thread prototypes. */ + +static void client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_coverage_test_application_define(void *first_unused_memory) +#endif +{ + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the DNS main thread. */ + tx_thread_create(&client_thread, "client thread", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 8192); + pointer = pointer + 8192; + + /* Create an IP instance. */ + nx_ip_create(&client_ip, "NetX IP Instance 0", IP_ADDRESS(10, 0, 0, 10), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable UDP traffic. */ + nx_udp_enable(&client_ip); +} + + + +/* Define the test thread. */ +static void client_thread_entry(ULONG thread_input) +{ + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + /* creates a packet pool that has payloads that are too small. */ + status = nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", 1, pointer, NX_DNS_PACKET_POOL_SIZE - 1); + pointer = pointer + NX_DNS_PACKET_POOL_SIZE; + if (status) + { + error_counter++; + } + + status = nx_dns_packet_pool_set(&client_dns, &client_pool); + if (status != NX_DNS_PARAM_ERROR) + { + error_counter++; + } +#endif + +#ifndef NX_DISABLE_ERROR_CHECKING + /* Force mutex create to fail. */ + mutex_ptr = _tx_mutex_created_ptr; + _tx_mutex_created_ptr = &client_dns.nx_dns_mutex; + _tx_mutex_created_count++; + + /* Attempt to create the DNS instance. */ + status = nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client"); + if (status != TX_MUTEX_ERROR) + { + error_counter++; + } + + /* Restore mutex. */ + _tx_mutex_created_ptr = mutex_ptr; + _tx_mutex_created_count--; +#endif + + /* Check the error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_coverage_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DNS Coverage Test.........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dns_test/netx_dns_fake_response_test.c b/test/regression/dns_test/netx_dns_fake_response_test.c new file mode 100644 index 00000000..c421daf8 --- /dev/null +++ b/test/regression/dns_test/netx_dns_fake_response_test.c @@ -0,0 +1,386 @@ +/* This NetX test concentrates on the basic DNS operation. Fake response test. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dns.h" +#else +#include "nx_dns.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#ifndef NX_DISABLE_IPV4 + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP client_ip; +static NX_IP server_ip; + +static NX_UDP_SOCKET server_socket; +static NX_DNS client_dns; + + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL +NX_PACKET_POOL client_pool; +#endif + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static UINT dns_query_port_1 = 0; +static UINT dns_query_port_2 = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +#define DNS_START_OFFSET (14 + 20 + 8) + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_fake_response_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the DNS main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 8192); + pointer = pointer + 8192; + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Create the packet pool for the DNS Client to send packets. + + If the DNS Client is configured for letting the host application create + the DNS packet pool, (see NX_DNS_CLIENT_USER_CREATE_PACKET_POOL option), see + nx_dns_create() for guidelines on packet payload size and pool size. + packet traffic for NetX Duo processes. + */ + status = nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", NX_DNS_PACKET_PAYLOAD, pointer, NX_DNS_PACKET_POOL_SIZE); + + pointer = pointer + NX_DNS_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + return; +#endif + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "NetX IP Instance 0", IP_ADDRESS(192, 168, 100, 98), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "NetX IP Instance 1", IP_ADDRESS(192, 168, 100, 2), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UCHAR record_buffer[64]; +UINT record_count; +ULONG *ipv4_address_ptr; + + /* Print out some test information banners. */ + printf("NetX Test: DNS Fake Response Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a DNS instance for the Client. Note this function will create + the DNS Client packet pool for creating DNS message packets intended + for querying its DNS server. */ + status = nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client"); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Is the DNS client configured for the host application to create the pecket pool? */ +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Yes, use the packet pool created above which has appropriate payload size + for DNS messages. */ + status = nx_dns_packet_pool_set(&client_dns, &client_pool); + + /* Check for set DNS packet pool error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Add an IPv4 server address to the Client list. */ + status = nx_dns_server_add(&client_dns, IP_ADDRESS(192, 168, 100, 2)); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send query. */ + status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 64, &record_count, NX_IP_PERIODIC_RATE); + ipv4_address_ptr = (ULONG *)record_buffer; + + /* Check status. */ + if ((status) || + (*ipv4_address_ptr != IP_ADDRESS(74,125,224,194))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send query again. */ + status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 64, &record_count, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +extern char response_a_google_com_pkt[]; +extern int response_a_google_com_pkt_size; +extern char response_a_berkley_edu_pkt[]; +extern int response_a_berkley_edu_pkt_size; + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT port; +USHORT nx_dns_transmit_id; +UCHAR *data_ptr; +NX_PACKET *response_packet; +UCHAR *response_data; +UINT response_data_size; + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&server_socket, 53, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + for (UINT i = 0; i < 2; i++) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS client UDP port. */ + status = nx_udp_packet_info_extract(my_packet, NX_NULL, NX_NULL, &port, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + if (i == 0) + { + dns_query_port_1 = port; + } + else + { + dns_query_port_2 = port; + } + + /* Get the DNS transmit ID. */ + data_ptr = my_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + nx_dns_transmit_id = *data_ptr++; + nx_dns_transmit_id = (USHORT)((nx_dns_transmit_id << 8) | *data_ptr); + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send the DNS response packet. */ + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + if (i == 0) + { + response_data = response_a_google_com_pkt; + response_data_size = response_a_google_com_pkt_size; + } + else + { + response_data = response_a_berkley_edu_pkt; + response_data_size = response_a_berkley_edu_pkt_size; + } + + /* Write the DNS response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, response_data + DNS_START_OFFSET, response_data_size - DNS_START_OFFSET); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = response_data_size - DNS_START_OFFSET; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Update the DNS transmit ID. */ + data_ptr = response_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + *data_ptr++ = (UCHAR)(nx_dns_transmit_id >> 8); + *data_ptr = (UCHAR)nx_dns_transmit_id; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(&server_socket, response_packet, IP_ADDRESS(192, 168, 100, 98), port); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + return; + } + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Let the DNS threads execute. */ + tx_thread_relinquish(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_fake_response_test_application_define(void *first_unused_memory) +#endif + +{ + + /* Print out test information banner. */ + printf("NetX Test: DNS Fake Response Test....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/dns_test/netx_dns_function_test.c b/test/regression/dns_test/netx_dns_function_test.c new file mode 100644 index 00000000..65fb4190 --- /dev/null +++ b/test/regression/dns_test/netx_dns_function_test.c @@ -0,0 +1,1612 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dns.h" +#else +#include "nx_dns.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_UDP_SOCKET server_socket; + +static NX_DNS client_dns; + +#define DNS_SERVER_ADDRESS IP_ADDRESS(10,0,0,1) + +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS address_ipv4_0; +static NXD_ADDRESS address_ipv4_1; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_ipv6_0; +static NXD_ADDRESS address_ipv6_1; +#endif +#endif + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL +NX_PACKET_POOL client_pool; +#endif + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG notify_calls = 0; + +static UCHAR record_buffer[500]; +static UINT record_count; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); + +/* DNS Tests. */ +static void dns_test_initialize(); +static void dns_a_type_test(); + +#ifdef __PRODUCT_NETXDUO__ +static void dns_aaaa_type_test(); +#endif /* __PRODUCT_NETXDUO__ */ + +#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES +static void dns_a_cname_type_test(); +static void dns_mx_type_test(); +static void dns_mx_a_type_test(); +static void dns_cname_type_test(); +static void dns_ns_a_type_test(); +static void dns_srv_type_test(); +static void dns_txt_type_test(); +static void dns_soa_type_test(); +#endif + +/* DNS retransmit test. */ +static void dns_retransmit_test(); + +/* Send DNS response. */ +static UINT nx_dns_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, USHORT nx_dns_transmit_id, UINT packet_number); + +extern char response_a_google_com_pkt[246]; +extern int response_a_google_com_pkt_size; + +extern char response_a_berkley_edu_pkt[88]; +extern int response_a_berkley_edu_pkt_size; + +extern char response_aaaa_berkley_edu_pkt[100]; +extern int response_aaaa_berkley_edu_pkt_size; + +#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES + +extern char response_a_cname_www_npr_org_pkt[119]; +extern int response_a_cname_www_npr_org_pkt_size; + +extern char response_mx_google_com_pkt[178]; +extern int response_mx_google_com_pkt_size; + +extern char response_mx_a_google_com_pkt[258]; +extern int response_mx_a_google_com_pkt_size; + +extern char response_mx_a_berkley_edu_pkt[107]; +extern int response_mx_a_berkley_edu_pkt_size; + +extern char response_cname_www_baidu_com_pkt[100]; +extern int response_cname_www_baidu_com_pkt_size; + +extern char response_ns_a_ti_com_pkt[349]; +extern int response_ns_a_ti_com_pkt_size; + +extern char response_srv_google_com_pkt[373]; +extern int response_srv_google_com_pkt_size; + +extern char response_txt_google_com_pkt[373]; +extern int response_txt_google_com_pkt_size; + +extern char response_soa_google_com_pkt[120]; +extern int response_soa_google_com_pkt_size; + +#endif + +typedef struct DNS_TEST_STRUCT +{ + char *dns_test_pkt_data; + int dns_test_pkt_size; +} DNS_TEST; + +#define test_count 19 +static DNS_TEST dns_test[test_count]; + +extern ULONG test_control_successful_tests; +extern ULONG test_control_failed_tests; + +#define DNS_START_OFFSET (14 + 20 + 8) + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_function_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the DNS main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 8192); + pointer = pointer + 8192; + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Create the packet pool for the DNS Client to send packets. + + If the DNS Client is configured for letting the host application create + the DNS packet pool, (see NX_DNS_CLIENT_USER_CREATE_PACKET_POOL option), see + nx_dns_create() for guidelines on packet payload size and pool size. + packet traffic for NetX Duo processes. + */ + status = nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", NX_DNS_PACKET_PAYLOAD, pointer, NX_DNS_PACKET_POOL_SIZE); + + pointer = pointer + NX_DNS_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + return; +#endif + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "NetX IP Instance 0", IP_ADDRESS(10, 0, 0, 10), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "NetX IP Instance 1", IP_ADDRESS(10, 0, 0, 1), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + /* Create a DNS instance for the Client. Note this function will create + the DNS Client packet pool for creating DNS message packets intended + for querying its DNS server. */ + status = nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client"); + + /* Is the DNS client configured for the host application to create the pecket pool? */ +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Yes, use the packet pool created above which has appropriate payload size + for DNS messages. */ + status = nx_dns_packet_pool_set(&client_dns, &client_pool); + + /* Check for set DNS packet pool error. */ + if (status) + { + error_counter++; + } + +#endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Add a then remove ipv4 DNS servers, check for max entries as well */ + for (int i = 0; i < (NX_DNS_MAX_SERVERS); i++) + { + status = nx_dns_server_add(&client_dns, IP_ADDRESS(10,1,1,i)); + if (status) + { + error_counter++; + } + } + + status = nx_dns_server_add(&client_dns, IP_ADDRESS(10,1,1,NX_DNS_MAX_SERVERS)); + if (status != NX_NO_MORE_ENTRIES) + { + error_counter++; + } + + /* check size when we are at max entries. */ + UINT size = 0; + status = nx_dns_get_serverlist_size(&client_dns, &size); + if (status != NX_SUCCESS || size != 5) + { + error_counter++; + } + + for (int i = 0; i < (NX_DNS_MAX_SERVERS); i++) + { + status = nx_dns_server_remove(&client_dns, IP_ADDRESS(10,1,1,i)); + if (status) + { + error_counter++; + } + } + +#ifdef __PRODUCT_NETXDUO__ + /* Add one IPv4 server address. */ + address_ipv4_0.nxd_ip_address.v4 = IP_ADDRESS(1,1,1,1); + address_ipv4_0.nxd_ip_version = NX_IP_VERSION_V4; + status = nxd_dns_server_add(&client_dns,&address_ipv4_0); + if (status) + { + error_counter++; + } + + /* Add an other IPv4 server address to the Client list. */ + address_ipv4_1.nxd_ip_address.v4 = IP_ADDRESS(10,1,1,1); + address_ipv4_1.nxd_ip_version = NX_IP_VERSION_V4; + status = nxd_dns_server_add(&client_dns, &address_ipv4_1); + if (status) + { + error_counter++; + } + +#ifdef FEATURE_NX_IPV6 + /* Add one IPv6 server address. */ + address_ipv6_0.nxd_ip_address.v6[0] = 13; + address_ipv6_0.nxd_ip_address.v6[1] = 13; + address_ipv6_0.nxd_ip_address.v6[2] = 13; + address_ipv6_0.nxd_ip_address.v6[3] = 13; + address_ipv6_0.nxd_ip_version = NX_IP_VERSION_V6; + status = nxd_dns_server_add(&client_dns, &address_ipv6_0); + if (status) + { + error_counter++; + } + + /* Add an other IPv6 server address to the Client list. */ + address_ipv6_1.nxd_ip_address.v6[0] = 14; + address_ipv6_1.nxd_ip_address.v6[1] = 14; + address_ipv6_1.nxd_ip_address.v6[2] = 14; + address_ipv6_1.nxd_ip_address.v6[3] = 14; + address_ipv6_1.nxd_ip_version = NX_IP_VERSION_V6; + status = nxd_dns_server_add(&client_dns, &address_ipv6_1); + if (status) + { + error_counter++; + } +#endif + + /* Check duplicate server logic */ + status = nxd_dns_server_add(&client_dns, &address_ipv4_1); + if (status != NX_DNS_DUPLICATE_ENTRY) + { + error_counter++; + } + +#ifdef FEATURE_NX_IPV6 + status = nxd_dns_server_add(&client_dns, &address_ipv6_1); + if (status != NX_DNS_DUPLICATE_ENTRY) + { + error_counter++; + } +#endif + + /* check for size less than max entries. */ + status = nx_dns_get_serverlist_size(&client_dns, &size); +#ifdef FEATURE_NX_IPV6 + if (status != NX_SUCCESS || size != 4) +#else + if (status != NX_SUCCESS || size != 2) +#endif + { + error_counter++; + } + + ULONG get_ipv4_address; +#ifdef FEATURE_NX_IPV6 + /* use nx api for IPv6 address. */ + status = nx_dns_server_get(&client_dns, 2, &get_ipv4_address); + if (status != NX_DNS_INVALID_ADDRESS_TYPE) + { + error_counter++; + } +#endif + + /* try getting address outside of bounds. */ + status = nx_dns_server_get(&client_dns, NX_DNS_MAX_SERVERS, &get_ipv4_address); + if (status != NX_DNS_PARAM_ERROR) { + error_counter++; + } + + /* try getting from index that is not set. */ + status = nx_dns_server_get(&client_dns, 4, &get_ipv4_address); + if (status != NX_DNS_SERVER_NOT_FOUND) + { + error_counter++; + } + + /* these should work. */ + status = nx_dns_server_get(&client_dns, 0, &get_ipv4_address); + if (status != NX_SUCCESS || get_ipv4_address != IP_ADDRESS(1,1,1,1)) + { + error_counter++; + } + + status = nx_dns_server_get(&client_dns, 1, &get_ipv4_address); + if (status != NX_SUCCESS || get_ipv4_address != IP_ADDRESS(10,1,1,1)) + { + error_counter++; + } + +#ifdef FEATURE_NX_IPV6 + NXD_ADDRESS get_ipv6_address; + status = nxd_dns_server_get(&client_dns, 2, &get_ipv6_address); + if (status != NX_SUCCESS || !CHECK_IPV6_ADDRESSES_SAME(&get_ipv6_address.nxd_ip_address.v6[0], &address_ipv6_0.nxd_ip_address.v6[0])) + { + error_counter++; + } + + /* Check for an address that does not exist. */ + address_ipv6_0.nxd_ip_address.v6[0] = 1; + address_ipv6_0.nxd_ip_address.v6[1] = 2; + address_ipv6_0.nxd_ip_address.v6[2] = 3; + address_ipv6_0.nxd_ip_address.v6[3] = 4; + status = nxd_dns_server_remove(&client_dns, &address_ipv6_0); + if (status != NX_DNS_SERVER_NOT_FOUND) + { + error_counter++; + } + + /* Remove an ipv6 that does exist. */ + status = nxd_dns_server_remove(&client_dns, &address_ipv6_1); + if (status != NX_SUCCESS) + { + error_counter++; + } +#endif + status = nx_dns_server_remove_all(&client_dns); + if (status != NX_SUCCESS) + { + error_counter++; + } +#endif + + /* Add an IPv4 server address to the Client list. */ + status = nx_dns_server_add(&client_dns, DNS_SERVER_ADDRESS); + if (status) + { + error_counter++; + } + + status = nx_dns_get_serverlist_size(&client_dns, &size); + if (status != NX_SUCCESS || size != 1) + { + error_counter++; + } + + /* The DNS test initialize. */ + dns_test_initialize(); + + /* Test the DNS A type function. */ + dns_a_type_test(); + + /* DNS retransmit test. */ + dns_retransmit_test(); + +#ifdef __PRODUCT_NETXDUO__ + /* Test the DNS AAAA type function. */ + dns_aaaa_type_test(); +#endif + +#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES + + /* Test the DNS A + CNAME type function. */ + dns_a_cname_type_test(); + + /* Test the DNS MX type function. */ + dns_mx_type_test(); + + /* Test the DNS MX type with addtional A type function. */ + dns_mx_a_type_test(); + + /* Test the DNS CNAME type function. */ + dns_cname_type_test(); + + /* Test the DNS NS type with addtional A type function. */ + dns_ns_a_type_test(); + + /* Test the DNS SRV type. */ + dns_srv_type_test(); + + /* Test the DNS SRV type. */ + dns_txt_type_test(); + + /* Test the DNS SOA type. */ + dns_soa_type_test(); + +#endif + + status = nx_dns_delete(&client_dns); + + if (status) + { + error_counter++; + } + + test_control_return(0xdeadbeef); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT port; +UINT i; +USHORT nx_dns_transmit_id; +UCHAR *data_ptr; + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&server_socket, 53, TX_WAIT_FOREVER); + + /* Act as the DNS server to receive the DNS query and send the DNS response. */ + for (i = 0; i < test_count; i++ ) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* If the Test the DNS client retransmission.*/ + if((i == 4) || (i == 5)) + { + nx_packet_release(my_packet); + continue; + } + + /* Get the DNS client UDP port. */ + status = nx_udp_packet_info_extract(my_packet, NX_NULL ,NX_NULL, &port, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS transmit ID. */ + data_ptr = my_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + nx_dns_transmit_id = *data_ptr++; + nx_dns_transmit_id = (USHORT)((nx_dns_transmit_id << 8) | *data_ptr); + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send the DNS response packet. */ + status = nx_dns_response_packet_send(&server_socket, port, nx_dns_transmit_id, i); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Let the DNS threads execute. */ + tx_thread_relinquish(); +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_dns_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, USHORT nx_dns_transmit_id, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; +UCHAR *data_ptr; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the DNS response messages into the packet payload! */ + dns_test[packet_number].dns_test_pkt_data += DNS_START_OFFSET; + memcpy(response_packet -> nx_packet_prepend_ptr, dns_test[packet_number].dns_test_pkt_data, dns_test[packet_number].dns_test_pkt_size - DNS_START_OFFSET); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dns_test[packet_number].dns_test_pkt_size - DNS_START_OFFSET; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Update the DNS transmit ID. */ + data_ptr = response_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + *data_ptr++ = (UCHAR)(nx_dns_transmit_id >> 8); + *data_ptr = (UCHAR)nx_dns_transmit_id; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(server_socket, response_packet, IP_ADDRESS(10, 0, 0, 10), port); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} + +static void dns_test_initialize() +{ + + /* DNS A type test. */ + dns_test[0].dns_test_pkt_data = &response_a_google_com_pkt[0]; + dns_test[0].dns_test_pkt_size = response_a_google_com_pkt_size; + dns_test[1].dns_test_pkt_data = &response_a_google_com_pkt[0]; + dns_test[1].dns_test_pkt_size = response_a_google_com_pkt_size; + dns_test[2].dns_test_pkt_data = &response_a_berkley_edu_pkt[0]; + dns_test[2].dns_test_pkt_size = response_a_berkley_edu_pkt_size; + dns_test[3].dns_test_pkt_data = &response_a_berkley_edu_pkt[0]; + dns_test[3].dns_test_pkt_size = response_a_berkley_edu_pkt_size; + + /* DNS retransmit test. */ + dns_test[4].dns_test_pkt_data = &response_a_berkley_edu_pkt[0]; + dns_test[4].dns_test_pkt_size = response_a_berkley_edu_pkt_size; + dns_test[5].dns_test_pkt_data = &response_a_berkley_edu_pkt[0]; + dns_test[5].dns_test_pkt_size = response_a_berkley_edu_pkt_size; + dns_test[6].dns_test_pkt_data = &response_a_berkley_edu_pkt[0]; + dns_test[6].dns_test_pkt_size = response_a_berkley_edu_pkt_size; + +#ifdef __PRODUCT_NETXDUO__ + +#ifdef FEATURE_NX_IPV6 + /* DNS A type test. */ + dns_test[7].dns_test_pkt_data = &response_aaaa_berkley_edu_pkt[0]; + dns_test[7].dns_test_pkt_size = response_aaaa_berkley_edu_pkt_size; + dns_test[8].dns_test_pkt_data = &response_aaaa_berkley_edu_pkt[0]; + dns_test[8].dns_test_pkt_size = response_aaaa_berkley_edu_pkt_size; + +#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES + + /* DNS extended type test. */ + dns_test[9].dns_test_pkt_data = &response_a_cname_www_npr_org_pkt[0]; + dns_test[9].dns_test_pkt_size = response_a_cname_www_npr_org_pkt_size; + dns_test[10].dns_test_pkt_data = &response_a_cname_www_npr_org_pkt[0]; + dns_test[10].dns_test_pkt_size = response_a_cname_www_npr_org_pkt_size; + dns_test[11].dns_test_pkt_data = &response_mx_google_com_pkt[0]; + dns_test[11].dns_test_pkt_size = response_mx_google_com_pkt_size; + dns_test[12].dns_test_pkt_data = &response_mx_a_google_com_pkt[0]; + dns_test[12].dns_test_pkt_size = response_mx_a_google_com_pkt_size; + dns_test[13].dns_test_pkt_data = &response_mx_a_berkley_edu_pkt[0]; + dns_test[13].dns_test_pkt_size = response_mx_a_berkley_edu_pkt_size; + dns_test[14].dns_test_pkt_data = &response_cname_www_baidu_com_pkt[0]; + dns_test[14].dns_test_pkt_size = response_cname_www_baidu_com_pkt_size; + dns_test[15].dns_test_pkt_data = &response_ns_a_ti_com_pkt[0]; + dns_test[15].dns_test_pkt_size = response_ns_a_ti_com_pkt_size; + dns_test[16].dns_test_pkt_data = &response_srv_google_com_pkt[0]; + dns_test[16].dns_test_pkt_size = response_srv_google_com_pkt_size; + dns_test[17].dns_test_pkt_data = &response_txt_google_com_pkt[0]; + dns_test[17].dns_test_pkt_size = response_txt_google_com_pkt_size; + dns_test[18].dns_test_pkt_data = &response_soa_google_com_pkt[0]; + dns_test[18].dns_test_pkt_size = response_soa_google_com_pkt_size; +#endif /* NX_DNS_ENABLE_EXTENDED_RR_TYPES */ + +#else /* FEATURE_NX_IPV6 */ + + /* DNS A type test. */ + dns_test[7].dns_test_pkt_data = &response_aaaa_berkley_edu_pkt[0]; + dns_test[7].dns_test_pkt_size = response_aaaa_berkley_edu_pkt_size; + +#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES + + /* DNS extended type test. */ + dns_test[8].dns_test_pkt_data = &response_a_cname_www_npr_org_pkt[0]; + dns_test[8].dns_test_pkt_size = response_a_cname_www_npr_org_pkt_size; + dns_test[9].dns_test_pkt_data = &response_a_cname_www_npr_org_pkt[0]; + dns_test[9].dns_test_pkt_size = response_a_cname_www_npr_org_pkt_size; + dns_test[10].dns_test_pkt_data = &response_mx_google_com_pkt[0]; + dns_test[10].dns_test_pkt_size = response_mx_google_com_pkt_size; + dns_test[11].dns_test_pkt_data = &response_mx_a_google_com_pkt[0]; + dns_test[11].dns_test_pkt_size = response_mx_a_google_com_pkt_size; + dns_test[12].dns_test_pkt_data = &response_mx_a_berkley_edu_pkt[0]; + dns_test[12].dns_test_pkt_size = response_mx_a_berkley_edu_pkt_size; + dns_test[13].dns_test_pkt_data = &response_cname_www_baidu_com_pkt[0]; + dns_test[13].dns_test_pkt_size = response_cname_www_baidu_com_pkt_size; + dns_test[14].dns_test_pkt_data = &response_ns_a_ti_com_pkt[0]; + dns_test[14].dns_test_pkt_size = response_ns_a_ti_com_pkt_size; + dns_test[15].dns_test_pkt_data = &response_srv_google_com_pkt[0]; + dns_test[15].dns_test_pkt_size = response_srv_google_com_pkt_size; + dns_test[16].dns_test_pkt_data = &response_txt_google_com_pkt[0]; + dns_test[16].dns_test_pkt_size = response_txt_google_com_pkt_size; + dns_test[17].dns_test_pkt_data = &response_soa_google_com_pkt[0]; + dns_test[17].dns_test_pkt_size = response_soa_google_com_pkt_size; +#endif /* NX_DNS_ENABLE_EXTENDED_RR_TYPES */ +#endif /* FEATURE_NX_IPV6 */ + +#else /* __PRODUCT_NETXDUO__ */ + +#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES + + /* DNS extended type test. */ + dns_test[7].dns_test_pkt_data = &response_a_cname_www_npr_org_pkt[0]; + dns_test[7].dns_test_pkt_size = response_a_cname_www_npr_org_pkt_size; + dns_test[8].dns_test_pkt_data = &response_a_cname_www_npr_org_pkt[0]; + dns_test[8].dns_test_pkt_size = response_a_cname_www_npr_org_pkt_size; + dns_test[9].dns_test_pkt_data = &response_mx_google_com_pkt[0]; + dns_test[9].dns_test_pkt_size = response_mx_google_com_pkt_size; + dns_test[10].dns_test_pkt_data = &response_mx_a_google_com_pkt[0]; + dns_test[10].dns_test_pkt_size = response_mx_a_google_com_pkt_size; + dns_test[11].dns_test_pkt_data = &response_mx_a_berkley_edu_pkt[0]; + dns_test[11].dns_test_pkt_size = response_mx_a_berkley_edu_pkt_size; + dns_test[12].dns_test_pkt_data = &response_cname_www_baidu_com_pkt[0]; + dns_test[12].dns_test_pkt_size = response_cname_www_baidu_com_pkt_size; + dns_test[13].dns_test_pkt_data = &response_ns_a_ti_com_pkt[0]; + dns_test[13].dns_test_pkt_size = response_ns_a_ti_com_pkt_size; + dns_test[14].dns_test_pkt_data = &response_srv_google_com_pkt[0]; + dns_test[14].dns_test_pkt_size = response_srv_google_com_pkt_size; + dns_test[15].dns_test_pkt_data = &response_txt_google_com_pkt[0]; + dns_test[15].dns_test_pkt_size = response_txt_google_com_pkt_size; + dns_test[16].dns_test_pkt_data = &response_soa_google_com_pkt[0]; + dns_test[16].dns_test_pkt_size = response_soa_google_com_pkt_size; +#endif /* NX_DNS_ENABLE_EXTENDED_RR_TYPES */ + +#endif /* __PRODUCT_NETXDUO__ */ +} + +static void dns_a_type_test() +{ +ULONG host_ip_address; +ULONG *ipv4_address_ptr1; +ULONG *ipv4_address_ptr2; +ULONG *ipv4_address_ptr3; +ULONG *ipv4_address_ptr4; +ULONG *ipv4_address_ptr5; +ULONG *ipv4_address_ptr6; +ULONG *ipv4_address_ptr7; +ULONG *ipv4_address_ptr8; +ULONG *ipv4_address_ptr9; +ULONG *ipv4_address_ptr10; +ULONG *ipv4_address_ptr11; + + /* Test the A type with the old API,(google.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS A Type Google Com Old API Record Singer Addr Test....."); + + /* Secd dns query, and record the single host ip address. */ + status = nx_dns_host_by_name_get(&client_dns, (UCHAR *)"google.com", &host_ip_address, 4 * NX_IP_PERIODIC_RATE); + + /* Check status and compare the host ip address. */ + if (status || host_ip_address != IP_ADDRESS(74,125,224,194)) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + + + /* Test the A type with the new API,(google.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS A Type Google Com New API Record Multi Addr Test......"); + + /* Test the A type NetX(new API) to process the multiple address. */ + status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 500, &record_count, 4 * NX_IP_PERIODIC_RATE); + + /* Check the record buffer. */ + ipv4_address_ptr1 = (ULONG *)record_buffer; + ipv4_address_ptr2 = (ULONG *)(record_buffer + 4); + ipv4_address_ptr3 = (ULONG *)(record_buffer + 8); + ipv4_address_ptr4 = (ULONG *)(record_buffer + 12); + ipv4_address_ptr5 = (ULONG *)(record_buffer + 16); + ipv4_address_ptr6 = (ULONG *)(record_buffer + 20); + ipv4_address_ptr7 = (ULONG *)(record_buffer + 24); + ipv4_address_ptr8 = (ULONG *)(record_buffer + 28); + ipv4_address_ptr9 = (ULONG *)(record_buffer + 32); + ipv4_address_ptr10 = (ULONG *)(record_buffer + 36); + ipv4_address_ptr11 = (ULONG *)(record_buffer + 40); + + /* Check status and compare the host ip address. */ + if (status || (record_count != 11) || + (*ipv4_address_ptr1 != IP_ADDRESS(74,125,224,194)) || + (*ipv4_address_ptr2 != IP_ADDRESS(74,125,224,195)) || + (*ipv4_address_ptr3 != IP_ADDRESS(74,125,224,196)) || + (*ipv4_address_ptr4 != IP_ADDRESS(74,125,224,197)) || + (*ipv4_address_ptr5 != IP_ADDRESS(74,125,224,198)) || + (*ipv4_address_ptr6 != IP_ADDRESS(74,125,224,199)) || + (*ipv4_address_ptr7 != IP_ADDRESS(74,125,224,200)) || + (*ipv4_address_ptr8 != IP_ADDRESS(74,125,224,201)) || + (*ipv4_address_ptr9 != IP_ADDRESS(74,125,224,206)) || + (*ipv4_address_ptr10 != IP_ADDRESS(74,125,224,192))|| + (*ipv4_address_ptr11 != IP_ADDRESS(74,125,224,193))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + + + /* Test the A type with the old API,(berkeley.edu.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS A Type Berkley Edu Old API Record Singer Addr Test...."); + + /* Secd dns query, and record the single host ip address. */ + status = nx_dns_host_by_name_get(&client_dns, (UCHAR *)"berkeley.edu", &host_ip_address, 4 * NX_IP_PERIODIC_RATE); + + /* Check status and compare the host ip address. */ + if (status || host_ip_address != IP_ADDRESS(169,229,216,200)) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + + + /* Test the A type with the new API,(berkeley.edu.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS A Type Berkley Edu New API Record Multi Addr Test....."); + + /* Test the A type NetX(new API) to process the multiple address. */ + status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"berkeley.edu", &record_buffer[0], 500, &record_count, 4 * NX_IP_PERIODIC_RATE); + + /* Check the record buffer. */ + ipv4_address_ptr1 = (ULONG *)record_buffer; + + /* Check status and compare the host ip address. */ + if (status || (record_count != 1) || + (*ipv4_address_ptr1 != IP_ADDRESS(169,229,216,200))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + +} + +static void dns_retransmit_test() +{ +ULONG *ipv4_address_ptr1; + + /* Test DNS Query retransmission the A type with the new API,(berkeley.edu.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS A Type Berkley Edu New API Retransmission Test........"); + + /* Test the A type NetX(new API) to process the multiple address. */ + status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"berkeley.edu", &record_buffer[0], 500, &record_count, 2 * NX_IP_PERIODIC_RATE); + + /* Check the record buffer. */ + ipv4_address_ptr1 = (ULONG *)record_buffer; + + /* Check status and compare the host ip address. */ + if (status || (record_count != 1) || + (*ipv4_address_ptr1 != IP_ADDRESS(169,229,216,200))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + +} + +#ifdef __PRODUCT_NETXDUO__ +static void dns_aaaa_type_test() +{ + +NX_DNS_IPV6_ADDRESS *ipv6_address_ptr; + +#ifdef FEATURE_NX_IPV6 +NXD_ADDRESS host_ipduo_address; +#endif + +#ifdef FEATURE_NX_IPV6 + /* Test the AAAA type with the old API,(berkeley.edu.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS AAAA Type Berkley Edu Old API Record Singer Addr Test."); + + /* Secd DNS AAAA query, and record the single host ip address. */ + status = nxd_dns_host_by_name_get(&client_dns, (UCHAR *)"berkeley.edu", &host_ipduo_address, 4 * NX_IP_PERIODIC_RATE, NX_IP_VERSION_V6); + + /* Check status and compare the host ip address. */ + if (status || + host_ipduo_address.nxd_ip_address.v6[0] != 0x2607f140 || + host_ipduo_address.nxd_ip_address.v6[1] != 0x00000081 || + host_ipduo_address.nxd_ip_address.v6[2] != 0x00000000 || + host_ipduo_address.nxd_ip_address.v6[3] != 0x0000000f) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } +#endif + + /* Test the A type with the new API,(berkeley.edu.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS AAAA Type Berkley Edu New API Record Multi Addr Test.."); + + /* Test the AAAA type NetX Duo(new API) to process the multiple address. */ + status = nxd_dns_ipv6_address_by_name_get(&client_dns, (UCHAR *)"berkeley.edu", &record_buffer[0], 200, &record_count, 4 * NX_IP_PERIODIC_RATE); + + ipv6_address_ptr = (NX_DNS_IPV6_ADDRESS *)record_buffer; + + /* Check the record buffer. */ + /* Check status and compare the host ip address. */ + if (status || record_count != 1 || + (*ipv6_address_ptr).ipv6_address[0] != 0x2607f140 || + (*ipv6_address_ptr).ipv6_address[1] != 0x00000081 || + (*ipv6_address_ptr).ipv6_address[2] != 0x00000000 || + (*ipv6_address_ptr).ipv6_address[3] != 0x0000000f) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } +} +#endif /* __PRODUCT_NETXDUO__ */ + + +#ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES + +static void dns_a_cname_type_test() +{ +ULONG host_ip_address; +ULONG *ipv4_address_ptr1; + + /* Test the A type with the old API,(google.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS A CNAME Type Www Npr Org Old API Test................."); + + /* Secd dns query, and record the single host ip address. */ + status = nx_dns_host_by_name_get(&client_dns, (UCHAR *)"www.npr.org", &host_ip_address, 4 * NX_IP_PERIODIC_RATE); + + /* Check status and compare the host ip address. */ + if (status || host_ip_address != IP_ADDRESS(216,35,221,76)) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + + + /* Test the A type with the new API,(google.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS A CNAME Type Www Npr Org New API Test................."); + + /* Test the A type NetX(new API) to process the multiple address. */ + status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"www.npr.org", &record_buffer[0], 500, &record_count, 4 * NX_IP_PERIODIC_RATE); + + /* Check the record buffer. */ + ipv4_address_ptr1 = (ULONG *)record_buffer; + + /* Check status and compare the host ip address. */ + if (status || (record_count != 1) || + (*ipv4_address_ptr1 != IP_ADDRESS(216,35,221,76))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + +} + +static void dns_mx_type_test() +{ + +NX_DNS_MX_ENTRY *nx_dns_mx_entry_ptr1; +NX_DNS_MX_ENTRY *nx_dns_mx_entry_ptr2; +NX_DNS_MX_ENTRY *nx_dns_mx_entry_ptr3; +NX_DNS_MX_ENTRY *nx_dns_mx_entry_ptr4; +NX_DNS_MX_ENTRY *nx_dns_mx_entry_ptr5; + + /* Test the MX type (google.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS MX Type Google Com New API Record Multi MX Test......."); + + /* Secd DNS MX query, and record the multiple mail exchange info. */ + status = nx_dns_domain_mail_exchange_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 500, &record_count, 4 * NX_IP_PERIODIC_RATE); + + + /* Check the record buffer. */ + nx_dns_mx_entry_ptr1 = (NX_DNS_MX_ENTRY *)record_buffer; + nx_dns_mx_entry_ptr2 = (NX_DNS_MX_ENTRY *)(record_buffer + sizeof(NX_DNS_MX_ENTRY)); + nx_dns_mx_entry_ptr3 = (NX_DNS_MX_ENTRY *)(record_buffer + (2 * sizeof(NX_DNS_MX_ENTRY))); + nx_dns_mx_entry_ptr4 = (NX_DNS_MX_ENTRY *)(record_buffer + (3 * sizeof(NX_DNS_MX_ENTRY))); + nx_dns_mx_entry_ptr5 = (NX_DNS_MX_ENTRY *)(record_buffer + (4 * sizeof(NX_DNS_MX_ENTRY))); + + /* Check status and compare the host ip address. */ + if (status || record_count != 5) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_mx_entry_ptr1 -> nx_dns_mx_preference != 50 || + memcmp(nx_dns_mx_entry_ptr1 -> nx_dns_mx_hostname_ptr, "alt4.aspmx.l.google.com", strlen((const char*)(nx_dns_mx_entry_ptr1 -> nx_dns_mx_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_mx_entry_ptr2 -> nx_dns_mx_preference != 30 || + memcmp(nx_dns_mx_entry_ptr2 -> nx_dns_mx_hostname_ptr, "alt2.aspmx.l.google.com", strlen((const char*)(nx_dns_mx_entry_ptr2 -> nx_dns_mx_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_mx_entry_ptr3 -> nx_dns_mx_preference != 10 || + memcmp(nx_dns_mx_entry_ptr3 -> nx_dns_mx_hostname_ptr, "aspmx.l.google.com", strlen((const char*)(nx_dns_mx_entry_ptr3 -> nx_dns_mx_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_mx_entry_ptr4 -> nx_dns_mx_preference != 20 || + memcmp(nx_dns_mx_entry_ptr4 -> nx_dns_mx_hostname_ptr, "alt1.aspmx.l.google.com", strlen((const char*)(nx_dns_mx_entry_ptr4 -> nx_dns_mx_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_mx_entry_ptr5 -> nx_dns_mx_preference != 40 || + memcmp(nx_dns_mx_entry_ptr5 -> nx_dns_mx_hostname_ptr, "alt3.aspmx.l.google.com", strlen((const char*)(nx_dns_mx_entry_ptr5 -> nx_dns_mx_hostname_ptr)))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + +} + + + +static void dns_mx_a_type_test() +{ + +NX_DNS_MX_ENTRY *nx_dns_mx_entry_ptr1; +NX_DNS_MX_ENTRY *nx_dns_mx_entry_ptr2; +NX_DNS_MX_ENTRY *nx_dns_mx_entry_ptr3; +NX_DNS_MX_ENTRY *nx_dns_mx_entry_ptr4; +NX_DNS_MX_ENTRY *nx_dns_mx_entry_ptr5; + + /* Test the MX&A type (google.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS MX&A Type Google Com New API Record Multi MX Test....."); + + /* Secd DNS MX query, and record the multiple mail exchange info. */ + status = nx_dns_domain_mail_exchange_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 500, &record_count, 4 * NX_IP_PERIODIC_RATE); + + + /* Check the record buffer. */ + nx_dns_mx_entry_ptr1 = (NX_DNS_MX_ENTRY *)record_buffer; + nx_dns_mx_entry_ptr2 = (NX_DNS_MX_ENTRY *)(record_buffer + sizeof(NX_DNS_MX_ENTRY)); + nx_dns_mx_entry_ptr3 = (NX_DNS_MX_ENTRY *)(record_buffer + (2 * sizeof(NX_DNS_MX_ENTRY))); + nx_dns_mx_entry_ptr4 = (NX_DNS_MX_ENTRY *)(record_buffer + (3 * sizeof(NX_DNS_MX_ENTRY))); + nx_dns_mx_entry_ptr5 = (NX_DNS_MX_ENTRY *)(record_buffer + (4 * sizeof(NX_DNS_MX_ENTRY))); + + /* Check status and compare the host ip address. */ + if (status || record_count != 5) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_mx_entry_ptr1 -> nx_dns_mx_preference != 20 || + nx_dns_mx_entry_ptr1 -> nx_dns_mx_ipv4_address != IP_ADDRESS(209,85,225,26) || + memcmp(nx_dns_mx_entry_ptr1 -> nx_dns_mx_hostname_ptr, "alt1.aspmx.l.google.com", strlen((const char*)(nx_dns_mx_entry_ptr1 -> nx_dns_mx_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_mx_entry_ptr2 -> nx_dns_mx_preference != 30 || + nx_dns_mx_entry_ptr2 -> nx_dns_mx_ipv4_address != IP_ADDRESS(74,125,130,26) || + memcmp(nx_dns_mx_entry_ptr2 -> nx_dns_mx_hostname_ptr, "alt2.aspmx.l.google.com", strlen((const char*)(nx_dns_mx_entry_ptr2 -> nx_dns_mx_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_mx_entry_ptr3 -> nx_dns_mx_preference != 40 || + nx_dns_mx_entry_ptr3 -> nx_dns_mx_ipv4_address != IP_ADDRESS(173,194,76,26) || + memcmp(nx_dns_mx_entry_ptr3 -> nx_dns_mx_hostname_ptr, "alt3.aspmx.l.google.com", strlen((const char*)(nx_dns_mx_entry_ptr3 -> nx_dns_mx_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_mx_entry_ptr4 -> nx_dns_mx_preference != 50 || + nx_dns_mx_entry_ptr4 -> nx_dns_mx_ipv4_address != IP_ADDRESS(173,194,73,26) || + memcmp(nx_dns_mx_entry_ptr4 -> nx_dns_mx_hostname_ptr, "alt4.aspmx.l.google.com", strlen((const char*)(nx_dns_mx_entry_ptr4 -> nx_dns_mx_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_mx_entry_ptr5 -> nx_dns_mx_preference != 10 || + nx_dns_mx_entry_ptr5 -> nx_dns_mx_ipv4_address != IP_ADDRESS(173,194,79,26) || + memcmp(nx_dns_mx_entry_ptr5 -> nx_dns_mx_hostname_ptr, "aspmx.l.google.com", strlen((const char*)(nx_dns_mx_entry_ptr5 -> nx_dns_mx_hostname_ptr)))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + + + /* Test the MX&A type (berkeley.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS MX&A Type Berkley Com New API Record Multi MX Test...."); + + /* Secd DNS MX query, and record the multiple mail exchange info. */ + status = nx_dns_domain_mail_exchange_get(&client_dns, (UCHAR *)"berkeley.edu", &record_buffer[0], 500, &record_count, 4 * NX_IP_PERIODIC_RATE); + + /* Check the record buffer. */ + nx_dns_mx_entry_ptr1 = (NX_DNS_MX_ENTRY *)record_buffer; + + /* Check status and compare the host ip address. */ + if (status || record_count != 1) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_mx_entry_ptr1 -> nx_dns_mx_preference != 10 || + nx_dns_mx_entry_ptr1 -> nx_dns_mx_ipv4_address != IP_ADDRESS(169,229,218,141) || + memcmp(nx_dns_mx_entry_ptr1 -> nx_dns_mx_hostname_ptr, "mx.berkeley.edu", strlen((const char*)(nx_dns_mx_entry_ptr1 -> nx_dns_mx_hostname_ptr)))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + +} + + +static void dns_cname_type_test() +{ + + /* Test the CNAME type (mail.baidu.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS CNAME Type Www Baidu Com New API Record Cname Test...."); + + /* Secd DNS CNAME query, and record the cname info. */ + status = nx_dns_cname_get(&client_dns, (UCHAR *)"www.baidu.com", &record_buffer[0], 500, 4 * NX_IP_PERIODIC_RATE); + + /* Check status and compare the host ip address. */ + if (status || + memcmp(record_buffer, "www.a.shifen.com", strlen((const char*)(&record_buffer[0])))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + +} + +static void dns_ns_a_type_test() +{ + +NX_DNS_NS_ENTRY *nx_dns_ns_entry_ptr1; +NX_DNS_NS_ENTRY *nx_dns_ns_entry_ptr2; +NX_DNS_NS_ENTRY *nx_dns_ns_entry_ptr3; +NX_DNS_NS_ENTRY *nx_dns_ns_entry_ptr4; +NX_DNS_NS_ENTRY *nx_dns_ns_entry_ptr5; +NX_DNS_NS_ENTRY *nx_dns_ns_entry_ptr6; +NX_DNS_NS_ENTRY *nx_dns_ns_entry_ptr7; +NX_DNS_NS_ENTRY *nx_dns_ns_entry_ptr8; + + /* Test the NS&A type (ti.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS NS&A Type Ti Com New API Record Multi NS Test........."); + + /* Secd DNS NS query, and record the multiple name server info. */ + status = nx_dns_domain_name_server_get(&client_dns, (UCHAR *)"ti.com", &record_buffer[0], 200, &record_count, 4 * NX_IP_PERIODIC_RATE); + + /* Check the record buffer. */ + nx_dns_ns_entry_ptr1 = (NX_DNS_NS_ENTRY *)record_buffer; + nx_dns_ns_entry_ptr2 = (NX_DNS_NS_ENTRY *)(record_buffer + sizeof(NX_DNS_NS_ENTRY)); + nx_dns_ns_entry_ptr3 = (NX_DNS_NS_ENTRY *)(record_buffer + (2 * sizeof(NX_DNS_NS_ENTRY))); + nx_dns_ns_entry_ptr4 = (NX_DNS_NS_ENTRY *)(record_buffer + (3 * sizeof(NX_DNS_NS_ENTRY))); + nx_dns_ns_entry_ptr5 = (NX_DNS_NS_ENTRY *)(record_buffer + (4 * sizeof(NX_DNS_NS_ENTRY))); + nx_dns_ns_entry_ptr6 = (NX_DNS_NS_ENTRY *)(record_buffer + (5 * sizeof(NX_DNS_NS_ENTRY))); + nx_dns_ns_entry_ptr7 = (NX_DNS_NS_ENTRY *)(record_buffer + (6 * sizeof(NX_DNS_NS_ENTRY))); + nx_dns_ns_entry_ptr8 = (NX_DNS_NS_ENTRY *)(record_buffer + (7 * sizeof(NX_DNS_NS_ENTRY))); + + /* Check status and compare the host ip address. */ + if (status || record_count != 8) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_ns_entry_ptr8 -> nx_dns_ns_ipv4_address!= IP_ADDRESS(64,95,61,4) || + memcmp(nx_dns_ns_entry_ptr8 -> nx_dns_ns_hostname_ptr, "ns-c.pnap.net", strlen((const char*)(nx_dns_ns_entry_ptr8 -> nx_dns_ns_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_ns_entry_ptr7 -> nx_dns_ns_ipv4_address!= IP_ADDRESS(64,94,123,4) || + memcmp(nx_dns_ns_entry_ptr7 -> nx_dns_ns_hostname_ptr, "ns-a.pnap.net", strlen((const char*)(nx_dns_ns_entry_ptr7 -> nx_dns_ns_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_ns_entry_ptr6 -> nx_dns_ns_ipv4_address!= IP_ADDRESS(192,94,94,43) || + memcmp(nx_dns_ns_entry_ptr6 -> nx_dns_ns_hostname_ptr, "ns2.ti.com", strlen((const char*)(nx_dns_ns_entry_ptr6 -> nx_dns_ns_hostname_ptr)))) + { + error_counter++; + } + + + /* Check the all mail exchange info. */ + if(nx_dns_ns_entry_ptr5 -> nx_dns_ns_ipv4_address!= IP_ADDRESS(192,94,94,42) || + memcmp(nx_dns_ns_entry_ptr5 -> nx_dns_ns_hostname_ptr, "ns.ti.com", strlen((const char*)(nx_dns_ns_entry_ptr5 -> nx_dns_ns_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_ns_entry_ptr4 -> nx_dns_ns_ipv4_address!= IP_ADDRESS(198,47,26,151) || + memcmp(nx_dns_ns_entry_ptr4 -> nx_dns_ns_hostname_ptr, "ns4.ti.com", strlen((const char*)(nx_dns_ns_entry_ptr4 -> nx_dns_ns_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_ns_entry_ptr3 -> nx_dns_ns_ipv4_address!= IP_ADDRESS(198,47,26,150) || + memcmp(nx_dns_ns_entry_ptr3 -> nx_dns_ns_hostname_ptr, "ns3.ti.com", strlen((const char*)(nx_dns_ns_entry_ptr3 -> nx_dns_ns_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_ns_entry_ptr2 -> nx_dns_ns_ipv4_address!= IP_ADDRESS(64,94,123,36) || + memcmp(nx_dns_ns_entry_ptr2 -> nx_dns_ns_hostname_ptr, "ns-b.pnap.net", strlen((const char*)(nx_dns_ns_entry_ptr2 -> nx_dns_ns_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_ns_entry_ptr1 -> nx_dns_ns_ipv4_address!= IP_ADDRESS(64,95,61,36) || + memcmp(nx_dns_ns_entry_ptr1 -> nx_dns_ns_hostname_ptr, "ns-d.pnap.net", strlen((const char*)(nx_dns_ns_entry_ptr1 -> nx_dns_ns_hostname_ptr)))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } +} + + +static void dns_srv_type_test() +{ + +NX_DNS_SRV_ENTRY *nx_dns_srv_entry_ptr1; +NX_DNS_SRV_ENTRY *nx_dns_srv_entry_ptr2; +NX_DNS_SRV_ENTRY *nx_dns_srv_entry_ptr3; +NX_DNS_SRV_ENTRY *nx_dns_srv_entry_ptr4; +NX_DNS_SRV_ENTRY *nx_dns_srv_entry_ptr5; + + /* Test the SRV type (google.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS SRV Type Google Com New API Record Multi service Test."); + + /* Secd DNS SRV query, and record the multiple service info. */ + status = nx_dns_domain_service_get(&client_dns, (UCHAR *)"_xmpp-client._tcp.google.com", &record_buffer[0], 500, &record_count, 4 * NX_IP_PERIODIC_RATE); + + /* Check the record buffer. */ + nx_dns_srv_entry_ptr1 = (NX_DNS_SRV_ENTRY *)record_buffer; + nx_dns_srv_entry_ptr2 = (NX_DNS_SRV_ENTRY *)(record_buffer + sizeof(NX_DNS_SRV_ENTRY)); + nx_dns_srv_entry_ptr3 = (NX_DNS_SRV_ENTRY *)(record_buffer + (2 * sizeof(NX_DNS_SRV_ENTRY))); + nx_dns_srv_entry_ptr4 = (NX_DNS_SRV_ENTRY *)(record_buffer + (3 * sizeof(NX_DNS_SRV_ENTRY))); + nx_dns_srv_entry_ptr5 = (NX_DNS_SRV_ENTRY *)(record_buffer + (4 * sizeof(NX_DNS_SRV_ENTRY))); + + /* Check status and compare the host ip address. */ + if (status || record_count != 5) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_srv_entry_ptr1 -> nx_dns_srv_port_number != 5222 || + nx_dns_srv_entry_ptr1 -> nx_dns_srv_priority != 20 || + nx_dns_srv_entry_ptr1 -> nx_dns_srv_weight != 0 || + memcmp(nx_dns_srv_entry_ptr1 -> nx_dns_srv_hostname_ptr, "alt3.xmpp.l.google.com", strlen((const char*)(nx_dns_srv_entry_ptr1 -> nx_dns_srv_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_srv_entry_ptr2 -> nx_dns_srv_port_number != 5222 || + nx_dns_srv_entry_ptr2 -> nx_dns_srv_priority != 20 || + nx_dns_srv_entry_ptr2 -> nx_dns_srv_weight != 0 || + memcmp(nx_dns_srv_entry_ptr2 -> nx_dns_srv_hostname_ptr, "alt1.xmpp.l.google.com", strlen((const char*)(nx_dns_srv_entry_ptr2 -> nx_dns_srv_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_srv_entry_ptr3 -> nx_dns_srv_port_number != 5222 || + nx_dns_srv_entry_ptr3 -> nx_dns_srv_priority != 20 || + nx_dns_srv_entry_ptr3 -> nx_dns_srv_weight != 0 || + memcmp(nx_dns_srv_entry_ptr3 -> nx_dns_srv_hostname_ptr, "alt4.xmpp.l.google.com", strlen((const char*)(nx_dns_srv_entry_ptr3 -> nx_dns_srv_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_srv_entry_ptr4 -> nx_dns_srv_port_number != 5222 || + nx_dns_srv_entry_ptr4 -> nx_dns_srv_priority != 5 || + nx_dns_srv_entry_ptr4 -> nx_dns_srv_weight != 0 || + memcmp(nx_dns_srv_entry_ptr4 -> nx_dns_srv_hostname_ptr, "xmpp.l.google.com", strlen((const char*)(nx_dns_srv_entry_ptr4 -> nx_dns_srv_hostname_ptr)))) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_srv_entry_ptr5 -> nx_dns_srv_port_number != 5222 || + nx_dns_srv_entry_ptr5 -> nx_dns_srv_priority != 20 || + nx_dns_srv_entry_ptr5 -> nx_dns_srv_weight != 0 || + memcmp(nx_dns_srv_entry_ptr5 -> nx_dns_srv_hostname_ptr, "alt2.xmpp.l.google.com", strlen((const char*)(nx_dns_srv_entry_ptr5 -> nx_dns_srv_hostname_ptr)))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + +} + + +static void dns_txt_type_test() +{ + + /* Test the TXT type (google.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS TXT Type Google Com New API Record Txt Test..........."); + + /* Secd DNS CNAME query, and record the cname info. */ + status = nx_dns_host_text_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 500, 4 * NX_IP_PERIODIC_RATE); + + /* Check status and compare the host ip address. */ + if (status || + memcmp(record_buffer, "v=spf1 include:_netblocks.google.com ip4:216.73.93.70/31 ip4:216.73.93.72/31 ~all", strlen((const char*)(&record_buffer[0])))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + +} + + +static void dns_soa_type_test() +{ + +NX_DNS_SOA_ENTRY *nx_dns_soa_entry_ptr; + + /* Test the SOA type (google.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS SOA Type Google Com New API Record start of zone Test."); + + /* Secd DNS SRV query, and record the multiple service info. */ + status = nx_dns_authority_zone_start_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 100, 4 * NX_IP_PERIODIC_RATE); + + /* Check the record buffer. */ + nx_dns_soa_entry_ptr = (NX_DNS_SOA_ENTRY *)record_buffer; + + /* Check status and compare the host ip address. */ + if (status) + { + error_counter++; + } + + /* Check the all mail exchange info. */ + if(nx_dns_soa_entry_ptr -> nx_dns_soa_serial != 2012090400 || + nx_dns_soa_entry_ptr -> nx_dns_soa_refresh != 2 * 60 * 60 || + nx_dns_soa_entry_ptr -> nx_dns_soa_retry != 30 * 60 || + nx_dns_soa_entry_ptr -> nx_dns_soa_expire != 14 * 24 * 60 * 60 || + nx_dns_soa_entry_ptr -> nx_dns_soa_minmum != 5 * 60 || + memcmp( nx_dns_soa_entry_ptr -> nx_dns_soa_host_mname_ptr, "ns1.google.com", strlen((const char*)(nx_dns_soa_entry_ptr -> nx_dns_soa_host_mname_ptr))) || + memcmp( nx_dns_soa_entry_ptr -> nx_dns_soa_host_rname_ptr, "dns-admin.google.com", strlen((const char*)(nx_dns_soa_entry_ptr -> nx_dns_soa_host_rname_ptr)))) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + +} + +#endif +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_function_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DNS Function Test.........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dns_test/netx_dns_invalid_name_unencode_test.c b/test/regression/dns_test/netx_dns_invalid_name_unencode_test.c new file mode 100644 index 00000000..9c0e8127 --- /dev/null +++ b/test/regression/dns_test/netx_dns_invalid_name_unencode_test.c @@ -0,0 +1,407 @@ +/* This NetX test concentrates on the basic DNS operation. Unencode invalid string. */ + +/* Frame (125 bytes) */ +static unsigned char invalid_ptr_response_0[125] = { +0xf4, 0x8e, 0x38, 0xa3, 0xab, 0xf6, 0x8c, 0xec, /* ..8..... */ +0x4b, 0x68, 0xd1, 0xfe, 0x08, 0x00, 0x45, 0x00, /* Kh....E. */ +0x00, 0x6f, 0x1a, 0x9a, 0x40, 0x00, 0x40, 0x11, /* .o..@.@. */ +0xd6, 0x2e, 0xc0, 0xa8, 0x64, 0x02, 0xc0, 0xa8, /* ....d... */ +0x64, 0x62, 0x00, 0x35, 0xef, 0x67, 0x00, 0x5b, /* db.5.g.[ */ +0x7e, 0xb5, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, /* ~....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, /* .......1 */ +0x34, 0x03, 0x32, 0x30, 0x33, 0x02, 0x35, 0x38, /* 4.203.58 */ +0x03, 0x32, 0x31, 0x36, 0x07, 0x69, 0x6e, 0x2d, /* .216.in- */ +0x61, 0x64, 0x64, 0x72, 0x04, 0x61, 0x72, 0x70, /* addr.arp */ +0x61, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x02, 0x31, /* a......1 */ +0x34, 0x03, 0x32, 0x30, 0x33, 0x02, 0x35, 0x38, /* 4.203.58 */ +0x03, 0x32, 0x31, 0x36, 0x07, 0x69, 0x6e, 0x2d, /* .216.in- */ +0x61, 0x64, 0x64, 0x72, 0x04, 0x61, 0x72, 0x70, /* addr.arp */ +0x61, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* a....... */ +0x95, 0x04, 0x00, 0x01, 0x00 /* ..... */ +}; + +/* Frame-2 (128 bytes) */ +static unsigned char invalid_ptr_response_1[128] = { +0xf4, 0x8e, 0x38, 0xa3, 0xab, 0xf6, 0x8c, 0xec, /* ..8..... */ +0x4b, 0x68, 0xd1, 0xfe, 0x08, 0x00, 0x45, 0x00, /* Kh....E. */ +0x00, 0x6f, 0x1a, 0x9a, 0x40, 0x00, 0x40, 0x11, /* .o..@.@. */ +0xd6, 0x2e, 0xc0, 0xa8, 0x64, 0x02, 0xc0, 0xa8, /* ....d... */ +0x64, 0x62, 0x00, 0x35, 0xef, 0x67, 0x00, 0x5b, /* db.5.g.[ */ +0x7e, 0xb5, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, /* ~....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, /* .......1 */ +0x34, 0x03, 0x32, 0x30, 0x33, 0x02, 0x35, 0x38, /* 4.203.58 */ +0x03, 0x32, 0x31, 0x36, 0x07, 0x69, 0x6e, 0x2d, /* .216.in- */ +0x61, 0x64, 0x64, 0x72, 0x04, 0x61, 0x72, 0x70, /* addr.arp */ +0x61, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x02, 0x31, /* a......1 */ +0x34, 0x03, 0x32, 0x30, 0x33, 0x02, 0x35, 0x38, /* 4.203.58 */ +0x03, 0x32, 0x31, 0x36, 0x07, 0x69, 0x6e, 0x2d, /* .216.in- */ +0x61, 0x64, 0x64, 0x72, 0x04, 0x61, 0x72, 0x70, /* addr.arp */ +0x61, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* a....... */ +0x95, 0x04, 0x00, 0x01, 0xc0, 0x54, 0xc0, 0x52 /* ..... */ +}; + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dns.h" +#else +#include "nx_dns.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#ifndef NX_DISABLE_IPV4 + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP client_ip; +static NX_IP server_ip; + +static NX_UDP_SOCKET server_socket; +static NX_DNS client_dns; + + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL +NX_PACKET_POOL client_pool; +#endif + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +#define DNS_START_OFFSET (14 + 20 + 8) + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_invalid_name_unencode_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the DNS main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 8192); + pointer = pointer + 8192; + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Create the packet pool for the DNS Client to send packets. + + If the DNS Client is configured for letting the host application create + the DNS packet pool, (see NX_DNS_CLIENT_USER_CREATE_PACKET_POOL option), see + nx_dns_create() for guidelines on packet payload size and pool size. + packet traffic for NetX Duo processes. + */ + status = nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", NX_DNS_PACKET_PAYLOAD, pointer, NX_DNS_PACKET_POOL_SIZE); + + pointer = pointer + NX_DNS_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + return; +#endif + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "NetX IP Instance 0", IP_ADDRESS(192, 168, 100, 98), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "NetX IP Instance 1", IP_ADDRESS(192, 168, 100, 2), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UCHAR host_name[300]; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: DNS Invalid Name Unencode Test............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a DNS instance for the Client. Note this function will create + the DNS Client packet pool for creating DNS message packets intended + for querying its DNS server. */ + status = nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client"); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Is the DNS client configured for the host application to create the pecket pool? */ +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Yes, use the packet pool created above which has appropriate payload size + for DNS messages. */ + status = nx_dns_packet_pool_set(&client_dns, &client_pool); + + /* Check for set DNS packet pool error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Add an IPv4 server address to the Client list. */ + status = nx_dns_server_add(&client_dns, IP_ADDRESS(192, 168, 100, 2)); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + host_name[0] = '.'; + host_name[1] = '.'; + host_name[2] = '.'; + host_name[3] = '.'; + + for (i = 0; i < 2; i++) { + /* Send DNS PTR query, response invalid name. */ + status = nx_dns_host_by_address_get(&client_dns, IP_ADDRESS(216, 58, 203, 14), &host_name[4], 256, NX_IP_PERIODIC_RATE); + + /* Sleep 1s to check if crash. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT port; +USHORT nx_dns_transmit_id; +UCHAR *data_ptr; +NX_PACKET *response_packet[2]; +UINT i; +UCHAR *invalid_ptr_response; +UINT response_len; + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&server_socket, 53, TX_WAIT_FOREVER); + + + /* Act as the DNS server to receive the DNS query and send the DNS response. */ + for (i = 0; i < 2; i++) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS client UDP port. */ + status = nx_udp_packet_info_extract(my_packet, NX_NULL, NX_NULL, &port, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS transmit ID. */ + data_ptr = my_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + nx_dns_transmit_id = *data_ptr++; + nx_dns_transmit_id = (USHORT)((nx_dns_transmit_id << 8) | *data_ptr); + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send the DNS response packet. */ + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet[i], NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + if (i == 0) + { + invalid_ptr_response = invalid_ptr_response_0; + response_len = 125; + } else { + invalid_ptr_response = invalid_ptr_response_1; + response_len = 128; + } + /* Write the DNS response messages into the packet payload! */ + memcpy(response_packet[i] -> nx_packet_prepend_ptr, invalid_ptr_response + DNS_START_OFFSET, response_len - DNS_START_OFFSET); + + /* Adjust the write pointer. */ + response_packet[i] -> nx_packet_length = response_len - DNS_START_OFFSET; + response_packet[i] -> nx_packet_append_ptr = response_packet[i] -> nx_packet_prepend_ptr + response_packet[i] -> nx_packet_length; + + /* Update the DNS transmit ID. */ + data_ptr = response_packet[i] -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + *data_ptr++ = (UCHAR)(nx_dns_transmit_id >> 8); + *data_ptr = (UCHAR)nx_dns_transmit_id; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(&server_socket, response_packet[i], IP_ADDRESS(192, 168, 100, 98), port); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet[i]); + return; + } + + } + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Let the DNS threads execute. */ + tx_thread_relinquish(); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_invalid_name_unencode_test_application_define(void *first_unused_memory) +#endif + +{ + + /* Print out test information banner. */ + printf("NetX Test: DNS Invalid Name Unencode Test............................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/dns_test/netx_dns_invalid_resource_get_test.c b/test/regression/dns_test/netx_dns_invalid_resource_get_test.c new file mode 100644 index 00000000..c3b5fdc8 --- /dev/null +++ b/test/regression/dns_test/netx_dns_invalid_resource_get_test.c @@ -0,0 +1,428 @@ +/* This NetX test concentrates on DNS operation with invalid resource in DNS response packet. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dns.h" +#else +#include "nx_dns.h" +#endif + +extern char invalid_response_ptr_0[119]; +extern UINT invalid_response_size_0; +extern char invalid_response_ptr_1[119]; +extern UINT invalid_response_size_1; +extern char invalid_response_ptr_2[119]; +extern UINT invalid_response_size_2; +extern char invalid_response_ptr_3[119]; +extern UINT invalid_response_size_3; + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_UDP_SOCKET server_socket; + +static NX_DNS client_dns; + +#define DNS_SERVER_ADDRESS IP_ADDRESS(10,0,0,1) + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL +NX_PACKET_POOL client_pool; +#endif + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG notify_calls = 0; + +static UCHAR record_buffer[500]; +static UINT record_count; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); + +/* DNS Tests. */ +static void dns_test_initialize(); + +/* Send DNS response. */ +static UINT nx_dns_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, USHORT nx_dns_transmit_id, UINT packet_number); + +/* Send DNS query. */ +static UINT nx_dns_query_packet_send(); + +typedef struct DNS_TEST_STRUCT +{ + char *dns_test_pkt_data; + UINT dns_test_pkt_size; +} DNS_TEST; + +#define test_count 4 +static DNS_TEST dns_test[test_count]; + +extern ULONG test_control_successful_tests; +extern ULONG test_control_failed_tests; + +#define DNS_START_OFFSET (14 + 20 + 8) + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_invalid_resource_get_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the DNS main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 8192); + pointer = pointer + 8192; + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Create the packet pool for the DNS Client to send packets. + + If the DNS Client is configured for letting the host application create + the DNS packet pool, (see NX_DNS_CLIENT_USER_CREATE_PACKET_POOL option), see + nx_dns_create() for guidelines on packet payload size and pool size. + packet traffic for NetX Duo processes. + */ + status = nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", NX_DNS_PACKET_PAYLOAD, pointer, NX_DNS_PACKET_POOL_SIZE); + + pointer = pointer + NX_DNS_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + return; +#endif + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "NetX IP Instance 0", IP_ADDRESS(10, 0, 0, 10), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "NetX IP Instance 1", IP_ADDRESS(10, 0, 0, 1), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT i; + + /* Create a DNS instance for the Client. Note this function will create + the DNS Client packet pool for creating DNS message packets intended + for querying its DNS server. */ + status = nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client"); + + /* Is the DNS client configured for the host application to create the pecket pool? */ +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Yes, use the packet pool created above which has appropriate payload size + for DNS messages. */ + status = nx_dns_packet_pool_set(&client_dns, &client_pool); + + /* Check for set DNS packet pool error. */ + if (status) + { + error_counter++; + } + +#endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Add an IPv4 server address to the Client list. */ + status = nx_dns_server_add(&client_dns, DNS_SERVER_ADDRESS); + if (status) + { + error_counter++; + } + + /* The DNS test initialize. */ + dns_test_initialize(); + + printf("Begin test\n"); + nx_dns_query_packet_send(); + + test_control_return(0xdeadbeef); +} + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT port; +UINT i; +USHORT nx_dns_transmit_id; +UCHAR *data_ptr; + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&server_socket, 53, TX_WAIT_FOREVER); + + /* Act as the DNS server to receive the DNS query and send the DNS response. */ + for (i = 0; i < test_count; i++ ) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS client UDP port. */ + status = nx_udp_packet_info_extract(my_packet, NX_NULL ,NX_NULL, &port, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS transmit ID. */ + data_ptr = my_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + nx_dns_transmit_id = *data_ptr++; + nx_dns_transmit_id = (USHORT)((nx_dns_transmit_id << 8) | *data_ptr); + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send the DNS response packet. */ + status = nx_dns_response_packet_send(&server_socket, port, nx_dns_transmit_id, i); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Let the DNS threads execute. */ + tx_thread_relinquish(); +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_dns_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port, USHORT nx_dns_transmit_id, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; +UCHAR *data_ptr; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the DNS response messages into the packet payload! */ + dns_test[packet_number].dns_test_pkt_data += DNS_START_OFFSET; + memcpy(response_packet -> nx_packet_prepend_ptr, dns_test[packet_number].dns_test_pkt_data, dns_test[packet_number].dns_test_pkt_size - DNS_START_OFFSET); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = dns_test[packet_number].dns_test_pkt_size - DNS_START_OFFSET; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Update the DNS transmit ID. */ + data_ptr = response_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + *data_ptr++ = (UCHAR)(nx_dns_transmit_id >> 8); + *data_ptr = (UCHAR)nx_dns_transmit_id; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(server_socket, response_packet, IP_ADDRESS(10, 0, 0, 10), port); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} + +static UINT nx_dns_query_packet_send() +{ +UINT status; +UINT i; + + for (i = 0; i < test_count; i++) + { + printf("NetX Test: DNS Test [%u] with invalid resource in response ........", i); + + status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"berkeley.edu", &record_buffer[0], 500, &record_count, 2 * NX_IP_PERIODIC_RATE); + + /* Check the record buffer. */ + if (!status) + { + error_counter++; + } + + /* Printf the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + + } + return 0; +} + +static void dns_test_initialize() +{ + dns_test[0].dns_test_pkt_data = &invalid_response_ptr_2[0]; + dns_test[0].dns_test_pkt_size = invalid_response_size_2; + + dns_test[1].dns_test_pkt_data = &invalid_response_ptr_1[0]; + dns_test[1].dns_test_pkt_size = invalid_response_size_1; + + dns_test[2].dns_test_pkt_data = &invalid_response_ptr_2[0]; + dns_test[2].dns_test_pkt_size = invalid_response_size_2; + + dns_test[3].dns_test_pkt_data = &invalid_response_ptr_3[0]; + dns_test[3].dns_test_pkt_size = invalid_response_size_3; + + return; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_invalid_resource_get_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: DNS Invalid Resource Get Test.........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/dns_test/netx_dns_non_blocking_a_test.c b/test/regression/dns_test/netx_dns_non_blocking_a_test.c new file mode 100644 index 00000000..57551580 --- /dev/null +++ b/test/regression/dns_test/netx_dns_non_blocking_a_test.c @@ -0,0 +1,420 @@ +/* This NetX test concentrates on the basic DNS operation. Non-blocking test. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dns.h" +#else +#include "nx_dns.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#ifndef NX_DISABLE_IPV4 + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_SEMAPHORE semaphore; + +static NX_PACKET_POOL pool_0; +static NX_IP client_ip; +static NX_IP server_ip; + +static NX_UDP_SOCKET server_socket; +static NX_DNS client_dns; + + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL +NX_PACKET_POOL client_pool; +#endif + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void _nx_dns_udp_receive_notify(NX_UDP_SOCKET *socket_ptr); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +#define DNS_START_OFFSET (14 + 20 + 8) + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_non_blocking_a_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the DNS main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 8192); + pointer = pointer + 8192; + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Create the packet pool for the DNS Client to send packets. + + If the DNS Client is configured for letting the host application create + the DNS packet pool, (see NX_DNS_CLIENT_USER_CREATE_PACKET_POOL option), see + nx_dns_create() for guidelines on packet payload size and pool size. + packet traffic for NetX Duo processes. + */ + status = nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", NX_DNS_PACKET_PAYLOAD, pointer, NX_DNS_PACKET_POOL_SIZE); + + pointer = pointer + NX_DNS_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + return; +#endif + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "NetX IP Instance 0", IP_ADDRESS(192, 168, 100, 98), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "NetX IP Instance 1", IP_ADDRESS(192, 168, 100, 2), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UCHAR record_buffer[64]; +UINT record_count; +ULONG *ipv4_address_ptr1; +ULONG *ipv4_address_ptr2; +ULONG *ipv4_address_ptr3; +ULONG *ipv4_address_ptr4; +ULONG *ipv4_address_ptr5; +ULONG *ipv4_address_ptr6; +ULONG *ipv4_address_ptr7; +ULONG *ipv4_address_ptr8; +ULONG *ipv4_address_ptr9; +ULONG *ipv4_address_ptr10; +ULONG *ipv4_address_ptr11; + + /* Print out some test information banners. */ + printf("NetX Test: DNS Non Blocking A Test..................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the test control semaphore. */ + tx_semaphore_create(&semaphore, "DNS Non Blocking", 0); + + /* Create a DNS instance for the Client. Note this function will create + the DNS Client packet pool for creating DNS message packets intended + for querying its DNS server. */ + status = nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client"); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Is the DNS client configured for the host application to create the pecket pool? */ +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Yes, use the packet pool created above which has appropriate payload size + for DNS messages. */ + status = nx_dns_packet_pool_set(&client_dns, &client_pool); + + /* Check for set DNS packet pool error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Add an IPv4 server address to the Client list. */ + status = nx_dns_server_add(&client_dns, IP_ADDRESS(192, 168, 100, 2)); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the UDP socket receive callback function. */ + nx_udp_socket_receive_notify(&(client_dns.nx_dns_socket), _nx_dns_udp_receive_notify); + + /* Send query. */ + status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 64, &record_count, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_IN_PROGRESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the semaphore. */ + status = tx_semaphore_get(&semaphore, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != TX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the response. */ + status = _nx_dns_response_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 64, &record_count, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the record buffer. */ + ipv4_address_ptr1 = (ULONG *)record_buffer; + ipv4_address_ptr2 = (ULONG *)(record_buffer + 4); + ipv4_address_ptr3 = (ULONG *)(record_buffer + 8); + ipv4_address_ptr4 = (ULONG *)(record_buffer + 12); + ipv4_address_ptr5 = (ULONG *)(record_buffer + 16); + ipv4_address_ptr6 = (ULONG *)(record_buffer + 20); + ipv4_address_ptr7 = (ULONG *)(record_buffer + 24); + ipv4_address_ptr8 = (ULONG *)(record_buffer + 28); + ipv4_address_ptr9 = (ULONG *)(record_buffer + 32); + ipv4_address_ptr10 = (ULONG *)(record_buffer + 36); + ipv4_address_ptr11 = (ULONG *)(record_buffer + 40); + + /* Check status and compare the host ip address. */ + if ((record_count != 11) || + (*ipv4_address_ptr1 != IP_ADDRESS(74,125,224,194)) || + (*ipv4_address_ptr2 != IP_ADDRESS(74,125,224,195)) || + (*ipv4_address_ptr3 != IP_ADDRESS(74,125,224,196)) || + (*ipv4_address_ptr4 != IP_ADDRESS(74,125,224,197)) || + (*ipv4_address_ptr5 != IP_ADDRESS(74,125,224,198)) || + (*ipv4_address_ptr6 != IP_ADDRESS(74,125,224,199)) || + (*ipv4_address_ptr7 != IP_ADDRESS(74,125,224,200)) || + (*ipv4_address_ptr8 != IP_ADDRESS(74,125,224,201)) || + (*ipv4_address_ptr9 != IP_ADDRESS(74,125,224,206)) || + (*ipv4_address_ptr10 != IP_ADDRESS(74,125,224,192))|| + (*ipv4_address_ptr11 != IP_ADDRESS(74,125,224,193))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +extern char response_a_google_com_pkt[]; +extern int response_a_google_com_pkt_size; + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT port; +USHORT nx_dns_transmit_id; +UCHAR *data_ptr; +NX_PACKET *response_packet; + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&server_socket, 53, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS client UDP port. */ + status = nx_udp_packet_info_extract(my_packet, NX_NULL, NX_NULL, &port, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS transmit ID. */ + data_ptr = my_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + nx_dns_transmit_id = *data_ptr++; + nx_dns_transmit_id = (USHORT)((nx_dns_transmit_id << 8) | *data_ptr); + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send the DNS response packet. */ + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Write the DNS response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, response_a_google_com_pkt + DNS_START_OFFSET, response_a_google_com_pkt_size - DNS_START_OFFSET); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = response_a_google_com_pkt_size - DNS_START_OFFSET; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Update the DNS transmit ID. */ + data_ptr = response_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + *data_ptr++ = (UCHAR)(nx_dns_transmit_id >> 8); + *data_ptr = (UCHAR)nx_dns_transmit_id; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(&server_socket, response_packet, IP_ADDRESS(192, 168, 100, 98), port); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + return; + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Let the DNS threads execute. */ + tx_thread_relinquish(); +} + +static void _nx_dns_udp_receive_notify(NX_UDP_SOCKET *socket_ptr) +{ + + NX_PARAMETER_NOT_USED(socket_ptr); + tx_semaphore_put(&semaphore); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_non_blocking_a_test_application_define(void *first_unused_memory) +#endif + +{ + + /* Print out test information banner. */ + printf("NetX Test: DNS Non Blocking A Test...................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/dns_test/netx_dns_nxe_api_test.c b/test/regression/dns_test/netx_dns_nxe_api_test.c new file mode 100644 index 00000000..100d10a7 --- /dev/null +++ b/test/regression/dns_test/netx_dns_nxe_api_test.c @@ -0,0 +1,261 @@ +/* NetX DNS Client API error tests. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#include "nx_ip.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dns.h" +#else +#include "nx_dns.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* DNS Client Error Checking Test. */ +static void error_checking_test(void); + +static NX_IP ip_0; +static NX_DNS dns_0; +static UCHAR temp_uchar; +static UINT temp_uint; +static ULONG temp_ulong; +static USHORT temp_ushort; +static USHORT temp_ushort2; // we need a second ushort to make sure this one is not 32 bit aligned + +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS address_0; +#endif + +extern volatile ULONG _tx_thread_system_state; +extern TX_THREAD *_tx_thread_current_ptr; +extern TX_THREAD _tx_timer_thread; + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: DNS Client Error Checking Test..........................\n"); + + static CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_checking_test(); + + printf("SUCCESS!\n"); + test_control_return(0); +} + +#define validate_expected_status(status,expected_status) if (expected_status != status) {printf("%s,%d: ERROR!",__FILE__, __LINE__);test_control_return(1);} + + +static void nxe_dns_server_add_remove_error_check_test(NX_DNS *dns_ptr, ULONG server_address, UINT expected_status) +{ + //_nxe_dns_server_add(NX_DNS *dns_ptr, ULONG server_address) + validate_expected_status(_nxe_dns_server_add(dns_ptr, server_address), expected_status); + + //_nxe_dns_server_remove(NX_DNS *dns_ptr, ULONG server_address) + validate_expected_status(_nxe_dns_server_remove(dns_ptr, server_address), expected_status); + + //_nxe_dns_server_remove_all(NX_DNS *dns_ptr) + if (expected_status != NX_DNS_BAD_ADDRESS_ERROR) { + validate_expected_status(_nxe_dns_server_remove_all(dns_ptr), expected_status); + } +} + +#ifdef __PRODUCT_NETXDUO__ +static void nxde_address_error_checks() { + dns_0.nx_dns_id = NX_DNS_ID; + address_0.nxd_ip_version = NX_NULL; + validate_expected_status(_nxde_dns_server_add(&dns_0, &address_0), NX_DNS_PARAM_ERROR); + + address_0.nxd_ip_version = 0x1; + validate_expected_status(_nxde_dns_server_add(&dns_0, &address_0), NX_DNS_INVALID_ADDRESS_TYPE); + validate_expected_status(_nxde_dns_server_remove(&dns_0, &address_0), NX_DNS_INVALID_ADDRESS_TYPE); + + address_0.nxd_ip_version = NX_IP_VERSION_V4; + address_0.nxd_ip_address.v4 = 0; + validate_expected_status(_nxde_dns_server_add(&dns_0, &address_0), NX_DNS_BAD_ADDRESS_ERROR); + validate_expected_status(_nxde_dns_server_remove(&dns_0, &address_0), NX_DNS_BAD_ADDRESS_ERROR); + +#ifdef FEATURE_NX_IPV6 + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0; + validate_expected_status(_nxde_dns_server_add(&dns_0, &address_0), NX_DNS_BAD_ADDRESS_ERROR); + validate_expected_status(_nxde_dns_server_remove(&dns_0, &address_0), NX_DNS_BAD_ADDRESS_ERROR); +#endif +} +#endif + +static void nx_dns_id_calls(void) +{ + validate_expected_status(_nxe_dns_delete(&dns_0), NX_CALLER_ERROR); + nxe_dns_server_add_remove_error_check_test(&dns_0, 1, NX_CALLER_ERROR); + validate_expected_status(_nxe_dns_get_serverlist_size(&dns_0, &temp_uint), NX_CALLER_ERROR); + validate_expected_status(_nxe_dns_server_get(&dns_0, 0, &temp_ulong), NX_CALLER_ERROR); + validate_expected_status(_nxe_dns_host_by_name_get(&dns_0, &temp_uchar, &temp_ulong, 1), NX_CALLER_ERROR); + validate_expected_status(_nxe_dns_ipv4_address_by_name_get(&dns_0, &temp_uchar, (void*)&temp_ulong, 1, &temp_uint, 1), NX_CALLER_ERROR); + validate_expected_status(_nxe_dns_host_by_address_get(&dns_0, 1, &temp_uchar, 1, 1), NX_CALLER_ERROR); +#ifdef __PRODUCT_NETXDUO__ +#ifdef FEATURE_NX_IPV6 + validate_expected_status(_nxde_dns_ipv6_address_by_name_get(&dns_0, &temp_uchar, (void*)&temp_ulong, 1, &temp_uint, 1), NX_CALLER_ERROR); + validate_expected_status(_nxde_dns_host_by_address_get(&dns_0, &address_0, &temp_uchar, 1, 1), NX_CALLER_ERROR); + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 13; + address_0.nxd_ip_address.v6[1] = 14; + address_0.nxd_ip_address.v6[2] = 13; + address_0.nxd_ip_address.v6[3] = 14; + validate_expected_status(_nxde_dns_server_add(&dns_0, &address_0), NX_CALLER_ERROR); +#endif + address_0.nxd_ip_version = NX_IP_VERSION_V4; + address_0.nxd_ip_address.v4 = 1314; + validate_expected_status(_nxde_dns_server_add(&dns_0, &address_0), NX_CALLER_ERROR); + validate_expected_status(_nxde_dns_server_remove(&dns_0, &address_0), NX_CALLER_ERROR); + validate_expected_status(_nxde_dns_server_get(&dns_0, 0, &address_0), NX_CALLER_ERROR); + validate_expected_status(_nxde_dns_host_by_name_get(&dns_0, &temp_uchar, &address_0, 0, 1), NX_CALLER_ERROR); +#endif +} + +static void error_checking_test(void) +{ + validate_expected_status(_nxe_dns_create(NX_NULL, NX_NULL, NX_NULL), NX_PTR_ERROR); + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + validate_expected_status(_nxe_dns_packet_pool_set(NX_NULL, NX_NULL), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_packet_pool_set(&dns_0, NX_NULL), NX_PTR_ERROR); +#endif + + validate_expected_status(_nxe_dns_delete(NX_NULL), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_get_serverlist_size(NX_NULL, NX_NULL), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_server_get(NX_NULL, 0, NX_NULL), NX_PTR_ERROR); + nxe_dns_server_add_remove_error_check_test(NX_NULL, 1, NX_PTR_ERROR); + + validate_expected_status(_nxe_dns_host_by_name_get(NX_NULL, NX_NULL, NX_NULL, 1), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_host_by_name_get(&dns_0, NX_NULL, NX_NULL, 1), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_host_by_name_get(&dns_0, &temp_uchar, NX_NULL, 1), NX_PTR_ERROR); + + validate_expected_status(_nxe_dns_ipv4_address_by_name_get(NX_NULL, &temp_uchar, (void*)&temp_ulong, 1, &temp_uint, 1), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_ipv4_address_by_name_get(&dns_0, NX_NULL, (void*)&temp_ulong, 1, &temp_uint, 1), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_ipv4_address_by_name_get(&dns_0, &temp_uchar, NX_NULL, 1, &temp_uint, 1), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_ipv4_address_by_name_get(&dns_0, &temp_uchar, (void*)&temp_ulong, 1, NX_NULL, 1), NX_PTR_ERROR); + + validate_expected_status(_nxe_dns_host_by_address_get(NX_NULL, 1, &temp_uchar, 1, 1), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_host_by_address_get(&dns_0, 1, NX_NULL, 1, 1), NX_PTR_ERROR); + +#ifdef __PRODUCT_NETXDUO__ + validate_expected_status(_nxde_dns_ipv6_address_by_name_get(NX_NULL, &temp_uchar, (void*)&temp_ulong, 1, &temp_uint, 1), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_ipv6_address_by_name_get(&dns_0, NX_NULL, (void*)&temp_ulong, 1, &temp_uint, 1), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_ipv6_address_by_name_get(&dns_0, &temp_uchar, NX_NULL, 1, &temp_uint, 1), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_ipv6_address_by_name_get(&dns_0, &temp_uchar, (void*)&temp_ulong, 1, NX_NULL, 1), NX_PTR_ERROR); + + + validate_expected_status(_nxde_dns_host_by_address_get(NX_NULL, &address_0, &temp_uchar, 1, 1), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_host_by_address_get(&dns_0, NX_NULL, &temp_uchar, 1, 1), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_host_by_address_get(&dns_0, &address_0, NX_NULL, 1, 1), NX_PTR_ERROR); + + validate_expected_status(_nxde_dns_server_add(NX_NULL, &address_0), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_server_add(&dns_0, NX_NULL), NX_PTR_ERROR); + + validate_expected_status(_nxde_dns_server_remove(NX_NULL, &address_0), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_server_remove(&dns_0, NX_NULL), NX_PTR_ERROR); + + validate_expected_status(_nxde_dns_server_get(NX_NULL, 0, &address_0), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_server_get(&dns_0, 0, NX_NULL), NX_PTR_ERROR); + + //_nxde_dns_host_by_name_get(NX_DNS *dns_ptr, UCHAR *host_name, NXD_ADDRESS *host_address_ptr, ULONG wait_option, UINT lookup_type) + validate_expected_status(_nxde_dns_host_by_name_get(NX_NULL, &temp_uchar, &address_0, 0, 0), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_host_by_name_get(&dns_0, NX_NULL, &address_0, 0, 0), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_host_by_name_get(&dns_0, &temp_uchar, NX_NULL, 0, 0), NX_PTR_ERROR); + nxde_address_error_checks(); +#endif + + ip_0.nx_ip_id = 0; + validate_expected_status(_nxe_dns_create(NX_NULL, &ip_0, NX_NULL), NX_PTR_ERROR); + + ip_0.nx_ip_id = NX_IP_ID; + validate_expected_status(_nxe_dns_create(NX_NULL, &ip_0, NX_NULL), NX_PTR_ERROR); + + dns_0.nx_dns_id = NX_DNS_ID; + + validate_expected_status(_nxe_dns_host_by_address_get(&dns_0, 0, &temp_uchar, 1, 1), NX_DNS_PARAM_ERROR); + validate_expected_status(_nxe_dns_host_by_address_get(&dns_0, 1, &temp_uchar, 0, 1), NX_DNS_PARAM_ERROR); + +#ifdef __PRODUCT_NETXDUO__ + validate_expected_status(_nxde_dns_host_by_address_get(&dns_0, &address_0, &temp_uchar, 0, 1), NX_DNS_PARAM_ERROR); +#endif + + validate_expected_status(_nxe_dns_create(&dns_0, &ip_0, NX_NULL), NX_PTR_ERROR); + + // Alignment check tests + validate_expected_status(_nxe_dns_ipv4_address_by_name_get(&dns_0, &temp_uchar, (void*)&temp_ushort2 - 1, 1, &temp_uint, 1), NX_PTR_ERROR); +#ifdef __PRODUCT_NETXDUO__ + validate_expected_status(_nxde_dns_ipv6_address_by_name_get(&dns_0, &temp_uchar, (void*)&temp_ushort2 - 1, 1, &temp_uint, 1), NX_PTR_ERROR); +#endif + + nxe_dns_server_add_remove_error_check_test(&dns_0, 0, NX_DNS_BAD_ADDRESS_ERROR); + validate_expected_status(_nxe_dns_get_serverlist_size(&dns_0, NX_NULL), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_server_get(&dns_0, 0, NX_NULL), NX_PTR_ERROR); + + // apis that require requires nx_dns_id == NX_DNS_ID for the thread state tests + _tx_thread_system_state = 1; + nx_dns_id_calls(); + + _tx_thread_system_state = 0; + _tx_thread_current_ptr = TX_NULL; + nx_dns_id_calls(); + + _tx_thread_current_ptr = &_tx_timer_thread; + nx_dns_id_calls(); + +#ifdef __PRODUCT_NETXDUO__ + validate_expected_status(_nxde_dns_host_by_name_get(&dns_0, &temp_uchar, &address_0, 0, 0), NX_DNS_PARAM_ERROR); +#endif + + dns_0.nx_dns_id = 0; + validate_expected_status(_nxe_dns_delete(&dns_0), NX_PTR_ERROR); + nxe_dns_server_add_remove_error_check_test(&dns_0, 1, NX_PTR_ERROR); + validate_expected_status(_nxe_dns_get_serverlist_size(&dns_0, 0), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_server_get(&dns_0, 0, NX_NULL), NX_PTR_ERROR); + validate_expected_status(_nxe_dns_host_by_name_get(&dns_0, &temp_uchar, &temp_ulong, 1), NX_DNS_PARAM_ERROR); + validate_expected_status(_nxe_dns_ipv4_address_by_name_get(&dns_0, &temp_uchar, (void*)&temp_ulong, 1, &temp_uint, 1), NX_DNS_PARAM_ERROR); + validate_expected_status(_nxe_dns_host_by_address_get(&dns_0, 1, &temp_uchar, 1, 1), NX_DNS_PARAM_ERROR); +#ifdef __PRODUCT_NETXDUO__ + validate_expected_status(_nxde_dns_ipv6_address_by_name_get(&dns_0, &temp_uchar, (void*)&temp_ulong, 1, &temp_uint, 1), NX_DNS_PARAM_ERROR); + validate_expected_status(_nxde_dns_host_by_address_get(&dns_0, &address_0, &temp_uchar, 1, 1), NX_DNS_PARAM_ERROR); + validate_expected_status(_nxde_dns_server_add(&dns_0, &address_0), NX_DNS_PARAM_ERROR); + validate_expected_status(_nxde_dns_server_remove(&dns_0, &address_0), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_server_get(&dns_0, 0, &address_0), NX_PTR_ERROR); + validate_expected_status(_nxde_dns_host_by_name_get(&dns_0, &temp_uchar, &address_0, 0, 1), NX_DNS_PARAM_ERROR); +#endif + + // apis that require requires nx_dns_id == 0 for the thread state tests + _tx_thread_system_state = 1; + validate_expected_status(_nxe_dns_create(&dns_0, &ip_0, NX_NULL), NX_CALLER_ERROR); + + _tx_thread_system_state = 0; + _tx_thread_current_ptr = TX_NULL; + validate_expected_status(_nxe_dns_create(&dns_0, &ip_0, NX_NULL), NX_CALLER_ERROR); + + _tx_thread_current_ptr = &_tx_timer_thread; + validate_expected_status(_nxe_dns_create(&dns_0, &ip_0, NX_NULL), NX_CALLER_ERROR); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_api_error_test_application_define(void *first_unused_memory) +#endif +{ + /* Print out test information banner. */ + printf("NetX Test: DNS Client Error Checking Test.......................N/A\n"); + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/dns_test/netx_dns_packet_double_release_test.c b/test/regression/dns_test/netx_dns_packet_double_release_test.c new file mode 100644 index 00000000..3edcf0e6 --- /dev/null +++ b/test/regression/dns_test/netx_dns_packet_double_release_test.c @@ -0,0 +1,351 @@ +/* This NetX test concentrates on the basic DNS operation. Packet double release. */ + +#include "tx_api.h" +#include "tx_timer.h" +#include "nx_api.h" +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dns.h" +#else +#include "nx_dns.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_IPV4) && !defined (NX_DISABLE_PACKET_INFO) + +#define DEMO_STACK_SIZE 2048 +#define NX_PACKET_SIZE 1536 +#define NX_PACKET_POOL_SIZE ((NX_PACKET_SIZE + sizeof(NX_PACKET)) * 32) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP client_ip; +static NX_IP server_ip; + +static NX_UDP_SOCKET server_socket; +static NX_DNS client_dns; + + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL +NX_PACKET_POOL client_pool; +#endif + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG pool_stack[NX_PACKET_POOL_SIZE / sizeof(ULONG)]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void _nx_dns_udp_receive_notify(NX_UDP_SOCKET *socket_ptr); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +#define DNS_START_OFFSET (14 + 20 + 8) + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_packet_double_release_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the DNS main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_PACKET_SIZE, pool_stack, NX_PACKET_POOL_SIZE); + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Create the packet pool for the DNS Client to send packets. + + If the DNS Client is configured for letting the host application create + the DNS packet pool, (see NX_DNS_CLIENT_USER_CREATE_PACKET_POOL option), see + nx_dns_create() for guidelines on packet payload size and pool size. + packet traffic for NetX Duo processes. + */ + status = nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", NX_DNS_PACKET_PAYLOAD, pointer, NX_DNS_PACKET_POOL_SIZE); + + pointer = pointer + NX_DNS_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + return; +#endif + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "NetX IP Instance 0", IP_ADDRESS(192, 168, 100, 98), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "NetX IP Instance 1", IP_ADDRESS(192, 168, 100, 2), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UCHAR record_buffer[64]; +UINT record_count; + + /* Print out some test information banners. */ + printf("NetX Test: DNS Packet Double Free Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a DNS instance for the Client. Note this function will create + the DNS Client packet pool for creating DNS message packets intended + for querying its DNS server. */ + status = nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client"); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Is the DNS client configured for the host application to create the pecket pool? */ +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Yes, use the packet pool created above which has appropriate payload size + for DNS messages. */ + status = nx_dns_packet_pool_set(&client_dns, &client_pool); + + /* Check for set DNS packet pool error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Add an IPv4 server address to the Client list. */ + status = nx_dns_server_add(&client_dns, IP_ADDRESS(192, 168, 100, 2)); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send query. */ + status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 64, &record_count, 1); + + /* Check status, ID mismatch. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check if there is invalid packet release. */ + if (pool_0.nx_packet_pool_invalid_releases) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check errors. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +extern char response_a_google_com_pkt[]; +extern int response_a_google_com_pkt_size; + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT port; +NX_PACKET *response_packet; + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&server_socket, 53, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + tx_thread_resume(&thread_0); + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS client UDP port. */ + status = nx_udp_packet_info_extract(my_packet, NX_NULL, NX_NULL, &port, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Send the DNS response packet. */ + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Write the DNS response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, response_a_google_com_pkt + DNS_START_OFFSET, response_a_google_com_pkt_size - DNS_START_OFFSET); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = response_a_google_com_pkt_size - DNS_START_OFFSET; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + _tx_timer_system_clock++; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(&server_socket, response_packet, IP_ADDRESS(192, 168, 100, 98), port); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + return; + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Let the DNS threads execute. */ + tx_thread_relinquish(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_packet_double_release_test_application_define(void *first_unused_memory) +#endif + +{ + + /* Print out test information banner. */ + printf("NetX Test: DNS Packet Double Free Test...............................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/dns_test/netx_dns_request_a_response_cname_a_smtp_live_com_test.c b/test/regression/dns_test/netx_dns_request_a_response_cname_a_smtp_live_com_test.c new file mode 100644 index 00000000..b35819d2 --- /dev/null +++ b/test/regression/dns_test/netx_dns_request_a_response_cname_a_smtp_live_com_test.c @@ -0,0 +1,433 @@ +/* This NetX test concentrates on the basic DNS operation. Request: smtp.live.com A, Response: CNAME + A*/ + +/* +Frame 4: 294 bytes on wire (2352 bits), 294 bytes captured (2352 bits) on interface 0 +Ethernet II, Src: IntelCor_0e:3d:f4 (00:1b:21:0e:3d:f4), Dst: Lantroni_98:00:26 (00:80:a3:98:00:26) +Internet Protocol Version 4, Src: 172.19.1.1, Dst: 172.19.100.172 +User Datagram Protocol, Src Port: 53 (53), Dst Port: 30005 (30005) +Domain Name System (response) + [Request In: 3] + [Time: 0.000331000 seconds] + Transaction ID: 0x486a + Flags: 0x8180 Standard query response, No error + Questions: 1 + Answer RRs: 2 + Authority RRs: 4 + Additional RRs: 4 + Queries + smtp.live.com: type A, class IN + Answers + smtp.live.com: type CNAME, class IN, cname smtp.glbdns2.microsoft.com + Name: smtp.live.com + Type: CNAME (Canonical NAME for an alias) (5) + Class: IN (0x0001) + Time to live: 3000 + Data length: 25 + CNAME: smtp.glbdns2.microsoft.com + smtp.glbdns2.microsoft.com: type A, class IN, addr 65.55.163.152 + Name: smtp.glbdns2.microsoft.com + Type: A (Host Address) (1) + Class: IN (0x0001) + Time to live: 16 + Data length: 4 + Address: 65.55.163.152 + Authoritative nameservers + microsoft.com: type NS, class IN, ns ns3.msft.net + microsoft.com: type NS, class IN, ns ns4.msft.net + microsoft.com: type NS, class IN, ns ns1.msft.net + microsoft.com: type NS, class IN, ns ns2.msft.net + Additional records + ns2.msft.net: type A, class IN, addr 208.84.2.53 + ns2.msft.net: type AAAA, class IN, addr 2620:0:32::53 + ns4.msft.net: type A, class IN, addr 208.76.45.53 + ns4.msft.net: type AAAA, class IN, addr 2620:0:37::53 + +*/ + +/* Frame (294 bytes) */ +char response_cname_a[294] = { +0x00, 0x80, 0xa3, 0x98, 0x00, 0x26, 0x00, 0x1b, /* .....&.. */ +0x21, 0x0e, 0x3d, 0xf4, 0x08, 0x00, 0x45, 0x00, /* !.=...E. */ +0x01, 0x18, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, /* ....@.@. */ +0x7c, 0x01, 0xac, 0x13, 0x01, 0x01, 0xac, 0x13, /* |....... */ +0x64, 0xac, 0x00, 0x35, 0x75, 0x35, 0x01, 0x04, /* d..5u5.. */ +0xdc, 0xb6, 0x48, 0x6a, 0x81, 0x80, 0x00, 0x01, /* ..Hj.... */ +0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x04, 0x73, /* .......s */ +0x6d, 0x74, 0x70, 0x04, 0x6c, 0x69, 0x76, 0x65, /* mtp.live */ +0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, /* .com.... */ +0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x0b, 0xb8, 0x00, 0x19, 0x04, 0x73, 0x6d, /* ......sm */ +0x74, 0x70, 0x07, 0x67, 0x6c, 0x62, 0x64, 0x6e, /* tp.glbdn */ +0x73, 0x32, 0x09, 0x6d, 0x69, 0x63, 0x72, 0x6f, /* s2.micro */ +0x73, 0x6f, 0x66, 0x74, 0xc0, 0x16, 0xc0, 0x2b, /* soft...+ */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, /* ........ */ +0x00, 0x04, 0x41, 0x37, 0xa3, 0x98, 0xc0, 0x38, /* ..A7...8 */ +0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x28, 0x8b, /* ......(. */ +0x00, 0x0e, 0x03, 0x6e, 0x73, 0x33, 0x04, 0x6d, /* ...ns3.m */ +0x73, 0x66, 0x74, 0x03, 0x6e, 0x65, 0x74, 0x00, /* sft.net. */ +0xc0, 0x38, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, /* .8...... */ +0x28, 0x8b, 0x00, 0x06, 0x03, 0x6e, 0x73, 0x34, /* (....ns4 */ +0xc0, 0x64, 0xc0, 0x38, 0x00, 0x02, 0x00, 0x01, /* .d.8.... */ +0x00, 0x00, 0x28, 0x8b, 0x00, 0x06, 0x03, 0x6e, /* ..(....n */ +0x73, 0x31, 0xc0, 0x64, 0xc0, 0x38, 0x00, 0x02, /* s1.d.8.. */ +0x00, 0x01, 0x00, 0x00, 0x28, 0x8b, 0x00, 0x06, /* ....(... */ +0x03, 0x6e, 0x73, 0x32, 0xc0, 0x64, 0xc0, 0x9e, /* .ns2.d.. */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x63, 0x63, /* ......cc */ +0x00, 0x04, 0xd0, 0x54, 0x02, 0x35, 0xc0, 0x9e, /* ...T.5.. */ +0x00, 0x1c, 0x00, 0x01, 0x00, 0x01, 0x63, 0x63, /* ......cc */ +0x00, 0x10, 0x26, 0x20, 0x00, 0x00, 0x00, 0x32, /* ..& ...2 */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x53, 0xc0, 0x7a, 0x00, 0x01, 0x00, 0x01, /* .S.z.... */ +0x00, 0x00, 0x1d, 0x92, 0x00, 0x04, 0xd0, 0x4c, /* .......L */ +0x2d, 0x35, 0xc0, 0x7a, 0x00, 0x1c, 0x00, 0x01, /* -5.z.... */ +0x00, 0x00, 0x1d, 0x92, 0x00, 0x10, 0x26, 0x20, /* ......& */ +0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, /* ...7.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x53 /* .....S */ +}; + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dns.h" +#else +#include "nx_dns.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_UDP_SOCKET server_socket; + +static NX_DNS client_dns; + +#define DNS_SERVER_ADDRESS IP_ADDRESS(172,19,1,1) + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL +NX_PACKET_POOL client_pool; +#endif + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +#define DNS_START_OFFSET (14 + 20 + 8) + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_request_a_response_cname_a_smtp_live_com_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the DNS main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 8192); + pointer = pointer + 8192; + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Create the packet pool for the DNS Client to send packets. + + If the DNS Client is configured for letting the host application create + the DNS packet pool, (see NX_DNS_CLIENT_USER_CREATE_PACKET_POOL option), see + nx_dns_create() for guidelines on packet payload size and pool size. + packet traffic for NetX Duo processes. + */ + status = nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", NX_DNS_PACKET_PAYLOAD, pointer, NX_DNS_PACKET_POOL_SIZE); + + pointer = pointer + NX_DNS_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + return; +#endif + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "NetX IP Instance 0", IP_ADDRESS(172, 19, 100, 172), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "NetX IP Instance 1", IP_ADDRESS(172, 19, 1, 1), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +NXD_ADDRESS ip_address; + + /* Test the A type with the new API,(google.com.) */ + /* Print out some test information banners. */ + printf("NetX Test: DNS Request A Response CNAME+A smtp.live.com Test........."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a DNS instance for the Client. Note this function will create + the DNS Client packet pool for creating DNS message packets intended + for querying its DNS server. */ + status = nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client"); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Is the DNS client configured for the host application to create the pecket pool? */ +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Yes, use the packet pool created above which has appropriate payload size + for DNS messages. */ + status = nx_dns_packet_pool_set(&client_dns, &client_pool); + + /* Check for set DNS packet pool error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Add an IPv4 server address to the Client list. */ + status = nx_dns_server_add(&client_dns, DNS_SERVER_ADDRESS); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Secd dns query, and record the single host ip address. */ + status = nxd_dns_host_by_name_get(&client_dns, (UCHAR *)"smtp.live.com", &ip_address, 4 * NX_IP_PERIODIC_RATE, NX_IP_VERSION_V4); + + /* Check status and compare the host ip address. */ + if (status || (ip_address.nxd_ip_address.v4 != IP_ADDRESS(65, 55, 163, 152))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT port; +USHORT nx_dns_transmit_id; +UCHAR *data_ptr; +NX_PACKET *response_packet; + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&server_socket, 53, TX_WAIT_FOREVER); + + /* Act as the DNS server to receive the DNS query and send the DNS response. */ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS client UDP port. */ + status = nx_udp_packet_info_extract(my_packet, NX_NULL, NX_NULL, &port, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS transmit ID. */ + data_ptr = my_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + nx_dns_transmit_id = *data_ptr++; + nx_dns_transmit_id = (USHORT)((nx_dns_transmit_id << 8) | *data_ptr); + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send the DNS response packet. */ + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Write the DNS response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, response_cname_a + DNS_START_OFFSET, sizeof(response_cname_a) - DNS_START_OFFSET); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = sizeof(response_cname_a) - DNS_START_OFFSET; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Update the DNS transmit ID. */ + data_ptr = response_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + *data_ptr++ = (UCHAR)(nx_dns_transmit_id >> 8); + *data_ptr = (UCHAR)nx_dns_transmit_id; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(&server_socket, response_packet, IP_ADDRESS(172, 19, 100, 172), port); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + return; + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Let the DNS threads execute. */ + tx_thread_relinquish(); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_request_a_response_cname_a_smtp_live_com_test_application_define(void *first_unused_memory) +#endif + +{ + + /* Print out test information banner. */ + printf("NetX Test: DNS Request A Response CNAME+A smtp.live.com Test.........N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/dns_test/netx_dns_source_port_test.c b/test/regression/dns_test/netx_dns_source_port_test.c new file mode 100644 index 00000000..888f5182 --- /dev/null +++ b/test/regression/dns_test/netx_dns_source_port_test.c @@ -0,0 +1,375 @@ +/* This NetX test concentrates on the basic DNS operation. Non-blocking test. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dns.h" +#else +#include "nx_dns.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#ifndef NX_DISABLE_IPV4 + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP client_ip; +static NX_IP server_ip; + +static NX_UDP_SOCKET server_socket; +static NX_DNS client_dns; + + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL +NX_PACKET_POOL client_pool; +#endif + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static UINT dns_query_port_1 = 0; +static UINT dns_query_port_2 = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +#define DNS_START_OFFSET (14 + 20 + 8) + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_source_port_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the DNS main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 8192); + pointer = pointer + 8192; + +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Create the packet pool for the DNS Client to send packets. + + If the DNS Client is configured for letting the host application create + the DNS packet pool, (see NX_DNS_CLIENT_USER_CREATE_PACKET_POOL option), see + nx_dns_create() for guidelines on packet payload size and pool size. + packet traffic for NetX Duo processes. + */ + status = nx_packet_pool_create(&client_pool, "DNS Client Packet Pool", NX_DNS_PACKET_PAYLOAD, pointer, NX_DNS_PACKET_POOL_SIZE); + + pointer = pointer + NX_DNS_PACKET_POOL_SIZE; + + /* Check for pool creation error. */ + if (status) + return; +#endif + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "NetX IP Instance 0", IP_ADDRESS(192, 168, 100, 98), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "NetX IP Instance 1", IP_ADDRESS(192, 168, 100, 2), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&client_ip); + status += nx_udp_enable(&server_ip); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UCHAR record_buffer[64]; +UINT record_count; + + /* Print out some test information banners. */ + printf("NetX Test: DNS Source Port Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a DNS instance for the Client. Note this function will create + the DNS Client packet pool for creating DNS message packets intended + for querying its DNS server. */ + status = nx_dns_create(&client_dns, &client_ip, (UCHAR *)"DNS Client"); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Is the DNS client configured for the host application to create the pecket pool? */ +#ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL + + /* Yes, use the packet pool created above which has appropriate payload size + for DNS messages. */ + status = nx_dns_packet_pool_set(&client_dns, &client_pool); + + /* Check for set DNS packet pool error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#endif /* NX_DNS_CLIENT_USER_CREATE_PACKET_POOL */ + + /* Add an IPv4 server address to the Client list. */ + status = nx_dns_server_add(&client_dns, IP_ADDRESS(192, 168, 100, 2)); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send query. */ + status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 64, &record_count, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send query again. */ + status = nx_dns_ipv4_address_by_name_get(&client_dns, (UCHAR *)"google.com", &record_buffer[0], 64, &record_count, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the port. */ + if (dns_query_port_1 == dns_query_port_2) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +extern char response_a_google_com_pkt[]; +extern int response_a_google_com_pkt_size; + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT port; +USHORT nx_dns_transmit_id; +UCHAR *data_ptr; +NX_PACKET *response_packet; + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&server_ip, &server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&server_socket, 53, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + for (UINT i = 0; i < 2; i++) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Get the DNS client UDP port. */ + status = nx_udp_packet_info_extract(my_packet, NX_NULL, NX_NULL, &port, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + if (i == 0) + { + dns_query_port_1 = port; + } + else + { + dns_query_port_2 = port; + } + + /* Get the DNS transmit ID. */ + data_ptr = my_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + nx_dns_transmit_id = *data_ptr++; + nx_dns_transmit_id = (USHORT)((nx_dns_transmit_id << 8) | *data_ptr); + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send the DNS response packet. */ + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Write the DNS response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, response_a_google_com_pkt + DNS_START_OFFSET, response_a_google_com_pkt_size - DNS_START_OFFSET); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = response_a_google_com_pkt_size - DNS_START_OFFSET; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Update the DNS transmit ID. */ + data_ptr = response_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET; + *data_ptr++ = (UCHAR)(nx_dns_transmit_id >> 8); + *data_ptr = (UCHAR)nx_dns_transmit_id; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(&server_socket, response_packet, IP_ADDRESS(192, 168, 100, 98), port); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + return; + } + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Let the DNS threads execute. */ + tx_thread_relinquish(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dns_source_port_test_application_define(void *first_unused_memory) +#endif + +{ + + /* Print out test information banner. */ + printf("NetX Test: DNS Source Port Test......................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/dns_test/response_a_berkley_edu.c b/test/regression/dns_test/response_a_berkley_edu.c new file mode 100644 index 00000000..5aad00bb --- /dev/null +++ b/test/regression/dns_test/response_a_berkley_edu.c @@ -0,0 +1,44 @@ +/* +No. Time Source Destination Protocol Length Info + 130 168.629156 192.2.2.1 192.2.2.240 DNS 88 Standard query response 0x0002 A 169.229.216.200 + +Frame 130: 88 bytes on wire (704 bits), 88 bytes captured (704 bits) +Ethernet II, Src: TyanComp_45:7a:c6 (00:e0:81:45:7a:c6), Dst: Dell_8e:ec:b5 (d4:be:d9:8e:ec:b5) +Internet Protocol Version 4, Src: 192.2.2.1 (192.2.2.1), Dst: 192.2.2.240 (192.2.2.240) +User Datagram Protocol, Src Port: domain (53), Dst Port: 55271 (55271) +Domain Name System (response) + [Request In: 129] + [Time: 0.000138000 seconds] + Transaction ID: 0x0002 + Flags: 0x8180 Standard query response, No error + Questions: 1 + Answer RRs: 1 + Authority RRs: 0 + Additional RRs: 0 + Queries + Answers + berkeley.edu: type A, class IN, addr 169.229.216.200 + Name: berkeley.edu + Type: A (Host address) + Class: IN (0x0001) + Time to live: 4 minutes, 59 seconds + Data length: 4 + Addr: 169.229.216.200 (169.229.216.200) +*/ + +/* Frame (88 bytes) */ +char response_a_berkley_edu_pkt[88] = { +0xd4, 0xbe, 0xd9, 0x8e, 0xec, 0xb5, 0x00, 0xe0, /* ........ */ +0x81, 0x45, 0x7a, 0xc6, 0x08, 0x00, 0x45, 0x00, /* .Ez...E. */ +0x00, 0x4a, 0x4d, 0xc2, 0x00, 0x00, 0x80, 0x11, /* .JM..... */ +0x67, 0xeb, 0xc0, 0x02, 0x02, 0x01, 0xc0, 0x02, /* g....... */ +0x02, 0xf0, 0x00, 0x35, 0xd7, 0xe7, 0x00, 0x36, /* ...5...6 */ +0x43, 0xf5, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, /* C....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x62, /* .......b */ +0x65, 0x72, 0x6b, 0x65, 0x6c, 0x65, 0x79, 0x03, /* erkeley. */ +0x65, 0x64, 0x75, 0x00, 0x00, 0x01, 0x00, 0x01, /* edu..... */ +0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x01, 0x2b, 0x00, 0x04, 0xa9, 0xe5, 0xd8, 0xc8 /* .+...... */ +}; + +int response_a_berkley_edu_pkt_size = 88; diff --git a/test/regression/dns_test/response_a_cname_www_npr_org.c b/test/regression/dns_test/response_a_cname_www_npr_org.c new file mode 100644 index 00000000..25e09ea7 --- /dev/null +++ b/test/regression/dns_test/response_a_cname_www_npr_org.c @@ -0,0 +1,57 @@ +/* +No. Time Source Destination Protocol Length Info +8 1.404839 192.2.2.1 192.2.2.66 DNS 119 Yes Standard query response 0x261c CNAME www.npr.cotcdb.net A 216.35.221.76 + +Frame 8: 119 bytes on wire (952 bits), 119 bytes captured (952 bits) +Ethernet II, Src: TyanComp_45:7a:c6 (00:e0:81:45:7a:c6), Dst: 00:cf:54:85:c3:01 (00:cf:54:85:c3:01) +Internet Protocol Version 4, Src: 192.2.2.1 (192.2.2.1), Dst: 192.2.2.66 (192.2.2.66) +User Datagram Protocol, Src Port: domain (53), Dst Port: 30000 (30000) +Domain Name System (response) + Request In: 5 + Time: 0.010296000 seconds + Transaction ID: 0x261c + Flags: 0x8180 (Standard query response, No error) + Questions: 1 + Answer RRs: 2 + Authority RRs: 0 + Additional RRs: 0 + Queries + www.npr.org: type A, class IN + Name: www.npr.org + Type: A (Host address) + Class: IN (0x0001) + Answers + www.npr.org: type CNAME, class IN, cname www.npr.cotcdb.net + Name: www.npr.org + Type: CNAME (Canonical name for an alias) + Class: IN (0x0001) + Time to live: 49 seconds + Data length: 20 + Primaryname: www.npr.cotcdb.net + www.npr.cotcdb.net: type A, class IN, addr 216.35.221.76 + Name: www.npr.cotcdb.net + Type: A (Host address) + Class: IN (0x0001) + Time to live: 1 minute, 22 seconds + Data length: 4 + Addr: 216.35.221.76 (216.35.221.76) +*/ + +char response_a_cname_www_npr_org_pkt[119] = { +0x00, 0xcf, 0x54, 0x85, 0xc3, 0x01, 0x00, 0xe0, +0x81, 0x45, 0x7a, 0xc6, 0x08, 0x00, 0x45, 0x00, +0x00, 0x69, 0x7c, 0xa7, 0x00, 0x00, 0x80, 0x11, +0x39, 0x95, 0xc0, 0x02, 0x02, 0x01, 0xc0, 0x02, +0x02, 0x42, 0x00, 0x35, 0x75, 0x30, 0x00, 0x55, +0x39, 0x0f, 0x26, 0x1c, 0x81, 0x80, 0x00, 0x01, +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, +0x77, 0x77, 0x03, 0x6e, 0x70, 0x72, 0x03, 0x6f, +0x72, 0x67, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, +0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, +0x31, 0x00, 0x14, 0x03, 0x77, 0x77, 0x77, 0x03, +0x6e, 0x70, 0x72, 0x06, 0x63, 0x6f, 0x74, 0x63, +0x64, 0x62, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, +0x29, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, +0x52, 0x00, 0x04, 0xd8, 0x23, 0xdd, 0x4c }; + +int response_a_cname_www_npr_org_pkt_size = sizeof(response_a_cname_www_npr_org_pkt); \ No newline at end of file diff --git a/test/regression/dns_test/response_a_google_com.c b/test/regression/dns_test/response_a_google_com.c new file mode 100644 index 00000000..bfd547be --- /dev/null +++ b/test/regression/dns_test/response_a_google_com.c @@ -0,0 +1,134 @@ +/* +No. Time Source Destination Protocol Length Info + 54 82.002033 192.2.2.1 192.2.2.240 DNS 246 Standard query response 0x0002 A 74.125.224.194 A 74.125.224.195 A 74.125.224.196 A 74.125.224.197 A 74.125.224.198 A 74.125.224.199 A 74.125.224.200 A 74.125.224.201 A 74.125.224.206 A 74.125.224.192 A 74.125.224.193 + +Frame 54: 246 bytes on wire (1968 bits), 246 bytes captured (1968 bits) +Ethernet II, Src: TyanComp_45:7a:c6 (00:e0:81:45:7a:c6), Dst: Dell_8e:ec:b5 (d4:be:d9:8e:ec:b5) +Internet Protocol Version 4, Src: 192.2.2.1 (192.2.2.1), Dst: 192.2.2.240 (192.2.2.240) +User Datagram Protocol, Src Port: domain (53), Dst Port: 52427 (52427) +Domain Name System (response) + [Request In: 53] + [Time: 0.015609000 seconds] + Transaction ID: 0x0002 + Flags: 0x8180 Standard query response, No error + Questions: 1 + Answer RRs: 11 + Authority RRs: 0 + Additional RRs: 0 + Queries + Answers + google.com: type A, class IN, addr 74.125.224.194 + Name: google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 2 minutes, 22 seconds + Data length: 4 + Addr: 74.125.224.194 (74.125.224.194) + google.com: type A, class IN, addr 74.125.224.195 + Name: google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 2 minutes, 22 seconds + Data length: 4 + Addr: 74.125.224.195 (74.125.224.195) + google.com: type A, class IN, addr 74.125.224.196 + Name: google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 2 minutes, 22 seconds + Data length: 4 + Addr: 74.125.224.196 (74.125.224.196) + google.com: type A, class IN, addr 74.125.224.197 + Name: google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 2 minutes, 22 seconds + Data length: 4 + Addr: 74.125.224.197 (74.125.224.197) + google.com: type A, class IN, addr 74.125.224.198 + Name: google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 2 minutes, 22 seconds + Data length: 4 + Addr: 74.125.224.198 (74.125.224.198) + google.com: type A, class IN, addr 74.125.224.199 + Name: google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 2 minutes, 22 seconds + Data length: 4 + Addr: 74.125.224.199 (74.125.224.199) + google.com: type A, class IN, addr 74.125.224.200 + Name: google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 2 minutes, 22 seconds + Data length: 4 + Addr: 74.125.224.200 (74.125.224.200) + google.com: type A, class IN, addr 74.125.224.201 + Name: google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 2 minutes, 22 seconds + Data length: 4 + Addr: 74.125.224.201 (74.125.224.201) + google.com: type A, class IN, addr 74.125.224.206 + Name: google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 2 minutes, 22 seconds + Data length: 4 + Addr: 74.125.224.206 (74.125.224.206) + google.com: type A, class IN, addr 74.125.224.192 + Name: google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 2 minutes, 22 seconds + Data length: 4 + Addr: 74.125.224.192 (74.125.224.192) + google.com: type A, class IN, addr 74.125.224.193 + Name: google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 2 minutes, 22 seconds + Data length: 4 + Addr: 74.125.224.193 (74.125.224.193) +*/ + +/* Frame (246 bytes) */ +char response_a_google_com_pkt[246] = { +0xd4, 0xbe, 0xd9, 0x8e, 0xec, 0xb5, 0x00, 0xe0, /* ........ */ +0x81, 0x45, 0x7a, 0xc6, 0x08, 0x00, 0x45, 0x00, /* .Ez...E. */ +0x00, 0xe8, 0x4b, 0x83, 0x00, 0x00, 0x80, 0x11, /* ..K..... */ +0x69, 0x8c, 0xc0, 0x02, 0x02, 0x01, 0xc0, 0x02, /* i....... */ +0x02, 0xf0, 0x00, 0x35, 0xcc, 0xcb, 0x00, 0xd4, /* ...5.... */ +0xf5, 0x39, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, /* .9...... */ +0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, /* .......g */ +0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, /* oogle.co */ +0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, /* m....... */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, /* ........ */ +0x00, 0x04, 0x4a, 0x7d, 0xe0, 0xc2, 0xc0, 0x0c, /* ..J}.... */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, /* ........ */ +0x00, 0x04, 0x4a, 0x7d, 0xe0, 0xc3, 0xc0, 0x0c, /* ..J}.... */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, /* ........ */ +0x00, 0x04, 0x4a, 0x7d, 0xe0, 0xc4, 0xc0, 0x0c, /* ..J}.... */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, /* ........ */ +0x00, 0x04, 0x4a, 0x7d, 0xe0, 0xc5, 0xc0, 0x0c, /* ..J}.... */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, /* ........ */ +0x00, 0x04, 0x4a, 0x7d, 0xe0, 0xc6, 0xc0, 0x0c, /* ..J}.... */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, /* ........ */ +0x00, 0x04, 0x4a, 0x7d, 0xe0, 0xc7, 0xc0, 0x0c, /* ..J}.... */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, /* ........ */ +0x00, 0x04, 0x4a, 0x7d, 0xe0, 0xc8, 0xc0, 0x0c, /* ..J}.... */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, /* ........ */ +0x00, 0x04, 0x4a, 0x7d, 0xe0, 0xc9, 0xc0, 0x0c, /* ..J}.... */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, /* ........ */ +0x00, 0x04, 0x4a, 0x7d, 0xe0, 0xce, 0xc0, 0x0c, /* ..J}.... */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, /* ........ */ +0x00, 0x04, 0x4a, 0x7d, 0xe0, 0xc0, 0xc0, 0x0c, /* ..J}.... */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, /* ........ */ +0x00, 0x04, 0x4a, 0x7d, 0xe0, 0xc1 /* ..J}.. */ +}; + +int response_a_google_com_pkt_size = 246; diff --git a/test/regression/dns_test/response_aaaa_berkley_edu.c b/test/regression/dns_test/response_aaaa_berkley_edu.c new file mode 100644 index 00000000..374a5dbc --- /dev/null +++ b/test/regression/dns_test/response_aaaa_berkley_edu.c @@ -0,0 +1,46 @@ +/* +No. Time Source Destination Protocol Length Info + 132 168.635407 192.2.2.1 192.2.2.240 DNS 100 Standard query response 0x0003 AAAA 2607:f140:0:81::f + +Frame 132: 100 bytes on wire (800 bits), 100 bytes captured (800 bits) +Ethernet II, Src: TyanComp_45:7a:c6 (00:e0:81:45:7a:c6), Dst: Dell_8e:ec:b5 (d4:be:d9:8e:ec:b5) +Internet Protocol Version 4, Src: 192.2.2.1 (192.2.2.1), Dst: 192.2.2.240 (192.2.2.240) +User Datagram Protocol, Src Port: domain (53), Dst Port: 55272 (55272) +Domain Name System (response) + [Request In: 131] + [Time: 0.000208000 seconds] + Transaction ID: 0x0003 + Flags: 0x8180 Standard query response, No error + Questions: 1 + Answer RRs: 1 + Authority RRs: 0 + Additional RRs: 0 + Queries + Answers + berkeley.edu: type AAAA, class IN, addr 2607:f140:0:81::f + Name: berkeley.edu + Type: AAAA (IPv6 address) + Class: IN (0x0001) + Time to live: 59 minutes, 53 seconds + Data length: 16 + Addr: 2607:f140:0:81::f +*/ + +/* Frame (100 bytes) */ +char response_aaaa_berkley_edu_pkt[100] = { +0xd4, 0xbe, 0xd9, 0x8e, 0xec, 0xb5, 0x00, 0xe0, /* ........ */ +0x81, 0x45, 0x7a, 0xc6, 0x08, 0x00, 0x45, 0x00, /* .Ez...E. */ +0x00, 0x56, 0x4d, 0xc3, 0x00, 0x00, 0x80, 0x11, /* .VM..... */ +0x67, 0xde, 0xc0, 0x02, 0x02, 0x01, 0xc0, 0x02, /* g....... */ +0x02, 0xf0, 0x00, 0x35, 0xd7, 0xe8, 0x00, 0x42, /* ...5...B */ +0xa1, 0x91, 0x00, 0x03, 0x81, 0x80, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x62, /* .......b */ +0x65, 0x72, 0x6b, 0x65, 0x6c, 0x65, 0x79, 0x03, /* erkeley. */ +0x65, 0x64, 0x75, 0x00, 0x00, 0x1c, 0x00, 0x01, /* edu..... */ +0xc0, 0x0c, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x0e, 0x09, 0x00, 0x10, 0x26, 0x07, 0xf1, 0x40, /* ....&..@ */ +0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x0f /* .... */ +}; + +int response_aaaa_berkley_edu_pkt_size = 100; diff --git a/test/regression/dns_test/response_cname_mail_baidu_com.c b/test/regression/dns_test/response_cname_mail_baidu_com.c new file mode 100644 index 00000000..6b24affc --- /dev/null +++ b/test/regression/dns_test/response_cname_mail_baidu_com.c @@ -0,0 +1,48 @@ +/* +No. Time Source Destination Protocol Length Info +165 19.285254000 192.168.0.1 192.168.0.105 DNS 100 Standard query response 0x0002 CNAME www.a.shifen.com + +Frame 165: 100 bytes on wire (800 bits), 100 bytes captured (800 bits) +Ethernet II, Src: TendaTec_60:4b:46 (c8:3a:35:60:4b:46), Dst: Dell_33:c1:bd (18:03:73:33:c1:bd) +Internet Protocol Version 4, Src: 192.168.0.1 (192.168.0.1), Dst: 192.168.0.105 (192.168.0.105) +User Datagram Protocol, Src Port: domain (53), Dst Port: 50976 (50976) +Domain Name System (response) + Request In: 164 + Time: 0.036077000 seconds + Transaction ID: 0x0002 + Flags: 0x8180 (Standard query response, No error) + Questions: 1 + Answer RRs: 1 + Authority RRs: 0 + Additional RRs: 0 + Queries + www.baidu.com: type CNAME, class IN + Name: www.baidu.com + Type: CNAME (Canonical name for an alias) + Class: IN (0x0001) + Answers + www.baidu.com: type CNAME, class IN, cname www.a.shifen.com + Name: www.baidu.com + Type: CNAME (Canonical name for an alias) + Class: IN (0x0001) + Time to live: 8 minutes, 7 seconds + Data length: 15 + Primaryname: www.a.shifen.com +*/ + +char response_cname_www_baidu_com_pkt[100] = { +0x18, 0x03, 0x73, 0x33, 0xc1, 0xbd, 0xc8, 0x3a, +0x35, 0x60, 0x4b, 0x46, 0x08, 0x00, 0x45, 0x00, +0x00, 0x56, 0xa6, 0x10, 0x00, 0x00, 0x40, 0x11, +0x52, 0xcc, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8, +0x00, 0x69, 0x00, 0x35, 0xc7, 0x20, 0x00, 0x42, +0x1b, 0x3d, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, +0x77, 0x77, 0x05, 0x62, 0x61, 0x69, 0x64, 0x75, +0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x05, 0x00, +0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, +0x00, 0x01, 0xe7, 0x00, 0x0f, 0x03, 0x77, 0x77, +0x77, 0x01, 0x61, 0x06, 0x73, 0x68, 0x69, 0x66, +0x65, 0x6e, 0xc0, 0x16 }; + +int response_cname_www_baidu_com_pkt_size = sizeof(response_cname_www_baidu_com_pkt); \ No newline at end of file diff --git a/test/regression/dns_test/response_mx_a_berkley_edu.c b/test/regression/dns_test/response_mx_a_berkley_edu.c new file mode 100644 index 00000000..a514649a --- /dev/null +++ b/test/regression/dns_test/response_mx_a_berkley_edu.c @@ -0,0 +1,57 @@ +/* +No. Time Source Destination Protocol Length Info + 108 142.849657 192.2.2.1 192.2.2.240 DNS 107 Standard query response 0x0002 MX 10 mx.berkeley.edu + +Frame 108: 107 bytes on wire (856 bits), 107 bytes captured (856 bits) +Ethernet II, Src: TyanComp_45:7a:c6 (00:e0:81:45:7a:c6), Dst: Dell_8e:ec:b5 (d4:be:d9:8e:ec:b5) +Internet Protocol Version 4, Src: 192.2.2.1 (192.2.2.1), Dst: 192.2.2.240 (192.2.2.240) +User Datagram Protocol, Src Port: domain (53), Dst Port: 50825 (50825) +Domain Name System (response) + [Request In: 107] + [Time: 0.000166000 seconds] + Transaction ID: 0x0002 + Flags: 0x8180 Standard query response, No error + Questions: 1 + Answer RRs: 1 + Authority RRs: 0 + Additional RRs: 1 + Queries + Answers + berkeley.edu: type MX, class IN, preference 10, mx mx.berkeley.edu + Name: berkeley.edu + Type: MX (Mail exchange) + Class: IN (0x0001) + Time to live: 59 minutes, 53 seconds + Data length: 7 + Preference: 10 + Mail exchange: mx.berkeley.edu + Additional records + mx.berkeley.edu: type A, class IN, addr 169.229.218.141 + Name: mx.berkeley.edu + Type: A (Host address) + Class: IN (0x0001) + Time to live: 59 minutes, 57 seconds + Data length: 4 + Addr: 169.229.218.141 (169.229.218.141) + +*/ + +/* Frame (107 bytes) */ +char response_mx_a_berkley_edu_pkt[107] = { +0xd4, 0xbe, 0xd9, 0x8e, 0xec, 0xb5, 0x00, 0xe0, /* ........ */ +0x81, 0x45, 0x7a, 0xc6, 0x08, 0x00, 0x45, 0x00, /* .Ez...E. */ +0x00, 0x5d, 0x4d, 0x47, 0x00, 0x00, 0x80, 0x11, /* .]MG.... */ +0x68, 0x53, 0xc0, 0x02, 0x02, 0x01, 0xc0, 0x02, /* hS...... */ +0x02, 0xf0, 0x00, 0x35, 0xc6, 0x89, 0x00, 0x49, /* ...5...I */ +0x90, 0x53, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, /* .S...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x62, /* .......b */ +0x65, 0x72, 0x6b, 0x65, 0x6c, 0x65, 0x79, 0x03, /* erkeley. */ +0x65, 0x64, 0x75, 0x00, 0x00, 0x0f, 0x00, 0x01, /* edu..... */ +0xc0, 0x0c, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x0e, 0x09, 0x00, 0x07, 0x00, 0x0a, 0x02, 0x6d, /* .......m */ +0x78, 0xc0, 0x0c, 0xc0, 0x2c, 0x00, 0x01, 0x00, /* x...,... */ +0x01, 0x00, 0x00, 0x0e, 0x0d, 0x00, 0x04, 0xa9, /* ........ */ +0xe5, 0xda, 0x8d /* ... */ +}; + +int response_mx_a_berkley_edu_pkt_size = 107; \ No newline at end of file diff --git a/test/regression/dns_test/response_mx_a_google_com.c b/test/regression/dns_test/response_mx_a_google_com.c new file mode 100644 index 00000000..67191ca5 --- /dev/null +++ b/test/regression/dns_test/response_mx_a_google_com.c @@ -0,0 +1,135 @@ +/* +No. Time Source Destination Protocol Length Info + 50 57.439998 192.2.2.1 192.2.2.240 DNS 258 Standard query response 0x0003 MX 20 alt1.aspmx.l.google.com MX 30 alt2.aspmx.l.google.com MX 40 alt3.aspmx.l.google.com MX 50 alt4.aspmx.l.google.com MX 10 aspmx.l.google.com + +Frame 50: 258 bytes on wire (2064 bits), 258 bytes captured (2064 bits) +Ethernet II, Src: TyanComp_45:7a:c6 (00:e0:81:45:7a:c6), Dst: Dell_8e:ec:b5 (d4:be:d9:8e:ec:b5) +Internet Protocol Version 4, Src: 192.2.2.1 (192.2.2.1), Dst: 192.2.2.240 (192.2.2.240) +User Datagram Protocol, Src Port: domain (53), Dst Port: 52423 (52423) +Domain Name System (response) + [Request In: 49] + [Time: 0.221586000 seconds] + Transaction ID: 0x0003 + Flags: 0x8180 Standard query response, No error + Questions: 1 + Answer RRs: 5 + Authority RRs: 0 + Additional RRs: 5 + Queries + Answers + google.com: type MX, class IN, preference 20, mx alt1.aspmx.l.google.com + Name: google.com + Type: MX (Mail exchange) + Class: IN (0x0001) + Time to live: 9 minutes, 59 seconds + Data length: 17 + Preference: 20 + Mail exchange: alt1.aspmx.l.google.com + google.com: type MX, class IN, preference 30, mx alt2.aspmx.l.google.com + Name: google.com + Type: MX (Mail exchange) + Class: IN (0x0001) + Time to live: 9 minutes, 59 seconds + Data length: 9 + Preference: 30 + Mail exchange: alt2.aspmx.l.google.com + google.com: type MX, class IN, preference 40, mx alt3.aspmx.l.google.com + Name: google.com + Type: MX (Mail exchange) + Class: IN (0x0001) + Time to live: 9 minutes, 59 seconds + Data length: 9 + Preference: 40 + Mail exchange: alt3.aspmx.l.google.com + google.com: type MX, class IN, preference 50, mx alt4.aspmx.l.google.com + Name: google.com + Type: MX (Mail exchange) + Class: IN (0x0001) + Time to live: 9 minutes, 59 seconds + Data length: 9 + Preference: 50 + Mail exchange: alt4.aspmx.l.google.com + google.com: type MX, class IN, preference 10, mx aspmx.l.google.com + Name: google.com + Type: MX (Mail exchange) + Class: IN (0x0001) + Time to live: 9 minutes, 59 seconds + Data length: 4 + Preference: 10 + Mail exchange: aspmx.l.google.com + Additional records + alt1.aspmx.l.google.com: type A, class IN, addr 209.85.225.26 + Name: alt1.aspmx.l.google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 1 minute, 50 seconds + Data length: 4 + Addr: 209.85.225.26 (209.85.225.26) + alt2.aspmx.l.google.com: type A, class IN, addr 74.125.130.26 + Name: alt2.aspmx.l.google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 30 seconds + Data length: 4 + Addr: 74.125.130.26 (74.125.130.26) + alt3.aspmx.l.google.com: type A, class IN, addr 173.194.76.26 + Name: alt3.aspmx.l.google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 4 minutes, 53 seconds + Data length: 4 + Addr: 173.194.76.26 (173.194.76.26) + alt4.aspmx.l.google.com: type A, class IN, addr 173.194.73.26 + Name: alt4.aspmx.l.google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 4 minutes, 53 seconds + Data length: 4 + Addr: 173.194.73.26 (173.194.73.26) + aspmx.l.google.com: type A, class IN, addr 173.194.79.26 + Name: aspmx.l.google.com + Type: A (Host address) + Class: IN (0x0001) + Time to live: 4 minutes, 52 seconds + Data length: 4 + Addr: 173.194.79.26 (173.194.79.26) +*/ + +/* Frame (258 bytes) */ +char response_mx_a_google_com_pkt[258] = { +0xd4, 0xbe, 0xd9, 0x8e, 0xec, 0xb5, 0x00, 0xe0, /* ........ */ +0x81, 0x45, 0x7a, 0xc6, 0x08, 0x00, 0x45, 0x00, /* .Ez...E. */ +0x00, 0xf4, 0x4a, 0x8d, 0x00, 0x00, 0x80, 0x11, /* ..J..... */ +0x6a, 0x76, 0xc0, 0x02, 0x02, 0x01, 0xc0, 0x02, /* jv...... */ +0x02, 0xf0, 0x00, 0x35, 0xcc, 0xc7, 0x00, 0xe0, /* ...5.... */ +0x30, 0x39, 0x00, 0x03, 0x81, 0x80, 0x00, 0x01, /* 09...... */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x06, 0x67, /* .......g */ +0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, /* oogle.co */ +0x6d, 0x00, 0x00, 0x0f, 0x00, 0x01, 0xc0, 0x0c, /* m....... */ +0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x02, 0x57, /* .......W */ +0x00, 0x11, 0x00, 0x14, 0x04, 0x61, 0x6c, 0x74, /* .....alt */ +0x31, 0x05, 0x61, 0x73, 0x70, 0x6d, 0x78, 0x01, /* 1.aspmx. */ +0x6c, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0f, 0x00, /* l....... */ +0x01, 0x00, 0x00, 0x02, 0x57, 0x00, 0x09, 0x00, /* ....W... */ +0x1e, 0x04, 0x61, 0x6c, 0x74, 0x32, 0xc0, 0x2f, /* ..alt2./ */ +0xc0, 0x0c, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x02, 0x57, 0x00, 0x09, 0x00, 0x28, 0x04, 0x61, /* .W...(.a */ +0x6c, 0x74, 0x33, 0xc0, 0x2f, 0xc0, 0x0c, 0x00, /* lt3./... */ +0x0f, 0x00, 0x01, 0x00, 0x00, 0x02, 0x57, 0x00, /* ......W. */ +0x09, 0x00, 0x32, 0x04, 0x61, 0x6c, 0x74, 0x34, /* ..2.alt4 */ +0xc0, 0x2f, 0xc0, 0x0c, 0x00, 0x0f, 0x00, 0x01, /* ./...... */ +0x00, 0x00, 0x02, 0x57, 0x00, 0x04, 0x00, 0x0a, /* ...W.... */ +0xc0, 0x2f, 0xc0, 0x2a, 0x00, 0x01, 0x00, 0x01, /* ./.*.... */ +0x00, 0x00, 0x00, 0x6e, 0x00, 0x04, 0xd1, 0x55, /* ...n...U */ +0xe1, 0x1a, 0xc0, 0x47, 0x00, 0x01, 0x00, 0x01, /* ...G.... */ +0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x4a, 0x7d, /* ......J} */ +0x82, 0x1a, 0xc0, 0x5c, 0x00, 0x01, 0x00, 0x01, /* ...\.... */ +0x00, 0x00, 0x01, 0x25, 0x00, 0x04, 0xad, 0xc2, /* ...%.... */ +0x4c, 0x1a, 0xc0, 0x71, 0x00, 0x01, 0x00, 0x01, /* L..q.... */ +0x00, 0x00, 0x01, 0x25, 0x00, 0x04, 0xad, 0xc2, /* ...%.... */ +0x49, 0x1a, 0xc0, 0x86, 0x00, 0x01, 0x00, 0x01, /* I....... */ +0x00, 0x00, 0x01, 0x24, 0x00, 0x04, 0xad, 0xc2, /* ...$.... */ +0x4f, 0x1a /* O. */ +}; + +int response_mx_a_google_com_pkt_size = 258; diff --git a/test/regression/dns_test/response_mx_google_com.c b/test/regression/dns_test/response_mx_google_com.c new file mode 100644 index 00000000..c1996ac6 --- /dev/null +++ b/test/regression/dns_test/response_mx_google_com.c @@ -0,0 +1,89 @@ +/* +No. Time Source Destination Protocol Length Info +42 2.441991000 192.168.0.1 192.168.0.105 DNS 178 Standard query response 0x0002 MX 40 alt3.aspmx.l.google.com MX 30 alt2.aspmx.l.google.com MX 10 aspmx.l.google.com MX 20 alt1.aspmx.l.google.com MX 50 alt4.aspmx.l.google.com + +Frame 171: 178 bytes on wire (1424 bits), 178 bytes captured (1424 bits) +Ethernet II, Src: TendaTec_60:4b:46 (c8:3a:35:60:4b:46), Dst: Dell_33:c1:bd (18:03:73:33:c1:bd) +Internet Protocol Version 4, Src: 192.168.0.1 (192.168.0.1), Dst: 192.168.0.105 (192.168.0.105) +User Datagram Protocol, Src Port: domain (53), Dst Port: 53738 (53738) +Domain Name System (response) + Request In: 164 + Time: 0.037374000 seconds + Transaction ID: 0x0002 + Flags: 0x8180 (Standard query response, No error) + Questions: 1 + Answer RRs: 5 + Authority RRs: 0 + Additional RRs: 0 + Queries + google.com: type MX, class IN + Answers + google.com: type MX, class IN, preference 50, mx alt4.aspmx.l.google.com + Name: google.com + Type: MX (Mail exchange) + Class: IN (0x0001) + Time to live: 10 minutes + Data length: 17 + Preference: 50 + Mail exchange: alt4.aspmx.l.google.com + google.com: type MX, class IN, preference 30, mx alt2.aspmx.l.google.com + Name: google.com + Type: MX (Mail exchange) + Class: IN (0x0001) + Time to live: 10 minutes + Data length: 9 + Preference: 30 + Mail exchange: alt2.aspmx.l.google.com + google.com: type MX, class IN, preference 10, mx aspmx.l.google.com + Name: google.com + Type: MX (Mail exchange) + Class: IN (0x0001) + Time to live: 10 minutes + Data length: 4 + Preference: 10 + Mail exchange: aspmx.l.google.com + google.com: type MX, class IN, preference 20, mx alt1.aspmx.l.google.com + Name: google.com + Type: MX (Mail exchange) + Class: IN (0x0001) + Time to live: 10 minutes + Data length: 9 + Preference: 20 + Mail exchange: alt1.aspmx.l.google.com + google.com: type MX, class IN, preference 40, mx alt3.aspmx.l.google.com + Name: google.com + Type: MX (Mail exchange) + Class: IN (0x0001) + Time to live: 10 minutes + Data length: 9 + Preference: 40 + Mail exchange: alt3.aspmx.l.google.com +*/ + +char response_mx_google_com_pkt[178] = { +0x18, 0x03, 0x73, 0x33, 0xc1, 0xbd, 0xc8, 0x3a, +0x35, 0x60, 0x4b, 0x46, 0x08, 0x00, 0x45, 0x00, +0x00, 0xa4, 0x98, 0xa1, 0x00, 0x00, 0x40, 0x11, +0x5f, 0xed, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8, +0x00, 0x69, 0x00, 0x35, 0xd1, 0xea, 0x00, 0x90, +0x68, 0x6a, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, +0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, +0x6d, 0x00, 0x00, 0x0f, 0x00, 0x01, 0xc0, 0x0c, +0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x02, 0x58, +0x00, 0x11, 0x00, 0x32, 0x04, 0x61, 0x6c, 0x74, +0x34, 0x05, 0x61, 0x73, 0x70, 0x6d, 0x78, 0x01, +0x6c, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0f, 0x00, +0x01, 0x00, 0x00, 0x02, 0x58, 0x00, 0x09, 0x00, +0x1e, 0x04, 0x61, 0x6c, 0x74, 0x32, 0xc0, 0x2f, +0xc0, 0x0c, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, +0x02, 0x58, 0x00, 0x04, 0x00, 0x0a, 0xc0, 0x2f, +0xc0, 0x0c, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, +0x02, 0x58, 0x00, 0x09, 0x00, 0x14, 0x04, 0x61, +0x6c, 0x74, 0x31, 0xc0, 0x2f, 0xc0, 0x0c, 0x00, +0x0f, 0x00, 0x01, 0x00, 0x00, 0x02, 0x58, 0x00, +0x09, 0x00, 0x28, 0x04, 0x61, 0x6c, 0x74, 0x33, +0xc0, 0x2f +}; + +int response_mx_google_com_pkt_size = sizeof(response_mx_google_com_pkt); \ No newline at end of file diff --git a/test/regression/dns_test/response_ns_a_ti_com.c b/test/regression/dns_test/response_ns_a_ti_com.c new file mode 100644 index 00000000..bef59036 --- /dev/null +++ b/test/regression/dns_test/response_ns_a_ti_com.c @@ -0,0 +1,95 @@ +/* +No. Time Source Destination Protocol Length Info + 30 51.227025 192.2.2.1 192.2.2.240 DNS 349 Standard query response NS ns-d.pnap.net NS ns-b.pnap.net NS ns3.ti.com NS ns4.ti.com NS ns.ti.com NS ns2.ti.com NS ns-a.pnap.net NS ns-c.pnap.net + +Frame 30: 349 bytes on wire (2792 bits), 349 bytes captured (2792 bits) +Ethernet II, Src: TyanComp_45:7a:c6 (00:e0:81:45:7a:c6), Dst: Dell_8e:ec:b5 (d4:be:d9:8e:ec:b5) +Internet Protocol Version 4, Src: 192.2.2.1 (192.2.2.1), Dst: 192.2.2.240 (192.2.2.240) +User Datagram Protocol, Src Port: domain (53), Dst Port: 53051 (53051) +Domain Name System (response) + [Request In: 29] + [Time: 0.000192000 seconds] + Transaction ID: 0x0002 + Flags: 0x8180 (Standard query response, No error) + 1... .... .... .... = Response: Message is a response + .000 0... .... .... = Opcode: Standard query (0) + .... .0.. .... .... = Authoritative: Server is not an authority for domain + .... ..0. .... .... = Truncated: Message is not truncated + .... ...1 .... .... = Recursion desired: Do query recursively + .... .... 1... .... = Recursion available: Server can do recursive queries + .... .... .0.. .... = Z: reserved (0) + .... .... ..0. .... = Answer authenticated: Answer/authority portion was not authenticated by the server + .... .... ...0 .... = Non-authenticated data: Unacceptable + .... .... .... 0000 = Reply code: No error (0) + Questions: 1 + Answer RRs: 8 + Authority RRs: 0 + Additional RRs: 8 + Queries + Answers + ti.com: type NS, class IN, ns ns-d.pnap.net + ti.com: type NS, class IN, ns ns-b.pnap.net + ti.com: type NS, class IN, ns ns3.ti.com + ti.com: type NS, class IN, ns ns4.ti.com + ti.com: type NS, class IN, ns ns.ti.com + ti.com: type NS, class IN, ns ns2.ti.com + ti.com: type NS, class IN, ns ns-a.pnap.net + ti.com: type NS, class IN, ns ns-c.pnap.net + Additional records + ns-d.pnap.net: type A, class IN, addr 64.95.61.36 + ns-b.pnap.net: type A, class IN, addr 64.94.123.36 + ns3.ti.com: type A, class IN, addr 198.47.26.150 + ns4.ti.com: type A, class IN, addr 198.47.26.151 + ns.ti.com: type A, class IN, addr 192.94.94.42 + ns2.ti.com: type A, class IN, addr 192.94.94.43 + ns-a.pnap.net: type A, class IN, addr 64.94.123.4 + ns-c.pnap.net: type A, class IN, addr 64.95.61.4 +*/ + +char response_ns_a_ti_com_pkt[349] = { +0xd4, 0xbe, 0xd9, 0x8e, 0xec, 0xb5, 0x00, 0xe0, +0x81, 0x45, 0x7a, 0xc6, 0x08, 0x00, 0x45, 0x00, +0x01, 0x4f, 0x0f, 0xb4, 0x00, 0x00, 0x80, 0x11, +0xa4, 0xf4, 0xc0, 0x02, 0x02, 0x01, 0xc0, 0x02, +0x02, 0xf0, 0x00, 0x35, 0xcf, 0x3b, 0x01, 0x3b, +0xe8, 0x68, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, +0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x02, 0x74, +0x69, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x02, +0x00, 0x01, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, +0x00, 0x00, 0x78, 0x39, 0x00, 0x0f, 0x04, 0x6e, +0x73, 0x2d, 0x64, 0x04, 0x70, 0x6e, 0x61, 0x70, +0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x0c, 0x00, +0x02, 0x00, 0x01, 0x00, 0x00, 0x78, 0x39, 0x00, +0x07, 0x04, 0x6e, 0x73, 0x2d, 0x62, 0xc0, 0x29, +0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, +0x78, 0x39, 0x00, 0x06, 0x03, 0x6e, 0x73, 0x33, +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, +0x00, 0x00, 0x78, 0x39, 0x00, 0x06, 0x03, 0x6e, +0x73, 0x34, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x02, +0x00, 0x01, 0x00, 0x00, 0x78, 0x39, 0x00, 0x05, +0x02, 0x6e, 0x73, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, +0x02, 0x00, 0x01, 0x00, 0x00, 0x78, 0x39, 0x00, +0x06, 0x03, 0x6e, 0x73, 0x32, 0xc0, 0x0c, 0xc0, +0x0c, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x78, +0x39, 0x00, 0x07, 0x04, 0x6e, 0x73, 0x2d, 0x61, +0xc0, 0x29, 0xc0, 0x0c, 0x00, 0x02, 0x00, 0x01, +0x00, 0x00, 0x78, 0x39, 0x00, 0x07, 0x04, 0x6e, +0x73, 0x2d, 0x63, 0xc0, 0x29, 0xc0, 0x24, 0x00, +0x01, 0x00, 0x01, 0x00, 0x00, 0x77, 0x7d, 0x00, +0x04, 0x40, 0x5f, 0x3d, 0x24, 0xc0, 0x3f, 0x00, +0x01, 0x00, 0x01, 0x00, 0x00, 0x96, 0x12, 0x00, +0x04, 0x40, 0x5e, 0x7b, 0x24, 0xc0, 0x52, 0x00, +0x01, 0x00, 0x01, 0x00, 0x01, 0x49, 0xf4, 0x00, +0x04, 0xc6, 0x2f, 0x1a, 0x96, 0xc0, 0x64, 0x00, +0x01, 0x00, 0x01, 0x00, 0x01, 0x49, 0xf4, 0x00, +0x04, 0xc6, 0x2f, 0x1a, 0x97, 0xc0, 0x76, 0x00, +0x01, 0x00, 0x01, 0x00, 0x01, 0x49, 0xf4, 0x00, +0x04, 0xc0, 0x5e, 0x5e, 0x2a, 0xc0, 0x87, 0x00, +0x01, 0x00, 0x01, 0x00, 0x01, 0x49, 0xf4, 0x00, +0x04, 0xc0, 0x5e, 0x5e, 0x2b, 0xc0, 0x99, 0x00, +0x01, 0x00, 0x01, 0x00, 0x00, 0x76, 0xe1, 0x00, +0x04, 0x40, 0x5e, 0x7b, 0x04, 0xc0, 0xac, 0x00, +0x01, 0x00, 0x01, 0x00, 0x00, 0x47, 0x46, 0x00, +0x04, 0x40, 0x5f, 0x3d, 0x04 }; + +int response_ns_a_ti_com_pkt_size = sizeof(response_ns_a_ti_com_pkt); \ No newline at end of file diff --git a/test/regression/dns_test/response_soa_google_com.c b/test/regression/dns_test/response_soa_google_com.c new file mode 100644 index 00000000..0ef29260 --- /dev/null +++ b/test/regression/dns_test/response_soa_google_com.c @@ -0,0 +1,54 @@ +/* +No. Time Source Destination Protocol Length Info +18 4.207289000 192.168.0.1 192.168.0.105 DNS 120 Yes Standard query response 0x0002 SOA ns1.google.com + +Frame 18: 120 bytes on wire (960 bits), 120 bytes captured (960 bits) +Ethernet II, Src: TendaTec_60:4b:46 (c8:3a:35:60:4b:46), Dst: Dell_33:c1:bd (18:03:73:33:c1:bd) +Internet Protocol Version 4, Src: 192.168.0.1 (192.168.0.1), Dst: 192.168.0.105 (192.168.0.105) +User Datagram Protocol, Src Port: domain (53), Dst Port: 55808 (55808) +Domain Name System (response) + Request In: 17 + Time: 0.081002000 seconds + Transaction ID: 0x0002 + Flags: 0x8180 (Standard query response, No error) + Questions: 1 + Answer RRs: 1 + Authority RRs: 0 + Additional RRs: 0 + Queries + google.com: type SOA, class IN + Answers + google.com: type SOA, class IN, mname ns1.google.com + Name: google.com + Type: SOA (Start of zone of authority) + Class: IN (0x0001) + Time to live: 11 hours, 56 minutes, 51 seconds + Data length: 38 + Primary name server: ns1.google.com + Responsible authority's mailbox: dns-admin.google.com + Serial number: 2012090400 + Refresh interval: 2 hours + Retry interval: 30 minutes + Expiration limit: 14 days + Minimum TTL: 5 minutes +*/ + +char response_soa_google_com_pkt[120] = { +0x18, 0x03, 0x73, 0x33, 0xc1, 0xbd, 0xc8, 0x3a, +0x35, 0x60, 0x4b, 0x46, 0x08, 0x00, 0x45, 0x00, +0x00, 0x6a, 0x5c, 0x34, 0x00, 0x00, 0x40, 0x11, +0x9c, 0x94, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8, +0x00, 0x69, 0x00, 0x35, 0xda, 0x00, 0x00, 0x56, +0x1b, 0x90, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, +0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, +0x6d, 0x00, 0x00, 0x06, 0x00, 0x01, 0xc0, 0x0c, +0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0xa8, 0x03, +0x00, 0x26, 0x03, 0x6e, 0x73, 0x31, 0xc0, 0x0c, +0x09, 0x64, 0x6e, 0x73, 0x2d, 0x61, 0x64, 0x6d, +0x69, 0x6e, 0xc0, 0x0c, 0x77, 0xee, 0x10, 0x20, +0x00, 0x00, 0x1c, 0x20, 0x00, 0x00, 0x07, 0x08, +0x00, 0x12, 0x75, 0x00, 0x00, 0x00, 0x01, 0x2c +}; + +int response_soa_google_com_pkt_size = sizeof(response_soa_google_com_pkt); \ No newline at end of file diff --git a/test/regression/dns_test/response_srv_google_com.c b/test/regression/dns_test/response_srv_google_com.c new file mode 100644 index 00000000..d7427f90 --- /dev/null +++ b/test/regression/dns_test/response_srv_google_com.c @@ -0,0 +1,122 @@ +/* +No. Time Source Destination Protocol Length Info +10 2.964289000 192.168.0.1 192.168.0.105 DNS 293 Yes Standard query response 0x0002 SRV 5 0 5222 xmpp.l.google.com SRV 20 0 5222 alt3.xmpp.l.google.com SRV 20 0 5222 alt2.xmpp.l.google.com SRV 20 0 5222 alt4.xmpp.l.google.com SRV 20 0 5222 alt1.xmpp.l.google.com + +Frame 10: 293 bytes on wire (2344 bits), 293 bytes captured (2344 bits) +Ethernet II, Src: TendaTec_60:4b:46 (c8:3a:35:60:4b:46), Dst: Dell_33:c1:bd (18:03:73:33:c1:bd) +Internet Protocol Version 4, Src: 192.168.0.1 (192.168.0.1), Dst: 192.168.0.105 (192.168.0.105) +User Datagram Protocol, Src Port: domain (53), Dst Port: 49903 (49903) +Domain Name System (response) + Request In: 9 + Time: 0.064681000 seconds + Transaction ID: 0x0002 + Flags: 0x8180 (Standard query response, No error) + Questions: 1 + Answer RRs: 5 + Authority RRs: 0 + Additional RRs: 0 + Queries + _xmpp-client._tcp.google.com: type SRV, class IN + Answers + _xmpp-client._tcp.google.com: type SRV, class IN, priority 20, weight 0, port 5222, target alt3.xmpp.l.google.com + Service: xmpp-client + Protocol: tcp + Name: google.com + Type: SRV (Service location) + Class: IN (0x0001) + Time to live: 14 minutes, 33 seconds + Data length: 30 + Priority: 20 + Weight: 0 + Port: 5222 + Target: alt3.xmpp.l.google.com + _xmpp-client._tcp.google.com: type SRV, class IN, priority 20, weight 0, port 5222, target alt1.xmpp.l.google.com + Service: xmpp-client + Protocol: tcp + Name: google.com + Type: SRV (Service location) + Class: IN (0x0001) + Time to live: 14 minutes, 33 seconds + Data length: 30 + Priority: 20 + Weight: 0 + Port: 5222 + Target: alt1.xmpp.l.google.com + _xmpp-client._tcp.google.com: type SRV, class IN, priority 20, weight 0, port 5222, target alt4.xmpp.l.google.com + Service: xmpp-client + Protocol: tcp + Name: google.com + Type: SRV (Service location) + Class: IN (0x0001) + Time to live: 14 minutes, 33 seconds + Data length: 30 + Priority: 20 + Weight: 0 + Port: 5222 + Target: alt4.xmpp.l.google.com + _xmpp-client._tcp.google.com: type SRV, class IN, priority 5, weight 0, port 5222, target xmpp.l.google.com + Service: xmpp-client + Protocol: tcp + Name: google.com + Type: SRV (Service location) + Class: IN (0x0001) + Time to live: 14 minutes, 33 seconds + Data length: 25 + Priority: 5 + Weight: 0 + Port: 5222 + Target: xmpp.l.google.com + _xmpp-client._tcp.google.com: type SRV, class IN, priority 20, weight 0, port 5222, target alt2.xmpp.l.google.com + Service: xmpp-client + Protocol: tcp + Name: google.com + Type: SRV (Service location) + Class: IN (0x0001) + Time to live: 14 minutes, 33 seconds + Data length: 30 + Priority: 20 + Weight: 0 + Port: 5222 + Target: alt2.xmpp.l.google.com +*/ + +char response_srv_google_com_pkt[293] = { +0x18, 0x03, 0x73, 0x33, 0xc1, 0xbd, 0xc8, 0x3a, +0x35, 0x60, 0x4b, 0x46, 0x08, 0x00, 0x45, 0x00, +0x01, 0x17, 0xbe, 0x7e, 0x00, 0x00, 0x40, 0x11, +0x39, 0x9d, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8, +0x00, 0x69, 0x00, 0x35, 0xe1, 0xf6, 0x01, 0x03, +0x6f, 0x26, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, +0x78, 0x6d, 0x70, 0x70, 0x2d, 0x63, 0x6c, 0x69, +0x65, 0x6e, 0x74, 0x04, 0x5f, 0x74, 0x63, 0x70, +0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, +0x63, 0x6f, 0x6d, 0x00, 0x00, 0x21, 0x00, 0x01, +0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, 0x00, 0x00, +0x03, 0x84, 0x00, 0x1e, 0x00, 0x14, 0x00, 0x00, +0x14, 0x66, 0x04, 0x61, 0x6c, 0x74, 0x33, 0x04, +0x78, 0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06, 0x67, +0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, +0x6d, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, 0x01, +0x00, 0x00, 0x03, 0x84, 0x00, 0x1e, 0x00, 0x14, +0x00, 0x00, 0x14, 0x66, 0x04, 0x61, 0x6c, 0x74, +0x31, 0x04, 0x78, 0x6d, 0x70, 0x70, 0x01, 0x6c, +0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, +0x63, 0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00, 0x21, +0x00, 0x01, 0x00, 0x00, 0x03, 0x84, 0x00, 0x1e, +0x00, 0x14, 0x00, 0x00, 0x14, 0x66, 0x04, 0x61, +0x6c, 0x74, 0x34, 0x04, 0x78, 0x6d, 0x70, 0x70, +0x01, 0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, +0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0xc0, 0x0c, +0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x03, 0x84, +0x00, 0x19, 0x00, 0x05, 0x00, 0x00, 0x14, 0x66, +0x04, 0x78, 0x6d, 0x70, 0x70, 0x01, 0x6c, 0x06, +0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, +0x6f, 0x6d, 0x00, 0xc0, 0x0c, 0x00, 0x21, 0x00, +0x01, 0x00, 0x00, 0x03, 0x84, 0x00, 0x1e, 0x00, +0x14, 0x00, 0x00, 0x14, 0x66, 0x04, 0x61, 0x6c, +0x74, 0x32, 0x04, 0x78, 0x6d, 0x70, 0x70, 0x01, +0x6c, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, +0x03, 0x63, 0x6f, 0x6d, 0x00 }; + +int response_srv_google_com_pkt_size = sizeof(response_srv_google_com_pkt); \ No newline at end of file diff --git a/test/regression/dns_test/response_txt_google_com.c b/test/regression/dns_test/response_txt_google_com.c new file mode 100644 index 00000000..f8386365 --- /dev/null +++ b/test/regression/dns_test/response_txt_google_com.c @@ -0,0 +1,53 @@ +/* +No. Time Source Destination Protocol Length Info +237 10.385804000 192.168.0.1 192.168.0.105 DNS 164 Yes Standard query response 0x0002 TXT + +Frame 237: 164 bytes on wire (1312 bits), 164 bytes captured (1312 bits) +Ethernet II, Src: TendaTec_60:4b:46 (c8:3a:35:60:4b:46), Dst: Dell_33:c1:bd (18:03:73:33:c1:bd) +Internet Protocol Version 4, Src: 192.168.0.1 (192.168.0.1), Dst: 192.168.0.105 (192.168.0.105) +User Datagram Protocol, Src Port: domain (53), Dst Port: 49547 (49547) +Domain Name System (response) + Request In: 236 + Time: 0.117301000 seconds + Transaction ID: 0x0002 + Flags: 0x8180 (Standard query response, No error) + Questions: 1 + Answer RRs: 1 + Authority RRs: 0 + Additional RRs: 0 + Queries + google.com: type TXT, class IN + Answers + google.com: type TXT, class IN + Name: google.com + Type: TXT (Text strings) + Class: IN (0x0001) + Time to live: 1 hour + Data length: 82 + Text: v=spf1 include:_netblocks.google.com ip4:216.73.93.70/31 ip4:216.73.93.72/31 ~all +*/ + +char response_txt_google_com_pkt[293] = { +0x18, 0x03, 0x73, 0x33, 0xc1, 0xbd, 0xc8, 0x3a, +0x35, 0x60, 0x4b, 0x46, 0x08, 0x00, 0x45, 0x00, +0x00, 0x96, 0xc1, 0xa0, 0x00, 0x00, 0x40, 0x11, +0x36, 0xfc, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8, +0x00, 0x69, 0x00, 0x35, 0xc1, 0x8b, 0x00, 0x82, +0xec, 0x71, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01, +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, +0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, +0x6d, 0x00, 0x00, 0x10, 0x00, 0x01, 0xc0, 0x0c, +0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, +0x00, 0x52, 0x51, 0x76, 0x3d, 0x73, 0x70, 0x66, +0x31, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, +0x65, 0x3a, 0x5f, 0x6e, 0x65, 0x74, 0x62, 0x6c, +0x6f, 0x63, 0x6b, 0x73, 0x2e, 0x67, 0x6f, 0x6f, +0x67, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x20, +0x69, 0x70, 0x34, 0x3a, 0x32, 0x31, 0x36, 0x2e, +0x37, 0x33, 0x2e, 0x39, 0x33, 0x2e, 0x37, 0x30, +0x2f, 0x33, 0x31, 0x20, 0x69, 0x70, 0x34, 0x3a, +0x32, 0x31, 0x36, 0x2e, 0x37, 0x33, 0x2e, 0x39, +0x33, 0x2e, 0x37, 0x32, 0x2f, 0x33, 0x31, 0x20, +0x7e, 0x61, 0x6c, 0x6c }; + +int response_txt_google_com_pkt_size = sizeof(response_txt_google_com_pkt); \ No newline at end of file diff --git a/test/regression/dns_test/response_with_invalid_resource.c b/test/regression/dns_test/response_with_invalid_resource.c new file mode 100644 index 00000000..e626fd08 --- /dev/null +++ b/test/regression/dns_test/response_with_invalid_resource.c @@ -0,0 +1,103 @@ +/* A valid DNS response packet + +00000000: 1c1a dfb0 2f0a 74b6 b640 932d 0800 4500 ..../.t..@.-..E. +00000010: 0069 725d 0000 4011 80a6 c0a8 01fe c0a8 .ir]..@......... +00000020: 0432 0035 c8e1 0055 4c59 88cc 8180 0001 .2.5...ULY...... +00000030: 0002 0000 0000 0863 6c69 656e 7473 3406 .......clients4. +00000040: 676f 6f67 6c65 0363 6f6d 0000 0100 01c0 google.com...... +00000050: 0c00 0500 0100 0000 c300 0c07 636c 6965 ............clie +00000060: 6e74 7301 6cc0 15c0 3100 0100 0100 0001 nts.l...1....... +00000070: 2c00 04ac d903 ce ,...... + +Domain Name System (response) + Transaction ID: 0x88cc + Flags: 0x8180 Standard query response, No error + Questions: 1 + Answer RRs: 2 + Authority RRs: 0 + Additional RRs: 0 + Queries + clients4.google.com: type A, class IN + Name: clients4.google.com + [Name Length: 19] + [Label Count: 3] + Type: A (Host Address) (1) + Class: IN (0x0001) + Answers + clients4.google.com: type CNAME, class IN, cname clients.l.google.com + Name: clients4.google.com + Type: CNAME (Canonical NAME for an alias) (5) + Class: IN (0x0001) + Time to live: 195 (3 minutes, 15 seconds) + Data length: 12 + CNAME: clients.l.google.com + clients.l.google.com: type A, class IN, addr 172.217.3.206 + Name: clients.l.google.com + Type: A (Host Address) (1) + Class: IN (0x0001) + Time to live: 300 (5 minutes) + Data length: 4 + Address: 172.217.3.206 + [Unsolicited: True] + +*/ + +/* Invalid response packet 0 */ +/* where CNAME lableSize 0xc0 (the 80th Byte) is changed to 0x3e, + which leads to name buffer OOB in _nx_dns_name_size_calculate(), then is detected.*/ +char invalid_response_ptr_0[119] = { + 0x1c, 0x1a, 0xdf, 0xb0, 0x2f, 0x0a, 0x74, 0xb6, 0xb6, 0x40, 0x93, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x69, 0x72, 0x5d, 0x00, 0x00, 0x40, 0x11, 0x80, 0xa6, 0xc0, 0xa8, 0x01, 0xfe, 0xc0, 0xa8, + 0x04, 0x32, 0x00, 0x35, 0xc8, 0xe1, 0x00, 0x55, 0x4c, 0x59, 0x88, 0xcc, 0x81, 0x80, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x34, 0x06, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0x3e, + 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x0c, 0x07, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x73, 0x01, 0x6c, 0xc0, 0x15, 0xc0, 0x31, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x04, 0xac, 0xd9, 0x03, 0xce +}; +unsigned int invalid_response_size_0 = 119; + +/* Invalid response packet 1 */ +/* where question lableSize 0x08 (the 55th byte) is changed to 0x3e, + which leads to name buffer OOB in _nx_dns_name_size_calculate(), then is detected.*/ +char invalid_response_ptr_1[119] = { + 0x1c, 0x1a, 0xdf, 0xb0, 0x2f, 0x0a, 0x74, 0xb6, 0xb6, 0x40, 0x93, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x69, 0x72, 0x5d, 0x00, 0x00, 0x40, 0x11, 0x80, 0xa6, 0xc0, 0xa8, 0x01, 0xfe, 0xc0, 0xa8, + 0x04, 0x32, 0x00, 0x35, 0xc8, 0xe1, 0x00, 0x55, 0x4c, 0x59, 0x88, 0xcc, 0x81, 0x80, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x34, 0x06, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0x3e, + 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x0c, 0x07, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x73, 0x01, 0x6c, 0xc0, 0x15, 0xc0, 0x31, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x04, 0xac, 0xd9, 0x03, 0xce +}; +unsigned int invalid_response_size_1 = 119; + +/* Invalid response packet 2 */ +/* where A address lableSize 0xc0 (the 104th Byte) is changed to 0x0d, the 117th Byte is changed to 0, + which leads to buffer OOB in _nx_dns_resource_type_get(), then is detected. */ +char invalid_response_ptr_2[119] = { + 0x1c, 0x1a, 0xdf, 0xb0, 0x2f, 0x0a, 0x74, 0xb6, 0xb6, 0x40, 0x93, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x69, 0x72, 0x5d, 0x00, 0x00, 0x40, 0x11, 0x80, 0xa6, 0xc0, 0xa8, 0x01, 0xfe, 0xc0, 0xa8, + 0x04, 0x32, 0x00, 0x35, 0xc8, 0xe1, 0x00, 0x55, 0x4c, 0x59, 0x88, 0xcc, 0x81, 0x80, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x34, 0x06, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, + 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x0c, 0x07, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x73, 0x01, 0x6c, 0xc0, 0x15, 0x0d, 0x31, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, + 0x2c, 0x00, 0x04, 0xac, 0x00, 0x00, 0xce +}; +unsigned int invalid_response_size_2 = 119; + +/* Invalid response packet 3 */ +/* where the last 7 Bytes are deleted, + which leads to buffer OOB in _nx_dns_resource_data_length_get(), then is detected.*/ +char invalid_response_ptr_3[112] = { + 0x1c, 0x1a, 0xdf, 0xb0, 0x2f, 0x0a, 0x74, 0xb6, 0xb6, 0x40, 0x93, 0x2d, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x69, 0x72, 0x5d, 0x00, 0x00, 0x40, 0x11, 0x80, 0xa6, 0xc0, 0xa8, 0x01, 0xfe, 0xc0, 0xa8, + 0x04, 0x32, 0x00, 0x35, 0xc8, 0xe1, 0x00, 0x55, 0x4c, 0x59, 0x88, 0xcc, 0x81, 0x80, 0x00, 0x01, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x73, 0x34, 0x06, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, + 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x0c, 0x07, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x73, 0x01, 0x6c, 0xc0, 0x15, 0xc0, 0x31, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00 +}; +unsigned int invalid_response_size_3 = 112; + diff --git a/test/regression/ftp_test/netx_ftp_access_control_commands_01_test.c b/test/regression/ftp_test/netx_ftp_access_control_commands_01_test.c new file mode 100644 index 00000000..bf3e1345 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_access_control_commands_01_test.c @@ -0,0 +1,317 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG username_counter = 0; +static ULONG flag = 0; +static UINT test_done = NX_FALSE; + + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_access_control_commands_01_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + + +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + flag = 1; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Access Control Commands User 01 Test..........."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) && ( username_counter != 1 )) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check the packet is a SYN one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (flag != 1)) + { + if(!memcmp(message,"USER name",9)) + username_counter++; + + /* Deal packets with default routing. */ + server_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* When ftp client connect the ftp server, increase the flage to make sure the "User" packet is the first packet we get. */ + if(flag) + flag++; + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_access_control_commands_01_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Access Control Commands User 01 Test...........N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_access_control_commands_02_test.c b/test/regression/ftp_test/netx_ftp_access_control_commands_02_test.c new file mode 100644 index 00000000..78e0a9a6 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_access_control_commands_02_test.c @@ -0,0 +1,322 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG username_counter = 0; +static ULONG passwd_counter = 0; +static UINT test_done = NX_FALSE; + + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_access_control_commands_02_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + + +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Access Control Commands Pass Test.............."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) && ( username_counter != 1 ) && ( passwd_counter != 1 )) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; +static int flag = 0; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check the packet is a SYN one. */ + if(*message == 'U') + { + if(!memcmp(message,"USER name",9)) + { + username_counter++; + flag = 0; + } + } + /* Check if the PASSWORD command must be immediately preceded by the user name command. */ + else if (*message == 'P' && flag == 1) + { + if(!memcmp(message,"PASS password",13)) + passwd_counter++; + + server_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + /* Deal packets with default routing. */ + + flag ++; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_access_control_commands_02_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Access Control Commands Pass Test..............N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_access_control_commands_03_test.c b/test/regression/ftp_test/netx_ftp_access_control_commands_03_test.c new file mode 100644 index 00000000..d603e15a --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_access_control_commands_03_test.c @@ -0,0 +1,487 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG logg_in_counter = 0; +static UINT test_done = NX_FALSE; + + + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_access_control_commands_03_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + + +UINT status; +NX_PACKET *my_packet; +NX_PACKET *data_packet; +ULONG data_port; +ULONG control_port; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + client_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_client; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + control_port = ftp_client.nx_ftp_client_control_socket.nx_tcp_socket_port; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + memcpy(my_packet -> nx_packet_prepend_ptr, "USER name1", 10); + + *(my_packet -> nx_packet_prepend_ptr + 10) = 13; + *(my_packet -> nx_packet_prepend_ptr + 11) = 10; + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 12; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 12; + + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_tcp_socket_receive(&(ftp_client.nx_ftp_client_control_socket), &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(my_packet->nx_packet_prepend_ptr,"33",2)) + error_counter++; + else + { + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + + memcpy(my_packet -> nx_packet_prepend_ptr, "PASS password1", 14); + *(my_packet -> nx_packet_prepend_ptr + 14) = 13; + *(my_packet -> nx_packet_prepend_ptr + 15) = 10; + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 16; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 16; + + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Check if the transfer parameters has been changed */ + if(ftp_client.nx_ftp_client_control_socket.nx_tcp_socket_port != control_port) + error_counter++; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + } + } + + + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &data_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(data_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + data_packet -> nx_packet_length = 28; + data_packet -> nx_packet_append_ptr = data_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, data_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + data_port = ftp_client.nx_ftp_client_data_port; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + memcpy(my_packet -> nx_packet_prepend_ptr, "USER name2", 10); + + *(my_packet -> nx_packet_prepend_ptr + 10) = 13; + *(my_packet -> nx_packet_prepend_ptr + 11) = 10; + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 12; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 12; + + + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_tcp_socket_receive(&(ftp_client.nx_ftp_client_control_socket), &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(my_packet->nx_packet_prepend_ptr,"33",2)) + error_counter++; + else + { + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + memcpy(my_packet -> nx_packet_prepend_ptr, "PASS password2", 14); + *(my_packet -> nx_packet_prepend_ptr + 14) = 13; + *(my_packet -> nx_packet_prepend_ptr + 15) = 10; + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 16; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 16; + + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + nx_packet_release(my_packet); + + /* Check if the transfer parameters has been changed */ + if((ftp_client.nx_ftp_client_data_port != data_port) && (ftp_client.nx_ftp_client_control_socket.nx_tcp_socket_port != control_port)) + error_counter++; + } + } + + nx_packet_release(data_packet); + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if ((status != 0) && (status != NX_NOT_BOUND)) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if ((status != 0) && (status != NX_NOT_CONNECTED)) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +CHAR type; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Access Control Commands User 03 Test..........."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTP Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Check if the transfer parameter has been changed. */ + type = ftp_server.nx_ftp_server_client_list[0].nx_ftp_client_request_transfer_type; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Check if it has flushed the old user, passwd */ + if((memcmp(ftp_server.nx_ftp_server_client_list[0].nx_ftp_client_request_username,"name1",5)) || (memcmp(ftp_server.nx_ftp_server_client_list[0].nx_ftp_client_request_password,"password1",9))) + error_counter++; + + /* Check if the transfer parameter has been changed. */ + if(type != ftp_server.nx_ftp_server_client_list[0].nx_ftp_client_request_transfer_type) + error_counter++; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Check if the transfer parameter has been changed. */ + if(type != ftp_server.nx_ftp_server_client_list[0].nx_ftp_client_request_transfer_type) + error_counter++; + + /* Check if it has flushed the old user, passwd */ + if((memcmp(ftp_server.nx_ftp_server_client_list[0].nx_ftp_client_request_username,"name2",5)) || (memcmp(ftp_server.nx_ftp_server_client_list[0].nx_ftp_client_request_password,"password2",9))) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) && ( logg_in_counter != 3 )) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if(!memcmp(message,"230 Logged in",13)) + logg_in_counter++; + + if(logg_in_counter == 3) + client_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_access_control_commands_03_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Access Control Commands User 03 Test...........N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ftp_test/netx_ftp_access_control_commands_04_test.c b/test/regression/ftp_test/netx_ftp_access_control_commands_04_test.c new file mode 100644 index 00000000..ada3a8af --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_access_control_commands_04_test.c @@ -0,0 +1,381 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG cdup_counter = 0; +static ULONG success_counter = 0; +static UINT test_done = NX_FALSE; + + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_access_control_commands_04_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + + +UINT status; +NX_PACKET *my_packet; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + client_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_client; + + + nx_ftp_client_directory_create(&ftp_client,"/abc", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_ftp_client_directory_default_set(&ftp_client, "/abc" , NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "CDUP ", 5); + + *(my_packet -> nx_packet_prepend_ptr + 5) = 13; + *(my_packet -> nx_packet_prepend_ptr + 6) = 10; + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 7; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 7; + + + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Do the clean job */ + nx_packet_release(my_packet); + + nx_ftp_client_directory_delete(&ftp_client,"/abc",NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Access Control Commands CDUP Test.............."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) && ( success_counter != 2 ) && (cdup_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *tcp_header_ptr; + UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (*message == 'C')) + { + + if(!memcmp(message,"CDUP ",5)) + { + cdup_counter++; + server_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if(!memcmp(message,"250 \"/abc\" set successfully",26)) + success_counter++; + + else if(!memcmp(message,"250 \"/\" set successfully",23)) + { + success_counter++; + client_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_access_control_commands_04_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Access Control Commands CDUP Test..............N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_basic_test.c b/test/regression/ftp_test/netx_ftp_basic_test.c new file mode 100644 index 00000000..6c053c01 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_basic_test.c @@ -0,0 +1,339 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_basic_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Re-create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Now open the same file for reading. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Read the file. */ + status = nx_ftp_client_file_read(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Close this file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Basic Test............................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the ftp Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* OK to restart the ftp Server. */ + status = nx_ftp_server_stop(&ftp_server); + status += nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Basic Test............................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_client_buffer_overflow_test.c b/test/regression/ftp_test/netx_ftp_client_buffer_overflow_test.c new file mode 100644 index 00000000..f7130db2 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_client_buffer_overflow_test.c @@ -0,0 +1,402 @@ +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#else +#include "nx_ftp_client.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_LOOPBACK_INTERFACE) + +#define DEMO_STACK_SIZE 2048 +#define PACKET_PAYLOAD 1536 + + +/* Define the ThreadX, NetX, and FileX object control blocks... */ + +static NX_TCP_SOCKET server_socket; +static TX_THREAD client_thread; +static TX_THREAD server_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; + +/* Define the NetX FTP object control block. */ + +static NX_FTP_CLIENT ftp_client; + + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client_thread_done = NX_FALSE; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(127,0,0,1) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +#define SERVER_PORT 21 +#define SERVER_PASSIVE_PORT1 21017 +#define SERVER_PASSIVE_PORT2 21018 + + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, ULONG packet_type, UCHAR *data, UINT data_size); + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +/* There are for logging in */ +static UCHAR welcome_220_response_1[27] = { +0x32, 0x32, 0x30, 0x2d, 0x4d, 0x69, 0x63, 0x72, /* 220-Micr */ +0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x46, 0x54, /* osoft FT */ +0x50, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, /* PServic */ +0x65, 0x0d, 0x0a /* e.. */ +}; + +static UINT welcome_220_response_1_size = 27; + +static UCHAR welcome_220_response_2[21] = { +0x32, 0x32, 0x30, 0x20, 0x57, 0x69, 0x6e, 0x68, /* 220 Winh */ +0x6f, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x20, /* ost.com */ +0x46, 0x54, 0x50, 0x0d, 0x0a /* FTP.. */ +}; + +static UINT welcome_220_response_2_size = 21; + +static UCHAR password_request_331[23] = { +0x33, 0x33, 0x31, 0x20, 0x50, 0x61, 0x73, 0x73, /* 331 Pass */ +0x77, 0x6f, 0x72, 0x64, 0x20, 0x72, 0x65, 0x71, /* word req */ +0x75, 0x69, 0x72, 0x65, 0x64, 0x0d, 0x0a /* uired.. */ +}; + +static UINT password_request_331_size = 23; + +static UCHAR logged_in_230_response[21] = { +0x32, 0x33, 0x30, 0x20, 0x55, 0x73, 0x65, 0x72, /* 230 User */ +0x20, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x64, 0x20, /* logged */ +0x69, 0x6e, 0x2e, 0x0d, 0x0a /* in... */ +}; + +static UINT logged_in_230_response_size = 21; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_buffer_overflow_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the FTP Server. */ + + /* Create the main FTP server thread. */ + status = tx_thread_create(&server_thread, "FTP Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + + /* Set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", PACKET_PAYLOAD, pointer, 25*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 25*PACKET_PAYLOAD; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, DEMO_STACK_SIZE, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + DEMO_STACK_SIZE; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable TCP for client IP instance. */ + nx_tcp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + /* Let the server set up. */ + tx_thread_sleep(20); + + NX_PARAMETER_NOT_USED(thread_input); + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Now connect with the NetX FTP (IPv4) server on the control socket. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "equenet0_alpha1", "29Pi2A792N", 500); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Delete the FTP client. */ + nx_ftp_client_disconnect(&ftp_client, 0); + nx_ftp_client_delete(&ftp_client); + + client_thread_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: FTP Client Buffer Overflow Test..........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket as the FTP server. */ + status = nx_tcp_socket_create(&client_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the FTP control port. */ + status = nx_tcp_server_socket_listen(&client_ip, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Send welcome response. */ + if (nx_ftp_response_packet_send(&server_socket, (client_pool.nx_packet_pool_payload_size - welcome_220_response_1_size) & 0xFFFFFFFC, + welcome_220_response_1, welcome_220_response_1_size)) + { + error_counter++; + } + + if (nx_ftp_response_packet_send(&server_socket, (client_pool.nx_packet_pool_payload_size - welcome_220_response_2_size) & 0xFFFFFFFC, + welcome_220_response_2, welcome_220_response_2_size)) + { + error_counter++; + } + + /* Receive USER request message. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((status) || (memcmp(my_packet ->nx_packet_prepend_ptr, "USER equenet0_alpha1", sizeof("USER equenet0_alpha1") - 1))) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Send password required message. */ + if (nx_ftp_response_packet_send(&server_socket, (client_pool.nx_packet_pool_payload_size - password_request_331_size) & 0xFFFFFFFC, + password_request_331, password_request_331_size)) + { + error_counter++; + } + + /* Receive PASS request message. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((status) || (memcmp(my_packet ->nx_packet_prepend_ptr, "PASS 29Pi2A792N", sizeof("USER 29Pi2A792N") - 1))) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Send logged in message. */ + if (nx_ftp_response_packet_send(&server_socket, (client_pool.nx_packet_pool_payload_size - password_request_331_size) & 0xFFFFFFFC, + logged_in_230_response, logged_in_230_response_size)) + { + error_counter++; + } + + /* Wait for client thread. */ + while (client_thread_done == NX_FALSE) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + nx_tcp_socket_disconnect(&server_socket, 0); + nx_tcp_socket_delete(&server_socket); + + /* Make sure the packet pool is not corrupted. */ + while (client_pool.nx_packet_pool_available) + { + if (nx_packet_allocate(&client_pool, &my_packet, 0, NX_NO_WAIT) || + (my_packet -> nx_packet_pool_owner != &client_pool)) + { + + error_counter++; + break; + } + } + + /* Check for error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; + + return; + +} + +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, ULONG packet_type, UCHAR *data, UINT data_size) +{ + +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&client_pool, &response_packet, packet_type, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the FTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, data, data_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = data_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_buffer_overflow_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Client Buffer Overflow Test...........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ftp_test/netx_ftp_client_file_write_fail_test.c b/test/regression/ftp_test/netx_ftp_client_file_write_fail_test.c new file mode 100644 index 00000000..9a9829a5 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_client_file_write_fail_test.c @@ -0,0 +1,1026 @@ +/* This is a small demo of NetX FTP on the high-performance NetX TCP/IP stack. This demo + relies on ThreadX, NetX, and FileX to show a simple file transfer from the client + to the server and a directory listing get using passive file transfer (PASV). */ + + + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#else +#include "nx_ftp_client.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define PACKET_PAYLOAD 1518 + + +/* Define the ThreadX, NetX, and FileX object control blocks... */ + +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET server_socket_passive; +static TX_THREAD client_thread; +static TX_THREAD server_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control block. */ +static NX_FTP_CLIENT ftp_client; + +typedef struct FTP_RESPONSE_STRUCT +{ + char *ftp_response_pkt_data; + int ftp_response_pkt_size; +} FTP_RESPONSE; + +#define NUM_RESPONSES 10 +static FTP_RESPONSE ftp_response[NUM_RESPONSES]; + +#define LOGIN_RESPONSES 3 +static FTP_RESPONSE ftp_login[LOGIN_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; + +/* Define the memory area for the FileX RAM disk. */ + +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; +static UCHAR zero_data_buffer[4096]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +#define SERVER_PORT 21 +#define SERVER_PASSIVE_PORT1 21017 +#define SERVER_PASSIVE_PORT2 21018 + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern VOID _fx_ram_driver(FX_MEDIA *media_ptr); + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); +static UINT nx_ftp_login_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); +static void ftp_test_initialize(); + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +/* There are for logging in */ +static char welcome_220_response[21] = { +0x32, 0x32, 0x30, 0x20, 0x44, 0x20, 0x63, 0x6f, /* 220 .... */ +0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x75, /* mmand su */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int welcome_220_response_size = 21; + +static char password_request_331[17] = { +0x33, 0x33, 0x31, 0x20, /* 331 .... */ +0x30, 0x20, 0x43, 0x57, 0x44, 0x20, 0x63, 0x6f, /* 0 CWD co */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int password_request_331_size = 17; + +static char logged_in_230_response[13] = { +0x32, 0x33, 0x30, 0x20, 0x44, 0x20, 0x63, 0x6f, /* 230 .... */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int logged_in_230_response_size = 13; + + +/* These are for downloading information. */ +static char cwd_250_response[23] = { +0x32, 0x35, /* D0v...25 */ +0x30, 0x20, 0x43, 0x57, 0x44, 0x20, 0x63, 0x6f, /* 0 CWD co */ +0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x75, /* mmand su */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int cwd_250_response_size = 23; + + +static char pasv_nlst_227_response[43] = { +0x32, 0x32, /* D.r...22 */ +0x37, 0x20, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x69, /* 7 Enteri */ +0x6e, 0x67, 0x20, 0x50, 0x61, 0x73, 0x73, 0x69, /* ng Passi */ +0x76, 0x65, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x20, /* ve Mode */ +0x28, 0x31, 0x2c, 0x32, 0x2c, 0x33, 0x2c, 0x34, /* (1,2,3,4 */ +0x2c, 0x38, 0x32, 0x2c, 0x32, 0x35, 0x29, 0x0d, /* ,82,25)*/ +0x0a /* ... */ +}; + +static int pasv_nlst_227_response_size = 43; + +static char nlst_complete_150_response[48] = { +0x31, 0x35, /* D.....15 */ +0x30, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, /* 0 Openin */ +0x61, 0x6e, 0x65, 0x74, 0x0d, 0x0a /* anet.. */ +}; + +static int nlst_complete_150_response_size = 48; + +static char server_nlst_download1_response[57] = { +0x74, 0x79, /* ...R..ty */ +0x70, 0x65, 0x3d, 0x63, 0x64, 0x69, 0x72, 0x3b, /* pe=cdir; */ +0x73, 0x69, 0x7a, 0x65, 0x3d, 0x30, 0x3b, 0x6d, /* size=0;m */ +0x6f, 0x64, 0x69, 0x66, 0x79, 0x3d, 0x32, 0x30, /* odify=20 */ +0x31, 0x36, 0x30, 0x37, 0x30, 0x32, 0x30, 0x30, /* 16070200 */ +0x63, 0x64, 0x65, 0x66, 0x6c, 0x6d, 0x70, 0x3b, /* cdeflmp; */ +0x20, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x5c, /* \Users\ */ +0x6a, 0x61, 0x6e, 0x65, 0x74, 0x0d, 0x0a /* janet.. */ +}; + +static int server_nlst_download1_response_size = 57; + + +static char nlst_complete_226_response[24] = { +0x32, 0x32, /* C.:P..22 */ +0x36, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, /* 6 Transf */ +0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, /* er compl */ +0x65, 0x74, 0x65, 0x2e, 0x0d, 0x0a /* ete... */ +}; + +static int nlst_complete_226_response_size = 24; + +static char type_I_200_response[19] = { +0x32, 0x30, /* D.z...20 */ +0x30, 0x20, 0x54, 0x79, 0x70, 0x65, 0x20, 0x73, /* 0 Type s */ +0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x49, 0x0d, /* et to I. */ +0x0a /* . */ +}; + +static int type_I_200_response_size = 19; + +static char pasv2_227_response[49] = { +0x32, 0x32, /* D.qN..22 */ +0x37, 0x20, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x69, /* 7 Enteri */ +0x6e, 0x67, 0x20, 0x50, 0x61, 0x73, 0x73, 0x69, /* ng Passi */ +0x76, 0x65, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x20, /* ve Mode */ +0x28, 0x31, 0x2c, 0x32, 0x2c, 0x33, 0x2c, 0x34, /* (1,2,3,4 */ +0x2c, 0x38, 0x32, 0x2c, 0x32, 0x36, 0x29, 0x0d, /* ,82,25)*/ +0x0a /* ... */ +}; + +static int pasv2_227_response_size = 49; + +static char stor_150_response[30] = { +0x31, 0x35, /* C.....15 */ +0x30, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, /* 0 Openin */ +0x67, 0x20, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, /* g BINARY */ +0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, /* connect */ +0x70, 0x6c, 0x0d, 0x0a /* pl.. */ +}; + +static int stor_150_response_size = 30; + +static char download_complete_226_response[24] = { +0x32, 0x32, /* C.:P..22 */ +0x36, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, /* 6 Transf */ +0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, /* er compl */ +0x65, 0x74, 0x65, 0x2e, 0x0d, 0x0a /* ete... */ +}; + +static int download_complete_226_response_size = 24; + +static char quit_221_response[24] = { +0x32, 0x32, /* 221 .... */ +0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, /* 1 Transf */ +0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, /* er compl */ +0x65, 0x74, 0x65, 0x2e, 0x0d, 0x0a /* ete... */ +}; + +static int quit_221_response_size = 24; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_file_write_fail_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the FTP Server. */ + + /* Create the main FTP server thread. */ + status = tx_thread_create(&server_thread, "FTP Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR 1!\n"); + test_control_return(1); + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "FTP Server Packet Pool", 700, + pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + { + printf("ERROR 2!\n"); + test_control_return(1); + } + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "FTP Server IP", + FTP_SERVER_ADDRESS, + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + { + printf("ERROR 3!\n"); + test_control_return(1); + } + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + + /* Set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR 4!\n"); + test_control_return(1); + } + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", PACKET_PAYLOAD, pointer, 20*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR 5!\n"); + test_control_return(1); + } + + pointer = pointer + 20*PACKET_PAYLOAD; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, DEMO_STACK_SIZE, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR 6!\n"); + test_control_return(1); + } + + pointer = pointer + DEMO_STACK_SIZE; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable TCP for client IP instance. */ + nx_tcp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + + return; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet, *recv_packet_ptr; +UINT packets_sent = 0; +UINT status; + + /* Let the server set up. */ + tx_thread_sleep(20); + + NX_PARAMETER_NOT_USED(thread_input); + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Now connect with the NetX FTP (IPv4) server on the control socket. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "User", "password", 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable passive mode. */ + status = nx_ftp_client_passive_mode_set(&ftp_client, NX_TRUE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Set directory to /Users/Test. This does not require the PASV command. */ + status = nx_ftp_client_directory_default_set(&ftp_client, "\\Users\\Test", 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Get directory listing (NLST) ; this is where the Client sends the PASV command and opens another data socket .*/ + status = nx_ftp_client_directory_listing_get(&ftp_client, "", &my_packet, 3 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + do + { + status = nx_ftp_client_directory_listing_continue(&ftp_client, &recv_packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + { + nx_packet_release(recv_packet_ptr); + } + + if (status == NX_FTP_END_OF_LISTING) + break; + + } while (status == NX_SUCCESS); + + /* Check for complete download. */ + if (status != NX_FTP_END_OF_LISTING) + { + error_counter++; + } + + /* Request a file downloaded. This sends PASV and STOR commands and opens another data socket. */ + status = nx_ftp_client_file_open(&ftp_client, "socket_tcp_client_recv2.pl", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + do + { + + /* Allocate an FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + error_counter++; + break; + } + + if (packets_sent < 2) + { + + /* Write ABCs into the packet payload */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + } + else + { + + /* Append data larger than TCP window size to trigger a failure during file write. */ + status = nx_packet_data_append(my_packet, zero_data_buffer, sizeof(zero_data_buffer), &client_pool, NX_NO_WAIT); + } + + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_NO_WAIT); + packets_sent++; + + if (status != NX_SUCCESS) + { + nx_packet_release(my_packet); + } + } while ((status == NX_SUCCESS) && (packets_sent < 3)); + + /* This does not send a command. The data port is closed and the client state set to CONNECTED. + The server initiates closing the data socket connection. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Delete the FTP client. */ + nx_ftp_client_delete(&ftp_client); +} + + +/* Define the helper FTP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: FTP File Write Fail Test.................................."); + + /* Check for earlier error. */ + if(error_counter) + { + error_counter++; + } + + /* Create a TCP socket as the FTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Create a secondary TCP socket as the FTP server passive mode connection. Do not bind a port yet */ + status = nx_tcp_socket_create(&server_ip, &server_socket_passive, "Passive Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Bind the TCP socket to the FTP control port. */ + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + ftp_test_initialize(); + + /* Let the client log in */ + + for (i = 0; i < LOGIN_RESPONSES; i++) + { + + status = nx_ftp_login_packet_send(&server_socket, 80, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + if (i != 2) + { + + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + } + + /* This is responding to CWD */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 0); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is responding to PASV */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80,1); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PASSIVE_PORT1, &server_socket_passive, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket_passive, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is NLST command after passive connection set up */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 2); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_ftp_response_packet_send(&server_socket_passive, 80, 3); + + /* Check status. */ + if (status) + { + error_counter++; + } + + nx_tcp_socket_disconnect(&(server_socket_passive), 100); + nx_tcp_server_socket_unaccept(&server_socket_passive); + nx_tcp_server_socket_unlisten(&server_ip, SERVER_PASSIVE_PORT1); + + status = nx_ftp_response_packet_send(&server_socket, 80, 4); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is the second TYPE command (TYPE I) */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is the second PASV request. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 6); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PASSIVE_PORT2, &server_socket_passive, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. We are assuming the server uses the same IP address, + although on real FTP servers this is not necessarily the case. */ + status = nx_tcp_server_socket_accept(&server_socket_passive, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is responding to the STOR command. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + + status = nx_ftp_response_packet_send(&server_socket, 80, 7); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is the file data packet */ + status = nx_tcp_socket_receive(&server_socket_passive, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* this is the second data packet */ + status = nx_tcp_socket_receive(&server_socket_passive, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 8); + + /* Check status. */ + if (status) + { + error_counter++; + } + + nx_tcp_socket_disconnect(&(server_socket_passive), 100); + nx_tcp_server_socket_unaccept(&server_socket_passive); + nx_tcp_server_socket_unlisten(&server_ip, SERVER_PASSIVE_PORT2); + + + /* this is the QUIT command. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 9); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Disconnect and delete the TCP socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 100); + + /* Check status. */ + if (status) + { + error_counter++; + } + + nx_tcp_socket_delete(&server_socket); + + /* Check invalid packet release count. */ + if (client_pool.nx_packet_pool_invalid_releases != 0) + { + error_counter++; + } + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; + + return; + +} + + +static void ftp_test_initialize() +{ + +/* Logging in responses */ + + ftp_login[0].ftp_response_pkt_data = &welcome_220_response[0]; + ftp_login[0].ftp_response_pkt_size = welcome_220_response_size ; + + ftp_login[1].ftp_response_pkt_data = &password_request_331[0]; + ftp_login[1].ftp_response_pkt_size = password_request_331_size ; + + ftp_login[2].ftp_response_pkt_data = &logged_in_230_response[0]; + ftp_login[2].ftp_response_pkt_size = logged_in_230_response_size ; + +/* Download data responses */ + ftp_response[0].ftp_response_pkt_data = &cwd_250_response[0]; + ftp_response[0].ftp_response_pkt_size = cwd_250_response_size ; + + + ftp_response[1].ftp_response_pkt_data = &pasv_nlst_227_response[0]; + ftp_response[1].ftp_response_pkt_size = pasv_nlst_227_response_size ; + + ftp_response[2].ftp_response_pkt_data = &nlst_complete_150_response[0]; + ftp_response[2].ftp_response_pkt_size = nlst_complete_150_response_size ; + + ftp_response[3].ftp_response_pkt_data = &server_nlst_download1_response[0]; + ftp_response[3].ftp_response_pkt_size = server_nlst_download1_response_size ; + + ftp_response[4].ftp_response_pkt_data = &nlst_complete_226_response[0]; + ftp_response[4].ftp_response_pkt_size = nlst_complete_226_response_size ; + + + ftp_response[5].ftp_response_pkt_data = &type_I_200_response[0]; + ftp_response[5].ftp_response_pkt_size = type_I_200_response_size ; + + ftp_response[6].ftp_response_pkt_data = &pasv2_227_response[0]; + ftp_response[6].ftp_response_pkt_size = pasv2_227_response_size ; + + ftp_response[7].ftp_response_pkt_data = &stor_150_response[0]; + ftp_response[7].ftp_response_pkt_size = stor_150_response_size ; + + ftp_response[8].ftp_response_pkt_data = &download_complete_226_response[0]; + ftp_response[8].ftp_response_pkt_size = download_complete_226_response_size ; + + ftp_response[9].ftp_response_pkt_data = &quit_221_response[0]; + ftp_response[9].ftp_response_pkt_size = quit_221_response_size ; +} + + + +static UINT nx_ftp_login_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *login_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &login_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the FTP response messages into the packet payload! */ + memcpy(login_packet -> nx_packet_prepend_ptr, ftp_login[packet_number].ftp_response_pkt_data, + ftp_login[packet_number].ftp_response_pkt_size); + + /* Adjust the write pointer. */ + login_packet -> nx_packet_length = ftp_login[packet_number].ftp_response_pkt_size; + login_packet -> nx_packet_append_ptr = login_packet -> nx_packet_prepend_ptr + login_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, login_packet, 100); + + /* Check the status. */ + if (status) + nx_packet_release(login_packet); + + return status; +} + + +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the FTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, ftp_response[packet_number].ftp_response_pkt_data, + ftp_response[packet_number].ftp_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = ftp_response[packet_number].ftp_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_file_write_fail_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP File Write Fail Test..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ftp_test/netx_ftp_client_invalid_username_password_length_test.c b/test/regression/ftp_test/netx_ftp_client_invalid_username_password_length_test.c new file mode 100644 index 00000000..1755076c --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_client_invalid_username_password_length_test.c @@ -0,0 +1,293 @@ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; +static UINT data_control_counter; + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; +static CHAR invalid_username[2048]; +static CHAR invalid_password[2048]; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_invalid_username_password_length_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + + data_control_counter = 0; +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Set the username. */ + for (i = 0; i < 2048; i++) + invalid_username[i] = 'u'; + + /* Now using invalid username to connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, invalid_username, "password", NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_FTP_FAILED) + error_counter++; + + /* Set the username. */ + for (i = 0; i < 2048; i++) + invalid_password[i] = 'p'; + + /* Now using invalid username to connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "username", invalid_password, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_FTP_FAILED) + error_counter++; + + status = nx_ftp_client_delete(&ftp_client); + if(status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + + UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Client Invalid Username Password Length Test.........."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_invalid_username_password_length_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Client Invalid Username Password Length Test..........N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_client_multiple_connection_responses_test.c b/test/regression/ftp_test/netx_ftp_client_multiple_connection_responses_test.c new file mode 100644 index 00000000..f185f795 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_client_multiple_connection_responses_test.c @@ -0,0 +1,426 @@ +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#else +#include "nx_ftp_client.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define PACKET_PAYLOAD 1518 + + +/* Define the ThreadX, NetX, and FileX object control blocks... */ + +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET server_socket_passive; +static TX_THREAD client_thread; +static TX_THREAD server_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server_ip; + +/* Define the NetX FTP object control block. */ + +static NX_FTP_CLIENT ftp_client; + + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; +static UINT client_thread_done = NX_FALSE; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +#define SERVER_PORT 21 +#define SERVER_PASSIVE_PORT1 21017 +#define SERVER_PASSIVE_PORT2 21018 + + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, UCHAR *data, UINT data_size); + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +/* There are for logging in */ +static UCHAR welcome_220_response_1[27] = { +0x32, 0x32, 0x30, 0x2d, 0x4d, 0x69, 0x63, 0x72, /* 220-Micr */ +0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x46, 0x54, /* osoft FT */ +0x50, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, /* PServic */ +0x65, 0x0d, 0x0a /* e.. */ +}; + +static UINT welcome_220_response_1_size = 27; + +static UCHAR welcome_220_response_2[21] = { +0x32, 0x32, 0x30, 0x20, 0x57, 0x69, 0x6e, 0x68, /* 220 Winh */ +0x6f, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x20, /* ost.com */ +0x46, 0x54, 0x50, 0x0d, 0x0a /* FTP.. */ +}; + +static UINT welcome_220_response_2_size = 21; + +static UCHAR password_request_331[23] = { +0x33, 0x33, 0x31, 0x20, 0x50, 0x61, 0x73, 0x73, /* 331 Pass */ +0x77, 0x6f, 0x72, 0x64, 0x20, 0x72, 0x65, 0x71, /* word req */ +0x75, 0x69, 0x72, 0x65, 0x64, 0x0d, 0x0a /* uired.. */ +}; + +static UINT password_request_331_size = 23; + +static UCHAR logged_in_230_response[21] = { +0x32, 0x33, 0x30, 0x20, 0x55, 0x73, 0x65, 0x72, /* 230 User */ +0x20, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x64, 0x20, /* logged */ +0x69, 0x6e, 0x2e, 0x0d, 0x0a /* in... */ +}; + +static UINT logged_in_230_response_size = 21; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_multiple_connection_response_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the FTP Server. */ + + /* Create the main FTP server thread. */ + status = tx_thread_create(&server_thread, "FTP Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "FTP Server Packet Pool", 700, + pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "FTP Server IP", + FTP_SERVER_ADDRESS, + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + + /* Set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", PACKET_PAYLOAD, pointer, 25*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 25*PACKET_PAYLOAD; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, DEMO_STACK_SIZE, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + DEMO_STACK_SIZE; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable TCP for client IP instance. */ + nx_tcp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + /* Let the server set up. */ + tx_thread_sleep(20); + + NX_PARAMETER_NOT_USED(thread_input); + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Now connect with the NetX FTP (IPv4) server on the control socket. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "equenet0_alpha1", "29Pi2A792N", 500); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Delete the FTP client. */ + nx_ftp_client_disconnect(&ftp_client, 0); + nx_ftp_client_delete(&ftp_client); + + client_thread_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: FTP Client Multiple Connection Response Test.............."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket as the FTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Create a secondary TCP socket as the FTP server passive mode connection. Do not bind a port yet */ + status = nx_tcp_socket_create(&server_ip, &server_socket_passive, "Passive Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Bind the TCP socket to the FTP control port. */ + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Send welcome response. */ + if (nx_ftp_response_packet_send(&server_socket, welcome_220_response_1, welcome_220_response_1_size)) + { + error_counter++; + } + if (nx_ftp_response_packet_send(&server_socket, welcome_220_response_2, welcome_220_response_2_size)) + { + error_counter++; + } + + /* Receive USER request message. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((status) || (memcmp(my_packet ->nx_packet_prepend_ptr, "USER equenet0_alpha1", sizeof("USER equenet0_alpha1") - 1))) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Send password required message. */ + if (nx_ftp_response_packet_send(&server_socket, password_request_331, password_request_331_size)) + { + error_counter++; + } + + /* Receive PASS request message. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((status) || (memcmp(my_packet ->nx_packet_prepend_ptr, "PASS 29Pi2A792N", sizeof("USER 29Pi2A792N") - 1))) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Send logged in message. */ + if (nx_ftp_response_packet_send(&server_socket, logged_in_230_response, logged_in_230_response_size)) + { + error_counter++; + } + + /* Wait for client thread. */ + while (client_thread_done == NX_FALSE) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + nx_tcp_socket_disconnect(&server_socket, 0); + nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; + + return; + +} + +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, UCHAR *data, UINT data_size) +{ + +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the FTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, data, data_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = data_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_multiple_connection_response_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Client Multiple Connection Response Test..............N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ftp_test/netx_ftp_client_packet_leak_test.c b/test/regression/ftp_test/netx_ftp_client_packet_leak_test.c new file mode 100644 index 00000000..3ce89cb3 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_client_packet_leak_test.c @@ -0,0 +1,358 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_packet_leak_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Check packet leak. */ + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + error_counter++; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Check packet leak. */ + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Check packet leak. */ + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + error_counter++; + + /* Get directory listing (NLST). */ + status = nx_ftp_client_directory_listing_get(&ftp_client, "", &my_packet, 200); + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + nx_packet_release(my_packet); + } + + do + { + /* Receive the next data packet. */ + status = nx_ftp_client_directory_listing_continue(&ftp_client, &my_packet, 200); + if (status == NX_SUCCESS) + { + nx_packet_release(my_packet); + } + + /* Check if this is the end of the download. */ + if (status == NX_FTP_END_OF_LISTING) + break; + + } while (status == NX_SUCCESS); + + /* Check packet leak. */ + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Check packet leak. */ + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Client Packet Leak Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the ftp Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* OK to restart the ftp Server. */ + status = nx_ftp_server_stop(&ftp_server); + status += nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_packet_leak_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Client Packet Leak Test...............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_client_pasv_denied.c b/test/regression/ftp_test/netx_ftp_client_pasv_denied.c new file mode 100644 index 00000000..0f7be20c --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_client_pasv_denied.c @@ -0,0 +1,670 @@ +/* This is a small demo of NetX FTP on the high-performance NetX TCP/IP stack. This demo + relies on ThreadX, NetX, and FileX to show a simple directory listing get from the client + in passive mode transfer, except the server refuses the passive mode request. */ + + + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#else +#include "nx_ftp_client.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define PACKET_PAYLOAD 1518 + + +/* Define the ThreadX, NetX, and FileX object control blocks... */ + +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET server_socket_passive; +static TX_THREAD client_thread; +static TX_THREAD server_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control block. */ +static NX_FTP_CLIENT ftp_client; + +typedef struct FTP_RESPONSE_STRUCT +{ + char *ftp_response_pkt_data; + int ftp_response_pkt_size; +} FTP_RESPONSE; + +#define NUM_RESPONSES 4 +static FTP_RESPONSE ftp_response[NUM_RESPONSES]; + +#define LOGIN_RESPONSES 3 +static FTP_RESPONSE ftp_login[LOGIN_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; + + +/* Define the memory area for the FileX RAM disk. */ + +UCHAR ram_disk_memory[32000]; +UCHAR ram_disk_sector_cache[512]; + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +#define SERVER_PORT 21 +#define SERVER_PASSIVE_PORT1 21017 +#define SERVER_PASSIVE_PORT2 21018 + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +VOID _fx_ram_driver(FX_MEDIA *media_ptr); + + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); +static UINT nx_ftp_login_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); +static void ftp_test_initialize(); + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +/* There are for logging in */ +static char welcome_220_response[21] = { +0x32, 0x32, 0x30, 0x20, 0x44, 0x20, 0x63, 0x6f, /* 220 ... */ +0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x75, /* mmand su */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int welcome_220_response_size = 21; + +static char password_request_331[17] = { +0x33, 0x33, 0x31, 0x20, /* 331 ... */ +0x30, 0x20, 0x43, 0x57, 0x44, 0x20, 0x63, 0x6f, /* 0 CWD co */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int password_request_331_size = 17; + +static char logged_in_230_response[13] = { +0x32, 0x33, 0x30, 0x20, 0x44, 0x20, 0x63, 0x6f, /* 230 ... */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int logged_in_230_response_size = 13; + + +/* These are for downloading information. */ +static char cwd_250_response[23] = { +0x32, 0x35, /* D0v...25 */ +0x30, 0x20, 0x43, 0x57, 0x44, 0x20, 0x63, 0x6f, /* 0 CWD co */ +0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x75, /* mmand su */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int cwd_250_response_size = 23; + +static char pasv_nlst_500_response[43] = { +0x35, 0x30, /* D.r...50 */ +0x30, 0x20, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x69, /* 0 Denied */ +0x6e, 0x67, 0x20, 0x50, 0x61, 0x73, 0x73, 0x69, /* ng Passi */ +0x76, 0x65, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x20, /* ve Mode */ +0x28, 0x31, 0x2c, 0x32, 0x2c, 0x33, 0x2c, 0x34, /* (1,2,3,4 */ +0x2c, 0x38, 0x32, 0x2c, 0x32, 0x35, 0x29, 0x0d, /* ,82,25)*/ +0x0a /* ... */ +}; + +static int pasv_nlst_500_response_size = 43; + + +static char quit_221_response[24] = { +0x32, 0x32, /* 221 .... */ +0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, /* 1 Transf */ +0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, /* er compl */ +0x65, 0x74, 0x65, 0x2e, 0x0d, 0x0a /* ete... */ +}; + +static int quit_221_response_size = 24; + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_pasv_denied_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the FTP Server. */ + + /* Create the main FTP server thread. */ + status = tx_thread_create(&server_thread, "FTP Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "FTP Server Packet Pool", 700, + pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "FTP Server IP", + FTP_SERVER_ADDRESS, + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + + /* Set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", PACKET_PAYLOAD, pointer, 25*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 25*PACKET_PAYLOAD; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, DEMO_STACK_SIZE, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + DEMO_STACK_SIZE; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable TCP for client IP instance. */ + nx_tcp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT status; + + /* Let the server set up. */ + tx_thread_sleep(20); + + NX_PARAMETER_NOT_USED(thread_input); + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Now connect with the NetX FTP (IPv4) server on the control socket. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "User", "password", 500); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Enable passive mode. */ + status = nx_ftp_client_passive_mode_set(&ftp_client, NX_TRUE); + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Set directory to /Users/Self. This does not require the PASV command. */ + status = nx_ftp_client_directory_default_set(&ftp_client, "\\Users\\Self", 100); + + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Get directory listing (NLST) ; this is where the Client sends the PASV command and opens another data socket .*/ + status = nx_ftp_client_directory_listing_get(&ftp_client, "", &my_packet, 100); + + /* The server refuses the PASV request so this should not succeed! */ + if (status == NX_SUCCESS) + { + + error_counter++; + } + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Delete the FTP client. */ + nx_ftp_client_delete(&ftp_client); + +} + + +/* Define the helper FTP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: FTP Passive Mode Transfer PASV Refused Test..............."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket as the FTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Create a secondary TCP socket as the FTP server passive mode connection. Do not bind a port yet */ + status = nx_tcp_socket_create(&server_ip, &server_socket_passive, "Passive Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Bind the TCP socket to the FTP control port. */ + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + ftp_test_initialize(); + + /* Let the client log in */ + + for (i = 0; i < LOGIN_RESPONSES; i++) + { + + status = nx_ftp_login_packet_send(&server_socket, 80, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + if (i != 2) + { + + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + } + } + + /* this is CWD */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Respond to CWD command. */ + status = nx_ftp_response_packet_send(&server_socket, 80, 0); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is the PASV request*/ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 1); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is the QUIT command. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 2); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Delete the TCP socket. */ + nx_tcp_socket_delete(&server_socket); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; + + return; + +} + + +static void ftp_test_initialize() +{ + +/* Logging in responses */ + + ftp_login[0].ftp_response_pkt_data = &welcome_220_response[0]; + ftp_login[0].ftp_response_pkt_size = welcome_220_response_size ; + + ftp_login[1].ftp_response_pkt_data = &password_request_331[0]; + ftp_login[1].ftp_response_pkt_size = password_request_331_size ; + + ftp_login[2].ftp_response_pkt_data = &logged_in_230_response[0]; + ftp_login[2].ftp_response_pkt_size = logged_in_230_response_size ; + +/* Download data responses */ + ftp_response[0].ftp_response_pkt_data = &cwd_250_response[0]; + ftp_response[0].ftp_response_pkt_size = cwd_250_response_size ; + + ftp_response[1].ftp_response_pkt_data = &pasv_nlst_500_response[0]; + ftp_response[1].ftp_response_pkt_size = pasv_nlst_500_response_size ; + + ftp_response[2].ftp_response_pkt_data = &quit_221_response[0]; + ftp_response[2].ftp_response_pkt_size = quit_221_response_size ; + + +} + + + +static UINT nx_ftp_login_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *login_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &login_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the FTP response messages into the packet payload! */ + memcpy(login_packet -> nx_packet_prepend_ptr, ftp_login[packet_number].ftp_response_pkt_data, + ftp_login[packet_number].ftp_response_pkt_size); + + /* Adjust the write pointer. */ + login_packet -> nx_packet_length = ftp_login[packet_number].ftp_response_pkt_size; + login_packet -> nx_packet_append_ptr = login_packet -> nx_packet_prepend_ptr + login_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, login_packet, 100); + + /* Check the status. */ + if (status) + nx_packet_release(login_packet); + + return status; +} + + +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ + +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the FTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, ftp_response[packet_number].ftp_response_pkt_data, + ftp_response[packet_number].ftp_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = ftp_response[packet_number].ftp_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_pasv_denied_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Passive Mode Transfer PASV Refused Test...............N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ftp_test/netx_ftp_client_pasv_file_read_test.c b/test/regression/ftp_test/netx_ftp_client_pasv_file_read_test.c new file mode 100644 index 00000000..376383a0 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_client_pasv_file_read_test.c @@ -0,0 +1,987 @@ +/* This is a small demo of NetX FTP on the high-performance NetX TCP/IP stack. This demo + relies on ThreadX, NetX, and FileX to show a simple file transfer from the server + to client, and a directory listing get, in passive transfer mode (PASV). */ + + + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#else +#include "nx_ftp_client.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define PACKET_PAYLOAD 1518 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ + +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET server_socket_passive; +static TX_THREAD client_thread; +static TX_THREAD server_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control block. */ +static NX_FTP_CLIENT ftp_client; + +typedef struct FTP_RESPONSE_STRUCT +{ + char *ftp_response_pkt_data; + int ftp_response_pkt_size; +} FTP_RESPONSE; + +#define NUM_RESPONSES 11 +static FTP_RESPONSE ftp_response[NUM_RESPONSES]; + +#define LOGIN_RESPONSES 3 +static FTP_RESPONSE ftp_login[LOGIN_RESPONSES]; + +/* Define the counters used in the demo application... */ +static UINT error_counter = 0; + +/* Define the memory area for the FileX RAM disk. */ + +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +#define SERVER_PORT 21 +#define SERVER_PASSIVE_PORT1 21017 +#define SERVER_PASSIVE_PORT2 21018 + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +VOID _fx_ram_driver(FX_MEDIA *media_ptr); + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); +static UINT nx_ftp_login_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); +static void ftp_test_initialize(); + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +/* There are for logging in */ +static char welcome_220_response[21] = { +0x32, 0x32, 0x30, 0x20, 0x44, 0x20, 0x63, 0x6f, /* 220 ... */ +0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x75, /* mmand su */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int welcome_220_response_size = 21; + +static char password_request_331[17] = { +0x33, 0x33, 0x31, 0x20, /* 331 ... */ +0x30, 0x20, 0x43, 0x57, 0x44, 0x20, 0x63, 0x6f, /* 0 CWD co */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int password_request_331_size = 17; + +static char logged_in_230_response[13] = { +0x32, 0x33, 0x30, 0x20, 0x44, 0x20, 0x63, 0x6f, /* 230 ... */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int logged_in_230_response_size = 13; + + +/* These are for downloading information. */ +static char cwd_250_response[23] = { +0x32, 0x35, /* D0v...25 */ +0x30, 0x20, 0x43, 0x57, 0x44, 0x20, 0x63, 0x6f, /* 0 CWD co */ +0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x75, /* mmand su */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int cwd_250_response_size = 23; + + +static char pasv_nlst_227_response[43] = { +0x32, 0x32, /* D.r...22 */ +0x37, 0x20, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x69, /* 7 Enteri */ +0x6e, 0x67, 0x20, 0x50, 0x61, 0x73, 0x73, 0x69, /* ng Passi */ +0x76, 0x65, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x20, /* ve Mode */ +0x28, 0x31, 0x2c, 0x32, 0x2c, 0x33, 0x2c, 0x34, /* (1,2,3,4 */ +0x2c, 0x38, 0x32, 0x2c, 0x32, 0x35, 0x29, 0x0d, /* ,82,25)*/ +0x0a /* ... */ +}; + +static int pasv_nlst_227_response_size = 43; + +static char nlst_complete_150_response[48] = { +0x31, 0x35, /* D.....15 */ +0x30, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, /* 0 Openin */ +0x61, 0x6e, 0x65, 0x74, 0x0d, 0x0a /* anet.. */ +}; + +static int nlst_complete_150_response_size = 48; + +static char server_nlst_download1_response[57] = { +0x74, 0x79, /* ...R..ty */ +0x70, 0x65, 0x3d, 0x63, 0x64, 0x69, 0x72, 0x3b, /* pe=cdir; */ +0x73, 0x69, 0x7a, 0x65, 0x3d, 0x30, 0x3b, 0x6d, /* size=0;m */ +0x6f, 0x64, 0x69, 0x66, 0x79, 0x3d, 0x32, 0x30, /* odify=20 */ +0x31, 0x36, 0x30, 0x37, 0x30, 0x32, 0x30, 0x30, /* 16070200 */ +0x63, 0x64, 0x65, 0x66, 0x6c, 0x6d, 0x70, 0x3b, /* cdeflmp; */ +0x20, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x5c, /* \Users\ */ +0x6a, 0x61, 0x6e, 0x65, 0x74, 0x0d, 0x0a /* janet.. */ +}; + +static int server_nlst_download1_response_size = 57; + + +static char nlst_complete_226_response[24] = { +0x32, 0x32, /* C.:P..22 */ +0x36, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, /* 6 Transf */ +0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, /* er compl */ +0x65, 0x74, 0x65, 0x2e, 0x0d, 0x0a /* ete... */ +}; + +static int nlst_complete_226_response_size = 24; + +static char type_I_200_response[19] = { +0x32, 0x30, /* D.z...20 */ +0x30, 0x20, 0x54, 0x79, 0x70, 0x65, 0x20, 0x73, /* 0 Type s */ +0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x49, 0x0d, /* et to I. */ +0x0a /* . */ +}; + +static int type_I_200_response_size = 19; + +static char pasv2_227_response[49] = { +0x32, 0x32, /* D.qN..22 */ +0x37, 0x20, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x69, /* 7 Enteri */ +0x6e, 0x67, 0x20, 0x50, 0x61, 0x73, 0x73, 0x69, /* ng Passi */ +0x76, 0x65, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x20, /* ve Mode */ +0x28, 0x31, 0x2c, 0x32, 0x2c, 0x33, 0x2c, 0x34, /* (1,2,3,4 */ +0x2c, 0x38, 0x32, 0x2c, 0x32, 0x36, 0x29, 0x0d, /* ,82,25)*/ +0x0a /* ... */ +}; + +static int pasv2_227_response_size = 49; + +static char retr_150_response[30] = { +0x31, 0x35, /* C.....15 */ +0x30, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, /* 0 Openin */ +0x67, 0x20, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, /* g BINARY */ +0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, /* connect */ +0x70, 0x6c, 0x0d, 0x0a /* pl.. */ +}; + +static int retr_150_response_size = 30; + +static char download_file[49] = { +0x23, 0x20, /* ...X..# */ +0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x61, /* Create a */ +0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, /* client */ +0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x20, 0x74, /* socket t */ +0x6f, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x20, 0x54, /* o make T */ +0x6f, 0x73, 0x65, 0x28, 0x24, 0x73, 0x6f, 0x63, /* ose($soc */ +0x6b, 0x20, 0x29, 0x3b, 0x3b, 0x0d, 0x0a /* k );;.. */ +}; + +static int download_file_size = 49; + +static char download_complete_226_response[24] = { +0x32, 0x32, /* C.:P..22 */ +0x36, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, /* 6 Transf */ +0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, /* er compl */ +0x65, 0x74, 0x65, 0x2e, 0x0d, 0x0a /* ete... */ +}; + +static int download_complete_226_response_size = 24; + + +static char quit_221_response[24] = { +0x32, 0x32, /* 221 .... */ +0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, /* 1 Transf */ +0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, /* er compl */ +0x65, 0x74, 0x65, 0x2e, 0x0d, 0x0a /* ete... */ +}; + +static int quit_221_response_size = 24; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_pasv_file_read_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the FTP Server. */ + + /* Create the main FTP server thread. */ + status = tx_thread_create(&server_thread, "FTP Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "FTP Server Packet Pool", 700, + pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "FTP Server IP", + FTP_SERVER_ADDRESS, + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + + /* Set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", PACKET_PAYLOAD, pointer, 8*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + 8*PACKET_PAYLOAD; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, DEMO_STACK_SIZE, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + pointer = pointer + DEMO_STACK_SIZE; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable TCP for client IP instance. */ + nx_tcp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet, *recv_packet_ptr; +UINT status; + + /* Let the server set up. */ + tx_thread_sleep(20); + + NX_PARAMETER_NOT_USED(thread_input); + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Now connect with the NetX FTP (IPv4) server on the control socket. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "User", "Password", 500); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Enable passive mode. */ + status = nx_ftp_client_passive_mode_set(&ftp_client, NX_TRUE); + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Set directory to /Users/Test. This does not require the PASV command. */ + status = nx_ftp_client_directory_default_set(&ftp_client, "\\Users\\Test", 200); + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Get directory listing (MLSD) ; this is where the Client sends the PASV command and opens another data socket .*/ + status = nx_ftp_client_directory_listing_get(&ftp_client, "", &my_packet, 300); + if (status != NX_SUCCESS) + { + + error_counter++; + } + + nx_packet_release(my_packet); + + do + { + status = nx_ftp_client_directory_listing_continue(&ftp_client, &recv_packet_ptr, 200); + if (status == NX_SUCCESS) + { + nx_packet_release(recv_packet_ptr); + } + + if (status == NX_FTP_END_OF_LISTING) + break; + + } while (status == NX_SUCCESS); + + /* Check for complete download. */ + if (status != NX_FTP_END_OF_LISTING) + { + error_counter++; + } + + /* Request a file downloaded. This sends PASV and RETR commands and opens another data socket. */ + status = nx_ftp_client_file_open(&ftp_client, "test_script.pl", NX_FTP_OPEN_FOR_READ, 500); + + if (status != NX_SUCCESS) + { + + error_counter++; + } + + do + { + status = nx_ftp_client_file_read(&ftp_client, &recv_packet_ptr, 500); + if (status == NX_SUCCESS) + { + nx_packet_release(recv_packet_ptr); + } + } while (status == NX_SUCCESS); + + /* Check for complete download. */ + if (status != NX_FTP_END_OF_FILE) + { + error_counter++; + } + + /* This does not send a command. The data socket is closed and the client state set to CONNECTED. + The server initiates closing the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; +} + + +/* Define the helper FTP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: FTP Passive Mode Transfer File Read Test.................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket as the FTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Create a secondary TCP socket as the FTP server passive mode connection. Do not bind a port yet */ + status = nx_tcp_socket_create(&server_ip, &server_socket_passive, "Passive Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the FTP control port. */ + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + ftp_test_initialize(); + + /* Let the client log in */ + + for (i = 0; i < LOGIN_RESPONSES; i++) + { + + status = nx_ftp_login_packet_send(&server_socket, 80, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + if (i != 2) + { + + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + } + } + + /* this is responding to CWD */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 0); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is responding to PASV */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 1); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PASSIVE_PORT1, &server_socket_passive, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. We are assuming the server uses the same IP address, + although on real FTP servers this is not necessarily the case. */ + status = nx_tcp_server_socket_accept(&server_socket_passive, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is NLST command after passive connection set up */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 2); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_ftp_response_packet_send(&server_socket_passive, 80, 3); + + /* Check status. */ + if (status) + { + error_counter++; + } + + nx_tcp_socket_disconnect(&(server_socket_passive), 100); + nx_tcp_server_socket_unaccept(&server_socket_passive); + nx_tcp_server_socket_unlisten(&server_ip, SERVER_PASSIVE_PORT1); + + status = nx_ftp_response_packet_send(&server_socket, 80, 4); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is the second TYPE command (TYPE I) */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is responding to the second PASV */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 6); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PASSIVE_PORT2, &server_socket_passive, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. We are assuming the server uses the same IP address, + although on real FTP servers this is not necessarily the case. */ + status = nx_tcp_server_socket_accept(&server_socket_passive, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is the RETR command */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 7); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Download the file. */ + + status = nx_ftp_response_packet_send(&server_socket_passive, 80, 8); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 9); + + /* Check status. */ + if (status) + { + error_counter++; + } + + nx_tcp_socket_disconnect(&(server_socket_passive), 100); + nx_tcp_server_socket_unaccept(&server_socket_passive); + nx_tcp_server_socket_unlisten(&server_ip, SERVER_PASSIVE_PORT2); + + /* this is the QUIT command */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 10); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Disconnect the server. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +static void ftp_test_initialize() +{ + +/* Logging in responses */ + + ftp_login[0].ftp_response_pkt_data = &welcome_220_response[0]; + ftp_login[0].ftp_response_pkt_size = welcome_220_response_size ; + + ftp_login[1].ftp_response_pkt_data = &password_request_331[0]; + ftp_login[1].ftp_response_pkt_size = password_request_331_size ; + + ftp_login[2].ftp_response_pkt_data = &logged_in_230_response[0]; + ftp_login[2].ftp_response_pkt_size = logged_in_230_response_size ; + +/* Download data responses */ + ftp_response[0].ftp_response_pkt_data = &cwd_250_response[0]; + ftp_response[0].ftp_response_pkt_size = cwd_250_response_size ; + + ftp_response[1].ftp_response_pkt_data = &pasv_nlst_227_response[0]; + ftp_response[1].ftp_response_pkt_size = pasv_nlst_227_response_size ; + + ftp_response[2].ftp_response_pkt_data = &nlst_complete_150_response[0]; + ftp_response[2].ftp_response_pkt_size = nlst_complete_150_response_size ; + + ftp_response[3].ftp_response_pkt_data = &server_nlst_download1_response[0]; + ftp_response[3].ftp_response_pkt_size = server_nlst_download1_response_size ; + + ftp_response[4].ftp_response_pkt_data = &nlst_complete_226_response[0]; + ftp_response[4].ftp_response_pkt_size = nlst_complete_226_response_size ; + + ftp_response[5].ftp_response_pkt_data = &type_I_200_response[0]; + ftp_response[5].ftp_response_pkt_size = type_I_200_response_size ; + + ftp_response[6].ftp_response_pkt_data = &pasv2_227_response[0]; + ftp_response[6].ftp_response_pkt_size = pasv2_227_response_size ; + + ftp_response[7].ftp_response_pkt_data = &retr_150_response[0]; + ftp_response[7].ftp_response_pkt_size = retr_150_response_size ; + + ftp_response[8].ftp_response_pkt_data = &download_file[0]; + ftp_response[8].ftp_response_pkt_size = download_file_size ; + + ftp_response[9].ftp_response_pkt_data = &download_complete_226_response[0]; + ftp_response[9].ftp_response_pkt_size = download_complete_226_response_size ; + + ftp_response[10].ftp_response_pkt_data = &quit_221_response[0]; + ftp_response[10].ftp_response_pkt_size = quit_221_response_size ; + +} + + + +static UINT nx_ftp_login_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *login_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &login_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the FTP response messages into the packet payload! */ + memcpy(login_packet -> nx_packet_prepend_ptr, ftp_login[packet_number].ftp_response_pkt_data, + ftp_login[packet_number].ftp_response_pkt_size); + + /* Adjust the write pointer. */ + login_packet -> nx_packet_length = ftp_login[packet_number].ftp_response_pkt_size; + login_packet -> nx_packet_append_ptr = login_packet -> nx_packet_prepend_ptr + login_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, login_packet, 100); + + /* Check the status. */ + if (status) + nx_packet_release(login_packet); + + return status; +} + + +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the FTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, ftp_response[packet_number].ftp_response_pkt_data, + ftp_response[packet_number].ftp_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = ftp_response[packet_number].ftp_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_pasv_file_read_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Passive Mode Transfer File Read Test..................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ftp_test/netx_ftp_client_pasv_file_write_test.c b/test/regression/ftp_test/netx_ftp_client_pasv_file_write_test.c new file mode 100644 index 00000000..3dd74158 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_client_pasv_file_write_test.c @@ -0,0 +1,1008 @@ +/* This is a small demo of NetX FTP on the high-performance NetX TCP/IP stack. This demo + relies on ThreadX, NetX, and FileX to show a simple file transfer from the client + to the server and a directory listing get using passive file transfer (PASV). */ + + + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#else +#include "nx_ftp_client.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define PACKET_PAYLOAD 1518 + + +/* Define the ThreadX, NetX, and FileX object control blocks... */ + +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET server_socket_passive; +static TX_THREAD client_thread; +static TX_THREAD server_thread; +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control block. */ +static NX_FTP_CLIENT ftp_client; + +typedef struct FTP_RESPONSE_STRUCT +{ + char *ftp_response_pkt_data; + int ftp_response_pkt_size; +} FTP_RESPONSE; + +#define NUM_RESPONSES 10 +static FTP_RESPONSE ftp_response[NUM_RESPONSES]; + +#define LOGIN_RESPONSES 3 +static FTP_RESPONSE ftp_login[LOGIN_RESPONSES]; + +/* Define the counters used in the demo application... */ + +static UINT error_counter = 0; + +/* Define the memory area for the FileX RAM disk. */ + +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +#define SERVER_PORT 21 +#define SERVER_PASSIVE_PORT1 21017 +#define SERVER_PASSIVE_PORT2 21018 + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern VOID _fx_ram_driver(FX_MEDIA *media_ptr); + +static void server_thread_entry(ULONG thread_input); +static void client_thread_entry(ULONG thread_input); +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); +static UINT nx_ftp_login_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); +static void ftp_test_initialize(); + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +/* There are for logging in */ +static char welcome_220_response[21] = { +0x32, 0x32, 0x30, 0x20, 0x44, 0x20, 0x63, 0x6f, /* 220 .... */ +0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x75, /* mmand su */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int welcome_220_response_size = 21; + +static char password_request_331[17] = { +0x33, 0x33, 0x31, 0x20, /* 331 .... */ +0x30, 0x20, 0x43, 0x57, 0x44, 0x20, 0x63, 0x6f, /* 0 CWD co */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int password_request_331_size = 17; + +static char logged_in_230_response[13] = { +0x32, 0x33, 0x30, 0x20, 0x44, 0x20, 0x63, 0x6f, /* 230 .... */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int logged_in_230_response_size = 13; + + +/* These are for downloading information. */ +static char cwd_250_response[23] = { +0x32, 0x35, /* D0v...25 */ +0x30, 0x20, 0x43, 0x57, 0x44, 0x20, 0x63, 0x6f, /* 0 CWD co */ +0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x75, /* mmand su */ +0x65, 0x74, 0x29, 0x0d, 0x0a /* et).. */ +}; + +static int cwd_250_response_size = 23; + + +static char pasv_nlst_227_response[43] = { +0x32, 0x32, /* D.r...22 */ +0x37, 0x20, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x69, /* 7 Enteri */ +0x6e, 0x67, 0x20, 0x50, 0x61, 0x73, 0x73, 0x69, /* ng Passi */ +0x76, 0x65, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x20, /* ve Mode */ +0x28, 0x31, 0x2c, 0x32, 0x2c, 0x33, 0x2c, 0x34, /* (1,2,3,4 */ +0x2c, 0x38, 0x32, 0x2c, 0x32, 0x35, 0x29, 0x0d, /* ,82,25)*/ +0x0a /* ... */ +}; + +static int pasv_nlst_227_response_size = 43; + +static char nlst_complete_150_response[48] = { +0x31, 0x35, /* D.....15 */ +0x30, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, /* 0 Openin */ +0x61, 0x6e, 0x65, 0x74, 0x0d, 0x0a /* anet.. */ +}; + +static int nlst_complete_150_response_size = 48; + +static char server_nlst_download1_response[57] = { +0x74, 0x79, /* ...R..ty */ +0x70, 0x65, 0x3d, 0x63, 0x64, 0x69, 0x72, 0x3b, /* pe=cdir; */ +0x73, 0x69, 0x7a, 0x65, 0x3d, 0x30, 0x3b, 0x6d, /* size=0;m */ +0x6f, 0x64, 0x69, 0x66, 0x79, 0x3d, 0x32, 0x30, /* odify=20 */ +0x31, 0x36, 0x30, 0x37, 0x30, 0x32, 0x30, 0x30, /* 16070200 */ +0x63, 0x64, 0x65, 0x66, 0x6c, 0x6d, 0x70, 0x3b, /* cdeflmp; */ +0x20, 0x5c, 0x55, 0x73, 0x65, 0x72, 0x73, 0x5c, /* \Users\ */ +0x6a, 0x61, 0x6e, 0x65, 0x74, 0x0d, 0x0a /* janet.. */ +}; + +static int server_nlst_download1_response_size = 57; + + +static char nlst_complete_226_response[24] = { +0x32, 0x32, /* C.:P..22 */ +0x36, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, /* 6 Transf */ +0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, /* er compl */ +0x65, 0x74, 0x65, 0x2e, 0x0d, 0x0a /* ete... */ +}; + +static int nlst_complete_226_response_size = 24; + +static char type_I_200_response[19] = { +0x32, 0x30, /* D.z...20 */ +0x30, 0x20, 0x54, 0x79, 0x70, 0x65, 0x20, 0x73, /* 0 Type s */ +0x65, 0x74, 0x20, 0x74, 0x6f, 0x20, 0x49, 0x0d, /* et to I. */ +0x0a /* . */ +}; + +static int type_I_200_response_size = 19; + +static char pasv2_227_response[49] = { +0x32, 0x32, /* D.qN..22 */ +0x37, 0x20, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x69, /* 7 Enteri */ +0x6e, 0x67, 0x20, 0x50, 0x61, 0x73, 0x73, 0x69, /* ng Passi */ +0x76, 0x65, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x20, /* ve Mode */ +0x28, 0x31, 0x2c, 0x32, 0x2c, 0x33, 0x2c, 0x34, /* (1,2,3,4 */ +0x2c, 0x38, 0x32, 0x2c, 0x32, 0x36, 0x29, 0x0d, /* ,82,25)*/ +0x0a /* ... */ +}; + +static int pasv2_227_response_size = 49; + +static char stor_150_response[30] = { +0x31, 0x35, /* C.....15 */ +0x30, 0x20, 0x4f, 0x70, 0x65, 0x6e, 0x69, 0x6e, /* 0 Openin */ +0x67, 0x20, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, /* g BINARY */ +0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, /* connect */ +0x70, 0x6c, 0x0d, 0x0a /* pl.. */ +}; + +static int stor_150_response_size = 30; + +static char download_complete_226_response[24] = { +0x32, 0x32, /* C.:P..22 */ +0x36, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, /* 6 Transf */ +0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, /* er compl */ +0x65, 0x74, 0x65, 0x2e, 0x0d, 0x0a /* ete... */ +}; + +static int download_complete_226_response_size = 24; + +static char quit_221_response[24] = { +0x32, 0x32, /* 221 .... */ +0x31, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, /* 1 Transf */ +0x65, 0x72, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, /* er compl */ +0x65, 0x74, 0x65, 0x2e, 0x0d, 0x0a /* ete... */ +}; + +static int quit_221_response_size = 24; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_pasv_file_write_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Set up the FTP Server. */ + + /* Create the main FTP server thread. */ + status = tx_thread_create(&server_thread, "FTP Server thread ", server_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR 1!\n"); + test_control_return(1); + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "FTP Server Packet Pool", 700, + pointer , 700*10); + + pointer = pointer + 700*10; + if (status) + { + printf("ERROR 2!\n"); + test_control_return(1); + } + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "FTP Server IP", + FTP_SERVER_ADDRESS, + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + { + printf("ERROR 3!\n"); + test_control_return(1); + } + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + + /* Set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR 4!\n"); + test_control_return(1); + } + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", PACKET_PAYLOAD, pointer, 8*PACKET_PAYLOAD); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR 5!\n"); + test_control_return(1); + } + + pointer = pointer + 8*PACKET_PAYLOAD; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1024, pointer, DEMO_STACK_SIZE, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR 6!\n"); + test_control_return(1); + } + + pointer = pointer + DEMO_STACK_SIZE; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + nx_arp_enable(&client_ip, (void *) pointer, 1024); + + pointer = pointer + 1024; + + /* Enable TCP for client IP instance. */ + nx_tcp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + + return; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet, *recv_packet_ptr; +UINT packets_sent = 0; +UINT status; + + /* Let the server set up. */ + tx_thread_sleep(20); + + NX_PARAMETER_NOT_USED(thread_input); + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Now connect with the NetX FTP (IPv4) server on the control socket. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "User", "password", 500); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable passive mode. */ + status = nx_ftp_client_passive_mode_set(&ftp_client, NX_TRUE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Set directory to /Users/Test. This does not require the PASV command. */ + status = nx_ftp_client_directory_default_set(&ftp_client, "\\Users\\Test", 200); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Get directory listing (NLST) ; this is where the Client sends the PASV command and opens another data socket .*/ + status = nx_ftp_client_directory_listing_get(&ftp_client, "", &my_packet, 300); + if (status != NX_SUCCESS) + { + error_counter++; + } + + do + { + status = nx_ftp_client_directory_listing_continue(&ftp_client, &recv_packet_ptr, 200); + if (status == NX_SUCCESS) + { + nx_packet_release(recv_packet_ptr); + } + + if (status == NX_FTP_END_OF_LISTING) + break; + + } while (status == NX_SUCCESS); + + /* Check for complete download. */ + if (status != NX_FTP_END_OF_LISTING) + { + error_counter++; + } + + /* Request a file downloaded. This sends PASV and STOR commands and opens another data socket. */ + status = nx_ftp_client_file_open(&ftp_client, "socket_tcp_client_recv2.pl", NX_FTP_OPEN_FOR_WRITE, 100); + if (status != NX_SUCCESS) + { + error_counter++; + } + + do + { + + /* Allocate an FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + error_counter++; + break; + } + + /* Write ABCs into the packet payload */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + status = nx_ftp_client_file_write(&ftp_client, my_packet, 500); + packets_sent++; + + if (status != NX_SUCCESS) + { + nx_packet_release(recv_packet_ptr); + } + } while ((status == NX_SUCCESS) && (packets_sent < 2)); + + /* This does not send a command. The data port is closed and the client state set to CONNECTED. + The server initiates closing the data socket connection. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Delete the FTP client. */ + nx_ftp_client_delete(&ftp_client); +} + + +/* Define the helper FTP server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: FTP Passive Mode Transfer File Write Test................."); + + /* Check for earlier error. */ + if(error_counter) + { + error_counter++; + } + + /* Create a TCP socket as the FTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Create a secondary TCP socket as the FTP server passive mode connection. Do not bind a port yet */ + status = nx_tcp_socket_create(&server_ip, &server_socket_passive, "Passive Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Bind the TCP socket to the FTP control port. */ + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + ftp_test_initialize(); + + /* Let the client log in */ + + for (i = 0; i < LOGIN_RESPONSES; i++) + { + + status = nx_ftp_login_packet_send(&server_socket, 80, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + if (i != 2) + { + + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + } + } + + /* This is responding to CWD */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 0); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is responding to PASV */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80,1); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PASSIVE_PORT1, &server_socket_passive, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket_passive, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is NLST command after passive connection set up */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 2); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_ftp_response_packet_send(&server_socket_passive, 80, 3); + + /* Check status. */ + if (status) + { + error_counter++; + } + + nx_tcp_socket_disconnect(&(server_socket_passive), 100); + nx_tcp_server_socket_unaccept(&server_socket_passive); + nx_tcp_server_socket_unlisten(&server_ip, SERVER_PASSIVE_PORT1); + + status = nx_ftp_response_packet_send(&server_socket, 80, 4); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is the second TYPE command (TYPE I) */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is the second PASV request. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 6); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PASSIVE_PORT2, &server_socket_passive, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. We are assuming the server uses the same IP address, + although on real FTP servers this is not necessarily the case. */ + status = nx_tcp_server_socket_accept(&server_socket_passive, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is responding to the STOR command. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + + status = nx_ftp_response_packet_send(&server_socket, 80, 7); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* this is the file data packet */ + status = nx_tcp_socket_receive(&server_socket_passive, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* this is the second data packet */ + status = nx_tcp_socket_receive(&server_socket_passive, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 8); + + /* Check status. */ + if (status) + { + error_counter++; + } + + nx_tcp_socket_disconnect(&(server_socket_passive), 100); + nx_tcp_server_socket_unaccept(&server_socket_passive); + nx_tcp_server_socket_unlisten(&server_ip, SERVER_PASSIVE_PORT2); + + + /* this is the QUIT command. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + status = nx_ftp_response_packet_send(&server_socket, 80, 9); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Disconnect and delete the TCP socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 100); + + /* Check status. */ + if (status) + { + error_counter++; + } + + nx_tcp_socket_delete(&server_socket); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; + + return; + +} + + +static void ftp_test_initialize() +{ + +/* Logging in responses */ + + ftp_login[0].ftp_response_pkt_data = &welcome_220_response[0]; + ftp_login[0].ftp_response_pkt_size = welcome_220_response_size ; + + ftp_login[1].ftp_response_pkt_data = &password_request_331[0]; + ftp_login[1].ftp_response_pkt_size = password_request_331_size ; + + ftp_login[2].ftp_response_pkt_data = &logged_in_230_response[0]; + ftp_login[2].ftp_response_pkt_size = logged_in_230_response_size ; + +/* Download data responses */ + ftp_response[0].ftp_response_pkt_data = &cwd_250_response[0]; + ftp_response[0].ftp_response_pkt_size = cwd_250_response_size ; + + + ftp_response[1].ftp_response_pkt_data = &pasv_nlst_227_response[0]; + ftp_response[1].ftp_response_pkt_size = pasv_nlst_227_response_size ; + + ftp_response[2].ftp_response_pkt_data = &nlst_complete_150_response[0]; + ftp_response[2].ftp_response_pkt_size = nlst_complete_150_response_size ; + + ftp_response[3].ftp_response_pkt_data = &server_nlst_download1_response[0]; + ftp_response[3].ftp_response_pkt_size = server_nlst_download1_response_size ; + + ftp_response[4].ftp_response_pkt_data = &nlst_complete_226_response[0]; + ftp_response[4].ftp_response_pkt_size = nlst_complete_226_response_size ; + + + ftp_response[5].ftp_response_pkt_data = &type_I_200_response[0]; + ftp_response[5].ftp_response_pkt_size = type_I_200_response_size ; + + ftp_response[6].ftp_response_pkt_data = &pasv2_227_response[0]; + ftp_response[6].ftp_response_pkt_size = pasv2_227_response_size ; + + ftp_response[7].ftp_response_pkt_data = &stor_150_response[0]; + ftp_response[7].ftp_response_pkt_size = stor_150_response_size ; + + ftp_response[8].ftp_response_pkt_data = &download_complete_226_response[0]; + ftp_response[8].ftp_response_pkt_size = download_complete_226_response_size ; + + ftp_response[9].ftp_response_pkt_data = &quit_221_response[0]; + ftp_response[9].ftp_response_pkt_size = quit_221_response_size ; +} + + + +static UINT nx_ftp_login_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *login_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &login_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the FTP response messages into the packet payload! */ + memcpy(login_packet -> nx_packet_prepend_ptr, ftp_login[packet_number].ftp_response_pkt_data, + ftp_login[packet_number].ftp_response_pkt_size); + + /* Adjust the write pointer. */ + login_packet -> nx_packet_length = ftp_login[packet_number].ftp_response_pkt_size; + login_packet -> nx_packet_append_ptr = login_packet -> nx_packet_prepend_ptr + login_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, login_packet, 100); + + /* Check the status. */ + if (status) + nx_packet_release(login_packet); + + return status; +} + + +static UINT nx_ftp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the FTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, ftp_response[packet_number].ftp_response_pkt_data, + ftp_response[packet_number].ftp_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = ftp_response[packet_number].ftp_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_client_pasv_file_write_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Passive Mode Transfer File Write Test.................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ftp_test/netx_ftp_commands_characters_test.c b/test/regression/ftp_test/netx_ftp_commands_characters_test.c new file mode 100644 index 00000000..09cf55c5 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_commands_characters_test.c @@ -0,0 +1,377 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG up_counter = 0; +static ULONG low_counter = 0; +static ULONG command_success_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_commands_characters_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + client_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_client; + + status = nx_ftp_client_directory_create(&ftp_client,"/abc", NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "Mkd /def", 8); + + *(my_packet -> nx_packet_prepend_ptr + 8) = 13; + *(my_packet -> nx_packet_prepend_ptr + 9) = 10; + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 10; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 10; + + + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + /* Wait for response from the FTP server. */ + status = nx_tcp_socket_receive(&(ftp_client.nx_ftp_client_control_socket), &my_packet, NX_IP_PERIODIC_RATE/2); + /* Determine if a packet was not received. */ + if (status) + error_counter++; + + client_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + status = nx_ftp_client_directory_default_set(&ftp_client, "/abc" ,NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + status = nx_ftp_client_directory_default_set(&ftp_client, "/def" ,NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Commands Characters Test.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) || (up_counter != 1) || (low_counter != 1) || (command_success_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *tcp_header_ptr; + UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && *message == 'M' ) + { + + if(!memcmp(message,"MKD /abc ",8)) + up_counter++; + else if(!memcmp(message,"Mkd /def ",8)) + { + low_counter++; + server_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if((packet_ptr -> nx_packet_length > 23) && (!memcmp(message,"200",3))) + command_success_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_commands_characters_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Commands Characters Test..............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_commands_replys_test.c b/test/regression/ftp_test/netx_ftp_commands_replys_test.c new file mode 100644 index 00000000..ab3e3dc9 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_commands_replys_test.c @@ -0,0 +1,444 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UCHAR command_counter[7]; +static UCHAR reply_counter[7]; +static ULONG reply_specified = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_commands_replys_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UCHAR *temp; +UINT i; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + + client_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_client; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "NOOP ",5); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 5; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 5; + + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + /* Wait for response from the FTP server. */ + status = nx_tcp_socket_receive(&(ftp_client.nx_ftp_client_control_socket), &my_packet, NX_IP_PERIODIC_RATE/2); + /* Determine if a packet was not received. */ + if (status) + error_counter++; + else + { + /*Check if the reply is defined to contain the 3-digit code, followed by Space, followed by one line of text */ + temp = my_packet->nx_packet_prepend_ptr; + if ((*temp >= '0' && *temp <= '9') && + (*(temp + 1) >= '0' && *(temp + 1) <= '9') && + (*(temp + 2) >= '0' && *(temp + 2) <= '9') && + (*(temp +3) == ' ') && + (*(temp + 4) >= 65 && *(temp + 4) <= 122)) + reply_specified++; + } + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Now open the same file for reading. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Read the file. */ + status = nx_ftp_client_file_read(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Close this file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + client_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + for(i = 0;i < 7; i++) + { + if((command_counter[i] != NX_TRUE) || (reply_counter[i] != NX_TRUE)) + error_counter++; + } + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Reply Standard and Minimum Implementation Test........"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + server_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) || (reply_specified != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *tcp_header_ptr; + UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check if our host can accept these commands*/ + if(!memcmp(message,"USER ",5)) + command_counter[0] = NX_TRUE; + else if(!memcmp(message,"PORT ",5)) + command_counter[1] = NX_TRUE; + else if(!memcmp(message,"TYPE ",5)) + command_counter[2] = NX_TRUE; + else if(!memcmp(message,"RETR ",5)) + command_counter[3] = NX_TRUE; + else if(!memcmp(message,"STOR ",5)) + command_counter[4] = NX_TRUE; + else if(!memcmp( message,"NOOP ",5)) + command_counter[5] = NX_TRUE; + else if(!memcmp( message,"QUIT",4)) + command_counter[6] = NX_TRUE; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check if our host can accept these commands successfully*/ + if(!memcmp(message,"230 Logged in",13)) + reply_counter[0] = NX_TRUE; + else if(!memcmp(message,"200 Port set",12)) + reply_counter[1] = NX_TRUE; + else if(!memcmp(message,"200 Type Binary",15)) + reply_counter[2] = NX_TRUE; + else if(!memcmp(message,"250 File Sent",13)) + reply_counter[3] = NX_TRUE; + else if(!memcmp(message,"250 File Written ",16)) + reply_counter[4] = NX_TRUE; + else if(!memcmp( message,"200 NOOP Success",16)) + reply_counter[5] = NX_TRUE; + else if(!memcmp( message,"221 Logging Off",15)) + reply_counter[6] = NX_TRUE; + /* Check if any command cause a wrong reply information*/ + else if (*message == '5' && *(message + 3) == ' ') + error_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_commands_replys_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Reply Standard and Minimum Implementation Test........N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_control_connection_test.c b/test/regression/ftp_test/netx_ftp_control_connection_test.c new file mode 100644 index 00000000..e5f1bc74 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_control_connection_test.c @@ -0,0 +1,294 @@ +/* No.5 The control connection is used for the transfer of commands. + rfc959, page 9, 3. DATA TRANSFER FUNCTIONS */ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_control_connection_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* If after closing the client data socket we can also successfully transfer FTP commands, then we can make sure that the The control connection is used for the transfer of commands.*/ + status = nx_tcp_socket_disconnect(&(ftp_client.nx_ftp_client_data_socket), NX_IP_PERIODIC_RATE); + if(status != NX_NOT_CONNECTED && status != NX_SUCCESS) + error_counter++; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Control Connection Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_control_connection_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Control Connection Test...............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_data_connection_test.c b/test/regression/ftp_test/netx_ftp_data_connection_test.c new file mode 100644 index 00000000..07bcdfbf --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_data_connection_test.c @@ -0,0 +1,367 @@ +/* No.4 Files are transferred only via the data connection. + rfc959, page 9, 3. DATA TRANSFER FUNCTIONS */ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; +static UINT data_control_counter; + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_data_connection_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + + data_control_counter = 0; +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Now open the same file for reading. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Read the file. */ + status = nx_ftp_client_file_read(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + data_control_counter++; + nx_packet_release(my_packet); + } + /* Close this file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* If after closing the client data socket we can also successfully transfer FTP commands, then we can make sure that the The control connection is used for the transfer of commands.*/ + status = nx_tcp_socket_disconnect(&(ftp_client.nx_ftp_client_data_socket), NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + ftp_client.nx_ftp_client_data_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + + nx_tcp_client_socket_unbind(&(ftp_client.nx_ftp_client_data_socket)); + /* Check for error. */ + if(status) + error_counter++; + + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&ftp_client.nx_ftp_client_data_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the data socket connection we can find that we cannot successfully transfer the files. */ + /* Read the file. */ + status = nx_ftp_client_file_read(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE); + if (status == NX_NOT_BOUND) + data_control_counter++; + else + { + nx_packet_release(my_packet); + } + + /* Close this file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + + UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Data Connection Test.................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter != 0) || (data_control_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_data_connection_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Data Connection Test..................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_disconnection_event_test.c b/test/regression/ftp_test/netx_ftp_disconnection_event_test.c new file mode 100644 index 00000000..34517904 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_disconnection_event_test.c @@ -0,0 +1,312 @@ +/* Clent sends NLST and disconnets data socket. */ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_disconnection_event_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet, *recv_packet_ptr; +UINT packets_sent = 0; +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Enable passive mode. */ + status = nx_ftp_client_passive_mode_set(&ftp_client, NX_TRUE); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + /* Send NLST command. The direcotory doesn't exist, should returen error and disconnect the data socket. */ + status = nx_ftp_client_directory_listing_get(&ftp_client, "/test", &recv_packet_ptr, NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + { + error_counter++; + nx_packet_release(recv_packet_ptr); + } + + /* Let server processing disconnetion event. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Resume server thread. */ + tx_thread_resume(&server_thread); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Resume server thread. */ + tx_thread_resume(&server_thread); +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + + UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Disconnection Evnet Test.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + tx_thread_suspend(&server_thread); + + /* Only 4 control sockets should exist, all the data sockets need to be deleted. */ + if (server_ip.nx_ip_tcp_created_sockets_count > 4) + error_counter++; + + /* Wait for test. */ + tx_thread_suspend(&server_thread); + + /* Only 4 control sockets should exist, all the data sockets need to be deleted. */ + if (server_ip.nx_ip_tcp_created_sockets_count > 4) + error_counter++; + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_disconnection_event_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Disconnection Event Test..............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_establish_data_connection_03_test.c b/test/regression/ftp_test/netx_ftp_establish_data_connection_03_test.c new file mode 100644 index 00000000..b8e6a62b --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_establish_data_connection_03_test.c @@ -0,0 +1,422 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG port_change_counter = 0; +static ULONG data_port_default = 0; +static UINT data_port = 0; +static UINT server_not_change_count = 0; +static NX_PACKET *my_packet; +static UCHAR buffer_ptr[30] = " "; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_establish_data_connection_03_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + data_port_default = ftp_client.nx_ftp_client_data_port; + + /* Pickup the next free port for the data socket. */ + if (ftp_client.nx_ftp_client_data_port >= NX_MAX_PORT) + { + + status = nx_tcp_free_port_find(ftp_client.nx_ftp_client_ip_ptr, + ftp_client.nx_ftp_client_control_socket.nx_tcp_socket_port, &data_port); + + if (data_port <= ftp_client.nx_ftp_client_control_socket.nx_tcp_socket_port) + { + + status = NX_NO_FREE_PORTS; + } + } + else + { + + /* Try to increment the data port by one. */ + status = nx_tcp_free_port_find(ftp_client.nx_ftp_client_ip_ptr, + ftp_client.nx_ftp_client_data_port + 2, &data_port); + + if (data_port <= ftp_client.nx_ftp_client_control_socket.nx_tcp_socket_port) + { + + status = nx_tcp_free_port_find(ftp_client.nx_ftp_client_ip_ptr, + ftp_client.nx_ftp_client_control_socket.nx_tcp_socket_port, &data_port); + + if (data_port <= ftp_client.nx_ftp_client_control_socket.nx_tcp_socket_port) + { + + status = NX_NO_FREE_PORTS; + } + } + } + + if(status) + error_counter++; + + client_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_client; + + /* Let the Server change the port */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + if(ftp_client.nx_ftp_client_data_port == data_port_default) + server_not_change_count++; + + nx_packet_release(my_packet); + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if ((status != 0) && (status != NX_FTP_EXPECTED_2XX_CODE)) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; +ULONG ip_address; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Change Default Port Test......................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&server_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + ip_address = ftp_server.nx_ftp_server_ip_ptr->nx_ip_address; + + buffer_ptr[0] = (UCHAR)'P'; + buffer_ptr[1] = (UCHAR)'O'; + buffer_ptr[2] = (UCHAR)'R'; + buffer_ptr[3] = (UCHAR)'T'; + buffer_ptr[4] = (UCHAR)' '; + + buffer_ptr[5] = (UCHAR)('0' + (ip_address >> 24)/100); + buffer_ptr[6] = (UCHAR)('0' + ((ip_address >> 24)/10)%10); + buffer_ptr[7] = (UCHAR)('0' + (ip_address >> 24)%10); + buffer_ptr[8] = ','; + + buffer_ptr[9] = (UCHAR)('0' + ((ip_address >> 16) & 0xFF)/100); + buffer_ptr[10] = (UCHAR)('0' + (((ip_address >> 16) & 0xFF)/10)%10); + buffer_ptr[11] = (UCHAR)('0' + ((ip_address >> 16) & 0xFF)%10); + buffer_ptr[12] = (UCHAR)','; + + buffer_ptr[13] = (UCHAR)('0' + ((ip_address >> 8) & 0xFF)/100); + buffer_ptr[14] = (UCHAR)('0' + (((ip_address >> 8) & 0xFF)/10)%10); + buffer_ptr[15] = (UCHAR)('0' + ((ip_address >> 8) & 0xFF)%10); + buffer_ptr[16] = (UCHAR)','; + + buffer_ptr[17] = (UCHAR)('0' + (ip_address & 0xFF)/100); + buffer_ptr[18] = (UCHAR)('0' + ((ip_address & 0xFF)/10)%10); + buffer_ptr[19] = (UCHAR)('0' + (ip_address & 0xFF)%10); + buffer_ptr[20] = (UCHAR)','; + + buffer_ptr[21] = (UCHAR)('0' + (data_port >> 8)/100); + buffer_ptr[22] = (UCHAR)('0' + ((data_port >> 8)/10)%10); + buffer_ptr[23] = (UCHAR)('0' + ((data_port >> 8)%10)); + buffer_ptr[24] = ','; + + buffer_ptr[25] = (UCHAR)('0' + (data_port & 255)/100); + buffer_ptr[26] = (UCHAR)('0' + ((data_port & 255)/10)%10); + buffer_ptr[27] = (UCHAR)('0' + ((data_port & 255)%10)); + + /* Set the CR/LF. */ + buffer_ptr[28] = 13; + buffer_ptr[29] = 10; + + + + /* Change the port to the one we found.. */ + memcpy(my_packet -> nx_packet_prepend_ptr, buffer_ptr, 30); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 30; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 30; + + status = nx_tcp_socket_send(&ftp_server.nx_ftp_server_client_list[0].nx_ftp_client_request_control_socket, my_packet, NX_IP_PERIODIC_RATE/2); + if(status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) || (server_not_change_count != 1) || (port_change_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check the packet is a SYN one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (*message == 'P') && (*(message+1) == 'O')) + { + if(!memcmp(message,buffer_ptr,28)) + port_change_counter++; + + /* Deal packets with default routing. */ + client_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_establish_data_connection_03_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Change Default Port Test.......................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/ftp_test/netx_ftp_establish_data_connection_05_test.c b/test/regression/ftp_test/netx_ftp_establish_data_connection_05_test.c new file mode 100644 index 00000000..633409e6 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_establish_data_connection_05_test.c @@ -0,0 +1,303 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG control_disconnect_counter = 0; +static ULONG server_disconnect_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_establish_data_connection_05_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Make a situation that the control connection is closed legally */ + nx_tcp_socket_disconnect(&(ftp_client.nx_ftp_client_control_socket), NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + nx_tcp_client_socket_unbind(&(ftp_client.nx_ftp_client_control_socket)); + if (status) + error_counter++; + + if(ftp_client.nx_ftp_client_control_socket.nx_tcp_socket_state == NX_TCP_CLOSED) + control_disconnect_counter++; + + if(ftp_client.nx_ftp_client_data_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + server_disconnect_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Close Data Connection 05 Test.................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) || (control_disconnect_counter != 1) || (server_disconnect_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_establish_data_connection_05_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Close Data Connection 05 Test..................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ftp_test/netx_ftp_establish_data_connection_06_test.c b/test/regression/ftp_test/netx_ftp_establish_data_connection_06_test.c new file mode 100644 index 00000000..c9236e4a --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_establish_data_connection_06_test.c @@ -0,0 +1,337 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG eof_counter = 0; +static UINT test_done = NX_FALSE; + + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_establish_data_connection_06_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Now open the same file for reading. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Read the file. */ + status = nx_ftp_client_file_read(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Read the file. */ + status = nx_ftp_client_file_read(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE); + + if (status == NX_FTP_END_OF_FILE) + { + eof_counter++; + } + else + error_counter++; + + if(ftp_client.nx_ftp_client_data_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) + error_counter++; + + /* Close this file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Close Data Connection 06 Test.................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter !=0) && ( eof_counter == 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_establish_data_connection_06_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Close Data Connection 06 Test..................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_establish_data_connection_08_test.c b/test/regression/ftp_test/netx_ftp_establish_data_connection_08_test.c new file mode 100644 index 00000000..ce852f94 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_establish_data_connection_08_test.c @@ -0,0 +1,340 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG server_reply_counter = 0; +static UINT test_done = NX_FALSE; + + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_establish_data_connection_08_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + client_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_client; + + /* Close this file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + if(ftp_client.nx_ftp_client_data_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Close Data Connection 08 Test.................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) && ( server_reply_counter != 1 )) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *tcp_header_ptr; + UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check the packet is a SYN one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (*message >= '0') && (*(message) <= '9')) + { + if((!memcmp(message,"250",3)) || (!memcmp(message,"226",3)) ) + server_reply_counter++; + + /* Deal packets with default routing. */ + client_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_establish_data_connection_08_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Close Data Connection 08 Test..................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_ipv6_epsv_test.c b/test/regression/ftp_test/netx_ftp_ipv6_epsv_test.c new file mode 100644 index 00000000..a0f131cf --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_ipv6_epsv_test.c @@ -0,0 +1,467 @@ +/* Clent sends EPSV twice. */ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_RESET_DISCONNECT) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define NetX Duo IP address for the NetX Duo FTP Server and Client. */ +static NXD_ADDRESS server_ip_address; +static NXD_ADDRESS client_ip_address; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login6(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, NXD_ADDRESS *client_ipduo_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout6(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, NXD_ADDRESS *client_ipduo_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_ipv6_epsv_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nxd_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login6, server_logout6); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + /* Next set the NetX Duo FTP Server and Client addresses. */ + server_ip_address.nxd_ip_address.v6[3] = 0x105; + server_ip_address.nxd_ip_address.v6[2] = 0x0; + server_ip_address.nxd_ip_address.v6[1] = 0x0000f101; + server_ip_address.nxd_ip_address.v6[0] = 0x20010db8; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + + client_ip_address.nxd_ip_address.v6[3] = 0x101; + client_ip_address.nxd_ip_address.v6[2] = 0x0; + client_ip_address.nxd_ip_address.v6[1] = 0x0000f101; + client_ip_address.nxd_ip_address.v6[0] = 0x20010db8; + client_ip_address.nxd_ip_version = NX_IP_VERSION_V6; +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet, *recv_packet_ptr; +UINT status; +UINT iface_index, address_index; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Here's where we make the FTP Client IPv6 enabled. */ + status = nxd_ipv6_enable(&client_ip); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + status = nxd_icmp_enable(&client_ip); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Set the Client link local and global addresses. */ + iface_index = 0; + + /* This assumes we are using the primary network interface (index 0). */ + status = nxd_ipv6_address_set(&client_ip, iface_index, NX_NULL, 10, &address_index); + + /* Check for link local address set error. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Set the host global IP address. We are assuming a 64 + bit prefix here but this can be any value (< 128). */ + status = nxd_ipv6_address_set(&client_ip, iface_index, &client_ip_address, 64, &address_index); + + /* Check for global address set error. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Let NetX Duo validate the addresses. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nxd_ftp_client_connect(&ftp_client, &server_ip_address, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Enable passive mode. */ + status = nx_ftp_client_passive_mode_set(&ftp_client, NX_TRUE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* This sends EPSV commands and opens data socket. */ + _nx_ftp_client_passive_transfer_setup(&ftp_client, NX_IP_PERIODIC_RATE); + nx_tcp_socket_disconnect(&(ftp_client.nx_ftp_client_data_socket), NX_NO_WAIT); + nx_tcp_client_socket_unbind(&(ftp_client.nx_ftp_client_data_socket)); + + /* Request a file downloaded. This sends EPSV and STOR commands and opens another data socket. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, 100); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Allocate an FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Write ABCs into the packet payload */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + status = nx_ftp_client_file_write(&ftp_client, my_packet, 500); + if (status != NX_SUCCESS) + { + nx_packet_release(my_packet); + } + + /* This does not send a command. The data port is closed and the client state set to CONNECTED. + The server initiates closing the data socket connection. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Request a file downloaded. This sends EPSV and RETR commands and opens another data socket. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, 100); + if (status != NX_SUCCESS) + { + error_counter++; + } + + do + { + status = nx_ftp_client_file_read(&ftp_client, &recv_packet_ptr, 500); + if (status == NX_SUCCESS) + { + nx_packet_release(recv_packet_ptr); + } + } while (status == NX_SUCCESS); + + /* Check for complete download. */ + if (status != NX_FTP_END_OF_FILE) + { + error_counter++; + } + + /* This does not send a command. The data port is closed and the client state set to CONNECTED. + The server initiates closing the data socket connection. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Resume server thread. */ + tx_thread_resume(&server_thread); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + if (((UINT)packet_ptr -> nx_packet_prepend_ptr & 0x3) != 0) + { + error_counter++; + } + + return(NX_TRUE); +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +UINT iface_index, address_index; + + /* Print out test information banner. */ + printf("NetX Test: FTP IPv6 EPSV Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + packet_process_callback = my_packet_process; + + /* Here's where we make the FTP server IPv6 enabled. */ + status = nxd_ipv6_enable(&server_ip); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + status = nxd_icmp_enable(&server_ip); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Set the link local address with the host MAC address. */ + iface_index = 0; + + /* This assumes we are using the primary network interface (index 0). */ + status = nxd_ipv6_address_set(&server_ip, iface_index, NX_NULL, 10, &address_index); + + /* Check for link local address set error. */ + if (status) + { + error_counter++; + } + + /* Set the host global IP address. We are assuming a 64 + bit prefix here but this can be any value (< 128). */ + status = nxd_ipv6_address_set(&server_ip, iface_index, &server_ip_address, 64, &address_index); + + /* Check for global address set error. */ + if (status) + { + error_counter++; + } + + /* Wait while NetX Duo validates the link local and global address. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + tx_thread_suspend(&server_thread); + + /* Only 4 control sockets should exist, all the data sockets need to be deleted. */ + if (server_ip.nx_ip_tcp_created_sockets_count > 4) + error_counter++; + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login6(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, NXD_ADDRESS *client_ipduo_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout6(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, NXD_ADDRESS *client_ipduo_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_ipv6_epsv_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP IPv6 EPSV Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_parse_ipv6_address_test.c b/test/regression/ftp_test/netx_ftp_parse_ipv6_address_test.c new file mode 100644 index 00000000..32534225 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_parse_ipv6_address_test.c @@ -0,0 +1,118 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if defined(FEATURE_NX_IPV6) + +#define DEMO_STACK_SIZE 4096 + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; + +static TX_THREAD test_thread; +static void thread_test_entry(ULONG thread_input); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_parse_ipv6_address_test_application_define(void *first_unused_memory) +#endif +{ + +UCHAR *pointer; + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&test_thread, "FTP test thread", thread_test_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the helper FTP server thread. */ +void thread_test_entry(ULONG thread_input) +{ +UINT i; +UINT status; +UCHAR *buffer_ptr; +UCHAR valid_buffer[100]; + + + /* Print out test information banner. */ + printf("NetX Test: FTP Parse IPv6 Address Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + memset(valid_buffer, 0xFF, sizeof(valid_buffer)); + + /* Invalid colons 1. */ + buffer_ptr = "1:2:3:4:5:6:7:8:9:10"; + status = _nx_ftp_utility_parse_IPv6_address(buffer_ptr, 21, (NXD_ADDRESS *)(&valid_buffer)); + if (status != NX_FTP_INVALID_ADDRESS) + error_counter++; + + /* Invalid conlons 2. */ + buffer_ptr = "1:2:3:4:5:6::8:9:10"; + status = _nx_ftp_utility_parse_IPv6_address(buffer_ptr, 20, (NXD_ADDRESS *)(&valid_buffer)); + if (status != NX_FTP_INVALID_ADDRESS) + error_counter++; + + /* Invalid conlons 3. */ + buffer_ptr = "1:2:3::4:5:6:7:8"; + status = _nx_ftp_utility_parse_IPv6_address(buffer_ptr, 17, (NXD_ADDRESS *)(&valid_buffer)); + if (status != NX_FTP_INVALID_ADDRESS) + error_counter++; + + /* Check write overflow. */ + for (i = sizeof(NXD_ADDRESS); i < sizeof(valid_buffer); i++) + { + if (valid_buffer[i] != 0xFF) + { + error_counter++; + break; + } + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_parse_ipv6_address_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Parse IPv6 Address Test...............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_pasv_port_test.c b/test/regression/ftp_test/netx_ftp_pasv_port_test.c new file mode 100644 index 00000000..3e8733a4 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_pasv_port_test.c @@ -0,0 +1,321 @@ +/* Clent sends PASV and format of IP address and port in the response. */ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_pasv_port_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet, *recv_packet_ptr; +UCHAR buffer[] = "227 Entering Passive Mode (1,2,3,4,192,0).\r\n"; +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Enable passive mode. */ + status = nx_ftp_client_passive_mode_set(&ftp_client, NX_TRUE); + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* This sends PASV commands and opens data socket. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Write QUIT into the packet payload */ + memcpy(my_packet -> nx_packet_prepend_ptr, "PASV\r\n", 6); + my_packet -> nx_packet_length = 6; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 6; + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + nx_packet_release(my_packet); + } + + status = nx_tcp_socket_receive(&(ftp_client.nx_ftp_client_control_socket), &recv_packet_ptr, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + } + else + { + + /* Check if the format of IP address and port are correct. */ + if ((recv_packet_ptr -> nx_packet_length != (sizeof(buffer) - 1)) || + (memcmp(recv_packet_ptr -> nx_packet_prepend_ptr, buffer, sizeof(buffer) - 1) != 0)) + { + error_counter++; + } + + nx_packet_release(recv_packet_ptr); + } + + /* Disconnect the FTP client. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Resume server thread. */ + tx_thread_resume(&server_thread); +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + + UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP PASV Port Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + tx_thread_suspend(&server_thread); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_pasv_port_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP PASV Port Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_pasv_stor_test.c b/test/regression/ftp_test/netx_ftp_pasv_stor_test.c new file mode 100644 index 00000000..874e4588 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_pasv_stor_test.c @@ -0,0 +1,489 @@ +/* Test steps: + 1. Client sends STOR in passive mode; + 2. Client connects data socket and sends data; + 3. Client disconnects data socket; + 4. Client receives the response of STOR; + */ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_RESET_DISCONNECT) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_pasv_stor_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet, *recv_packet_ptr; +UINT status; +UCHAR *buffer_ptr; +UINT data_port; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Enable passive mode. */ + status = nx_ftp_client_passive_mode_set(&ftp_client, NX_TRUE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* This sends TYPE commands. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + memcpy(my_packet -> nx_packet_prepend_ptr, "TYPE I\r\n", 8); + my_packet -> nx_packet_length = 8; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Check response for PASV. */ + status = nx_tcp_socket_receive(&(ftp_client.nx_ftp_client_control_socket), &recv_packet_ptr, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + buffer_ptr = recv_packet_ptr -> nx_packet_prepend_ptr; + if ((recv_packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2')) + { + error_counter++; + } + nx_packet_release(recv_packet_ptr); + } + + /* This sends PASV commands. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + memcpy(my_packet -> nx_packet_prepend_ptr, "PASV\r\n", 6); + my_packet -> nx_packet_length = 6; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Check response for PASV. */ + status = nx_tcp_socket_receive(&(ftp_client.nx_ftp_client_control_socket), &recv_packet_ptr, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + buffer_ptr = recv_packet_ptr -> nx_packet_prepend_ptr; + if ((recv_packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2') || (buffer_ptr[1] != '2') || (buffer_ptr[2] != '7')) + { + error_counter++; + } + nx_packet_release(recv_packet_ptr); + } + +#ifdef __PRODUCT_NETXDUO__ + ftp_client.nx_ftp_client_data_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + ftp_client.nx_ftp_client_data_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = FTP_SERVER_ADDRESS; +#else + ftp_client.nx_ftp_client_data_socket.nx_tcp_socket_connect_ip = FTP_SERVER_ADDRESS; +#endif /* __PRODUCT_NETXDUO__ */ + data_port = ftp_server.nx_ftp_server_data_port - 1; + + /* This sends STOR commands. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + memcpy(my_packet -> nx_packet_prepend_ptr, "STOR test.txt\r\n", 15); + my_packet -> nx_packet_length = 15; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Bind the client data socket to any port. */ + status = nx_tcp_client_socket_bind((&ftp_client.nx_ftp_client_data_socket), NX_ANY_PORT, NX_IP_PERIODIC_RATE); + /* Check for an error. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Now connect to the IP address and port the server asked us to. */ +#ifdef __PRODUCT_NETXDUO__ + status = nxd_tcp_client_socket_connect(&(ftp_client.nx_ftp_client_data_socket), + &(ftp_client.nx_ftp_client_data_socket.nx_tcp_socket_connect_ip), + data_port, NX_IP_PERIODIC_RATE); +#else + status = nx_tcp_client_socket_connect(&(ftp_client.nx_ftp_client_data_socket), + ftp_client.nx_ftp_client_data_socket.nx_tcp_socket_connect_ip, + data_port, NX_IP_PERIODIC_RATE); +#endif /* __PRODUCT_NETXDUO__ */ + + /* Check for an error. */ + if (status != NX_SUCCESS) + { + error_counter++; + nx_tcp_client_socket_unbind(&(ftp_client.nx_ftp_client_data_socket)); + } + + /* Allocate an FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_data_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect the data socket. */ + _nx_ftp_client_data_socket_cleanup(&ftp_client, 50); + + /* Check response for STOR. */ + status = nx_tcp_socket_receive(&(ftp_client.nx_ftp_client_control_socket), &recv_packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + buffer_ptr = recv_packet_ptr -> nx_packet_prepend_ptr; + if ((recv_packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '1')) + { + error_counter++; + } + nx_packet_release(recv_packet_ptr); + } + + /* Check response for file write. */ + status = nx_tcp_socket_receive(&(ftp_client.nx_ftp_client_control_socket), &recv_packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + buffer_ptr = recv_packet_ptr -> nx_packet_prepend_ptr; + if ((recv_packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '2')) + { + error_counter++; + } + nx_packet_release(recv_packet_ptr); + } + + if (error_counter) + { + tx_thread_resume(&server_thread); + return; + } + + /* Check if file is stored in server. */ + /* Request a file downloaded. This sends PASV and RETR commands and opens another data socket. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, 100); + if (status != NX_SUCCESS) + { + error_counter++; + } + + do + { + status = nx_ftp_client_file_read(&ftp_client, &recv_packet_ptr, 500); + if (status == NX_SUCCESS) + { + nx_packet_release(recv_packet_ptr); + } + } while (status == NX_SUCCESS); + + /* Check for complete download. */ + if (status != NX_FTP_END_OF_FILE) + { + error_counter++; + } + + /* This does not send a command. The data port is closed and the client state set to CONNECTED. + The server initiates closing the data socket connection. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Resume server thread. */ + tx_thread_resume(&server_thread); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + if (((UINT)packet_ptr -> nx_packet_prepend_ptr & 0x3) != 0) + { + error_counter++; + } + + return(NX_TRUE); +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + + UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP PASV STOR Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + packet_process_callback = my_packet_process; + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + tx_thread_suspend(&server_thread); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_pasv_stor_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP PASV STOR Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_pasv_twice_test.c b/test/regression/ftp_test/netx_ftp_pasv_twice_test.c new file mode 100644 index 00000000..31a1fb65 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_pasv_twice_test.c @@ -0,0 +1,414 @@ +/* Clent sends PASV twice. */ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_RESET_DISCONNECT) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_pasv_twice_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet, *recv_packet_ptr; +UINT packets_sent = 0; +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Enable passive mode. */ + status = nx_ftp_client_passive_mode_set(&ftp_client, NX_TRUE); + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* This sends PASV commands and opens data socket. */ + _nx_ftp_client_passive_transfer_setup(&ftp_client, NX_IP_PERIODIC_RATE); + nx_tcp_socket_disconnect(&(ftp_client.nx_ftp_client_data_socket), NX_NO_WAIT); + nx_tcp_client_socket_unbind(&(ftp_client.nx_ftp_client_data_socket)); + + /* Request a file downloaded. This sends PASV and STOR commands and opens another data socket. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, 100); + if (status != NX_SUCCESS) + { + error_counter++; + } + + + /* Allocate an FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Write ABCs into the packet payload */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + status = nx_ftp_client_file_write(&ftp_client, my_packet, 500); + packets_sent++; + + if (status != NX_SUCCESS) + { + nx_packet_release(my_packet); + } + + /* This does not send a command. The data port is closed and the client state set to CONNECTED. + The server initiates closing the data socket connection. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Request a file downloaded. This sends PASV and RETR commands and opens another data socket. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, 100); + if (status != NX_SUCCESS) + { + error_counter++; + } + + do + { + status = nx_ftp_client_file_read(&ftp_client, &recv_packet_ptr, 500); + if (status == NX_SUCCESS) + { + nx_packet_release(recv_packet_ptr); + } + } while (status == NX_SUCCESS); + + /* Check for complete download. */ + if (status != NX_FTP_END_OF_FILE) + { + error_counter++; + } + + /* This does not send a command. The data port is closed and the client state set to CONNECTED. + The server initiates closing the data socket connection. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + tx_thread_resume(&server_thread); + + /* This sends PASV commands and opens data socket. */ + _nx_ftp_client_passive_transfer_setup(&ftp_client, NX_IP_PERIODIC_RATE); + nx_tcp_socket_disconnect(&(ftp_client.nx_ftp_client_data_socket), NX_NO_WAIT); + nx_tcp_client_socket_unbind(&(ftp_client.nx_ftp_client_data_socket)); + + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Write QUIT into the packet payload */ + memcpy(my_packet -> nx_packet_prepend_ptr, "QUIT\r\n", 6); + my_packet -> nx_packet_length = 6; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 6; + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Wait for response from the FTP server. */ + status = nx_tcp_socket_receive(&(ftp_client.nx_ftp_client_control_socket), &recv_packet_ptr, NX_IP_PERIODIC_RATE); + + /* Determine if a packet was not received. */ + if (status) + { + error_counter++; + } + else + { + nx_packet_release(my_packet); + } + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Disconnect from the server. */ + ftp_client.nx_ftp_client_state = NX_FTP_STATE_NOT_CONNECTED; + nx_tcp_socket_disconnect(&(ftp_client.nx_ftp_client_control_socket), NX_NO_WAIT); + nx_tcp_client_socket_unbind(&(ftp_client.nx_ftp_client_control_socket)); + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Resume server thread. */ + tx_thread_resume(&server_thread); +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + + UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP PASV Twice Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + tx_thread_suspend(&server_thread); + + /* Only 4 control sockets should exist, all the data sockets need to be deleted. */ + if (server_ip.nx_ip_tcp_created_sockets_count > 4) + error_counter++; + + /* Wait for test. */ + tx_thread_suspend(&server_thread); + + /* Only 4 control sockets should exist, all the data sockets need to be deleted. */ + if (server_ip.nx_ip_tcp_created_sockets_count > 4) + error_counter++; + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_pasv_twice_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP PASV Twice Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_rst_test.c b/test/regression/ftp_test/netx_ftp_rst_test.c new file mode 100644 index 00000000..f74ee0a2 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_rst_test.c @@ -0,0 +1,338 @@ +/* This case tests the FTP server on handling RST packet. + * JIRA: https://expresslogic.atlassian.net/browse/NETXDUO-235 + */ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#include +#include +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_RESET_DISCONNECT) + + + +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_server.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define LOOP 100 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD server_thread; +static NX_PACKET_POOL pool_server; +static NX_PACKET_POOL pool_client; +static NX_IP ip_server; +static NX_IP ip_client; +static TX_THREAD test_threads[NX_FTP_MAX_CLIENTS]; +static NX_TCP_SOCKET test_sockets[NX_FTP_MAX_CLIENTS]; +static UINT run_count[NX_FTP_MAX_CLIENTS]; +static UCHAR test_thread_stack[NX_FTP_MAX_CLIENTS][DEMO_STACK_SIZE]; +static TX_SEMAPHORE sema_0; + +/* Define FTP objects. */ + +static NX_FTP_SERVER ftp_server; +static FX_MEDIA ram_disk; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + +static UINT data_received; +static UCHAR send_buff[256]; +static UCHAR recv_buff[256]; + + +#define SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define function prototypes. */ + +static void thread_server_entry(ULONG thread_input); +static void thread_test_entry(ULONG thread_input); + +/* Replace the 'ram' driver with your actual Ethernet driver. */ +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _fx_ram_driver(FX_MEDIA *media_ptr); + + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_rst_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create packet pool. */ + status = nx_packet_pool_create(&pool_server, "Server NetX Packet Pool", 600, pointer, 8192); + pointer = pointer + 8192; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_server, "Server NetX IP Instance", SERVER_ADDRESS, + 0xFFFFFF00UL, &pool_server, _nx_ram_network_driver_512, + pointer, 4096, 1); + pointer = pointer + 4096; + if(status) + error_counter++; + + /* Create another packet pool. */ + status = nx_packet_pool_create(&pool_client, "Client NetX Packet Pool", 600, pointer, 8192); + pointer = pointer + 8192; + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_client, "Client NetX IP Instance", CLIENT_ADDRESS, + 0xFFFFFF00UL, &pool_client, _nx_ram_network_driver_512, + pointer, 4096, 1); + pointer = pointer + 4096; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_server, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_client, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_server); + status += nx_tcp_enable(&ip_client); + if(status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &ip_server, &ram_disk, pointer, DEMO_STACK_SIZE, &pool_server, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "Semaphore", 0); + if (status) + error_counter++; +} + +static void thread_test_entry(ULONG thread_input) +{ +NX_TCP_SOCKET *socket_ptr = &test_sockets[thread_input]; +UINT status; +UINT i; + + /* Create Client socket. */ + status = nx_tcp_socket_create(&ip_client, socket_ptr, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + error_counter++; + return; + } + + for (i = 0; i < LOOP; i++) + { + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(socket_ptr, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + break; + } + + status = nx_tcp_client_socket_connect(socket_ptr, SERVER_ADDRESS, NX_FTP_SERVER_CONTROL_PORT, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + break; + } + + nx_tcp_socket_disconnect(socket_ptr, NX_NO_WAIT); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(socket_ptr); + + /* Check for error. */ + if (status) + { + error_counter++; + break; + } + + run_count[thread_input]++; + } + + nx_tcp_socket_delete(socket_ptr); + tx_semaphore_put(&sema_0); +} + +/* Define the Server thread. */ +static void thread_server_entry(ULONG thread_input) +{ + +UINT i; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP RST Test.............................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* OK to start the ftp Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + for (i = 0; i < sizeof(test_threads) / sizeof(TX_THREAD); i++) + { + run_count[i] = 0; + tx_thread_create(&test_threads[i], "Test thread", thread_test_entry, i, + test_thread_stack[i], DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + } + + for (i = 0; i < sizeof(test_threads) / sizeof(TX_THREAD); i++) + { + if (tx_semaphore_get(&sema_0, 30 * NX_IP_PERIODIC_RATE)) + { + error_counter++; + break; + } + } + + for (i = 0; i < sizeof(test_threads) / sizeof(TX_THREAD); i++) + { + if (run_count[i] != LOOP) + { + error_counter++; + } + } + + status = nx_ftp_server_stop(&ftp_server); + if (status) + error_counter++; + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_rst_test_application_define(void *first_unused_memory) +#endif +{ + /* Print out test information banner. */ + printf("NetX Test: FTP RST Test..............................................N/A\n"); + test_control_return(3); +} +#endif + + diff --git a/test/regression/ftp_test/netx_ftp_server_abnormal_packet_test.c b/test/regression/ftp_test/netx_ftp_server_abnormal_packet_test.c new file mode 100644 index 00000000..eab6f20e --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_server_abnormal_packet_test.c @@ -0,0 +1,349 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +extern VOID _nx_ftp_server_command_present(NX_TCP_SOCKET *control_socket_ptr); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_server_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +static UCHAR valid_buffer[4]; +static UCHAR *valid_data_ptr = NX_NULL; +static VOID tcp_receive_callback(NX_TCP_SOCKET *tcp_socket) +{ +NX_PACKET *packet_ptr = tcp_socket -> nx_tcp_socket_receive_queue_head; +UCHAR *buffer_ptr; + + _nx_ftp_server_command_present(tcp_socket); + + if (!packet_ptr) + return; + + buffer_ptr = packet_ptr -> nx_packet_prepend_ptr; + if (buffer_ptr[20] == 'C') + { + + /* Move payload to the end of the packet. */ + memmove(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_length, buffer_ptr, packet_ptr -> nx_packet_length); + packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_length; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_data_end; + valid_data_ptr = packet_ptr -> nx_packet_data_end; + memcpy(valid_buffer, valid_data_ptr, sizeof(valid_buffer)); + } +} + +/* Define the FTP client thread. */ +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT status; +UCHAR *buffer_ptr; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate packet. */ + status = _nx_ftp_client_packet_allocate(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + ftp_server.nx_ftp_server_client_list[0].nx_ftp_client_request_control_socket.nx_tcp_receive_callback = tcp_receive_callback; + buffer_ptr = my_packet -> nx_packet_prepend_ptr; + + /* Build "CDUP" message. */ + buffer_ptr[0] = 'C'; + buffer_ptr[1] = 'D'; + buffer_ptr[2] = 'U'; + buffer_ptr[3] = 'P'; + buffer_ptr[4] = ' '; + + /* Set the packet length. */ + my_packet -> nx_packet_length = 5; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + /* Send the packet. */ + status = nx_tcp_socket_send(&(ftp_client.nx_ftp_client_control_socket), my_packet, NX_IP_PERIODIC_RATE); + if (status) + { + nx_packet_release(my_packet); + error_counter++; + test_done = NX_TRUE; + return; + } + + /* Wait for response from the FTP server. */ + status = nx_tcp_socket_receive(&(ftp_client.nx_ftp_client_control_socket), &my_packet, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + } + else + { + nx_packet_release(my_packet); + } + + /* Check if the buffer was modified. */ + if (valid_data_ptr) + { + if (memcmp(valid_buffer, valid_data_ptr, sizeof(valid_buffer)) != 0) + error_counter++; + } + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Abnormal Packet Test..........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the ftp Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* OK to restart the ftp Server. */ + status = nx_ftp_server_stop(&ftp_server); + status += nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_server_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Abnormal Packet Test...........................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_server_dangling_pointer_test.c b/test/regression/ftp_test/netx_ftp_server_dangling_pointer_test.c new file mode 100644 index 00000000..d09dc458 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_server_dangling_pointer_test.c @@ -0,0 +1,351 @@ +/* This test case focus on a bug that nx_ftp_client_request_packet will be released multiple times in NX_FTP_QUIT command process. */ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_PACKET_INFO) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_TCP_SOCKET client_socket; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT send_data(CHAR *data); + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_server_dangling_pinter_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "FTP Client Socket", NX_IP_NORMAL, + NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 512, NX_NULL, NX_NULL); + if (status) + error_counter++; + + for (i = 0; i <= NX_FTP_MAX_CLIENTS; i++) + { + + /* Bind to any port. */ + status = nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, NX_NO_WAIT); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_tcp_client_socket_connect(&client_socket, FTP_SERVER_ADDRESS, NX_FTP_SERVER_CONTROL_PORT, + NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = send_data("USER aaa\n"); + if (status) + error_counter++; + + status = send_data("PASS aaa\n"); + if (status) + error_counter++; + + if (i != NX_FTP_MAX_CLIENTS) + { + status = send_data("TYPE I\n"); + if (status) + error_counter++; + + status = send_data("STOR 1.txt\n"); + if (status) + error_counter++; + + status = send_data("RNFR 1.txt\n"); + if (status) + error_counter++; + } + + status = send_data("QUIT\n"); + if (status) + error_counter++; + + /* Disconnect from the server. */ + nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&client_socket); + } + + /* Cleanup the socket. */ + nx_tcp_client_socket_unbind(&client_socket); + nx_tcp_socket_delete(&client_socket); + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Dangling Pointer Test.........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the ftp Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* OK to restart the ftp Server. */ + status = nx_ftp_server_stop(&ftp_server); + status += nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + /* Make sure there is no invalid release. */ + if (server_pool.nx_packet_pool_invalid_releases) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT send_data(CHAR *data) +{ +UINT status; +NX_PACKET *packet_ptr; + + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + return(status); + + status = nx_packet_data_append(packet_ptr, data, strlen(data), &client_pool, NX_IP_PERIODIC_RATE); + if (status) + { + nx_packet_release(packet_ptr); + return(status); + } + + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE); + if (status) + { + nx_packet_release(packet_ptr); + return(status); + } + + /* Return success. */ + return(NX_SUCCESS); +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_server_dangling_pinter_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Dangling Pointer Test..........................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_server_invalid_month_crash_test.c b/test/regression/ftp_test/netx_ftp_server_invalid_month_crash_test.c new file mode 100644 index 00000000..7d5f3297 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_server_invalid_month_crash_test.c @@ -0,0 +1,740 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "fx_system.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT ftp_client_directory_listing_get(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_path, + NX_PACKET **packet_ptr, ULONG wait_option); + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT ftp_server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT ftp_server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_server_invalid_month_crash_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + ftp_server_login, ftp_server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT status, date; +ULONG packet_size = 0; + + + /* Make filex crashed. */ + date = _fx_system_date; + _fx_system_date = 0; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Fix the mistake. */ + _fx_system_date = date; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test1.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Send LIST command to get directory listing. */ + status = ftp_client_directory_listing_get(&ftp_client, "", &my_packet, 200); + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + packet_size += my_packet -> nx_packet_length; + nx_packet_release(my_packet); + } + do + { + /* Receive the next data packet. */ + status = nx_ftp_client_directory_listing_continue(&ftp_client, &my_packet, 200); + if (status == NX_SUCCESS) + { + packet_size += my_packet -> nx_packet_length; + nx_packet_release(my_packet); + } + } while (status == NX_SUCCESS); + + /* Check the packet size. */ + if (packet_size != 61) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Invalid Month Crash Test......................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the ftp Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* OK to restart the ftp Server. */ + status = nx_ftp_server_stop(&ftp_server); + status += nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT ftp_server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT ftp_server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + + +/* Send LIST command. */ +static UINT ftp_client_directory_listing_get(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_path, + NX_PACKET **packet_ptr, ULONG wait_option) +{ + +UINT i; +UINT data_port; +#ifndef NX_DISABLE_IPV4 +ULONG ip_address; +#endif /* NX_DISABLE_IPV4 */ +UCHAR *buffer_ptr; +NX_PACKET *new_packet_ptr; +UINT status; + + + /* Set packet pointer to NULL. */ + *packet_ptr = NX_NULL; + + /* Ensure the client is the proper state for directory listing request. */ + if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_CONNECTED) + return(NX_FTP_NOT_CONNECTED); + + /* Transfer the data in active transfer mode. */ + /* Pickup the next free port for the data socket. */ + nx_tcp_free_port_find(ftp_client_ptr -> nx_ftp_client_ip_ptr, + ftp_client_ptr -> nx_ftp_client_control_socket.nx_tcp_socket_port, &data_port); + + /* Start listening on the data port. */ + status = nx_tcp_server_socket_listen(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port, + &(ftp_client_ptr -> nx_ftp_client_data_socket), 5, 0); + + /* Determine if the listen is successful. */ + if (status) + { + + /* Return error. */ + return(status); + } + + /* Allocate a packet for sending the PORT command. */ + status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &new_packet_ptr, wait_option); + + /* Determine if the packet allocation was successful. */ + if (status) + { + + /* Stop listening on the data port. */ + nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port); + + /* Return error. */ + return(status); + } + + /* We have a packet, setup pointer to the buffer area. */ + buffer_ptr = new_packet_ptr -> nx_packet_prepend_ptr; + +#ifdef __PRODUCT_NETXDUO__ + if (ftp_client_ptr -> nx_ftp_client_control_socket.nx_tcp_socket_connect_ip.nxd_ip_version == NX_IP_VERSION_V6) + { +#ifndef FEATURE_NX_IPV6 + return NX_NOT_ENABLED; +#else + CHAR ipduo_buffer[NX_FTP_IPV6_ADDRESS_BUFSIZE]; + UINT index; + UINT ipduo_size; + + /* EPRT command: EPRT |2|1080::8:800:200C:417A|5282| + RFC2428, Section2, Page3. */ + + buffer_ptr[0] = 'E'; + buffer_ptr[1] = 'P'; + buffer_ptr[2] = 'R'; + buffer_ptr[3] = 'T'; + buffer_ptr[4] = ' '; + buffer_ptr[5] = '|'; + buffer_ptr[6] = '2'; + buffer_ptr[7] = '|'; + + /* Convert the PORT command ipv6 address and port number format to ascii text. */ + + /* Clear our scratch buffer. */ + memset(&ipduo_buffer[0], 0, NX_FTP_IPV6_ADDRESS_BUFSIZE); + + /* Convert the IPv6 address to text. */ + status = _nx_ftp_utility_convert_IPv6_to_ascii(&(ftp_client_ptr -> nx_ftp_client_control_socket), + &ipduo_buffer[0], NX_FTP_IPV6_ADDRESS_BUFSIZE, &ipduo_size); + + /* Append to the packet buffer . */ + memcpy(&buffer_ptr[8], ipduo_buffer, ipduo_size); + + /* Update the index past the IPv6 address. */ + index = 8 + ipduo_size; + + /* Add the required space character. */ + buffer_ptr[index++] = '|'; + + /* Clear the scratch buffer again. */ + memset(&ipduo_buffer[0], 0, NX_FTP_IPV6_ADDRESS_BUFSIZE); + + /* Convert the preferred port to ascii. */ + status = _nx_ftp_utility_convert_portnumber_ascii(data_port, &ipduo_buffer[0], &ipduo_size); + + /* Append to the packet buffer. */ + memcpy(&buffer_ptr[index], ipduo_buffer, ipduo_size); + + /* Update the index past the port. */ + index += ipduo_size; + + /* Add the required space character. */ + buffer_ptr[index++] = '|'; + + /* Set the CR/LF. */ + buffer_ptr[index++] = 13; + buffer_ptr[index++] = 10; + + /* Null terminate the string. */ + buffer_ptr[index] = 0; + + /* Set the packet length. */ + new_packet_ptr -> nx_packet_length = strlen((const char *)buffer_ptr); +#endif /* FEATURE_NX_IPV6*/ + } + else +#endif /* __PRODUCT_NETXDUO__ */ + { + +#ifdef NX_DISABLE_IPV4 + return NX_NOT_ENABLED; +#else + /* Pickup the IP address of this IP instance. */ + ip_address = (ftp_client_ptr -> nx_ftp_client_ip_ptr) -> nx_ip_address; + + /* Now build the IP and port number FTP message. */ + buffer_ptr[0] = (UCHAR)'P'; + buffer_ptr[1] = (UCHAR)'O'; + buffer_ptr[2] = (UCHAR)'R'; + buffer_ptr[3] = (UCHAR)'T'; + buffer_ptr[4] = (UCHAR)' '; + + buffer_ptr[5] = (UCHAR)('0' + (ip_address >> 24)/100); + buffer_ptr[6] = (UCHAR)('0' + ((ip_address >> 24)/10)%10); + buffer_ptr[7] = (UCHAR)('0' + (ip_address >> 24)%10); + buffer_ptr[8] = ','; + + buffer_ptr[9] = (UCHAR)('0' + ((ip_address >> 16) & 0xFF)/100); + buffer_ptr[10] = (UCHAR)('0' + (((ip_address >> 16) & 0xFF)/10)%10); + buffer_ptr[11] = (UCHAR)('0' + ((ip_address >> 16) & 0xFF)%10); + buffer_ptr[12] = (UCHAR)','; + + buffer_ptr[13] = (UCHAR)('0' + ((ip_address >> 8) & 0xFF)/100); + buffer_ptr[14] = (UCHAR)('0' + (((ip_address >> 8) & 0xFF)/10)%10); + buffer_ptr[15] = (UCHAR)('0' + ((ip_address >> 8) & 0xFF)%10); + buffer_ptr[16] = (UCHAR)','; + + buffer_ptr[17] = (UCHAR)('0' + (ip_address & 0xFF)/100); + buffer_ptr[18] = (UCHAR)('0' + ((ip_address & 0xFF)/10)%10); + buffer_ptr[19] = (UCHAR)('0' + (ip_address & 0xFF)%10); + buffer_ptr[20] = (UCHAR)','; + + buffer_ptr[21] = (UCHAR)('0' + (data_port >> 8)/100); + buffer_ptr[22] = (UCHAR)('0' + ((data_port >> 8)/10)%10); + buffer_ptr[23] = (UCHAR)('0' + ((data_port >> 8)%10)); + buffer_ptr[24] = ','; + + buffer_ptr[25] = (UCHAR)('0' + (data_port & 255)/100); + buffer_ptr[26] = (UCHAR)('0' + ((data_port & 255)/10)%10); + buffer_ptr[27] = (UCHAR)('0' + ((data_port & 255)%10)); + + /* Set the CR/LF. */ + buffer_ptr[28] = 13; + buffer_ptr[29] = 10; + + /* Set the packet length. */ + new_packet_ptr -> nx_packet_length = 30; +#endif /* NX_DISABLE_IPV4 */ + } + + /* Setup the packet append pointer. */ + new_packet_ptr -> nx_packet_append_ptr = new_packet_ptr -> nx_packet_prepend_ptr + new_packet_ptr -> nx_packet_length; + + /* Send the PORT message. */ + status = nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), new_packet_ptr, wait_option); + + /* Determine if the send was unsuccessful. */ + if (status) + { + + /* Stop listening on the data port. */ + nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port); + + /* Release the packet. */ + nx_packet_release(new_packet_ptr); + + /* Return error. */ + return(status); + } + + /* Wait for response from the FTP server. */ + status = nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &new_packet_ptr, wait_option); + + /* Determine if a packet was not received. */ + if (status) + { + + /* Stop listening on the data port. */ + nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port); + + /* Unable to send PORT command to FTP server. */ + return(status); + } + +#ifndef NX_DISABLE_PACKET_CHAIN + if (new_packet_ptr -> nx_packet_next) + { + + /* Release the packet. */ + nx_packet_release(new_packet_ptr); + + /* Stop listening on the data port. */ + nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port); + + /* Return. */ + return(NX_INVALID_PACKET); + } +#endif /* NX_DISABLE_PACKET_CHAIN */ + + /* We have a packet, setup pointer to the buffer area. */ + buffer_ptr = new_packet_ptr -> nx_packet_prepend_ptr; + + /* Check for 2xx message, signaling the IP/port was received properly. */ + if (buffer_ptr[0] != '2') + { + + /* Stop listening on the data port. */ + nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port); + + /* Release the packet. */ + nx_packet_release(new_packet_ptr); + + /* Unable to send PORT command to FTP server. */ + return(NX_FTP_EXPECTED_2XX_CODE); + } + + /* Now build the actual NLST request. */ + buffer_ptr[0] = 'L'; + buffer_ptr[1] = 'I'; + buffer_ptr[2] = 'S'; + buffer_ptr[3] = 'T'; + buffer_ptr[4] = ' '; + + /* Copy the directory path into the buffer. */ + for(i = 0; directory_path[i]; i++) + { + + /* Copy character of directory path. */ + buffer_ptr[5+i] = (UCHAR)directory_path[i]; + } + + /* Insert the CR/LF. */ + buffer_ptr[5+i] = 13; + buffer_ptr[5+i+1] = 10; + + /* Setup the length of the packet. */ + new_packet_ptr -> nx_packet_length = i + 7; + + /* Setup the packet append pointer. */ + new_packet_ptr -> nx_packet_append_ptr = new_packet_ptr -> nx_packet_prepend_ptr + new_packet_ptr -> nx_packet_length; + + /* Send the LIST message. */ + status = nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), new_packet_ptr, wait_option); + + /* Determine if the send was unsuccessful. */ + if (status) + { + + /* Stop listening on the data port. */ + nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port); + + /* Release the packet. */ + nx_packet_release(new_packet_ptr); + + /* Return error. */ + return(status); + } + + /* Now wait for the data connection to connect. */ + status = nx_tcp_server_socket_accept(&(ftp_client_ptr -> nx_ftp_client_data_socket), wait_option); + + /* Determine if the accept was unsuccessful. */ + if (status) + { + + /* Stop listening on the data port. */ + nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port); + + /* Return error. */ + return(status); + } + + /* Now wait for response from the FTP server control port. */ + status = nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &new_packet_ptr, wait_option); + + /* Determine if a packet was not received. */ + if (status) + { + + /* Unaccept the on the data port. */ + nx_tcp_server_socket_unaccept(&(ftp_client_ptr -> nx_ftp_client_data_socket)); + + /* Stop listening on the data port. */ + nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port); + + /* Error in NLST request to FTP server. */ + return(status); + } + + /* We have a packet, setup pointer to the buffer area. */ + buffer_ptr = new_packet_ptr -> nx_packet_prepend_ptr; + + /* Check for 1xx message, signaling the data port was connected properly and ready for + transfer. */ + if (buffer_ptr[0] != '1') + { + + /* Unaccept the on the data port. */ + nx_tcp_server_socket_unaccept(&(ftp_client_ptr -> nx_ftp_client_data_socket)); + + /* Stop listening on the data port. */ + nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port); + + /* Release the packet. */ + nx_packet_release(new_packet_ptr); + + /* Error in NLST request to FTP server. */ + return(NX_FTP_EXPECTED_1XX_CODE); + } + + /* Release the last packet. */ + nx_packet_release(new_packet_ptr); + + /* Now read a listing packet from the data socket. */ + status = nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_data_socket), packet_ptr, wait_option); + + /* Determine if an error occurred. */ + if (status) + { + + /* Unaccept the on the data port. */ + nx_tcp_server_socket_unaccept(&(ftp_client_ptr -> nx_ftp_client_data_socket)); + + /* Stop listening on the data port. */ + nx_tcp_server_socket_unlisten(ftp_client_ptr -> nx_ftp_client_ip_ptr, data_port); + + /* Map all unsuccessful status to error. */ + return(status); + } + + /* Return success to caller. */ + return(NX_SUCCESS); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_server_invalid_month_crash_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Invalid Month Crash Test.......................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ftp_test/netx_ftp_server_list_command_test.c b/test/regression/ftp_test/netx_ftp_server_list_command_test.c new file mode 100644 index 00000000..bfee4265 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_server_list_command_test.c @@ -0,0 +1,535 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define DEMO_DATA "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT ftp_client_directory_listing_get(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_path, + NX_PACKET **packet_ptr, ULONG wait_option); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_server_list_command_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Set the data as 04/02/2021. */ + fx_system_date_set(2021, 4, 2); + + /* Set the time as 08:05:30. */ + fx_system_time_set(8, 5, 30); + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, DEMO_DATA, sizeof(DEMO_DATA)); /* Use case of memcpy is verified. */ + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = sizeof(DEMO_DATA); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + sizeof(DEMO_DATA); + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Get directory listing (NLST). */ + status = ftp_client_directory_listing_get(&ftp_client, "", &my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + + /* Check the data. */ + if (memcmp(my_packet -> nx_packet_prepend_ptr, "-rw-rw-rw- 1 owner group 28 APR 02 08:05 test.txt\r\n", my_packet -> nx_packet_length)) + { + error_counter++; + } + nx_packet_release(my_packet); + } + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server LIST Command Test.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the ftp Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(1); + + status = nx_ftp_server_stop(&ftp_server); + status += nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT ftp_client_directory_listing_get(NX_FTP_CLIENT *ftp_client_ptr, CHAR *directory_path, + NX_PACKET **packet_ptr, ULONG wait_option) +{ + +UINT i; +UCHAR *buffer_ptr; +NX_PACKET *new_packet_ptr; +UINT status; + + + /* Set packet pointer to NULL. */ + *packet_ptr = NX_NULL; + + /* Ensure the client is the proper state for directory listing request. */ + if (ftp_client_ptr -> nx_ftp_client_state != NX_FTP_STATE_CONNECTED) + return(NX_FTP_NOT_CONNECTED); + + /* Transfer the data in active transfer mode. */ + status = _nx_ftp_client_active_transfer_setup(ftp_client_ptr, wait_option); + + /* Determine if set up successful. */ + if (status) + { + return(status); + } + + /* Allocate a packet for sending the NLST command. */ + status = _nx_ftp_client_packet_allocate(ftp_client_ptr, &new_packet_ptr, wait_option); + + /* Determine if the packet allocation was successful. */ + if (status != NX_SUCCESS) + { + + /* Cleanup data socket. */ + _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option); + + /* Return error. */ + return(status); + } + + /* Check if out of boundary. */ + if ((UINT)(new_packet_ptr -> nx_packet_data_end - new_packet_ptr -> nx_packet_prepend_ptr) < 7) + { + + /* Cleanup data socket. */ + _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option); + + /* Release the packet. */ + nx_packet_release(new_packet_ptr); + + /* Set the error status. */ + return(NX_FTP_FAILED); + } + + /* We have a packet, setup pointer to the buffer area. */ + buffer_ptr = new_packet_ptr -> nx_packet_prepend_ptr; + + /* Now build the actual LIST request. */ + buffer_ptr[0] = 'L'; + buffer_ptr[1] = 'I'; + buffer_ptr[2] = 'S'; + buffer_ptr[3] = 'T'; + buffer_ptr[4] = ' '; + + /* Copy the directory path into the buffer. */ + for(i = 0; directory_path[i]; i++) + { + + /* Check if out of boundary. */ + if ((i + 7) >= (UINT)(new_packet_ptr -> nx_packet_data_end - new_packet_ptr -> nx_packet_prepend_ptr)) + { + + /* Cleanup data socket. */ + _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option); + + /* Release the packet. */ + nx_packet_release(new_packet_ptr); + + /* Set the error status. */ + return(NX_FTP_FAILED); + } + + /* Copy character of directory path. */ + buffer_ptr[5+i] = (UCHAR)directory_path[i]; + } + + /* Insert the CR/LF. */ + buffer_ptr[5+i] = 13; + buffer_ptr[5+i+1] = 10; + + /* Setup the length of the packet. */ + new_packet_ptr -> nx_packet_length = i + 7; + + /* Setup the packet append pointer. */ + new_packet_ptr -> nx_packet_append_ptr = new_packet_ptr -> nx_packet_prepend_ptr + new_packet_ptr -> nx_packet_length; + + /* Send the NLST message. */ + status = nx_tcp_socket_send(&(ftp_client_ptr -> nx_ftp_client_control_socket), new_packet_ptr, wait_option); + + /* Determine if the send was unsuccessful. */ + if (status) + { + + /* Cleanup data socket. */ + _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option); + + /* Release the packet. */ + nx_packet_release(new_packet_ptr); + + /* Return error. */ + return(status); + } + + /* Check if enable passive mode. */ + if (ftp_client_ptr -> nx_ftp_client_passive_transfer_enabled == NX_FALSE) + { + + /* Now wait for the data connection to connect. */ + status = nx_tcp_server_socket_accept(&(ftp_client_ptr -> nx_ftp_client_data_socket), wait_option); + + /* Determine if the accept was unsuccessful. */ + if (status) + { + + /* Cleanup data socket. */ + _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option); + + /* Return error. */ + return(status); + } + } + + /* Now wait for response from the FTP server control port. */ + status = nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_control_socket), &new_packet_ptr, wait_option); + + /* Determine if a packet was not received. */ + if (status) + { + + /* Cleanup data socket. */ + _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option); + + /* Error in NLST request to FTP server. */ + return(status); + } + + /* We have a packet, setup pointer to the buffer area. */ + buffer_ptr = new_packet_ptr -> nx_packet_prepend_ptr; + + /* Check for 1xx message, signaling the data port was connected properly and ready for + transfer. */ + if ((new_packet_ptr -> nx_packet_length < 3) || (buffer_ptr[0] != '1')) + { + + /* Cleanup data socket. */ + _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option); + + /* Release the packet. */ + nx_packet_release(new_packet_ptr); + + /* Error in NLST request to FTP server. */ + return(NX_FTP_EXPECTED_1XX_CODE); + } + + /* Release the last packet. */ + nx_packet_release(new_packet_ptr); + + /* Now read a listing packet from the data socket. */ + status = nx_tcp_socket_receive(&(ftp_client_ptr -> nx_ftp_client_data_socket), packet_ptr, wait_option); + + /* Determine if an error occurred. */ + if (status) + { + + /* Map all unsuccessful status to error. */ + return(status); + } + + /* Cleanup data socket. */ + _nx_ftp_client_data_socket_cleanup(ftp_client_ptr, wait_option); + + /* Return staus to caller. */ + return(status); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_server_list_command_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server LIST Command Test..............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_server_mss_too_small_test.c b/test/regression/ftp_test/netx_ftp_server_mss_too_small_test.c new file mode 100644 index 00000000..59479d14 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_server_mss_too_small_test.c @@ -0,0 +1,452 @@ +/* This test case focus on a bug while processing NX_FTP_NLST, TCP MSS less than length of filename would cause integer underflow. */ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_PACKET_CHAIN) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static TX_THREAD data_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET data_socket; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + +static CHAR command_buffer[1024]; +static UINT delay_close = NX_NO_WAIT; + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void data_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT send_data(CHAR *data); +static VOID tcp_listen_callback(NX_TCP_SOCKET *socket_ptr, UINT port); + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_server_mss_too_small_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create FTP data thread. */ + status = tx_thread_create(&data_thread, "FTP Data thread ", data_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 16384); + pointer = pointer + 16384; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +UINT i; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 320, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "FTP Client Socket", NX_IP_NORMAL, + NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 512, NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Bind to any port. */ + status = nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, NX_NO_WAIT); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_tcp_client_socket_connect(&client_socket, FTP_SERVER_ADDRESS, NX_FTP_SERVER_CONTROL_PORT, + NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = send_data("USER aaa\n"); + if (status) + error_counter++; + + status = send_data("PASS aaa\n"); + if (status) + error_counter++; + + status = send_data("TYPE I\n"); + if (status) + error_counter++; + + status = send_data("PORT 1,2,3,5,0,255\r"); + if (status) + error_counter++; + + for (i = 0; i < 10; i++) + { + + /* Initialize command buffer. */ + strncpy(command_buffer, "STOR 1", 6); + memset(command_buffer + 6, '0' + i, 200); + command_buffer[206] = '\0'; + strncat(command_buffer, ".txt\n", 6); + + status = send_data(command_buffer); + if (status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + delay_close = NX_IP_PERIODIC_RATE; + status = send_data("NLST /\0"); + if (status) + error_counter++; + + /* Disconnect from the server. */ + nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&client_socket); + + /* Cleanup the socket. */ + nx_tcp_client_socket_unbind(&client_socket); + nx_tcp_socket_delete(&client_socket); + + /* Set the flag. */ + test_done = NX_TRUE; +} + +/* Define the FTP data thread. */ + +void data_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; + + /* Create an FTP data socket. */ + status = nx_tcp_socket_create(&client_ip, &data_socket, "FTP Data Socket", NX_IP_NORMAL, + NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 512, NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Set MSS to 100. */ + status = nx_tcp_socket_mss_set(&data_socket, 100); + + /* Listen to port 255. */ + status = nx_tcp_server_socket_listen(&client_ip, 255, &data_socket, 5, NX_NULL); + if (status) + error_counter++; + + while (test_done == NX_FALSE) + { + + /* Loop to accept connection. */ + status = nx_tcp_server_socket_accept(&data_socket, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_packet_data_append(packet_ptr, "data", sizeof("data") - 1, &client_pool, NX_IP_PERIODIC_RATE); + if (status) + { + nx_packet_release(packet_ptr); + error_counter++; + } + + status = nx_tcp_socket_send(&data_socket, packet_ptr, NX_IP_PERIODIC_RATE); + if (status) + { + nx_packet_release(packet_ptr); + error_counter++; + } + + if (delay_close) + { + tx_thread_sleep(delay_close); + delay_close = NX_NO_WAIT; + } + + nx_tcp_socket_disconnect(&data_socket, NX_IP_PERIODIC_RATE); + + status = nx_tcp_server_socket_unaccept(&data_socket); + if (status) + error_counter++; + + status = nx_tcp_server_socket_relisten(&client_ip, 255, &data_socket); + if (status) + error_counter++; + } +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server MSS Too Small Test............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the ftp Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* OK to restart the ftp Server. */ + status = nx_ftp_server_stop(&ftp_server); + status += nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + /* Make sure there is no invalid release. */ + if (server_pool.nx_packet_pool_invalid_releases) + error_counter++; + + /* Make sure the packet pool is not corrupted. */ + while (server_pool.nx_packet_pool_available) + { + if (nx_packet_allocate(&server_pool, &my_packet, 0, NX_NO_WAIT) || + (my_packet -> nx_packet_pool_owner != &server_pool)) + { + + error_counter++; + break; + } + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT send_data(CHAR *data) +{ +UINT status; +NX_PACKET *packet_ptr; + + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + return(status); + + status = nx_packet_data_append(packet_ptr, data, strlen(data), &client_pool, NX_IP_PERIODIC_RATE); + if (status) + { + nx_packet_release(packet_ptr); + return(status); + } + + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE); + if (status) + { + nx_packet_release(packet_ptr); + return(status); + } + + /* Return success. */ + return(NX_SUCCESS); +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_server_mss_too_small_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server MSS Too Small Test.............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_service_commands_RETR_STOR_test.c b/test/regression/ftp_test/netx_ftp_service_commands_RETR_STOR_test.c new file mode 100644 index 00000000..141d7b82 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_service_commands_RETR_STOR_test.c @@ -0,0 +1,379 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_IP client_ip_2; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG retr_counter = 0; +static ULONG stor_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define FTP_CLIENT_2_ADDRESS IP_ADDRESS(1,2,3,6) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_RETR_STOR_test_application_define(void *first_unused_memory) +#endif +{ +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip_2, "NetX Client IP Instance", FTP_CLIENT_2_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip_2); + if (status) + error_counter++; + + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ +NX_PACKET *my_packet; +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Now open the same file for reading. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Read the file. */ + status = nx_ftp_client_file_read(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(my_packet->nx_packet_prepend_ptr,"ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + error_counter++; + } + /* Close this file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Service Command RETR STOR rest ......................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter != 0) || (retr_counter != 1) || (stor_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && ((*(message) == 'R') || *(message) == 'S')) + { + if(!memcmp(message,"STOR test.txt",13)) + stor_counter++; + + else if(!memcmp(message,"RETR test.txt",13)) + { + retr_counter++; + /* Deal packets with default routing. */ + server_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_RETR_STOR_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Service Command RETR STOR rest .......................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_service_commands_dele_test.c b/test/regression/ftp_test/netx_ftp_service_commands_dele_test.c new file mode 100644 index 00000000..fb76202d --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_service_commands_dele_test.c @@ -0,0 +1,396 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG dele_counter = 0; +static ULONG fail_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_dele_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a File. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_ftp_client_file_delete(&ftp_client,"test.txt",NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a File. */ + status = nx_ftp_client_file_open(&ftp_client, "/test1.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_ftp_client_file_delete(&ftp_client,"/test1.txt",NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + client_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_client; + + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + error_counter++; + + status = nx_ftp_client_file_open(&ftp_client, "/test1.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + error_counter++; + + client_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Disconnect from the server. */ + nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Service Command DELE Test ............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) || ( dele_counter != 2 ) || (fail_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check the packet is a SYN one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && *(message) == 'D') + { + if(!memcmp(message,"DELE test.txt",13)) + dele_counter++; + else if(!memcmp(message,"DELE /test1.txt",15)) + { + dele_counter++; + /* Deal packets with default routing. */ + server_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check the packet is a SYN one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && *(message) == '5') + { + if(!memcmp(message,"550 File Open Fail",18)) + fail_counter++; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_dele_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Service Command DELE Test ............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_service_commands_file_write_test.c b/test/regression/ftp_test/netx_ftp_service_commands_file_write_test.c new file mode 100644 index 00000000..36e23dae --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_service_commands_file_write_test.c @@ -0,0 +1,423 @@ +/* This file tests that a failed fx_file_write() operation results in a 550 error message + back to the FTP Client from the Server. The first file is small enough there is enough + memory in the FileX ram disk space so it should succeed. The second file is large enough + there is not enough ram disk space available so it should fail. Further, the test + checks that there are two STOR commands received by the FTP server as part of the + requirements for successful outcome. + + Note that the ram_disk_memory is much smaller than the typical FileX demo (only 3200 bytes) + and the number of sectors is reduced from 256 to 25. */ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG stor_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ + + +#define BIG_SEND 4300 +#define NOT_SO_BIG_SEND 1600 + +UCHAR buffer[BIG_SEND]; +#define NX_PACKET_POOL_SIZE ((1536 + sizeof(NX_PACKET)) * 10) +ULONG client_packet_pool_area[NX_PACKET_POOL_SIZE/4 + 4]; +ULONG server_packet_pool_area[NX_PACKET_POOL_SIZE/4 + 4]; +ULONG client_ip_thread_stack[2 * 1024 / sizeof(ULONG)]; +ULONG server_ip_thread_stack[2 * 1024 / sizeof(ULONG)]; +ULONG client_arp_space_area[512 / sizeof(ULONG)]; +ULONG server_arp_space_area[512 / sizeof(ULONG)]; + +static UCHAR ram_disk_memory[3200]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_file_write_test_application_define(void *first_unused_memory) +#endif +{ +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "Server Packet Pool", 1536, (ULONG*)(((int)server_packet_pool_area + 15) & ~15) , NX_PACKET_POOL_SIZE); + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1500, + (UCHAR*)server_ip_thread_stack, + sizeof(server_ip_thread_stack), + 1); + + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *)server_arp_space_area, sizeof(server_arp_space_area)); + + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "Client Packet Pool", 1536, (ULONG*)(((int)client_packet_pool_area + 15) & ~15) , NX_PACKET_POOL_SIZE); + + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_1500, + (UCHAR*)client_ip_thread_stack, + sizeof(client_ip_thread_stack), + 1); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *)client_arp_space_area, sizeof(client_arp_space_area)); + + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ +NX_PACKET *my_packet; +UINT status; +UINT i; +UCHAR c; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 25, /* Total sectors */ // jlc restore to 24 + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + c = 0x20; + for (i = 0; i < BIG_SEND; i++) + { + buffer[i] = c; + c++; + if (c == 0x7E) + { + c = 0x20; + } + } + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Open a smaller FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test_2.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Add data to the packet. */ + status = nx_packet_data_append(my_packet, &buffer[0], NOT_SO_BIG_SEND, &client_pool, 200); + + /* Check status. */ + if (status != NX_SUCCESS) + { + nx_packet_release(my_packet); + error_counter++; + } + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, 10*NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + + /* The FTP Client should have received an 250 message from the FTP server, so status should be SUCCESS. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + + /* Open a bigger FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Add data to the packet. */ + status = nx_packet_data_append(my_packet, &buffer[0], BIG_SEND, &client_pool, 200); + + /* Check status. */ + if (status != NX_SUCCESS) + { + nx_packet_release(my_packet); + error_counter++; + } + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, 10*NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + + /* The FTP Client should have received an error message from the FTP server, so status should be an error. */ + if (status == NX_SUCCESS) + { + error_counter++; + } + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: FTP Service Command file write test ......................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTP Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter != 0) || (stor_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (*(message) == 'S')) + { + + if(!memcmp(message,"STOR test.txt",13)) + { + + stor_counter++; + } + if(!memcmp(message,"STOR test_2.txt",15)) + { + + stor_counter++; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_file_write_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: FTP Service Command file write test ......................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_PACKET_CHAIN */ diff --git a/test/regression/ftp_test/netx_ftp_service_commands_m_d_dir_test.c b/test/regression/ftp_test/netx_ftp_service_commands_m_d_dir_test.c new file mode 100644 index 00000000..e9dcc5e9 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_service_commands_m_d_dir_test.c @@ -0,0 +1,424 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG mkd_counter = 0; +static ULONG rmd_counter = 0; +static ULONG dir_fail_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_m_d_dir_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_ftp_client_directory_create(&ftp_client,"/abc",NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + status = nx_ftp_client_directory_create(&ftp_client,"def",NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + /*To ensure the making dir successfully*/ + status = nx_ftp_client_directory_default_set(&ftp_client, "/abc" ,NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_ftp_client_directory_default_set(&ftp_client, "/def" ,NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + client_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_client; + status = nx_ftp_client_directory_delete(&ftp_client,"/abc",NX_IP_PERIODIC_RATE/2); + if (status != NX_FTP_EXPECTED_2XX_CODE) + error_counter++; + + status = nx_ftp_client_directory_default_set(&ftp_client, "/" ,NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + status = nx_ftp_client_directory_delete(&ftp_client,"def",NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + /*Check the response when deleting a dir deleted.*/ + status = nx_ftp_client_file_delete(&ftp_client, "/abc/test.txt",NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + status = nx_ftp_client_directory_delete(&ftp_client,"/abc",NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + + /*Check if the two dir have been successfully deleted. */ + status = nx_ftp_client_directory_default_set(&ftp_client, "/abc" ,NX_IP_PERIODIC_RATE/2); + if (status == NX_SUCCESS) + error_counter++; + + status = nx_ftp_client_directory_default_set(&ftp_client, "/def" ,NX_IP_PERIODIC_RATE/2); + if (status == NX_SUCCESS) + error_counter++; + + status = nx_ftp_client_directory_delete(&ftp_client,"/abc",NX_IP_PERIODIC_RATE/2); + if (status != NX_FTP_EXPECTED_2XX_CODE) + error_counter++; + + status = nx_ftp_client_directory_delete(&ftp_client,"def",NX_IP_PERIODIC_RATE/2); + if (status != NX_FTP_EXPECTED_2XX_CODE) + error_counter++; + + client_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Service Commands make dele dir Test............"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) || ( rmd_counter != 2 ) || (mkd_counter != 2) || (dir_fail_counter != 5)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *tcp_header_ptr; + UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + + if(!memcmp(message,"MKD /abc ",8) || !memcmp(message,"MKD def ",7)) + mkd_counter++; + else if(!memcmp(message,"RMD /abc ",8)) + rmd_counter++; + else if (!memcmp(message,"RMD def ",7)) + { + rmd_counter++; + server_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && *(message) == '5') + { + + if(!memcmp(message,"550 Delete Directory Fail",25) || !memcmp(message,"550 Change Dir Fail",19)) + dir_fail_counter++; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_m_d_dir_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Server Service Commands make dele dir Test............N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_service_commands_nlist_test.c b/test/regression/ftp_test/netx_ftp_service_commands_nlist_test.c new file mode 100644 index 00000000..a651ce99 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_service_commands_nlist_test.c @@ -0,0 +1,433 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG fail_counter = 0; +static ULONG nlist_counter = 0; +static ULONG type_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_nlist_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +UCHAR buffer_list[26]; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_ftp_client_directory_create(&ftp_client,"/abc",NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + status = nx_ftp_client_directory_create(&ftp_client,"def",NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + /* Create a File. */ + status = nx_ftp_client_file_open(&ftp_client, "test1.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a File. */ + status = nx_ftp_client_file_open(&ftp_client, "/abc/test2.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_ftp_client_directory_create(&ftp_client,"cpp",NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + + client_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_client; + + buffer_list[0] = '.'; + buffer_list[1] = 13; + buffer_list[2] = 10; + buffer_list[3] = '.'; + buffer_list[4] = '.'; + buffer_list[5] = 13; + buffer_list[6] = 10; + buffer_list[7] = 't'; + buffer_list[8] = 'e'; + buffer_list[9] = 's'; + buffer_list[10] = 't'; + buffer_list[11] = '2'; + buffer_list[12] = '.'; + buffer_list[13] = 't'; + buffer_list[14] = 'x'; + buffer_list[15] = 't'; + + status = nx_ftp_client_directory_listing_get(&ftp_client,"/abc",&my_packet,NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + else if(memcmp(buffer_list,my_packet->nx_packet_prepend_ptr,15)) + error_counter++; + + status = nx_ftp_client_directory_listing_continue(&ftp_client,&my_packet,NX_IP_PERIODIC_RATE/2); + if (status != NX_FTP_END_OF_LISTING) + error_counter++; + + memcpy(buffer_list,"abc",3); + buffer_list[3] = 13; + buffer_list[4] = 10; + memcpy(buffer_list + 5,"def",3); + buffer_list[8] = 13; + buffer_list[9] = 10; + memcpy(buffer_list + 10,"test1.txt",9); + buffer_list[19] = 13; + buffer_list[20] = 10; + memcpy(buffer_list + 21,"cpp",3); + buffer_list[24] = 13; + buffer_list[25] = 10; + + status = nx_ftp_client_directory_listing_get(&ftp_client,"",&my_packet,NX_IP_PERIODIC_RATE/2); + if (status) + error_counter++; + else if(memcmp(my_packet->nx_packet_prepend_ptr,buffer_list,25)) + error_counter++; + + status = nx_ftp_client_directory_listing_continue(&ftp_client,&my_packet,NX_IP_PERIODIC_RATE/2); + if (status != NX_FTP_END_OF_LISTING) + error_counter++; + + + status = nx_ftp_client_directory_listing_get(&ftp_client,"/ /abc",&my_packet,NX_IP_PERIODIC_RATE/2); + if (status == NX_SUCCESS) + error_counter++; + + status = nx_ftp_client_directory_listing_continue(&ftp_client,&my_packet,NX_IP_PERIODIC_RATE/2); + if (status != NX_FTP_EXPECTED_2XX_CODE) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Service Command NLIST Test ..........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) || ( nlist_counter != 1 ) || (fail_counter != 1) || (type_counter >= 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_PSH_BIT ) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) ) + { + if(*message == 'T') + { + if(*(message + 5) == 'A' || *(message + 5) == 'E') + type_counter++; + } + else if(*message == 'N') + { + if (!memcmp(message,"NLST /abc",9)) + nlist_counter++; + server_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && *(message) == '5') + { + if(!memcmp(message,"550 List bad Directory",18)) + { + fail_counter++; + client_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_nlist_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Service Command NLIST Test ...........................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_service_commands_rename_test.c b/test/regression/ftp_test/netx_ftp_service_commands_rename_test.c new file mode 100644 index 00000000..99ff8b2d --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_service_commands_rename_test.c @@ -0,0 +1,414 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static ULONG rename_counter = 0; +static ULONG fail_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + + +/* Define server login/logout functions. These are stubs for functions that would +validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_rename_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a File. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + status = nx_ftp_client_file_rename(&ftp_client,"test.txt","test1.txt",NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + client_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_client; + + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + error_counter++; + + status = nx_ftp_client_file_open(&ftp_client, "test1.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Read the file. */ + status = nx_ftp_client_file_read(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(my_packet->nx_packet_prepend_ptr,"ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP Service Command Rename Test .........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) || ( rename_counter != 2 ) || (fail_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_PSH_BIT ) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) ) + { + if(*(message) == 'R') + { + if(!memcmp(message,"RNFR test.txt",13)) + { + if(rename_counter == 0) + rename_counter++; + } + else if(!memcmp(message,"RNTO test1.txt",14)) + { + if(rename_counter == 1) + { + rename_counter++; + /* Deal packets with default routing. */ + server_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + else + rename_counter = 3; + } + } + else if (rename_counter) + rename_counter++; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +void my_ftp_packet_receive_client(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && *(message) == '5') + { + if(!memcmp(message,"550 File Open Fail",18)) + { + fail_counter++; + client_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_service_commands_rename_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP Service Command Rename Test ..........................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ftp_test/netx_ftp_two_listen_test.c b/test/regression/ftp_test/netx_ftp_two_listen_test.c new file mode 100644 index 00000000..15461c72 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_two_listen_test.c @@ -0,0 +1,314 @@ +/* This case tests the FTP server on handling two session listen situation. + * JIRA: https://expresslogic.atlassian.net/browse/NETXDUO-238 + */ +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#include +#include +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_RESET_DISCONNECT) + + + +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_server.h" +#endif + +#define DEMO_STACK_SIZE 4096 +#define LOOP 100 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD server_thread; +static NX_PACKET_POOL pool_server; +static NX_PACKET_POOL pool_client; +static NX_IP ip_server; +static NX_IP ip_client; +static NX_TCP_SOCKET test_sockets[3]; +static TX_SEMAPHORE sema_0; + +/* Define FTP objects. */ + +static NX_FTP_SERVER ftp_server; +static FX_MEDIA ram_disk; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; + +static UINT data_received; +static UCHAR send_buff[256]; +static UCHAR recv_buff[256]; + + +#define SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define function prototypes. */ + +static void thread_server_entry(ULONG thread_input); +static void thread_test_entry(ULONG thread_input); + +/* Replace the 'ram' driver with your actual Ethernet driver. */ +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _fx_ram_driver(FX_MEDIA *media_ptr); + + + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_two_listen_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&server_thread, "server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create packet pool. */ + status = nx_packet_pool_create(&pool_server, "Server NetX Packet Pool", 600, pointer, 8192); + pointer = pointer + 8192; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_server, "Server NetX IP Instance", SERVER_ADDRESS, + 0xFFFFFF00UL, &pool_server, _nx_ram_network_driver_512, + pointer, 4096, 1); + pointer = pointer + 4096; + if(status) + error_counter++; + + /* Create another packet pool. */ + status = nx_packet_pool_create(&pool_client, "Client NetX Packet Pool", 600, pointer, 8192); + pointer = pointer + 8192; + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_client, "Client NetX IP Instance", CLIENT_ADDRESS, + 0xFFFFFF00UL, &pool_client, _nx_ram_network_driver_512, + pointer, 4096, 1); + pointer = pointer + 4096; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_server, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_client, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_server); + status += nx_tcp_enable(&ip_client); + if(status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &ip_server, &ram_disk, pointer, DEMO_STACK_SIZE, &pool_server, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for errors. */ + if (status) + error_counter++; + + status = tx_semaphore_create(&sema_0, "Semaphore", 0); + if (status) + error_counter++; +} + +/* Define the Server thread. */ +static void thread_server_entry(ULONG thread_input) +{ + +UINT i; +UINT status; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: FTP Two Listen Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* OK to start the ftp Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + /* Initialize test sockets. */ + for (i = 0; i < sizeof(test_sockets) / sizeof(NX_TCP_SOCKET); i++) + { + + /* Create Client socket. */ + status = nx_tcp_socket_create(&ip_client, &test_sockets[i], "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + error_counter++; + return; + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&test_sockets[i], NX_ANY_PORT, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + break; + } + } + + /* Connect to Telnet server. */ + status = nx_tcp_client_socket_connect(&test_sockets[0], SERVER_ADDRESS, NX_FTP_SERVER_CONTROL_PORT, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + + /* Send data to Telnet server. */ + nx_packet_allocate(&pool_client, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + nx_packet_data_append(packet_ptr, "PASS 1234\r\n", 11, &pool_client, NX_NO_WAIT); + nx_tcp_socket_send(&test_sockets[0], packet_ptr, NX_NO_WAIT); + + /* Disconnect immediately. */ + nx_tcp_socket_disconnect(&test_sockets[0], NX_IP_PERIODIC_RATE); + + if (tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE)) + { + error_counter++; + } + + /* Let another two sockets connect to Telnet server without block. */ + nx_tcp_client_socket_connect(&test_sockets[1], SERVER_ADDRESS, NX_FTP_SERVER_CONTROL_PORT, NX_NO_WAIT); + nx_tcp_client_socket_connect(&test_sockets[2], SERVER_ADDRESS, NX_FTP_SERVER_CONTROL_PORT, NX_NO_WAIT); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure the state of sockets is ESTABLISHED. */ + if (test_sockets[1].nx_tcp_socket_state != NX_TCP_ESTABLISHED) + { + error_counter++; + } + if (test_sockets[2].nx_tcp_socket_state != NX_TCP_ESTABLISHED) + { + error_counter++; + } + + status = nx_ftp_server_stop(&ftp_server); + status += nx_ftp_server_delete(&ftp_server); + if (status) + error_counter++; + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + tx_semaphore_put(&sema_0); + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_two_listen_test_application_define(void *first_unused_memory) +#endif +{ + /* Print out test information banner. */ + printf("NetX Test: FTP Two Listen Test.......................................N/A\n"); + test_control_return(3); +} +#endif + + diff --git a/test/regression/ftp_test/netx_ftp_user_data_type_test.c b/test/regression/ftp_test/netx_ftp_user_data_type_test.c new file mode 100644 index 00000000..3b8dbf32 --- /dev/null +++ b/test/regression/ftp_test/netx_ftp_user_data_type_test.c @@ -0,0 +1,362 @@ + +#include "tx_api.h" +#include "fx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_ftp_client.h" +#include "nxd_ftp_server.h" +#else +#include "nx_ftp_client.h" +#include "nx_ftp_server.h" +#endif +#include "nx_tcp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX, NetX, and FileX object control blocks... */ +static TX_THREAD server_thread; +static TX_THREAD client_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static FX_MEDIA ram_disk; + + +/* Define the NetX FTP object control blocks. */ +static NX_FTP_CLIENT ftp_client; +static NX_FTP_SERVER ftp_server; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; +static UINT test_done = NX_FALSE; + +/* Define the memory area for the FileX RAM disk. */ +static UCHAR ram_disk_memory[32000]; +static UCHAR ram_disk_sector_cache[512]; +static UINT type_counter = 0;; +static UINT sp_counter = 0; +static UINT client_counter = 0; + +#define FTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define FTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +extern UINT _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size, + CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors, + ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster, + UINT heads, UINT sectors_per_track); + +/* Define the FileX and NetX driver entry functions. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr); + +static void client_thread_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define server login/logout functions. These are stubs for functions that would + validate a client login request. */ +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_user_data_type_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the packet pool for the FTP Server. */ + status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create the IP instance for the FTP Server. */ + status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the FTP server. */ + status = nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool, + server_login, server_logout); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Now set up the FTP Client. */ + + /* Create the main FTP client thread. */ + status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE ; + if (status) + error_counter++; + + /* Create a packet pool for the FTP client. */ + status = nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status) + error_counter++; + + /* Create an IP instance for the FTP client. */ + status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL, + &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the FTP Client IP. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP for client IP instance. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + +/* Define the FTP client thread. */ + +void client_thread_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +UINT status; + + /* Format the RAM disk - the memory for the RAM disk was defined above. */ + status = _fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + ram_disk_sector_cache, /* Media buffer pointer */ + sizeof(ram_disk_sector_cache), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check status. */ + if (status) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache)); + if (status) + error_counter++; + + /* Create an FTP client. */ + status = nx_ftp_client_create(&ftp_client, "FTP Client", &client_ip, 2000, &client_pool); + if (status) + error_counter++; + + /* Now connect with the NetX FTP (IPv4) server. */ + status = nx_ftp_client_connect(&ftp_client, FTP_SERVER_ADDRESS, "name", "password", NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Open a FTP file for writing. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_WRITE, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + + /* Allocate a FTP packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Write the packet to the file test.txt. */ + status = nx_ftp_client_file_write(&ftp_client, my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Close the file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Now open the same file for reading. */ + status = nx_ftp_client_file_open(&ftp_client, "test.txt", NX_FTP_OPEN_FOR_READ, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Read the file. */ + status = nx_ftp_client_file_read(&ftp_client, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Close this file. */ + status = nx_ftp_client_file_close(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Disconnect from the server. */ + status = nx_ftp_client_disconnect(&ftp_client, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Delete the FTP client. */ + status = nx_ftp_client_delete(&ftp_client); + if (status) + error_counter++; + + /* Set the flag. */ + test_done = NX_TRUE; +} + + +/* Define the helper FTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: FTP User Data Type Test..................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the FTPv6 Server. */ + status = nx_ftp_server_start(&ftp_server); + if (status) + error_counter++; + + server_ip.nx_ip_tcp_packet_receive = my_ftp_packet_receive_server; + + /* Wait for test. */ + while(test_done == NX_FALSE) + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_ftp_server_delete(&ftp_server); + if(status) + error_counter++; + + if((error_counter) || (type_counter != 1) || (client_counter != 1) || (sp_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +static UINT server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info) +{ + /* Always return success. */ + return(NX_SUCCESS); +} + +void my_ftp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +UCHAR *message; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + message = packet_ptr -> nx_packet_prepend_ptr + 20; + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (*message == 'T')) + { + /* Check if The parameters are separated by a */ + if((!memcmp(message,"TYPE",4)) && (*(message + 4) == ' ')) + sp_counter++; + + /* Check if the default Type is "I' (which means the ASCII) */ + if(*(message + 5) == 'I') + { + type_counter++; + client_counter++; + } + /* Deal packets with default routing. */ + server_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ftp_user_data_type_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: FTP User Data Type Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_basic_authenticate_test.c b/test/regression/http_test/netx_http_basic_authenticate_test.c new file mode 100644 index 00000000..769204e6 --- /dev/null +++ b/test/regression/http_test/netx_http_basic_authenticate_test.c @@ -0,0 +1,443 @@ +/* This case tests the basic authentication, + * name:password is the correct account + * name2:password is the wrong account + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_HTTP_CLIENT my_client; +static NX_IP client_ip; +static UINT error_counter; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + +static TX_SEMAPHORE server_start; +static TX_SEMAPHORE client_stop; + + +/* Define the application's authentication check. This is called by + the HTTP server whenever a new request is received. */ +static UINT authentication_check(NX_HTTP_SERVER *server_ptr, UINT request_type, + CHAR *resource, CHAR **name, CHAR **password, CHAR **realm) +{ + + /* Just use a simple name, password, and realm for all + requests and resources. */ + *name = "name"; + *password = "password"; + *realm = "NetX Duo HTTP demo"; + + /* Request basic authentication. */ + return(NX_HTTP_BASIC_AUTHENTICATE); +} + +static UINT authentication_check_extended(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, CHAR **name, UINT *name_length, + CHAR **password, UINT *password_length, CHAR **realm, UINT *realm_length) +{ + + /* Just use a simple name, password, and realm for all + requests and resources. */ + *name = "name"; + *password = "password"; + *realm = "NetX Duo HTTP demo"; + *name_length = 4; + *password_length = 8; + *realm_length = 18; + + /* Request basic authentication. */ + return(NX_HTTP_BASIC_AUTHENTICATE); +} + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_basic_authenticate_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, authentication_check, NX_NULL); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + tx_semaphore_create(&server_start, "server start", 0); + tx_semaphore_create(&client_stop, "client stop", 0); +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *send_packet; + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + if (status != FX_SUCCESS) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + if (status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + + /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */ + status = nxd_http_client_put_start(&my_client, &server_ip_address, "/client_test.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#else + + /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */ + status = nx_http_client_put_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Basic authentication, name = "name", passwd = "password". */ +#ifdef __PRODUCT_NETXDUO__ + + /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */ + status = nxd_http_client_get_start(&my_client, &server_ip_address, + "/client_test.htm", NX_NULL, 0, "name", "password", 50); +#else + + /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */ + status = nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm", + NX_NULL, 0, "name", "password", 50); +#endif + + /* Should pass the authentication. */ + if(status) + error_counter++; + + status = nx_http_client_delete(&my_client); + if(status) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + if (status) + error_counter++; + + /* Basic Authentication, name = "name2", passwd = "password". */ +#ifdef __PRODUCT_NETXDUO__ + + /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */ + status = nxd_http_client_get_start(&my_client, &server_ip_address, + "/client_test.htm", NX_NULL, 0, "name2", "password", 50); +#else + + /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */ + status = nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm", + NX_NULL, 0, "name2", "password", 50); +#endif + + /* Shouldn't pass the authentication. */ + if(status != NX_HTTP_AUTHENTICATION_ERROR) + error_counter++; + + status = nx_http_client_delete(&my_client); + if(status) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + if (status) + error_counter++; + + /* Basic Authentication, name = "name", passwd = "". */ +#ifdef __PRODUCT_NETXDUO__ + + /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */ + status = nxd_http_client_get_start(&my_client, &server_ip_address, + "/client_test.htm", NX_NULL, 0, "name", "", 50); +#else + + /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */ + status = nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm", + NX_NULL, 0, "name", "", 50); +#endif + + /* Shouldn't pass the authentication. */ + if(status != NX_HTTP_AUTHENTICATION_ERROR) + error_counter++; + + status = nx_http_client_delete(&my_client); + if(status) + error_counter++; + + tx_semaphore_put(&client_stop); + tx_semaphore_get(&server_start, NX_WAIT_FOREVER); + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + if (status) + error_counter++; + + /* Basic Authentication, name = "name2", passwd = "password". */ +#ifdef __PRODUCT_NETXDUO__ + + /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */ + status = nxd_http_client_get_start(&my_client, &server_ip_address, + "/client_test.htm", NX_NULL, 0, "name", "password", 50); +#else + + /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */ + status = nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm", + NX_NULL, 0, "name", "password", 50); +#endif + + /* Should pass the authentication. */ + if(status) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Basic Athentication Test............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + error_counter++; + + tx_semaphore_get(&client_stop, NX_WAIT_FOREVER); + + status = nx_http_server_authentication_check_set(&my_server, authentication_check_extended); + if (status) + error_counter++; + + tx_semaphore_put(&server_start); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_basic_authenticate_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Basic Athentication Test.............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/http_test/netx_http_basic_test.c b/test/regression/http_test/netx_http_basic_test.c new file mode 100644 index 00000000..27aa8a3a --- /dev/null +++ b/test/regression/http_test/netx_http_basic_test.c @@ -0,0 +1,439 @@ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_HTTP_CLIENT my_client; +static NX_IP client_ip; +static UINT error_counter; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + +/* Define the application's authentication check. This is called by + the HTTP server whenever a new request is received. */ +static UINT authentication_check(NX_HTTP_SERVER *server_ptr, UINT request_type, + CHAR *resource, CHAR **name, CHAR **password, CHAR **realm) +{ + + /* Just use a simple name, password, and realm for all + requests and resources. */ + *name = "name"; + *password = "password"; + *realm = "NetX Duo HTTP demo"; + + /* Request basic authentication. */ + return(NX_HTTP_BASIC_AUTHENTICATE); +} + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, authentication_check, NX_NULL); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *send_packet; +NX_PACKET *recv_packet; + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + /* Check the media open status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + + /* Check status. */ + if (status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + + /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */ + status = nxd_http_client_put_start(&my_client, &server_ip_address, "/client_test.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#else + + /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */ + status = nx_http_client_put_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + error_counter++; + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Now GET the test file */ + +#ifdef __PRODUCT_NETXDUO__ + + /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */ + status = nxd_http_client_get_start(&my_client, &server_ip_address, + "/client_test.htm", NX_NULL, 0, "name", "password", 50); +#else + + /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */ + status = nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm", + NX_NULL, 0, "name", "password", 50); +#endif /* USE_DUO */ + + if(status) + error_counter++; + + while (1) + { + status = nx_http_client_get_packet(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + + if (status == NX_HTTP_GET_DONE) + break; + + if (status) + error_counter++; + else + nx_packet_release(recv_packet); + } + +#ifdef __PRODUCT_NETXDUO__ + + /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */ + status = nxd_http_client_put_start_extended(&my_client, &server_ip_address, "/client_test_extended.htm", 25, + "name", 4, "password", 8, 103, 5 * NX_IP_PERIODIC_RATE); +#else + + /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */ + status = nx_http_client_put_start_extended(&my_client, HTTP_SERVER_ADDRESS, "/client_test_extended.htm", 25, + "name", 4, "password", 8, 103, 5 * NX_IP_PERIODIC_RATE); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + error_counter++; + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Now GET the test file */ + +#ifdef __PRODUCT_NETXDUO__ + + /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */ + status = nxd_http_client_get_start_extended(&my_client, &server_ip_address, + "/client_test_extended.htm", 25, NX_NULL, 0, "name", 4, "password", 8, 50); +#else + + /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */ + status = nx_http_client_get_start_extended(&my_client, HTTP_SERVER_ADDRESS, "/client_test_extended.htm", 25, + NX_NULL, 0, "name", 4, "password", 8, 50); +#endif /* USE_DUO */ + + if(status) + error_counter++; + + while (1) + { + status = nx_http_client_get_packet(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + + if (status == NX_HTTP_GET_DONE) + break; + + if (status) + error_counter++; + else + nx_packet_release(recv_packet); + } + + status = nx_http_client_delete(&my_client); + if(status) + error_counter++; + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Basic Test..........................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + error_counter++; + + /* Restart HTTP server. */ + status = nx_http_server_stop(&my_server); + status += nx_http_server_start(&my_server); + if(status) + error_counter++; + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + status = nx_http_server_delete(&my_server); + if(status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Basic Test...........................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/http_test/netx_http_client_change_connect_port_test.c b/test/regression/http_test/netx_http_client_change_connect_port_test.c new file mode 100644 index 00000000..5e69d7f1 --- /dev/null +++ b/test/regression/http_test/netx_http_client_change_connect_port_test.c @@ -0,0 +1,681 @@ +/* This case tests the ability of the HTTP Client to change ports it connects to the server on at + runtime. It initially makes a PUT request and based on server information it receives, it . + changes the connect port from the default 80 to 85. . + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#else +#include "nx_http_client.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define SERVER_PORT 80 +#define SECONDARY_SERVER_PORT 85 + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static void http_test_initialize(); +static UINT nx_http_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); + + +static char PUT_firstreply[202] = { +0x48, 0x54, /* HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x32, /* TP/1.1 2 */ +0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, /* 00 OK..D */ +0x61, 0x74, 0x65, 0x3a, 0x20, 0x54, 0x75, 0x65, /* ate: Tue */ +0x2c, 0x20, 0x32, 0x34, 0x20, 0x4d, 0x61, 0x79, /* , 24 May */ +0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x32, 0x33, /* 2016 23 */ +0x3a, 0x32, 0x36, 0x3a, 0x35, 0x34, 0x20, 0x47, /* :26:54 G */ +0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72, 0x76, /* MT..Serv */ +0x65, 0x72, 0x3a, 0x20, 0x4d, 0x61, 0x6b, 0x6f, /* er: Mako */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x6e, /* Server.n */ +0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, /* et..Cont */ +0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, /* ent-Type */ +0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, /* : text/h */ +0x74, 0x6d, 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, /* tml; cha */ +0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, /* rset=utf */ +0x2d, 0x38, 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, /* -8..Cach */ +0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, /* e-Contro */ +0x6c, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x73, 0x74, /* l: no-st */ +0x6f, 0x72, 0x65, 0x2c, 0x20, 0x6e, 0x6f, 0x2d, /* ore, no- */ +0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x6d, /* cache, m */ +0x75, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x76, 0x61, /* ust-reva */ +0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2c, 0x20, /* lidate, */ +0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, 0x3d, /* max-age= */ +0x30, 0x0d, 0x0a, 0x4b, 0x65, 0x65, 0x70, 0x2d, /* 0..Keep- */ +0x41, 0x6c, 0x69, 0x76, 0x65, 0x3a, 0x20, 0x43, /* Alive: C */ +0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x0d, 0x0a /* lose.... */ +}; + +static int PUT_firstreply_size = 202; + + +static char GET_firstreply[638] = { +0x48, 0x54, /* HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x32, /* TP/1.1 2 */ +0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x43, /* 00 OK..C */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, /* ontent-T */ +0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, /* ype: tex */ +0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x20, /* t/html; */ +0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, /* charset= */ +0x75, 0x74, 0x66, 0x2d, 0x38, 0x0d, 0x0a, 0x43, /* utf-8..C */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, /* ontent-L */ +0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, /* ength: 4 */ +0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, /* ..Connec */ +0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, /* tion: cl */ +0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x53, 0x74, 0x61, /* ose..Sta */ +0x74, 0x75, 0x73, 0x3a, 0x20, 0x32, 0x30, 0x30, /* tus: 200 */ +0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x58, 0x2d, 0x46, /* OK..X-F */ +0x72, 0x61, 0x6d, 0x65, 0x2d, 0x4f, 0x70, 0x74, /* rame-Opt */ +0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x41, 0x4c, /* ions: AL */ +0x4c, 0x4f, 0x57, 0x41, 0x4c, 0x4c, 0x0d, 0x0a, /* LOWALL.. */ +0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x43, /* Access-C */ +0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x41, /* ontrol-A */ +0x6c, 0x6c, 0x6f, 0x77, 0x2d, 0x4f, 0x72, 0x69, /* llow-Ori */ +0x67, 0x69, 0x6e, 0x3a, 0x20, 0x2a, 0x0d, 0x0a, /* gin: *.. */ +0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x43, /* Access-C */ +0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x41, /* ontrol-A */ +0x6c, 0x6c, 0x6f, 0x77, 0x2d, 0x4d, 0x65, 0x74, /* llow-Met */ +0x68, 0x6f, 0x64, 0x73, 0x3a, 0x20, 0x47, 0x45, /* hods: GE */ +0x54, 0x2c, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x2c, /* T, POST, */ +0x20, 0x50, 0x55, 0x54, 0x2c, 0x20, 0x4f, 0x50, /* PUT, OP */ +0x54, 0x49, 0x4f, 0x4e, 0x53, 0x2c, 0x20, 0x44, /* TIONS, D */ +0x45, 0x4c, 0x45, 0x54, 0x45, 0x2c, 0x20, 0x50, /* ELETE, P */ +0x41, 0x54, 0x43, 0x48, 0x0d, 0x0a, 0x41, 0x63, /* ATCH..Ac */ +0x63, 0x65, 0x73, 0x73, 0x2d, 0x43, 0x6f, 0x6e, /* cess-Con */ +0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x41, 0x6c, 0x6c, /* trol-All */ +0x6f, 0x77, 0x2d, 0x48, 0x65, 0x61, 0x64, 0x65, /* ow-Heade */ +0x72, 0x73, 0x3a, 0x20, 0x6f, 0x72, 0x69, 0x67, /* rs: orig */ +0x69, 0x6e, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, /* in, cont */ +0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, /* ent-type */ +0x2c, 0x20, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75, /* , X-Requ */ +0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, /* ested-Wi */ +0x74, 0x68, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, /* th..Acce */ +0x73, 0x73, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, /* ss-Contr */ +0x6f, 0x6c, 0x2d, 0x4d, 0x61, 0x78, 0x2d, 0x41, /* ol-Max-A */ +0x67, 0x65, 0x3a, 0x20, 0x31, 0x38, 0x30, 0x30, /* ge: 1800 */ +0x0d, 0x0a, 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, /* ..ETag: */ +0x22, 0x36, 0x30, 0x35, 0x39, 0x38, 0x32, 0x38, /* "6059828 */ +0x32, 0x63, 0x65, 0x36, 0x38, 0x32, 0x38, 0x66, /* 2ce6828f */ +0x36, 0x38, 0x35, 0x34, 0x35, 0x34, 0x64, 0x66, /* 685454df */ +0x66, 0x39, 0x62, 0x35, 0x65, 0x66, 0x34, 0x66, /* f9b5ef4f */ +0x64, 0x22, 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, /* d"..Cach */ +0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, /* e-Contro */ +0x6c, 0x3a, 0x20, 0x6d, 0x61, 0x78, 0x2d, 0x61, /* l: max-a */ +0x67, 0x65, 0x3d, 0x30, 0x2c, 0x20, 0x70, 0x72, /* ge=0, pr */ +0x69, 0x76, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x6d, /* ivate, m */ +0x75, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x76, 0x61, /* ust-reva */ +0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x0d, 0x0a, /* lidate.. */ +0x58, 0x2d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, /* X-Reques */ +0x74, 0x2d, 0x49, 0x64, 0x3a, 0x20, 0x30, 0x30, /* t-Id: 00 */ +0x63, 0x61, 0x64, 0x31, 0x30, 0x36, 0x2d, 0x61, /* cad106-a */ +0x32, 0x34, 0x35, 0x2d, 0x34, 0x61, 0x39, 0x34, /* 245-4a94 */ +0x2d, 0x39, 0x61, 0x39, 0x36, 0x2d, 0x35, 0x31, /* -9a96-51 */ +0x37, 0x37, 0x66, 0x62, 0x61, 0x64, 0x34, 0x62, /* 77fbad4b */ +0x35, 0x64, 0x0d, 0x0a, 0x58, 0x2d, 0x52, 0x75, /* 5d..X-Ru */ +0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x20, 0x30, /* ntime: 0 */ +0x2e, 0x36, 0x34, 0x33, 0x37, 0x35, 0x30, 0x0d, /* .643750. */ +0x0a, 0x58, 0x2d, 0x50, 0x6f, 0x77, 0x65, 0x72, /* .X-Power */ +0x65, 0x64, 0x2d, 0x42, 0x79, 0x3a, 0x20, 0x50, /* ed-By: P */ +0x68, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x50, /* husion P */ +0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, /* assenger */ +0x20, 0x34, 0x2e, 0x30, 0x2e, 0x35, 0x37, 0x0d, /* 4.0.57. */ +0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x54, /* .Date: T */ +0x75, 0x65, 0x2c, 0x20, 0x32, 0x34, 0x20, 0x4d, /* ue, 24 M */ +0x61, 0x79, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, /* ay 2016 */ +0x32, 0x33, 0x3a, 0x32, 0x36, 0x3a, 0x33, 0x31, /* 23:26:31 */ +0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, /* GMT..Se */ +0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x6e, 0x67, /* rver: ng */ +0x69, 0x6e, 0x78, 0x2f, 0x31, 0x2e, 0x39, 0x2e, /* inx/1.9. */ +0x33, 0x20, 0x2b, 0x20, 0x50, 0x68, 0x75, 0x73, /* 3 + Phus */ +0x69, 0x6f, 0x6e, 0x20, 0x50, 0x61, 0x73, 0x73, /* ion Pass */ +0x65, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x34, 0x2e, /* enger 4. */ +0x30, 0x2e, 0x35, 0x37, 0x0d, 0x0a, 0x0d, 0x0a, /* 0.57.... */ +0x36, 0x38, 0x2e, 0x32 /* 68.2 */ +}; + +static int GET_firstreply_size = 638; + + +typedef struct HTTP_RESPONSE_STRUCT +{ + char *http_response_pkt_data; + int http_response_pkt_size; +} HTTP_RESPONSE; + + +static HTTP_RESPONSE http_response[2]; + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (800) +#define CLIENT_PACKET_POOL_SIZE ((CLIENT_PACKET_SIZE + sizeof(NX_PACKET)) * 4) +ULONG client_packet_pool_area[CLIENT_PACKET_POOL_SIZE/4 + 4]; + +static TX_THREAD client_thread; +static NX_HTTP_CLIENT my_client; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static UINT error_counter = 0; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (800) +#define SERVER_PACKET_POOL_SIZE ((SERVER_PACKET_SIZE + sizeof(NX_PACKET)) * 4) +ULONG server_packet_pool_area[SERVER_PACKET_POOL_SIZE/4 + 4]; + +/* Define the IP thread stack areas. */ + +ULONG server_ip_thread_stack[2 * 1024 / sizeof(ULONG)]; +ULONG client_ip_thread_stack[2 * 1024 / sizeof(ULONG)]; + +/* Define the ARP cache areas. */ + +ULONG server_arp_space_area[512 / sizeof(ULONG)]; +ULONG client_arp_space_area[512 / sizeof(ULONG)]; + + + +static NX_TCP_SOCKET server_socket; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + +static CHAR *pointer; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_client_change_connect_port_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + status = tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 5, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer , SERVER_PACKET_POOL_SIZE); + + pointer = pointer + SERVER_PACKET_POOL_SIZE; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "HTTP Server IP", + HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_POOL_SIZE); + + pointer = pointer + CLIENT_PACKET_POOL_SIZE; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *send_packet; + + /* wait for the server to set up */ + tx_thread_sleep(20); + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + { + + error_counter++; + } + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + if (status != FX_SUCCESS) + { + + error_counter++; + } + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1460); + if (status) + { + + error_counter++; + } + + /* Upload the 1st file to the server domain. */ +#ifdef __PRODUCT_NETXDUO__ + + status = nxd_http_client_put_start(&my_client, &server_ip_address, "http://www.abc.com/client_test.htm", + "name", "password", 103, 3 * NX_IP_PERIODIC_RATE); +#else + + status = nx_http_client_put_start(&my_client, server_ip_address, "http://www.abc.com/client_test.htm", + "name", "password", 103, 3 * NX_IP_PERIODIC_RATE); +#endif + + if (status) + { + + error_counter++; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + { + + error_counter++; + } + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + { + + + error_counter++; + } + + /* Based on information from the Server we need to connect on a different port. */ + status = nx_http_client_set_connect_port(&my_client, SECONDARY_SERVER_PORT); + + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Need a sleep to let the 'server' thread listen on the new port. */ + tx_thread_sleep(10); + + /* Send the 1st GET request to the server. */ +#ifdef __PRODUCT_NETXDUO__ + + status = nxd_http_client_get_start(&my_client, &server_ip_address, "http://www.abc.com/client_test.htm", + NX_NULL, 0, "name", "password", 100); +#else + + status = nx_http_client_get_start(&my_client, server_ip_address, "http://www.abc.com/client_test.htm", + NX_NULL, 0, "name", "password", 100); +#endif /* USE_DUO */ + + if(status) + { + + error_counter++; + } + + status = nx_http_client_delete(&my_client); + if(status) + { + + error_counter++; + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Client Change Connect Port Test......................"); + + /* Check for earlier error. */ + if(error_counter) + { + test_control_return(1); + } + + /* Create a TCP socket act as the HTTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + + error_counter++; + } + + /* Bind the TCP socket to the default HTTP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + + error_counter++; + } + + /* Load up the server 'responses'. */ + http_test_initialize(); + + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + error_counter++; + } + + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + error_counter++; + } + else + { + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Receive another TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + error_counter++; + } + + tx_thread_sleep(20); + + /* Send the TCP response packet. */ + status = nx_http_response_packet_send(&server_socket, 80, 0); + + /* Check status. */ + if (status) + { + + error_counter++; + } + + nx_tcp_socket_disconnect(&server_socket, 500); + + + /* Unaccept the server socket. */ + nx_tcp_server_socket_unaccept(&server_socket); + + nx_tcp_server_socket_unlisten(&server_ip, SERVER_PORT); + + /* Listen on the alternative server port. */ + status = nx_tcp_server_socket_listen(&server_ip, SECONDARY_SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + + error_counter++; + } + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + error_counter++; + } + + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + /* Release the packet. */ + nx_packet_release(my_packet); + } + + tx_thread_sleep(10); + + /* Send the TCP response packet. */ + nx_http_response_packet_send(&server_socket, 80, 1); + + + /* Wait for the client to terminate the connection. */ + tx_thread_sleep(20); + + /* Delete the TCP socket. */ + nx_tcp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +static void http_test_initialize() +{ + + http_response[0].http_response_pkt_data = &PUT_firstreply[0]; + http_response[0].http_response_pkt_size = PUT_firstreply_size; + + http_response[1].http_response_pkt_data = &GET_firstreply[0]; + http_response[1].http_response_pkt_size = GET_firstreply_size; + +} + + +static UINT nx_http_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + error_counter++; + } + + /* Write the HTTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, http_response[packet_number].http_response_pkt_data, + http_response[packet_number].http_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = http_response[packet_number].http_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + { + + nx_packet_release(response_packet); + } + + return status; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_client_change_connect_port_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Client Change Connect Port Test......................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_delete_basic_test.c b/test/regression/http_test/netx_http_delete_basic_test.c new file mode 100644 index 00000000..aa035d37 --- /dev/null +++ b/test/regression/http_test/netx_http_delete_basic_test.c @@ -0,0 +1,390 @@ +/* This case tests basic DELETE function. */ +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* This is a HTTP get packet captured by wireshark. DELETE index.html*/ +static char pkt[] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0xb8, 0xca, /* .."3DW.. */ +0x3a, 0x95, 0xdb, 0x0b, 0x08, 0x00, 0x45, 0x00, /* :.....E. */ +0x00, 0x81, 0x00, 0x21, 0x40, 0x00, 0x80, 0x06, /* ...!@... */ +0x78, 0x21, 0xc0, 0xa8, 0x00, 0x69, 0xc0, 0xa8, /* x!...i.. */ +0x00, 0x7b, 0xc1, 0x4b, 0x00, 0x50, 0x40, 0x81, /* .{.K.P@. */ +0xf0, 0x40, 0x77, 0x7f, 0x23, 0xc7, 0x50, 0x18, /* .@w.#.P. */ +0xfa, 0xf0, 0xf0, 0x51, 0x00, 0x00, 0x44, 0x45, /* ...Q..DE */ +0x4c, 0x45, 0x54, 0x45, 0x20, 0x2f, 0x69, 0x6e, /* LETE /in */ +0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x20, /* dex.htm */ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, /* HTTP/1.1 */ +0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, /* ..User-A */ +0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x75, /* gent: cu */ +0x72, 0x6c, 0x2f, 0x37, 0x2e, 0x33, 0x32, 0x2e, /* rl/7.32. */ +0x30, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, /* 0..Host: */ +0x20, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, /* 192.168 */ +0x2e, 0x30, 0x2e, 0x31, 0x32, 0x33, 0x0d, 0x0a, /* .0.123.. */ +0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, /* Accept: */ +0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a /* */ +}; + + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_HTTP_CLIENT my_client; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET client_socket; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(192,168,0,105) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(192,168,0,123) + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_delete_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, NX_NULL, NX_NULL); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *send_packet; +NX_PACKET *recv_packet; +NX_PACKET *my_packet; +CHAR *buffer_ptr; + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + /* Check the media open status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + + /* Check status. */ + if (status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + + /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */ + status = nxd_http_client_put_start(&my_client, &server_ip_address, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#else + + /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */ + status = nx_http_client_put_start(&my_client, HTTP_SERVER_ADDRESS, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + error_counter++; + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_http_client_delete(&my_client); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 50295, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, HTTP_SERVER_ADDRESS, 80, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Write DELETE packet into the packet payload. */ + status = nx_packet_data_append(my_packet, &pkt[54] , (sizeof(pkt)-54), &client_pool, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + + /* Receive the response from http server. */ + status = nx_tcp_socket_receive(&client_socket, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + buffer_ptr = (CHAR *)recv_packet ->nx_packet_prepend_ptr; + + /* Check the status, If success , it should be 200. */ + if((buffer_ptr[9] != '2') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '0')) + error_counter++; + + nx_packet_release(recv_packet); + } + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Delete Basic Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + error_counter++; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + status = nx_http_server_delete(&my_server); + if(status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_delete_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Delete Basic Test....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_digest_authenticate_test.c b/test/regression/http_test/netx_http_digest_authenticate_test.c new file mode 100644 index 00000000..6f021a2b --- /dev/null +++ b/test/regression/http_test/netx_http_digest_authenticate_test.c @@ -0,0 +1,528 @@ +/* This case tests digest authentication. + HA1 = MD5("name:NetX Duo HTTP demo:password") + = 01bb2595c9221423951ee86f3573b465 + HA2 = MD5("GET:/index.htm") + = d4b1da8c7955d2e98bc56ffc93003b44 + Response = MD5("01bb2595c9221423951ee86f3573b465: + nonce: + 00000001:0a4f113b:auth: + d4b1da8c7955d2e98bc56ffc93003b44") + */ +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_HTTP_DIGEST_ENABLE) + +#include "../web_test/http_digest_authentication.c" + + +#define DEMO_STACK_SIZE 4096 + +/* Set up FileX and file memory resources. */ +static CHAR ram_disk_memory[4096]; +static FX_MEDIA ram_disk; +static UCHAR media_memory[4096]; + +static UCHAR server_stack[16000]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_CLIENT_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_HTTP_CLIENT my_client; +static NX_IP client_ip; +static UINT error_counter; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + +static TX_SEMAPHORE server_start; +static TX_SEMAPHORE client_stop; + + +static UINT authentication_check(NX_HTTP_SERVER *server_ptr, UINT request_type, + CHAR *resource, CHAR **name, CHAR **password, CHAR **realm); +static UINT authentication_check_extended(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, CHAR **name, UINT *name_length, + CHAR **password, UINT *password_length, CHAR **realm, UINT *realm_length); + +static CHAR nonce_buffer[NX_HTTP_SERVER_NONCE_SIZE + 1]; +static CHAR temp_nonce_buffer[NX_HTTP_SERVER_NONCE_SIZE + 1]; +static CHAR response_buffer[32 + 1]; +static NX_MD5 client_md5data; + +static char pkt[] = { +0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x20, /* GET /index.htm */ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, /* HTTP/1.1.. */ +}; + +static UINT test_count; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_digest_authenticate_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + tx_semaphore_create(&server_start, "server start", 0); + tx_semaphore_create(&client_stop, "client stop", 0); +} + +void thread_client_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *send_packet; +NX_PACKET *recv_packet; +CHAR *buffer_ptr; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1536); + + /* Check status. */ + if (status) + error_counter++; + + for (test_count = 0; test_count < 2; test_count++) + { + tx_semaphore_get(&server_start, NX_WAIT_FOREVER); + + /* Bind the client socket. */ + status = nx_tcp_client_socket_bind(&(my_client.nx_http_client_socket), NX_ANY_PORT, NX_WAIT_FOREVER); + + /* Check status of the bind. */ + if (status) + error_counter++; + + /* Connect to the HTTP server. */ +#ifdef __PRODUCT_NETXDUO__ + + /* Invoke the 'Duo' (supports IPv6/IPv4) connection call. */ + status = nxd_tcp_client_socket_connect(&(my_client.nx_http_client_socket), &server_ip_address, + my_client.nx_http_client_connect_port, NX_WAIT_FOREVER); +#else + /* Invoke the NetX (IPv4 only) connection call. */ + status = nx_tcp_client_socket_connect(&(my_client.nx_http_client_socket), server_ip_address, + my_client.nx_http_client_connect_port, NX_WAIT_FOREVER); +#endif + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + nx_packet_data_append(send_packet, pkt, sizeof(pkt), &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 2, &client_pool, NX_WAIT_FOREVER); + + /* Send the request. */ + status = nx_tcp_socket_send(&(my_client.nx_http_client_socket), send_packet, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + + /* Initialize the buffer. */ + memset(nonce_buffer, 0, sizeof(nonce_buffer)); + memset(response_buffer, 0, sizeof(response_buffer)); + + /* Pickup the response from the Server. */ + status = nx_tcp_socket_receive(&(my_client.nx_http_client_socket), &recv_packet, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + else + { + status = http_nonce_retrieve(recv_packet, nonce_buffer); + if (status) + error_counter++; + nx_packet_release(recv_packet); + + /* Check if the nonce is regenerated. */ + if (test_count == 0) + { + memcpy(temp_nonce_buffer, nonce_buffer, sizeof(nonce_buffer)); + } + else + { + if (memcmp(temp_nonce_buffer, nonce_buffer, sizeof(nonce_buffer)) == 0) + { + error_counter++; + } + } + } + + http_digest_response_calculate(&client_md5data, "name", "NetX Duo HTTP demo", "password", nonce_buffer, "GET", + "/index.htm", "00000001", "0a4f113b", response_buffer); + + /* Disconnect and unbind the socket. */ + nx_tcp_socket_disconnect(&(my_client.nx_http_client_socket), NX_HTTP_CLIENT_TIMEOUT); + nx_tcp_client_socket_unbind(&(my_client.nx_http_client_socket)); + + /* Bind the client socket. */ + status = nx_tcp_client_socket_bind(&(my_client.nx_http_client_socket), NX_ANY_PORT, NX_WAIT_FOREVER); + + /* Check status of the bind. */ + if (status) + error_counter++; + + /* Connect to the HTTP server. */ +#ifdef __PRODUCT_NETXDUO__ + + /* Invoke the 'Duo' (supports IPv6/IPv4) connection call. */ + status = nxd_tcp_client_socket_connect(&(my_client.nx_http_client_socket), &server_ip_address, + my_client.nx_http_client_connect_port, NX_WAIT_FOREVER); +#else + /* Invoke the NetX (IPv4 only) connection call. */ + status = nx_tcp_client_socket_connect(&(my_client.nx_http_client_socket), server_ip_address, + my_client.nx_http_client_connect_port, NX_WAIT_FOREVER); +#endif + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + nx_packet_data_append(send_packet, pkt, sizeof(pkt), &client_pool, NX_WAIT_FOREVER); + + /* Build the Authorization header. */ + nx_packet_data_append(send_packet, "Authorization: Digest", 21, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, " username=\"name\",", 17, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, " realm=\"NetX Duo HTTP demo\",", 28, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, " nonce=\"", 8, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, nonce_buffer, NX_HTTP_SERVER_NONCE_SIZE, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\",", 2, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, " uri=\"/index.htm\",", 17, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, " qop=auth,", 10, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, " nc=00000001,", 13, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, " cnonce=\"0a4f113b\",", 19, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, " response=\"", 11, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, response_buffer, 32, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\",", 2, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, " opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"\r\n", 44, &client_pool, NX_WAIT_FOREVER); + + nx_packet_data_append(send_packet, "\r\n", 2, &client_pool, NX_WAIT_FOREVER); + + /* Now send the packet to the HTTP server. */ + status = nx_tcp_socket_send(&(my_client.nx_http_client_socket), send_packet, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + + /* Pickup the response from the Server. */ + status = nx_tcp_socket_receive(&(my_client.nx_http_client_socket), &recv_packet, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + buffer_ptr = (CHAR *)recv_packet->nx_packet_prepend_ptr; + + if (test_count == 0) + { + /* Check the status, If authentication success , it should be 200. */ + if ((buffer_ptr[9] != '2') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '0')) + error_counter++; + } + else + { + /* Check the status, If authentication fail , it should be 401. */ + if ((buffer_ptr[9] != '4') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '1')) + error_counter++; + } + + nx_packet_release(recv_packet); + } + + /* Disconnect and unbind the socket. */ + nx_tcp_socket_disconnect(&(my_client.nx_http_client_socket), NX_HTTP_CLIENT_TIMEOUT); + nx_tcp_client_socket_unbind(&(my_client.nx_http_client_socket)); + + tx_semaphore_put(&client_stop); + } + + status = nx_http_client_delete(&my_client); + if (status) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT digest_authenticate_callback(NX_HTTP_SERVER *server_ptr, CHAR *name_ptr, + CHAR *realm_ptr, CHAR *password_ptr, CHAR *method, + CHAR *authorization_uri, CHAR *authorization_nc, + CHAR *authorization_cnonce) +{ + + if (memcmp(authorization_nc, "00000001", 8) != 0) + { + return 1; + } + + if (test_count == 0) + { + /* Test authentication success. */ + return 0; + } + else + { + /* Test authentication fail. */ + return 1; + } +} + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; +FX_FILE my_file; + + + /* Print out test information banner. */ + printf("NetX Test: HTTP Digest Authenticate Test............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + fx_media_format(&ram_disk, + _fx_ram_driver, // Driver entry + ram_disk_memory, // RAM disk memory pointer + media_memory, // Media buffer pointer + sizeof(media_memory), // Media buffer size + "MY_RAM_DISK", // Volume Name + 1, // Number of FATs + 32, // Directory Entries + 0, // Hidden sectors + 256, // Total sectors + 512, // Sector size + 8, // Sectors per cluster + 1, // Heads + 1); // Sectors per track + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ; + if(status) + error_counter++; + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = fx_file_create(&ram_disk, "index.htm"); + status += fx_file_open(&ram_disk, &my_file, "index.htm", FX_OPEN_FOR_WRITE); + status += fx_file_write(&my_file, "https server", 12); + status += fx_file_close(&my_file); + if (status) + error_counter++; + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + server_stack, sizeof(server_stack), &server_pool, authentication_check, NX_NULL); + if (status) + error_counter++; + + nx_http_server_digest_authenticate_notify_set(&my_server, digest_authenticate_callback); + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if (status) + error_counter++; + + tx_semaphore_put(&server_start); + tx_semaphore_get(&client_stop, NX_WAIT_FOREVER); + + status = nx_http_server_authentication_check_set(&my_server, authentication_check_extended); + if (status) + error_counter++; + + tx_semaphore_put(&server_start); +} + +/* Define the application's authentication check. This is called by + the HTTP server whenever a new request is received. */ +static UINT authentication_check(NX_HTTP_SERVER *server_ptr, UINT request_type, + CHAR *resource, CHAR **name, CHAR **password, CHAR **realm) +{ + + /* Just use a simple name, password, and realm for all + requests and resources. */ + *name = "name"; + *password = "password"; + *realm = "NetX Duo HTTP demo"; + + /* Request digest authentication. */ + return(NX_HTTP_DIGEST_AUTHENTICATE); +} + +static UINT authentication_check_extended(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, CHAR **name, UINT *name_length, + CHAR **password, UINT *password_length, CHAR **realm, UINT *realm_length) +{ + + /* Just use a simple name, password, and realm for all + requests and resources. */ + *name = "name"; + *password = "password"; + *realm = "NetX Duo HTTP demo"; + *name_length = 4; + *password_length = 8; + *realm_length = 18; + + /* Request digest authentication. */ + return(NX_HTTP_DIGEST_AUTHENTICATE); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_digest_authenticate_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Digest Authenticate Test.............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/http_test/netx_http_digest_authenticate_timeout_test.c b/test/regression/http_test/netx_http_digest_authenticate_timeout_test.c new file mode 100644 index 00000000..d99a8abb --- /dev/null +++ b/test/regression/http_test/netx_http_digest_authenticate_timeout_test.c @@ -0,0 +1,531 @@ +/* This case tests digest authentication. + HA1 = MD5("name:NetX Duo HTTP demo:Placeholderpassword") + = 01bb2595c9221423951ee86f3573b465 + HA2 = MD5("GET:/index.htm") + = d4b1da8c7955d2e98bc56ffc93003b44 + Response = MD5("01bb2595c9221423951ee86f3573b465: + nonce: + 00000001:0a4f113b:auth: + d4b1da8c7955d2e98bc56ffc93003b44") + */ +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_HTTP_DIGEST_ENABLE) + +#include "../web_test/http_digest_authentication.c" + + +#define DEMO_STACK_SIZE 4096 + +/* Set up FileX and file memory resources. */ +static CHAR ram_disk_memory[4096]; +static FX_MEDIA ram_disk; +static UCHAR media_memory[4096]; + +static UCHAR server_stack[16000]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_CLIENT_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_HTTP_CLIENT my_client; +static NX_IP client_ip; +static UINT error_counter; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +static NX_TCP_SOCKET client_socket[NX_HTTP_SERVER_NONCE_MAX + 1]; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + +static TX_SEMAPHORE server_start; +static TX_SEMAPHORE client_stop; + +static UINT authentication_check(NX_HTTP_SERVER *server_ptr, UINT request_type, + CHAR *resource, CHAR **name, CHAR **password, CHAR **realm); + +static CHAR nonce_buffer[NX_HTTP_SERVER_NONCE_SIZE + 1]; +static CHAR temp_nonce_buffer[NX_HTTP_SERVER_NONCE_SIZE + 1]; +static CHAR response_buffer[32 + 1]; +static NX_MD5 client_md5data; + +static char pkt[] = { +0x47, 0x45, 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x20, /* GET /index.htm */ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, /* HTTP/1.1.. */ +}; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_digest_authenticate_timeout_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*16); + pointer = pointer + CLIENT_PACKET_SIZE * 16; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + tx_semaphore_create(&server_start, "server start", 0); + tx_semaphore_create(&client_stop, "client stop", 0); +} + +void thread_client_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *send_packet[NX_HTTP_SERVER_NONCE_MAX + 1]; +NX_PACKET *recv_packet; +CHAR *buffer_ptr; +INT i; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + tx_semaphore_get(&server_start, NX_WAIT_FOREVER); + + for (i = 0; i < NX_HTTP_SERVER_NONCE_MAX + 1; i++) + { + + /* Create an HTTP client instance. */ + status = nx_tcp_socket_create(&client_ip, &client_socket[i], "Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the client socket. */ + status = nx_tcp_client_socket_bind(&client_socket[i], NX_ANY_PORT, NX_WAIT_FOREVER); + + /* Check status of the bind. */ + if (status) + error_counter++; + + /* Connect to the HTTP server. */ +#ifdef __PRODUCT_NETXDUO__ + + /* Invoke the 'Duo' (supports IPv6/IPv4) connection call. */ + status = nxd_tcp_client_socket_connect(&client_socket[i], &server_ip_address, + NX_HTTP_SERVER_PORT, NX_WAIT_FOREVER); +#else + /* Invoke the NetX (IPv4 only) connection call. */ + status = nx_tcp_client_socket_connect(&client_socket[i], server_ip_address, + NX_HTTP_SERVER_PORT, NX_WAIT_FOREVER); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet[i], NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + nx_packet_data_append(send_packet[i], pkt, sizeof(pkt), &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], "\r\n", 2, &client_pool, NX_WAIT_FOREVER); + + /* Initialize the buffer. */ + memset(nonce_buffer, 0, sizeof(nonce_buffer)); + memset(response_buffer, 0, sizeof(response_buffer)); + + /* Send the request. */ + status = nx_tcp_socket_send(&client_socket[i], send_packet[i], NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + + /* Pickup the response from the Server. */ + status = nx_tcp_socket_receive(&client_socket[i], &recv_packet, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + else + { + + if (i == NX_HTTP_SERVER_NONCE_MAX) + { + buffer_ptr = (CHAR *)recv_packet->nx_packet_prepend_ptr; + + /* Check the status, no nonce entry, it should be 200. */ + if ((buffer_ptr[9] != '5') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '0')) + error_counter++; + + nx_packet_release(recv_packet); + + /* Discconect. */ + nx_tcp_socket_disconnect(&client_socket[i], NX_NO_WAIT); + + /* Sleep for the allocated nonce to be timed out. */ + tx_thread_sleep(NX_HTTP_SERVER_NONCE_TIMEOUT + NX_IP_PERIODIC_RATE); + + /* Reconnect to HTTP server. */ +#ifdef __PRODUCT_NETXDUO__ + + /* Invoke the 'Duo' (supports IPv6/IPv4) connection call. */ + status = nxd_tcp_client_socket_connect(&client_socket[i], &server_ip_address, + NX_HTTP_SERVER_PORT, NX_WAIT_FOREVER); +#else + /* Invoke the NetX (IPv4 only) connection call. */ + status = nx_tcp_client_socket_connect(&client_socket[i], server_ip_address, + NX_HTTP_SERVER_PORT, NX_WAIT_FOREVER); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet[i], NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + nx_packet_data_append(send_packet[i], pkt, sizeof(pkt), &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], "\r\n", 2, &client_pool, NX_WAIT_FOREVER); + + /* Initialize the buffer. */ + memset(nonce_buffer, 0, sizeof(nonce_buffer)); + memset(response_buffer, 0, sizeof(response_buffer)); + + /* Send the request. */ + status = nx_tcp_socket_send(&client_socket[i], send_packet[i], NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + + /* Pickup the response from the Server. */ + status = nx_tcp_socket_receive(&client_socket[i], &recv_packet, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + } + + /* Retrieve the nonce. */ + status = http_nonce_retrieve(recv_packet, nonce_buffer); + if (status) + error_counter++; + + nx_packet_release(recv_packet); + } + + /* Calculate the response. */ + http_digest_response_calculate(&client_md5data, "name", "NetX Duo HTTP demo", "Placeholderpassword", nonce_buffer, "GET", + "/index.htm", "00000001", "0a4f113b", response_buffer); + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet[i], NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + nx_packet_data_append(send_packet[i], pkt, sizeof(pkt), &client_pool, NX_WAIT_FOREVER); + + /* Build the Authorization header. */ + nx_packet_data_append(send_packet[i], "Authorization: Digest", 21, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], " username=\"name\",", 17, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], " realm=\"NetX Duo HTTP demo\",", 28, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], " nonce=\"", 8, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], nonce_buffer, NX_HTTP_SERVER_NONCE_SIZE, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], "\",", 2, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], " uri=\"/index.htm\",", 17, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], " qop=auth,", 10, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], " nc=00000001,", 13, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], " cnonce=\"0a4f113b\",", 19, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], " response=\"", 11, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], response_buffer, 32, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], "\",", 2, &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet[i], " opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"\r\n", 44, &client_pool, NX_WAIT_FOREVER); + + nx_packet_data_append(send_packet[i], "\r\n", 2, &client_pool, NX_WAIT_FOREVER); + + nx_tcp_socket_disconnect(&client_socket[i], NX_NO_WAIT); + } + + for (i = NX_HTTP_SERVER_NONCE_MAX; i >= 0; i--) + { + + /* Reconnect to the HTTP server. */ +#ifdef __PRODUCT_NETXDUO__ + + /* Invoke the 'Duo' (supports IPv6/IPv4) connection call. */ + status = nxd_tcp_client_socket_connect(&client_socket[i], &server_ip_address, + NX_HTTP_SERVER_PORT, NX_WAIT_FOREVER); +#else + /* Invoke the NetX (IPv4 only) connection call. */ + status = nx_tcp_client_socket_connect(&client_socket[i], server_ip_address, + NX_HTTP_SERVER_PORT, NX_WAIT_FOREVER); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Now send the packet to the HTTP server. */ + status = nx_tcp_socket_send(&client_socket[i], send_packet[i], NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + + /* Pickup the response from the Server. */ + status = nx_tcp_socket_receive(&client_socket[i], &recv_packet, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + buffer_ptr = (CHAR *)recv_packet->nx_packet_prepend_ptr; + + if (i == 0) + { + /* This nonce is timed out, the response should be 401. */ + if ((buffer_ptr[9] != '4') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '1')) + error_counter++; + } + else + { + /* Check the status, If authentication success , it should be 200. */ + if ((buffer_ptr[9] != '2') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '0')) + error_counter++; + } + + nx_packet_release(recv_packet); + } + + /* Disconnect and unbind the socket. */ + status = nx_tcp_socket_disconnect(&client_socket[i], NX_HTTP_CLIENT_TIMEOUT); + status += nx_tcp_client_socket_unbind(&client_socket[i]); + status += nx_tcp_socket_delete(&client_socket[i]); + if (status) + error_counter++; + } + + tx_semaphore_put(&client_stop); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; +FX_FILE my_file; + + + /* Print out test information banner. */ + printf("NetX Test: HTTP Digest Authenticate Timeout Test....................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + fx_media_format(&ram_disk, + _fx_ram_driver, // Driver entry + ram_disk_memory, // RAM disk memory pointer + media_memory, // Media buffer pointer + sizeof(media_memory), // Media buffer size + "MY_RAM_DISK", // Volume Name + 1, // Number of FATs + 32, // Directory Entries + 0, // Hidden sectors + 256, // Total sectors + 512, // Sector size + 8, // Sectors per cluster + 1, // Heads + 1); // Sectors per track + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)) ; + if(status) + error_counter++; + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = fx_file_create(&ram_disk, "index.htm"); + status += fx_file_open(&ram_disk, &my_file, "index.htm", FX_OPEN_FOR_WRITE); + status += fx_file_write(&my_file, "https server", 12); + status += fx_file_close(&my_file); + if (status) + error_counter++; + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + server_stack, sizeof(server_stack), &server_pool, authentication_check, NX_NULL); + if (status) + error_counter++; + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if (status) + error_counter++; + + tx_semaphore_put(&server_start); +} + +/* Define the application's authentication check. This is called by + the HTTP server whenever a new request is received. */ +static UINT authentication_check(NX_HTTP_SERVER *server_ptr, UINT request_type, + CHAR *resource, CHAR **name, CHAR **password, CHAR **realm) +{ + + /* Just use a simple name, password, and realm for all + requests and resources. */ + *name = "name"; + *password = "Placeholderpassword"; + *realm = "NetX Duo HTTP demo"; + + /* Request digest authentication. */ + return(NX_HTTP_DIGEST_AUTHENTICATE); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_digest_authenticate_timeout_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Digest Authenticate Timeout Test.....................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/http_test/netx_http_get_content_length_test.c b/test/regression/http_test/netx_http_get_content_length_test.c new file mode 100644 index 00000000..9e05ab43 --- /dev/null +++ b/test/regression/http_test/netx_http_get_content_length_test.c @@ -0,0 +1,615 @@ +/* This case tests the get content length task which should allow zero or more white + spaces between field name (Content-Length) and value. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static void http_test_initialize(); +static UINT nx_http_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); + + +char get_response_packet[130] = { +0x48, 0x54, /* ......HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, /* TP/1.0 2 */ +0x30, 0x30, 0x20, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, /* 00 ..Con */ +0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, /* tent-Len */ +0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, 0x31, 0x35, /* gth: 415 */ +0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* 4..Conte */ +0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, /* nt-Type: */ +0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* text/pl */ +0x61, 0x69, 0x6e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, /* ain....< */ +0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x0d, /* html>... */ +0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, /* .. */ +0x0a, 0x0d, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, /* ...Main W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x3c, 0x2f, 0x74, /* indow..< */ +0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, /* /head>.. */ +0x0d, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, /* .. */ + +}; + +int get_response_size = 130; + +char get_response_packet_nospace[129] = { +0x48, 0x54, /* ......HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, /* TP/1.0 2 */ +0x30, 0x30, 0x20, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, /* 00 ..Con */ +0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, /* tent-Len */ +0x67, 0x74, 0x68, 0x3a, 0x34, 0x31, 0x35, /* gth:415 */ +0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* 4..Conte */ +0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, /* nt-Type: */ +0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* text/pl */ +0x61, 0x69, 0x6e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, /* ain....< */ +0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x0d, /* html>... */ +0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, /* .. */ +0x0a, 0x0d, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, /* ...Main W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x3c, 0x2f, 0x74, /* indow..< */ +0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, /* /head>.. */ +0x0d, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, /* .. */ + +}; + +int get_response_packet_nospace_size = 129; + +char get_response_packet_3spaces[132] = { +0x48, 0x54, /* ......HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, /* TP/1.0 2 */ +0x30, 0x30, 0x20, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, /* 00 ..Con */ +0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, /* tent-Len */ +0x67, 0x74, 0x68, 0x3a, 0x20, 0x20, 0x20, 0x34, 0x31, 0x35, /* gth: 415 */ +0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* 4..Conte */ +0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, /* nt-Type: */ +0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* text/pl */ +0x61, 0x69, 0x6e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, /* ain....< */ +0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x0d, /* html>... */ +0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, /* .. */ +0x0a, 0x0d, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, /* ...Main W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x3c, 0x2f, 0x74, /* indow..< */ +0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, /* /head>.. */ +0x0d, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, /* .. */ + +}; +int get_response_packet_3spaces_size = 132; + +char get_response_packet_nolength[130] = { +0x48, 0x54, /* ......HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, /* TP/1.0 2 */ +0x30, 0x30, 0x20, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, /* 00 ..Con */ +0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, /* tent-Len */ +0x67, 0x74, 0x68, 0x3a, 0x20, 0x20, 0x20, 0x20, /* gth: */ +0x20, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* ..Conte */ +0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, /* nt-Type: */ +0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* text/pl */ +0x61, 0x69, 0x6e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, /* ain....< */ +0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x0d, /* html>... */ +0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, /* .. */ +0x0a, 0x0d, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, /* ...Main W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x3c, 0x2f, 0x74, /* indow..< */ +0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, /* /head>.. */ +0x0d, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, /* .. */ + +}; + +int get_response_packet_nolength_size = 130; + +char get_response_packet_nolength_400[130] = { +0x48, 0x54, /* ......HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, /* TP/1.0 4 */ +0x30, 0x30, 0x20, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, /* 00 ..Con */ +0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, /* tent-Len */ +0x67, 0x74, 0x68, 0x3a, 0x20, 0x20, 0x20, 0x20, /* gth: */ +0x20, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* ..Conte */ +0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, /* nt-Type: */ +0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* text/pl */ +0x61, 0x69, 0x6e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, /* ain....< */ +0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x0d, /* html>... */ +0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, /* .. */ +0x0a, 0x0d, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, /* ...Main W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x3c, 0x2f, 0x74, /* indow..< */ +0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, /* /head>.. */ +0x0d, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, /* .. */ + +}; + +int get_response_packet_nolength_400_size = 130; + +#define RESPONSE_COUNT 5 + +typedef struct HTTP_RESPONSE_STRUCT +{ + char *http_response_pkt_data; + int http_response_pkt_size; +} HTTP_RESPONSE; + + +static HTTP_RESPONSE http_response[RESPONSE_COUNT]; + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_HTTP_CLIENT my_client; +static NX_IP client_ip; +static UINT error_counter; +static UINT client_received_response = NX_FALSE; +static UINT server_start = NX_FALSE; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_TCP_SOCKET server_socket; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_get_content_length_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *send_packet; +UINT i; + + /* wait for the server to set up */ + tx_thread_sleep(50); + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + if (status != FX_SUCCESS) + error_counter++; + + /* Open four client connections, to test the response to Get Start. */ + for (i = 0; i < RESPONSE_COUNT; i++) + { + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 6 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if(status) + error_counter++; + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + while(!server_start) + tx_thread_sleep(10); + + /* Send a series of get requests to the Server, testing the ability to find Content-Length data + with different formats, including the last test where the response is missing the length. */ + + #ifdef __PRODUCT_NETXDUO__ + + /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */ + status = nxd_http_client_get_start(&my_client, &server_ip_address, + "/client_test.htm", NX_NULL, 0, "", "", 2 * NX_IP_PERIODIC_RATE); + #else + + /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */ + status = nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm", + NX_NULL, 0, "", "", 2 * NX_IP_PERIODIC_RATE); + #endif + + if (status && (i < 3)) + { + error_counter++; + } + else if ((i >= 3) && (status == NX_SUCCESS)) + { + error_counter++; + } + + server_start = NX_FALSE; + client_received_response = NX_TRUE; + + status = nx_http_client_delete(&my_client); + if(status) + error_counter++; + } + + if (client_pool.nx_packet_pool_invalid_releases) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Get Content-Length Test.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the HTTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the IP port. */ + status = nx_tcp_server_socket_listen(&server_ip, 80, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + http_test_initialize(); + + /* Act as the HTTP server to receive the Client query and send the HTTP server response. */ + for (i = 0; i < RESPONSE_COUNT; i++ ) + { + + server_start = NX_TRUE; + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + client_received_response = NX_FALSE; + + /* Send the TCP response packet. */ + status = nx_http_response_packet_send(&server_socket, 80, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + if (i < 3) + { + while(!client_received_response) + tx_thread_sleep(10); + } + + /* Done with SMTP connection. Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + error_counter++; + } + + if (i >= 3) + { + while(!client_received_response) + tx_thread_sleep(10); + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Unbind the UDP socket. */ + status = nx_tcp_server_socket_relisten(&server_ip, 80, &server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Unbind the UDP socket. */ + status = nx_tcp_server_socket_unlisten(&server_ip, 80); + + /* Check status. */ + if (status) + { + error_counter++; + } + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } +} + + +static void http_test_initialize() +{ + + http_response[0].http_response_pkt_data = &get_response_packet[0]; + http_response[0].http_response_pkt_size = get_response_size; + + http_response[1].http_response_pkt_data = &get_response_packet_nospace[0]; + http_response[1].http_response_pkt_size = get_response_packet_nospace_size; + + http_response[2].http_response_pkt_data = &get_response_packet_3spaces[0]; + http_response[2].http_response_pkt_size = get_response_packet_3spaces_size; + + http_response[3].http_response_pkt_data = &get_response_packet_nolength[0]; + http_response[3].http_response_pkt_size = get_response_packet_nolength_size; + + http_response[4].http_response_pkt_data = &get_response_packet_nolength_400[0]; + http_response[4].http_response_pkt_size = get_response_packet_nolength_400_size; + +} + + +static UINT nx_http_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the HTTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, http_response[packet_number].http_response_pkt_data, + http_response[packet_number].http_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = http_response[packet_number].http_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 200); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_get_content_length_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Get Content-Length Test..............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_get_contentlength_packetleak_test.c b/test/regression/http_test/netx_http_get_contentlength_packetleak_test.c new file mode 100644 index 00000000..8099aa57 --- /dev/null +++ b/test/regression/http_test/netx_http_get_contentlength_packetleak_test.c @@ -0,0 +1,646 @@ +/* This case tests the get content length task which should allow zero or more white + spaces between field name (Content-Length) and value. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 +#define SERVER_PORT 80 + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static void http_test_initialize(); +static UINT nx_http_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); + + +static char get_response_packet_nolabel[130] = { +0x48, 0x54, /* ......HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, /* TP/1.0 2 */ +0x30, 0x30, 0x20, 0x0d, 0x0a, 0x53, 0x6f, 0x6e, /* 00 ..XXn */ +0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, /* tent-Len */ +0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, 0x31, 0x35, /* gth: 415 */ +0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* 4..Conte */ +0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, /* nt-Type: */ +0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* text/pl */ +0x61, 0x69, 0x6e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, /* ain....< */ +0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x0d, /* html>... */ +0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, /* .. */ +0x0a, 0x0d, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, /* ...Main W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x3c, 0x2f, 0x74, /* indow..< */ +0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, /* /head>.. */ +0x0d, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, /* .. */ + +}; + +static int get_response_nolabel_size = 130; + + +static char get_response_packet_nolength[130] = { +0x48, 0x54, /* ......HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, /* TP/1.0 2 */ +0x30, 0x30, 0x20, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, /* 00 ..Con */ +0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, /* tent-Len */ +0x67, 0x74, 0x68, 0x3a, 0x20, 0x20, 0x20, 0x20, /* gth: */ +0x20, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* ..Conte */ +0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, /* nt-Type: */ +0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* text/pl */ +0x61, 0x69, 0x6e, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, /* ain....< */ +0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x0d, /* html>... */ +0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, /* .. */ +0x0a, 0x0d, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, /* ...Main W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x3c, 0x2f, 0x74, /* indow..< */ +0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, /* /head>.. */ +0x0d, 0x0a, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, /* .. */ + +}; + +static int get_response_packet_nolength_size = 130; + +static char get_response_ok_packet[130] = { +0x48, 0x54, /* ......HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, /* TP/1.0 2 */ +0x30, 0x30, 0x20, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, /* 00 ..Con */ +0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, /* tent-Len */ +0x67, 0x74, 0x68, 0x3a, 0x20, 0x20, 0x31, 0x30, /* gth: 10 */ +0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* 4..Conte */ +0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, /* nt-Type: */ +0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* text/pl */ +0x61, 0x69, 0x6e, 0x0e, 0x0a, 0x0d, 0x0b, 0x3c, /* ain....< */ +0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x0e, /* html>... */ +0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, /* .. */ +0x0a, 0x0d, 0x0b, 0x3c, 0x74, 0x69, 0x74, 0x6c, /* ...Main W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x3c, 0x2f, 0x74, /* indow..< */ +0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, /* /head>.. */ +0x0e, 0x0b, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, /* .. */ + +}; + +static int get_response_ok_size = 130; + +static char get_response_bad_packet[202] = { +0x48, 0x54, /* ......HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, /* TP/1.0 2 */ +0x30, 0x30, 0x20, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, /* 00 ..Con */ +0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, /* tent-Len */ +0x67, 0x74, 0x68, 0x3a, 0x20, 0x20, 0x31, 0x35, /* gth: 15 */ +0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, /* 4..Conte */ +0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, /* nt-Type: */ +0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, /* text/pl */ +0x61, 0x69, 0x6e, 0x0d, 0x0a, 0x0e, 0x0a, 0x3c, /* ain....< */ +0x68, 0x74, 0x6d, 0x6c, 0x3e, 0x0e, 0x0b, 0x0d, /* html>... */ +0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0d, /* .. */ +0x0a, 0x0e, 0x0a, 0x3c, 0x74, 0x69, 0x74, 0x6c, /* ...... */ +0x0a, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0e, /* .. */ +0x0b, 0x0d, 0x0b, 0x3c, 0x74, 0x69, 0x74, 0x6c, /* ...Main W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x3c, 0x2f, 0x74, /* indow..< */ +0x2f, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x0e, 0x0a, /* /head>.. */ +0x0d, 0x0b, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, /* .. */ + +}; + +static int get_response_bad_size = 202; + +#define RESPONSE_COUNT 4 + +typedef struct HTTP_RESPONSE_STRUCT +{ + char *http_response_pkt_data; + int http_response_pkt_size; +} HTTP_RESPONSE; + + +static HTTP_RESPONSE http_response[RESPONSE_COUNT]; + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 1) +#define CLIENT_PACKET_POOL_SIZE ((CLIENT_PACKET_SIZE + sizeof(NX_PACKET)) * 5) +ULONG client_packet_pool_area[CLIENT_PACKET_POOL_SIZE/4 + 4]; + +static TX_THREAD client_thread; +static NX_HTTP_CLIENT my_client; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static UINT error_counter; +static UINT client_received_response = NX_FALSE; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 1) +#define SERVER_PACKET_POOL_SIZE ((SERVER_PACKET_SIZE + sizeof(NX_PACKET)) * 5) +ULONG server_packet_pool_area[SERVER_PACKET_POOL_SIZE/4 + 4]; + +/* Define the IP thread stack areas. */ + +ULONG server_ip_thread_stack[2 * 1024 / sizeof(ULONG)]; +ULONG client_ip_thread_stack[2 * 1024 / sizeof(ULONG)]; + +/* Define the ARP cache areas. */ + +ULONG server_arp_space_area[512 / sizeof(ULONG)]; +ULONG client_arp_space_area[512 / sizeof(ULONG)]; + + + +static NX_TCP_SOCKET server_socket; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_get_contentlength_packetleak_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, (ULONG*)(((int)server_packet_pool_area + 15) & ~15) , SERVER_PACKET_POOL_SIZE); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "HTTP Server IP", + HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + (UCHAR*)server_ip_thread_stack, + sizeof(server_ip_thread_stack), + 1); + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *)server_arp_space_area, sizeof(server_arp_space_area)); + + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, (ULONG*)(((int)client_packet_pool_area + 15) & ~15) , CLIENT_PACKET_POOL_SIZE); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + (UCHAR*)client_ip_thread_stack, + sizeof(client_ip_thread_stack), + 1); + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *)client_arp_space_area, sizeof(client_arp_space_area)); + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *recv_packet; +UINT i; +UINT previously_available = 0; + + /* wait for the server to set up */ + tx_thread_sleep(50); + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + if (status != FX_SUCCESS) + error_counter++; + + /* Open four client connections, to test the response to Get Start. */ + for (i = 0; i < 3; i++) + { + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + if (status) + error_counter++; + + previously_available = client_pool.nx_packet_pool_available; + + /* Send a series of get requests to the Server, testing the ability to find Content-Length data + with different formats, including the last test where the response is missing the length. */ + +#ifdef __PRODUCT_NETXDUO__ + + /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */ + status = nxd_http_client_get_start(&my_client, &server_ip_address, + "/client_test.htm", NX_NULL, 0, "", "", 50); +#else + + /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */ + status = nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/client_test.htm", + NX_NULL, 0, "", "",50); +#endif + + if (status != NX_SUCCESS) + { + if (client_pool.nx_packet_pool_available != previously_available) + { + error_counter++; + } + + } + else /* get start does not fail, we request a GET packet*/ + { + + tx_thread_sleep(10); + previously_available = client_pool.nx_packet_pool_available; + + status = nx_http_client_get_packet(&my_client, &recv_packet, 200); + + if (status != NX_SUCCESS) + { + if (client_pool.nx_packet_pool_available != previously_available) + { + error_counter++; + } + } + } + + client_received_response = NX_TRUE; + tx_thread_sleep(50); + + status = nx_http_client_delete(&my_client); + if(status) + error_counter++; + } + + client_received_response = NX_TRUE; + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i, test_count; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Get Content Length Packet Leak Test.................."); + + /* Check for earlier error. */ + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the HTTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the IP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + http_test_initialize(); + + test_count = 2; + + /* Act as the HTTP server to receive the Client query and send the HTTP server response. */ + for (i = 0; i < test_count; i++ ) + { + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Send the TCP response packet. */ + status = nx_http_response_packet_send(&server_socket, 80, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + while(!client_received_response) + tx_thread_sleep(50); + + client_received_response = NX_FALSE; + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Unbind the UDP socket. */ + status = nx_tcp_server_socket_relisten(&server_ip, SERVER_PORT, &server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 30 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status ) + { + error_counter++; + } + + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + + /* Send the TCP response packet. */ + status = nx_http_response_packet_send(&server_socket, 80, 2); + + /* Check status. */ + if (status) + { + error_counter++; + + } + + /* Give Client a chance to process previous packet. */ + tx_thread_sleep(50); + + /* Send the fourth server response packet. */ + status = nx_http_response_packet_send(&server_socket, 80, 3); + + /* Check status. */ + if (status) + { + error_counter++; + } + + while(!client_received_response) + tx_thread_sleep(50); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Unbind the TCP socket. */ + status = nx_tcp_server_socket_unlisten(&server_ip, SERVER_PORT); + + /* Check status. */ + if (status) + { + error_counter++; + } + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + }; + +} + + +static void http_test_initialize() +{ + + http_response[0].http_response_pkt_data = &get_response_packet_nolabel[0]; + http_response[0].http_response_pkt_size = get_response_nolabel_size; + + http_response[1].http_response_pkt_data = &get_response_packet_nolength[0]; + http_response[1].http_response_pkt_size = get_response_packet_nolength_size; + + http_response[2].http_response_pkt_data = &get_response_ok_packet[0]; + http_response[2].http_response_pkt_size = get_response_ok_size; + + http_response[3].http_response_pkt_data = &get_response_bad_packet[0]; + http_response[3].http_response_pkt_size = get_response_bad_size; + +} + + +static UINT nx_http_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the HTTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, http_response[packet_number].http_response_pkt_data, + http_response[packet_number].http_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = http_response[packet_number].http_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 200); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_get_contentlength_packetleak_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Get Content Length Packet Leak Test..................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_get_put_referred_URI_test.c b/test/regression/http_test/netx_http_get_put_referred_URI_test.c new file mode 100644 index 00000000..1e594ebb --- /dev/null +++ b/test/regression/http_test/netx_http_get_put_referred_URI_test.c @@ -0,0 +1,629 @@ +/* This case tests the ability of the HTTP Client to accept a URI resource string that does not + designate a root directory based file location. If the string begins with an HTTP: or HTTPS: (not . + case sensitive) the HTTP Client will send the string as is. (Note this does not guarantee the HTTP server . + will forward to the referred location.) Otherwise the URI is processed as if it is root directory based, . + and a leading forward slash '/' is appended if one is missing. . + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#else +#include "nx_http_client.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define SERVER_PORT 80 + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static void http_test_initialize(); +static UINT nx_http_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number); + + +static char PUT_firstreply[202] = { +0x48, 0x54, /* HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x32, /* TP/1.1 2 */ +0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x44, /* 00 OK..D */ +0x61, 0x74, 0x65, 0x3a, 0x20, 0x54, 0x75, 0x65, /* ate: Tue */ +0x2c, 0x20, 0x32, 0x34, 0x20, 0x4d, 0x61, 0x79, /* , 24 May */ +0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x32, 0x33, /* 2016 23 */ +0x3a, 0x32, 0x36, 0x3a, 0x35, 0x34, 0x20, 0x47, /* :26:54 G */ +0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, 0x72, 0x76, /* MT..Serv */ +0x65, 0x72, 0x3a, 0x20, 0x4d, 0x61, 0x6b, 0x6f, /* er: Mako */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x6e, /* Server.n */ +0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, /* et..Cont */ +0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, /* ent-Type */ +0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, /* : text/h */ +0x74, 0x6d, 0x6c, 0x3b, 0x20, 0x63, 0x68, 0x61, /* tml; cha */ +0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, /* rset=utf */ +0x2d, 0x38, 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, /* -8..Cach */ +0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, /* e-Contro */ +0x6c, 0x3a, 0x20, 0x6e, 0x6f, 0x2d, 0x73, 0x74, /* l: no-st */ +0x6f, 0x72, 0x65, 0x2c, 0x20, 0x6e, 0x6f, 0x2d, /* ore, no- */ +0x63, 0x61, 0x63, 0x68, 0x65, 0x2c, 0x20, 0x6d, /* cache, m */ +0x75, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x76, 0x61, /* ust-reva */ +0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2c, 0x20, /* lidate, */ +0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, 0x3d, /* max-age= */ +0x30, 0x0d, 0x0a, 0x4b, 0x65, 0x65, 0x70, 0x2d, /* 0..Keep- */ +0x41, 0x6c, 0x69, 0x76, 0x65, 0x3a, 0x20, 0x43, /* Alive: C */ +0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x0d, 0x0a /* lose.... */ +}; + +static int PUT_firstreply_size = 202; + + +static char GET_firstreply[638] = { +0x48, 0x54, /* HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x32, /* TP/1.1 2 */ +0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x43, /* 00 OK..C */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, /* ontent-T */ +0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, /* ype: tex */ +0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3b, 0x20, /* t/html; */ +0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, /* charset= */ +0x75, 0x74, 0x66, 0x2d, 0x38, 0x0d, 0x0a, 0x43, /* utf-8..C */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, /* ontent-L */ +0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34, /* ength: 4 */ +0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, /* ..Connec */ +0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, /* tion: cl */ +0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x53, 0x74, 0x61, /* ose..Sta */ +0x74, 0x75, 0x73, 0x3a, 0x20, 0x32, 0x30, 0x30, /* tus: 200 */ +0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x58, 0x2d, 0x46, /* OK..X-F */ +0x72, 0x61, 0x6d, 0x65, 0x2d, 0x4f, 0x70, 0x74, /* rame-Opt */ +0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x20, 0x41, 0x4c, /* ions: AL */ +0x4c, 0x4f, 0x57, 0x41, 0x4c, 0x4c, 0x0d, 0x0a, /* LOWALL.. */ +0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x43, /* Access-C */ +0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x41, /* ontrol-A */ +0x6c, 0x6c, 0x6f, 0x77, 0x2d, 0x4f, 0x72, 0x69, /* llow-Ori */ +0x67, 0x69, 0x6e, 0x3a, 0x20, 0x2a, 0x0d, 0x0a, /* gin: *.. */ +0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x43, /* Access-C */ +0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x41, /* ontrol-A */ +0x6c, 0x6c, 0x6f, 0x77, 0x2d, 0x4d, 0x65, 0x74, /* llow-Met */ +0x68, 0x6f, 0x64, 0x73, 0x3a, 0x20, 0x47, 0x45, /* hods: GE */ +0x54, 0x2c, 0x20, 0x50, 0x4f, 0x53, 0x54, 0x2c, /* T, POST, */ +0x20, 0x50, 0x55, 0x54, 0x2c, 0x20, 0x4f, 0x50, /* PUT, OP */ +0x54, 0x49, 0x4f, 0x4e, 0x53, 0x2c, 0x20, 0x44, /* TIONS, D */ +0x45, 0x4c, 0x45, 0x54, 0x45, 0x2c, 0x20, 0x50, /* ELETE, P */ +0x41, 0x54, 0x43, 0x48, 0x0d, 0x0a, 0x41, 0x63, /* ATCH..Ac */ +0x63, 0x65, 0x73, 0x73, 0x2d, 0x43, 0x6f, 0x6e, /* cess-Con */ +0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x41, 0x6c, 0x6c, /* trol-All */ +0x6f, 0x77, 0x2d, 0x48, 0x65, 0x61, 0x64, 0x65, /* ow-Heade */ +0x72, 0x73, 0x3a, 0x20, 0x6f, 0x72, 0x69, 0x67, /* rs: orig */ +0x69, 0x6e, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, /* in, cont */ +0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, /* ent-type */ +0x2c, 0x20, 0x58, 0x2d, 0x52, 0x65, 0x71, 0x75, /* , X-Requ */ +0x65, 0x73, 0x74, 0x65, 0x64, 0x2d, 0x57, 0x69, /* ested-Wi */ +0x74, 0x68, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, /* th..Acce */ +0x73, 0x73, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, /* ss-Contr */ +0x6f, 0x6c, 0x2d, 0x4d, 0x61, 0x78, 0x2d, 0x41, /* ol-Max-A */ +0x67, 0x65, 0x3a, 0x20, 0x31, 0x38, 0x30, 0x30, /* ge: 1800 */ +0x0d, 0x0a, 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, /* ..ETag: */ +0x22, 0x36, 0x30, 0x35, 0x39, 0x38, 0x32, 0x38, /* "6059828 */ +0x32, 0x63, 0x65, 0x36, 0x38, 0x32, 0x38, 0x66, /* 2ce6828f */ +0x36, 0x38, 0x35, 0x34, 0x35, 0x34, 0x64, 0x66, /* 685454df */ +0x66, 0x39, 0x62, 0x35, 0x65, 0x66, 0x34, 0x66, /* f9b5ef4f */ +0x64, 0x22, 0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, /* d"..Cach */ +0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, /* e-Contro */ +0x6c, 0x3a, 0x20, 0x6d, 0x61, 0x78, 0x2d, 0x61, /* l: max-a */ +0x67, 0x65, 0x3d, 0x30, 0x2c, 0x20, 0x70, 0x72, /* ge=0, pr */ +0x69, 0x76, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x6d, /* ivate, m */ +0x75, 0x73, 0x74, 0x2d, 0x72, 0x65, 0x76, 0x61, /* ust-reva */ +0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x0d, 0x0a, /* lidate.. */ +0x58, 0x2d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, /* X-Reques */ +0x74, 0x2d, 0x49, 0x64, 0x3a, 0x20, 0x30, 0x30, /* t-Id: 00 */ +0x63, 0x61, 0x64, 0x31, 0x30, 0x36, 0x2d, 0x61, /* cad106-a */ +0x32, 0x34, 0x35, 0x2d, 0x34, 0x61, 0x39, 0x34, /* 245-4a94 */ +0x2d, 0x39, 0x61, 0x39, 0x36, 0x2d, 0x35, 0x31, /* -9a96-51 */ +0x37, 0x37, 0x66, 0x62, 0x61, 0x64, 0x34, 0x62, /* 77fbad4b */ +0x35, 0x64, 0x0d, 0x0a, 0x58, 0x2d, 0x52, 0x75, /* 5d..X-Ru */ +0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x20, 0x30, /* ntime: 0 */ +0x2e, 0x36, 0x34, 0x33, 0x37, 0x35, 0x30, 0x0d, /* .643750. */ +0x0a, 0x58, 0x2d, 0x50, 0x6f, 0x77, 0x65, 0x72, /* .X-Power */ +0x65, 0x64, 0x2d, 0x42, 0x79, 0x3a, 0x20, 0x50, /* ed-By: P */ +0x68, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x50, /* husion P */ +0x61, 0x73, 0x73, 0x65, 0x6e, 0x67, 0x65, 0x72, /* assenger */ +0x20, 0x34, 0x2e, 0x30, 0x2e, 0x35, 0x37, 0x0d, /* 4.0.57. */ +0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x54, /* .Date: T */ +0x75, 0x65, 0x2c, 0x20, 0x32, 0x34, 0x20, 0x4d, /* ue, 24 M */ +0x61, 0x79, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, /* ay 2016 */ +0x32, 0x33, 0x3a, 0x32, 0x36, 0x3a, 0x33, 0x31, /* 23:26:31 */ +0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65, /* GMT..Se */ +0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x6e, 0x67, /* rver: ng */ +0x69, 0x6e, 0x78, 0x2f, 0x31, 0x2e, 0x39, 0x2e, /* inx/1.9. */ +0x33, 0x20, 0x2b, 0x20, 0x50, 0x68, 0x75, 0x73, /* 3 + Phus */ +0x69, 0x6f, 0x6e, 0x20, 0x50, 0x61, 0x73, 0x73, /* ion Pass */ +0x65, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x34, 0x2e, /* enger 4. */ +0x30, 0x2e, 0x35, 0x37, 0x0d, 0x0a, 0x0d, 0x0a, /* 0.57.... */ +0x36, 0x38, 0x2e, 0x32 /* 68.2 */ +}; + +static int GET_firstreply_size = 638; + + +typedef struct HTTP_RESPONSE_STRUCT +{ + char *http_response_pkt_data; + int http_response_pkt_size; +} HTTP_RESPONSE; + + +static HTTP_RESPONSE http_response[2]; + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (800) +#define CLIENT_PACKET_POOL_SIZE ((CLIENT_PACKET_SIZE + sizeof(NX_PACKET)) * 4) +ULONG client_packet_pool_area[CLIENT_PACKET_POOL_SIZE/4 + 4]; + +static TX_THREAD client_thread; +static NX_HTTP_CLIENT my_client; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static UINT error_counter = 0; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (800) +#define SERVER_PACKET_POOL_SIZE ((SERVER_PACKET_SIZE + sizeof(NX_PACKET)) * 4) +ULONG server_packet_pool_area[SERVER_PACKET_POOL_SIZE/4 + 4]; + +/* Define the IP thread stack areas. */ + +ULONG server_ip_thread_stack[2 * 1024 / sizeof(ULONG)]; +ULONG client_ip_thread_stack[2 * 1024 / sizeof(ULONG)]; + +/* Define the ARP cache areas. */ + +ULONG server_arp_space_area[512 / sizeof(ULONG)]; +ULONG client_arp_space_area[512 / sizeof(ULONG)]; + + + +static NX_TCP_SOCKET server_socket; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + +static CHAR *pointer; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_get_put_referred_URI_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + status = tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 5, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer , SERVER_PACKET_POOL_SIZE); + + pointer = pointer + SERVER_PACKET_POOL_SIZE; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "HTTP Server IP", + HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_POOL_SIZE); + + pointer = pointer + CLIENT_PACKET_POOL_SIZE; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *send_packet; + + /* wait for the server to set up */ + tx_thread_sleep(20); + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + if (status != FX_SUCCESS) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1460); + if (status) + error_counter++; + + /* Upload the 1st file to the server domain. */ +#ifdef __PRODUCT_NETXDUO__ + + status = nxd_http_client_put_start(&my_client, &server_ip_address, "http://www.abc.com/client_test.htm", + "name", "password", 103, 3 * NX_IP_PERIODIC_RATE); +#else + + status = nx_http_client_put_start(&my_client, server_ip_address, "http://www.abc.com/client_test.htm", + "name", "password", 103, 3 * NX_IP_PERIODIC_RATE); +#endif + + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + { + error_counter++; + } + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + { + error_counter++; + } + + tx_thread_sleep(10); + + /* Send the 1st GET request to the server. */ +#ifdef __PRODUCT_NETXDUO__ + + status = nxd_http_client_get_start(&my_client, &server_ip_address, "http://www.abc.com/client_test.htm", + NX_NULL, 0, "name", "password", 100); +#else + + status = nx_http_client_get_start(&my_client, server_ip_address, "http://www.abc.com/client_test.htm", + NX_NULL, 0, "name", "password", 100); +#endif /* USE_DUO */ + + if(status) + { + error_counter++; + } + + nx_http_client_delete(&my_client); + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: HTTP GET PUT Referred URI Test............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the HTTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the IP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + http_test_initialize(); + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Receive another TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + error_counter++; + } + else + { + /* Release the packet. */ + nx_packet_release(my_packet); + } + + tx_thread_sleep(20); + + /* Send the TCP response packet. */ + nx_http_response_packet_send(&server_socket, 80, 0); + + nx_tcp_socket_disconnect(&server_socket, 500); + + /* Unaccept the server socket. */ + nx_tcp_server_socket_unaccept(&server_socket); + + nx_tcp_server_socket_relisten(&server_ip, SERVER_PORT, &server_socket); + + /* Wait for a 2nd connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + /* Release the packet. */ + nx_packet_release(my_packet); + } + + tx_thread_sleep(10); + + /* Send the TCP response packet. */ + nx_http_response_packet_send(&server_socket, 80, 1); + + /* Wait for the client to terminate the connection. */ + tx_thread_sleep(20); + + /* Delete the TCP socket. */ + nx_tcp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +static void http_test_initialize() +{ + + http_response[0].http_response_pkt_data = &PUT_firstreply[0]; + http_response[0].http_response_pkt_size = PUT_firstreply_size; + + http_response[1].http_response_pkt_data = &GET_firstreply[0]; + http_response[1].http_response_pkt_size = GET_firstreply_size; + +} + + +static UINT nx_http_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, INT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the HTTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, http_response[packet_number].http_response_pkt_data, + http_response[packet_number].http_response_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = http_response[packet_number].http_response_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + nx_packet_release(response_packet); + + return status; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_get_put_referred_URI_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP GET PUT Referred URI Test............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_head_basic_test.c b/test/regression/http_test/netx_http_head_basic_test.c new file mode 100644 index 00000000..c0a085ab --- /dev/null +++ b/test/regression/http_test/netx_http_head_basic_test.c @@ -0,0 +1,390 @@ +/* This case tests basic HEAD method. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* This is a HTTP get packet captured by wireshark. HEAD index.html*/ +static char pkt[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0xb8, 0xca, /* .."3DW.. */ + 0x3a, 0x95, 0xdb, 0x0b, 0x08, 0x00, 0x45, 0x00, /* :.....E. */ + 0x00, 0x7f, 0x0f, 0xef, 0x40, 0x00, 0x80, 0x06, /* ....@... */ + 0x68, 0x55, 0xc0, 0xa8, 0x00, 0x69, 0xc0, 0xa8, /* hU...i.. */ + 0x00, 0x7b, 0xcf, 0xf1, 0x00, 0x50, 0x64, 0x0c, /* .{...Pd. */ + 0x11, 0x41, 0x77, 0x7f, 0x23, 0xc7, 0x50, 0x18, /* .Aw.#.P. */ + 0xfa, 0xf0, 0xf8, 0x68, 0x00, 0x00, 0x48, 0x45, /* ...h..HE */ + 0x41, 0x44, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x65, /* AD /inde */ + 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x20, 0x48, 0x54, /* x.htm HT */ + 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, /* TP/1.1.. */ + 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, /* User-Age */ + 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x75, 0x72, 0x6c, /* nt: curl */ + 0x2f, 0x37, 0x2e, 0x33, 0x32, 0x2e, 0x30, 0x0d, /* /7.32.0. */ + 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, /* .Host: 1 */ + 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, /* 92.168.0 */ + 0x2e, 0x31, 0x32, 0x33, 0x0d, 0x0a, 0x41, 0x63, /* .123..Ac */ + 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, /* cept: */ + 0x2a, 0x0d, 0x0a, 0x0d, 0x0a /* *.... */ +}; + + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_HTTP_CLIENT my_client; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET client_socket; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(192,168,0,105) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(192,168,0,123) + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_head_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, NX_NULL, NX_NULL); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *send_packet; +NX_PACKET *recv_packet; +NX_PACKET *my_packet; +CHAR *buffer_ptr; + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + /* Check the media open status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + + /* Check status. */ + if (status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + + /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */ + status = nxd_http_client_put_start(&my_client, &server_ip_address, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#else + + /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */ + status = nx_http_client_put_start(&my_client, HTTP_SERVER_ADDRESS, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + error_counter++; + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_http_client_delete(&my_client); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 50295, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, HTTP_SERVER_ADDRESS, 80, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Write HEAD packet into the packet payload. */ + status = nx_packet_data_append(my_packet, &pkt[54] , (sizeof(pkt)-54), &client_pool, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + + /* Receive the response from http server. */ + status = nx_tcp_socket_receive(&client_socket, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + buffer_ptr = (CHAR *)recv_packet ->nx_packet_prepend_ptr; + + /* Check the status, If success , it should be 200. */ + if((buffer_ptr[9] != '2') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '0')) + error_counter++; + + nx_packet_release(recv_packet); + } + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Head Basic Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + error_counter++; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + status = nx_http_server_delete(&my_server); + if(status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_head_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Head Basic Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_if_modified_since_test.c b/test/regression/http_test/netx_http_if_modified_since_test.c new file mode 100644 index 00000000..5c91897a --- /dev/null +++ b/test/regression/http_test/netx_http_if_modified_since_test.c @@ -0,0 +1,464 @@ +/* This case tests filed If-Modified-field. + * if the requested variant has not been modified since the time specified in this field, + * an entity will not be returned from the server; instead, a 304 (not modified) response + * will be returned without any message-body. + * + * In this case, client get the index.htm with If-Modified-Since = 20130101, and index.htm is + * modified on 2013...., So server should send 304. + * */ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + + +#if defined(WIN32) || defined(__linux__) +#include +#include +#include +#endif /* defined(WIN32) || defined(__linux__) */ + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + + +/* Frame (190 bytes) */ +/* This is a HTTP get packet captured by wireshark. If-Modified-since = 20130101 .*/ +static char pkt[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0xb8, 0xca, /* .."3DW.. */ + 0x3a, 0x95, 0xdb, 0x0b, 0x08, 0x00, 0x45, 0x00, /* :.....E. */ + 0x00, 0xb0, 0x09, 0xb8, 0x40, 0x00, 0x80, 0x06, /* ....@... */ + 0x6e, 0x5b, 0xc0, 0xa8, 0x00, 0x69, 0xc0, 0xa8, /* n[...i.. */ + 0x00, 0x7b, 0xc4, 0x77, 0x00, 0x50, 0x51, 0x6d, /* .{.w.PQm */ + 0xbc, 0x22, 0x77, 0x7f, 0x23, 0xc7, 0x50, 0x18, /* ."w.#.P. */ + 0xfa, 0xf0, 0x20, 0x9c, 0x00, 0x00, 0x47, 0x45, /* .. ...GE */ + 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, /* T /index */ + 0x2e, 0x68, 0x74, 0x6d, 0x20, 0x48, 0x54, 0x54, /* .htm HTT */ + 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x55, /* P/1.1..U */ + 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, /* ser-Agen */ + 0x74, 0x3a, 0x20, 0x63, 0x75, 0x72, 0x6c, 0x2f, /* t: curl/ */ + 0x37, 0x2e, 0x33, 0x32, 0x2e, 0x30, 0x0d, 0x0a, /* 7.32.0.. */ + 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, /* Host: 19 */ + 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, /* 2.168.0. */ + 0x31, 0x32, 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, /* 123..Acc */ + 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, /* ept: */ + 0x0d, 0x0a, 0x49, 0x66, 0x2d, 0x4d, 0x6f, 0x64, /* ..If-Mod */ + 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x53, 0x69, /* ified-Si */ + 0x6e, 0x63, 0x65, 0x3a, 0x20, 0x54, 0x75, 0x65, /* nce: Tue */ + 0x2c, 0x20, 0x30, 0x31, 0x20, 0x4a, 0x61, 0x6e, /* , 01 Jan */ + 0x20, 0x32, 0x30, 0x31, 0x33, 0x20, 0x30, 0x30, /* 2013 00 */ + 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x20, 0x47, /* :00:00 G */ + 0x4d, 0x54, 0x0d, 0x0a, 0x0d, 0x0a /* MT.... */ +}; + + + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +#if defined(WIN32) || defined(__linux__) +static VOID get_gmt(NX_HTTP_SERVER_DATE *now); +static UINT cache_info_get(CHAR *resource, UINT *max_age, NX_HTTP_SERVER_DATE *last_modified); +#endif + + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_HTTP_CLIENT my_client; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET client_socket; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(192,168,0,105) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(192,168,0,123) + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_if_modified_since_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, NX_NULL, NX_NULL); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +#if defined(WIN32) || defined(__linux__) + nx_http_server_gmt_callback_set(&my_server, get_gmt); + nx_http_server_cache_info_callback_set(&my_server, cache_info_get); +#endif /* WIN32 || __linux__ */ + +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *send_packet; +NX_PACKET *recv_packet; +NX_PACKET *my_packet; +CHAR *buffer_ptr; + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + /* Check the media open status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + + /* Check status. */ + if (status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + + /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */ + status = nxd_http_client_put_start(&my_client, &server_ip_address, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#else + + /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */ + status = nx_http_client_put_start(&my_client, HTTP_SERVER_ADDRESS, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + error_counter++; + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_http_client_delete(&my_client); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 50295, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, HTTP_SERVER_ADDRESS, 80, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Write If-Mdified-since Get packet into the packet payload. */ + status = nx_packet_data_append(my_packet, &pkt[54] , (sizeof(pkt)-54), &client_pool, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + + /* Receive the response from http server. */ + status = nx_tcp_socket_receive(&client_socket, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + + buffer_ptr = (CHAR *)recv_packet ->nx_packet_prepend_ptr; + + /* Check the status, If success , it should be 304. */ + if((buffer_ptr[9] != '3') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '4')) + error_counter++; + + nx_packet_release(recv_packet); + } + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP If Modified Since Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + error_counter++; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + status = nx_http_server_delete(&my_server); + if(status) + error_counter++; + +} + + +#if defined(WIN32) || defined(__linux__) +VOID get_gmt(NX_HTTP_SERVER_DATE *now) +{ +time_t rawtime; +struct tm *timeinfo; + + time (&rawtime); + timeinfo = gmtime(&rawtime); + + now -> nx_http_server_day = timeinfo -> tm_mday; + now -> nx_http_server_month = timeinfo -> tm_mon; + now -> nx_http_server_year = timeinfo -> tm_year + 1900; + now -> nx_http_server_hour = timeinfo -> tm_hour; + now -> nx_http_server_minute = timeinfo -> tm_min; + now -> nx_http_server_second = timeinfo -> tm_sec; + now -> nx_http_server_weekday = timeinfo -> tm_wday; + + +} + + +UINT cache_info_get(CHAR *resource, UINT *max_age, NX_HTTP_SERVER_DATE *last_modified) +{ + *max_age = 315360000; + + /* 0130101 */ + last_modified -> nx_http_server_day = 1; + last_modified -> nx_http_server_month = 0; + last_modified -> nx_http_server_year = 113 + 1900; /* 2013 */ + last_modified -> nx_http_server_hour = 0; + last_modified -> nx_http_server_minute = 0; + last_modified -> nx_http_server_second = 0; + last_modified -> nx_http_server_weekday = 2; + + return NX_TRUE; +} +#endif /* WIN32 || __linux__ */ + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_if_modified_since_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP If Modified Since Test...............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_multipart_fragment_test.c b/test/regression/http_test/netx_http_multipart_fragment_test.c new file mode 100644 index 00000000..fdbf8381 --- /dev/null +++ b/test/regression/http_test/netx_http_multipart_fragment_test.c @@ -0,0 +1,599 @@ +/* This case tests whether HTTP server can work well with multipart/form-data. + * server packet size 800 + * client packet size 1400 + * pkt size is bigger than 1500 to cause client/server fragmentation. + */ + +/* Here is the packet content. */ +/* +------------------------------4ebf00fbcf09 +Content-Disposition: form-data; name="example" + +testtest(repeat 49 times) +------------------------------4ebf00fbcf09 +Content-Disposition: form-data; name="example2" + +test2test2(repeat 35 times) +------------------------------4ebf00fbcf09 +Content-Disposition: form-data; name="example3" + +test3test3(repeat 39 times) +------------------------------4ebf00fbcf09 +Content-Disposition: form-data; name="example4" + +test4test4(repeat 51times) +------------------------------4ebf00fbcf09 +Content-Disposition: form-data; name="example5" + +test5(repeat 54times) +------------------------------4ebf00fbcf09-- +*/ + +/* length1 = 196, + * length2 = 175, + * length3 = 195, + * length4 = 205 + * length5 = 220. + * */ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" + +extern void test_control_return(UINT); +#if defined(NX_HTTP_MULTIPART_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +#define DEMO_STACK_SIZE 4096 + +/* This is a HTTP get packet captured by wireshark. HEAD index.html*/ +static char pkt[] = { + 0x50, 0x4f, 0x53, 0x54, 0x20, 0x2f, 0x20, 0x48, /* POST / H */ + 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, /* TTP/1.1. */ + 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, /* .User-Ag */ + 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x75, 0x72, /* ent: cur */ + 0x6c, 0x2f, 0x37, 0x2e, 0x33, 0x32, 0x2e, 0x30, /* l/7.32.0 */ + 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, /* ..Host: */ + 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, /* 192.168. */ + 0x30, 0x2e, 0x31, 0x32, 0x33, 0x0d, 0x0a, 0x41, /* 0.123..A */ + 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, /* ccept: * */ + 0x2f, 0x2a, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, /* *..Cont */ + 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, /* ent-Type */ + 0x3a, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* : multip */ + 0x61, 0x72, 0x74, 0x2f, 0x66, 0x6f, 0x72, 0x6d, /* art/form */ + 0x2d, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x20, 0x62, /* -data; b */ + 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x3d, /* oundary= */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, /* ----4ebf */ + 0x30, 0x30, 0x66, 0x62, 0x63, 0x66, 0x30, 0x39, /* 00fbcf09 */ + 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* ..Conten */ + 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, /* t-Length */ + 0x3a, 0x20, 0x31, 0x35, 0x32, 0x31, 0x0d, 0x0a, /* : 1521.. */ + 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x3a, 0x20, /* Expect: */ + 0x31, 0x30, 0x30, 0x2d, 0x63, 0x6f, 0x6e, 0x74, /* 100-cont */ + 0x69, 0x6e, 0x75, 0x65, 0x0d, 0x0a, 0x0d, 0x0a, /* inue.... */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, /* ------4e */ + 0x62, 0x66, 0x30, 0x30, 0x66, 0x62, 0x63, 0x66, /* bf00fbcf */ + 0x30, 0x39, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, /* 09..Cont */ + 0x65, 0x6e, 0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, /* ent-Disp */ + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, /* osition: */ + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, /* form-da */ + 0x74, 0x61, 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, /* ta; name */ + 0x3d, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, /* ="exampl */ + 0x65, 0x22, 0x0d, 0x0a, 0x0d, 0x0a, 0x74, 0x65, /* e"....te */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, /* st..---- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, 0x30, 0x30, /* --4ebf00 */ + 0x66, 0x62, 0x63, 0x66, 0x30, 0x39, 0x0d, 0x0a, /* fbcf09.. */ + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, /* Content- */ + 0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x69, 0x74, /* Disposit */ + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x6f, 0x72, /* ion: for */ + 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x20, /* m-data; */ + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x65, 0x78, /* name="ex */ + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x32, 0x22, 0x0d, /* ample2". */ + 0x0a, 0x0d, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x32, /* ...test2 */ + 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */ + 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */ + 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */ + 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */ + 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */ + 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */ + 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */ + 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */ + 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */ + 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */ + 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */ + 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */ + 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */ + 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */ + 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */ + 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */ + 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */ + 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */ + 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */ + 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */ + 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */ + 0x74, 0x32, 0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, /* t2..---- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, 0x30, 0x30, /* --4ebf00 */ + 0x66, 0x62, 0x63, 0x66, 0x30, 0x39, 0x0d, 0x0a, /* fbcf09.. */ + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, /* Content- */ + 0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x69, 0x74, /* Disposit */ + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x6f, 0x72, /* ion: for */ + 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x20, /* m-data; */ + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x65, 0x78, /* name="ex */ + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x33, 0x22, 0x0d, /* ample3". */ + 0x0a, 0x0d, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x33, /* ...test3 */ + 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */ + 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */ + 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */ + 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */ + 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */ + 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */ + 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */ + 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */ + 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */ + 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */ + 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */ + 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */ + 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */ + 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */ + 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */ + 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */ + 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */ + 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */ + 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */ + 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */ + 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */ + 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */ + 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */ + 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x0d, 0x0a, /* 3test3.. */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, /* ------4e */ + 0x62, 0x66, 0x30, 0x30, 0x66, 0x62, 0x63, 0x66, /* bf00fbcf */ + 0x30, 0x39, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, /* 09..Cont */ + 0x65, 0x6e, 0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, /* ent-Disp */ + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, /* osition: */ + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, /* form-da */ + 0x74, 0x61, 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, /* ta; name */ + 0x3d, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, /* ="exampl */ + 0x65, 0x34, 0x22, 0x0d, 0x0a, 0x0d, 0x0a, 0x74, /* e4"....t */ + 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */ + 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */ + 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */ + 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */ + 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */ + 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */ + 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */ + 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */ + 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */ + 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */ + 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */ + 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */ + 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */ + 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */ + 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */ + 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */ + 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */ + 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */ + 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */ + 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */ + 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */ + 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */ + 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */ + 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */ + 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */ + 0x65, 0x73, 0x74, 0x34, 0x0d, 0x0a, 0x2d, 0x2d, /* est4..-- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, /* ----4ebf */ + 0x30, 0x30, 0x66, 0x62, 0x63, 0x66, 0x30, 0x39, /* 00fbcf09 */ + 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* ..Conten */ + 0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, /* t-Dispos */ + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, /* ition: f */ + 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, /* orm-data */ + 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, /* ; name=" */ + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x35, /* example5 */ + 0x22, 0x0d, 0x0a, 0x0d, 0x0a, 0x74, 0x65, 0x73, /* "....tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */ + 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */ + 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */ + 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */ + 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */ + 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */ + 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */ + 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */ + 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */ + 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */ + 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* 5..----- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x34, 0x65, 0x62, 0x66, 0x30, 0x30, 0x66, /* -4ebf00f */ + 0x62, 0x63, 0x66, 0x30, 0x39, 0x2d, 0x2d, 0x0d, /* bcf09--. */ + 0x0a /* . */ +}; + + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UINT my_get_notify(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr); + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE 1400 + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET client_socket; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE 800 + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + +static UINT multipart_flag; + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(192,168,0,105) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(192,168,0,123) + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_multipart_fragment_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, NX_NULL, my_get_notify); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *recv_packet; +NX_PACKET *my_packet; +CHAR *buffer_ptr; + + multipart_flag = 0; + + /* Create a socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 50295, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, HTTP_SERVER_ADDRESS, 80, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Write HEAD packet into the packet payload. */ + status = nx_packet_data_append(my_packet, pkt, sizeof(pkt), &client_pool, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive the response from http server. */ + status = nx_tcp_socket_receive(&client_socket, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + buffer_ptr = (CHAR *)recv_packet ->nx_packet_prepend_ptr; + + /* Check the status, If success , it should be 200. */ + if((buffer_ptr[9] != '2') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '0')) + error_counter++; + + nx_packet_release(recv_packet); + } + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (multipart_flag != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Multipart Fragment Test.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + error_counter++; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + status = nx_http_server_delete(&my_server); + if(status) + error_counter++; + +} + +UINT my_get_notify(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr) +{ + +ULONG offset, total_length; +ULONG length; +UCHAR buffer[1440]; +UINT count = 0; +UINT status; +NX_PACKET *response_pkt; + + /* Process multipart data. */ + if(request_type == NX_HTTP_SERVER_POST_REQUEST) + { + while(nx_http_server_get_entity_header(server_ptr, &packet_ptr, buffer, sizeof(buffer)) == NX_SUCCESS) + { + + multipart_flag = 1; + + /* Send the result. */ + total_length = 0; + count++; + + while(nx_http_server_get_entity_content(server_ptr, &packet_ptr, &offset, &length) == NX_SUCCESS) + { + /* Print content data. */ + nx_packet_data_extract_offset(packet_ptr, offset, buffer, length, &length); + buffer[length] = 0; + total_length += length; + } + + /* Check the data length. */ + if((count == 1) && (total_length != 196)) + error_counter++; + else if((count == 2) && (total_length != 175)) + error_counter++; + else if((count == 3) && (total_length != 195)) + error_counter++; + else if((count == 4) && (total_length != 205)) + error_counter++; + else if((count == 5) && (total_length != 220)) + error_counter++; + + } + + /* Generate HTTP header. */ + status = nx_http_server_callback_generate_response_header(server_ptr, &response_pkt, NX_HTTP_STATUS_OK, 800, "text/html", "Server: NetXDuo HTTP 5.3\r\n"); + if(status == NX_SUCCESS) + { + if(nx_http_server_callback_packet_send(server_ptr, response_pkt)) + nx_packet_release(response_pkt); + } + else + error_counter++; + } + else + return NX_SUCCESS; + + return(NX_HTTP_CALLBACK_COMPLETED); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_multipart_fragment_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: HTTP Multipart Fragment Test..............................N/A\n"); + test_control_return(3); +} +#endif + diff --git a/test/regression/http_test/netx_http_multipart_underflow_test.c b/test/regression/http_test/netx_http_multipart_underflow_test.c new file mode 100644 index 00000000..b35bffe2 --- /dev/null +++ b/test/regression/http_test/netx_http_multipart_underflow_test.c @@ -0,0 +1,614 @@ +/* This case tests whether HTTP server can work well with multipart/form-data. + * server packet size 800 + * client packet size 1400 + * pkt size is bigger than 1500 to cause client/server fragmentation. + */ + +/* Here is the packet content. */ +/* First two bytes of Content-Disposition is replaced with CRLF */ +/* +------------------------------4ebf00fbcf09 + +ntent-Disposition: form-data; name="example" + +testtest(repeat 49 times) +------------------------------4ebf00fbcf09 +Content-Disposition: form-data; name="example2" + +test2test2(repeat 35 times) +------------------------------4ebf00fbcf09 +Content-Disposition: form-data; name="example3" + +test3test3(repeat 39 times) +------------------------------4ebf00fbcf09 +Content-Disposition: form-data; name="example4" + +test4test4(repeat 51times) +------------------------------4ebf00fbcf09 +Content-Disposition: form-data; name="example5" + +test5(repeat 54times) +------------------------------4ebf00fbcf09-- +*/ + +/* length1 = 196, + * length2 = 175, + * length3 = 195, + * length4 = 205 + * length5 = 220. + * */ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" + +extern void test_control_return(UINT); +#if defined(NX_HTTP_MULTIPART_ENABLE) && !defined(NX_DISABLE_IPV4) +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +#define DEMO_STACK_SIZE 4096 + +/* This is a HTTP get packet captured by wireshark. HEAD index.html*/ +static char pkt[] = { + 0x50, 0x4f, 0x53, 0x54, 0x20, 0x2f, 0x20, 0x48, /* POST / H */ + 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, /* TTP/1.1. */ + 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, /* .User-Ag */ + 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x75, 0x72, /* ent: cur */ + 0x6c, 0x2f, 0x37, 0x2e, 0x33, 0x32, 0x2e, 0x30, /* l/7.32.0 */ + 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, /* ..Host: */ + 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, /* 192.168. */ + 0x30, 0x2e, 0x31, 0x32, 0x33, 0x0d, 0x0a, 0x41, /* 0.123..A */ + 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, /* ccept: * */ + 0x2f, 0x2a, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, /* *..Cont */ + 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, /* ent-Type */ + 0x3a, 0x20, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* : multip */ + 0x61, 0x72, 0x74, 0x2f, 0x66, 0x6f, 0x72, 0x6d, /* art/form */ + 0x2d, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x20, 0x62, /* -data; b */ + 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x3d, /* oundary= */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, /* ----4ebf */ + 0x30, 0x30, 0x66, 0x62, 0x63, 0x66, 0x30, 0x39, /* 00fbcf09 */ + 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* ..Conten */ + 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, /* t-Length */ + 0x3a, 0x20, 0x31, 0x35, 0x32, 0x31, 0x0d, 0x0a, /* : 1521.. */ + 0x45, 0x78, 0x70, 0x65, 0x63, 0x74, 0x3a, 0x20, /* Expect: */ + 0x31, 0x30, 0x30, 0x2d, 0x63, 0x6f, 0x6e, 0x74, /* 100-cont */ + 0x69, 0x6e, 0x75, 0x65, 0x0d, 0x0a, 0x0d, 0x0a, /* inue.... */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, /* ------4e */ + 0x62, 0x66, 0x30, 0x30, 0x66, 0x62, 0x63, 0x66, /* bf00fbcf */ + 0x30, 0x39, 0x0d, 0x0a, 0x0d, 0x0a, 0x6e, 0x74, /* 09..Cont */ + 0x65, 0x6e, 0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, /* ent-Disp */ + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, /* osition: */ + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, /* form-da */ + 0x74, 0x61, 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, /* ta; name */ + 0x3d, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, /* ="exampl */ + 0x65, 0x22, 0x0d, 0x0a, 0x0d, 0x0a, 0x74, 0x65, /* e"....te */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x74, 0x65, 0x73, 0x74, 0x74, 0x65, /* sttestte */ + 0x73, 0x74, 0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, /* st..---- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, 0x30, 0x30, /* --4ebf00 */ + 0x66, 0x62, 0x63, 0x66, 0x30, 0x39, 0x0d, 0x0a, /* fbcf09.. */ + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, /* Content- */ + 0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x69, 0x74, /* Disposit */ + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x6f, 0x72, /* ion: for */ + 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x20, /* m-data; */ + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x65, 0x78, /* name="ex */ + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x32, 0x22, 0x0d, /* ample2". */ + 0x0a, 0x0d, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x32, /* ...test2 */ + 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */ + 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */ + 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */ + 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */ + 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */ + 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */ + 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */ + 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */ + 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */ + 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */ + 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */ + 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */ + 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */ + 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */ + 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */ + 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */ + 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, /* t2test2t */ + 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, /* est2test */ + 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, /* 2test2te */ + 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, 0x74, 0x32, /* st2test2 */ + 0x74, 0x65, 0x73, 0x74, 0x32, 0x74, 0x65, 0x73, /* test2tes */ + 0x74, 0x32, 0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, /* t2..---- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, 0x30, 0x30, /* --4ebf00 */ + 0x66, 0x62, 0x63, 0x66, 0x30, 0x39, 0x0d, 0x0a, /* fbcf09.. */ + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, /* Content- */ + 0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, 0x69, 0x74, /* Disposit */ + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x6f, 0x72, /* ion: for */ + 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x20, /* m-data; */ + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x65, 0x78, /* name="ex */ + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x33, 0x22, 0x0d, /* ample3". */ + 0x0a, 0x0d, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x33, /* ...test3 */ + 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */ + 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */ + 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */ + 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */ + 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */ + 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */ + 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */ + 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */ + 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */ + 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */ + 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */ + 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */ + 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */ + 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */ + 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */ + 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */ + 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */ + 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */ + 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, /* 3test3te */ + 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, /* st3test3 */ + 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, /* test3tes */ + 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x74, /* t3test3t */ + 0x65, 0x73, 0x74, 0x33, 0x74, 0x65, 0x73, 0x74, /* est3test */ + 0x33, 0x74, 0x65, 0x73, 0x74, 0x33, 0x0d, 0x0a, /* 3test3.. */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, /* ------4e */ + 0x62, 0x66, 0x30, 0x30, 0x66, 0x62, 0x63, 0x66, /* bf00fbcf */ + 0x30, 0x39, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, /* 09..Cont */ + 0x65, 0x6e, 0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, /* ent-Disp */ + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, /* osition: */ + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, /* form-da */ + 0x74, 0x61, 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, /* ta; name */ + 0x3d, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, /* ="exampl */ + 0x65, 0x34, 0x22, 0x0d, 0x0a, 0x0d, 0x0a, 0x74, /* e4"....t */ + 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */ + 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */ + 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */ + 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */ + 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */ + 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */ + 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */ + 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */ + 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */ + 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */ + 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */ + 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */ + 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */ + 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */ + 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */ + 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */ + 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */ + 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */ + 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */ + 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */ + 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, /* est4test */ + 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, /* 4test4te */ + 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, /* st4test4 */ + 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, 0x65, 0x73, /* test4tes */ + 0x74, 0x34, 0x74, 0x65, 0x73, 0x74, 0x34, 0x74, /* t4test4t */ + 0x65, 0x73, 0x74, 0x34, 0x0d, 0x0a, 0x2d, 0x2d, /* est4..-- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x65, 0x62, 0x66, /* ----4ebf */ + 0x30, 0x30, 0x66, 0x62, 0x63, 0x66, 0x30, 0x39, /* 00fbcf09 */ + 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* ..Conten */ + 0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, /* t-Dispos */ + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, /* ition: f */ + 0x6f, 0x72, 0x6d, 0x2d, 0x64, 0x61, 0x74, 0x61, /* orm-data */ + 0x3b, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, /* ; name=" */ + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x35, /* example5 */ + 0x22, 0x0d, 0x0a, 0x0d, 0x0a, 0x74, 0x65, 0x73, /* "....tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */ + 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */ + 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */ + 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */ + 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */ + 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */ + 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */ + 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */ + 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, /* 5test5te */ + 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, /* st5test5 */ + 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, /* test5tes */ + 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, 0x35, 0x74, /* t5test5t */ + 0x65, 0x73, 0x74, 0x35, 0x74, 0x65, 0x73, 0x74, /* est5test */ + 0x35, 0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* 5..----- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, /* -------- */ + 0x2d, 0x34, 0x65, 0x62, 0x66, 0x30, 0x30, 0x66, /* -4ebf00f */ + 0x62, 0x63, 0x66, 0x30, 0x39, 0x2d, 0x2d, 0x0d, /* bcf09--. */ + 0x0a /* . */ +}; + + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UINT my_get_notify(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr); + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE 1400 + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET client_socket; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE 800 + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + +static UINT multipart_flag; + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(192,168,0,105) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(192,168,0,123) + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_multipart_underflow_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, NX_NULL, my_get_notify); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *recv_packet; +NX_PACKET *my_packet; +CHAR *buffer_ptr; + + multipart_flag = 0; + + /* Create a socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 50295, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, HTTP_SERVER_ADDRESS, 80, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Write HEAD packet into the packet payload. */ + status = nx_packet_data_append(my_packet, pkt, sizeof(pkt), &client_pool, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive the response from http server. */ + status = nx_tcp_socket_receive(&client_socket, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + buffer_ptr = (CHAR *)recv_packet ->nx_packet_prepend_ptr; + + /* Check the status, If success , it should be 200. */ + if((buffer_ptr[9] != '2') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '0')) + error_counter++; + + nx_packet_release(recv_packet); + } + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if((error_counter) || (multipart_flag != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Multipart Underflow Test............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + error_counter++; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + status = nx_http_server_delete(&my_server); + if(status) + error_counter++; + +} + +UINT my_get_notify(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr) +{ + +ULONG offset, total_length; +ULONG length; +UCHAR buffer[1440]; +UINT count = 0; +UINT status; +NX_PACKET *response_pkt; + + /* Set first 5 bytes to 0. */ + buffer[0] = 0xFF; + buffer[1] = 0xFF; + buffer[2] = 0xFF; + buffer[3] = 0xFF; + buffer[4] = 0xFF; + + /* Process multipart data. */ + if(request_type == NX_HTTP_SERVER_POST_REQUEST) + { + while(nx_http_server_get_entity_header(server_ptr, &packet_ptr, buffer + 5, sizeof(buffer) - 5) == NX_SUCCESS) + { + if ((buffer[0] & buffer[1] & buffer[2] & buffer[3] & buffer[4]) != 0xFF) + { + + /* Detected underflow. */ + error_counter++; + } + + multipart_flag = 1; + + /* Send the result. */ + total_length = 0; + count++; + + while(nx_http_server_get_entity_content(server_ptr, &packet_ptr, &offset, &length) == NX_SUCCESS) + { + /* Print content data. */ + nx_packet_data_extract_offset(packet_ptr, offset, buffer + 5, length, &length); + buffer[length + 5] = 0; + total_length += length; + } + + /* Check the data length. */ + /* if((count == 1) && (total_length != 196)) + error_counter++; */ + if((count == 2) && (total_length != 175)) + error_counter++; + else if((count == 3) && (total_length != 195)) + error_counter++; + else if((count == 4) && (total_length != 205)) + error_counter++; + else if((count == 5) && (total_length != 220)) + error_counter++; + + } + + /* Generate HTTP header. */ + status = nx_http_server_callback_generate_response_header(server_ptr, &response_pkt, NX_HTTP_STATUS_OK, 800, "text/html", "Server: NetXDuo HTTP 5.3\r\n"); + if(status == NX_SUCCESS) + { + if(nx_http_server_callback_packet_send(server_ptr, response_pkt)) + nx_packet_release(response_pkt); + } + else + error_counter++; + } + else + return NX_SUCCESS; + + return(NX_HTTP_CALLBACK_COMPLETED); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_multipart_underflow_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: HTTP Multipart Underflow Test.............................N/A\n"); + test_control_return(3); +} +#endif + diff --git a/test/regression/http_test/netx_http_post_basic_test.c b/test/regression/http_test/netx_http_post_basic_test.c new file mode 100644 index 00000000..2a8f1a3f --- /dev/null +++ b/test/regression/http_test/netx_http_post_basic_test.c @@ -0,0 +1,464 @@ +/* This case tests basic post method. */ +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* This is a HTTP get packet captured by wireshark. POST AAAAAAAAAA*/ +static char pkt[] = { + 0x50, 0x4f, 0x53, 0x54, 0x20, 0x2f, 0x69, 0x6e, /* POST /in */ + 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x20, /* dex.htm */ + 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, /* HTTP/1.1 */ + 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, /* ..User-A */ + 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x75, /* gent: cu */ + 0x72, 0x6c, 0x2f, 0x37, 0x2e, 0x33, 0x32, 0x2e, /* rl/7.32. */ + 0x30, 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, /* 0..Host: */ + 0x20, 0x31, 0x39, 0x32, 0x2e, 0x31, 0x36, 0x38, /* 192.168 */ + 0x2e, 0x30, 0x2e, 0x31, 0x32, 0x33, 0x0d, 0x0a, /* .0.123.. */ + 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, /* Accept: */ + 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, /* */ + 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, /* tent-Len */ + 0x67, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x0d, /* gth: 10. */ + 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, /* .Content */ + 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, /* -Type: a */ + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, /* pplicati */ + 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x77, 0x77, 0x77, /* on/x-www */ + 0x2d, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x75, 0x72, /* -form-ur */ + 0x6c, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, /* lencoded */ + 0x0d, 0x0a, 0x0d, 0x0a, 0x41, 0x41, 0x41, 0x41, /* ....AAAA */ + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 /* AAAAAA */ +}; + + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_HTTP_CLIENT my_client; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET client_socket; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(192,168,0,105) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(192,168,0,123) + +static UINT my_get_notify(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_post_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, NX_NULL, my_get_notify); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *send_packet; +NX_PACKET *recv_packet; +NX_PACKET *my_packet; +CHAR *buffer_ptr; + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + /* Check the media open status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + + /* Check status. */ + if (status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + + /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */ + status = nxd_http_client_put_start(&my_client, &server_ip_address, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#else + + /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */ + status = nx_http_client_put_start(&my_client, HTTP_SERVER_ADDRESS, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + error_counter++; + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Now GET the test file */ + +#ifdef __PRODUCT_NETXDUO__ + + /* Use the 'duo' service to send a GET request to the server (can use IPv4 or IPv6 addresses). */ + status = nxd_http_client_get_start(&my_client, &server_ip_address, + "/index.htm", NX_NULL, 0, "name", "password", NX_IP_PERIODIC_RATE); +#else + + /* Use the 'NetX' service to send a GET request to the server (can only use IPv4 addresses). */ + status = nx_http_client_get_start(&my_client, HTTP_SERVER_ADDRESS, "/index.htm", + NX_NULL, 0, "name", "password", NX_IP_PERIODIC_RATE); +#endif /* USE_DUO */ + + if(status) + error_counter++; + + while (1) + { + status = nx_http_client_get_packet(&my_client, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + + if (status == NX_HTTP_GET_DONE) + break; + + if (status) + error_counter++; + else + nx_packet_release(recv_packet); + } + + status = nx_http_client_delete(&my_client); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 50295, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, HTTP_SERVER_ADDRESS, 80, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Write POST packet into the packet payload. */ + status = nx_packet_data_append(my_packet, pkt, sizeof(pkt), &client_pool, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + + /* Receive the response from http server. */ + status = nx_tcp_socket_receive(&client_socket, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + buffer_ptr = (CHAR *)recv_packet ->nx_packet_prepend_ptr; + + /* Check the status, If success , it should be 200. */ + if((buffer_ptr[9] != '2') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '0')) + error_counter++; + + nx_packet_release(recv_packet); + } + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Post Basic Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + error_counter++; + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + status = nx_http_server_delete(&my_server); + if(status) + error_counter++; + +} + + +/* Test extended functions. */ +UINT my_get_notify(NX_HTTP_SERVER *server_ptr, UINT request_type, CHAR *resource, NX_PACKET *packet_ptr) +{ + +UINT status; +NX_PACKET *response_pkt; +UCHAR data[] = "hello"; + + /* Process multipart data. */ + if (request_type == NX_HTTP_SERVER_GET_REQUEST) + { + + /* Generate HTTP header. */ + status = nx_http_server_callback_generate_response_header_extended(server_ptr, &response_pkt, NX_HTTP_STATUS_OK, sizeof(NX_HTTP_STATUS_OK) - 1, sizeof(data) - 1, "text/html", 9, "Server: NetXDuo HTTP 5.3\r\n", 26); + if (status == NX_SUCCESS) + { + if (nx_http_server_callback_packet_send(server_ptr, response_pkt)) + nx_packet_release(response_pkt); + } + else + error_counter++; + + status = nx_http_server_callback_data_send(server_ptr, data, sizeof(data) - 1); + if (status) + error_counter++; + } + else if (request_type == NX_HTTP_SERVER_POST_REQUEST) + { + status = nx_http_server_callback_response_send_extended(server_ptr, NX_HTTP_STATUS_OK, sizeof(NX_HTTP_STATUS_OK) - 1, "Server: NetXDuo HTTP 5.3\r\n", 26, NX_NULL, 0); + if (status) + error_counter++; + } + else + return NX_SUCCESS; + + return(NX_HTTP_CALLBACK_COMPLETED); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_post_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Post Basic Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_request_in_multiple_packets_test.c b/test/regression/http_test/netx_http_request_in_multiple_packets_test.c new file mode 100644 index 00000000..c4656796 --- /dev/null +++ b/test/regression/http_test/netx_http_request_in_multiple_packets_test.c @@ -0,0 +1,452 @@ +/* This case tests the ability of the HTTP server to process HTTP request string in multiple packets. + * Packet1. GET / HTTP/1.0 + * Packet2. CR + * Packet3. LF + * Packet4. CR + * Packet5. LF + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +extern void test_control_return(UINT); +#ifndef NX_DISABLE_IPV4 +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +#define DEMO_STACK_SIZE 2048 +#define SERVER_PORT 80 + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UINT error_counter = 0; + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (800) +#define CLIENT_PACKET_POOL_SIZE ((CLIENT_PACKET_SIZE + sizeof(NX_PACKET)) * 16) +ULONG client_packet_pool_area[CLIENT_PACKET_POOL_SIZE/4 + 4]; + +static TX_THREAD client_thread; +static NX_HTTP_CLIENT my_client; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (800) +#define SERVER_PACKET_POOL_SIZE ((SERVER_PACKET_SIZE + sizeof(NX_PACKET)) * 16) +ULONG server_packet_pool_area[SERVER_PACKET_POOL_SIZE/4 + 4]; + +static TX_THREAD server_thread; +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + +/* Define the IP thread stack areas. */ + +ULONG server_ip_thread_stack[2 * 1024 / sizeof(ULONG)]; +ULONG client_ip_thread_stack[2 * 1024 / sizeof(ULONG)]; + +/* Define the ARP cache areas. */ + +ULONG server_arp_space_area[512 / sizeof(ULONG)]; +ULONG client_arp_space_area[512 / sizeof(ULONG)]; + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + +static CHAR *pointer; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_request_in_multiple_packets_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + status = tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 5, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer , SERVER_PACKET_POOL_SIZE); + + pointer = pointer + SERVER_PACKET_POOL_SIZE; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "HTTP Server IP", + HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, + &server_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; +#endif + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_POOL_SIZE); + + pointer = pointer + CLIENT_PACKET_POOL_SIZE; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, DEMO_STACK_SIZE, 1); + + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, NX_NULL, NX_NULL); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *send_packet; +NX_PACKET *recv_packet; + + /* wait for the server to set up */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + if (status != FX_SUCCESS) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 1460); + if (status) + error_counter++; + + /* Upload the 1st file to the server domain. */ +#ifdef __PRODUCT_NETXDUO__ + + status = nxd_http_client_put_start(&my_client, &server_ip_address, "http://www.abc.com/client_test.htm", + "name", "password", 103, 3 * NX_IP_PERIODIC_RATE); +#else + + status = nx_http_client_put_start(&my_client, server_ip_address, "http://www.abc.com/client_test.htm", + "name", "password", 103, 3 * NX_IP_PERIODIC_RATE); +#endif + + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + { + error_counter++; + } + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + { + error_counter++; + } + + + /* Bind the socket. */ + if (nx_tcp_client_socket_bind(&(my_client.nx_http_client_socket), NX_ANY_PORT, NX_WAIT_FOREVER)) + { + error_counter++; + } + + /* Connect to server. */ + if (nx_tcp_client_socket_connect(&(my_client.nx_http_client_socket), HTTP_SERVER_ADDRESS, + my_client.nx_http_client_connect_port, NX_IP_PERIODIC_RATE)) + { + error_counter++; + } + + /* Build simple request. */ + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + nx_packet_data_append(send_packet, "GET / HTTP/1.0", 14, + &client_pool, NX_WAIT_FOREVER); + if (nx_tcp_socket_send(&(my_client.nx_http_client_socket), send_packet, NX_IP_PERIODIC_RATE)) + { + nx_packet_release(send_packet); + error_counter++; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + nx_packet_data_append(send_packet, "\r", 1, + &client_pool, NX_WAIT_FOREVER); + if (nx_tcp_socket_send(&(my_client.nx_http_client_socket), send_packet, NX_IP_PERIODIC_RATE)) + { + nx_packet_release(send_packet); + error_counter++; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + nx_packet_data_append(send_packet, "\n", 1, + &client_pool, NX_WAIT_FOREVER); + if (nx_tcp_socket_send(&(my_client.nx_http_client_socket), send_packet, NX_IP_PERIODIC_RATE)) + { + nx_packet_release(send_packet); + error_counter++; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + nx_packet_data_append(send_packet, "\r", 1, + &client_pool, NX_WAIT_FOREVER); + if (nx_tcp_socket_send(&(my_client.nx_http_client_socket), send_packet, NX_IP_PERIODIC_RATE)) + { + nx_packet_release(send_packet); + error_counter++; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + nx_packet_data_append(send_packet, "\n", 1, + &client_pool, NX_WAIT_FOREVER); + if (nx_tcp_socket_send(&(my_client.nx_http_client_socket), send_packet, NX_IP_PERIODIC_RATE)) + { + nx_packet_release(send_packet); + error_counter++; + } + + /* Receive response from HTTP server. */ + if (nx_tcp_socket_receive(&(my_client.nx_http_client_socket), &recv_packet, NX_IP_PERIODIC_RATE)) + { + error_counter++; + } + else + { + nx_packet_release(recv_packet); + } + + /* wait for the server to set up */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + nx_http_client_delete(&my_client); + nx_http_server_stop(&my_server); + nx_http_server_delete(&my_server); + + /* Verify no packet is leak. */ + if ((client_pool.nx_packet_pool_total != client_pool.nx_packet_pool_available) || + (server_pool.nx_packet_pool_total != server_pool.nx_packet_pool_available)) + { + error_counter++; + } + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Request in Multiple Packets Test....................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + { + error_counter++; + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_request_in_multiple_packets_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: HTTP Request in Multiple Packets Test.....................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_server_type_retrieve_test.c b/test/regression/http_test/netx_http_server_type_retrieve_test.c new file mode 100644 index 00000000..a3fca24e --- /dev/null +++ b/test/regression/http_test/netx_http_server_type_retrieve_test.c @@ -0,0 +1,190 @@ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_server.h" +#else +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +/* Set up the HTTP client global variables. */ +static UINT error_counter; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; + + +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_server_type_retrieve_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, NX_NULL, NX_NULL); + pointer = pointer + 2048; + if (status) + error_counter++; +} + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; +UCHAR type[20]; +UINT type_length; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Server Type Retrieve Test............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Type is "text/html", should return 9. */ + type_length = nx_http_server_type_get(&my_server, "test.htm", type); + if (type_length != 9) + error_counter++; + type_length = nx_http_server_type_get_extended(&my_server, "test.htm", 8, type, sizeof(type)); + if (type_length != 9) + error_counter++; + + /* The max size of destination string is not enough, should return 0. */ + type_length = nx_http_server_type_get_extended(&my_server, "test.htm", 8, type, 9); + if (type_length != 0) + error_counter++; + + /* Type is default "text/plain", should return 10. */ + type_length = nx_http_server_type_get(&my_server, "test.xml", type); + if (type_length != 10) + error_counter++; + type_length = nx_http_server_type_get_extended(&my_server, "test.xml", 8, type, sizeof(type)); + if (type_length != 10) + error_counter++; + + /* The max size of destination string is not enough, should return 0. */ + type_length = nx_http_server_type_get_extended(&my_server, "test.xml", 8, type, 5); + if (type_length != 0) + error_counter++; + + /* Type is default "text/plain", should return 10. */ + type_length = nx_http_server_type_get(&my_server, "test", type); + if (type_length != 10) + error_counter++; + type_length = nx_http_server_type_get_extended(&my_server, "test", 4, type, sizeof(type)); + if (type_length != 10) + error_counter++; + + /* The max size of destination string is not enough, should return 0. */ + type_length = nx_http_server_type_get_extended(&my_server, "test", 4, type, 5); + if (type_length != 0) + error_counter++; + + status = nx_http_server_delete(&my_server); + if(status) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_server_type_retrieve_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Server Type Retrieve Test............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/http_test/netx_http_status_400_test.c b/test/regression/http_test/netx_http_status_400_test.c new file mode 100644 index 00000000..56e7d352 --- /dev/null +++ b/test/regression/http_test/netx_http_status_400_test.c @@ -0,0 +1,406 @@ +/* + 1. If Request-URIis an absoluteURI, the host is part of the Request-URI. Any Host header + field value in the request MUST be ignored. + 2. If the Request-URIis not an absoluteURI, and the request includes a Hostheader field, + the host is determined by the Hostheader field value. + 3. If the host as determined by rule 1 or 2 is not a valid host on the server, the response + MUST be a 400 (Bad Request) error message. + + Change Host field value from 192.168.0.123 to 192.168.0.120 .*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +/* This is a HTTP get packet captured by wireshark. + * curl 192.168.0.123 + * 123: pkt[120] = 0x31, pkt[121] = 0x32, pkt[122] = 0x33 + * 122: pkt[120] = 0x31, pkt[121] = 0x32, pkt[122] = 0x32 + * */ +static char pkt[] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0xb8, 0xca, /* .."3DW.. */ +0x3a, 0x95, 0xdb, 0x0b, 0x08, 0x00, 0x45, 0x00, /* :.....E. */ +0x00, 0x7e, 0x0b, 0xd2, 0x40, 0x00, 0x80, 0x06, /* .~..@... */ +0x6c, 0x73, 0xc0, 0xa8, 0x00, 0x69, 0xc0, 0xa8, /* ls...i.. */ +0x00, 0x7b, 0xca, 0x95, 0x00, 0x50, 0x66, 0x2b, /* .{...Pf+ */ +0xe7, 0x60, 0xb6, 0xa2, 0xe6, 0xf3, 0x50, 0x18, /* .`....P. */ +0xfa, 0xf0, 0x59, 0x33, 0x00, 0x00, 0x47, 0x45, /* ..Y3..GE */ +0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, /* T /index */ +0x2e, 0x68, 0x74, 0x6d, 0x20, 0x48, 0x54, 0x54, /* .htm HTT */ +0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x55, /* P/1.1..U */ +0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, /* ser-Agen */ +0x74, 0x3a, 0x20, 0x63, 0x75, 0x72, 0x6c, 0x2f, /* t: curl/ */ +0x37, 0x2e, 0x33, 0x32, 0x2e, 0x30, 0x0d, 0x0a, /* 7.32.0.. */ +0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, /* Host: 19 */ +0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, /* 2.168.0. */ +0x31, 0x32, 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, /* 123..Acc */ +0x65, 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, /* ept: */ +0x0d, 0x0a, 0x0d, 0x0a /* .... */ + +}; + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_HTTP_CLIENT my_client; +static NX_IP client_ip; + +static UINT error_counter; +static NX_TCP_SOCKET client_socket; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +static NXD_ADDRESS client_ip_address; +#else +static ULONG server_ip_address; +static ULONG client_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_status_400_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = HTTP_CLIENT_ADDRESS; + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; + client_ip_address = HTTP_CLIENT_ADDRESS; +#endif + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, NX_NULL, NX_NULL); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR *buffer_ptr; +NX_PACKET *recv_packet; +NX_PACKET *send_packet; + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + /* Check the media open status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + + /* Check status. */ + if (status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + + /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */ + status = nxd_http_client_put_start(&my_client, &server_ip_address, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#else + + /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */ + status = nx_http_client_put_start(&my_client, HTTP_SERVER_ADDRESS, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + error_counter++; + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 50295, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, HTTP_SERVER_ADDRESS, 80, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Change '3' to '2' .*/ + pkt[122] = '2'; + + /* Write Aet packet into the packet payload. */ + status = nx_packet_data_append(my_packet, &pkt[54] , (sizeof(pkt)-54), &client_pool, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive the response from http server. */ + status = nx_tcp_socket_receive(&client_socket, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + + buffer_ptr = (CHAR *)recv_packet ->nx_packet_prepend_ptr; + + /* Check the status, If success , it should be 200. */ + if((buffer_ptr[9] != '4') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '0')) + error_counter++; + + nx_packet_release(recv_packet); + } + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Status 400 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + error_counter++; + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + status = nx_http_server_delete(&my_server); + if(status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_status_400_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Status 400 Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_status_404_test.c b/test/regression/http_test/netx_http_status_404_test.c new file mode 100644 index 00000000..f02cff6a --- /dev/null +++ b/test/regression/http_test/netx_http_status_404_test.c @@ -0,0 +1,392 @@ +/* If Tthe server has not found anything matching the Request-URI. + * 404 should be sent. */ + +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; +static unsigned char media_memory[512]; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +/* This is a HTTP get packet captured by wireshark. + * curl 192.168.0.123/aaa.index + * */ +static char pkt[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0xb8, 0xca, /* .."3DW.. */ + 0x3a, 0x95, 0xdb, 0x0b, 0x08, 0x00, 0x45, 0x00, /* :.....E. */ + 0x00, 0x7c, 0x3a, 0xff, 0x40, 0x00, 0x80, 0x06, /* .|:.@... */ + 0x3d, 0x48, 0xc0, 0xa8, 0x00, 0x69, 0xc0, 0xa8, /* =H...i.. */ + 0x00, 0x7b, 0xcb, 0xef, 0x00, 0x50, 0x4d, 0x7b, /* .{...PM{ */ + 0x22, 0xf0, 0xcf, 0xed, 0x46, 0xa4, 0x50, 0x18, /* "...F.P. */ + 0xfa, 0xf0, 0x2e, 0x84, 0x00, 0x00, 0x47, 0x45, /* ......GE */ + 0x54, 0x20, 0x2f, 0x61, 0x61, 0x61, 0x2e, 0x68, /* T /aaa.h */ + 0x74, 0x6d, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, /* tm HTTP/ */ + 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x73, 0x65, /* 1.1..Use */ + 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, /* r-Agent: */ + 0x20, 0x63, 0x75, 0x72, 0x6c, 0x2f, 0x37, 0x2e, /* curl/7. */ + 0x33, 0x32, 0x2e, 0x30, 0x0d, 0x0a, 0x48, 0x6f, /* 32.0..Ho */ + 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32, 0x2e, /* st: 192. */ + 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31, 0x32, /* 168.0.12 */ + 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, /* 3..Accep */ + 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, /* t: */ + 0x0d, 0x0a /* .. */ +}; + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_HTTP_CLIENT my_client; +static NX_IP client_ip; + +static UINT error_counter; +static NX_TCP_SOCKET client_socket; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +static NXD_ADDRESS client_ip_address; +#else +static ULONG server_ip_address; +static ULONG client_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_status_404_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = HTTP_CLIENT_ADDRESS; + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; + client_ip_address = HTTP_CLIENT_ADDRESS; +#endif + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, NX_NULL, NX_NULL); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR *buffer_ptr; +NX_PACKET *recv_packet; +NX_PACKET *send_packet; + + /* Format the RAM disk - the memory for the RAM disk was setup in + tx_application_define above. This must be set up before the client(s) start + sending requests. */ + status = fx_media_format(&ram_disk, + _fx_ram_driver, /* Driver entry */ + ram_disk_memory, /* RAM disk memory pointer */ + media_memory, /* Media buffer pointer */ + sizeof(media_memory), /* Media buffer size */ + "MY_RAM_DISK", /* Volume Name */ + 1, /* Number of FATs */ + 32, /* Directory Entries */ + 0, /* Hidden sectors */ + 256, /* Total sectors */ + 128, /* Sector size */ + 1, /* Sectors per cluster */ + 1, /* Heads */ + 1); /* Sectors per track */ + + /* Check the media format status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Open the RAM disk. */ + status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, media_memory, sizeof(media_memory)); + + /* Check the media open status. */ + if (status != FX_SUCCESS) + error_counter++; + + /* Create an HTTP client instance. */ + status = nx_http_client_create(&my_client, "HTTP Client", &client_ip, &client_pool, 600); + + /* Check status. */ + if (status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + + /* Now upload an HTML file to the HTTP IP server using the 'duo' service (supports IPv4 and IPv6). */ + status = nxd_http_client_put_start(&my_client, &server_ip_address, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#else + + /* Now upload an HTML file to the HTTP IP server using the 'NetX' service (supports only IPv4). */ + status = nx_http_client_put_start(&my_client, HTTP_SERVER_ADDRESS, "/index.htm", + "name", "password", 103, 5 * NX_IP_PERIODIC_RATE); +#endif + + /* Check status. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if(status) + error_counter++; + + /* Build a simple 103-byte HTML page. */ + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, + "NetX HTTP Test\r\n", 44, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 8, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "

Another NetX Test Page!

\r\n", 25, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + nx_packet_data_append(send_packet, "\r\n", 9, + &client_pool, NX_WAIT_FOREVER); + + /* Complete the PUT by writing the total length. */ + status = nx_http_client_put_packet(&my_client, send_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 50295, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, HTTP_SERVER_ADDRESS, 80, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Write Aet packet into the packet payload. */ + status = nx_packet_data_append(my_packet, &pkt[54] , (sizeof(pkt)-54), &client_pool, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive the response from http server. */ + status = nx_tcp_socket_receive(&client_socket, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + + buffer_ptr = (CHAR *)recv_packet ->nx_packet_prepend_ptr; + + /* Check the status, If success , it should be 200. */ + if((buffer_ptr[9] != '4') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '4')) + error_counter++; + + nx_packet_release(recv_packet); + } + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Status 404 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + error_counter++; + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + status = nx_http_server_delete(&my_server); + if(status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_status_404_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Status 404 Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/http_test/netx_http_status_501_test.c b/test/regression/http_test/netx_http_status_501_test.c new file mode 100644 index 00000000..c62a5d70 --- /dev/null +++ b/test/regression/http_test/netx_http_status_501_test.c @@ -0,0 +1,315 @@ +/* If the method is unrecognized or not implemented by the origin server, + * should repond 501. + * change GET to AET to build a unrecognized method packet. */ +#include "tx_api.h" +#include "nx_api.h" +#include "fx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_http_client.h" +#include "nxd_http_server.h" +#else +#include "nx_http_client.h" +#include "nx_http_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Set up FileX and file memory resources. */ +static CHAR *ram_disk_memory; +static FX_MEDIA ram_disk; + +/* Define device drivers. */ +extern void _fx_ram_driver(FX_MEDIA *media_ptr); +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + + +/* This is a HTTP get packet captured by wireshark. + * curl 192.168.0.123 + * GET: pkt[54] = 0x47, pkt[55] = 0x45, pkt[56] = 0x54 + * AET: pkt[54] = 'A' , pkt[55] = 0x45, pkt[56] = 0x54 + * */ +static char pkt[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0xb8, 0xca, /* .."3DW.. */ + 0x3a, 0x95, 0xdb, 0x0b, 0x08, 0x00, 0x45, 0x00, /* :.....E. */ + 0x00, 0x75, 0x47, 0x4a, 0x40, 0x00, 0x80, 0x06, /* .uGJ@... */ + 0x31, 0x04, 0xc0, 0xa8, 0x00, 0x69, 0xc0, 0xa8, /* 1....i.. */ + 0x00, 0x7b, 0xe8, 0xeb, 0x00, 0x50, 0xe5, 0x59, /* .{...P.Y */ + 0x56, 0x32, 0x41, 0xf1, 0x07, 0xf0, 0x50, 0x18, /* V2A...P. */ + 0xfa, 0xf0, 0x65, 0x69, 0x00, 0x00, 0x47, 0x45, /* ..ei..GE */ + 0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, /* T / HTTP */ + 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x55, 0x73, /* /1.1..Us */ + 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, /* er-Agent */ + 0x3a, 0x20, 0x63, 0x75, 0x72, 0x6c, 0x2f, 0x37, /* : curl/7 */ + 0x2e, 0x33, 0x32, 0x2e, 0x30, 0x0d, 0x0a, 0x48, /* .32.0..H */ + 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32, /* ost: 192 */ + 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31, /* .168.0.1 */ + 0x32, 0x33, 0x0d, 0x0a, 0x41, 0x63, 0x63, 0x65, /* 23..Acce */ + 0x70, 0x74, 0x3a, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, /* pt: */ + 0x0a, 0x0d, 0x0a /* ... */ +}; + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; + +static UINT error_counter; +static NX_TCP_SOCKET client_socket; + +/* Set up the HTTP server global variables */ + +#define SERVER_PACKET_SIZE (NX_HTTP_SERVER_MIN_PACKET_SIZE * 2) + +static NX_HTTP_SERVER my_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +#ifdef __PRODUCT_NETXDUO__ +static NXD_ADDRESS server_ip_address; +static NXD_ADDRESS client_ip_address; +#else +static ULONG server_ip_address; +static ULONG client_ip_address; +#endif + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); + +#define HTTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define HTTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_status_501_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "HTTP Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "HTTP Server Packet Pool", SERVER_PACKET_SIZE, + pointer, SERVER_PACKET_SIZE*8); + pointer = pointer + SERVER_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "HTTP Server IP", HTTP_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 4096, 1); + pointer = pointer + 4096; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Set up the server's IPv4 address here. */ +#ifdef __PRODUCT_NETXDUO__ + server_ip_address.nxd_ip_address.v4 = HTTP_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = HTTP_CLIENT_ADDRESS; + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; +#else + server_ip_address = HTTP_SERVER_ADDRESS; + client_ip_address = HTTP_CLIENT_ADDRESS; +#endif + + /* Create the HTTP Server. */ + status = nx_http_server_create(&my_server, "My HTTP Server", &server_ip, &ram_disk, + pointer, 2048, &server_pool, NX_NULL, NX_NULL); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Save the memory pointer for the RAM disk. */ + ram_disk_memory = pointer; + + /* Create the HTTP Client thread. */ + status = tx_thread_create(&client_thread, "HTTP Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "HTTP Client Packet Pool", CLIENT_PACKET_SIZE, + pointer, CLIENT_PACKET_SIZE*8); + pointer = pointer + CLIENT_PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "HTTP Client IP", HTTP_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; +} + + +void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR *buffer_ptr; +NX_PACKET *recv_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 50295, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, HTTP_SERVER_ADDRESS, 80, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&client_pool, &my_packet, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Change 'G' to 'A' .*/ + pkt[54] = 'A'; + + /* Write Aet packet into the packet payload. */ + status = nx_packet_data_append(my_packet, &pkt[54] , (sizeof(pkt)-54), &client_pool, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive the response from http server. */ + status = nx_tcp_socket_receive(&client_socket, &recv_packet, 1 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + + buffer_ptr = (CHAR *)recv_packet ->nx_packet_prepend_ptr; + + /* Check the status, If success , it should be 200. */ + if((buffer_ptr[9] != '5') || (buffer_ptr[10] != '0') || (buffer_ptr[11] != '1')) + error_counter++; + + nx_packet_release(recv_packet); + } + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: HTTP Status 501 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* OK to start the HTTP Server. */ + status = nx_http_server_start(&my_server); + if(status) + error_counter++; + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + status = nx_http_server_delete(&my_server); + if(status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_status_501_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Status 501 Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/capture/_http._tcp.c b/test/regression/mdns_test/capture/_http._tcp.c new file mode 100644 index 00000000..445c4975 --- /dev/null +++ b/test/regression/mdns_test/capture/_http._tcp.c @@ -0,0 +1,59 @@ +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (153 bytes) */ +static const unsigned char pkt2[153] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt3[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x85, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + diff --git a/test/regression/mdns_test/capture/_http._tcp.pcapng b/test/regression/mdns_test/capture/_http._tcp.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..0e0611c434b3ba2781b5c16c378bdfa902c8f720 GIT binary patch literal 1376 zcmcIk&1(};5T7)g8cT{@C)bc<5gsxR7;bcNJRqP!R`a-@JMA<~P52lXP`= zcijVk>2o8eJh+;Ucwq#>p`D!gd``!q2yhFI%P@eB`aLu=6Tt=JJ12+H+;0LAnoF5VZ=i%5CnEa-EV ze#c;&5-z^l5dPVB4dV&gqz>2qjppr-7S~7B*Ekvc z)(_;$?f&9g+iTeGXFZ_T9SeZpgcE^Srlgjplc7mLsI>x}6;;=iO6w$e>Qw11;3#uz z2u?eDKY9UDtqA&h$cI@hPE<41{+Z5EsP<UTk6mG z*yqPEaNxCE0;#^k^D}U%X*@+gsmuH-N1R`!_!SfU$J%Lre5mvrB%vO^|F&azpbuiI vUc#|lVdaWiE##Fv%dWD#{ioIeek*q2#irqPY`VvxeceuldF`=vwid=uCHP52 literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/_pdl-datastream._tcp.c b/test/regression/mdns_test/capture/_pdl-datastream._tcp.c new file mode 100644 index 00000000..c4b60be4 --- /dev/null +++ b/test/regression/mdns_test/capture/_pdl-datastream._tcp.c @@ -0,0 +1,131 @@ +/* Frame (86 bytes) */ +static const unsigned char pkt1[86] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x48, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .H..@... */ +0xd9, 0xb7, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x34, /* .......4 */ +0x03, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .,...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* l..... */ +}; + +/* Frame (496 bytes) */ +static const unsigned char pkt2[496] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x01, 0xe2, 0x77, 0x3a, 0x00, 0x00, 0xff, 0x11, /* ..w:.... */ +0xa1, 0x28, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* .(...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0xce, /* ........ */ +0xee, 0x32, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .2...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, /* .....Can */ +0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* onMF4500 */ +0x77, 0xc0, 0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, /* w...rout */ +0x65, 0x72, 0xc0, 0x21, 0x00, 0x01, 0x80, 0x01, /* er.!.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x04, 0xc0, 0x32, 0x00, 0x21, 0x80, 0x01, /* ...2.!.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, /* ...x.... */ +0x00, 0x00, 0x23, 0x8c, 0xc0, 0x41, 0xc0, 0x32, /* ..#..A.2 */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x01, 0x4e, 0x09, 0x74, 0x78, 0x74, 0x76, 0x65, /* .N.txtve */ +0x72, 0x73, 0x3d, 0x31, 0x05, 0x6e, 0x6f, 0x74, /* rs=1.not */ +0x65, 0x3d, 0x08, 0x71, 0x74, 0x6f, 0x74, 0x61, /* e=.qtota */ +0x6c, 0x3d, 0x31, 0x0b, 0x70, 0x72, 0x69, 0x6f, /* l=1.prio */ +0x72, 0x69, 0x74, 0x79, 0x3d, 0x31, 0x30, 0x11, /* rity=10. */ +0x74, 0x79, 0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ty=Canon */ +0x20, 0x4d, 0x46, 0x34, 0x35, 0x37, 0x30, 0x64, /* MF4570d */ +0x77, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, /* w.produc */ +0x74, 0x3d, 0x28, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* t=(Canon */ +0x20, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* MF4500w */ +0x29, 0x1c, 0x70, 0x64, 0x6c, 0x3d, 0x61, 0x70, /* ).pdl=ap */ +0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, /* plicatio */ +0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, /* n/octet- */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2a, 0x61, /* stream*a */ +0x64, 0x6d, 0x69, 0x6e, 0x75, 0x72, 0x6c, 0x3d, /* dminurl= */ +0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x72, /* http://r */ +0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x6c, 0x6f, /* outer.lo */ +0x63, 0x61, 0x6c, 0x2e, 0x2f, 0x74, 0x5f, 0x77, /* cal./t_w */ +0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x67, /* elcom.cg */ +0x69, 0x0d, 0x75, 0x73, 0x62, 0x5f, 0x4d, 0x46, /* i.usb_MF */ +0x47, 0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x27, /* G=Canon' */ +0x75, 0x73, 0x62, 0x5f, 0x4d, 0x44, 0x4c, 0x3d, /* usb_MDL= */ +0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x20, 0x4d, 0x46, /* Canon MF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x20, 0x53, 0x65, /* 4500w Se */ +0x72, 0x69, 0x65, 0x73, 0x20, 0x28, 0x55, 0x46, /* ries (UF */ +0x52, 0x49, 0x49, 0x20, 0x4c, 0x54, 0x29, 0x0d, /* RII LT). */ +0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, /* transpar */ +0x65, 0x6e, 0x74, 0x3d, 0x46, 0x08, 0x42, 0x69, /* ent=F.Bi */ +0x6e, 0x61, 0x72, 0x79, 0x3d, 0x46, 0x06, 0x54, /* nary=F.T */ +0x42, 0x43, 0x50, 0x3d, 0x46, 0x07, 0x43, 0x6f, /* BCP=F.Co */ +0x6c, 0x6f, 0x72, 0x3d, 0x46, 0x08, 0x43, 0x6f, /* lor=F.Co */ +0x70, 0x69, 0x65, 0x73, 0x3d, 0x54, 0x08, 0x44, /* pies=T.D */ +0x75, 0x70, 0x6c, 0x65, 0x78, 0x3d, 0x54, 0x0d, /* uplex=T. */ +0x50, 0x61, 0x70, 0x65, 0x72, 0x43, 0x75, 0x73, /* PaperCus */ +0x74, 0x6f, 0x6d, 0x3d, 0x54, 0x06, 0x42, 0x69, /* tom=T.Bi */ +0x6e, 0x64, 0x3d, 0x46, 0x09, 0x43, 0x6f, 0x6c, /* nd=F.Col */ +0x6c, 0x61, 0x74, 0x65, 0x3d, 0x54, 0x06, 0x53, /* late=T.S */ +0x6f, 0x72, 0x74, 0x3d, 0x54, 0x08, 0x53, 0x74, /* ort=T.St */ +0x61, 0x70, 0x6c, 0x65, 0x3d, 0x46, 0x07, 0x50, /* aple=F.P */ +0x75, 0x6e, 0x63, 0x68, 0x3d, 0x46, 0x11, 0x50, /* unch=F.P */ +0x61, 0x70, 0x65, 0x72, 0x4d, 0x61, 0x78, 0x3d, /* aperMax= */ +0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x41, 0x34 /* legal-A4 */ +}; + +/* Frame (165 bytes) */ +static const unsigned char pkt3[165] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x97, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x67, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .g...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x83, /* ........ */ +0x26, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* &3...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, /* l......_ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x93, 0x00, 0x29, 0x0c, 0x43, 0x61, 0x6e, /* ...).Can */ +0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* onMF4500 */ +0x77, 0x0f, 0x5f, 0x70, 0x64, 0x6c, 0x2d, 0x64, /* w._pdl-d */ +0x61, 0x74, 0x61, 0x73, 0x74, 0x72, 0x65, 0x61, /* atastrea */ +0x6d, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* m._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + +/* Frame (165 bytes) */ +static const unsigned char pkt4[165] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x97, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x66, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .f...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x83, /* ........ */ +0x26, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* &5...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, /* l......_ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x91, 0x00, 0x29, 0x0c, 0x43, 0x61, 0x6e, /* ...).Can */ +0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* onMF4500 */ +0x77, 0x0f, 0x5f, 0x70, 0x64, 0x6c, 0x2d, 0x64, /* w._pdl-d */ +0x61, 0x74, 0x61, 0x73, 0x74, 0x72, 0x65, 0x61, /* atastrea */ +0x6d, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* m._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + diff --git a/test/regression/mdns_test/capture/_pdl-datastream._tcp.pcapng b/test/regression/mdns_test/capture/_pdl-datastream._tcp.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..a6f33f6999781d5b3e7823e7a22915422fdfce61 GIT binary patch literal 2564 zcmeHJL1-Lh6n>NJY&SKb87K%6%HIl_*zWFZc9XCrBhBt+YDp88X1gL(*MDcG$=KPM zarU3=MiB}T@lYvh!J~K(d-Wj2+g_@ka`IxaPOee-4xkBuFE9{`r;Pd+E%y&uakoP^mzx@imcs_mLyr_JWrsugV5hQ+GfxWaO$ zSTnR8lg-VlIY>YjDq+hvxX*H#oSISDpOd%Qo zVH56$@x9*%7=mfIRIv!^(n?ityj#qb)ai15Cao?m7Sjc_IGZl13zc-PQYz&a^F@8O zpuYz&f}WD-XY?s!$1M>)?d{S4<(vBnn2^rOb+kz(cmv>fP)_74^%N`uyaI>LKwtUk zR_`X1?%}he4~{;7!tg0vJV*&|M;gBAq)je(TLczwB^tu;WydqPLt$d#gh#m7P)P{) z6U2QBZPI)mFEQ>1ci+ST6qNqXRWk6TloS0OjHo{}7{}K*mY08v#&ohrM#d;#OyU_N?!{*yZT~Vos4L|M!~5eZH{i%< znY*65tQTffwbL6-23{zvpm!XktK_8%3Bu@2!|`~W!dZC!T5kd8#%WHuA+3yvuGp}G zww9A!Pgq*&ZQ%*-Xt`(n!1e-LY-%}G!E1!Z2yRX_JJ0%oXNHE*CjXkpFs3H3dK&kA z$2PdIJvZwa!V>90Ennhh%XY)S(bk3VPiM1(kTX$rGg;B-SdQVfGRB%c7Pgy>W&P{` z_QhyaIln6i1f!SBw%Tm+qJH7rId;A_H6{Y?wtXI0uF&*U$#!|Lsp-jDsa)0cLuJqL z0-P^WOR#&TyRk?2k<*+ThmR3vRK2y_2aJj?rNNUMdFA%tVRd8I7j;f(+ ztZTXwZCmDD&9TkJjky`|VZcr4j&kNtZXUbd-$AB4iks4% zd8`<{`v=02iI@}Pd$IrL%fHDN;tBEP2dXOy^^aSny8I>Dq<`z7pFt|>p=%HI(5)A! z=h1R{^Y`srPtadJg{g=7%VW0;;-@@*CU_LeaC+x{vO>+1j=0-W~ ztT|?@o)XBk7NlZ wpzMV%ei+*fKUo{LX_>6K$;`oz*AS#4u73XdygVG+v@e17cI-<=d$$nAA6rwc;s5{u literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/_printer._tcp.c b/test/regression/mdns_test/capture/_printer._tcp.c new file mode 100644 index 00000000..c4fa12a6 --- /dev/null +++ b/test/regression/mdns_test/capture/_printer._tcp.c @@ -0,0 +1,125 @@ +/* Frame (79 bytes) */ +static const unsigned char pkt1[79] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x41, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .A..@... */ +0xd9, 0xbe, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2d, /* .......- */ +0xc5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* al..... */ +}; + +/* Frame (497 bytes) */ +static const unsigned char pkt2[497] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x01, 0xe3, 0x77, 0x9c, 0x00, 0x00, 0xff, 0x11, /* ..w..... */ +0xa0, 0xc5, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0xcf, /* ........ */ +0x46, 0x4d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FM...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, /* ......Ca */ +0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, /* nonMF450 */ +0x30, 0x77, 0xc0, 0x0c, 0x06, 0x72, 0x6f, 0x75, /* 0w...rou */ +0x74, 0x65, 0x72, 0xc0, 0x1a, 0x00, 0x01, 0x80, /* ter..... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, /* ....x... */ +0xa8, 0x00, 0x04, 0xc0, 0x2b, 0x00, 0x21, 0x80, /* ....+.!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x02, 0x03, 0xc0, 0x3a, 0xc0, /* ......:. */ +0x2b, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, /* +....... */ +0x94, 0x01, 0x56, 0x09, 0x74, 0x78, 0x74, 0x76, /* ..V.txtv */ +0x65, 0x72, 0x73, 0x3d, 0x31, 0x07, 0x72, 0x70, /* ers=1.rp */ +0x3d, 0x61, 0x75, 0x74, 0x6f, 0x05, 0x6e, 0x6f, /* =auto.no */ +0x74, 0x65, 0x3d, 0x08, 0x71, 0x74, 0x6f, 0x74, /* te=.qtot */ +0x61, 0x6c, 0x3d, 0x31, 0x0b, 0x70, 0x72, 0x69, /* al=1.pri */ +0x6f, 0x72, 0x69, 0x74, 0x79, 0x3d, 0x32, 0x30, /* ority=20 */ +0x11, 0x74, 0x79, 0x3d, 0x43, 0x61, 0x6e, 0x6f, /* .ty=Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x37, 0x30, /* n MF4570 */ +0x64, 0x77, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, /* dw.produ */ +0x63, 0x74, 0x3d, 0x28, 0x43, 0x61, 0x6e, 0x6f, /* ct=(Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* n MF4500 */ +0x77, 0x29, 0x1c, 0x70, 0x64, 0x6c, 0x3d, 0x61, /* w).pdl=a */ +0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, /* pplicati */ +0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, /* on/octet */ +0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2a, /* -stream* */ +0x61, 0x64, 0x6d, 0x69, 0x6e, 0x75, 0x72, 0x6c, /* adminurl */ +0x3d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, /* =http:// */ +0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x6c, /* router.l */ +0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x2f, 0x74, 0x5f, /* ocal./t_ */ +0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x2e, 0x63, /* welcom.c */ +0x67, 0x69, 0x0d, 0x75, 0x73, 0x62, 0x5f, 0x4d, /* gi.usb_M */ +0x46, 0x47, 0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* FG=Canon */ +0x27, 0x75, 0x73, 0x62, 0x5f, 0x4d, 0x44, 0x4c, /* 'usb_MDL */ +0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x20, 0x4d, /* =Canon M */ +0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0x20, 0x53, /* F4500w S */ +0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x28, 0x55, /* eries (U */ +0x46, 0x52, 0x49, 0x49, 0x20, 0x4c, 0x54, 0x29, /* FRII LT) */ +0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, /* .transpa */ +0x72, 0x65, 0x6e, 0x74, 0x3d, 0x46, 0x08, 0x42, /* rent=F.B */ +0x69, 0x6e, 0x61, 0x72, 0x79, 0x3d, 0x46, 0x06, /* inary=F. */ +0x54, 0x42, 0x43, 0x50, 0x3d, 0x46, 0x07, 0x43, /* TBCP=F.C */ +0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x46, 0x08, 0x43, /* olor=F.C */ +0x6f, 0x70, 0x69, 0x65, 0x73, 0x3d, 0x54, 0x08, /* opies=T. */ +0x44, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x3d, 0x54, /* Duplex=T */ +0x0d, 0x50, 0x61, 0x70, 0x65, 0x72, 0x43, 0x75, /* .PaperCu */ +0x73, 0x74, 0x6f, 0x6d, 0x3d, 0x54, 0x06, 0x42, /* stom=T.B */ +0x69, 0x6e, 0x64, 0x3d, 0x46, 0x09, 0x43, 0x6f, /* ind=F.Co */ +0x6c, 0x6c, 0x61, 0x74, 0x65, 0x3d, 0x54, 0x06, /* llate=T. */ +0x53, 0x6f, 0x72, 0x74, 0x3d, 0x54, 0x08, 0x53, /* Sort=T.S */ +0x74, 0x61, 0x70, 0x6c, 0x65, 0x3d, 0x46, 0x07, /* taple=F. */ +0x50, 0x75, 0x6e, 0x63, 0x68, 0x3d, 0x46, 0x11, /* Punch=F. */ +0x50, 0x61, 0x70, 0x65, 0x72, 0x4d, 0x61, 0x78, /* PaperMax */ +0x3d, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x41, /* =legal-A */ +0x34 /* 4 */ +}; + +/* Frame (144 bytes) */ +static const unsigned char pkt3[144] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x82, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x7c, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .|...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6e, /* .......n */ +0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .<...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x08, /* al...... */ +0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, /* _printer */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x93, 0x00, 0x22, 0x0c, 0x43, /* .....".C */ +0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, /* anonMF45 */ +0x30, 0x30, 0x77, 0x08, 0x5f, 0x70, 0x72, 0x69, /* 00w._pri */ +0x6e, 0x74, 0x65, 0x72, 0x04, 0x5f, 0x74, 0x63, /* nter._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + +/* Frame (144 bytes) */ +static const unsigned char pkt4[144] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x82, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x7b, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .{...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6e, /* .......n */ +0x18, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .>...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x08, /* al...... */ +0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, /* _printer */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x91, 0x00, 0x22, 0x0c, 0x43, /* .....".C */ +0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, /* anonMF45 */ +0x30, 0x30, 0x77, 0x08, 0x5f, 0x70, 0x72, 0x69, /* 00w._pri */ +0x6e, 0x74, 0x65, 0x72, 0x04, 0x5f, 0x74, 0x63, /* nter._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + diff --git a/test/regression/mdns_test/capture/_printer._tcp.pcapng b/test/regression/mdns_test/capture/_printer._tcp.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..0515f8363f4e8f694b41e234181045059fbd02fe GIT binary patch literal 2460 zcmeHJPi)&{6n}2hHrX6eLnY8uO{N@ZDNdXwYm{o9+9Wlaw2Y|D%4H(Bw%M#Y{ygV% z(=sMa2qA6-u_Ff#95{jmSCj+e%B6y$X>3|Gq#ZdUHN59o(3N)L&wvY0diMLie((GJ z-s`W=J(f-%dm8|1r>9Q{`0m9v2-7fIP*xo-zv6fn>$K&fyle;Sj%mwv!(5YdFUqT- z<63fYR?R^IvQQ0MzG?V!E|XI;syw;8a$a7t*X2T~SW@NJ1J;tWJP5rtg-%Q%8USGv z?z{23*8>=U8Ms)r3F_kcy5786%9YibO8%6hE-sdof?AqY%IZQ@$yLkc{9?YO&ldD+ z04cm_81E7PBzH`S@F~})1=<()5^(3qZSiG{$pv^7;AfB~^3|0jECMXR$UO9<@4xJR z0_D5-v#|$b4?wv&iii6p;Vaqn1IOcbkZ5w#A99&#xWrG0a0rj;CnLQ1r?y2CWAc0+ zA2HrLw_n2rC{l0lItADvX`;7>OnL+Tb^MGuzz@-y+KP5G2f`)}WAQD-;o7%5;!l`K z9@l(w>$5kusb*of^C2ok`sgOsoVXj;EPSKa;yMU%@Mt`cZom^_#qgL{(+j6mwbK=c z0~TU`x+g%mPU#zvpv$|{@NB$J;w}sfcIR+!l=h?>!b*y7@O3+AYq^oY*Nl*}A&+re zOJ3oO8?Kf+j*Vx5!#A}VRl;Y4Didr`wK`Ax0kcArYm>k2Bb}*n-*Pp>_g%*{xWl|G zGr7%`HV7TsGUMo{4^|nJjO1Y}aJ1jCsjPhwas7O@FBm`+T&j zp4&$P!RW8avD@jAE_{x1-M^f zKIUnSWHt0%dqZoa>xOR!m9WiOOKS{co~7w2JnkCUlE&~d3pgHM<_4a}i|V0gUeoU?rUzfryY5rGTp4{r~p;`{prEu%a zmB*oz@mLq52SNYW%zvaA(h6zjQ*<(#BcC^R#rH5K|K03-3zE_7eDk5%={<9rvhg?# zf}`iwqXx_eF!9iUIrJ>?B)(q}3>xuWyRa*Mj4}Bkv)B8Bv)5~+=*EA(2I79O=Ud+i z=|}WD74`h;fu5iF+kD^ut35C72AAE3<4|ECedpUU pep%KX%eLgzP1)-ILo@)%NMqLhuf@SQro05k_u{*TFy3#3@e9uni<|%e literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/_smb._tcp.c b/test/regression/mdns_test/capture/_smb._tcp.c new file mode 100644 index 00000000..cfe4fe11 --- /dev/null +++ b/test/regression/mdns_test/capture/_smb._tcp.c @@ -0,0 +1,102 @@ +/* Frame (75 bytes) */ +static const unsigned char pkt1[75] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3d, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .=..@... */ +0xd9, 0xc2, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x29, /* .......) */ +0xb3, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (332 bytes) */ +static const unsigned char pkt2[332] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x33, 0xc1, 0xbd, 0x08, 0x00, 0x45, 0x00, /* s3....E. */ +0x01, 0x3e, 0x09, 0x17, 0x00, 0x00, 0xff, 0x11, /* .>...... */ +0x0f, 0x8f, 0xc0, 0xa8, 0x00, 0x65, 0xe0, 0x00, /* .....e.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x2a, /* .......* */ +0x56, 0xdc, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* V....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0c, 0x09, 0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, /* ..Chenbo */ +0x2d, 0x50, 0x43, 0xc0, 0x0c, 0x09, 0x43, 0x68, /* -PC...Ch */ +0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, 0x43, 0x0c, /* enbo-PC. */ +0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, /* _device- */ +0x69, 0x6e, 0x66, 0x6f, 0xc0, 0x11, 0x00, 0x10, /* info.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0e, /* ........ */ +0x0d, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x3d, 0x57, /* .model=W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0xc0, 0x27, /* indows.' */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbd, /* ........ */ +0x09, 0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, /* .Chenbo- */ +0x50, 0x43, 0xc0, 0x16, 0xc0, 0x27, 0x00, 0x10, /* PC...'.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x23, /* .......# */ +0x11, 0x6e, 0x65, 0x74, 0x62, 0x69, 0x6f, 0x73, /* .netbios */ +0x3d, 0x43, 0x48, 0x45, 0x4e, 0x42, 0x4f, 0x2d, /* =CHENBO- */ +0x50, 0x43, 0x10, 0x64, 0x6f, 0x6d, 0x61, 0x69, /* PC.domai */ +0x6e, 0x3d, 0x57, 0x4f, 0x52, 0x4b, 0x47, 0x52, /* n=WORKGR */ +0x4f, 0x55, 0x50, 0xc0, 0x76, 0x00, 0x01, 0x80, /* OUP.v... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, /* ....x... */ +0xa8, 0x00, 0x65, 0xc0, 0x76, 0x00, 0x1c, 0x80, /* ..e.v... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0x20, /* ....x.. */ +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xc0, /* ......1. */ +0x76, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, /* v....... */ +0x78, 0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, /* x....... */ +0x00, 0x00, 0x00, 0x01, 0x59, 0x44, 0x79, 0xe1, /* ....YDy. */ +0x0a, 0xd7, 0xf4, 0xc0, 0x27, 0x00, 0x2f, 0x80, /* ....'./. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x09, 0xc0, /* ....x... */ +0x27, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* '......@ */ +0xc0, 0x76, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* .v./.... */ +0x00, 0x78, 0x00, 0x08, 0xc0, 0x76, 0x00, 0x04, /* .x...v.. */ +0x40, 0x00, 0x00, 0x08 /* @... */ +}; + +/* Frame (129 bytes) */ +static const unsigned char pkt3[129] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x73, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .s..@... */ +0xd9, 0x8b, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x5f, /* ......._ */ +0x9d, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x04, 0x5f, 0x73, 0x6d, 0x62, /* ...._smb */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x93, 0x00, 0x1b, 0x09, 0x43, /* .......C */ +0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, 0x43, /* henbo-PC */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00 /* . */ +}; + +/* Frame (129 bytes) */ +static const unsigned char pkt4[129] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x73, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .s..@... */ +0xd9, 0x8a, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x5f, /* ......._ */ +0x9d, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x04, 0x5f, 0x73, 0x6d, 0x62, /* ...._smb */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x91, 0x00, 0x1b, 0x09, 0x43, /* .......C */ +0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, 0x43, /* henbo-PC */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00 /* . */ +}; + diff --git a/test/regression/mdns_test/capture/_smb._tcp.pcapng b/test/regression/mdns_test/capture/_smb._tcp.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..33092eb73ed0e6a22f6f757ff4777ca781de8b19 GIT binary patch literal 1672 zcmcIkO=uHQ5S~p^o0L?uQdG2uXFb$fw@sRu8Z=V#Q-x|9T5J)DYm(jK(j*)5r$xjF zB4Q6B)uT6sUUE{zLo3mXUOY>SN|hiK4bw+OaFpDMF(cz%)U4C&3tco4ULTr z*8$-4(e~XOu2nbiKAdBUdgv7eNP8V39 z6GHi9Iv!0kSBJ~l;bi-VhWpu|Twoqwx6jGOGHQ}_<}&%zxIib`5DkE^3HPS4R;vIe z=z`IZOi-i!kzVn#&lPZX1>J`PXE^K=JWiii2sn?21Xm~!aEIN#UazP33V;nWZNWVD zzpNcYG<=Fpkc0C0qXni+rAi;#q#T?B_yK&2J2Y&CFn}NGd!WkCy(mvZU;+1<7Mm8K z?a@~}tha=VMa(8+7BLr3*Co_=6qDOA6JZcm5tW3nz+9?`Xp_3#_%X0x?Kbu*FBrXY2ZrD3_lFk-P+uDh_`6`Y1uw{{m?}hq77=D~r$ zbbM=LQkCR{-7gN-%KX@|S9~eM5homN> zO3FVnFxYouaNta&Tma5UW}#-#Z#H}fBajtwt=?NEpF10x_|Wj?8^U%PaW=H;=rVgS zVELyNZA%Y;HGxTq>jy?+;<^-?sa!*!bi-U_!K%&G?=NZzI1E6k$#u=2$jlV% zSz&DBA-y)L@u>!(&*PEsOywT>q&4PI{KI(^=bmUu|4ZFe?|N=0U(WxETbsu1t##af z-gJ$3Hp8v$)%?HVR==>#aQoZ3DK$>@n)mS2_xBYJnjxs>Q#m=4W$BDsP$XGmu?Z&W gkG~15+I#l;@WYDPuqn=h_En8$%4;<&eWCa8C(^l#9RL6T literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/address_change.c b/test/regression/mdns_test/capture/address_change.c new file mode 100644 index 00000000..bcc439ac --- /dev/null +++ b/test/regression/mdns_test/capture/address_change.c @@ -0,0 +1,346 @@ +/* Frame (269 bytes) */ +static const unsigned char pkt1[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xaf, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt2[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xae, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt3[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xad, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt4[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x04, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x2b, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .+...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt5[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x05, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x2a, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .*...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt6[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x06, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x29, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .)...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (171 bytes) */ +static const unsigned char pkt7[171] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x9d, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x0a, 0x0a, 0x00, 0x00, 0x43, 0xe0, 0x00, /* .....C.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x89, /* ........ */ +0xee, 0x54, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .T...... */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* ......B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x43, /* .x.....C */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, /* ..x...AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x01, 0x40 /* ..@ */ +}; + +/* Frame (138 bytes) */ +static const unsigned char pkt8[138] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x7c, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .|..@... */ +0x90, 0x2a, 0x0a, 0x00, 0x00, 0x43, 0xe0, 0x00, /* .*...C.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x68, /* .......h */ +0xb8, 0x73, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .s...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x43, 0x0b, /* x.....C. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40 /* .@ */ +}; + +/* Frame (138 bytes) */ +static const unsigned char pkt9[138] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x7c, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .|..@... */ +0x90, 0x29, 0x0a, 0x00, 0x00, 0x43, 0xe0, 0x00, /* .)...C.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x68, /* .......h */ +0xb8, 0x73, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .s...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x43, 0x0b, /* x.....C. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40 /* .@ */ +}; + diff --git a/test/regression/mdns_test/capture/address_change.pcapng b/test/regression/mdns_test/capture/address_change.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..3f91b89f82dd21d7f5ed79c78b29712f4601ce91 GIT binary patch literal 3152 zcmeHJ&1(};5TDIQO=Bw-i=c=+g@QHRHfc5=g;ttu(t2qrZ84W(O|q*EO|#2plPW6o zAO$_Be}LXR`F%3|54`BVAQkjb3SPVv1mn!h2Aibasvs5Yz{|dU``*lNX5RcV-p)?% z9RQdZ_MH^)S+&FoJ_t)t0JuPe zL}^LSrgawRkM{f7xtU9oY+5ZdDJTU4?5d$Hu>sR46&6L@(2KT6$Tr!1WId}@00#`h zTtX#NbCXkJ^EV|q8jr^1F)@;qVxkn0{o+tO6cfWkNq;PqNJfL9@NIy0)YOK04#N?E zlA<$RGfWl=hJpYczv&OE;h0FDp8%q4eR6^MX0g(V?=%Fs4Db!Q&IS`H4oAdEt_ z>%l88Kztp)b#HWUz~-?Ye%yh-PDB@*o|s5X&djPs)1B9{={!H!uspwDn!0P=%<8-C zunr0kMA^^>rq$%7mt^3 zd%T4F*m#Y1I9cpikGq$ZRd)kc-5qZznR-!Eh~3G~{Yi}vVTU%OPI(p|QXe8W(8I40 zCXf%r70(F*3i+~m@onWE&S|vxatl1%7vhSazAUU2EnleH+LPP=2r9?ejP>LD&vsbb zIaaEZeZY!*4A^9Hp}0PEe^?XX6v$esU}6KubVDoW6jfoF8%(J+@ec6t9LR$gDo$%o P=Uh0ii+kIg*2u;WLCpZ` literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/announcement_in_multiple_packets.c b/test/regression/mdns_test/capture/announcement_in_multiple_packets.c new file mode 100644 index 00000000..2f5f64f3 --- /dev/null +++ b/test/regression/mdns_test/capture/announcement_in_multiple_packets.c @@ -0,0 +1,1935 @@ +/* Frame (1425 bytes) */ +static const unsigned char pkt1[1425] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0x83, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8b, 0x2b, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .+...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x6f, /* .......o */ +0x19, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, /* ........ */ +0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st1._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, /* .test2._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, /* est4._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, /* ocal.... */ +0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t6._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, /* al...... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x38, /* ...test8 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st9._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x06, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* B.test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, 0x04, /* ..test3. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st4._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 5._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, /* test6._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, /* ..test7. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x37, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 7._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 9._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, /* st10._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 11._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, /* est11._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00 /* . */ +}; + +/* Frame (420 bytes) */ +static const unsigned char pkt2[420] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x96, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x17, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x82, /* ........ */ +0x5b, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* [X...... */ +0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x06, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 2._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, /* st12._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 13._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, /* ..d....t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, /* ..test14 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00 /* d... */ +}; + +/* Frame (1425 bytes) */ +static const unsigned char pkt3[1425] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0x83, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8b, 0x29, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .)...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x6f, /* .......o */ +0x19, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, /* ........ */ +0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st1._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, /* .test2._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, /* est4._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, /* ocal.... */ +0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t6._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, /* al...... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x38, /* ...test8 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st9._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x06, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* B.test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, 0x04, /* ..test3. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st4._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 5._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, /* test6._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, /* ..test7. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x37, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 7._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 9._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, /* st10._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 11._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, /* est11._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00 /* . */ +}; + +/* Frame (420 bytes) */ +static const unsigned char pkt4[420] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x96, 0x00, 0x04, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x15, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x82, /* ........ */ +0x5b, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* [X...... */ +0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x06, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 2._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, /* st12._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 13._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, /* ..d....t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, /* ..test14 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00 /* d... */ +}; + +/* Frame (1425 bytes) */ +static const unsigned char pkt5[1425] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0x83, 0x00, 0x05, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8b, 0x27, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .'...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x6f, /* .......o */ +0x19, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, /* ........ */ +0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st1._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, /* .test2._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, /* est4._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, /* ocal.... */ +0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t6._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, /* al...... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x38, /* ...test8 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st9._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x06, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* B.test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, 0x04, /* ..test3. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st4._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 5._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, /* test6._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, /* ..test7. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x37, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 7._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 9._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, /* st10._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 11._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, /* est11._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00 /* . */ +}; + +/* Frame (420 bytes) */ +static const unsigned char pkt6[420] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x96, 0x00, 0x06, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x13, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x82, /* ........ */ +0x5b, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* [X...... */ +0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x06, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 2._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, /* st12._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 13._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, /* ..d....t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, /* ..test14 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00 /* d... */ +}; + +/* Frame (1510 bytes) */ +static const unsigned char pkt7[1510] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xd8, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xd0, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc4, /* ........ */ +0xa2, 0xee, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, /* .@.test1 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t1._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, /* .test1._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, /* ..test2. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, /* ...@.tes */ +0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t3._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, /* est3._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, /* l..test3 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, /* @.test4. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, /* .....d.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, /* .....x.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, /* .....@.t */ +0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, /* est5._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, /* .test5._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* ..._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, /* ..d...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t5._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 6._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, 0x04, /* ..test6. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* .......@ */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, /* .test7._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, /* l..test7 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* local. */ +}; + +/* Frame (1512 bytes) */ +static const unsigned char pkt8[1512] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xda, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xcd, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc6, /* ........ */ +0xb1, 0xb4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, /* est7._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, /* ocal../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, /* ....x... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 8._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, /* .@.test9 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t9._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, 0x5f, /* .test9._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, /* test10._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x31, /* @.test11 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x18, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x06, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 12._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x18, 0x06, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x06, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, /* st13._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x18, 0x06, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, /* test14._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + +/* Frame (119 bytes) */ +static const unsigned char pkt9[119] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x69, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .i..@... */ +0x90, 0x3d, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .=...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x55, /* .......U */ +0x14, 0x46, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .F...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* ......@ */ +}; + +/* Frame (1510 bytes) */ +static const unsigned char pkt10[1510] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xd8, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xcd, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc4, /* ........ */ +0xa2, 0xee, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, /* .@.test1 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t1._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, /* .test1._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, /* ..test2. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, /* ...@.tes */ +0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t3._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, /* est3._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, /* l..test3 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, /* @.test4. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, /* .....d.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, /* .....x.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, /* .....@.t */ +0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, /* est5._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, /* .test5._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* ..._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, /* ..d...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t5._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 6._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, 0x04, /* ..test6. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* .......@ */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, /* .test7._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, /* l..test7 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* local. */ +}; + +/* Frame (1512 bytes) */ +static const unsigned char pkt11[1512] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xda, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xca, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc6, /* ........ */ +0xb1, 0xb4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, /* est7._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, /* ocal../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, /* ....x... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 8._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, /* .@.test9 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t9._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, 0x5f, /* .test9._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, /* test10._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x31, /* @.test11 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x18, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x06, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 12._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x18, 0x06, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x06, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, /* st13._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x18, 0x06, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, /* test14._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + +/* Frame (119 bytes) */ +static const unsigned char pkt12[119] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x69, 0x00, 0x0c, 0x40, 0x00, 0xff, 0x11, /* .i..@... */ +0x90, 0x3a, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .:...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x55, /* .......U */ +0x14, 0x46, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .F...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* ......@ */ +}; + +/* Frame (1510 bytes) */ +static const unsigned char pkt13[1510] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xd8, 0x00, 0x0d, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xca, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc4, /* ........ */ +0xa2, 0xee, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, /* .@.test1 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t1._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, /* .test1._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, /* ..test2. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, /* ...@.tes */ +0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t3._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, /* est3._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, /* l..test3 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, /* @.test4. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, /* .....d.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, /* .....x.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, /* .....@.t */ +0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, /* est5._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, /* .test5._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* ..._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, /* ..d...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t5._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 6._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, 0x04, /* ..test6. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* .......@ */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, /* .test7._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, /* l..test7 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* local. */ +}; + +/* Frame (1512 bytes) */ +static const unsigned char pkt14[1512] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xda, 0x00, 0x0e, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xc7, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc6, /* ........ */ +0xb1, 0xb4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, /* est7._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, /* ocal../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, /* ....x... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 8._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, /* .@.test9 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t9._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, 0x5f, /* .test9._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, /* test10._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x31, /* @.test11 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x18, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x06, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 12._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x18, 0x06, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x06, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, /* st13._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x18, 0x06, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, /* test14._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + +/* Frame (119 bytes) */ +static const unsigned char pkt15[119] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x69, 0x00, 0x0f, 0x40, 0x00, 0xff, 0x11, /* .i..@... */ +0x90, 0x37, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .7...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x55, /* .......U */ +0x14, 0x46, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .F...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* ......@ */ +}; + diff --git a/test/regression/mdns_test/capture/announcement_in_multiple_packets.pcapng b/test/regression/mdns_test/capture/announcement_in_multiple_packets.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..64e3fd7290f1cdbec45648c69aa18c838622d786 GIT binary patch literal 15852 zcmeHO-)mz<82!>FwcBl1%eL0Ys#g(oso8BdY14{Ie=jVwlvZ8A#gaA=!giaOrd`Dq zia!waL4A>Z*eCHtL_yg_DmLGV%ZMMTAY5z!aXhdML&CYj8fx%na}BKN{2$;_N{ z@0lOpneQg)8yM(&nTVDi8ofOxUJrt!n?`9Oo7yPVytAe4Liys3m-E(&)xFYY(Ob!H zp7+uZcpJN=t%8@E7)w)}QZ&DNp|Y8;cG*o7Qi-qEHY;Y;DR))IU6plL zjk~KR+*LVu)ug*>3Rd+f$zvgPxIa)2#`fhbdY0m{>s@_$w`x?Nq#O=f0X#0`Edeq{ zss$JfCO1GD++Z}B+yH5CgXzHJ21tV&%qJ!{KpNa&LNd7l(%=R&n#m221~*s|Om2WQ zxWSrYasy;@5j|$dUVQQiiKcFG3OZjISi2%{`*mRLHR{0HY19EuZdU+kvn!l;#bpPAOm?7) z%MPGTb~$#Y?_T=uOqlO>E8jh?k74AyJ2kM<8#6ER-BwQr6TbayR=WX!Y))p?0!()% zH$WQPz&)AV0BLXo_hfPdq`?i`lgSN`1~+g|CO1GD++a;HxdF1t?KIE!Zyh+Q*KT;mwUFK%`T+D4W>Jj8z2pC;GRrwfHb&)dosBJ(%=T}$>at|gB!Rf zlN%rnZs49wZh&lZJI%8_xf5!#1M}pv189@o;k#2;m&1IwNBQniJ!VI~`(Ngi|Iz|tAP(3lRlt230$r zto6kcD6)~HD*~>~9U}nkK#`6171`zH7=aeLB4FKIMF84?A{*^1vdc|HpoOjo_%~M( zfOeqBM%R7dvJBtikomxSAFd`Ziudv~eSk`INczB=59>Zaj}0vbJ|MTz!FQPU)y#eZ zE&P5Wc|WE0-dfpD6|)`C@Fa5@Q!Pf|b8!Km$KkDLB~pGsOTTUyKcQ z-A(Jr*f@P;zy_Tu1|a!j02t;ekNlbs%To?3ANXANr$m&eM0twXQH1>*)8E^HU#f5> zaFnM|BV0y#O5+FB?W3kMqv&AP*?R^jYuyEcF|v^@xg_v!t|9>KK#`3`dCK%}`LH~t zU*#ze>OS!A+cxt*P7bwfkn(&YEhmd{=(sJ?d@=*?}ov~ zpE)uB$sZXT9OWtU|4UlZ1ri44$N(gNWB?fEDObw-VR_0C2BIeR)giy<8D4%>{15vW&6RhzYsKo0SE-iwN`+#<+j!0^_...j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2b, /* .......+ */ +0xa2, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .J...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x45, /* RMMDNSTE */ +0x53, 0x54, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* ST.local */ +0x00, 0x00, 0x01, 0x00, 0x01 /* ..... */ +}; + +/* Frame (138 bytes) */ +static const unsigned char pkt2[138] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x7c, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .|..@... */ +0x90, 0x2c, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .,...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x68, /* .......h */ +0xb9, 0x74, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .t...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40 /* .@ */ +}; + diff --git a/test/regression/mdns_test/capture/case_insensitivity.pcapng b/test/regression/mdns_test/capture/case_insensitivity.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..5b5b9cad325f8a2141c2dabbf965ce144775bd27 GIT binary patch literal 684 zcmb7?J#W)s5Xb*+5-2GhB2@?w!wCtADs^kePTWYmw5gK;DN$8dbg3v#>XJfxK*9`p`WPFQ4?h_HqGd1}XFU6xjm19h~KaN=T2NQ znM-;~y~yZy7AH@SttR`T3Z4Leu4np-d;7Df0}t=Je8s}g2j9Qq`6s!sH-Ey|;&UUUFcHFLn1`)Xm2;loPtJMog!d9zDZD6QWtwp9qM)*t&Y0sKJp4pt);rD*OTjH{ tgo9q<$9;<8a2R;LN9|YSr5|Jlvy;7k-S}i>roPl=**}xqKfb&P<1ct@o0I?m literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/client_passive.c b/test/regression/mdns_test/capture/client_passive.c new file mode 100644 index 00000000..23c5714e --- /dev/null +++ b/test/regression/mdns_test/capture/client_passive.c @@ -0,0 +1,209 @@ +/* Frame (134 bytes) */ +static const unsigned char pkt1[134] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0x78, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .x..@... */ +0xd9, 0x67, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .g...i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x64, /* .......d */ +0x0c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .O...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0xc0, 0x0c, /* l....... */ +0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x06, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0xc0, /* .ubuntu. */ +0x29, 0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01, 0x00, /* )....... */ +0x00, 0x11, 0x94, 0x00, 0x01, 0x00 /* ...... */ +}; + +/* Frame (134 bytes) */ +static const unsigned char pkt2[134] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0x78, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .x..@... */ +0xd9, 0x67, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .g...i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x64, /* .......d */ +0x0c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .O...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0xc0, 0x0c, /* l....... */ +0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x06, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0xc0, /* .ubuntu. */ +0x29, 0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01, 0x00, /* )....... */ +0x00, 0x11, 0x94, 0x00, 0x01, 0x00 /* ...... */ +}; + +/* Frame (134 bytes) */ +static const unsigned char pkt3[134] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0x78, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .x..@... */ +0xd9, 0x67, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .g...i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x64, /* .......d */ +0x0c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .O...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0xc0, 0x0c, /* l....... */ +0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x06, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0xc0, /* .ubuntu. */ +0x29, 0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01, 0x00, /* )....... */ +0x00, 0x11, 0x94, 0x00, 0x01, 0x00 /* ...... */ +}; + +/* Frame (223 bytes) */ +static const unsigned char pkt4[223] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0xd1, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x0e, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbd, /* ........ */ +0xc6, 0xe4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x1e, 0x00, /* ........ */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x0f, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x06, 0x75, 0x62, /* ....P.ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x29, 0xc0, 0x5b, /* untu.).[ */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x01, /* ....)... */ +0xd4, 0x79, 0xc0, 0x5b, 0x00, 0x01, 0x80, 0x01, /* .y.[.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x69, 0x09, 0x5f, 0x73, 0x65, 0x72, 0x76, /* .i._serv */ +0x69, 0x63, 0x65, 0x73, 0x07, 0x5f, 0x64, 0x6e, /* ices._dn */ +0x73, 0x2d, 0x73, 0x64, 0x04, 0x5f, 0x75, 0x64, /* s-sd._ud */ +0x70, 0xc0, 0x29, 0x00, 0x0c, 0x00, 0x01, 0x00, /* p.)..... */ +0x00, 0x11, 0x94, 0x00, 0x02, 0xc0, 0x1e /* ....... */ +}; + +/* Frame (223 bytes) */ +static const unsigned char pkt5[223] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0xd1, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x0e, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbd, /* ........ */ +0xc6, 0xe4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x1e, 0x00, /* ........ */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x0f, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x06, 0x75, 0x62, /* ....P.ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x29, 0xc0, 0x5b, /* untu.).[ */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x01, /* ....)... */ +0xd4, 0x79, 0xc0, 0x5b, 0x00, 0x01, 0x80, 0x01, /* .y.[.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x69, 0x09, 0x5f, 0x73, 0x65, 0x72, 0x76, /* .i._serv */ +0x69, 0x63, 0x65, 0x73, 0x07, 0x5f, 0x64, 0x6e, /* ices._dn */ +0x73, 0x2d, 0x73, 0x64, 0x04, 0x5f, 0x75, 0x64, /* s-sd._ud */ +0x70, 0xc0, 0x29, 0x00, 0x0c, 0x00, 0x01, 0x00, /* p.)..... */ +0x00, 0x11, 0x94, 0x00, 0x02, 0xc0, 0x1e /* ....... */ +}; + +/* Frame (223 bytes) */ +static const unsigned char pkt6[223] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0xd1, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x0e, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbd, /* ........ */ +0xc6, 0xe4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x1e, 0x00, /* ........ */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x0f, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x06, 0x75, 0x62, /* ....P.ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x29, 0xc0, 0x5b, /* untu.).[ */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x01, /* ....)... */ +0xd4, 0x79, 0xc0, 0x5b, 0x00, 0x01, 0x80, 0x01, /* .y.[.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x69, 0x09, 0x5f, 0x73, 0x65, 0x72, 0x76, /* .i._serv */ +0x69, 0x63, 0x65, 0x73, 0x07, 0x5f, 0x64, 0x6e, /* ices._dn */ +0x73, 0x2d, 0x73, 0x64, 0x04, 0x5f, 0x75, 0x64, /* s-sd._ud */ +0x70, 0xc0, 0x29, 0x00, 0x0c, 0x00, 0x01, 0x00, /* p.)..... */ +0x00, 0x11, 0x94, 0x00, 0x02, 0xc0, 0x1e /* ....... */ +}; + +/* Frame (223 bytes) */ +static const unsigned char pkt7[223] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0xd1, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x0e, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbd, /* ........ */ +0x6e, 0xb6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* n....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0xc0, 0x23, 0xc0, 0x34, 0x00, 0x0c, 0x00, /* p.#.4... */ +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x11, /* ........ */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0xc0, 0x34, 0xc0, 0x4d, 0x00, 0x21, 0x80, /* r.4.M.!. */ +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x06, 0x75, 0x62, /* ....P.ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x23, 0xc0, 0x73, /* untu.#.s */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x01, /* ....)... */ +0xd4, 0x79, 0xc0, 0x73, 0x00, 0x01, 0x80, 0x01, /* .y.s.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x69, 0xc0, 0x4d, 0x00, 0x10, 0x80, 0x01, /* .i.M.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 /* ....... */ +}; + +/* Frame (107 bytes) */ +static const unsigned char pkt8[107] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x5d, 0x13, 0xc0, 0x00, 0x00, 0xff, 0x11, /* .]...... */ +0x06, 0x28, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* .(...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x49, /* .......I */ +0x79, 0x60, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* y`...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x0d, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0xc0, 0x23 /* p.# */ +}; + diff --git a/test/regression/mdns_test/capture/client_passive.pcapng b/test/regression/mdns_test/capture/client_passive.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..d9878160a10b9a7f0b5acd1240a33b7c5beb5c52 GIT binary patch literal 2064 zcmd^A%}*0i5T9F(Jm7 zm}tBh$$!z3>|yYqHF-u!;^LTzoK zhX62nzW=ljpH)x%&=13^k~17OYZSH89h;@tjBb^Uyw0W<@=Gj!mgQWdpt00&EDka# zka3sI{DR5i10w@5);Du)ie1&qOiilEIJ;$)mf4_Vxy2;~H$*WO3B{(kue@iq3LrrO z<}*5lnxC4U$lgn()Uou4I;u>>l5s`N#F9!nF`Q6_E~ZCgnemBqVmy8yAc&q?(9cO| z2XHl$nI+3%L&>2eK=_FDpc|1B`CFqGl=oXQ_^+%7AE8dm2R8tIKsf5#thB;7zzV}|&}<*bu81BFt4p@3}w z9}mMBaWpH?A^x9kadU3bad{L?on(qU7aJ(Q{dw-pfA}x*Tr@uZvw4cc#j~Zpzj^#A z_!V_p2m1cm>w9}s-`6+3)$lEvbGW{DuGZVidl0j=7m0@n3}ixx9RR}|bbF@Gy;a6{82<7tq<+%..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (153 bytes) */ +static const unsigned char pkt2[153] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x7e, 0xd1, 0x00, 0x00, 0xff, 0x11, /* ..~..... */ +0x9a, 0xe8, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt3[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x85, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt4[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x84, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt5[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x83, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x8d, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt6[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x82, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x85, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + diff --git a/test/regression/mdns_test/capture/continuous_query.pcapng b/test/regression/mdns_test/capture/continuous_query.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..4c880dbef95297a8e4b2db32f292ee2c74f87cd8 GIT binary patch literal 2444 zcmcImQAkr^6h70*mHF!sfQ86v=RO|wWwY6THu z^-wP8E$p#}9)h3+J@sb!5?F{7B=pov4}rIH{#_&2Ma;Pa=ic-G_y5oLo$o)~d#h?{ zsuloX;AH1<1Kw55%ApgS4(oU%#YQ9Xurf2nTx?iQPDesA8w!S^OzL9e=}0WhTuxB} zBXol|J(&mv6HKy6qD^G&!y|+2tUS#eZkJnRmy*gP>rN%p@u-znoIo@H!Y16?+Fexv z%Ag0vyfQ(J4G#GO*W8jv?CH1nT1B7FZFPulr`02#_F5&c$7A=|-F~OTe;uF_GgV+7 z%YSmmEgYZr#%O@{V#^5cmmzxwV{!vr0Qdz$o83EN1|PsFIMxTM@bOJ<6+D~xtYN!h z8#=mv;^KTscryhiQmKS7kP0PCF(nkl>=rN(24Q8;$q1|U9%L_KOm4U1MZ>!JiDsZf zP1sDGri-qpN#kEvh$#wcyK4AaKvCo*Ggxq)g=WmTOBewlCuH+go z6lh#u1kdHeX&fE39gW7DrRA=tarIbqKaH!n#`6UlHx|M3?%_1vK%Pg^$6rdzT~Fis z%U}1?xSDHxqd?=9B6uzyPUCmT^GG!QURv&?u?d~N*JSiQem3you>qQ(UrERD6E?*X rNo6_`mcwj(mWA^_KxJU&YhOS4u~M$Zw9km~9DgTMUUNRFb|sA8WP(3~ literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/continuous_query_a.c b/test/regression/mdns_test/capture/continuous_query_a.c new file mode 100644 index 00000000..275318db --- /dev/null +++ b/test/regression/mdns_test/capture/continuous_query_a.c @@ -0,0 +1,30 @@ +/* Frame (79 bytes) */ +static const unsigned char pkt1[79] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x41, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .A..@... */ +0x90, 0xaf, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2d, /* .......- */ +0xf0, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .X...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x5f, 0x30, 0x05, 0x6c, 0x6f, 0x63, /* st_0.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x00, 0x01 /* al..... */ +}; + +/* Frame (89 bytes) */ +static const unsigned char pkt2[89] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x4b, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .K..@... */ +0x90, 0x5d, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .]...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x37, /* .......7 */ +0xad, 0x78, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x5f, 0x30, 0x05, 0x6c, 0x6f, 0x63, /* st_0.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42 /* B */ +}; + diff --git a/test/regression/mdns_test/capture/continuous_query_a.pcapng b/test/regression/mdns_test/capture/continuous_query_a.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..67deab8e5a84689f9fe879c31d5d9e8727b02bea GIT binary patch literal 640 zcmb7>J!{)g6oy|pcA7fz5J;EO;m|1|RVqi4WR1rf&*vgD++ zg$|txh5m@HrDOj=enHnlmJZpnXK>Du9q7`bFC6a6Js;1xQn6Gjege>Zw)#-vb3D}y zR#7q3ZjjJ^Fz~{&Az9S+<5AG_X{XaWq4E>zra|8$tD=>WhYBY>je4Dk%4^j%jh5Sc zE!y=*Wax%orZ;hTN>7tG9h|6Ku)-{nu!Z|=dXC3H4(m8_d_f(xcD9b+8TD$dTB~oV zR>QDW!>ViQM$NR<%0@%8O{Y=S&B_PhK2MtEIrDe`q+Uc(7$;=vrcRxKM?u87h5vjP zw`9A?TXQp2I^6c+a_{+sjriXq9ax-{7ho86cq zLJnR94<7so9`qv=B7O+H*?^bo)tg{^XS1O_2|h48?>q0z`#Xe<_e1>pXjwJQS6 zGhachA)`ob!(k1>)U4+NmSwxTJv2HxtF<}@EOm>uU8Ae9Y$ln42ni*(*YC9YEVZ6n zPqG`k4=b#$51Aq>a*92%tsdKOY}Y)HXv0lnad9^1zVqkV3<%&h_DecP?N@5s%@>NA zE9Q#owv;U^1xd-ONoli~E=ZZpaR8z&~pw||gPNyI0TAfyxocDa-JkCvWQ%IaUTA8{r%K4acSAqli(~-xW zU4Bhx6T*YZdvuQ%+@DW>%)KQufzZFWSH~PR!bSQ*I6B=rVUs1qc{TAC*Au4hv<+*J zSMQc9#VS1^u35d7Vdfjv`n{ccb+0zbLhzf3{5F)Y`gxpj$f;6iYk$V`g7BzxIE{Y! zMYRq8T$o~U3kcIy7HbiTL%...d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x36, /* .......6 */ +0xa2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .O...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (88 bytes) */ +static const unsigned char pkt2[88] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4a, 0x02, 0xe1, 0x00, 0x00, 0xff, 0x11, /* .J...... */ +0xcd, 0xc4, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x36, /* .......6 */ +0xb4, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (106 bytes) */ +static const unsigned char pkt3[106] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x33, 0xc1, 0xbd, 0x08, 0x00, 0x45, 0x00, /* s3....E. */ +0x00, 0x5c, 0x1e, 0xf3, 0x00, 0x00, 0xff, 0x11, /* .\...... */ +0xfa, 0x92, 0xc0, 0xa8, 0x00, 0x67, 0xe0, 0x00, /* .....g.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x48, /* .......H */ +0x0a, 0xee, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x0c, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0xc0, 0x23 /* .# */ +}; + +/* Frame (114 bytes) */ +static const unsigned char pkt4[114] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xe8, 0x39, /* ..^....9 */ +0x35, 0x44, 0xfe, 0xd4, 0x08, 0x00, 0x45, 0x00, /* 5D....E. */ +0x00, 0x64, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .d..@... */ +0xd9, 0xe2, 0xc0, 0xa8, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x50, /* .......P */ +0x42, 0x75, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* Bu...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x14, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0xc0, 0x23 /* .# */ +}; + +/* Frame (160 bytes) */ +static const unsigned char pkt5[160] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x92, 0x17, 0x39, 0x00, 0x00, 0xff, 0x11, /* ...9.... */ +0x02, 0x7a, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* .z...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7e, /* .......~ */ +0xbc, 0x15, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x17, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0xc0, 0x23, 0xc0, 0x0c, 0x00, /* tcp.#... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0b, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, /* .._print */ +0x65, 0x72, 0xc0, 0x44, 0xc0, 0x0c, 0x00, 0x0c, /* er.D.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x08, /* ........ */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0xc0, 0x44 /* ._http.D */ +}; + +/* Frame (219 bytes) */ +static const unsigned char pkt6[219] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0xcd, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x23, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* .#...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xb9, /* ........ */ +0x69, 0x6d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* im...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x14, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0xc0, 0x23, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* .#...... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x65, 0xc0, 0x41, 0xc0, /* teste.A. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, /* ...._tes */ +0x74, 0x64, 0xc0, 0x41, 0xc0, 0x0c, 0x00, 0x0c, /* td.A.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x09, /* ........ */ +0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x63, 0xc0, /* ._testc. */ +0x41, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* A....... */ +0x00, 0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, /* ......_t */ +0x65, 0x73, 0x74, 0x62, 0xc0, 0x41, 0xc0, 0x0c, /* estb.A.. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, /* ..._test */ +0x61, 0xc0, 0x41 /* a.A */ +}; + +/* Frame (212 bytes) */ +static const unsigned char pkt7[212] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0xc6, 0x58, 0x8e, 0x00, 0x00, 0xff, 0x11, /* ..X..... */ +0xc0, 0x90, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .....d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xb2, /* ........ */ +0xa2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x93, 0x00, 0x0c, 0x04, 0x5f, 0x73, 0x6d, /* ....._sm */ +0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* b._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x0f, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0xc0, 0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* n.?..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x12, 0x0f, /* ........ */ +0x5f, 0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, /* _pdl-dat */ +0x61, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xc0, /* astream. */ +0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ?....... */ +0x00, 0x11, 0x94, 0x00, 0x0b, 0x08, 0x5f, 0x70, /* ......_p */ +0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0xc0, 0x3f, /* rinter.? */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x08, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0xc0, 0x3f /* tp.? */ +}; + +/* Frame (225 bytes) */ +static const unsigned char pkt8[225] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0xd3, 0x02, 0xe2, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0xcd, 0x3a, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* .:...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbf, /* ........ */ +0x1b, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .:...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x14, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* n._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, /* ....._te */ +0x73, 0x74, 0x65, 0xc0, 0x47, 0xc0, 0x0c, 0x00, /* ste.G... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x64, /* .._testd */ +0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* .G...... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x63, 0xc0, 0x47, 0xc0, /* testc.G. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, /* ...._tes */ +0x74, 0x62, 0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, /* tb.G.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x09, /* ........ */ +0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x61, 0xc0, /* ._testa. */ +0x47 /* G */ +}; + +/* Frame (212 bytes) */ +static const unsigned char pkt9[212] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0xc6, 0x58, 0xcf, 0x00, 0x00, 0xff, 0x11, /* ..X..... */ +0xc0, 0x4f, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .O...d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xb2, /* ........ */ +0xa2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x90, 0x00, 0x0c, 0x04, 0x5f, 0x73, 0x6d, /* ....._sm */ +0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* b._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x0f, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0xc0, 0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* n.?..... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x12, 0x0f, /* ........ */ +0x5f, 0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, /* _pdl-dat */ +0x61, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xc0, /* astream. */ +0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ?....... */ +0x00, 0x11, 0x91, 0x00, 0x0b, 0x08, 0x5f, 0x70, /* ......_p */ +0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0xc0, 0x3f, /* rinter.? */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x08, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0xc0, 0x3f /* tp.? */ +}; + +/* Frame (225 bytes) */ +static const unsigned char pkt10[225] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0xd3, 0x02, 0xe3, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0xcd, 0x39, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* .9...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbf, /* ........ */ +0x21, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* !F...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x14, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* n._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, /* ....._te */ +0x73, 0x74, 0x65, 0xc0, 0x47, 0xc0, 0x0c, 0x00, /* ste.G... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x64, /* .._testd */ +0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* .G...... */ +0x00, 0x00, 0x11, 0x91, 0x00, 0x09, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x63, 0xc0, 0x47, 0xc0, /* testc.G. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, /* ...._tes */ +0x74, 0x62, 0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, /* tb.G.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x09, /* ........ */ +0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x61, 0xc0, /* ._testa. */ +0x47 /* G */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt11[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x59, 0x32, 0x00, 0x00, 0xff, 0x11, /* .ZY2.... */ +0xbf, 0x58, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .X...d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0xa3, 0x5f, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ._...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x64, 0x03, 0x31, 0x30, 0x30, /* ...d.100 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (136 bytes) */ +static const unsigned char pkt12[136] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7a, 0x02, 0xe4, 0x00, 0x00, 0xff, 0x11, /* .z...... */ +0xcd, 0x91, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x66, /* .......f */ +0x82, 0x29, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .)...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0x0a, 0x00, 0x00, 0x02, 0x01, 0x32, 0x01, 0x30, /* .....2.0 */ +0x01, 0x30, 0x02, 0x31, 0x30, 0x07, 0x69, 0x6e, /* .0.10.in */ +0x2d, 0x61, 0x64, 0x64, 0x72, 0x04, 0x61, 0x72, /* -addr.ar */ +0x70, 0x61, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, /* pa...... */ +0x00, 0x00, 0x78, 0x00, 0x02, 0xc0, 0x0c, 0xc0, /* ..x..... */ +0x0c, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x05, 0xc0, 0x0c, 0x00, 0x01, 0x40 /* x......@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt13[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x45, 0x59, 0xc5, 0x00, 0x00, 0xff, 0x11, /* .EY..... */ +0xbf, 0xda, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .....d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xa2, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .J...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt14[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x02, 0xe5, 0x00, 0x00, 0xff, 0x11, /* .E...... */ +0xcd, 0xc5, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0x95, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .L...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + diff --git a/test/regression/mdns_test/capture/dns_sd_query.pcapng b/test/regression/mdns_test/capture/dns_sd_query.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..1b1d5f0445757c794caf3217d0eabd72dd9c8749 GIT binary patch literal 3432 zcmcInU2GIp6h5=Ng>6{`Oic}tGKQGY;Lx4@Ut(? z0x>>d;!hXrgMW!Bn)Jy8)CY}(A)&@-8XxS7_)<^1SQmSW_Gr-%XV9<-uC3) zIeX9jzH`1av$HK5H@3V800$o4y_Lavu{`Xs8v;HqlULcp`C+MWtjGr0-kdU;&*s=3 zF+0HW53!k%{Gh}J18yE1z(IUuNY08f%kK&8akIO6pFGGuksD=wUZ0m|`<22F+o>ue z!vh>{=s+wQgiW~bl;_1o02_FqFPo1OOI&NAkE`vtqZLS5STiIn~fuIY8Hxy#KrZ3G+gA0l0(2kHVqcC;vf}~ zAv_b80tvU{Y%T6DZJih1KWE_Dt`hF-zF`)JFrM$Z|@E8_xenFNF=!RK==EvaB*@Yr zCyA<9RF#}KRHmi5sAcpm8=Qiy(N&IZoSAw~ zQH$s~6W!m@%zpZ+{bp(ougNOCZQjdYq+TWMw27*F`TW$^xS6&$(X?`JSCV8MryNhzAoE?-f4$^zqj+?2gxF$1lwme6^wOyl}XZKb; zM=oyLOVPM}m3mteShec=EJ5W~khD6^Y&~bDo>SEJA!*9JR`<8q2h$C7|3=sS(0`=+ z#4@^;6D;jk=ehvF;_P-0e#eSDaSeD^9EK z6{l7AinChx)2KiG>%IT;<&){7ctKWszcWvzJye5>DXZ>G@~mKa)-leQs44}nCuV+I zGpFeAF>p|nop-w#x1A4!?0nd>K0nNflB769MHcaUy}Z+=xvK$$N21dIiPhfhj!O7!CX$}WTh~6y!JIu$1*V~h%mQ)REueOJ|}EH>9v`usty0f;}osa#%X0t z`s%_rO??pNjw9QiW?(zS3M2ILP-KzrXkN-mZ00yC89z8|;MDnP;V)D6@|xltxTYLv VG~wDh2*boOYx-}oOoVz^e**&3E3*Iq literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/duplicate_question_suppression.c b/test/regression/mdns_test/capture/duplicate_question_suppression.c new file mode 100644 index 00000000..9d020109 --- /dev/null +++ b/test/regression/mdns_test/capture/duplicate_question_suppression.c @@ -0,0 +1,182 @@ + +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (76 bytes) */ +static const unsigned char pkt2[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (76 bytes) */ +static const unsigned char pkt3[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc0, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (76 bytes) */ +static const unsigned char pkt4[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xbf, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (153 bytes) */ +static const unsigned char pkt5[153] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0xe6, 0x7f, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0x33, 0x3a, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* 3:...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt6[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x83, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x90, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + + +/* Frame (135 bytes) */ +static const unsigned char pkt7[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x83, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x90, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + + +/* Frame (135 bytes) */ +static const unsigned char pkt8[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x82, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + + +/* Frame (76 bytes) */ +static const unsigned char pkt9[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + + +/* Frame (135 bytes) */ +static const unsigned char pkt10[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0c, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x81, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1,...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x78, 0x00, 0x1f, /* .....x.. */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; \ No newline at end of file diff --git a/test/regression/mdns_test/capture/error_response.pcapng b/test/regression/mdns_test/capture/error_response.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..74c0e33008784aa294eb09b9bddf41794d3707cb GIT binary patch literal 4384 zcmeI0Ur19?7{I@~-IdKLMq*Ks$No#r)NO8tL32}xQkF_WNTS<}p>At#_CFRC5fS+i zff)2hp`hp`h^QV`MA2Jd59Lc%59L!@SPwz#`_688=bbmCQHUNmyZ3m``Mz_0-}%1# z9ramR`jY@qQ?X&GfX}#8w6Fon%*IwP`A(RWv&)?J1g19S|h#= z53`mPmw*UHa7H?V?v@}cDY6w6v-S16YFVAPo0&~!QweJe1v=TLa46z$H{yUo)J27K zlio|xGad)fKq)jiy`-wC)>Ykn*zB-X+A1B@Mr)PXZZumR#m4eVi``gOUR7+jIIC>}sGjhFiww`<!dR_XY0SU^$%pOV(WR_)+f?q>m@u6B;v_K>-Eubj0#j0@#F(!a9h7m(mNPB zCB+kp;#0-&nG$4i2gHNoot#T=#!WRY3pkf|vyaQ_*SFQU=sB0SvxCbMI{sKF7h3hn zK6VY?sY-riC=_0vqg)6s0C4|pLN3CvlnX&LUW0=v57P37BCj!kpvV|vdGxX7=|#){ zIUvMrQ1I&)#dsitgn=tofIZmH|0VzqMsd8M!49Cc)0vm&7Ka8LV=6HylkeeJl5H)E zAIWoz)M*b)q)fka3pu+U%g!0kF6T|18ao4LcQpO%@*W3fJiFcP`_$NFadt=2!!C+v zo(lQw#lc%+cx$1Xi_&LZlFwdA^4W^bw^F|1WN8$G2mPsv>4?k@(+9;$PVIicjbCr{E8ygIIs$LldkY zd=tl?Vwa#)9!ZDgn&rR-$h%3#d;~GNp_{7X*Q(U#419d zS_Kb1=tX)JDToJ;qK60`ytpEG5mZWU_2fl72w7(~tJu1Sia0R)=FNL=zWL_O+kU^l z{{{feoC+Ov;AmLlf)GR_;XzTFh6OI4%m~0vnl|pJnHj28+aFae-Z~sVi)vUehYeVcKyL(EtdWaBo|qVE{N` z5*AVlK`qQ?Gr4PVF(FJQrKzxxPRGL$As!7UgfpqIm`Wt1v=q-oBbn;}UX0X-aeRN7 zJ03Cd>1>%MD6cvkJPLaCb7+$~;1a-h;Db_X-UDfX({N}S4F3I#_BJGTa4oPK*oD!t zZ@9Tf2?uv>sa~&gxq7kcE~~{nM)!e(FbJ!KNaBY9wyH@Yn{ zusVFu=wcRzvp2WC7XH#pb512ivBz)W3gJITB_aHc&wl+r+N2iO;ms#k-sCGjq3Ux6V)hs@?FW(M49a zwObdof95k}Z|$|F}`<4U$leABQ?`954h) vRjXiIuCi)PZIon1W`#8-_kL..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (153 bytes) */ +static const unsigned char pkt2[153] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x87, 0x82, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0x92, 0x37, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* .7...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt3[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x85, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt4[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x84, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x92, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt5[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x83, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x90, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + diff --git a/test/regression/mdns_test/capture/known_answer_suppression.pcapng b/test/regression/mdns_test/capture/known_answer_suppression.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..d84451bd50d93245220414708d00a0e90f0cece7 GIT binary patch literal 2088 zcmcIl%WD&15TCqiT2kzmfFLD)?Wwj+yW6A*0g;*)E7%fRsFz~QW2K=}o2Tl*>!Z%Vwo~DV2~|B$ilY!U&5OQ|To0dUyfMFb2V5 zCYOlim@q2vqdXg&ottJeQi-{JULVhHXyhku zZk2>DOLU=7$eE*sM9z|y6EVzg0|Q|YRt24mupS`Rb&SbfE_`TMD_>~_hB&2Jp#at4 z29zeUP>ijy_SEnf-l=1f6ipw$f-8jo2Az!XKX;4b6O75VS{>^zZhcg1U0c12ox#<; zSgUz!x7PCZ^Va>T7iiMQ0^lCQXZRuUYZPLTU<|NO1-%KO-U8h5H1*V;7hJp#}A z;WY055IY`?zn?63J&iXbmHjmCQZ=r&X>30N&xeQ8_!aUzmOlP*vfN2y3p)Kv$mm;9 zbG#G{&<6pzn8nZQ63gY~QYtAWS$vr#TR&$bSk=AH>bz*uVmfEWIIDgyD6h4ZRC^M} EZ-Nr#GXMYp literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/known_answer_suppression_query_half_ttl.c b/test/regression/mdns_test/capture/known_answer_suppression_query_half_ttl.c new file mode 100644 index 00000000..064ff449 --- /dev/null +++ b/test/regression/mdns_test/capture/known_answer_suppression_query_half_ttl.c @@ -0,0 +1,172 @@ +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0x90, 0xb2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (255 bytes) */ +static const unsigned char pkt2[255] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xf1, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd9, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xdd, /* ........ */ +0x19, 0x0d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, /* .......< */ +0x00, 0x24, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .$.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, /* local..S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x3c, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .<...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x3c, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* <...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt3[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt4[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt5[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt6[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (76 bytes) */ +static const unsigned char pkt7[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0x90, 0xb2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (255 bytes) */ +static const unsigned char pkt8[255] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xf1, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd8, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xdd, /* ........ */ +0x19, 0x0d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, /* .......< */ +0x00, 0x24, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .$.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, /* local..S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x3c, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .<...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x3c, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* <...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + diff --git a/test/regression/mdns_test/capture/known_answer_suppression_query_half_ttl.pcapng b/test/regression/mdns_test/capture/known_answer_suppression_query_half_ttl.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..c77212efc0a21cea6921b17e07735c1554972bbb GIT binary patch literal 1756 zcmd^=&ubG=5XWcpL(((>0}+fAd`b`2x-oG#KMJWezj}}+hNhTHF(la)*CyG=W)l$+ zJa|+p{s*F7#265~=MNC^;6YKLpqCy!E5w=27OD}cAXsqV?auC-H=lX$yTf|@e(!An zD5U0(2zVda=7f2O%VJ$KSw(9r`n3*Au(E3Ow1&z`wZ;aEo?`W`)>K#`9*KerM96hp zyiwyU8cv2I>_quuk*%sdCQGsuWtR=T#ZH?>x4j`^z#Ov3h)vu__I)%0aKIT@o3 zFP4_8H{@(Glgwn7#YA3Ci*h0x5f?JCv>0E=N7AueJ}JfGHvy(F(*evg4Tk`_3TIq5 zOcs-3605Zprg5C}{o%fFiB%irZPEkU+4nARzFz9Dpie`9O8{TNHz&Ng>w!E50GxwS z;NEjDPHy2`a67mSCqJQ!M%zVmSFe~RcU8>>cQ^G$4YT_|AO^9R9Yw6o4@-SK7NB9X z0>`CX#bSK{53x4iA?xVY4(nscKR#QF=J+)W)1_cGP}W+!sj`Y%w**#=$>_brz_D9Y za|%Lu1t?9YR||z)vAm{sOnZZSN^{Uo6ZG&JSB=HA?Cq&WN7LJj_? z_DwCh&$G||rAEXiqkg)Y4GmV%r!n!p{N>*LHk=v!rgx{T-hKQ3^sXDve76?8$I3u} v8OZA0wux=dxS{tnMO9e+I#b3!6bE=L-5jr8K6TnYt#hHjWA0r(y(7kVBGQ$-koqF9nZY#6z4(Hn1h3;K1VgN%Z+XEkb;h^?en zqT)_vqb$~po=_E4iHRNC+!K+m?X-7g0xS_13v)B?2lwpvfhpX>X2D>p&9b(-{Y=fL za;aQ?RZbSwtgI&UQ8}H9XXQk?7|q5D#gr0HJO?gPrVEs37W06kTf#E!u81pf1ql7; z_fVQaO`NaA7m`0eefStW)E<(}Dq#!w`|EP#`=_q~6oCiQ0d+7OJ~%#_37*i~;_2ck zmOkGm@bEL~@NG9O%eUQaSpJsTs8R9|WnvEIddJNmVXhhNP;=CAhpBma<}iaN848}EN;60RX{ tI_<7ucZ6k|y{2yHqW)Cq!=G^qfkDmH^*7qIYjd2B?2-6AHv4!N{{hdd_znO7 literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/mdns_known_answer_suppression_unique.c b/test/regression/mdns_test/capture/mdns_known_answer_suppression_unique.c new file mode 100644 index 00000000..4439693a --- /dev/null +++ b/test/regression/mdns_test/capture/mdns_known_answer_suppression_unique.c @@ -0,0 +1,26 @@ +/* Frame (171 bytes) */ +static const unsigned char pkt1[171] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x9d, 0x1e, 0x02, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0xf4, 0x9f, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x89, /* ........ */ +0x2c, 0xb0, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ,....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x04, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x11, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x08, 0x43, 0x61, /* ....P.Ca */ +0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0xc0, 0x1c, /* tro-PC.. */ +0xc0, 0x0c, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x33, 0x00, /* ......3. */ +0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x04, 0xc0, 0xa8, 0x07, 0x0a, 0xc0, 0x33, 0x00, /* ......3. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x05, 0xc0, 0x33, 0x00, 0x01, 0x40, 0xc0, 0x0c, /* ..3..@.. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x09, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x00, /* ........ */ +0x80, 0x00, 0x40 /* ..@ */ +}; + diff --git a/test/regression/mdns_test/capture/mdns_known_answer_suppression_unique.pcapng b/test/regression/mdns_test/capture/mdns_known_answer_suppression_unique.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..12f971b9f73925d956be5688f12026ae5df3ba69 GIT binary patch literal 644 zcmb7Bzl#%55dJpV)m*#-g9m~fGIl3-n;-6Ol0%D2Hn~PTf(P0hhRyDZ%O%-m^AZ&i zuCTGzRJKbu_>U5iiReubuaHmt;=L||f6vl!q!!pPjdlW>RU;WRS z_)7XNmHj3k1?P~wIbF0J5r=xuE)PT38A{foF15d;5%BA~if31UCT}^GN5LK7&yVw! zkFVbs&;?#x%<;BMzhBCZ-?+AZvVMZ6+wT@T;UxfhRrnL3_3sH0seR!_TBdmESnlkB zoRh6rSiUIPNLF!H7E8}rGBKcJOjXKoT*+ch)^?e_Osp{0fMe{YGcZIpS~|=1ucc24 uHeiR-vGC&wMR7O_Jl~_iL-H0MpF<(#e)v2}@)?%*RK`ow{=qUQHU0u}WR~6l literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/multiple_questions_per_query.c b/test/regression/mdns_test/capture/multiple_questions_per_query.c new file mode 100644 index 00000000..076ea0e1 --- /dev/null +++ b/test/regression/mdns_test/capture/multiple_questions_per_query.c @@ -0,0 +1,68 @@ +/* Frame (103 bytes) */ +static const unsigned char pkt1[103] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x59, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .Y..@... */ +0x90, 0x97, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x45, /* .......E */ +0xe9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, 0x74, /* test1._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x06, 0x5f, 0x74, /* ......_t */ +0x65, 0x73, 0x74, 0x32, 0xc0, 0x13, 0x00, 0x0c, /* est2.... */ +0x00, 0x01, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, /* ..._test */ +0x33, 0xc0, 0x13, 0x00, 0x0c, 0x00, 0x01 /* 3...... */ +}; + +/* Frame (103 bytes) */ +static const unsigned char pkt2[103] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x59, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .Y..@... */ +0x90, 0x97, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x45, /* .......E */ +0xe9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, 0x74, /* test1._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x06, 0x5f, 0x74, /* ......_t */ +0x65, 0x73, 0x74, 0x32, 0xc0, 0x13, 0x00, 0x0c, /* est2.... */ +0x00, 0x01, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, /* ..._test */ +0x33, 0xc0, 0x13, 0x00, 0x0c, 0x00, 0x01 /* 3...... */ +}; + +/* Frame (103 bytes) */ +static const unsigned char pkt3[103] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x59, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .Y..@... */ +0x90, 0x97, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x45, /* .......E */ +0xe9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, 0x74, /* test1._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x06, 0x5f, 0x74, /* ......_t */ +0x65, 0x73, 0x74, 0x32, 0xc0, 0x13, 0x00, 0x0c, /* est2.... */ +0x00, 0x01, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, /* ..._test */ +0x33, 0xc0, 0x13, 0x00, 0x0c, 0x00, 0x01 /* 3...... */ +}; + +/* Frame (103 bytes) */ +static const unsigned char pkt4[103] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x59, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .Y..@... */ +0x90, 0x97, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x45, /* .......E */ +0xe9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, 0x74, /* test1._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x06, 0x5f, 0x74, /* ......_t */ +0x65, 0x73, 0x74, 0x32, 0xc0, 0x13, 0x00, 0x0c, /* est2.... */ +0x00, 0x01, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, /* ..._test */ +0x33, 0xc0, 0x13, 0x00, 0x0c, 0x00, 0x01 /* 3...... */ +}; + diff --git a/test/regression/mdns_test/capture/multiple_questions_per_query.pcapng b/test/regression/mdns_test/capture/multiple_questions_per_query.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..e19858a4c8fe598ac26bc09eb81d71516435cca2 GIT binary patch literal 948 zcmd<$<>hK&U|{gI(UxKa(*L1=nL(Su%tSXSvqT|0GcP5-yja0pAvm?DEHgP(As{h1 zTftCAA*nPoCq=>B%)pR=g+Z6Wr8Ku7Ik7;&P|rfoKtUro%ugXGwM@ap*u>aSA+0Ds zS3$p|s5CEI7pOoJXcq{8>;~Dp1WNz^&%nUMV8jsPk_xga#xKAvzS_ju!pXwP*-h8n z)x=TP#N63H*V4(X+{Pa z2Iu_Jypq(SVugaD{IblH)D(rJN`(|iMqy&$0H>v2&yJpAhO$BWSb%I8U`1ks#6Wfc E0A$M5X#fBK literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/one_shot_query.c b/test/regression/mdns_test/capture/one_shot_query.c new file mode 100644 index 00000000..81ca06ab --- /dev/null +++ b/test/regression/mdns_test/capture/one_shot_query.c @@ -0,0 +1,86 @@ +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0x90, 0xb2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (255 bytes) */ +static const unsigned char pkt2[255] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xf1, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd9, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xdd, /* ........ */ +0xf0, 0xbc, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x24, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .$.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, /* local..S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt3[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* -....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, /* .....d.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt4[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2d, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* -....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, /* .....d.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + diff --git a/test/regression/mdns_test/capture/one_shot_query.pcapng b/test/regression/mdns_test/capture/one_shot_query.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..e2b6395cfaf97e68d0576f846ee6ba27af79142a GIT binary patch literal 1080 zcmc(eO=uHQ5P)aXL}HqPfq1A0j^e>uw@uvLB!x!IUj;ECHmyM@4ax2kmnPX|vx$fZ zA|5;_irzhlpl8n>dN)Te3PQkBZ+i9+XEs|<(?dNu@b=B_%$sk1-bUu;B98!|yt;To zqJ8Yk3@k!Qm0PBZb+c<&cY2t{ns5fDF0k6vcQAPYTYa-_U^OZAtA5iwVa$N+ wB{&HMtKW60g=jn0z%+z`t-EMUe%1hlJ>Q$Fk3Y`%I-d)YzAvHQbpFPSU)t*d_W%F@ literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/probing_conflict.c b/test/regression/mdns_test/capture/probing_conflict.c new file mode 100644 index 00000000..95e3f484 --- /dev/null +++ b/test/regression/mdns_test/capture/probing_conflict.c @@ -0,0 +1,280 @@ +/* Frame (225 bytes) */ +static const unsigned char pkt1[225] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xd3, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd5, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbf, /* ........ */ +0x13, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .w...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, /* Server._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x0f, 0x53, 0x69, 0x6d, /* .....Sim */ +0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, 0x53, 0x65, /* pleWebSe */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0f, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x57, 0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, /* WebServe */ +0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* r._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x14, 0x08, 0x70, 0x61, /* ..d...pa */ +0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, /* per=A4.v */ +0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, /* ersion=0 */ +0x31 /* 1 */ +}; + +/* Frame (235 bytes) */ +static const unsigned char pkt2[235] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbc, 0x39, 0x02, 0x08, 0x00, 0x45, 0x00, /* /.9...E. */ +0x00, 0xdd, 0x05, 0x71, 0x00, 0x00, 0xff, 0x11, /* ...q.... */ +0xca, 0xa2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc9, /* ........ */ +0x3d, 0x40, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* =@...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x0f, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, /* Server._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x09, 0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, /* .Chenbo- */ +0x50, 0x43, 0xc0, 0x27, 0xc0, 0x0c, 0x00, 0x10, /* PC.'.... */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x16, /* ........ */ +0x09, 0x5b, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* .[paper= */ +0x41, 0x34, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, /* A4.Versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x5d, 0xc0, 0x3e, /* on=01].> */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0x0a, 0x00, 0x00, 0x01, 0xc0, 0x3e, /* .......> */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x93, 0x9d, 0xaa, 0xda, 0xe3, /* ........ */ +0xea, 0xba, 0xc0, 0x3e, 0x00, 0x2f, 0x80, 0x01, /* ...>./.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0xc0, 0x3e, /* ...x...> */ +0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0xc0, 0x0c, /* ..@..... */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x09, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x00, /* ........ */ +0x80, 0x00, 0x40 /* ..@ */ +}; + +/* Frame (237 bytes) */ +static const unsigned char pkt3[237] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xdf, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xc8, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xcb, /* ........ */ +0x15, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .f...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, /* .SimpleW */ +0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* ebServer */ +0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, /* (2)._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x57, 0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, /* WebServe */ +0x72, 0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, /* r (2)._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (237 bytes) */ +static const unsigned char pkt4[237] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xdf, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xc7, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xcb, /* ........ */ +0x15, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .f...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, /* .SimpleW */ +0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* ebServer */ +0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, /* (2)._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x57, 0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, /* WebServe */ +0x72, 0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, /* r (2)._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (237 bytes) */ +static const unsigned char pkt5[237] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xdf, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xc6, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xcb, /* ........ */ +0x15, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .f...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, /* .SimpleW */ +0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* ebServer */ +0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, /* (2)._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x57, 0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, /* WebServe */ +0x72, 0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, /* r (2)._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (261 bytes) */ +static const unsigned char pkt6[261] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xf7, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xad, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xe3, /* ........ */ +0xf7, 0x54, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .T...... */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x13, /* .local.. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x26, 0x13, /* ....d.&. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + +/* Frame (261 bytes) */ +static const unsigned char pkt7[261] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xf7, 0x00, 0x0c, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xac, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xe3, /* ........ */ +0xf7, 0x54, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .T...... */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x13, /* .local.. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x26, 0x13, /* ....d.&. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + +/* Frame (261 bytes) */ +static const unsigned char pkt8[261] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xf7, 0x00, 0x0d, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xab, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xe3, /* ........ */ +0xf7, 0x54, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .T...... */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x13, /* .local.. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x26, 0x13, /* ....d.&. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + diff --git a/test/regression/mdns_test/capture/probing_conflict.pcapng b/test/regression/mdns_test/capture/probing_conflict.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..38fb0f1b43d505fc25f9fa0dc711a0c371e286a9 GIT binary patch literal 2600 zcmeH{O-vI(6vzLCt+u6&REh>;%;-TOxU{8}LL#P1TW%!{C2$bMek`G(v}-9Ji6PzubIELu0Pcs?m%#rx=c<*+482O-_w77YoX%$yh{Yfly?W*)Ov2L@XX(j46?j!t5<}TZ@e~2K#$huRO_|9j*==8%`z1m^Gc6NQ{cyqKTpbJT{Mer!eMn zKowds=#_b>!Ja_(&@G!J`6QR*728@pcF}2fxWukY4xi}qczn+GZcn@9=$Zla#&sj2{mc94j(Z}^K&r5B7cb1>w zzPUbuUzl3`ih#|z`OF&4dDq}N@B`*^4sX8>KHvk6x{)*AT_!bMtF&j?ux#K}-4q$; zu~h-bg0V3rE)U3I{ycI@J2a9`E5cAZqGAZ_dt!*>-T$mf_?IM zy5Oh+C$$A97M&7Ox+&mmBAd><$DSGRT7^zZ1t zmc0Uvda-E;TnDXB7uL0<89{s2!k&)if*a6Lgzay7nrnesxM3s)oJDOBiyJcwnQ!!s z_dWTr0-c%EC^_4v z(l$wYDZi8=7whX)vZnQkD2PIu+_H>qa@n?=?iNosB&jbH^o@RB`15E45P&PNQPR-W zMzyxudLT;qV!kM?^0~5D;KiJj;+Kn=0-s$jrwW-;IWJ_g4*^cllV<2Svv3-~QB7hR zmQ6B3Mj-93N_3OzVt*MIHDPRcE;6EA{}O`8z#SsH$G-{i1LEg|QZoW&fIe_5Fp59P zM*)flRF^nR9D@A*Ia;%DX~?sMwMwN_tv9ru9d6yWZ8Oxe6*Js1ly-*}0=OwVxE)N~ zJqV!}WJAV%I#7`D&8|CqN!K_yV2rUO_vtZXd__qvUng@ETnP5+U+xt4?U;!k9 uUK!2m5z{jIx~i!}zE4!|Aq_x;_5Y(g$}s4!(T=`8{z(Agu{HigA3p*0LQ|3e literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/query_and_response_chaos.c b/test/regression/mdns_test/capture/query_and_response_chaos.c new file mode 100644 index 00000000..6fe446b2 --- /dev/null +++ b/test/regression/mdns_test/capture/query_and_response_chaos.c @@ -0,0 +1,2034 @@ +/* Frame (83 bytes) */ +static const unsigned char pkt1[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x45, 0x44, 0x8b, 0x00, 0x00, 0xff, 0x11, /* .ED..... */ +0xd5, 0x0e, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xde, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .;...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt2[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x0a, 0x11, 0x00, 0x00, 0xff, 0x11, /* .E...... */ +0x08, 0xe9, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xd7, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (158 bytes) */ +static const unsigned char pkt3[158] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x90, 0x44, 0x8c, 0x00, 0x00, 0xff, 0x11, /* ..D..... */ +0xd4, 0xc2, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7c, /* .......| */ +0xa7, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* ........ */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x80, 0x01, 0xc0, 0x0c, 0x00, 0xff, 0x80, 0x01, /* ........ */ +0xc0, 0x0c, 0x00, 0xff, 0x80, 0x01, 0xc0, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0xc0, 0xa8, 0x00, 0x6a, 0xc0, 0x0c, /* .....j.. */ +0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, /* ..@..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0xc0, 0x0c, 0x00, 0x1c, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba /* I?Y.~. */ +}; + +/* Frame (90 bytes) */ +static const unsigned char pkt4[90] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4c, 0x0a, 0x12, 0x00, 0x00, 0xff, 0x11, /* .L...... */ +0x08, 0xe1, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x38, /* .......8 */ +0x9b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .p...... */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x80, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x07, 0x0a /* .. */ +}; + +/* Frame (158 bytes) */ +static const unsigned char pkt5[158] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x90, 0x44, 0x8d, 0x00, 0x00, 0xff, 0x11, /* ..D..... */ +0xd4, 0xc1, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7c, /* .......| */ +0x27, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* '0...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0xc0, 0x0c, 0x00, 0xff, 0x00, 0x01, /* ........ */ +0xc0, 0x0c, 0x00, 0xff, 0x00, 0x01, 0xc0, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0xc0, 0xa8, 0x00, 0x6a, 0xc0, 0x0c, /* .....j.. */ +0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, /* ..@..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0xc0, 0x0c, 0x00, 0x1c, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba /* I?Y.~. */ +}; + +/* Frame (90 bytes) */ +static const unsigned char pkt6[90] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4c, 0x0a, 0x13, 0x00, 0x00, 0xff, 0x11, /* .L...... */ +0x08, 0xe0, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x38, /* .......8 */ +0x1b, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .q...... */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x07, 0x0a /* .. */ +}; + +/* Frame (158 bytes) */ +static const unsigned char pkt7[158] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x90, 0x44, 0x91, 0x00, 0x00, 0xff, 0x11, /* ..D..... */ +0xd4, 0xbd, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7c, /* .......| */ +0x27, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* '0...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0xc0, 0x0c, 0x00, 0xff, 0x00, 0x01, /* ........ */ +0xc0, 0x0c, 0x00, 0xff, 0x00, 0x01, 0xc0, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0xc0, 0xa8, 0x00, 0x6a, 0xc0, 0x0c, /* .....j.. */ +0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, /* ..@..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0xc0, 0x0c, 0x00, 0x1c, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba /* I?Y.~. */ +}; + +/* Frame (90 bytes) */ +static const unsigned char pkt8[90] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4c, 0x0a, 0x14, 0x00, 0x00, 0xff, 0x11, /* .L...... */ +0x08, 0xdf, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x38, /* .......8 */ +0x1b, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .q...... */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x07, 0x0a /* .. */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt9[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x44, 0x93, 0x00, 0x00, 0xff, 0x11, /* .ZD..... */ +0xd3, 0xf1, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0x63, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* c....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x6a, 0x03, 0x31, 0x30, 0x36, /* ...j.106 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt10[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x0a, 0x15, 0x00, 0x00, 0xff, 0x11, /* .~...... */ +0x08, 0xac, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt11[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x45, 0x44, 0x95, 0x00, 0x00, 0xff, 0x11, /* .ED..... */ +0xd5, 0x04, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xde, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .;...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt12[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x0a, 0x16, 0x00, 0x00, 0xff, 0x11, /* .E...... */ +0x08, 0xe4, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xd7, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt13[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x44, 0xab, 0x00, 0x00, 0xff, 0x11, /* .ZD..... */ +0xd3, 0xd9, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0x63, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* c....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x6a, 0x03, 0x31, 0x30, 0x36, /* ...j.106 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt14[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x0a, 0x17, 0x00, 0x00, 0xff, 0x11, /* .~...... */ +0x08, 0xaa, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt15[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x45, 0x28, 0x00, 0x00, 0xff, 0x11, /* .ZE(.... */ +0xd3, 0x5c, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .\...j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0x63, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* c....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x6a, 0x03, 0x31, 0x30, 0x36, /* ...j.106 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt16[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x0a, 0x18, 0x00, 0x00, 0xff, 0x11, /* .~...... */ +0x08, 0xa9, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt17[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x45, 0x45, 0x29, 0x00, 0x00, 0xff, 0x11, /* .EE).... */ +0xd4, 0x70, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .p...j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xde, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .;...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt18[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x0a, 0x19, 0x00, 0x00, 0xff, 0x11, /* .E...... */ +0x08, 0xe1, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xd7, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt19[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x45, 0x51, 0x00, 0x00, 0xff, 0x11, /* .ZEQ.... */ +0xd3, 0x33, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .3...j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0x63, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* c....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x6a, 0x03, 0x31, 0x30, 0x36, /* ...j.106 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt20[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x0a, 0x1a, 0x00, 0x00, 0xff, 0x11, /* .~...... */ +0x08, 0xa7, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt21[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x45, 0x45, 0x75, 0x00, 0x00, 0xff, 0x11, /* .EEu.... */ +0xd4, 0x24, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .$...j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xde, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .;...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt22[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x0a, 0x1b, 0x00, 0x00, 0xff, 0x11, /* .E...... */ +0x08, 0xdf, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xd7, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (88 bytes) */ +static const unsigned char pkt23[88] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x4a, 0x45, 0x7a, 0x00, 0x00, 0xff, 0x11, /* .JEz.... */ +0xd4, 0x1a, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x36, /* .......6 */ +0xfd, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (88 bytes) */ +static const unsigned char pkt24[88] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4a, 0x0a, 0x1c, 0x00, 0x00, 0xff, 0x11, /* .J...... */ +0x08, 0xd9, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x36, /* .......6 */ +0xf6, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (106 bytes) */ +static const unsigned char pkt25[106] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x33, 0xc1, 0xbd, 0x08, 0x00, 0x45, 0x00, /* s3....E. */ +0x00, 0x5c, 0x78, 0x77, 0x00, 0x00, 0xff, 0x11, /* .\xw.... */ +0xa1, 0x09, 0xc0, 0xa8, 0x00, 0x6c, 0xe0, 0x00, /* .....l.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x48, /* .......H */ +0x0a, 0xe9, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x0c, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0xc0, 0x23 /* .# */ +}; + +/* Frame (114 bytes) */ +static const unsigned char pkt26[114] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xe8, 0x39, /* ..^....9 */ +0x35, 0x44, 0xfe, 0xd4, 0x08, 0x00, 0x45, 0x00, /* 5D....E. */ +0x00, 0x64, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .d..@... */ +0xd9, 0xe2, 0xc0, 0xa8, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x50, /* .......P */ +0x42, 0x75, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* Bu...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x14, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0xc0, 0x23 /* .# */ +}; + +/* Frame (113 bytes) */ +static const unsigned char pkt27[113] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x9b, 0xc6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0x63, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .c..@... */ +0xd9, 0xd1, 0xc0, 0xa8, 0x00, 0x14, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4f, /* .......O */ +0x64, 0xfc, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* d....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x13, 0x0b, 0x5f, /* ......._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, /* sh._tcp. */ +0x23 /* # */ +}; + +/* Frame (126 bytes) */ +static const unsigned char pkt28[126] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x92, 0xa6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0x70, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .p..@... */ +0xd9, 0xc3, 0xc0, 0xa8, 0x00, 0x15, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x5c, /* .......\ */ +0x3e, 0x43, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* >C...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x0d, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0xc0, 0x23, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* p.#..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x07, 0x04, /* ........ */ +0x5f, 0x72, 0x66, 0x62, 0xc0, 0x3a /* _rfb.: */ +}; + +/* Frame (94 bytes) */ +static const unsigned char pkt29[94] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x50, 0x45, 0x7e, 0x00, 0x00, 0xff, 0x11, /* .PE~.... */ +0xd4, 0x10, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3c, /* .......< */ +0x60, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* `....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x0c, 0x5f, 0x77, 0x6f, 0x72, /* ...._wor */ +0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, /* kstation */ +0xc0, 0x11, 0x00, 0x0c, 0x00, 0x01 /* ...... */ +}; + +/* Frame (94 bytes) */ +static const unsigned char pkt30[94] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x50, 0x0a, 0x1d, 0x00, 0x00, 0xff, 0x11, /* .P...... */ +0x08, 0xd2, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3c, /* .......< */ +0x5a, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ZA...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x0c, 0x5f, 0x77, 0x6f, 0x72, /* ...._wor */ +0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, /* kstation */ +0xc0, 0x11, 0x00, 0x0c, 0x00, 0x01 /* ...... */ +}; + +/* Frame (332 bytes) */ +static const unsigned char pkt31[332] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x33, 0xc1, 0xbd, 0x08, 0x00, 0x45, 0x00, /* s3....E. */ +0x01, 0x3e, 0x78, 0x7d, 0x00, 0x00, 0xff, 0x11, /* .>x}.... */ +0xa0, 0x21, 0xc0, 0xa8, 0x00, 0x6c, 0xe0, 0x00, /* .!...l.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x2a, /* .......* */ +0x4f, 0xd5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* O....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0c, 0x09, 0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, /* ..Chenbo */ +0x2d, 0x50, 0x43, 0xc0, 0x0c, 0x09, 0x43, 0x68, /* -PC...Ch */ +0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, 0x43, 0x0c, /* enbo-PC. */ +0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, /* _device- */ +0x69, 0x6e, 0x66, 0x6f, 0xc0, 0x11, 0x00, 0x10, /* info.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0e, /* ........ */ +0x0d, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x3d, 0x57, /* .model=W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0xc0, 0x27, /* indows.' */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbd, /* ........ */ +0x09, 0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, /* .Chenbo- */ +0x50, 0x43, 0xc0, 0x16, 0xc0, 0x27, 0x00, 0x10, /* PC...'.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x23, /* .......# */ +0x11, 0x6e, 0x65, 0x74, 0x62, 0x69, 0x6f, 0x73, /* .netbios */ +0x3d, 0x43, 0x48, 0x45, 0x4e, 0x42, 0x4f, 0x2d, /* =CHENBO- */ +0x50, 0x43, 0x10, 0x64, 0x6f, 0x6d, 0x61, 0x69, /* PC.domai */ +0x6e, 0x3d, 0x57, 0x4f, 0x52, 0x4b, 0x47, 0x52, /* n=WORKGR */ +0x4f, 0x55, 0x50, 0xc0, 0x76, 0x00, 0x01, 0x80, /* OUP.v... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, /* ....x... */ +0xa8, 0x00, 0x6c, 0xc0, 0x76, 0x00, 0x1c, 0x80, /* ..l.v... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0x20, /* ....x.. */ +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xc0, /* ......1. */ +0x76, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, /* v....... */ +0x78, 0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, /* x....... */ +0x00, 0x00, 0x00, 0x01, 0x59, 0x44, 0x79, 0xe1, /* ....YDy. */ +0x0a, 0xd7, 0xf4, 0xc0, 0x27, 0x00, 0x2f, 0x80, /* ....'./. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x09, 0xc0, /* ....x... */ +0x27, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* '......@ */ +0xc0, 0x76, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* .v./.... */ +0x00, 0x78, 0x00, 0x08, 0xc0, 0x76, 0x00, 0x04, /* .x...v.. */ +0x40, 0x00, 0x00, 0x08 /* @... */ +}; + +/* Frame (242 bytes) */ +static const unsigned char pkt32[242] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xe8, 0x39, /* ..^....9 */ +0x35, 0x44, 0xfe, 0xd4, 0x08, 0x00, 0x45, 0x00, /* 5D....E. */ +0x00, 0xe4, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x62, 0xc0, 0xa8, 0x00, 0x02, 0xe0, 0x00, /* .b...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xd0, /* ........ */ +0xa0, 0xd5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x31, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, /* 1.server */ +0x2d, 0x48, 0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, /* -HP-Z210 */ +0x2d, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, /* -Worksta */ +0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, /* tion [e8 */ +0x3a, 0x33, 0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, /* :39:35:4 */ +0x34, 0x3a, 0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, /* 4:fe:d4] */ +0xc0, 0x0c, 0xc0, 0x2f, 0x00, 0x10, 0x80, 0x01, /* .../.... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, /* ........ */ +0x2f, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* /.!..... */ +0x78, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, /* x.#..... */ +0x09, 0x1a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, /* ..server */ +0x2d, 0x48, 0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, /* -HP-Z210 */ +0x2d, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, /* -Worksta */ +0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x1e, 0xc0, 0x7f, /* tion.... */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xea, 0x39, 0x35, 0xff, 0xfe, 0x44, /* ...95..D */ +0xfe, 0xd4, 0xc0, 0x7f, 0x00, 0x01, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x02 /* .. */ +}; + +/* Frame (228 bytes) */ +static const unsigned char pkt33[228] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x9b, 0xc6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0xd6, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x5e, 0xc0, 0xa8, 0x00, 0x14, 0xe0, 0x00, /* .^...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc2, /* ........ */ +0x8a, 0x5a, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .Z...... */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x2a, 0x27, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* *'catro- */ +0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, /* OptiPlex */ +0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, 0x5b, 0x61, /* -3010 [a */ +0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, /* 4:1f:72: */ +0x35, 0x33, 0x3a, 0x39, 0x62, 0x3a, 0x63, 0x36, /* 53:9b:c6 */ +0x5d, 0xc0, 0x0c, 0xc0, 0x2f, 0x00, 0x10, 0x80, /* ].../... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, /* ........ */ +0xc0, 0x2f, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* ./.!.... */ +0x00, 0x78, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x09, 0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, /* -OptiPle */ +0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, 0x1e, /* x-3010.. */ +0xc0, 0x78, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, /* .x...... */ +0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, /* .x...... */ +0x00, 0x00, 0x00, 0x00, 0xa6, 0x1f, 0x72, 0xff, /* ......r. */ +0xfe, 0x53, 0x9b, 0xc6, 0xc0, 0x78, 0x00, 0x01, /* .S...x.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x14 /* .... */ +}; + +/* Frame (206 bytes) */ +static const unsigned char pkt34[206] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0xa0, 0xf7, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0xc0, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x75, 0xc0, 0xa8, 0x00, 0x13, 0xe0, 0x00, /* .u...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xac, /* ........ */ +0x17, 0x94, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, /* EL [a4:1 */ +0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, /* f:72:53: */ +0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, 0xc0, 0x0c, /* a0:f7].. */ +0xc0, 0x2f, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* ./...... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x2f, 0x00, /* ....../. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x08, /* ........ */ +0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, 0x45, 0x4c, /* catro-EL */ +0xc0, 0x1e, 0xc0, 0x6d, 0x00, 0x1c, 0x80, 0x01, /* ...m.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0x20, 0x01, /* ...x.. . */ +0x0d, 0xa8, 0x80, 0x08, 0x01, 0x27, 0x02, 0x0c, /* .....'.. */ +0x29, 0xff, 0xfe, 0xe5, 0x16, 0x93, 0xc0, 0x6d, /* )......m */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0xc0, 0xa8, 0x00, 0x13 /* ...... */ +}; + +/* Frame (160 bytes) */ +static const unsigned char pkt35[160] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x92, 0x67, 0xcc, 0x00, 0x00, 0xff, 0x11, /* ..g..... */ +0xb1, 0xe6, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7e, /* .......~ */ +0xbc, 0x15, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x17, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0xc0, 0x23, 0xc0, 0x0c, 0x00, /* tcp.#... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0b, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, /* .._print */ +0x65, 0x72, 0xc0, 0x44, 0xc0, 0x0c, 0x00, 0x0c, /* er.D.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x08, /* ........ */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0xc0, 0x44 /* ._http.D */ +}; + +/* Frame (222 bytes) */ +static const unsigned char pkt36[222] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x92, 0xa6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0xd0, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x63, 0xc0, 0xa8, 0x00, 0x15, 0xe0, 0x00, /* .c...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbc, /* ........ */ +0x27, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* '....... */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x27, 0x24, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* '$dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, /* 10 [a4:1 */ +0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, /* f:72:53: */ +0x39, 0x32, 0x3a, 0x61, 0x36, 0x5d, 0xc0, 0x0c, /* 92:a6].. */ +0xc0, 0x2f, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* ./...... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x2f, 0x00, /* ....../. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, /* ........ */ +0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, /* dc-OptiP */ +0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, /* lex-3010 */ +0xc0, 0x1e, 0xc0, 0x75, 0x00, 0x1c, 0x80, 0x01, /* ...u.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x1f, /* ........ */ +0x72, 0xff, 0xfe, 0x53, 0x92, 0xa6, 0xc0, 0x75, /* r..S...u */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0xc0, 0xa8, 0x00, 0x15 /* ...... */ +}; + +/* Frame (202 bytes) */ +static const unsigned char pkt37[202] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x6a, 0x2e, 0x7a, 0x08, 0x00, 0x45, 0x00, /* )j.z..E. */ +0x00, 0xbc, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x11, 0xc0, 0xa8, 0x00, 0x7b, 0xe0, 0x00, /* .....{.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xa8, /* ........ */ +0x1d, 0xc5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x1d, 0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, /* ..ubuntu */ +0x20, 0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, /* [00:0c: */ +0x32, 0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, /* 29:6a:2e */ +0x3a, 0x37, 0x61, 0x5d, 0xc0, 0x0c, 0xc0, 0x2f, /* :7a].../ */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x01, 0x00, 0xc0, 0x2f, 0x00, 0x21, 0x80, /* ..../.!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x0f, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x09, 0x06, 0x75, 0x62, /* ......ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x1e, 0xc0, 0x6b, /* untu...k */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x6a, /* ....)..j */ +0x2e, 0x7a, 0xc0, 0x6b, 0x00, 0x01, 0x80, 0x01, /* .z.k.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x7b /* .{ */ +}; + +/* Frame (94 bytes) */ +static const unsigned char pkt38[94] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x50, 0x45, 0x81, 0x00, 0x00, 0xff, 0x11, /* .PE..... */ +0xd4, 0x0d, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3c, /* .......< */ +0x75, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* u....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x5f, /* ......._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* sh._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0xc0, 0x18, 0x00, 0x0c, 0x00, 0x01 /* ...... */ +}; + +/* Frame (94 bytes) */ +static const unsigned char pkt39[94] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x50, 0x0a, 0x1e, 0x00, 0x00, 0xff, 0x11, /* .P...... */ +0x08, 0xd1, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3c, /* .......< */ +0x6f, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* o^...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x5f, /* ......._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* sh._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0xc0, 0x18, 0x00, 0x0c, 0x00, 0x01 /* ...... */ +}; + +/* Frame (163 bytes) */ +static const unsigned char pkt40[163] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x9b, 0xc6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0x95, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x9f, 0xc0, 0xa8, 0x00, 0x14, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x81, /* ........ */ +0xd2, 0x1f, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x5f, /* ......._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* sh._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x16, /* ........ */ +0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, 0x4f, /* .catro-O */ +0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, /* ptiPlex- */ +0x33, 0x30, 0x31, 0x30, 0xc0, 0x0c, 0xc0, 0x2e, /* 3010.... */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x01, 0x00, 0xc0, 0x2e, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1c, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x16, 0x13, 0x63, 0x61, /* ......ca */ +0x74, 0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* tro-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x1d /* 0.. */ +}; + +/* Frame (141 bytes) */ +static const unsigned char pkt41[141] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0xa0, 0xf7, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0x7f, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0xb6, 0xc0, 0xa8, 0x00, 0x13, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6b, /* .......k */ +0x96, 0xe5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x5f, /* ......._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* sh._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0b, /* ........ */ +0x08, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, 0x45, /* .catro-E */ +0x4c, 0xc0, 0x0c, 0xc0, 0x2e, 0x00, 0x10, 0x80, /* L....... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, /* ........ */ +0xc0, 0x2e, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* ...!.... */ +0x00, 0x78, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x16, 0x08, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x45, 0x4c, 0xc0, 0x1d /* -EL.. */ +}; + +/* Frame (250 bytes) */ +static const unsigned char pkt42[250] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x92, 0xa6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0xec, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x47, 0xc0, 0xa8, 0x00, 0x15, 0xe0, 0x00, /* .G...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xd8, /* ........ */ +0x88, 0xc6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x0c, 0xc0, 0x28, 0x00, 0x10, /* 10...(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, /* ..(.!... */ +0x00, 0x00, 0x78, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x16, 0xa8, 0x10, 0x64, 0x63, 0x2d, 0x4f, /* ....dc-O */ +0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, /* ptiPlex- */ +0x33, 0x30, 0x31, 0x30, 0xc0, 0x17, 0x0b, 0x5f, /* 3010..._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0xc0, 0x12, 0x00, 0x0c, 0x00, 0x01, /* sh...... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x13, 0x10, 0x64, /* .......d */ +0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, /* c-OptiPl */ +0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, /* ex-3010. */ +0x84, 0xc0, 0x9c, 0x00, 0x10, 0x80, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x9c, /* ........ */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, /* ........ */ +0xc0, 0x71 /* .q */ +}; + +/* Frame (97 bytes) */ +static const unsigned char pkt43[97] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x53, 0x45, 0x84, 0x00, 0x00, 0xff, 0x11, /* .SE..... */ +0xd4, 0x07, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3f, /* .......? */ +0x9a, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x72, 0x66, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* rfb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, 0x6c, /* ...._pdl */ +0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x72, /* -datastr */ +0x65, 0x61, 0x6d, 0xc0, 0x11, 0x00, 0x0c, 0x00, /* eam..... */ +0x01 /* . */ +}; + +/* Frame (97 bytes) */ +static const unsigned char pkt44[97] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x53, 0x0a, 0x1f, 0x00, 0x00, 0xff, 0x11, /* .S...... */ +0x08, 0xcd, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3f, /* .......? */ +0x94, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .7...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x72, 0x66, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* rfb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, 0x6c, /* ...._pdl */ +0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x72, /* -datastr */ +0x65, 0x61, 0x6d, 0xc0, 0x11, 0x00, 0x0c, 0x00, /* eam..... */ +0x01 /* . */ +}; + +/* Frame (173 bytes) */ +static const unsigned char pkt45[173] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x92, 0xa6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0x9f, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x94, 0xc0, 0xa8, 0x00, 0x15, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x8b, /* ........ */ +0x10, 0xea, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x72, 0x66, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* rfb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, 0x72, /* *'dc's r */ +0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, /* emote de */ +0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, /* sktop on */ +0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x0c, 0xc0, 0x27, 0x00, 0x10, 0x80, /* 0...'... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, /* ........ */ +0xc0, 0x27, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .'.!.... */ +0x00, 0x78, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x17, 0x0c, 0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, /* ...dc-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x16 /* 010.. */ +}; + +/* Frame (79 bytes) */ +static const unsigned char pkt46[79] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x41, 0x45, 0x8a, 0x00, 0x00, 0xff, 0x11, /* .AE..... */ +0xd4, 0x13, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2d, /* .......- */ +0xc4, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* al..... */ +}; + +/* Frame (79 bytes) */ +static const unsigned char pkt47[79] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x41, 0x0a, 0x20, 0x00, 0x00, 0xff, 0x11, /* .A. .... */ +0x08, 0xde, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2d, /* .......- */ +0xbe, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .H...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* al..... */ +}; + +/* Frame (562 bytes) */ +static const unsigned char pkt48[562] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x02, 0x24, 0x67, 0xcd, 0x00, 0x00, 0xff, 0x11, /* .$g..... */ +0xb0, 0x53, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* .S...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x02, 0x10, /* ........ */ +0x25, 0xc3, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* %....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, /* .....Can */ +0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* onMF4500 */ +0x77, 0xc0, 0x0c, 0x05, 0x5f, 0x68, 0x74, 0x74, /* w..._htt */ +0x70, 0xc0, 0x1c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* p....... */ +0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, /* ......Ca */ +0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, /* nonMF450 */ +0x30, 0x77, 0xc0, 0x41, 0x06, 0x72, 0x6f, 0x75, /* 0w.A.rou */ +0x74, 0x65, 0x72, 0xc0, 0x21, 0x00, 0x01, 0x80, /* ter.!... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, /* ....x... */ +0xa8, 0x00, 0x04, 0xc0, 0x32, 0x00, 0x21, 0x80, /* ....2.!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x23, 0x8c, 0xc0, 0x62, 0xc0, /* ...#..b. */ +0x32, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, /* 2....... */ +0x94, 0x01, 0x4e, 0x09, 0x74, 0x78, 0x74, 0x76, /* ..N.txtv */ +0x65, 0x72, 0x73, 0x3d, 0x31, 0x05, 0x6e, 0x6f, /* ers=1.no */ +0x74, 0x65, 0x3d, 0x08, 0x71, 0x74, 0x6f, 0x74, /* te=.qtot */ +0x61, 0x6c, 0x3d, 0x31, 0x0b, 0x70, 0x72, 0x69, /* al=1.pri */ +0x6f, 0x72, 0x69, 0x74, 0x79, 0x3d, 0x31, 0x30, /* ority=10 */ +0x11, 0x74, 0x79, 0x3d, 0x43, 0x61, 0x6e, 0x6f, /* .ty=Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x37, 0x30, /* n MF4570 */ +0x64, 0x77, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, /* dw.produ */ +0x63, 0x74, 0x3d, 0x28, 0x43, 0x61, 0x6e, 0x6f, /* ct=(Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* n MF4500 */ +0x77, 0x29, 0x1c, 0x70, 0x64, 0x6c, 0x3d, 0x61, /* w).pdl=a */ +0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, /* pplicati */ +0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, /* on/octet */ +0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2a, /* -stream* */ +0x61, 0x64, 0x6d, 0x69, 0x6e, 0x75, 0x72, 0x6c, /* adminurl */ +0x3d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, /* =http:// */ +0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x6c, /* router.l */ +0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x2f, 0x74, 0x5f, /* ocal./t_ */ +0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x2e, 0x63, /* welcom.c */ +0x67, 0x69, 0x0d, 0x75, 0x73, 0x62, 0x5f, 0x4d, /* gi.usb_M */ +0x46, 0x47, 0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* FG=Canon */ +0x27, 0x75, 0x73, 0x62, 0x5f, 0x4d, 0x44, 0x4c, /* 'usb_MDL */ +0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x20, 0x4d, /* =Canon M */ +0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0x20, 0x53, /* F4500w S */ +0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x28, 0x55, /* eries (U */ +0x46, 0x52, 0x49, 0x49, 0x20, 0x4c, 0x54, 0x29, /* FRII LT) */ +0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, /* .transpa */ +0x72, 0x65, 0x6e, 0x74, 0x3d, 0x46, 0x08, 0x42, /* rent=F.B */ +0x69, 0x6e, 0x61, 0x72, 0x79, 0x3d, 0x46, 0x06, /* inary=F. */ +0x54, 0x42, 0x43, 0x50, 0x3d, 0x46, 0x07, 0x43, /* TBCP=F.C */ +0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x46, 0x08, 0x43, /* olor=F.C */ +0x6f, 0x70, 0x69, 0x65, 0x73, 0x3d, 0x54, 0x08, /* opies=T. */ +0x44, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x3d, 0x54, /* Duplex=T */ +0x0d, 0x50, 0x61, 0x70, 0x65, 0x72, 0x43, 0x75, /* .PaperCu */ +0x73, 0x74, 0x6f, 0x6d, 0x3d, 0x54, 0x06, 0x42, /* stom=T.B */ +0x69, 0x6e, 0x64, 0x3d, 0x46, 0x09, 0x43, 0x6f, /* ind=F.Co */ +0x6c, 0x6c, 0x61, 0x74, 0x65, 0x3d, 0x54, 0x06, /* llate=T. */ +0x53, 0x6f, 0x72, 0x74, 0x3d, 0x54, 0x08, 0x53, /* Sort=T.S */ +0x74, 0x61, 0x70, 0x6c, 0x65, 0x3d, 0x46, 0x07, /* taple=F. */ +0x50, 0x75, 0x6e, 0x63, 0x68, 0x3d, 0x46, 0x11, /* Punch=F. */ +0x50, 0x61, 0x70, 0x65, 0x72, 0x4d, 0x61, 0x78, /* PaperMax */ +0x3d, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x41, /* =legal-A */ +0x34, 0xc0, 0x53, 0x00, 0x21, 0x80, 0x01, 0x00, /* 4.S.!... */ +0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0xc0, 0x62, 0xc0, 0x53, 0x00, /* ..P.b.S. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x01, 0x00 /* .. */ +}; + +/* Frame (468 bytes) */ +static const unsigned char pkt49[468] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0xc6, 0x45, 0x95, 0x00, 0x00, 0xff, 0x11, /* ..E..... */ +0xd2, 0x83, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0xb2, /* ........ */ +0x11, 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* ........ */ +0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0b, 0x5f, 0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, /* ._udisks */ +0x2d, 0x73, 0x73, 0x68, 0xc0, 0x33, 0x00, 0x0c, /* -ssh.3.. */ +0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0xc0, 0x33, 0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, /* .3...... */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x02, 0xc0, 0x2e, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, /* ........ */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0xc0, /* ation.3. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x50, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..P..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x07, 0x04, /* ........ */ +0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, 0xc0, 0x0c, /* _rfb.3.. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x12, 0x0f, 0x5f, 0x70, 0x64, 0x6c, 0x2d, /* ..._pdl- */ +0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x72, 0x65, /* datastre */ +0x61, 0x6d, 0xc0, 0x33, 0xc0, 0x0c, 0x00, 0x0c, /* am.3.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0b, /* ........ */ +0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, /* ._printe */ +0x72, 0xc0, 0x33, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* r.3..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x16, 0x13, /* ........ */ +0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, 0x4f, 0x70, /* catro-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, /* 010.>.>. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x45, 0x4c, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* EL.>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x13, /* ........ */ +0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* .dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x3e, 0xc0, 0x50, 0x00, 0x0c, 0x00, /* 0.>.P... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x2a, 0x27, /* ......*' */ +0x64, 0x63, 0x27, 0x73, 0x20, 0x72, 0x65, 0x6d, /* dc's rem */ +0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, 0x73, 0x6b, /* ote desk */ +0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, 0x20, 0x64, /* top on d */ +0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, /* c-OptiPl */ +0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, /* ex-3010. */ +0x50, 0xc0, 0x50, 0x00, 0x0c, 0x00, 0x01, 0x00, /* P.P..... */ +0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, /* ......Ca */ +0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, /* nonMF450 */ +0x30, 0x77, 0xc0, 0x50 /* 0w.P */ +}; + +/* Frame (468 bytes) */ +static const unsigned char pkt50[468] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x01, 0xc6, 0x0a, 0x21, 0x00, 0x00, 0xff, 0x11, /* ...!.... */ +0x07, 0x58, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* .X...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0xb2, /* ........ */ +0x0b, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* .9...... */ +0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0b, 0x5f, 0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, /* ._udisks */ +0x2d, 0x73, 0x73, 0x68, 0xc0, 0x33, 0x00, 0x0c, /* -ssh.3.. */ +0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0xc0, 0x33, 0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, /* .3...... */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x02, 0xc0, 0x2e, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, /* ........ */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0xc0, /* ation.3. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x50, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..P..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x07, 0x04, /* ........ */ +0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, 0xc0, 0x0c, /* _rfb.3.. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x12, 0x0f, 0x5f, 0x70, 0x64, 0x6c, 0x2d, /* ..._pdl- */ +0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x72, 0x65, /* datastre */ +0x61, 0x6d, 0xc0, 0x33, 0xc0, 0x0c, 0x00, 0x0c, /* am.3.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0b, /* ........ */ +0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, /* ._printe */ +0x72, 0xc0, 0x33, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* r.3..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x16, 0x13, /* ........ */ +0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, 0x4f, 0x70, /* catro-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, /* 010.>.>. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x45, 0x4c, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* EL.>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x13, /* ........ */ +0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* .dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x3e, 0xc0, 0x50, 0x00, 0x0c, 0x00, /* 0.>.P... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x2a, 0x27, /* ......*' */ +0x64, 0x63, 0x27, 0x73, 0x20, 0x72, 0x65, 0x6d, /* dc's rem */ +0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, 0x73, 0x6b, /* ote desk */ +0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, 0x20, 0x64, /* top on d */ +0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, /* c-OptiPl */ +0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, /* ex-3010. */ +0x50, 0xc0, 0x50, 0x00, 0x0c, 0x00, 0x01, 0x00, /* P.P..... */ +0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, /* ......Ca */ +0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, /* nonMF450 */ +0x30, 0x77, 0xc0, 0x50 /* 0w.P */ +}; + +/* Frame (447 bytes) */ +static const unsigned char pkt51[447] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0xb1, 0x45, 0x9f, 0x00, 0x00, 0xff, 0x11, /* ..E..... */ +0xd2, 0x8e, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x9d, /* ........ */ +0x79, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* yH...... */ +0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, /* ...._rfb */ +0xc0, 0x19, 0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xc0, 0x19, /* stream.. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, /* .......1 */ +0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, /* .server- */ +0x48, 0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, /* HP-Z210- */ +0x57, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* Workstat */ +0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, /* ion [e8: */ +0x33, 0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, /* 39:35:44 */ +0x3a, 0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, /* :fe:d4]. */ +0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x94, 0x00, 0x2a, 0x27, 0x63, 0x61, /* ....*'ca */ +0x74, 0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* tro-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, /* 0 [a4:1f */ +0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, /* :72:53:9 */ +0x62, 0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x0c, 0xc0, /* b:c6]... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, /* o-EL [a4 */ +0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, /* :1f:72:5 */ +0x33, 0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, /* 3:a0:f7] */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x27, 0x24, 0x64, /* .....'$d */ +0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, /* c-OptiPl */ +0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, /* ex-3010 */ +0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, /* [a4:1f:7 */ +0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, /* 2:53:92: */ +0x61, 0x36, 0x5d, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, /* a6]..... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x1d, 0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, /* ..ubuntu */ +0x20, 0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, /* [00:0c: */ +0x32, 0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, /* 29:6a:2e */ +0x3a, 0x37, 0x61, 0x5d, 0xc0, 0x0c, 0xc0, 0x29, /* :7a]...) */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x29, 0xc0, 0x34, 0x00, 0x0c, /* 10.).4.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x34 /* 4500w.4 */ +}; + +/* Frame (447 bytes) */ +static const unsigned char pkt52[447] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x01, 0xb1, 0x0a, 0x22, 0x00, 0x00, 0xff, 0x11, /* ...".... */ +0x07, 0x6c, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* .l...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x9d, /* ........ */ +0x72, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* r....... */ +0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, /* ...._rfb */ +0xc0, 0x19, 0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xc0, 0x19, /* stream.. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, /* .......1 */ +0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, /* .server- */ +0x48, 0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, /* HP-Z210- */ +0x57, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* Workstat */ +0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, /* ion [e8: */ +0x33, 0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, /* 39:35:44 */ +0x3a, 0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, /* :fe:d4]. */ +0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x94, 0x00, 0x2a, 0x27, 0x63, 0x61, /* ....*'ca */ +0x74, 0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* tro-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, /* 0 [a4:1f */ +0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, /* :72:53:9 */ +0x62, 0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x0c, 0xc0, /* b:c6]... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, /* o-EL [a4 */ +0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, /* :1f:72:5 */ +0x33, 0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, /* 3:a0:f7] */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x27, 0x24, 0x64, /* .....'$d */ +0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, /* c-OptiPl */ +0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, /* ex-3010 */ +0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, /* [a4:1f:7 */ +0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, /* 2:53:92: */ +0x61, 0x36, 0x5d, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, /* a6]..... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x1d, 0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, /* ..ubuntu */ +0x20, 0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, /* [00:0c: */ +0x32, 0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, /* 29:6a:2e */ +0x3a, 0x37, 0x61, 0x5d, 0xc0, 0x0c, 0xc0, 0x29, /* :7a]...) */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x29, 0xc0, 0x34, 0x00, 0x0c, /* 10.).4.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x34 /* 4500w.4 */ +}; + +/* Frame (497 bytes) */ +static const unsigned char pkt53[497] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x01, 0xe3, 0x67, 0xce, 0x00, 0x00, 0xff, 0x11, /* ..g..... */ +0xb0, 0x93, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0xcf, /* ........ */ +0x46, 0x4d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FM...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, /* ......Ca */ +0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, /* nonMF450 */ +0x30, 0x77, 0xc0, 0x0c, 0x06, 0x72, 0x6f, 0x75, /* 0w...rou */ +0x74, 0x65, 0x72, 0xc0, 0x1a, 0x00, 0x01, 0x80, /* ter..... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, /* ....x... */ +0xa8, 0x00, 0x04, 0xc0, 0x2b, 0x00, 0x21, 0x80, /* ....+.!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x02, 0x03, 0xc0, 0x3a, 0xc0, /* ......:. */ +0x2b, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, /* +....... */ +0x94, 0x01, 0x56, 0x09, 0x74, 0x78, 0x74, 0x76, /* ..V.txtv */ +0x65, 0x72, 0x73, 0x3d, 0x31, 0x07, 0x72, 0x70, /* ers=1.rp */ +0x3d, 0x61, 0x75, 0x74, 0x6f, 0x05, 0x6e, 0x6f, /* =auto.no */ +0x74, 0x65, 0x3d, 0x08, 0x71, 0x74, 0x6f, 0x74, /* te=.qtot */ +0x61, 0x6c, 0x3d, 0x31, 0x0b, 0x70, 0x72, 0x69, /* al=1.pri */ +0x6f, 0x72, 0x69, 0x74, 0x79, 0x3d, 0x32, 0x30, /* ority=20 */ +0x11, 0x74, 0x79, 0x3d, 0x43, 0x61, 0x6e, 0x6f, /* .ty=Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x37, 0x30, /* n MF4570 */ +0x64, 0x77, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, /* dw.produ */ +0x63, 0x74, 0x3d, 0x28, 0x43, 0x61, 0x6e, 0x6f, /* ct=(Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* n MF4500 */ +0x77, 0x29, 0x1c, 0x70, 0x64, 0x6c, 0x3d, 0x61, /* w).pdl=a */ +0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, /* pplicati */ +0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, /* on/octet */ +0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2a, /* -stream* */ +0x61, 0x64, 0x6d, 0x69, 0x6e, 0x75, 0x72, 0x6c, /* adminurl */ +0x3d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, /* =http:// */ +0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x6c, /* router.l */ +0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x2f, 0x74, 0x5f, /* ocal./t_ */ +0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x2e, 0x63, /* welcom.c */ +0x67, 0x69, 0x0d, 0x75, 0x73, 0x62, 0x5f, 0x4d, /* gi.usb_M */ +0x46, 0x47, 0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* FG=Canon */ +0x27, 0x75, 0x73, 0x62, 0x5f, 0x4d, 0x44, 0x4c, /* 'usb_MDL */ +0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x20, 0x4d, /* =Canon M */ +0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0x20, 0x53, /* F4500w S */ +0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x28, 0x55, /* eries (U */ +0x46, 0x52, 0x49, 0x49, 0x20, 0x4c, 0x54, 0x29, /* FRII LT) */ +0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, /* .transpa */ +0x72, 0x65, 0x6e, 0x74, 0x3d, 0x46, 0x08, 0x42, /* rent=F.B */ +0x69, 0x6e, 0x61, 0x72, 0x79, 0x3d, 0x46, 0x06, /* inary=F. */ +0x54, 0x42, 0x43, 0x50, 0x3d, 0x46, 0x07, 0x43, /* TBCP=F.C */ +0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x46, 0x08, 0x43, /* olor=F.C */ +0x6f, 0x70, 0x69, 0x65, 0x73, 0x3d, 0x54, 0x08, /* opies=T. */ +0x44, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x3d, 0x54, /* Duplex=T */ +0x0d, 0x50, 0x61, 0x70, 0x65, 0x72, 0x43, 0x75, /* .PaperCu */ +0x73, 0x74, 0x6f, 0x6d, 0x3d, 0x54, 0x06, 0x42, /* stom=T.B */ +0x69, 0x6e, 0x64, 0x3d, 0x46, 0x09, 0x43, 0x6f, /* ind=F.Co */ +0x6c, 0x6c, 0x61, 0x74, 0x65, 0x3d, 0x54, 0x06, /* llate=T. */ +0x53, 0x6f, 0x72, 0x74, 0x3d, 0x54, 0x08, 0x53, /* Sort=T.S */ +0x74, 0x61, 0x70, 0x6c, 0x65, 0x3d, 0x46, 0x07, /* taple=F. */ +0x50, 0x75, 0x6e, 0x63, 0x68, 0x3d, 0x46, 0x11, /* Punch=F. */ +0x50, 0x61, 0x70, 0x65, 0x72, 0x4d, 0x61, 0x78, /* PaperMax */ +0x3d, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x41, /* =legal-A */ +0x34 /* 4 */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt54[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x45, 0xa1, 0x00, 0x00, 0xff, 0x11, /* .ZE..... */ +0xd2, 0xe3, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0x63, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* c....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x6a, 0x03, 0x31, 0x30, 0x36, /* ...j.106 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt55[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x0a, 0x23, 0x00, 0x00, 0xff, 0x11, /* .~.#.... */ +0x08, 0x9e, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (106 bytes) */ +static const unsigned char pkt56[106] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x5c, 0x45, 0xa5, 0x00, 0x00, 0xff, 0x11, /* .\E..... */ +0xd3, 0xdd, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x48, /* .......H */ +0x7b, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* {....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0xc0, /* al...... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x0c /* .. */ +}; + +/* Frame (106 bytes) */ +static const unsigned char pkt57[106] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x5c, 0x0a, 0x24, 0x00, 0x00, 0xff, 0x11, /* .\.$.... */ +0x08, 0xbf, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x48, /* .......H */ +0x75, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* u-...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0xc0, /* al...... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x0c /* .. */ +}; + +/* Frame (850 bytes) */ +static const unsigned char pkt58[850] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x03, 0x44, 0x45, 0xac, 0x00, 0x00, 0xff, 0x11, /* .DE..... */ +0xd0, 0xee, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x03, 0x30, /* .......0 */ +0xfa, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* .n...... */ +0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0x00, /* ation.3. */ +0x0c, 0x00, 0x01, 0x0b, 0x5f, 0x75, 0x64, 0x69, /* ...._udi */ +0x73, 0x6b, 0x73, 0x2d, 0x73, 0x73, 0x68, 0xc0, /* sks-ssh. */ +0x33, 0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, /* 3....._h */ +0x74, 0x74, 0x70, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ttp.3... */ +0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, /* .._rfb.3 */ +0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, /* ....._pd */ +0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, /* l-datast */ +0x72, 0x65, 0x61, 0x6d, 0xc0, 0x33, 0x00, 0x0c, /* ream.3.. */ +0x00, 0x01, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, /* ..._prin */ +0x74, 0x65, 0x72, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ter.3... */ +0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x90, 0x00, 0x02, 0xc0, 0x2e, 0xc0, /* ........ */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x02, 0xc0, 0x51, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..Q..... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x02, 0xc0, /* ........ */ +0x63, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* c....... */ +0x00, 0x11, 0x91, 0x00, 0x02, 0xc0, 0x6f, 0xc0, /* ......o. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x02, 0xc0, 0x7a, 0xc0, 0x0c, 0x00, /* ....z... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x02, 0xc0, 0x90, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x31, 0x2e, /* ......1. */ +0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x48, /* server-H */ +0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, 0x57, /* P-Z210-W */ +0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, /* orkstati */ +0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, 0x33, /* on [e8:3 */ +0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, 0x3a, /* 9:35:44: */ +0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, 0x3e, /* fe:d4].> */ +0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* .>...... */ +0x11, 0x91, 0x00, 0x2a, 0x27, 0x63, 0x61, 0x74, /* ...*'cat */ +0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, /* ro-OptiP */ +0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, /* lex-3010 */ +0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, /* [a4:1f: */ +0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x62, /* 72:53:9b */ +0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, /* :c6].>.> */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, 0x3a, /* -EL [a4: */ +0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, /* 1f:72:53 */ +0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, 0xc0, /* :a0:f7]. */ +0x3e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, /* >.>..... */ +0x00, 0x11, 0x91, 0x00, 0x27, 0x24, 0x64, 0x63, /* ....'$dc */ +0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, /* -OptiPle */ +0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, 0x5b, /* x-3010 [ */ +0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, /* a4:1f:72 */ +0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, 0x61, /* :53:92:a */ +0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* 6].>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x1d, /* ........ */ +0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, /* .ubuntu */ +0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, 0x32, /* [00:0c:2 */ +0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, 0x3a, /* 9:6a:2e: */ +0x37, 0x61, 0x5d, 0xc0, 0x3e, 0xc0, 0x51, 0x00, /* 7a].>.Q. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x16, 0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, /* OptiPlex */ +0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, /* -3010.Q. */ +0x51, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* Q....... */ +0x91, 0x00, 0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0xc0, 0x51, 0xc0, 0x51, /* o-EL.Q.Q */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x13, 0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, /* ...dc-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, 0x63, 0x00, /* 010.Q.c. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, 0x72, /* *'dc's r */ +0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, /* emote de */ +0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, /* sktop on */ +0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x63, 0xc0, 0x63, 0x00, 0x0c, 0x00, /* 0.c.c... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0f, 0x0c, /* ........ */ +0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, /* CanonMF4 */ +0x35, 0x30, 0x30, 0x77, 0xc0, 0x63, 0xc0, 0x6f, /* 500w.c.o */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x6f, 0xc0, 0x7a, 0x00, 0x0c, /* 10.o.z.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x7a, 0xc0, /* 4500w.z. */ +0x90, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x92, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x90 /* .. */ +}; + +/* Frame (850 bytes) */ +static const unsigned char pkt59[850] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x03, 0x44, 0x0a, 0x25, 0x00, 0x00, 0xff, 0x11, /* .D.%.... */ +0x05, 0xd6, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x03, 0x30, /* .......0 */ +0xf3, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* ........ */ +0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0x00, /* ation.3. */ +0x0c, 0x00, 0x01, 0x0b, 0x5f, 0x75, 0x64, 0x69, /* ...._udi */ +0x73, 0x6b, 0x73, 0x2d, 0x73, 0x73, 0x68, 0xc0, /* sks-ssh. */ +0x33, 0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, /* 3....._h */ +0x74, 0x74, 0x70, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ttp.3... */ +0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, /* .._rfb.3 */ +0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, /* ....._pd */ +0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, /* l-datast */ +0x72, 0x65, 0x61, 0x6d, 0xc0, 0x33, 0x00, 0x0c, /* ream.3.. */ +0x00, 0x01, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, /* ..._prin */ +0x74, 0x65, 0x72, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ter.3... */ +0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x90, 0x00, 0x02, 0xc0, 0x2e, 0xc0, /* ........ */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x02, 0xc0, 0x51, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..Q..... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x02, 0xc0, /* ........ */ +0x63, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* c....... */ +0x00, 0x11, 0x91, 0x00, 0x02, 0xc0, 0x6f, 0xc0, /* ......o. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x02, 0xc0, 0x7a, 0xc0, 0x0c, 0x00, /* ....z... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x02, 0xc0, 0x90, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x31, 0x2e, /* ......1. */ +0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x48, /* server-H */ +0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, 0x57, /* P-Z210-W */ +0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, /* orkstati */ +0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, 0x33, /* on [e8:3 */ +0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, 0x3a, /* 9:35:44: */ +0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, 0x3e, /* fe:d4].> */ +0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* .>...... */ +0x11, 0x91, 0x00, 0x2a, 0x27, 0x63, 0x61, 0x74, /* ...*'cat */ +0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, /* ro-OptiP */ +0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, /* lex-3010 */ +0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, /* [a4:1f: */ +0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x62, /* 72:53:9b */ +0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, /* :c6].>.> */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, 0x3a, /* -EL [a4: */ +0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, /* 1f:72:53 */ +0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, 0xc0, /* :a0:f7]. */ +0x3e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, /* >.>..... */ +0x00, 0x11, 0x91, 0x00, 0x27, 0x24, 0x64, 0x63, /* ....'$dc */ +0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, /* -OptiPle */ +0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, 0x5b, /* x-3010 [ */ +0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, /* a4:1f:72 */ +0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, 0x61, /* :53:92:a */ +0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* 6].>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x1d, /* ........ */ +0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, /* .ubuntu */ +0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, 0x32, /* [00:0c:2 */ +0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, 0x3a, /* 9:6a:2e: */ +0x37, 0x61, 0x5d, 0xc0, 0x3e, 0xc0, 0x51, 0x00, /* 7a].>.Q. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x16, 0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, /* OptiPlex */ +0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, /* -3010.Q. */ +0x51, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* Q....... */ +0x91, 0x00, 0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0xc0, 0x51, 0xc0, 0x51, /* o-EL.Q.Q */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x13, 0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, /* ...dc-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, 0x63, 0x00, /* 010.Q.c. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, 0x72, /* *'dc's r */ +0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, /* emote de */ +0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, /* sktop on */ +0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x63, 0xc0, 0x63, 0x00, 0x0c, 0x00, /* 0.c.c... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0f, 0x0c, /* ........ */ +0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, /* CanonMF4 */ +0x35, 0x30, 0x30, 0x77, 0xc0, 0x63, 0xc0, 0x6f, /* 500w.c.o */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x6f, 0xc0, 0x7a, 0x00, 0x0c, /* 10.o.z.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x7a, 0xc0, /* 4500w.z. */ +0x90, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x92, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x90 /* .. */ +}; + +/* Frame (850 bytes) */ +static const unsigned char pkt60[850] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x03, 0x44, 0x45, 0xd0, 0x00, 0x00, 0xff, 0x11, /* .DE..... */ +0xd0, 0xca, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x03, 0x30, /* .......0 */ +0x81, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* ........ */ +0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0x00, /* ation.3. */ +0x0c, 0x00, 0x01, 0x0b, 0x5f, 0x75, 0x64, 0x69, /* ...._udi */ +0x73, 0x6b, 0x73, 0x2d, 0x73, 0x73, 0x68, 0xc0, /* sks-ssh. */ +0x33, 0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, /* 3....._h */ +0x74, 0x74, 0x70, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ttp.3... */ +0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, /* .._rfb.3 */ +0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, /* ....._pd */ +0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, /* l-datast */ +0x72, 0x65, 0x61, 0x6d, 0xc0, 0x33, 0x00, 0x0c, /* ream.3.. */ +0x00, 0x01, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, /* ..._prin */ +0x74, 0x65, 0x72, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ter.3... */ +0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x87, 0x00, 0x02, 0xc0, 0x2e, 0xc0, /* ........ */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x88, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x02, 0xc0, 0x51, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..Q..... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x02, 0xc0, /* ........ */ +0x63, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* c....... */ +0x00, 0x11, 0x88, 0x00, 0x02, 0xc0, 0x6f, 0xc0, /* ......o. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x88, 0x00, 0x02, 0xc0, 0x7a, 0xc0, 0x0c, 0x00, /* ....z... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x02, 0xc0, 0x90, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x31, 0x2e, /* ......1. */ +0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x48, /* server-H */ +0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, 0x57, /* P-Z210-W */ +0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, /* orkstati */ +0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, 0x33, /* on [e8:3 */ +0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, 0x3a, /* 9:35:44: */ +0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, 0x3e, /* fe:d4].> */ +0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* .>...... */ +0x11, 0x88, 0x00, 0x2a, 0x27, 0x63, 0x61, 0x74, /* ...*'cat */ +0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, /* ro-OptiP */ +0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, /* lex-3010 */ +0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, /* [a4:1f: */ +0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x62, /* 72:53:9b */ +0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, /* :c6].>.> */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, 0x3a, /* -EL [a4: */ +0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, /* 1f:72:53 */ +0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, 0xc0, /* :a0:f7]. */ +0x3e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, /* >.>..... */ +0x00, 0x11, 0x88, 0x00, 0x27, 0x24, 0x64, 0x63, /* ....'$dc */ +0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, /* -OptiPle */ +0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, 0x5b, /* x-3010 [ */ +0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, /* a4:1f:72 */ +0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, 0x61, /* :53:92:a */ +0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* 6].>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x1d, /* ........ */ +0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, /* .ubuntu */ +0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, 0x32, /* [00:0c:2 */ +0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, 0x3a, /* 9:6a:2e: */ +0x37, 0x61, 0x5d, 0xc0, 0x3e, 0xc0, 0x51, 0x00, /* 7a].>.Q. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x16, 0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, /* OptiPlex */ +0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, /* -3010.Q. */ +0x51, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* Q....... */ +0x88, 0x00, 0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0xc0, 0x51, 0xc0, 0x51, /* o-EL.Q.Q */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x13, 0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, /* ...dc-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, 0x63, 0x00, /* 010.Q.c. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, 0x72, /* *'dc's r */ +0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, /* emote de */ +0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, /* sktop on */ +0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x63, 0xc0, 0x63, 0x00, 0x0c, 0x00, /* 0.c.c... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0f, 0x0c, /* ........ */ +0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, /* CanonMF4 */ +0x35, 0x30, 0x30, 0x77, 0xc0, 0x63, 0xc0, 0x6f, /* 500w.c.o */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x6f, 0xc0, 0x7a, 0x00, 0x0c, /* 10.o.z.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x7a, 0xc0, /* 4500w.z. */ +0x90, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x89, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x90 /* .. */ +}; + +/* Frame (850 bytes) */ +static const unsigned char pkt61[850] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x03, 0x44, 0x0a, 0x26, 0x00, 0x00, 0xff, 0x11, /* .D.&.... */ +0x05, 0xd5, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x03, 0x30, /* .......0 */ +0x7b, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* {....... */ +0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0x00, /* ation.3. */ +0x0c, 0x00, 0x01, 0x0b, 0x5f, 0x75, 0x64, 0x69, /* ...._udi */ +0x73, 0x6b, 0x73, 0x2d, 0x73, 0x73, 0x68, 0xc0, /* sks-ssh. */ +0x33, 0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, /* 3....._h */ +0x74, 0x74, 0x70, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ttp.3... */ +0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, /* .._rfb.3 */ +0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, /* ....._pd */ +0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, /* l-datast */ +0x72, 0x65, 0x61, 0x6d, 0xc0, 0x33, 0x00, 0x0c, /* ream.3.. */ +0x00, 0x01, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, /* ..._prin */ +0x74, 0x65, 0x72, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ter.3... */ +0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x87, 0x00, 0x02, 0xc0, 0x2e, 0xc0, /* ........ */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x88, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x02, 0xc0, 0x51, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..Q..... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x02, 0xc0, /* ........ */ +0x63, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* c....... */ +0x00, 0x11, 0x88, 0x00, 0x02, 0xc0, 0x6f, 0xc0, /* ......o. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x88, 0x00, 0x02, 0xc0, 0x7a, 0xc0, 0x0c, 0x00, /* ....z... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x02, 0xc0, 0x90, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x31, 0x2e, /* ......1. */ +0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x48, /* server-H */ +0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, 0x57, /* P-Z210-W */ +0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, /* orkstati */ +0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, 0x33, /* on [e8:3 */ +0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, 0x3a, /* 9:35:44: */ +0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, 0x3e, /* fe:d4].> */ +0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* .>...... */ +0x11, 0x88, 0x00, 0x2a, 0x27, 0x63, 0x61, 0x74, /* ...*'cat */ +0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, /* ro-OptiP */ +0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, /* lex-3010 */ +0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, /* [a4:1f: */ +0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x62, /* 72:53:9b */ +0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, /* :c6].>.> */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, 0x3a, /* -EL [a4: */ +0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, /* 1f:72:53 */ +0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, 0xc0, /* :a0:f7]. */ +0x3e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, /* >.>..... */ +0x00, 0x11, 0x88, 0x00, 0x27, 0x24, 0x64, 0x63, /* ....'$dc */ +0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, /* -OptiPle */ +0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, 0x5b, /* x-3010 [ */ +0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, /* a4:1f:72 */ +0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, 0x61, /* :53:92:a */ +0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* 6].>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x1d, /* ........ */ +0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, /* .ubuntu */ +0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, 0x32, /* [00:0c:2 */ +0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, 0x3a, /* 9:6a:2e: */ +0x37, 0x61, 0x5d, 0xc0, 0x3e, 0xc0, 0x51, 0x00, /* 7a].>.Q. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x16, 0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, /* OptiPlex */ +0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, /* -3010.Q. */ +0x51, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* Q....... */ +0x88, 0x00, 0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0xc0, 0x51, 0xc0, 0x51, /* o-EL.Q.Q */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x13, 0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, /* ...dc-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, 0x63, 0x00, /* 010.Q.c. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, 0x72, /* *'dc's r */ +0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, /* emote de */ +0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, /* sktop on */ +0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x63, 0xc0, 0x63, 0x00, 0x0c, 0x00, /* 0.c.c... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0f, 0x0c, /* ........ */ +0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, /* CanonMF4 */ +0x35, 0x30, 0x30, 0x77, 0xc0, 0x63, 0xc0, 0x6f, /* 500w.c.o */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x6f, 0xc0, 0x7a, 0x00, 0x0c, /* 10.o.z.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x7a, 0xc0, /* 4500w.z. */ +0x90, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x89, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x90 /* .. */ +}; + diff --git a/test/regression/mdns_test/capture/query_and_response_chaos.pcapng b/test/regression/mdns_test/capture/query_and_response_chaos.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..3231ae0e41a8e3f76a9b2cd2e974a32856969566 GIT binary patch literal 16524 zcmeGk32+nF^{?eq*onpEgg{sVi8&%8`L>Gi`j9ySw!n~s0E#RLEG$bxT7iL-kSR?~ zu5zW*$w?+8kd}5rrtKstgv~{hOb$vyDAQ?bn$U(c(`lMCnMqr_@BLkA|E_Ey+c{_a znQ!gi{r|uF_-{8c78Dq_6G9fxnKglf-#(=o$ShJ>Zf^67{B{1IH?%RzSMjaB$Oga1 z$2;Ag4&Hh--xl)+ynI!q#Y!@XnKZ^a!yb2-x0Y0wSorC!*EaJ@eH-}lvhp%3za|pu z{M_ z28+3-zM{@tS>v$ORWv%P%PK0rPe>l@lnwigA|^t@p@_&=lvR}R?x2_Vhv9zyAZdan z6ffLU!~wMBf6F8rUhk-Fg=_2_Sxv})E-^%BxYpzn2O*BeJAjL(Qx{1G$+{kRHun73 z^Thh@_h7P2D*WWTq5+>TYz{|4U7IppF>g345c0SKh$BZ~>0!3Np@;cV(d?u956du( zKyaTa_q=p4$JmpAdHOyCN!bfO>A{q61vI4dwU;|sX@7sT>)e4GX4zD78yrVo}Jb3tolAw6q#oLe*pX$oO6saOoT1r zN@&Qt-#)cI74Pn%yn9Z|yJ8DnJ|OQ1l^z-f>NyOJqMx4Tww9d2So-uUM$TYN_Nb25V)t!CF(A;}4qMUT-AR9SOU^ z#V9kuR?%9OQIaKdrJQ9*|EzRXxxpW3suN$JKKVu8OPSs-ahKOAEjUPmJ<0cMHIAb?a7d#A z>$3l-$RPt4rIJIAF~bVzrzM6sx>VjJ1sgrX8tl&DeEowhtzR4%tfb6nnF)ExEd3k3)db2%1n)029*46O@|6Dh5b<1lrC z%FjNa00#{hV>mXXH|tjmg>`U^Jwb2Tb4O`?VrADxg!^zF&>QH9=aBP_=aqbyLcTD) zgqZe{{7hH0vn|sldcx9FIlo38?1hdEapBipBShdDyNt^RH5HA$Z&O^ngb0AknZE!o z89i}aob{l2Sc{UmpC&G2^IaQ5k&dY77X6`M0w=^pk5k6RYXm$VW0!H-KRMER-*JkQ zN5Sd$fYaEXI8H6z{|*7CF{7ZIC{g|(PWzx^Lp~L?E)urFHFg!J-H%b6 zpbkR$^a9{Ct|yMu%DD~98HJ?Dr-Ce3yC{YgY~UP%RW1}}PNplercJV`b+&DQ3pT{> z*j3HKYPiOp(5ZNx&FKKNA&wRTerla<&P``=HNg`UG*wsP1t@^55t?L@k=X{bkw5s0 z4dH*71fQ`br*RU(&poNJr8z6==<*@M4^Uf>;op0#Sy%*P>fk$)s#9~7VUj>41Gz!TMHJ%9TO zMgP*|$;@I8EfKebMZYuP>oS*FtQP)8ce%~F##U8ot0=S8wAnnBDVPB<4O-rqel`Lw zbR~1)vB{CXUhuu}jOD^uq#b$iPr9LOgR{o92yeg`yUK%opHm+xDLjY)561MwedM7c z2msq*KB{0kdNFyTjJjiymTw z11w56CKO%l3VQ=)uUm9S#fZ<{nH(KP<+{QVe^B&Aq(&xa-y^BbipJtAH&$V`<$Y z(}=Wg!%d(et)EU=k}5yAmF5QpKr53U#Cqv+B|azRN{q`^wCs|B^Mlu}(8Jf{2ba_Q z0CGAe*PatvJv{g?(&aM!d){9nJOX3vs;(>k`5r~q4*~tEf4=qPWY$(w(NE*|_Y`?QIp@aE)E&4f9^S)d5o>U(eCl zW9_}CVKS4i!*PHH0){pEKoL*bDQrCsr;>1BY_in|+7CJV>l&M^-CH$$93ZsNhJ3i~ zk>$cKV1zwMM;=miWUod??kN0_)oFSx((_@^Dx#+0kUXjxJ5`aQ{A9VqOBaH4AWy^4 zu^~ORTdx&b;2L|9TH?vtfg(IhhQ zEOc>xgF6@sE^aEXuvj)q`AUG9m@q}%gu3iVD2B<;6iqP9luES*IrUDd4elvNF0MIG z>=NOW5w%;hg5XE&x$DJ{=nmMeqad3KMf~C>yVYWXzZ4xF@u{+SHx|LiDBhSyv`<&> z1D-P`LYiiGhru$nKG7^EZ8P28PJb{K3E1&~Z<{?^M!AH3%~CR3bZztn zJfY4K&su*$EZXK;+%!)HTTDldix?yT7=B^o_eJ^X%bS)iSimn@Hlsj{xP#HKJK_t9 z_NLr=f6yJ-WN*q|R^Q;XH{~>h0-*@pZwQ59oqbtuV=N4(2>Y@Er#tM6G{mA}sMEeI z8`gR4O?faq;0Bf~%Wj3wgJ62A=!W^Qkuw(bwA-6ZblGBemp$NH>kgRf%B5Baio%{i7Gu)G=GgNsYiNoIu*H+Zi zJygP=u%YqrWq3zXF?ub<%PxCJhE$RmpgVmbFOFo7Wd?+nh}|Q*JR!Uvd4yY{?tROgkvzqo@D2T9T4ro&hOUP`2(BeSY;qN zxQoX6^npXJk6wz(n`B$`t`xWGy<`aGC3W#&>M-i63sx@Fsc9dY)g>1=XU-UcNzahV z6RUJ4T~1K0Xw$5Gg?)PYGB$nKcm=iTfX1dDh#W+@!Z(m3@@1-c@uJ8#FW<44vq3}q z{p5vJ!p9(Y?E2h~dv7h2{UG<-!{&b6n@x+A+z-|e!@#*_e@S0Fr<1JuOj0}Th zlV-)U4DMPrr^|_i?e3Tu8Zfsj9m(y|&Fw&Zs0(QG>^DC@T;>wmLAKbFeEJHG%W_bCFWG9GigL((koCRfYyD0P@xq3F#&Hz6B&w}eD?YK~I7V5FXxaI_>b6GtA+D5M!}){J&0&PTgQ|L3D!gHQL= zGtw@Se!9o5x7i)8)4SJhX?cdO7yb^6L>mAnq z4VF*v1t+{4AF(-N8nHR~Ro;lr5mUN0*L%WLmmmE*=>mE{^>n3T(xo$G(IM+?mjC0)=jC0+j z-#FJzQpP!CO1iHZ)i~F!k3DLf8_b4koJ-nJjdMHnum*^8)hG2fr-^e{(KvTX8|SuU zjo4hg_C8{B`ZzaYbBWiJip`<91gOc#=iKABEvn<-Khkap!52XAl97kEh8z4|pO5T@2}tF z@a=du2kVfPgtlh0T}@YvXFZl>Dr*Y^bk+(9lf;wIiB@9j7M0k{VZStY7Qt-jTK zC6)7~e5t%87{_QZHc!@p@pPrNd zvFBvHK^cL=2W_^N)N@}JX~wVuSIsa15yxLW>lTRs literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/query_during_probing_1.c b/test/regression/mdns_test/capture/query_during_probing_1.c new file mode 100644 index 00000000..272c4fbf --- /dev/null +++ b/test/regression/mdns_test/capture/query_during_probing_1.c @@ -0,0 +1,240 @@ +/* Frame (226 bytes) */ +static const unsigned char pkt1[226] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xd4, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xda, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc0, /* ........ */ +0x6d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* m....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x04, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* .test._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, /* ..test._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00 /* .. */ +}; + +/* Frame (226 bytes) */ +static const unsigned char pkt2[226] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xd4, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd9, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc0, /* ........ */ +0x6d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* m....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x04, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* .test._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, /* ..test._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00 /* .. */ +}; + +/* Frame (226 bytes) */ +static const unsigned char pkt3[226] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xd4, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd8, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc0, /* ........ */ +0x6d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* m....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x04, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* .test._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, /* ..test._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00 /* .. */ +}; + +/* Frame (338 bytes) */ +static const unsigned char pkt4[338] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x44, 0x00, 0x04, 0x40, 0x00, 0xff, 0x11, /* .D..@... */ +0x8f, 0x67, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .g...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x30, /* .......0 */ +0x12, 0x57, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .W...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, /* .@.test. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x16, 0x04, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, /* test._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1d, 0x04, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + +/* Frame (338 bytes) */ +static const unsigned char pkt5[338] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x44, 0x00, 0x05, 0x40, 0x00, 0xff, 0x11, /* .D..@... */ +0x8f, 0x66, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .f...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x30, /* .......0 */ +0x12, 0x57, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .W...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, /* .@.test. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x16, 0x04, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, /* test._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1d, 0x04, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + +/* Frame (338 bytes) */ +static const unsigned char pkt6[338] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x44, 0x00, 0x06, 0x40, 0x00, 0xff, 0x11, /* .D..@... */ +0x8f, 0x65, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .e...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x30, /* .......0 */ +0x12, 0x57, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .W...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, /* .@.test. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x16, 0x04, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, /* test._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1d, 0x04, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + diff --git a/test/regression/mdns_test/capture/query_during_probing_1.pcapng b/test/regression/mdns_test/capture/query_during_probing_1.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..d2f41774a3245f410e73a3fd5a097da00fc4ba0c GIT binary patch literal 2292 zcmeH}U2D@|6vzK*(^6|EPUb{Wc=T#Av$ZCD8Hn^H9eB}FTCq1{rEM~aYnza!^$lSc z-unf-_FD*k2$9wc5fR3|fgoC+lXX&STJYs+>_EtqJkL4*=lnS5Nx};Y;pYGfw^lC+ z{5~3+AFD_xQp0dq)#zyE!!Ap*if;Ffrp`+B<}QofV2z&9(pWMPjX{J2wb!t6TxKS_c zKM4)X{F$!lUJz7>E`$4%420;p>S52jMdjHGzm&E|(PDjE`^#RFLV89~|A%h)y*nd3 zZ$QJcx2X5qp9x%87K1Yv==5Lsbxx_r?L6^CH z!u(&D^O^_$5V}TZ%ZJFFp@7TCnZ1sq+g)baX5Y|sjWr%K?eIs#hmd;?-G0y=_{U@N P6Z!ba0uy6;M;bo>gCrrY literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/query_during_probing_2.c b/test/regression/mdns_test/capture/query_during_probing_2.c new file mode 100644 index 00000000..ae03bb09 --- /dev/null +++ b/test/regression/mdns_test/capture/query_during_probing_2.c @@ -0,0 +1,56 @@ +/* Frame (86 bytes) */ +static const unsigned char pkt1[86] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x48, 0x00, 0xf6, 0x00, 0x00, 0xff, 0x11, /* .H...... */ +0x12, 0x01, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x34, /* .......4 */ +0x9a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .e...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, /* est._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x00, 0x01, /* cal..!.. */ +0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01 /* ...... */ +}; + +/* Frame (289 bytes) */ +static const unsigned char pkt2[289] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x13, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x95, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xff, /* ........ */ +0x12, 0xde, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x04, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, /* est._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, /* test._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* B.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, /* ...x...A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x40, 0x04, 0x74, 0x65, 0x73, /* ...@.tes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1d, 0x04, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40 /* @ */ +}; + diff --git a/test/regression/mdns_test/capture/query_during_probing_2.pcapng b/test/regression/mdns_test/capture/query_during_probing_2.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..3dcc95586c3f8338485454440ea701e98b030078 GIT binary patch literal 840 zcmb7?&ui0Q7{|Zwn!2sqWSd1%6yAAKX4cjuZ3iCuBOP8^$|~DsSlT2)Sl5I!sS{Cp z5Il(|4~p#M!K+t6*gsO)!OOt2h#uU!a zN0G&_iL5HOZJ+PkUDJ8m<2l~2yuNK%yxuYndFCE(2X@EgxokQE2{QEH$TeCn&urzl z()>ie6E)B zrF^NpBj+k=QC4&1w7gx?igI?lk}hg`C9i1N7r>&JbVbm*!s5%5;hym6FgynS{=Am@_UX$4D!@bh5(=)Zv(wM>i8GN)o+rS5Xb-h(po=2@FaqRC#6PHlk@`wZJYMiqE_@GN}EIo)+VG$rHD5lpnCSA zP=&sLZ=q*zUVQ_>L*0!P#Dk#thh=7WX6LsvY;1fyb`GGl8lMg@+aD-|IFhnZGhNy> z8@hGUq!d*Qr)6peZB(@*N-R>%GwV8~l41g32vEIaTdUfXSV}L6G+)^%)0WX9S(2p$ z9Xi%AExV4_I1*UG0%LJ;Hs@XqY`+f#v4TC-;HbUwM)BZO&Zl$fT)rrz3UXGEQ+ZLy z6Vz!R{;CK8z$!@bvKFvu!g`o`jef@7%=v3>g!FX;0w{*QN;>;1$F`Ml2Gc@fqlYuFc`=Wy_$8^8?mme+6% or%ASBwM^a6sn#a_<3j}z^=E%CYTeMl=l8$Nt4+Jk3uL}7C{1=3rA_e~d!9$#Ry8%nd!43>>=DpeZzWLtUNHiLG0sz<7 zmM#dmj(rQl5~NkBVY+O~Z0pwj4$H7j!|9n#gH`IyZI)bSjjq|!StgxGf(Q~6yE}HX zZnNY{b|t|sZ{FHqH;o=s6;(;HyN>mPO}Kr39ghJ5a22XWgP^J# zm2&N&s$~n=f>xF?B{eUp87(2L7E*aBy;@4-Q^itNNu?hH%wnfA*yk+70c^{0SxQMM ztlrj{Y2*Iff6j!Ta9-5&86{}fev0t*aDUjsm|TE60DmBUNhxlHp#+%DSdRb{ zhIlrAG=Bu^7oTG>jmAxMjgA|t-E&=Athr4))Uuj&Y_|x)w4)dZ#DTbc_nL4nl`s3l zPneT?Tz;LGzr8!;TwVqGc%$)HVDND!GMsREy8PMGowEr}16F{X9fxIjo*+%wik@*n=FOfo5@ecTd;b@5`ebn3JE- zRf90sRX?Vy9DTtX5LL9PvtU0Di!cZ1WOSFmKa@wWF(yBu-$CFF*YDgh{T}tJzJAp7 zH2R%RGR_<2WI(NlseQ6f8(EeuVC9CoRAtdfAP78&kZvsN zm6Fbald;JFJ2QWAmgSWu3rQg<$gUXLGV_~8qqZob!CAy2B5cBa(mmU4fB`rMg|tFY zh1p!Tcq1goQn8er6{DHZj2Mc_0dXo7o)IHcnZQgqory`|$SQyfBOSpwN5KoAYlg|f zQdnZ8T9v6f>OKEi6S~-WQOuikLHfSM!^Yaz_$8EyIk*h)3%n<#^nw#I0Ow&a32pCs z!3~gV;oI=e@D9YXJQ{aO#luR~^NpX&6PVuEluZ0`dYAe}lNzWy11gm>b;9^V6}-DBUr9xZ1xep_DFa9wo z%9(OE2@;8BRG7;r=1?Z?%UuSSoqJ_p?tcF|d3Q1gI0&t68xR&@ejpDd!ffXAi4ByA z`}X4T7^aDPv9)h6?oPbu?!^E)IS#_?jTpZvq}=W{j9Q+(vzGo^4(ZRR1q..@... */ +0x90, 0x6a, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .j...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (1437 bytes) */ +static const unsigned char pkt2[1437] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x05, 0x8f, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8b, 0x61, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* .a...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x7b, /* .......{ */ +0x26, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* &....... */ +0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* .,....._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x31, 0x2e, 0x30, 0x31, 0x20, 0x53, 0x69, /* .1.01 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0xc0, 0x0c, 0xc0, 0x28, 0x00, 0x10, 0x80, /* s...(... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, /* ........ */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0x06, 0x75, 0x62, 0x75, 0x6e, 0x74, /* .P.ubunt */ +0x75, 0xc0, 0x17, 0xc0, 0x78, 0x00, 0x1c, 0x80, /* u...x... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, /* ....x... */ +0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x0c, 0x29, 0xff, 0xfe, 0x01, 0xd4, 0x8d, 0xc0, /* .)...... */ +0x78, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* x....... */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x01, 0xc0, /* x....... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x31, 0x2e, 0x31, 0x36, 0x20, 0x53, /* ..1.16 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0xc0, 0x0c, 0xc0, 0xb9, 0x00, 0x10, /* ts...... */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0xc0, 0xb9, 0x00, 0x21, 0x80, 0x01, 0x00, /* ....!... */ +0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, /* ..P.x... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x31, 0x2e, 0x31, 0x35, 0x20, 0x53, 0x69, 0x6d, /* 1.15 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0xc0, 0x0c, 0xc1, 0x17, 0x00, 0x10, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, 0xc1, /* ........ */ +0x17, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* x....... */ +0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* P.x..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, /* ......1. */ +0x31, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 13 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, /* ackets.. */ +0xc1, 0x75, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* .u...... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc1, 0x75, 0x00, /* ......u. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, /* ......P. */ +0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* x....... */ +0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, 0x30, 0x38, /* ....1.08 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, 0xc1, 0xd3, /* kets.... */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x01, 0x00, 0xc1, 0xd3, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, /* ....P.x. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x31, 0x2e, 0x31, 0x34, 0x20, 0x53, /* ..1.14 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0xc0, 0x0c, 0xc2, 0x31, 0x00, 0x10, /* ts...1.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0xc2, 0x31, 0x00, 0x21, 0x80, 0x01, 0x00, /* ..1.!... */ +0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, /* ..P.x... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x31, 0x2e, 0x31, 0x32, 0x20, 0x53, 0x69, 0x6d, /* 1.12 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0xc0, 0x0c, 0xc2, 0x8f, 0x00, 0x10, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, 0xc2, /* ........ */ +0x8f, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* x....... */ +0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* P.x..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, /* ......1. */ +0x31, 0x31, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 11 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, /* ackets.. */ +0xc2, 0xed, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc2, 0xed, 0x00, /* ........ */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, /* ......P. */ +0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* x....... */ +0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, 0x30, 0x39, /* ....1.09 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, 0xc3, 0x4b, /* kets...K */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x01, 0x00, 0xc3, 0x4b, 0x00, 0x21, 0x80, /* ....K.!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, /* ....P.x. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x31, 0x2e, 0x31, 0x30, 0x20, 0x53, /* ..1.10 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0xc0, 0x0c, 0xc3, 0xa9, 0x00, 0x10, /* ts...... */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0xc3, 0xa9, 0x00, 0x21, 0x80, 0x01, 0x00, /* ....!... */ +0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, /* ..P.x... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x31, 0x2e, 0x30, 0x37, 0x20, 0x53, 0x69, 0x6d, /* 1.07 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0xc0, 0x0c, 0xc4, 0x07, 0x00, 0x10, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, 0xc4, /* ........ */ +0x07, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* x....... */ +0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* P.x..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, /* ......1. */ +0x30, 0x35, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 05 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, /* ackets.. */ +0xc4, 0x65, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* .e...... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc4, 0x65, 0x00, /* ......e. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, /* ......P. */ +0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* x....... */ +0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, 0x30, 0x36, /* ....1.06 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, 0xc4, 0xc3, /* kets.... */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x01, 0x00, 0xc4, 0xc3, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, /* ....P.x. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x31, 0x2e, 0x30, 0x34, 0x20, 0x53, /* ..1.04 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0xc0, 0x0c, 0xc5, 0x21, 0x00, 0x10, /* ts...!.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0xc5, 0x21, 0x00, 0x21, 0x80, 0x01, 0x00, /* ..!.!... */ +0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0xc0, 0x78 /* ..P.x */ +}; + +/* Frame (265 bytes) */ +static const unsigned char pkt3[265] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0xfb, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xf5, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xe7, /* ........ */ +0x83, 0xd5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x31, 0x2e, 0x30, 0x32, 0x20, 0x53, 0x69, /* .1.02 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0xc0, 0x0c, 0xc0, 0x28, 0x00, 0x10, 0x80, /* s...(... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, /* ........ */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0x06, 0x75, 0x62, 0x75, 0x6e, 0x74, /* .P.ubunt */ +0x75, 0xc0, 0x17, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* u....... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, /* ......1. */ +0x30, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 03 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, /* ackets.. */ +0xc0, 0x8d, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x8d, 0x00, /* ........ */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, /* ......P. */ +0x78 /* x */ +}; + +/* Frame (1471 bytes) */ +static const unsigned char pkt4[1471] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xb1, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xf6, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x9d, /* ........ */ +0xd6, 0x19, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, /* .......A */ +0x2e, 0x30, 0x31, 0x20, 0x53, 0x69, 0x6d, 0x70, /* .01 Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, /* erver Te */ +0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, /* st For M */ +0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, /* ultiple */ +0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, /* Packets. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* .._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x31, 0x36, /* ....A.16 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, /* kets._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, /* local.._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x41, 0x2e, 0x31, 0x35, 0x20, 0x53, 0x69, /* .A.15 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, /* al.._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, /* ......A. */ +0x31, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 13 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x93, 0x00, 0x41, 0x2e, 0x30, 0x38, 0x20, /* ...A.08 */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, /* r Test F */ +0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, /* or Multi */ +0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, /* ple Pack */ +0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ets._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, /* ocal.._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, /* ........ */ +0x41, 0x2e, 0x31, 0x34, 0x20, 0x53, 0x69, 0x6d, /* A.14 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* l.._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x31, /* .....A.1 */ +0x32, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* 2 Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, /* ver Test */ +0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, /* For Mul */ +0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, /* tiple Pa */ +0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, /* ckets._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x93, 0x00, 0x41, 0x2e, 0x31, 0x31, 0x20, 0x53, /* ..A.11 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ts._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, /* cal.._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, /* .......A */ +0x2e, 0x30, 0x39, 0x20, 0x53, 0x69, 0x6d, 0x70, /* .09 Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, /* erver Te */ +0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, /* st For M */ +0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, /* ultiple */ +0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, /* Packets. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* .._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x31, 0x30, /* ....A.10 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, /* kets._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, /* local.._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x41, 0x2e, 0x30, 0x37, 0x20, 0x53, 0x69, /* .A.07 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, /* al.._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, /* ......A. */ +0x30, 0x35, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 05 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x93, 0x00, 0x41, 0x2e, 0x30, 0x36, 0x20, /* ...A.06 */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, /* r Test F */ +0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, /* or Multi */ +0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, /* ple Pack */ +0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ets._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, /* ocal.._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, /* ........ */ +0x41, 0x2e, 0x30, 0x34, 0x20, 0x53, 0x69, 0x6d, /* A.04 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* l.._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x30, /* .....A.0 */ +0x32, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* 2 Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, /* ver Test */ +0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, /* For Mul */ +0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, /* tiple Pa */ +0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, /* ckets._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (147 bytes) */ +static const unsigned char pkt5[147] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x85, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x21, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .!...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x71, /* .......q */ +0xae, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x41, 0x2e, 0x30, 0x33, 0x20, 0x53, 0x69, /* .A.03 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00 /* al. */ +}; + +/* Frame (1471 bytes) */ +static const unsigned char pkt6[1471] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xb1, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xf4, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x9d, /* ........ */ +0xe4, 0x29, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, /* .)...... */ +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x41, /* .......A */ +0x2e, 0x30, 0x31, 0x20, 0x53, 0x69, 0x6d, 0x70, /* .01 Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, /* erver Te */ +0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, /* st For M */ +0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, /* ultiple */ +0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, /* Packets. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* .._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, 0x31, 0x36, /* ....A.16 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, /* kets._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, /* local.._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x41, 0x2e, 0x31, 0x35, 0x20, 0x53, 0x69, /* .A.15 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, /* al.._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, /* ......A. */ +0x31, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 13 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x91, 0x00, 0x41, 0x2e, 0x30, 0x38, 0x20, /* ...A.08 */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, /* r Test F */ +0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, /* or Multi */ +0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, /* ple Pack */ +0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ets._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, /* ocal.._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x41, 0x2e, 0x31, 0x34, 0x20, 0x53, 0x69, 0x6d, /* A.14 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* l.._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, 0x31, /* .....A.1 */ +0x32, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* 2 Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, /* ver Test */ +0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, /* For Mul */ +0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, /* tiple Pa */ +0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, /* ckets._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x41, 0x2e, 0x31, 0x31, 0x20, 0x53, /* ..A.11 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ts._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, /* cal.._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x41, /* .......A */ +0x2e, 0x30, 0x39, 0x20, 0x53, 0x69, 0x6d, 0x70, /* .09 Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, /* erver Te */ +0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, /* st For M */ +0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, /* ultiple */ +0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, /* Packets. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* .._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, 0x31, 0x30, /* ....A.10 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, /* kets._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, /* local.._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x41, 0x2e, 0x30, 0x37, 0x20, 0x53, 0x69, /* .A.07 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, /* al.._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, /* ......A. */ +0x30, 0x35, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 05 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x91, 0x00, 0x41, 0x2e, 0x30, 0x36, 0x20, /* ...A.06 */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, /* r Test F */ +0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, /* or Multi */ +0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, /* ple Pack */ +0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ets._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, /* ocal.._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x41, 0x2e, 0x30, 0x34, 0x20, 0x53, 0x69, 0x6d, /* A.04 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* l.._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, 0x30, /* .....A.0 */ +0x32, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* 2 Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, /* ver Test */ +0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, /* For Mul */ +0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, /* tiple Pa */ +0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, /* ckets._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (147 bytes) */ +static const unsigned char pkt7[147] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x85, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x1f, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x71, /* .......q */ +0xae, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* . ...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x41, 0x2e, 0x30, 0x33, 0x20, 0x53, 0x69, /* .A.03 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00 /* al. */ +}; + diff --git a/test/regression/mdns_test/capture/query_with_tc.pcapng b/test/regression/mdns_test/capture/query_with_tc.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..0aaa1c21d9df9d78232055ac5794acf72712a37f GIT binary patch literal 5644 zcmcJT&u<$=6vv-ayG>HJjYXvjRFMf1Rnx{{xBd|aQAC_L7ibj`+FUB4*j|LG6EBe52;JN9yeQ+AG>146uikZqnx%SDT7!lK!vs5WrVrs5* zS(rnj=vAs^F_JY*h(Z!3ym`AcXA5&UH*AQL(-+T+cdaFnPNh?(_`s>ni`QJoTezIW z8wSxAHS$exw>?IYI62!dOVlU<;N$JBZc%>GCeYGBuDd^v1E3% zV2ouZ3b|A!dkvrmN&As=5Do))Wn0)a#}%1WCIt}Jd>_Qfn21-U4z^eCN8!{9eT{eU znvMv(5AYWxUP(>NbVC8)O*rrtG!r*J>IKMe#ERRgd8xY~*XzPBhlAPlxX-J{bA+2KkDu0FbXQ=g?PV+xHc_dg9xi zoWc-MTKfV>d=2KXVT$R>yj``#j8&B1)^fyq)}kvWYmPYQRow~=(#N*k#d^Gc68f&= zx59@bfSm#Az%m>mPcXILD|!pAS3g!?hU5NF-?Qs-5W3=n&1V=ojz#>jC5l^F#;9KG8*ei@b^Cg+ zZ`{E?9eZ^(_5*a2)_w65bCuuT)w;FcU!?yP@OG&{t+lST6$NJ%#xxaBMX45F%?Pfi zW-3axaJbg;Q&Fmg!?nJ-ic&2Mt|w(GO0_V!o|363)xzOg>rF+e77o|aF%_j+7+g=r zRFrCAa8pagRFrCAa6J)IQL2T*!(2p$mV~Kssumu(mV&7$)xzN&&U0DUslNY+2Q|{d zpDy+{R`HsSz4aYFhaRf$HwSoqhmXI1nV!ZbHMM=r9hNK^>t0Q|^T*kCn$#;b=`oKv zw)Q7(Z2z|=eHErA5j-?alJKyWlZ1EpfuB2jWX`p=S1L-i_{&K~9@biw@DA5%`^dx6 zB$;!qt(6+5YT-E#OOs^eS{o}hPSwI9*V|XADAmH@VQG>~OPKTA=y0C5)TFI@XWMDg zL8(doyuPC*38_dynj{m_Vabx3L|Y{KZIBx2D7;>1MBq4#*YL+S%UKk*Q(LN(t+FUy g5#^m9V7s7O-n$O*#y{ec z!;vOo5p-4Tcrn}bdXE1xVg_4x!@g&`Y^`nYGI@!060hqpLziUWK!kd-7ufB9$;*{x zi7l*ewAd53&s0TKWcDod_t;7tCcRw|H{3xMiP*&bFj|L0fC;z@+jW;v+pV>x^;)e} zs+DT3DH;vc6jh@piK|u36!q1HWNP(BMbY#(06b2*hI6jN4S>W6Sm1{-(-chsnEucA z!7-^Pn)iw>Q14GUI5y^mE$pds@D$+huep`)ACIP>0q}tTf(e%Shl9_B;t4*RJ)1oP z{m)O_oV_M4ycK0JMg`01MPlS|7Mjg>eY@QyqdDRc_W+ATT=U($5MWQ0aiJ_I_05#q zfx>;{9yE&p)sr!|HTNmYHx2j-T!8W+%;c?|I1V@~w#S~x2l+X~B9WgT-z_PrBftrEbL@Tr6$=K-g{*(xk44 zvIh?y1ih~w1P|WC4?&df9K@12K8OH0yo0F7I# z7X+FoNu;ofqAK^@kagUlY3ZDaGmudcVMwnF<*cP8Ai0@n?0Wu z*7UVJyV}0rWSjPwsfwx;m=kzAEEfjRa9bw9HDdALY|ed?%##VQfE(B{Y>wJ$wl=y? z)S6z^tF;ZeR97pqTB_yc^{Q5pi|h4#MKkKUq7|P4C#lj2skkaF8BHUr!4Bg9q9o%xSZYp@*yJ~(Amo2 z$|1CG)J`mqr^U))>L1)aF51O;`U0(aanjoS)}MXnlKWTw zE=vP@D9>wV4;PXGB7ehif*IlLafd>gy5@cn0Aynv+_$5TcO3y2QS+iV|DGi&<8E+89weEaK7Cza&hK&U|{gI(UxKa(*L1=nL(Su%tSXSvqT|0GcP5-yja0pAvm?DEHgP(As{h1 zTftCAA*nPoCq=>B%)pR=g+Z6Wr8Ku7Ik7;&P|rfoKtUro%ugXGwM@ap*u>aSA+0Ds zS3$p|s5CEI7pOoJXcq{8>;~Dp1WNz^&%nUMV8jsPk_xga#xKAvzS_ju!pXwP*-h8n z)x=TP#N63H*V4(iEnFnNpFe5`81H*3yK_z3Ca1I7n z28IL%CI^Q9f)fh37#QRq0Odqpio9g-xt0i24Dl||%iNAZzP>Jg!6B)|C9FC5$%#3@ z&}U%8Cd}9X3ZfJSmIEsoMpe(p(I)`QPIEMWKK(bhc`;NXVD zS7iAF&u}0ggfZgFlYtfNo)#4Mn9h}iq)(s*ARrtuAp1b^f^4sl#}s__vVrYwroO$i zC1&8WmmO?x6Xo`@0{sh2xL^Rv7jyY{donV}FgWLz=9Q!t6)O}J<(Flqq^2k&RVt)F g3J4|!4safN|B=~~8OjFfV*#>ZfE9@i5(C)*0Ex8(BLDyZ literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/response_aggregation.c b/test/regression/mdns_test/capture/response_aggregation.c new file mode 100644 index 00000000..2d235909 --- /dev/null +++ b/test/regression/mdns_test/capture/response_aggregation.c @@ -0,0 +1,182 @@ +/* Frame (140 bytes) */ +static const unsigned char pkt1[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x01, 0x4c, 0x00, 0x00, 0xff, 0x11, /* .~.L.... */ +0x11, 0x75, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* .u...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (79 bytes) */ +static const unsigned char pkt2[79] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x41, 0x01, 0x4d, 0x00, 0x00, 0xff, 0x11, /* .A.M.... */ +0x11, 0xb1, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2d, /* .......- */ +0xbe, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .H...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* al..... */ +}; + +/* Frame (79 bytes) */ +static const unsigned char pkt3[79] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x41, 0x01, 0x4e, 0x00, 0x00, 0xff, 0x11, /* .A.N.... */ +0x11, 0xb0, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2d, /* .......- */ +0xbe, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .H...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* al..... */ +}; + +/* Frame (75 bytes) */ +static const unsigned char pkt4[75] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x3d, 0x01, 0x4f, 0x00, 0x00, 0xff, 0x11, /* .=.O.... */ +0x11, 0xb3, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x29, /* .......) */ +0xa9, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .&...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (632 bytes) */ +static const unsigned char pkt5[632] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x02, 0x6a, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .j..@... */ +0x8e, 0x3e, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .>...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x02, 0x56, /* .......V */ +0x66, 0x0b, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* f....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x21, 0x0b, 0x41, 0x52, /* ..d.!.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, /* t._print */ +0x65, 0x72, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* er._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, /* local.._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x1d, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* STest._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, /* local..A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x08, 0x5f, /* NSTest._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, /* local..A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, /* st._prin */ +0x74, 0x65, 0x72, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ter._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* ...ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x08, 0x5f, /* NSTest._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x28, 0x0b, 0x41, 0x52, /* ..x.(.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, /* t._print */ +0x65, 0x72, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* er._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x0b, 0x41, 0x52, /* ....@.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, /* ocal..AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x0b, 0x41, 0x52, /* .d....AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x24, 0x0b, 0x41, 0x52, 0x4d, /* .x.$.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .......@ */ +}; + +/* Frame (101 bytes) */ +static const unsigned char pkt6[101] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x57, 0x01, 0x50, 0x00, 0x00, 0xff, 0x11, /* .W.P.... */ +0x11, 0x98, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x43, /* .......C */ +0x10, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x0e, 0x0b, /* ....d... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0xc0, 0x0c /* est.. */ +}; + +/* Frame (105 bytes) */ +static const unsigned char pkt7[105] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x5b, 0x01, 0x51, 0x00, 0x00, 0xff, 0x11, /* .[.Q.... */ +0x11, 0x93, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x47, /* .......G */ +0x26, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* &....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0xc0, /* al...... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x63, 0x00, 0x0e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* c...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0xc0, /* DNSTest. */ +0x0c /* . */ +}; + diff --git a/test/regression/mdns_test/capture/response_aggregation.pcapng b/test/regression/mdns_test/capture/response_aggregation.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..a22ca99e8bf94bfe3233b14659a32393990a4a48 GIT binary patch literal 1840 zcmbtVO=uHQ5T4CX8`B?JD2k%;DpFeNw%I1xq@X3gRnWw=mG)pUY_nU~{v^vbsgAM`;>}ABf)+e^Qasd|%|o@JxTA`1mWL4i%{rFqt0)+@zX9vylRi-fQV_o4aR+XHaH z08FM7f||_chV#pzWHb>?B!~G(Iuz$akz{}$OoZdSIG7H^!>M#M7#42=9KuWun5PL^ z0V=Y_w31$C;b1rj(0sspFpa^9@~zVX<;N!voRlB1RkTStxCZd^>yiG~k2igg2Drst z!Vb2#SGJxu`gibM$8N_i%rtzg)`^8-kS{5f^%9>;dgn?7X%2T*r~ymhp(vLS;3958 zjJk!vfkw5+OR}tcBwdrR2Gh~C)x6aV{pQMxHWypR6vS0SB_Xau+mF~~v`KAT<6Oqz zx>?7Se{+GN(cKVVUencLSj6Ljvb z8EA|l*1aJ=Kw`%{ch~rIljYoffA1xL44qB!(M%?l9lN3|lpS52xl-&2Ypl)9`m%O{ zzpoq-c5W?aN)3dZHNYfc-Ez*+X6E2vf8QG6?)_c804q>e zf~{ub(?4-Z2H&q_!ED;Bv+ctkumxvTegi zz+nK29S!FjzbQ23bb_r`YPes;CmyS)Bs3p)hIg2XHmQxrRc^%Kaleko`L6dAjqU~y z=R08KQgGlx9I!h;GfP5Tmc{RkgX54aRp{Hbz%;$IsLG1Wrfx8~`jc{j&+z^BB+T5V QO>rKyYvQ%ov_}}f0P|eDX8-^I literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/response_in_multiple_packets.c b/test/regression/mdns_test/capture/response_in_multiple_packets.c new file mode 100644 index 00000000..c59b4397 --- /dev/null +++ b/test/regression/mdns_test/capture/response_in_multiple_packets.c @@ -0,0 +1,470 @@ +/* Frame (75 bytes) */ +static const unsigned char pkt1[75] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x3d, 0x06, 0x3f, 0x00, 0x00, 0xff, 0x11, /* .=.?.... */ +0x0c, 0xc3, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x29, /* .......) */ +0xa9, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .&...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (1497 bytes) */ +static const unsigned char pkt2[1497] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xcb, 0x00, 0x1d, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xc7, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xb7, /* ........ */ +0x44, 0x6c, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* Dl...... */ +0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 2._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* l.._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, /* ..d...te */ +0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st3._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, /* cal.._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, /* local.._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 6._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* l.._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, /* ..d...te */ +0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st7._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, /* cal.._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, /* local.._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x18, 0x06, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 10._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* al.._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x18, 0x06, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, /* est11._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, /* local.._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x18, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, /* ..test12 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x18, 0x06, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t13._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, /* cal.._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, 0x06, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, /* test14._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, /* .local.. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, /* ..x...AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x01, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st1._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x05, /* ...d.... */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, 0x69, /* test1._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, /* .....x.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, /* .test1._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, /* .....@.t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, /* .test2._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, /* ...test2 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 2._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, 0x04, /* @.test3. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st3._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, /* est3._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, /* ...@.tes */ +0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t4._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, /* est4._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, /* ..test4. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, /* test5._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00 /* . */ +}; + +/* Frame (1490 bytes) */ +static const unsigned char pkt3[1490] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xc4, 0x00, 0x1e, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xcd, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xb0, /* ........ */ +0x12, 0x0c, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x05, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, /* est5._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, /* .test5._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, /* test6._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, 0x04, /* ..test6. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 6._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t6._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, /* .@.test7 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t7._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, /* ..d....t */ +0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, /* est7._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, /* ocal../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, /* ....x... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x38, 0x04, /* ..test8. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x38, /* ...test8 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* .......@ */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, 0x5f, /* .test9._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, /* l..test9 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, 0x73, /* d....tes */ +0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t9._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st9._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x06, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 10._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, 0x69, /* est10._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, /* ..test10 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 10._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* .@.test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, /* st11._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x31, 0x04, /* .test11. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, /* @.test12 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x06, /* ...d.... */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, /* test12._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, /* ..test12 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* .......@ */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 13._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, /* ..d....t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, /* test14._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00 /* l. */ +}; + +/* Frame (154 bytes) */ +static const unsigned char pkt4[154] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x8c, 0x00, 0x1f, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x04, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x78, /* .......x */ +0xef, 0x93, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, /* ..test14 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x31, 0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 14._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt5[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x01, 0x5a, 0x06, 0x40, 0x00, 0x00, 0xff, 0x11, /* .Z.@.... */ +0x0b, 0xa5, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0x9e, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .#...... */ +0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x08, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x31, 0xc0, 0x0c, 0xc0, /* test1... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x08, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x32, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* 2....... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x08, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x33, 0xc0, 0x0c, 0xc0, /* test3... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x08, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x34, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* 4....... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x08, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x35, 0xc0, 0x0c, 0xc0, /* test5... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x08, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x36, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* 6....... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x08, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0xc0, 0x0c, 0xc0, /* test7... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x08, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x38, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* 8....... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x08, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x39, 0xc0, 0x0c, 0xc0, /* test9... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x09, 0x06, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x31, 0x30, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0c, /* 10...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x09, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x31, 0xc0, /* .test11. */ +0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x00, 0x64, 0x00, 0x09, 0x06, 0x74, 0x65, /* ..d...te */ +0x73, 0x74, 0x31, 0x32, 0xc0, 0x0c, 0xc0, 0x0c, /* st12.... */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x09, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x33, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* 3....... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x09, 0x06, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0xc0, 0x0c /* test14.. */ +}; + diff --git a/test/regression/mdns_test/capture/response_in_multiple_packets.pcapng b/test/regression/mdns_test/capture/response_in_multiple_packets.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..142ad0b721de08c36457af5d714bddf344035532 GIT binary patch literal 4140 zcmb7{O=uHA6vyATNoBi z-v@w^3w=ive%>}(EA)XH@y+JTY%;%?E!6l$ZnPj3(Q|GRTk%bT+qvNVZ+>*_nC3t z-Ueua5KN_Wm}+WtY_|$=+Kq8tRiie}>J%D!J zlZ*G`fxQ5gY>^cUr80|#qhSDVljGstXiV7OJl^nj=BEQvpSRS@{2C7hZUAik>h`~X z@um%i04};N@h8~n{jk2a$GyS-*R|QT3B9k*amBNCCkSkpxmea6~166c8M$B#;7vBPI!?fZ&Kr z0x2Lk1|)$L*l`?kX)_p*6jDI6G&Ac)mS(2iurxF8hDDxuPhxyzBt1HDg)i3H&qZ0q zg0TV)T=|s1ZwL-j|5OGWtb91B*|KmLe?Blqm>W6w8%_lpDQZYPjRgEBz6v^;{H*Pw z5l#V(P*~9jfeB5XQ@dz{Q$QmWRy0CjLX+2yT{OZepb-iy8X+*D$<+z!3HVaOnvb>r zA3tNm+P~(ms^9oM9#ZZ92t8Wu|7xlIuMc>Q+K-(a)m9pj+U7DRoYpZD0?t}n#BzPL zI~|0x{...... */ +0x11, 0xeb, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x26, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* &/...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt2[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x28, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .(...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0xbf, 0xcd, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* ...ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* B.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, /* ...x...A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, /* ...@.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, /* ocal..AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x14, 0x08, 0x70, 0x61, /* ..d...pa */ +0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, /* per=A4.v */ +0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, /* ersion=0 */ +0x31, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* 1.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (102 bytes) */ +static const unsigned char pkt3[102] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x58, 0x01, 0x17, 0x00, 0x00, 0xff, 0x11, /* .X...... */ +0x11, 0xd0, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x44, /* .......D */ +0xe4, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .a...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x0e, /* .....d.. */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0xc0, 0x0c /* Test.. */ +}; + diff --git a/test/regression/mdns_test/capture/response_interval.pcapng b/test/regression/mdns_test/capture/response_interval.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..9c60b1cffa04f9cef6a4fc793c9dc3a48d8d9e9b GIT binary patch literal 1072 zcmb7D&ubG=5dOAJY)sQ)AhakVPr(wc+azZ5qhKXJHa(dT+G0hDA<1qrG|euXO;kk4 z!GkCL2fXP)Z+hxU?8%!T_z(2ZOVP6+9^y=P3k``B2Oe+Uyl>|FcHXRiX2$;vhG=l4*VfhMlkt*G+HJs8^|a01|UB*9UF}8FQu0J-nndFNX`kD{*y` zxuhPZGQ{;N><4lOE|=8&{MG5{psC*RTvT4erRnTiv8a~TH}tkWiW|ChWlB93_ZS|g z90!QFfVpv(Qf4SR+J(!5Yz^m$1Sk)o9R)+7(E{h(0wJGSHFawxtN6RR)ovKAm1yjg z++*oiPr-SC9x~25@q4{stz`UOp*LT!O+K%Y*|;ao4`$=r&}^uORn8_jxAq^iu^-?G zp=%AZC*@Imz)zZnX7rc#o!}RdH##kw8X!!|=r%N66SXHobAHkZ_y(H8t@oI8ea`cc Ne{9|pKF4@Q{{p(k0$Kn7 literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/response_interval_2.c b/test/regression/mdns_test/capture/response_interval_2.c new file mode 100644 index 00000000..01f3f0ae --- /dev/null +++ b/test/regression/mdns_test/capture/response_interval_2.c @@ -0,0 +1,520 @@ +/* Frame (269 bytes) */ +static const unsigned char pkt1[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xaf, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt2[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xae, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt3[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xad, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt4[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x04, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x2b, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .+...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt5[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x05, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x2a, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .*...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt6[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x06, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x29, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .)...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt7[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x01, 0x25, 0x00, 0x00, 0xff, 0x11, /* .E.%.... */ +0x11, 0xd5, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xd7, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (90 bytes) */ +static const unsigned char pkt8[90] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4c, 0x01, 0x26, 0x00, 0x00, 0xff, 0x11, /* .L.&.... */ +0x11, 0xcd, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x38, /* .......8 */ +0x9b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .p...... */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x80, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x07, 0x0a /* .. */ +}; + +/* Frame (90 bytes) */ +static const unsigned char pkt9[90] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4c, 0x01, 0x27, 0x00, 0x00, 0xff, 0x11, /* .L.'.... */ +0x11, 0xcc, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x38, /* .......8 */ +0x1b, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .q...... */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x07, 0x0a /* .. */ +}; + +/* Frame (90 bytes) */ +static const unsigned char pkt10[90] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4c, 0x01, 0x28, 0x00, 0x00, 0xff, 0x11, /* .L.(.... */ +0x11, 0xcb, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x38, /* .......8 */ +0x1b, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .q...... */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x07, 0x0a /* .. */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt11[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x01, 0x29, 0x00, 0x00, 0xff, 0x11, /* .~.).... */ +0x11, 0x98, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt12[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x01, 0x2a, 0x00, 0x00, 0xff, 0x11, /* .E.*.... */ +0x11, 0xd0, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xd7, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt13[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x01, 0x2b, 0x00, 0x00, 0xff, 0x11, /* .~.+.... */ +0x11, 0x96, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt14[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x01, 0x2c, 0x00, 0x00, 0xff, 0x11, /* .~.,.... */ +0x11, 0x95, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt15[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x01, 0x2d, 0x00, 0x00, 0xff, 0x11, /* .E.-.... */ +0x11, 0xcd, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xd7, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (94 bytes) */ +static const unsigned char pkt16[94] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x50, 0x01, 0x2e, 0x00, 0x00, 0xff, 0x11, /* .P...... */ +0x11, 0xc1, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3c, /* .......< */ +0xa4, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* st._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x00, 0x01, /* cal..!.. */ +0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01 /* ...... */ +}; + +/* Frame (340 bytes) */ +static const unsigned char pkt17[340] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x46, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .F..@... */ +0x8f, 0x62, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .b...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x32, /* .......2 */ +0xa4, 0x76, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .v...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* st._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, /* .local.. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* =01.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0x0a, 0x00, 0x00, 0x42, 0x0b, 0x41, 0x52, 0x4d, /* ...B.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x16, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, 0x40, 0x0b, /* cal...@. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, /* ocal../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x25, 0x0b, /* ....x.%. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40 /* ...@ */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt18[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x01, 0x2f, 0x00, 0x00, 0xff, 0x11, /* .~./.... */ +0x11, 0x92, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + diff --git a/test/regression/mdns_test/capture/response_interval_2.pcapng b/test/regression/mdns_test/capture/response_interval_2.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..3fbeaf81b483c3c99d820a42c6742b149c0a8c9c GIT binary patch literal 4512 zcmeHLTZj`^82%@hy^OoX;G$Ti9v9ZzI@x4%T~JIm$@Zac2(BoIG-NX)P0ePevy)WO zN+^A+C*(eUd(;|9@siG8>&$@doY>Cv(X; z=lk=0|9{SZBKG%-p8>$+uHm-@ytXX!!Z5_6(sadO2P-vM{dkro*p#9-DrJQgO68+0 zypv7WD^-~#;-N73K!R+2Mk|*z77iwZA+~MmK%VVW8Y~)#M#AifuFkL#L$BA4O4wmL zVv!Lx;m%ptRtvxbqi{H@5Y*v(VWM~cV+e!CL@zS!0^28!Q%yMF9Gq^7r60+$WkZL=K`o_{#@>2EXX-$7gB+ zybtgn1O_A7gFTQ#@<2#ID{%G)5ny}~zZ62eG&cW1U6l$M8>-b576^`L#p;H}nwU$m_4n4fVQ=Nwe>kx>eB_P|Pl#RL zy1@;58^`|r`C)&{-8MPDGPp@RjnC9NI6oy|d5t<>bYOqjb=TVWs1g-AIDfe5(I`(i zBqY4yc+wjl8||*tq>?P_zLKt$FhZK9ES`lv6v^Hd{3KY4d?bz9V=}+U++uPE_w~BN z*Jp~!c7E2*1>N`==9m{8m@k!|c3;`)J#N14X^kbHAw~p0wz+)fwvrA;>X*aqzQi{tk`Cqa?Rw3YN`0<5$ya)5QKfeksJ!2>;Z- zs<hK&U|{gI(UxKa(*L1=nL(Su%tSXSvqT|0GcP5-yja0pAvm?DEHgP(As{h1 zTftCAA*nPoCq=>B%)pR=g+Z6Wr8Ku7Ik7;&P|rfoKtUro%ugXGwM@ap*u>aSA+0Ds zS3$p|s5CEI7pOoJXcq{8>;~Dp080P=&%nUMV8jsPk_xga#xKAvzS`W}#M#oq#7Wo9 zz}QgN#Kpi^*V4$$NY~WS(#gQZ)y>k#)v%Uxteyb7ea9fN#*UHpPWQj1GibMliDb3js{Z~)l@ zvTqF#g8<0BABR@Cb^+NS46%WVD@F~EP;eA*ic5S z_BDX)t6*ROX~d>LAF4nMny)U0|h_mVaUmnZo8Y^Bn=2Q=_Usup)_I%1WS_L!nSEPY(7*( z?7_SA=21L(@aiQfc=m7b(1RXw)SC#6Guah9~g4(Y({+1}#;<*DxYW4GhbUaNCL`UbT}Zr7%KPSc@4g*7_ucUpbYH@7!6 zx>J8xqkU&grePX79r@lVZ4LcV??h$8I5{@Q=e z#3l3ZlAcm8ntoI8qa~Dqd(H2>#pK7y=XW^1;J4N3>J;g> z_t_kb%ExkXzgo3w^#{&i81H(WR#%>655f`NR}PWzKK(pzOgNVacu1xU>tN1%kHil1 zUj0e{rHjA3*EcqT-Oigv7xK=8_XLU*E;6izhU=GSY-B}~so5oS7n!$0^Q}dX$_}s; z%oOK7JnURD+cfo|5y2XEy-{!I_yg+u-q^Jro7zvw4t}U87mK$zdC`c4xzs7rG*tYb IT&{%i2lBP73IG5A literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/response_with_tc.c b/test/regression/mdns_test/capture/response_with_tc.c new file mode 100644 index 00000000..48089f81 --- /dev/null +++ b/test/regression/mdns_test/capture/response_with_tc.c @@ -0,0 +1,110 @@ +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0x90, 0xb2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (554 bytes) */ +static const unsigned char pkt2[554] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x02, 0x1c, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8e, 0x8c, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x02, 0x08, /* ........ */ +0x00, 0x93, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x41, 0x2e, 0x30, 0x33, 0x20, 0x53, 0x69, /* .A.03 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0x0a, 0x00, 0x00, 0x42, 0x0b, 0x41, 0x52, 0x4d, /* ...B.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x16, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, 0x40, 0x2e, /* cal...@. */ +0x30, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 03 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x2e, 0x30, 0x33, 0x20, 0x53, /* al..03 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ts._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x2e, /* ...d.... */ +0x30, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 03 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x48, 0x2e, 0x30, 0x33, 0x20, 0x53, 0x69, /* .H.03 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + +/* Frame (137 bytes) */ +static const unsigned char pkt3[137] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x7b, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .{..@... */ +0x90, 0x75, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* .u...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x67, /* .......g */ +0xcf, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x31, /* .....d.1 */ +0x2e, 0x30, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, /* .03 Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, /* erver Te */ +0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, /* st For M */ +0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, /* ultiple */ +0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0xc0, /* Packets. */ +0x0c /* . */ +}; + diff --git a/test/regression/mdns_test/capture/response_with_tc.pcapng b/test/regression/mdns_test/capture/response_with_tc.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..3a38cf5bf15d2e87008d933aa80f4d4b4053f922 GIT binary patch literal 1272 zcmbu9O=}Zj5XWcJL}QwQg(@gL%z6;px@qEWUJ4@3D?KzJG-@uTG08sa(j>cVcB4{+ z9=r%Df@g0Y1tFinZ{S6*QVqbvEpY<_~HDM2ow!mt$eTa$M*m8}Ij_Fi90YOlp;C8Kc)51h7 z6N}@m+QSO&i2-V=rY7*QZFX_fvEAOGLJ4ccVq-RQKl#_u2p|A=V80+3wO^^08b?|_ zlgs4tB_&w)JuR%ROtfMS%fP9u5O`a+72ewq>9a+ zj)q0C=sD-2EnaV2x5GDNH-87ACra`z`Me}J0Qd{hHR=1?Fcbmq0c^u)`Ta0L!4rzD zoUWY0`Y&?HcwDkjw0OyQZ!(mBYr+Z#LYx#y+s52|D z3KyC6?hUbWCq63>h7aSj^=P5lEGn-71H93%-`AdZWj!A%?hFD9V`2@&Vw;#VekYAI}Yf86AzHZ$!x_$EPC-0_oPr1_q zVBLO=@-JoSkT~ZAv~}Dg^?l|YOZ|8xORx%g)9pFJ?xSU!149=&wqBq<{@4T{?9H{K V{=o&`=Y2u)Cl>n8=l}Q}`v=OlKNJ7} literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/rr_timeout.c b/test/regression/mdns_test/capture/rr_timeout.c new file mode 100644 index 00000000..0911d7ca --- /dev/null +++ b/test/regression/mdns_test/capture/rr_timeout.c @@ -0,0 +1,87 @@ +/* Frame (75 bytes) */ +static const unsigned char pkt1[75] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x3d, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* .=..@... */ +0x90, 0x93, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x29, /* .......) */ +0x66, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* f....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (185 bytes) */ +static const unsigned char pkt2[185] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0xab, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x45, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* .E...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x97, /* ........ */ +0xa2, 0xd5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x14, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0xc0, 0x0c, 0xc0, 0x27, 0x00, /* ver...'. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x01, 0x00, 0xc0, 0x27, 0x00, 0x21, 0x80, 0x01, /* ...'.!.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x0f, 0x00, 0x00, /* ...x.... */ +0x00, 0x00, 0x00, 0x50, 0x06, 0x75, 0x62, 0x75, /* ...P.ubu */ +0x6e, 0x74, 0x75, 0xc0, 0x16, 0xc0, 0x5a, 0x00, /* ntu...Z. */ +0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x01, 0xd4, /* ...).... */ +0x8d, 0xc0, 0x5a, 0x00, 0x01, 0x80, 0x01, 0x00, /* ..Z..... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x01 /* . */ +}; + +/* Frame (129 bytes) */ +static const unsigned char pkt3[129] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x73, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* .s..@... */ +0x90, 0x5c, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* .\...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x5f, /* ......._ */ +0x92, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x00, 0x01, 0x06, 0x75, 0x62, /* ..!...ub */ +0x75, 0x6e, 0x74, 0x75, 0x05, 0x6c, 0x6f, 0x63, /* untu.loc */ +0x61, 0x6c, 0x00, 0x00, 0x1c, 0x00, 0x01, 0x06, /* al...... */ +0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x05, 0x6c, /* ubuntu.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, 0x00, /* ocal.... */ +0x01 /* . */ +}; + +/* Frame (158 bytes) */ +static const unsigned char pkt4[158] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x90, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x60, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* .`...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7c, /* .......| */ +0x3e, 0xb4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* >....... */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x75, /* .......u */ +0x62, 0x75, 0x6e, 0x74, 0x75, 0x05, 0x6c, 0x6f, /* buntu.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, /* ...x.... */ +0x00, 0x01, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* ...Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x04, 0x5f, 0x69, 0x70, /* rver._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x13, /* p._tcp.. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, /* ........ */ +0x29, 0xff, 0xfe, 0x01, 0xd4, 0x8d /* )..... */ +}; + diff --git a/test/regression/mdns_test/capture/rr_timeout.pcapng b/test/regression/mdns_test/capture/rr_timeout.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..f90a5d44c6f20a23e9895519f730b6e8ed400cba GIT binary patch literal 1088 zcmb7D&ubG=5S~powI(Sx7(J9&U#*~_ZcW_HkAjM6l3v6T3>cJPOtM>Cnq=2aHYzGq z@G2H9c=I6Myn4~o9`X+e_N0d#?LQ!b&^Yt5mBy&x!0dao^WJ>le6#DHn({vZfGg)0 zW&~UZu6bbrl8RK*JFKL)RO4=&rC3q3x_Vt>g=&4B#m}&stv6JbO2*jdBkfUTO$G^`Fw z$O)NMTPo8{%mx3mFTBFJQQZawWS>RYzU`mAj9YR6ZUX#(&kB$J#JU~`%)ZBf+{Fq; zg-=g8)>{CMl}9Y0zlZhm_4ZI(@KKdNV?k&O!l9zxG#eT#X*E7y&2oayDVW~CsbF3J z4CW|+dvJ(qL1DtK*{zQ49CdC$#7#}_Ztx^{g3-Y)lEa+f=0u`~S?Y;;qgivq-nPE= z<{x7~KBi+Eyu7#ah>n%#GyJxfKViIq@owipa7piJ9T|HgaE`={I6A}PeAaiq_vT+= zOg^UnrmO$05&a)teCO)VS^fq-BFw+|JBNR1KgkIda5%xgi$3H{Bj5k6_In3T3J`&; tfn(FGHZv`wtE-yIYWJBs{AoRa0634YADzq}V|Zz)n{)?iZ>8x^|`t9(LFZANlfqZ{GL$o<2{L;P`m( zIsg<;O-C8LcHHp8G^7N+u2^JAQ6+87Bx$lJ8*QZ_lX9)GLgL3ry`?lIl1|0qzyc5X z)~ep9=_EdrnTe4ji>bPJ~#o( zd6~9aE|ur2SA|?Ao5|+p`E)@Lc_E#P@w3^a$fsrtF)^7hWD?2LHGmPUG=z0VAq1dn zhDDNzWP;RGi6}a*kNxAB@DUpqt@)JRV4Q!;!s92OA`fs*2Ll%XzCmazkzWcx0pK<; zr=b&CKNJMWzQMilR(K26UVO%6=cstxQE{PI%$F9=$)?3sFIkq(R;`B4HMK^qi9Z4` z12QIU(k?^9u3Fxf?G|w`_hR?o`09n-XJen*o!Bdt?_SvbHulNggZ&H@HU`zqhcEu< zVZ5iKS2IimSc?75y>9Fb_in@S2bv3Gq-r|$Gl#2^YVxMUR$J0<&5Th+gzm$>em(WC zpcS0#gWHtTr$p~v7_7np1twe=;ecM#Wn)ehf^FF_6-}MP{}jp})o(YCw@&W&;*qm? zyt~KaARd1_i+k}nWb?Sb$Ky^sPM|JnP+#9<#OQmR)6wf|*o0x5$5-7v!t2eKuCM*H z%AeecTmQqI;PH<58+Rg%o!tpQdEjs#-&l4~K0ZF$!0(6ykkeYKg;plIp|urBmPq{y fk(>_%9|Uaf&UT(h{O+7S$Kw1~a9wk{Mtl4OVaFO) literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/server_announcement.c b/test/regression/mdns_test/capture/server_announcement.c new file mode 100644 index 00000000..bd89e7e6 --- /dev/null +++ b/test/regression/mdns_test/capture/server_announcement.c @@ -0,0 +1,282 @@ +/* Frame (321 bytes) */ +static const unsigned char pkt1[321] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x33, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* .3..@... */ +0x8f, 0x9e, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x1f, /* ........ */ +0xe5, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* .&...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, /* est._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, /* ocal..AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x15, 0x08, 0x70, 0x61, 0x70, /* .d...pap */ +0x65, 0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, /* er=A4.ve */ +0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, /* rsion=01 */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x1d, 0x0b, 0x41, 0x52, 0x4d, /* .d...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00 /* . */ +}; + +/* Frame (87 bytes) */ +static const unsigned char pkt2[87] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x49, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* .I..@... */ +0x90, 0x87, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x35, /* .......5 */ +0xa1, 0x99, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x1f /* d...... */ +}; + +/* Frame (321 bytes) */ +static const unsigned char pkt3[321] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x33, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* .3..@... */ +0x8f, 0x9c, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x1f, /* ........ */ +0xe5, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* .&...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, /* est._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, /* ocal..AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x15, 0x08, 0x70, 0x61, 0x70, /* .d...pap */ +0x65, 0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, /* er=A4.ve */ +0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, /* rsion=01 */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x1d, 0x0b, 0x41, 0x52, 0x4d, /* .d...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00 /* . */ +}; + +/* Frame (87 bytes) */ +static const unsigned char pkt4[87] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x49, 0x00, 0x04, 0x40, 0x00, 0xff, 0x11, /* .I..@... */ +0x90, 0x85, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x35, /* .......5 */ +0xa1, 0x99, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x1f /* d...... */ +}; + +/* Frame (321 bytes) */ +static const unsigned char pkt5[321] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x33, 0x00, 0x05, 0x40, 0x00, 0xff, 0x11, /* .3..@... */ +0x8f, 0x9a, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x1f, /* ........ */ +0xe5, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* .&...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, /* est._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, /* ocal..AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x15, 0x08, 0x70, 0x61, 0x70, /* .d...pap */ +0x65, 0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, /* er=A4.ve */ +0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, /* rsion=01 */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x1d, 0x0b, 0x41, 0x52, 0x4d, /* .d...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00 /* . */ +}; + +/* Frame (87 bytes) */ +static const unsigned char pkt6[87] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x49, 0x00, 0x06, 0x40, 0x00, 0xff, 0x11, /* .I..@... */ +0x90, 0x83, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x35, /* .......5 */ +0xa1, 0x99, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x1f /* d...... */ +}; + +/* Frame (234 bytes) */ +static const unsigned char pkt7[234] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xdc, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xee, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc8, /* ........ */ +0xf5, 0x0e, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, /* local..A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x15, 0x08, 0x70, 0x61, /* ..d...pa */ +0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, /* per=A4.v */ +0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, /* ersion=0 */ +0x31, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 1.._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x1d, 0x0b, 0x41, 0x52, /* ..d...AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00 /* l. */ +}; + +/* Frame (234 bytes) */ +static const unsigned char pkt8[234] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xdc, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xed, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc8, /* ........ */ +0xf5, 0x0e, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, /* local..A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x15, 0x08, 0x70, 0x61, /* ..d...pa */ +0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, /* per=A4.v */ +0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, /* ersion=0 */ +0x31, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 1.._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x1d, 0x0b, 0x41, 0x52, /* ..d...AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00 /* l. */ +}; + +/* Frame (234 bytes) */ +static const unsigned char pkt9[234] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xdc, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xec, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc8, /* ........ */ +0xf5, 0x0e, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, /* local..A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x15, 0x08, 0x70, 0x61, /* ..d...pa */ +0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, /* per=A4.v */ +0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, /* ersion=0 */ +0x31, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 1.._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x1d, 0x0b, 0x41, 0x52, /* ..d...AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00 /* l. */ +}; + diff --git a/test/regression/mdns_test/capture/server_announcement.pcapng b/test/regression/mdns_test/capture/server_announcement.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..bab8e0ace1663a50e8c5179e9d6d9b6baa0080f8 GIT binary patch literal 2628 zcmeHJ&ui0A9RH?GN85GcU>^KMpB_Y+neCFa8Fa9;=}@7itg>E)rEMaFbxlaq`U|0; z;!zJ?R)^qCy?fT9f5C9F!w@`7RJ;g+hx*=Y2HC2S4G*IG!b{#uzTfZXz0W84z84-D z3Eu<x$FXgYP}Z{4fp)fvf5^D(MZ?xY|TXRMf1tUei#aQd>mvv#8qA>nchnVsT)B z1EsZO)+#27Pe>CnbhWd?%3NY98!!(;?V1^=8?{Ou^AF5#9rh4) zqC?i8!eKg-f*Zm?c0U>fIOxP53YryDv!-Ps+}5n7ZZxKe_yfy`IR3}I)AqR~9ABdo z>vOyw61yclCT%CjZ~=UT;|KTL9E12|8K8sxaR4?q>K3yMeWe2X>M2Ai-cD^d-bh~B z`l+@nZrpusfBhx@T-(l?&D&JcDLHDK2LdRJ4Cg; z?dEvz+D7Pq-me$w8#CPx_^&5zpkAy)kZSvR8}93`c#G&@e^QaR*Neeo_O}*K!U3sa zZZ1|YDqdWKC>Njp4=x@aJ@3Uum~!#)-{c~IzYBbvphnIu?;aUl2980-XfhK&U|{gI(UxKa(*L1=nL(Su%tSXSvqT|0GcP5-yja0pAvm?DEHgP(As{h1 zTftCAA*nPoCq=>B%)pR=g+Z6Wr8Ku7Ik7;&P|rfoKtUro%ugXGwM@ap*u>aSA+0Ds zS3$p|s5CEI7pOoJXcq{8>;~Dp1WNz^&%nUMV8jsPk_xga#xKAvzS_ju!pXwP*-h8n z)x=TP#N63H*V4(SSmEDQxR7I`W1l2IaJBbX18V*$F{G04}~#Ve zCqFqc2N)v^j3~nK86_nJEb%4D1-Mi|H8M7U+*`rG!o|Sggkl6#feciE0J>9A6l2<_ z2-cUvAPIJQ0E%je(I`Tg1_(e65aB3DEJ!V~bu{5BOD!tS%+Iq0CM9q%QeBi)nc+)t%zaW(-m!}-jx&-8dFqZOU4w2=_98D!inaaQpay&{tq;9bQHBBE{ zhDc(wip7C}fdfSXvn-%(VZw@OArAv6*i#tf@H-5@ECbBnssz-rGB7kS0D}P(*Pt>D zInJFfTpo>c1_o+ZAcH#21!F#q#`!Rhb6}ol05;sf0Mu5L7GT$AWRPKS&M(a?0k(4# u3X1Z}GE-7h6p|_xQXq|HCI$|0yVALFwH7m!4bsN~WWxX}5*s82vI79WSLagz literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/capture/server_announcement_with_txt.c b/test/regression/mdns_test/capture/server_announcement_with_txt.c new file mode 100644 index 00000000..378822c4 --- /dev/null +++ b/test/regression/mdns_test/capture/server_announcement_with_txt.c @@ -0,0 +1,276 @@ +/* Frame (269 bytes) */ +static const unsigned char pkt1[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xaf, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt2[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xae, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt3[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xad, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt4[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x04, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x2b, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .+...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt5[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x05, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x2a, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .*...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt6[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x06, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x29, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .)...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + diff --git a/test/regression/mdns_test/capture/server_announcement_with_txt.pcapng b/test/regression/mdns_test/capture/server_announcement_with_txt.pcapng new file mode 100644 index 0000000000000000000000000000000000000000..ee60fff2124192b79f843e6ede1f60b1c353a48b GIT binary patch literal 2604 zcmeHJO=}ZD7=AX{)R;EKVi1&4MxkIEw@u9EqmV*AHu01Y8f`D7A<3>7nr4^HCMqK2 z;7!m!;6?E2$JwLc(VIU&!AtRM5In@0$p)InZt)-r=7rszoq6Yd-+i8WX4dET`yK%( zB!ia(`W)EiMi4Pssx>UK(`c#s-8PAnvSxN0b&Zs&^?ee)Mrxf#Qzh|OC=3x2l+J-s zuNox0mRJjstL5z?+0wd1j>wTPxozqPWZg15t$m3)tk7J{SZa-%$Wibhq%c@``q~F% zKGCtjVc-y7&oA@oE_!#<>e5?JEs)Y_J(sn@GbK5?wOa>ud^v0~MYlRWH+LXXvU z4UZjRT>{~ND2Y|Yzv-TFM=e?s5cbzF}^47bqqE{-&91I*;UHd}%UCahu!(4W@2zUKWg!ER9`fKdN%P+Kefj;~_vM%8 z3j}=k0AToBZ#RRF^+t0;FT{ARAnRycE{n>o85Bo3Nvq0536189Qz(2I6)JK`MDbWC z3@mVvsZ6WIyo$noiM|jznY%oK#-u9ZBYY%`ZfMFh>esbOd5XgWPGMi95#Pk`V&hn^ z1GwM}Ok^bDYGPz`Xz~u9PNWj4^bi-%@=1=5r$gL8Dw^bC1KChAn#m?2(b!#pHf*T{ z+i8b=02NV1s-o#A8i_^#{Cj*JY=*`}>fU|_uDY}?V^LI-Enj{nS(?pqtPP3bgU@O`FN6wnm z96!bhK!oFVg0wT{4;a0+MtcC}Kp-5FT4LmKWB#)hmmbQc-{JD_`=fcee0}h%6_+iP z%XWv$X62H+>q#Ru_U(z*8p7A4@2If{pp|m@*vKXPT)5Dvu`ID-S|#T;UF=olz`qeW z0Hz{m*MbT53Z{S`YP&{KZw_1%yx=jixEFZW0K|9lp3=uY{jLYa_MonY*t-j{9gF>{Gt_? z0m>zn7t4*k8z(QDB`@(;AmEKM+K9#+xKgY!a0t>$rL5yEC!}ghRTd=?6>cMOb0g9P bUaAMKuSeJ1jdL=O#pl19$8b*mBR+ls+yj5d literal 0 HcmV?d00001 diff --git a/test/regression/mdns_test/mdns_address_change_test.c b/test/regression/mdns_test/mdns_address_change_test.c new file mode 100644 index 00000000..04ee3e81 --- /dev/null +++ b/test/regression/mdns_test/mdns_address_change_test.c @@ -0,0 +1,382 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "netx_mdns_test.h" + +/* Frame (269 bytes) */ +static const unsigned char pkt1[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xaf, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt2[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xae, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt3[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xad, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt4[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x04, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x2b, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .+...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt5[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x05, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x2a, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .*...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt6[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x06, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x29, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .)...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (171 bytes) */ +static const unsigned char pkt7[171] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x9d, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x0a, 0x0a, 0x00, 0x00, 0x43, 0xe0, 0x00, /* .....C.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x89, /* ........ */ +0xee, 0x54, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .T...... */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* ......B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x43, /* .x.....C */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, /* ..x...AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x01, 0x40 /* ..@ */ +}; + +/* Frame (138 bytes) */ +static const unsigned char pkt8[138] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x7c, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .|..@... */ +0x90, 0x2a, 0x0a, 0x00, 0x00, 0x43, 0xe0, 0x00, /* .*...C.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x68, /* .......h */ +0xb8, 0x73, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .s...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x43, 0x0b, /* x.....C. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40 /* .@ */ +}; + +/* Frame (138 bytes) */ +static const unsigned char pkt9[138] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x7c, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .|..@... */ +0x90, 0x29, 0x0a, 0x00, 0x00, 0x43, 0xe0, 0x00, /* .)...C.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x68, /* .......h */ +0xb8, 0x73, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .s...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x43, 0x0b, /* x.....C. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40 /* .@ */ +}; + +static MDNS_SERVICE mdns_service = {"ARMMDNSTest", "_http._tcp", NX_NULL, "paper=A4;version=01", 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_address_change[] = { + {TITLE, "Address change", 14, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + + /* Wait the probing and announcement. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt4), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt5[0], sizeof(pkt5), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt6[0], sizeof(pkt6), 2}, + + /* Change ipv4 address. */ + {MDNS_SET_IPV4_ADDRESS, NX_NULL, IP_ADDRESS(10, 0, 0, 67), 0}, + + /* Check the announcement of address. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt7[0], sizeof(pkt7), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt8[0], sizeof(pkt8), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt9[0], sizeof(pkt9), 2}, + + /* Change ipv4 address. */ + {MDNS_SET_IPV4_ADDRESS, NX_NULL, IP_ADDRESS(10, 0, 0, 66), 0}, +}; + +int mdns_address_change_size = sizeof(mdns_address_change) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_announcement_in_multiple_packets_test.c b/test/regression/mdns_test/mdns_announcement_in_multiple_packets_test.c new file mode 100644 index 00000000..de0169d9 --- /dev/null +++ b/test/regression/mdns_test/mdns_announcement_in_multiple_packets_test.c @@ -0,0 +1,2000 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "netx_mdns_test.h" + +/* Frame (1425 bytes) */ +static const unsigned char pkt1[1425] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0x83, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8b, 0x2b, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .+...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x6f, /* .......o */ +0x19, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, /* ........ */ +0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st1._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, /* .test2._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, /* est4._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, /* ocal.... */ +0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t6._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, /* al...... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x38, /* ...test8 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st9._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x06, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* B.test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, 0x04, /* ..test3. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st4._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 5._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, /* test6._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, /* ..test7. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x37, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 7._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 9._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, /* st10._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 11._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, /* est11._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00 /* . */ +}; + +/* Frame (420 bytes) */ +static const unsigned char pkt2[420] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x96, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x17, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x82, /* ........ */ +0x5b, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* [X...... */ +0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x06, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 2._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, /* st12._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 13._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, /* ..d....t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, /* ..test14 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00 /* d... */ +}; + +/* Frame (1425 bytes) */ +static const unsigned char pkt3[1425] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0x83, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8b, 0x29, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .)...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x6f, /* .......o */ +0x19, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, /* ........ */ +0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st1._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, /* .test2._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, /* est4._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, /* ocal.... */ +0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t6._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, /* al...... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x38, /* ...test8 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st9._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x06, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* B.test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, 0x04, /* ..test3. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st4._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 5._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, /* test6._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, /* ..test7. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x37, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 7._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 9._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, /* st10._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 11._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, /* est11._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00 /* . */ +}; + +/* Frame (420 bytes) */ +static const unsigned char pkt4[420] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x96, 0x00, 0x04, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x15, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x82, /* ........ */ +0x5b, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* [X...... */ +0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x06, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 2._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, /* st12._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 13._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, /* ..d....t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, /* ..test14 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00 /* d... */ +}; + +/* Frame (1425 bytes) */ +static const unsigned char pkt5[1425] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0x83, 0x00, 0x05, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8b, 0x27, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .'...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x6f, /* .......o */ +0x19, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, /* ........ */ +0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st1._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, /* .test2._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, /* est4._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, /* ocal.... */ +0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t6._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x05, /* al...... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x05, 0x74, 0x65, 0x73, 0x74, 0x38, /* ...test8 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x05, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st9._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x06, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* B.test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, 0x04, /* ..test3. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st4._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 5._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, /* test6._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, /* ..test7. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x37, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 7._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 9._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, /* st10._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 11._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, /* est11._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00 /* . */ +}; + +/* Frame (420 bytes) */ +static const unsigned char pkt6[420] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x96, 0x00, 0x06, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x13, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x82, /* ........ */ +0x5b, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* [X...... */ +0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x06, 0x74, /* l......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 2._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, /* st12._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 13._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, /* ..d....t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, /* ..test14 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00 /* d... */ +}; + +/* Frame (1510 bytes) */ +static const unsigned char pkt7[1510] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xd8, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xd0, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc4, /* ........ */ +0xa2, 0xee, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, /* .@.test1 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t1._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, /* .test1._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, /* ..test2. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, /* ...@.tes */ +0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t3._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, /* est3._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, /* l..test3 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, /* @.test4. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, /* .....d.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, /* .....x.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, /* .....@.t */ +0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, /* est5._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, /* .test5._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* ..._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, /* ..d...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t5._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 6._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, 0x04, /* ..test6. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* .......@ */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, /* .test7._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, /* l..test7 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* local. */ +}; + +/* Frame (1512 bytes) */ +static const unsigned char pkt8[1512] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xda, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xcd, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc6, /* ........ */ +0xb1, 0xb4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, /* est7._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, /* ocal../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, /* ....x... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 8._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, /* .@.test9 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t9._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, 0x5f, /* .test9._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, /* test10._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x31, /* @.test11 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x18, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x06, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 12._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x18, 0x06, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x06, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, /* st13._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x18, 0x06, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, /* test14._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + +/* Frame (119 bytes) */ +static const unsigned char pkt9[119] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x69, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .i..@... */ +0x90, 0x3d, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .=...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x55, /* .......U */ +0x14, 0x46, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .F...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* ......@ */ +}; + +/* Frame (1510 bytes) */ +static const unsigned char pkt10[1510] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xd8, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xcd, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc4, /* ........ */ +0xa2, 0xee, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, /* .@.test1 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t1._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, /* .test1._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, /* ..test2. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, /* ...@.tes */ +0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t3._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, /* est3._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, /* l..test3 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, /* @.test4. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, /* .....d.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, /* .....x.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, /* .....@.t */ +0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, /* est5._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, /* .test5._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* ..._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, /* ..d...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t5._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 6._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, 0x04, /* ..test6. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* .......@ */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, /* .test7._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, /* l..test7 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* local. */ +}; + +/* Frame (1512 bytes) */ +static const unsigned char pkt11[1512] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xda, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xca, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc6, /* ........ */ +0xb1, 0xb4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, /* est7._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, /* ocal../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, /* ....x... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 8._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, /* .@.test9 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t9._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, 0x5f, /* .test9._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, /* test10._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x31, /* @.test11 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x18, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x06, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 12._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x18, 0x06, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x06, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, /* st13._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x18, 0x06, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, /* test14._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + +/* Frame (119 bytes) */ +static const unsigned char pkt12[119] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x69, 0x00, 0x0c, 0x40, 0x00, 0xff, 0x11, /* .i..@... */ +0x90, 0x3a, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .:...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x55, /* .......U */ +0x14, 0x46, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .F...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* ......@ */ +}; + +/* Frame (1510 bytes) */ +static const unsigned char pkt13[1510] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xd8, 0x00, 0x0d, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xca, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc4, /* ........ */ +0xa2, 0xee, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, /* .@.test1 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t1._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, /* .test1._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, /* test2._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, /* ..test2. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st2._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, /* ...@.tes */ +0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t3._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, /* est3._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, /* l..test3 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, /* @.test4. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, /* .....d.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, /* .....x.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, /* .....@.t */ +0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, /* est5._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, /* .test5._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* ..._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, /* ..d...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t5._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st5._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 6._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st6._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, 0x04, /* ..test6. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, /* ...test6 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* .......@ */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, /* .test7._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, /* l..test7 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* local. */ +}; + +/* Frame (1512 bytes) */ +static const unsigned char pkt14[1512] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xda, 0x00, 0x0e, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xc7, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xc6, /* ........ */ +0xb1, 0xb4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, /* est7._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, /* ocal../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, /* ....x... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 8._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t8._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, /* .@.test9 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t9._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, /* ..d...._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, 0x5f, /* .test9._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, /* test10._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, 0x04, /* .test10. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 0._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x31, /* @.test11 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x04, /* ...d.... */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x18, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t11._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x06, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 12._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x18, 0x06, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, 0x06, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, /* est12._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x06, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, /* st13._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ...._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x18, 0x06, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, /* test14._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* l..test1 */ +0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 4._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, /* .d...._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, /* .....d.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + +/* Frame (119 bytes) */ +static const unsigned char pkt15[119] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x69, 0x00, 0x0f, 0x40, 0x00, 0xff, 0x11, /* .i..@... */ +0x90, 0x37, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .7...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x55, /* .......U */ +0x14, 0x46, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .F...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, /* .test14. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* ......@ */ +}; + + +static MDNS_SERVICE mdns_service1 = {"test1", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service2 = {"test2", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service3 = {"test3", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service4 = {"test4", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service5 = {"test5", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service6 = {"test6", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service7 = {"test7", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service8 = {"test8", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service9 = {"test9", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service10 = {"test10", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service11 = {"test11", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service12 = {"test12", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service13 = {"test13", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service14 = {"test14", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_announcement_in_multiple_packets[] = { + {TITLE, "Announcement in multiple packets", 32, 0}, + + /* Add a service. */ + {MDNS_SERVICE_ADD, (char*)&mdns_service1, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service2, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service3, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service4, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service5, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service6, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service7, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service8, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service9, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service10, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service11, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service12, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service13, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service14, 0, 0}, + + /* Wait for the probings. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt4), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt5[0], sizeof(pkt5), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt6[0], sizeof(pkt6), 1}, + + /* Wait for the announcements. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt7[0], sizeof(pkt7), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt8[0], sizeof(pkt8), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt9[0], sizeof(pkt9), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt10[0], sizeof(pkt10), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt11[0], sizeof(pkt11), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt12[0], sizeof(pkt12), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt13[0], sizeof(pkt13), 2}, + {MDNS_CHECK_DATA_V4, (char*)&pkt14[0], sizeof(pkt14), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt15[0], sizeof(pkt15), 1}, +}; + +int mdns_announcement_in_multiple_packets_size = sizeof(mdns_announcement_in_multiple_packets) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_basic_ipv6_announcement_test.c b/test/regression/mdns_test/mdns_basic_ipv6_announcement_test.c new file mode 100644 index 00000000..e1857921 --- /dev/null +++ b/test/regression/mdns_test/mdns_basic_ipv6_announcement_test.c @@ -0,0 +1,364 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "netx_mdns_test.h" + +/* Frame (334 bytes) */ +static const unsigned char pkt1[334] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x57, 0x86, 0xdd, 0x60, 0x00, /* "3DW..`. */ +0x00, 0x00, 0x01, 0x18, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x57, 0xff, 0x02, /* "..3DW.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x01, 0x18, 0x58, 0xb1, 0x00, 0x00, /* ....X... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, /* ........ */ +0x00, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* ...ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, /* ocal.... */ +0x01, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ....ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0x0a, 0x00, 0x00, 0x42, 0x0b, 0x41, 0x52, 0x4d, /* ...B.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, /* ..."..3D */ +0x57, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* W.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* l..ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, /* ...paper */ +0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, /* =A4.vers */ +0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* ion=01 */ +}; + +/* Frame (334 bytes) */ +static const unsigned char pkt2[334] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x57, 0x86, 0xdd, 0x60, 0x00, /* "3DW..`. */ +0x00, 0x00, 0x01, 0x18, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x57, 0xff, 0x02, /* "..3DW.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x01, 0x18, 0x58, 0xb1, 0x00, 0x00, /* ....X... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, /* ........ */ +0x00, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* ...ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, /* ocal.... */ +0x01, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ....ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0x0a, 0x00, 0x00, 0x42, 0x0b, 0x41, 0x52, 0x4d, /* ...B.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, /* ..."..3D */ +0x57, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* W.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* l..ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, /* ...paper */ +0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, /* =A4.vers */ +0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* ion=01 */ +}; + +/* Frame (334 bytes) */ +static const unsigned char pkt3[334] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x57, 0x86, 0xdd, 0x60, 0x00, /* "3DW..`. */ +0x00, 0x00, 0x01, 0x18, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x57, 0xff, 0x02, /* "..3DW.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x01, 0x18, 0x58, 0xb1, 0x00, 0x00, /* ....X... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, /* ........ */ +0x00, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* ...ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, /* ocal.... */ +0x01, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ....ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0x0a, 0x00, 0x00, 0x42, 0x0b, 0x41, 0x52, 0x4d, /* ...B.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, /* ..."..3D */ +0x57, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* W.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* l..ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, /* ...paper */ +0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, /* =A4.vers */ +0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* ion=01 */ +}; + +/* Frame (466 bytes) */ +static const unsigned char pkt4[466] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x57, 0x86, 0xdd, 0x60, 0x00, /* "3DW..`. */ +0x00, 0x00, 0x01, 0x9c, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x57, 0xff, 0x02, /* "..3DW.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x01, 0x9c, 0x29, 0x22, 0x00, 0x00, /* ....)".. */ +0x84, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* ...ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, /* ....x... */ +0x00, 0x00, 0x42, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..B.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x1c, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x57, /* .."..3DW */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x19, 0x0b, 0x41, 0x52, /* ..x...AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0x0b, 0x41, /* ..@....A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* st._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, /* .local.. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x1e, 0x0b, /* ....d... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, /* ocal..AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x25, 0x0b, 0x41, 0x52, /* ..x.%.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + +/* Frame (466 bytes) */ +static const unsigned char pkt5[466] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x57, 0x86, 0xdd, 0x60, 0x00, /* "3DW..`. */ +0x00, 0x00, 0x01, 0x9c, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x57, 0xff, 0x02, /* "..3DW.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x01, 0x9c, 0x29, 0x22, 0x00, 0x00, /* ....)".. */ +0x84, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* ...ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, /* ....x... */ +0x00, 0x00, 0x42, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..B.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x1c, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x57, /* .."..3DW */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x19, 0x0b, 0x41, 0x52, /* ..x...AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0x0b, 0x41, /* ..@....A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* st._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, /* .local.. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x1e, 0x0b, /* ....d... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, /* ocal..AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x25, 0x0b, 0x41, 0x52, /* ..x.%.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + +/* Frame (466 bytes) */ +static const unsigned char pkt6[466] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x57, 0x86, 0xdd, 0x60, 0x00, /* "3DW..`. */ +0x00, 0x00, 0x01, 0x9c, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x57, 0xff, 0x02, /* "..3DW.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x01, 0x9c, 0x29, 0x22, 0x00, 0x00, /* ....)".. */ +0x84, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* ...ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, /* ....x... */ +0x00, 0x00, 0x42, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..B.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x1c, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, 0x44, 0x57, /* .."..3DW */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x19, 0x0b, 0x41, 0x52, /* ..x...AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0x0b, 0x41, /* ..@....A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* st._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, /* .local.. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x1e, 0x0b, /* ....d... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, /* ocal..AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x25, 0x0b, 0x41, 0x52, /* ..x.%.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + + +static MDNS_SERVICE mdns_service = {"ARMMDNSTest", "_http._tcp", NX_NULL, "paper=A4;version=01", 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_basic_ipv6_announcement[] = { + {TITLE, "Basic IPv6 announcement", 23, 0}, + + /* Add link local address. */ + {MDNS_LLA_ADD, NX_NULL, 0x00000011, 0x22334457}, + {WAIT, NX_NULL, 0, 5}, + + /* Recreate mDNS. */ + {MDNS_RECREATE, "ARMMDNSTest", 0, 0}, + + /* Add service. */ + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + + /* Check probing and announcement. */ + {MDNS_CHECK_DATA_V6, (char*)&pkt1[0], sizeof(pkt1), 1}, + {MDNS_CHECK_DATA_V6, (char*)&pkt2[0], sizeof(pkt2), 1}, + {MDNS_CHECK_DATA_V6, (char*)&pkt3[0], sizeof(pkt3), 1}, + {MDNS_CHECK_DATA_V6, (char*)&pkt4[0], sizeof(pkt4), 1}, + {MDNS_CHECK_DATA_V6, (char*)&pkt5[0], sizeof(pkt5), 1}, + {MDNS_CHECK_DATA_V6, (char*)&pkt6[0], sizeof(pkt6), 2}, + + /* Delete link local address. */ + {MDNS_LLA_DELETE, NX_NULL, 0, 0}, +}; + +int mdns_basic_ipv6_announcement_size = sizeof(mdns_basic_ipv6_announcement) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/mdns_test/mdns_basic_ipv6_query_test.c b/test/regression/mdns_test/mdns_basic_ipv6_query_test.c new file mode 100644 index 00000000..1a404c63 --- /dev/null +++ b/test/regression/mdns_test/mdns_basic_ipv6_query_test.c @@ -0,0 +1,104 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "netx_mdns_test.h" +/* Frame (96 bytes) */ +static const unsigned char pkt1[96] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, /* "3DV..`. */ +0x00, 0x00, 0x00, 0x2a, 0x11, 0xff, 0xfe, 0x80, /* ...*.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0xff, 0x02, /* "..3DV.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x00, 0x2a, 0x68, 0xc4, 0x00, 0x00, /* ...*h... */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (185 bytes) */ +static const unsigned char pkt2[185] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* 33...... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x86, 0xdd, 0x60, 0x00, /* ..z...`. */ +0x00, 0x00, 0x00, 0x83, 0x11, 0x40, 0xfe, 0x80, /* .....@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1e, /* ........ */ +0x8f, 0xff, 0xfe, 0xb1, 0x7a, 0xd4, 0xff, 0x02, /* ....z... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x00, 0x83, 0x30, 0x75, 0x00, 0x00, /* ....0u.. */ +0x84, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, /* .......C */ +0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, /* anonMF45 */ +0x30, 0x30, 0x77, 0xc0, 0x0c, 0x06, 0x72, 0x6f, /* 00w...ro */ +0x75, 0x74, 0x65, 0x72, 0xc0, 0x17, 0x00, 0x1c, /* uter.... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x02, 0x1e, 0x8f, 0xff, 0xfe, 0xb1, 0x7a, 0xd4, /* ......z. */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (155 bytes) */ +static const unsigned char pkt3[155] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, /* "3DV..`. */ +0x00, 0x00, 0x00, 0x65, 0x11, 0xff, 0xfe, 0x80, /* ...e.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0xff, 0x02, /* "..3DV.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x00, 0x65, 0x6c, 0xde, 0x00, 0x00, /* ...el... */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x93, 0x00, 0x1f, 0x0c, 0x43, 0x61, 0x6e, /* .....Can */ +0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* onMF4500 */ +0x77, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* w._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00 /* al. */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_http._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_basic_ipv6_query[] = { + {TITLE, "Basic IPv6 query", 16, 0}, + + /* Add link local address. */ + {MDNS_LLA_ADD, NX_NULL, 0x00000011, 0x22334456}, + {WAIT, NX_NULL, 0, 5}, + + /* Recreate mDNS. */ + {MDNS_RECREATE, "ARMMDNSTest-0", 0, 0}, + + /* Add query. */ + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + + /* Check query. */ + {MDNS_CHECK_DATA_V6, (char*)&pkt1[0], sizeof(pkt1), 3}, + + /* Inject response. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* Check query with known-answer. */ + {MDNS_CHECK_DATA_V6, (char*)&pkt3[0], sizeof(pkt3), 3}, + + /* Delete link local address. */ + {MDNS_LLA_DELETE, NX_NULL, 0, 0}, +}; + +int mdns_basic_ipv6_query_size = sizeof(mdns_basic_ipv6_query) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/mdns_test/mdns_basic_ipv6_response_test.c b/test/regression/mdns_test/mdns_basic_ipv6_response_test.c new file mode 100644 index 00000000..8ab30330 --- /dev/null +++ b/test/regression/mdns_test/mdns_basic_ipv6_response_test.c @@ -0,0 +1,141 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "netx_mdns_test.h" + +/* Frame (96 bytes) */ +static const unsigned char pkt1[96] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0xec, 0x17, /* 33...... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x86, 0xdd, 0x60, 0x00, /* /.....`. */ +0x00, 0x00, 0x00, 0x2a, 0x11, 0xff, 0x20, 0x01, /* ...*.. . */ +0x0d, 0xb1, 0x00, 0x00, 0xf1, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x00, 0x2a, 0xb0, 0x29, 0x00, 0x00, /* ...*.).. */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (466 bytes) */ +static const unsigned char pkt2[466] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x57, 0x86, 0xdd, 0x60, 0x00, /* "3DW..`. */ +0x00, 0x00, 0x01, 0x9c, 0x11, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x57, 0xff, 0x02, /* "..3DW.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x01, 0x9c, 0xa2, 0xa8, 0x00, 0x00, /* ........ */ +0x84, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x1e, 0x0b, 0x41, /* ...d...A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* st._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, /* cal..ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, 0x41, 0x52, /* ....B.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, /* ...."..3 */ +0x44, 0x57, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* DW.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, /* ocal../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x19, 0x0b, /* ....x... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08, /* l...@... */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x0b, 0x41, 0x52, /* on=01.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x25, 0x0b, 0x41, 0x52, /* ..x.%.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + +/* Frame (122 bytes) */ +static const unsigned char pkt3[122] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0xec, 0x17, /* 33...... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x86, 0xdd, 0x60, 0x00, /* /.....`. */ +0x00, 0x00, 0x00, 0x44, 0x11, 0xff, 0x20, 0x01, /* ...D.. . */ +0x0d, 0xb1, 0x00, 0x00, 0xf1, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x00, 0x44, 0x6e, 0x5c, 0x00, 0x00, /* ...Dn\.. */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x64, 0x00, 0x0e, 0x0b, 0x41, 0x52, 0x4d, /* .d...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0xc0, 0x0c /* .. */ +}; + +static MDNS_SERVICE mdns_service = {"ARMMDNSTest", "_http._tcp", NX_NULL, "paper=A4;version=01", 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_basic_ipv6_response[] = { + {TITLE, "Basic IPv6 response", 19, 0}, + + /* Add link local address. */ + {MDNS_LLA_ADD, NX_NULL, 0x00000011, 0x22334457}, + {WAIT, NX_NULL, 0, 5}, + + /* Recreate mDNS. */ + {MDNS_RECREATE, "ARMMDNSTest", 0, 0}, + + /* Add service. */ + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject query. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + + /* Check response. */ + {MDNS_CHECK_DATA_V6, (char*)&pkt2[0], sizeof(pkt2), 3}, + + /* Inject query. */ + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + + /* No response is expected. */ + {N_CHECK, NX_NULL, 0, 1}, + + /* Delete link local address. */ + {MDNS_LLA_DELETE, NX_NULL, 0, 0}, +}; + +int mdns_basic_ipv6_response_size = sizeof(mdns_basic_ipv6_response) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/mdns_test/mdns_case_insensitivity_test.c b/test/regression/mdns_test/mdns_case_insensitivity_test.c new file mode 100644 index 00000000..6c4f2e69 --- /dev/null +++ b/test/regression/mdns_test/mdns_case_insensitivity_test.c @@ -0,0 +1,58 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "netx_mdns_test.h" + +/* Frame (77 bytes) */ +static const unsigned char pkt1[77] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x3f, 0x3d, 0x61, 0x00, 0x00, 0xff, 0x11, /* .?=a.... */ +0xdc, 0x3e, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .>...j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2b, /* .......+ */ +0xba, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .J...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x45, /* RMMDNSTE */ +0x53, 0x54, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* ST.local */ +0x00, 0x00, 0x01, 0x00, 0x01 /* ..... */ +}; + +/* Frame (138 bytes) */ +static const unsigned char pkt2[138] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x7c, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .|..@... */ +0x90, 0x2c, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .,...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x68, /* .......h */ +0xb9, 0x74, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .t...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40 /* .@ */ +}; + + +MDNS_TEST_SEQ mdns_case_insensitivity[] = { + {TITLE, "Case-insensitivity", 18, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject a query with upper-case name. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + + /* Check the response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 1}, +}; + +int mdns_case_insensitivity_size = sizeof(mdns_case_insensitivity) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/mdns_test/mdns_client_passive_test.c b/test/regression/mdns_test/mdns_client_passive_test.c new file mode 100644 index 00000000..271ad60b --- /dev/null +++ b/test/regression/mdns_test/mdns_client_passive_test.c @@ -0,0 +1,244 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "netx_mdns_test.h" + +/* Frame (134 bytes) */ +static const unsigned char pkt1[134] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0x78, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .x..@... */ +0xd9, 0x67, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .g...i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x64, /* .......d */ +0x0c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .O...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0xc0, 0x0c, /* l....... */ +0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x06, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0xc0, /* .ubuntu. */ +0x29, 0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01, 0x00, /* )....... */ +0x00, 0x11, 0x94, 0x00, 0x01, 0x00 /* ...... */ +}; + +/* Frame (134 bytes) */ +static const unsigned char pkt2[134] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0x78, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .x..@... */ +0xd9, 0x67, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .g...i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x64, /* .......d */ +0x0c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .O...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0xc0, 0x0c, /* l....... */ +0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x06, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0xc0, /* .ubuntu. */ +0x29, 0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01, 0x00, /* )....... */ +0x00, 0x11, 0x94, 0x00, 0x01, 0x00 /* ...... */ +}; + +/* Frame (134 bytes) */ +static const unsigned char pkt3[134] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0x78, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .x..@... */ +0xd9, 0x67, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .g...i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x64, /* .......d */ +0x0c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .O...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0xc0, 0x0c, /* l....... */ +0x00, 0x21, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x06, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0xc0, /* .ubuntu. */ +0x29, 0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01, 0x00, /* )....... */ +0x00, 0x11, 0x94, 0x00, 0x01, 0x00 /* ...... */ +}; + +/* Frame (223 bytes) */ +static const unsigned char pkt4[223] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0xd1, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x0e, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbd, /* ........ */ +0xc6, 0xe4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x1e, 0x00, /* ........ */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x0f, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x06, 0x75, 0x62, /* ....P.ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x29, 0xc0, 0x5b, /* untu.).[ */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x01, /* ....)... */ +0xd4, 0x79, 0xc0, 0x5b, 0x00, 0x01, 0x80, 0x01, /* .y.[.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x69, 0x09, 0x5f, 0x73, 0x65, 0x72, 0x76, /* .i._serv */ +0x69, 0x63, 0x65, 0x73, 0x07, 0x5f, 0x64, 0x6e, /* ices._dn */ +0x73, 0x2d, 0x73, 0x64, 0x04, 0x5f, 0x75, 0x64, /* s-sd._ud */ +0x70, 0xc0, 0x29, 0x00, 0x0c, 0x00, 0x01, 0x00, /* p.)..... */ +0x00, 0x11, 0x94, 0x00, 0x02, 0xc0, 0x1e /* ....... */ +}; + +/* Frame (223 bytes) */ +static const unsigned char pkt5[223] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0xd1, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x0e, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbd, /* ........ */ +0xc6, 0xe4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x1e, 0x00, /* ........ */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x0f, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x06, 0x75, 0x62, /* ....P.ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x29, 0xc0, 0x5b, /* untu.).[ */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x01, /* ....)... */ +0xd4, 0x79, 0xc0, 0x5b, 0x00, 0x01, 0x80, 0x01, /* .y.[.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x69, 0x09, 0x5f, 0x73, 0x65, 0x72, 0x76, /* .i._serv */ +0x69, 0x63, 0x65, 0x73, 0x07, 0x5f, 0x64, 0x6e, /* ices._dn */ +0x73, 0x2d, 0x73, 0x64, 0x04, 0x5f, 0x75, 0x64, /* s-sd._ud */ +0x70, 0xc0, 0x29, 0x00, 0x0c, 0x00, 0x01, 0x00, /* p.)..... */ +0x00, 0x11, 0x94, 0x00, 0x02, 0xc0, 0x1e /* ....... */ +}; + +/* Frame (223 bytes) */ +static const unsigned char pkt6[223] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0xd1, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x0e, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbd, /* ........ */ +0xc6, 0xe4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x1e, 0x00, /* ........ */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x0f, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x06, 0x75, 0x62, /* ....P.ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x29, 0xc0, 0x5b, /* untu.).[ */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x01, /* ....)... */ +0xd4, 0x79, 0xc0, 0x5b, 0x00, 0x01, 0x80, 0x01, /* .y.[.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x69, 0x09, 0x5f, 0x73, 0x65, 0x72, 0x76, /* .i._serv */ +0x69, 0x63, 0x65, 0x73, 0x07, 0x5f, 0x64, 0x6e, /* ices._dn */ +0x73, 0x2d, 0x73, 0x64, 0x04, 0x5f, 0x75, 0x64, /* s-sd._ud */ +0x70, 0xc0, 0x29, 0x00, 0x0c, 0x00, 0x01, 0x00, /* p.)..... */ +0x00, 0x11, 0x94, 0x00, 0x02, 0xc0, 0x1e /* ....... */ +}; + +/* Frame (223 bytes) */ +static const unsigned char pkt7[223] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0xd1, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x0e, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbd, /* ........ */ +0x6e, 0xb6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* n....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0xc0, 0x23, 0xc0, 0x34, 0x00, 0x0c, 0x00, /* p.#.4... */ +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x11, /* ........ */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0xc0, 0x34, 0xc0, 0x4d, 0x00, 0x21, 0x80, /* r.4.M.!. */ +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x06, 0x75, 0x62, /* ....P.ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x23, 0xc0, 0x73, /* untu.#.s */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x01, /* ....)... */ +0xd4, 0x79, 0xc0, 0x73, 0x00, 0x01, 0x80, 0x01, /* .y.s.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x69, 0xc0, 0x4d, 0x00, 0x10, 0x80, 0x01, /* .i.M.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 /* ....... */ +}; + +/* Frame (107 bytes) */ +static const unsigned char pkt8[107] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x5d, 0x13, 0xc0, 0x00, 0x00, 0xff, 0x11, /* .]...... */ +0x06, 0x28, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* .(...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x49, /* .......I */ +0x79, 0x60, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* y`...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x0d, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0xc0, 0x23 /* p.# */ +}; + +MDNS_RR_DATA mdns_rr_data[] = { + {"Simple Web Server", "_http._tcp", "local"}, +}; + +MDNS_TEST_SEQ mdns_client_passive[] = { + {TITLE, "Client passive", 14, 0}, + + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 0, 0}, + {INJECT, (char*)&pkt4[0], sizeof(pkt4), 0}, + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 6, 0}, + {MDNS_CHECK_RR_DATA, (char*)mdns_rr_data, 1, 0}, + {INJECT, (char*)&pkt5[0], sizeof(pkt5), 0}, + {INJECT, (char*)&pkt6[0], sizeof(pkt6), 0}, + {MDNS_CHECK_RR_DATA, (char*)mdns_rr_data, 1, 0}, + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 6, 0}, + {INJECT, (char*)&pkt7[0], sizeof(pkt7), 0}, + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 6, 0}, + {WAIT, NX_NULL, 0, 1}, + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 2, 0}, + {INJECT, (char*)&pkt8[0], sizeof(pkt8), 0}, + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 3, 0}, +}; + +int mdns_client_passive_size = sizeof(mdns_client_passive) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/mdns_test/mdns_continuous_query_interval_test.c b/test/regression/mdns_test/mdns_continuous_query_interval_test.c new file mode 100644 index 00000000..220b2fbe --- /dev/null +++ b/test/regression/mdns_test/mdns_continuous_query_interval_test.c @@ -0,0 +1,174 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "netx_mdns_test.h" + +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (153 bytes) */ +static const unsigned char pkt2[153] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x7e, 0xd1, 0x00, 0x00, 0xff, 0x11, /* ..~..... */ +0x9a, 0xe8, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt3[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x85, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt4[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x84, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt5[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x83, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x8d, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt6[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x82, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x85, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_http._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_continuous_query_interval[] = { + {TITLE, "Continuous query interval", 25, 0}, + + /* Waiting for probing and announcing. */ + {WAIT, NX_NULL, 0, 5}, + + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Check the first query. */ + /* Interval between 20-120ms. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 1}, + {MDNS_TIMER_CHECK, NX_NULL, 5, 7}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Inject response. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* Check query with known answer. */ + /* The first two queries MUST be at least one second. */ + /* Interval 1s. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 1}, + {MDNS_TIMER_CHECK, NX_NULL, 3, 100}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Interval 2s. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt3), 2}, + {MDNS_TIMER_CHECK, NX_NULL, 3, 200}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Interval 4s. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt5[0], sizeof(pkt3), 4}, + {MDNS_TIMER_CHECK, NX_NULL, 3, 400}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Interval 8s. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt6[0], sizeof(pkt3), 8}, + {MDNS_TIMER_CHECK, NX_NULL, 3, 800}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, +}; + +int mdns_continuous_query_interval_size = sizeof(mdns_continuous_query_interval) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/mdns_test/mdns_continuous_query_test.c b/test/regression/mdns_test/mdns_continuous_query_test.c new file mode 100644 index 00000000..a981f089 --- /dev/null +++ b/test/regression/mdns_test/mdns_continuous_query_test.c @@ -0,0 +1,150 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "netx_mdns_test.h" +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (153 bytes) */ +static const unsigned char pkt2[153] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x7e, 0xd1, 0x00, 0x00, 0xff, 0x11, /* ..~..... */ +0x9a, 0xe8, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt3[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x85, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt4[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x84, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt5[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x83, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x8d, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt6[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x82, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x85, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_http._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_continuous_query[] = { + {TITLE, "Continuous query", 16, 0}, + + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + + /* Check query. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 1}, + + /* Inject response. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* Check query with known answer. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt3), 2}, + {MDNS_CHECK_DATA_V4, (char*)&pkt5[0], sizeof(pkt3), 4}, + {MDNS_CHECK_DATA_V4, (char*)&pkt6[0], sizeof(pkt3), 8}, +}; + +int mdns_continuous_query_size = sizeof(mdns_continuous_query) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/mdns_test/mdns_continuous_query_unique_answer_test.c b/test/regression/mdns_test/mdns_continuous_query_unique_answer_test.c new file mode 100644 index 00000000..4e72ce74 --- /dev/null +++ b/test/regression/mdns_test/mdns_continuous_query_unique_answer_test.c @@ -0,0 +1,84 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "netx_mdns_test.h" + +/* Frame (85 bytes) */ +static const unsigned char pkt1[85] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x47, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .G..@... */ +0x90, 0x61, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .a...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x33, /* .......3 */ +0xd8, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x43, /* .......C */ +0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, 0x43, /* henbo-PC */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01 /* ..... */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt2[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x33, 0xc1, 0xbd, 0x08, 0x00, 0x45, 0x00, /* s3....E. */ +0x00, 0xff, 0x17, 0x8d, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0x01, 0x51, 0xc0, 0xa8, 0x00, 0x6c, 0xe0, 0x00, /* .Q...l.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x67, 0xea, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* g....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x09, 0x43, /* .......C */ +0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, 0x43, /* henbo-PC */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x78, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x01, /* x....... */ +0xbd, 0x09, 0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, /* ..Chenbo */ +0x2d, 0x50, 0x43, 0xc0, 0x20, 0xc0, 0x0c, 0x00, /* -PC. ... */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x23, 0x11, 0x6e, 0x65, 0x74, 0x62, 0x69, 0x6f, /* #.netbio */ +0x73, 0x3d, 0x43, 0x48, 0x45, 0x4e, 0x42, 0x4f, /* s=CHENBO */ +0x2d, 0x50, 0x43, 0x10, 0x64, 0x6f, 0x6d, 0x61, /* -PC.doma */ +0x69, 0x6e, 0x3d, 0x57, 0x4f, 0x52, 0x4b, 0x47, /* in=WORKG */ +0x52, 0x4f, 0x55, 0x50, 0xc0, 0x37, 0x00, 0x01, /* ROUP.7.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x6c, 0xc0, 0x37, 0x00, 0x1c, /* ...l.7.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, /* .......1 */ +0xc0, 0x37, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, /* .7...... */ +0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, /* .x...... */ +0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x44, 0x79, /* .....YDy */ +0xe1, 0x0a, 0xd7, 0xf4, 0xc0, 0x37, 0x00, 0x2f, /* .....7./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x37, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08, /* .7..@... */ +0xc0, 0x0c, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* .../.... */ +0x00, 0x78, 0x00, 0x09, 0xc0, 0x0c, 0x00, 0x05, /* .x...... */ +0x00, 0x00, 0x80, 0x00, 0x40 /* ....@ */ +}; + +static MDNS_QUERY_INFO mdns_query = {"Chenbo-PC", "_smb._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_continuous_query_unique_answer[] = { + {TITLE, "Continuous query unique answer", 30, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 5}, + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* No more queries are expected. */ + {MDNS_REJECT_ANY_V4, NX_NULL, MDNS_FLAG_QUERY, 2}, + + /* Delete the query. */ + {MDNS_QUERY_DELETE, NX_NULL, 0, 0}, + + /* Since we have known a unique answer, no more queries are expected. */ + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + {MDNS_REJECT_ANY_V4, NX_NULL, MDNS_FLAG_QUERY, 2}, +}; + +int mdns_continuous_query_unique_answer_size = sizeof(mdns_continuous_query_unique_answer) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/mdns_test/mdns_dns_sd_query_test.c b/test/regression/mdns_test/mdns_dns_sd_query_test.c new file mode 100644 index 00000000..eb0f0c7f --- /dev/null +++ b/test/regression/mdns_test/mdns_dns_sd_query_test.c @@ -0,0 +1,386 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "netx_mdns_test.h" + +/* Frame (88 bytes) */ +static const unsigned char pkt1[88] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x4a, 0x58, 0x5c, 0x00, 0x00, 0xff, 0x11, /* .JX\.... */ +0xc1, 0x3e, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .>...d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x36, /* .......6 */ +0xa2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .O...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (88 bytes) */ +static const unsigned char pkt2[88] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4a, 0x02, 0xe1, 0x00, 0x00, 0xff, 0x11, /* .J...... */ +0xcd, 0xc4, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x36, /* .......6 */ +0xb4, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (106 bytes) */ +static const unsigned char pkt3[106] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x33, 0xc1, 0xbd, 0x08, 0x00, 0x45, 0x00, /* s3....E. */ +0x00, 0x5c, 0x1e, 0xf3, 0x00, 0x00, 0xff, 0x11, /* .\...... */ +0xfa, 0x92, 0xc0, 0xa8, 0x00, 0x67, 0xe0, 0x00, /* .....g.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x48, /* .......H */ +0x0a, 0xee, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x0c, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0xc0, 0x23 /* .# */ +}; + +/* Frame (114 bytes) */ +static const unsigned char pkt4[114] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xe8, 0x39, /* ..^....9 */ +0x35, 0x44, 0xfe, 0xd4, 0x08, 0x00, 0x45, 0x00, /* 5D....E. */ +0x00, 0x64, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .d..@... */ +0xd9, 0xe2, 0xc0, 0xa8, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x50, /* .......P */ +0x42, 0x75, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* Bu...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x14, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0xc0, 0x23 /* .# */ +}; + +/* Frame (160 bytes) */ +static const unsigned char pkt5[160] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x92, 0x17, 0x39, 0x00, 0x00, 0xff, 0x11, /* ...9.... */ +0x02, 0x7a, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* .z...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7e, /* .......~ */ +0xbc, 0x15, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x17, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0xc0, 0x23, 0xc0, 0x0c, 0x00, /* tcp.#... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0b, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, /* .._print */ +0x65, 0x72, 0xc0, 0x44, 0xc0, 0x0c, 0x00, 0x0c, /* er.D.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x08, /* ........ */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0xc0, 0x44 /* ._http.D */ +}; + +/* Frame (219 bytes) */ +static const unsigned char pkt6[219] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0xcd, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x23, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* .#...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xb9, /* ........ */ +0x69, 0x6d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* im...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x14, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0xc0, 0x23, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* .#...... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x65, 0xc0, 0x41, 0xc0, /* teste.A. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, /* ...._tes */ +0x74, 0x64, 0xc0, 0x41, 0xc0, 0x0c, 0x00, 0x0c, /* td.A.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x09, /* ........ */ +0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x63, 0xc0, /* ._testc. */ +0x41, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* A....... */ +0x00, 0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, /* ......_t */ +0x65, 0x73, 0x74, 0x62, 0xc0, 0x41, 0xc0, 0x0c, /* estb.A.. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, /* ..._test */ +0x61, 0xc0, 0x41 /* a.A */ +}; + +/* Frame (212 bytes) */ +static const unsigned char pkt7[212] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0xc6, 0x58, 0x8e, 0x00, 0x00, 0xff, 0x11, /* ..X..... */ +0xc0, 0x90, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .....d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xb2, /* ........ */ +0xa2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x93, 0x00, 0x0c, 0x04, 0x5f, 0x73, 0x6d, /* ....._sm */ +0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* b._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x0f, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0xc0, 0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* n.?..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x12, 0x0f, /* ........ */ +0x5f, 0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, /* _pdl-dat */ +0x61, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xc0, /* astream. */ +0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ?....... */ +0x00, 0x11, 0x94, 0x00, 0x0b, 0x08, 0x5f, 0x70, /* ......_p */ +0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0xc0, 0x3f, /* rinter.? */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x08, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0xc0, 0x3f /* tp.? */ +}; + +/* Frame (225 bytes) */ +static const unsigned char pkt8[225] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0xd3, 0x02, 0xe2, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0xcd, 0x3a, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* .:...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbf, /* ........ */ +0x1b, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .:...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x14, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* n._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, /* ....._te */ +0x73, 0x74, 0x65, 0xc0, 0x47, 0xc0, 0x0c, 0x00, /* ste.G... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x64, /* .._testd */ +0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* .G...... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x63, 0xc0, 0x47, 0xc0, /* testc.G. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, /* ...._tes */ +0x74, 0x62, 0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, /* tb.G.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x09, /* ........ */ +0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x61, 0xc0, /* ._testa. */ +0x47 /* G */ +}; + +/* Frame (212 bytes) */ +static const unsigned char pkt9[212] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0xc6, 0x58, 0xcf, 0x00, 0x00, 0xff, 0x11, /* ..X..... */ +0xc0, 0x4f, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .O...d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xb2, /* ........ */ +0xa2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x90, 0x00, 0x0c, 0x04, 0x5f, 0x73, 0x6d, /* ....._sm */ +0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* b._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x0f, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0xc0, 0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* n.?..... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x12, 0x0f, /* ........ */ +0x5f, 0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, /* _pdl-dat */ +0x61, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xc0, /* astream. */ +0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ?....... */ +0x00, 0x11, 0x91, 0x00, 0x0b, 0x08, 0x5f, 0x70, /* ......_p */ +0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0xc0, 0x3f, /* rinter.? */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x08, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0xc0, 0x3f /* tp.? */ +}; + +/* Frame (225 bytes) */ +static const unsigned char pkt10[225] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0xd3, 0x02, 0xe3, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0xcd, 0x39, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* .9...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbf, /* ........ */ +0x21, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* !F...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x14, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* n._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, /* ....._te */ +0x73, 0x74, 0x65, 0xc0, 0x47, 0xc0, 0x0c, 0x00, /* ste.G... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x64, /* .._testd */ +0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* .G...... */ +0x00, 0x00, 0x11, 0x91, 0x00, 0x09, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x63, 0xc0, 0x47, 0xc0, /* testc.G. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, /* ...._tes */ +0x74, 0x62, 0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, /* tb.G.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x09, /* ........ */ +0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x61, 0xc0, /* ._testa. */ +0x47 /* G */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt11[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x59, 0x32, 0x00, 0x00, 0xff, 0x11, /* .ZY2.... */ +0xbf, 0x58, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .X...d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0xa3, 0x5f, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ._...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x64, 0x03, 0x31, 0x30, 0x30, /* ...d.100 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (136 bytes) */ +static const unsigned char pkt12[136] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7a, 0x02, 0xe4, 0x00, 0x00, 0xff, 0x11, /* .z...... */ +0xcd, 0x91, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x66, /* .......f */ +0x82, 0x29, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .)...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0x0a, 0x00, 0x00, 0x02, 0x01, 0x32, 0x01, 0x30, /* .....2.0 */ +0x01, 0x30, 0x02, 0x31, 0x30, 0x07, 0x69, 0x6e, /* .0.10.in */ +0x2d, 0x61, 0x64, 0x64, 0x72, 0x04, 0x61, 0x72, /* -addr.ar */ +0x70, 0x61, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, /* pa...... */ +0x00, 0x00, 0x78, 0x00, 0x02, 0xc0, 0x0c, 0xc0, /* ..x..... */ +0x0c, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x05, 0xc0, 0x0c, 0x00, 0x01, 0x40 /* x......@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt13[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x45, 0x59, 0xc5, 0x00, 0x00, 0xff, 0x11, /* .EY..... */ +0xbf, 0xda, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .....d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xa2, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .J...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt14[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x02, 0xe5, 0x00, 0x00, 0xff, 0x11, /* .E...... */ +0xcd, 0xc5, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0x95, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .L...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, NX_NULL, NX_NULL}; + +MDNS_TEST_SEQ mdns_dns_sd_query[] = { + {TITLE, "DNS-SD query", 12, 0}, + + /* Wait 5 seconds. */ + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Add query. */ + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + + /* Check query. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 3}, + + /* Inject response. */ + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + {INJECT, (char*)&pkt4[0], sizeof(pkt4), 0}, + {INJECT, (char*)&pkt5[0], sizeof(pkt5), 0}, + {INJECT, (char*)&pkt6[0], sizeof(pkt6), 0}, + + /* Check RR count. */ + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 10, 0}, +}; + +int mdns_dns_sd_query_size = sizeof(mdns_dns_sd_query) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_dns_sd_response_test.c b/test/regression/mdns_test/mdns_dns_sd_response_test.c new file mode 100644 index 00000000..6688e6eb --- /dev/null +++ b/test/regression/mdns_test/mdns_dns_sd_response_test.c @@ -0,0 +1,381 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (88 bytes) */ +static const unsigned char pkt1[88] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x4a, 0x58, 0x5c, 0x00, 0x00, 0xff, 0x11, /* .JX\.... */ +0xc1, 0x3e, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .>...d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x36, /* .......6 */ +0xa2, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .O...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (88 bytes) */ +static const unsigned char pkt2[88] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4a, 0x02, 0xe1, 0x00, 0x00, 0xff, 0x11, /* .J...... */ +0xcd, 0xc4, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x36, /* .......6 */ +0xb4, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (106 bytes) */ +static const unsigned char pkt3[106] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x33, 0xc1, 0xbd, 0x08, 0x00, 0x45, 0x00, /* s3....E. */ +0x00, 0x5c, 0x1e, 0xf3, 0x00, 0x00, 0xff, 0x11, /* .\...... */ +0xfa, 0x92, 0xc0, 0xa8, 0x00, 0x67, 0xe0, 0x00, /* .....g.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x48, /* .......H */ +0x0a, 0xee, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x0c, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0xc0, 0x23 /* .# */ +}; + +/* Frame (114 bytes) */ +static const unsigned char pkt4[114] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xe8, 0x39, /* ..^....9 */ +0x35, 0x44, 0xfe, 0xd4, 0x08, 0x00, 0x45, 0x00, /* 5D....E. */ +0x00, 0x64, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .d..@... */ +0xd9, 0xe2, 0xc0, 0xa8, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x50, /* .......P */ +0x42, 0x75, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* Bu...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x14, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0xc0, 0x23 /* .# */ +}; + +/* Frame (160 bytes) */ +static const unsigned char pkt5[160] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x92, 0x17, 0x39, 0x00, 0x00, 0xff, 0x11, /* ...9.... */ +0x02, 0x7a, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* .z...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7e, /* .......~ */ +0xbc, 0x15, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x17, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0xc0, 0x23, 0xc0, 0x0c, 0x00, /* tcp.#... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0b, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, /* .._print */ +0x65, 0x72, 0xc0, 0x44, 0xc0, 0x0c, 0x00, 0x0c, /* er.D.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x08, /* ........ */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0xc0, 0x44 /* ._http.D */ +}; + +/* Frame (219 bytes) */ +static const unsigned char pkt6[219] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0xcd, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x23, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* .#...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xb9, /* ........ */ +0x69, 0x6d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* im...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x14, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0xc0, 0x23, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* .#...... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x65, 0xc0, 0x41, 0xc0, /* teste.A. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, /* ...._tes */ +0x74, 0x64, 0xc0, 0x41, 0xc0, 0x0c, 0x00, 0x0c, /* td.A.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x09, /* ........ */ +0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x63, 0xc0, /* ._testc. */ +0x41, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* A....... */ +0x00, 0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, /* ......_t */ +0x65, 0x73, 0x74, 0x62, 0xc0, 0x41, 0xc0, 0x0c, /* estb.A.. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, /* ..._test */ +0x61, 0xc0, 0x41 /* a.A */ +}; + +/* Frame (212 bytes) */ +static const unsigned char pkt7[212] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0xc6, 0x58, 0x8e, 0x00, 0x00, 0xff, 0x11, /* ..X..... */ +0xc0, 0x90, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .....d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xb2, /* ........ */ +0xa2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x93, 0x00, 0x0c, 0x04, 0x5f, 0x73, 0x6d, /* ....._sm */ +0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* b._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x0f, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0xc0, 0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* n.?..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x12, 0x0f, /* ........ */ +0x5f, 0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, /* _pdl-dat */ +0x61, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xc0, /* astream. */ +0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ?....... */ +0x00, 0x11, 0x94, 0x00, 0x0b, 0x08, 0x5f, 0x70, /* ......_p */ +0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0xc0, 0x3f, /* rinter.? */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x08, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0xc0, 0x3f /* tp.? */ +}; + +/* Frame (225 bytes) */ +static const unsigned char pkt8[225] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0xd3, 0x02, 0xe2, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0xcd, 0x3a, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* .:...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbf, /* ........ */ +0x1b, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .:...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x14, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* n._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, /* ....._te */ +0x73, 0x74, 0x65, 0xc0, 0x47, 0xc0, 0x0c, 0x00, /* ste.G... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x64, /* .._testd */ +0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* .G...... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x09, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x63, 0xc0, 0x47, 0xc0, /* testc.G. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, /* ...._tes */ +0x74, 0x62, 0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, /* tb.G.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x09, /* ........ */ +0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x61, 0xc0, /* ._testa. */ +0x47 /* G */ +}; + +/* Frame (212 bytes) */ +static const unsigned char pkt9[212] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0xc6, 0x58, 0xcf, 0x00, 0x00, 0xff, 0x11, /* ..X..... */ +0xc0, 0x4f, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .O...d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xb2, /* ........ */ +0xa2, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x90, 0x00, 0x0c, 0x04, 0x5f, 0x73, 0x6d, /* ....._sm */ +0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* b._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x0f, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0xc0, 0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* n.?..... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x12, 0x0f, /* ........ */ +0x5f, 0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, /* _pdl-dat */ +0x61, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xc0, /* astream. */ +0x3f, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ?....... */ +0x00, 0x11, 0x91, 0x00, 0x0b, 0x08, 0x5f, 0x70, /* ......_p */ +0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0xc0, 0x3f, /* rinter.? */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x08, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0xc0, 0x3f /* tp.? */ +}; + +/* Frame (225 bytes) */ +static const unsigned char pkt10[225] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0xd3, 0x02, 0xe3, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0xcd, 0x39, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* .9...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbf, /* ........ */ +0x21, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* !F...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x14, 0x0c, 0x5f, 0x77, 0x6f, /* ....._wo */ +0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, /* rkstatio */ +0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23, /* n._tcp.# */ +0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x91, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, /* ....._te */ +0x73, 0x74, 0x65, 0xc0, 0x47, 0xc0, 0x0c, 0x00, /* ste.G... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x64, /* .._testd */ +0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* .G...... */ +0x00, 0x00, 0x11, 0x91, 0x00, 0x09, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x63, 0xc0, 0x47, 0xc0, /* testc.G. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x09, 0x06, 0x5f, 0x74, 0x65, 0x73, /* ...._tes */ +0x74, 0x62, 0xc0, 0x47, 0xc0, 0x0c, 0x00, 0x0c, /* tb.G.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x09, /* ........ */ +0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x61, 0xc0, /* ._testa. */ +0x47 /* G */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt11[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x59, 0x32, 0x00, 0x00, 0xff, 0x11, /* .ZY2.... */ +0xbf, 0x58, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .X...d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0xa3, 0x5f, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ._...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x64, 0x03, 0x31, 0x30, 0x30, /* ...d.100 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (136 bytes) */ +static const unsigned char pkt12[136] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7a, 0x02, 0xe4, 0x00, 0x00, 0xff, 0x11, /* .z...... */ +0xcd, 0x91, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x66, /* .......f */ +0x82, 0x29, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .)...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0x0a, 0x00, 0x00, 0x02, 0x01, 0x32, 0x01, 0x30, /* .....2.0 */ +0x01, 0x30, 0x02, 0x31, 0x30, 0x07, 0x69, 0x6e, /* .0.10.in */ +0x2d, 0x61, 0x64, 0x64, 0x72, 0x04, 0x61, 0x72, /* -addr.ar */ +0x70, 0x61, 0x00, 0x00, 0x0c, 0x80, 0x01, 0x00, /* pa...... */ +0x00, 0x00, 0x78, 0x00, 0x02, 0xc0, 0x0c, 0xc0, /* ..x..... */ +0x0c, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x05, 0xc0, 0x0c, 0x00, 0x01, 0x40 /* x......@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt13[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x45, 0x59, 0xc5, 0x00, 0x00, 0xff, 0x11, /* .EY..... */ +0xbf, 0xda, 0xc0, 0xa8, 0x00, 0x64, 0xe0, 0x00, /* .....d.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xa2, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .J...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt14[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x02, 0xe5, 0x00, 0x00, 0xff, 0x11, /* .E...... */ +0xcd, 0xc5, 0x0a, 0x00, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0x95, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .L...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +static MDNS_SERVICE mdns_service = {"Simple Web Server", "_workstation._tcp", NX_NULL, "paper=A4;version=01", 4500, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_dns_sd_response[] = { + {TITLE, "DNS-SD response", 15, 0}, + + /* Add service. */ + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + + /* Wait 5 seconds. */ + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject a query. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* Check response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt4), 1}, +}; + +int mdns_dns_sd_response_size = sizeof(mdns_dns_sd_response) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_duplicate_answer_suppression_test.c b/test/regression/mdns_test/mdns_duplicate_answer_suppression_test.c new file mode 100644 index 00000000..78cb7bd4 --- /dev/null +++ b/test/regression/mdns_test/mdns_duplicate_answer_suppression_test.c @@ -0,0 +1,96 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (75 bytes) */ +static const unsigned char pkt1[75] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x3d, 0x01, 0x81, 0x00, 0x00, 0xff, 0x11, /* .=...... */ +0x11, 0x81, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x29, /* .......) */ +0xa9, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .&...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (110 bytes) */ +static const unsigned char pkt2[110] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x60, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .g..@... */ +0x90, 0x47, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .@...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4c, /* .......S */ +0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .9...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ......d. */ +0x1d, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* STest._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* local... */ +}; + +/* Frame (110 bytes) */ +static const unsigned char pkt3[110] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x60, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .g..@... */ +0x90, 0x47, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .@...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4c, /* .......S */ +0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .9...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, /* ......d. */ +0x1d, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* STest._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* local... */ +}; + +static MDNS_SERVICE mdns_service = {"ARMMDNSTest", "_ipp._tcp", NX_NULL, NX_NULL, 4500, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_duplicate_answer_suppression[] = { + {TITLE, "Duplicate answer suppression", 28, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject query. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + + /* Check response. */ + {MDNS_CHECK_ANY_V4, NX_NULL, MDNS_FLAG_RESPONSE, 1}, + + {WAIT, NX_NULL, 0, 3}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject query and response. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* No response should be received. */ + {MDNS_REJECT_ANY_V4, NX_NULL, MDNS_FLAG_RESPONSE, 1}, + + {WAIT, NX_NULL, 0, 3}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject query and response. The TTL in response is 100 which is less than 101. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + + /* Expect a response. */ + {MDNS_CHECK_ANY_V4, NX_NULL, MDNS_FLAG_RESPONSE, 1} +}; + +int mdns_duplicate_answer_suppression_size = sizeof(mdns_duplicate_answer_suppression) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_duplicate_question_suppression_test.c b/test/regression/mdns_test/mdns_duplicate_question_suppression_test.c new file mode 100644 index 00000000..232fa983 --- /dev/null +++ b/test/regression/mdns_test/mdns_duplicate_question_suppression_test.c @@ -0,0 +1,251 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + + +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (76 bytes) */ +static const unsigned char pkt2[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (76 bytes) */ +static const unsigned char pkt2_1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xac, 0xf6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x80, 0x01 /* .... */ +}; + +/* Frame (76 bytes) */ +static const unsigned char pkt3[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc0, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (76 bytes) */ +static const unsigned char pkt4[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xbf, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (153 bytes) */ +static const unsigned char pkt5[153] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0xe6, 0x7f, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0x33, 0x3a, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* 3:...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt6[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x83, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x90, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + + +/* Frame (135 bytes) */ +static const unsigned char pkt7[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x83, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x90, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + + +/* Frame (135 bytes) */ +static const unsigned char pkt8[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x82, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + + +/* Frame (76 bytes) */ +static const unsigned char pkt9[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + + +/* Frame (135 bytes) */ +static const unsigned char pkt10[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0c, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x81, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1,...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x78, 0x00, 0x1f, /* .....x.. */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_http._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_duplicate_question_suppression[] = { + {TITLE, "Duplicate question suppression", 30, 0}, + + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + + /* Check query. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 1}, + + /* Inject a duplicate question. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* The query after 1 seconds should not be sent. */ + {MDNS_REJECT_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 1}, + + /* Inject a duplicate question with QU set. It doesn't affact the query. */ + {INJECT, (char*)&pkt2_1[0], sizeof(pkt2_1), 0}, + + /* Inject a duplicate question with known answer. */ + /* It should not affect queriy. */ + {INJECT, (char*)&pkt7[0], sizeof(pkt7), 0}, + + /* Interval 2s. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt4), 2}, + + /* Inject response. */ + {INJECT, (char*)&pkt5[0], sizeof(pkt5), 0}, + + /* Check query with known answer. */ + /* Interval 4s. */ + {MDNS_REJECT_DATA_V4, (char*)&pkt6[0], sizeof(pkt6), 3}, + {MDNS_CHECK_DATA_V4, (char*)&pkt6[0], sizeof(pkt6), 1}, + + /* Inject a duplicate question. */ + {INJECT, (char*)&pkt9[0], sizeof(pkt9), 0}, + + /* Check query with known answer. */ + /* Interval 8s. */ + {MDNS_REJECT_DATA_V4, (char*)&pkt8[0], sizeof(pkt8), 7}, + {MDNS_CHECK_DATA_V4, (char*)&pkt8[0], sizeof(pkt8), 1}, +}; + +int mdns_duplicate_question_suppression_size = sizeof(mdns_duplicate_question_suppression) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_known_answer_ignored_test.c b/test/regression/mdns_test/mdns_known_answer_ignored_test.c new file mode 100644 index 00000000..7c4c807b --- /dev/null +++ b/test/regression/mdns_test/mdns_known_answer_ignored_test.c @@ -0,0 +1,193 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0x90, 0xb2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (255 bytes) */ +static const unsigned char pkt2[255] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xf1, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd9, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xdd, /* ........ */ +0x19, 0x0d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, /* .......< */ +0x00, 0x24, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .$.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, /* local..S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x3c, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .<...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x3c, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* <...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt3[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt4[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt5[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt6[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (76 bytes) */ +static const unsigned char pkt7[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0x90, 0xb2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (255 bytes) */ +static const unsigned char pkt8[255] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xf1, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd8, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xdd, /* ........ */ +0x19, 0x0d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, /* .......< */ +0x00, 0x24, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .$.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, /* local..S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x3c, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .<...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x3c, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* <...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +MDNS_TEST_SEQ mdns_known_answer_ignored[] = { + {TITLE, "Known answer ignored", 20, 0}, + + /* Inject the query with known answer. */ + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + + /* No RR should be stored. */ + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 0, 0} +}; + +int mdns_known_answer_ignored_size = sizeof(mdns_known_answer_ignored) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_known_answer_suppression_query_half_ttl_test.c b/test/regression/mdns_test/mdns_known_answer_suppression_query_half_ttl_test.c new file mode 100644 index 00000000..9feec32c --- /dev/null +++ b/test/regression/mdns_test/mdns_known_answer_suppression_query_half_ttl_test.c @@ -0,0 +1,201 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0x90, 0xb2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (255 bytes) */ +static const unsigned char pkt2[255] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xf1, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd9, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xdd, /* ........ */ +0x19, 0x0d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, /* .......< */ +0x00, 0x24, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .$.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, /* local..S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x3c, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .<...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x3c, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* <...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt3[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt4[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt5[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (108 bytes) */ +static const unsigned char pkt6[108] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x5e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .^..@... */ +0x90, 0x92, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4a, /* .......J */ +0x2e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, /* .....<.. */ +0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* .Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0xc0, 0x0c /* er.. */ +}; + +/* Frame (76 bytes) */ +static const unsigned char pkt7[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0x90, 0xb2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (255 bytes) */ +static const unsigned char pkt8[255] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xf1, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd8, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xdd, /* ........ */ +0x19, 0x0d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, /* .......< */ +0x00, 0x24, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .$.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, /* local..S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x3c, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .<...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x3c, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* <...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_http._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_known_answer_suppression_query_half_ttl[] = { + {TITLE, "Known answer suppression query half TTL", 39, 0}, + + /* Add a query. */ + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + + /* Check the query. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 1}, + + /* Inject the response. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* Check the query that past half TTL. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 32}, +}; + +int mdns_known_answer_suppression_query_half_ttl_size = sizeof(mdns_known_answer_suppression_query_half_ttl) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_known_answer_suppression_query_test.c b/test/regression/mdns_test/mdns_known_answer_suppression_query_test.c new file mode 100644 index 00000000..922c7bfd --- /dev/null +++ b/test/regression/mdns_test/mdns_known_answer_suppression_query_test.c @@ -0,0 +1,139 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (153 bytes) */ +static const unsigned char pkt2[153] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x87, 0x82, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0x92, 0x37, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* .7...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt3[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x85, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt4[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x84, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x92, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt5[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x83, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x90, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_http._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_known_answer_suppression_query[] = { + {TITLE, "Known answer suppression query", 30, 0}, + + /* Add a query. */ + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + + /* Check the query. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 1}, + + /* Inject the response. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* Check the query with known answer. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 2}, + + /* Delete the query. */ + {MDNS_QUERY_DELETE, NX_NULL, 0, 0}, + + /* Add a query. */ + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + + /* Check the query with known answer. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt4), 1}, +}; + +int mdns_known_answer_suppression_query_size = sizeof(mdns_known_answer_suppression_query) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_known_answer_suppression_response_test.c b/test/regression/mdns_test/mdns_known_answer_suppression_response_test.c new file mode 100644 index 00000000..8dc9209f --- /dev/null +++ b/test/regression/mdns_test/mdns_known_answer_suppression_response_test.c @@ -0,0 +1,145 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (75 bytes) */ +static const unsigned char pkt1[75] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x3d, 0x01, 0x81, 0x00, 0x00, 0xff, 0x11, /* .=...... */ +0x11, 0x81, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x29, /* .......) */ +0xa9, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .&...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (373 bytes) */ +static const unsigned char pkt2[373] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x67, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .g..@... */ +0x8f, 0x40, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .@...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x53, /* .......S */ +0xf4, 0x39, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .9...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x1d, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* STest._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, /* local..A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x04, 0x5f, /* NSTest._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* l..ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x04, 0x5f, /* NSTest._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* ...ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x04, 0x5f, /* NSTest._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x24, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* $.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* STest._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40 /* ....@ */ +}; + +/* Frame (101 bytes) */ +static const unsigned char pkt3[101] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x57, 0x01, 0x82, 0x00, 0x00, 0xff, 0x11, /* .W...... */ +0x11, 0x66, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* .f...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x43, /* .......C */ +0x10, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x0e, 0x0b, /* ....d... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0xc0, 0x0c /* est.. */ +}; + +/* Frame (101 bytes) */ +static const unsigned char pkt4[101] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x57, 0x01, 0x82, 0x00, 0x00, 0xff, 0x11, /* .W...... */ +0x11, 0x66, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* .f...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x43, /* .......C */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x0e, 0x0b, /* ....d... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0xc0, 0x0c /* est.. */ +}; + +static MDNS_SERVICE mdns_service = {"ARMMDNSTest", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_known_answer_suppression_response[] = { + {TITLE, "Known answer suppression response", 33, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Queries with known answer. */ + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + + /* No responses are expected. */ + {MDNS_REJECT_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 1}, + + /* Query only. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + + /* Check response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 2}, + + /* Queries with known answer. */ + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + + /* No responses are expected. */ + {MDNS_REJECT_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 1}, + + /* Queries with known answer. The TTL is less than half of the local RR. */ + {INJECT, (char*)&pkt4[0], sizeof(pkt4), 0}, + + /* Expect a response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 2}, +}; + +int mdns_known_answer_suppression_response_size = sizeof(mdns_known_answer_suppression_response) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_known_answer_suppression_unique_test.c b/test/regression/mdns_test/mdns_known_answer_suppression_unique_test.c new file mode 100644 index 00000000..0899e05e --- /dev/null +++ b/test/regression/mdns_test/mdns_known_answer_suppression_unique_test.c @@ -0,0 +1,55 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (171 bytes) */ +static const unsigned char pkt1[171] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x9d, 0x1e, 0x02, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0xf4, 0x9f, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x89, /* ........ */ +0x2c, 0xb0, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ,....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x04, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x11, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x08, 0x43, 0x61, /* ....P.Ca */ +0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0xc0, 0x1c, /* tro-PC.. */ +0xc0, 0x0c, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x33, 0x00, /* ......3. */ +0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x04, 0xc0, 0xa8, 0x07, 0x0a, 0xc0, 0x33, 0x00, /* ......3. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x05, 0xc0, 0x33, 0x00, 0x01, 0x40, 0xc0, 0x0c, /* ..3..@.. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x09, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x00, /* ........ */ +0x80, 0x00, 0x40 /* ..@ */ +}; + +static MDNS_QUERY_INFO mdns_query = {"test", "_http._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_known_answer_suppression_unique[] = { + {TITLE, "Known answer suppression unique", 31, 0}, + + /* Waiting for host name probing and announcing. */ + {WAIT, NX_NULL, 0, 5}, + + /* Inject one service. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + {DUMP, NX_NULL, 0, 0}, + + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + + /* No queries are expected. */ + {MDNS_REJECT_ANY_V4, NX_NULL, MDNS_FLAG_QUERY, 2}, +}; + +int mdns_known_answer_suppression_unique_size = sizeof(mdns_known_answer_suppression_unique) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_multiple_questions_per_query_test.c b/test/regression/mdns_test/mdns_multiple_questions_per_query_test.c new file mode 100644 index 00000000..d8116d6d --- /dev/null +++ b/test/regression/mdns_test/mdns_multiple_questions_per_query_test.c @@ -0,0 +1,41 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (103 bytes) */ +static const unsigned char pkt1[103] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x59, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .Y..@... */ +0x90, 0x97, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x45, /* .......E */ +0xe9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x5f, /* ......._ */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, 0x74, /* test1._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x06, 0x5f, 0x74, /* ......_t */ +0x65, 0x73, 0x74, 0x32, 0xc0, 0x13, 0x00, 0x0c, /* est2.... */ +0x00, 0x01, 0x06, 0x5f, 0x74, 0x65, 0x73, 0x74, /* ..._test */ +0x33, 0xc0, 0x13, 0x00, 0x0c, 0x00, 0x01 /* 3...... */ +}; + +static MDNS_QUERY_INFO mdns_query1 = {NX_NULL, "_test1._tcp", NX_NULL}; +static MDNS_QUERY_INFO mdns_query2 = {NX_NULL, "_test2._tcp", NX_NULL}; +static MDNS_QUERY_INFO mdns_query3 = {NX_NULL, "_test3._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_multiple_questions_per_query[] = { + {TITLE, "Multiple questions per query", 28, 0}, + + {MDNS_QUERY, (char*)&mdns_query1, 0, 0}, + {MDNS_QUERY, (char*)&mdns_query2, 0, 0}, + {MDNS_QUERY, (char*)&mdns_query3, 0, 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 2}, +}; + +int mdns_multiple_questions_per_query_size = sizeof(mdns_multiple_questions_per_query) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_poof_test.c b/test/regression/mdns_test/mdns_poof_test.c new file mode 100644 index 00000000..90986d05 --- /dev/null +++ b/test/regression/mdns_test/mdns_poof_test.c @@ -0,0 +1,103 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xa1, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (153 bytes) */ +static const unsigned char pkt2[153] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x01, 0x2a, 0x00, 0x00, 0xff, 0x11, /* ...*.... */ +0x18, 0x90, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (103 bytes) */ +static const unsigned char pkt3[103] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0x59, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .Y..@... */ +0xd9, 0x86, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x45, /* .......E */ +0x48, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* HP...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x0c /* 4500w.. */ +}; + +/* Frame (103 bytes) */ +static const unsigned char pkt4[103] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0x59, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .Y..@... */ +0xd9, 0x86, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x45, /* .......E */ +0x48, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* HP...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x0c /* 4500w.. */ +}; + +MDNS_TEST_SEQ mdns_poof[] = { + {TITLE, "Passive observation of failures", 31, 0}, + + /* Inject a response. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* 4 RRs are received. */ + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 4, 0}, + + /* Inject two queries. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + + /* Wait more than 10 seconds. */ + {WAIT, NX_NULL, 0, 11}, + + /* Check whether the RR is deleted. */ + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 3, 0}, +}; + +int mdns_poof_size = sizeof(mdns_poof) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_probing_conflict_test.c b/test/regression/mdns_test/mdns_probing_conflict_test.c new file mode 100644 index 00000000..31aa883e --- /dev/null +++ b/test/regression/mdns_test/mdns_probing_conflict_test.c @@ -0,0 +1,321 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (225 bytes) */ +static const unsigned char pkt1[225] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xd3, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd5, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbf, /* ........ */ +0x13, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .w...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0f, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, /* Server._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0xff, 0x00, 0x01, 0x0f, 0x53, 0x69, 0x6d, /* .....Sim */ +0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, 0x53, 0x65, /* pleWebSe */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0f, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x57, 0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, /* WebServe */ +0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* r._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x14, 0x08, 0x70, 0x61, /* ..d...pa */ +0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, /* per=A4.v */ +0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, /* ersion=0 */ +0x31 /* 1 */ +}; + +/* Frame (235 bytes) */ +static const unsigned char pkt2[235] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbc, 0x39, 0x02, 0x08, 0x00, 0x45, 0x00, /* /.9...E. */ +0x00, 0xdd, 0x05, 0x71, 0x00, 0x00, 0xff, 0x11, /* ...q.... */ +0xca, 0xa2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc9, /* ........ */ +0x3d, 0x40, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* =@...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x0f, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, /* Server._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x09, 0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, /* .Chenbo- */ +0x50, 0x43, 0xc0, 0x27, 0xc0, 0x0c, 0x00, 0x10, /* PC.'.... */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x16, /* ........ */ +0x09, 0x5b, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* .[paper= */ +0x41, 0x34, 0x0b, 0x56, 0x65, 0x72, 0x73, 0x69, /* A4.Versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x5d, 0xc0, 0x3e, /* on=01].> */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0x0a, 0x00, 0x00, 0x01, 0xc0, 0x3e, /* .......> */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xc0, 0x93, 0x9d, 0xaa, 0xda, 0xe3, /* ........ */ +0xea, 0xba, 0xc0, 0x3e, 0x00, 0x2f, 0x80, 0x01, /* ...>./.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0xc0, 0x3e, /* ...x...> */ +0x00, 0x04, 0x40, 0x00, 0x00, 0x08, 0xc0, 0x0c, /* ..@..... */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x09, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x00, /* ........ */ +0x80, 0x00, 0x40 /* ..@ */ +}; + +/* Frame (237 bytes) */ +static const unsigned char pkt3[237] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xdf, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xc8, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xcb, /* ........ */ +0x15, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .f...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, /* .SimpleW */ +0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* ebServer */ +0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, /* (2)._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x57, 0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, /* WebServe */ +0x72, 0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, /* r (2)._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (237 bytes) */ +static const unsigned char pkt4[237] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xdf, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xc7, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xcb, /* ........ */ +0x15, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .f...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, /* .SimpleW */ +0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* ebServer */ +0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, /* (2)._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x57, 0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, /* WebServe */ +0x72, 0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, /* r (2)._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (237 bytes) */ +static const unsigned char pkt5[237] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xdf, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xc6, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xcb, /* ........ */ +0x15, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .f...... */ +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, /* cal..... */ +0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, /* .SimpleW */ +0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* ebServer */ +0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, /* (2)._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x13, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x57, 0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x65, /* WebServe */ +0x72, 0x20, 0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, /* r (2)._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (261 bytes) */ +static const unsigned char pkt6[261] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xf7, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xad, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xe3, /* ........ */ +0xf7, 0x54, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .T...... */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x13, /* .local.. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x26, 0x13, /* ....d.&. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + +/* Frame (261 bytes) */ +static const unsigned char pkt7[261] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xf7, 0x00, 0x0c, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xac, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xe3, /* ........ */ +0xf7, 0x54, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .T...... */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x13, /* .local.. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x26, 0x13, /* ....d.&. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + +/* Frame (261 bytes) */ +static const unsigned char pkt8[261] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0xf7, 0x00, 0x0d, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xab, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xe3, /* ........ */ +0xf7, 0x54, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .T...... */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x13, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, 0x62, /* impleWeb */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x28, /* Server ( */ +0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* 2)._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x13, /* .local.. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x26, 0x13, /* ....d.&. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x57, 0x65, /* SimpleWe */ +0x62, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* bServer */ +0x28, 0x32, 0x29, 0x05, 0x5f, 0x68, 0x74, 0x74, /* (2)._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + + +static MDNS_SERVICE mdns_service = {"SimpleWebServer", "_http._tcp", NX_NULL, "paper=A4;version=01", 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_probing_conflict[] = { + {TITLE, "Probing conflict", 16, 0}, + + /* Wait 5 seconds. */ + {WAIT, NX_NULL, 0, 5}, + + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + + /* Wait the first probing. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 1}, + + /* Inject response. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* Expect probing with other name. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 1}, + + /* Set callback state. */ + {MDNS_SET_PROBING_CALLBACK_STATE, NX_NULL, NX_MDNS_LOCAL_SERVICE_REGISTERED_SUCCESS, 0}, + + /* Wait 3 seconds. */ + {WAIT, NX_NULL, 0, 3}, + + /* Check callback invoked. */ + {MDNS_CHECK_PROBING_CALLBACK_INVOKED, NX_NULL, 0, 1}, +}; + +int mdns_probing_conflict_size = sizeof(mdns_probing_conflict) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_query_and_response_chaos_test.c b/test/regression/mdns_test/mdns_query_and_response_chaos_test.c new file mode 100644 index 00000000..002d7561 --- /dev/null +++ b/test/regression/mdns_test/mdns_query_and_response_chaos_test.c @@ -0,0 +1,2113 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (83 bytes) */ +static const unsigned char pkt1[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x45, 0x44, 0x8b, 0x00, 0x00, 0xff, 0x11, /* .ED..... */ +0xd5, 0x0e, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xde, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .;...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt2[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x0a, 0x11, 0x00, 0x00, 0xff, 0x11, /* .E...... */ +0x08, 0xe9, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xd7, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (158 bytes) */ +static const unsigned char pkt3[158] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x90, 0x44, 0x8c, 0x00, 0x00, 0xff, 0x11, /* ..D..... */ +0xd4, 0xc2, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7c, /* .......| */ +0xa7, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* ........ */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x80, 0x01, 0xc0, 0x0c, 0x00, 0xff, 0x80, 0x01, /* ........ */ +0xc0, 0x0c, 0x00, 0xff, 0x80, 0x01, 0xc0, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0xc0, 0xa8, 0x00, 0x6a, 0xc0, 0x0c, /* .....j.. */ +0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, /* ..@..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0xc0, 0x0c, 0x00, 0x1c, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba /* I?Y.~. */ +}; + +/* Frame (90 bytes) */ +static const unsigned char pkt4[90] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4c, 0x0a, 0x12, 0x00, 0x00, 0xff, 0x11, /* .L...... */ +0x08, 0xe1, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x38, /* .......8 */ +0x9b, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .p...... */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x80, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x07, 0x0a /* .. */ +}; + +/* Frame (158 bytes) */ +static const unsigned char pkt5[158] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x90, 0x44, 0x8d, 0x00, 0x00, 0xff, 0x11, /* ..D..... */ +0xd4, 0xc1, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7c, /* .......| */ +0x27, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* '0...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0xc0, 0x0c, 0x00, 0xff, 0x00, 0x01, /* ........ */ +0xc0, 0x0c, 0x00, 0xff, 0x00, 0x01, 0xc0, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0xc0, 0xa8, 0x00, 0x6a, 0xc0, 0x0c, /* .....j.. */ +0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, /* ..@..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0xc0, 0x0c, 0x00, 0x1c, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba /* I?Y.~. */ +}; + +/* Frame (90 bytes) */ +static const unsigned char pkt6[90] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4c, 0x0a, 0x13, 0x00, 0x00, 0xff, 0x11, /* .L...... */ +0x08, 0xe0, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x38, /* .......8 */ +0x1b, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .q...... */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x07, 0x0a /* .. */ +}; + +/* Frame (158 bytes) */ +static const unsigned char pkt7[158] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x90, 0x44, 0x91, 0x00, 0x00, 0xff, 0x11, /* ..D..... */ +0xd4, 0xbd, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7c, /* .......| */ +0x27, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* '0...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0xc0, 0x0c, 0x00, 0xff, 0x00, 0x01, /* ........ */ +0xc0, 0x0c, 0x00, 0xff, 0x00, 0x01, 0xc0, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0xc0, 0xa8, 0x00, 0x6a, 0xc0, 0x0c, /* .....j.. */ +0x00, 0x1c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, /* ..@..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0xc0, 0x0c, 0x00, 0x1c, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba /* I?Y.~. */ +}; + +/* Frame (90 bytes) */ +static const unsigned char pkt8[90] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4c, 0x0a, 0x14, 0x00, 0x00, 0xff, 0x11, /* .L...... */ +0x08, 0xdf, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x38, /* .......8 */ +0x1b, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .q...... */ +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, /* local... */ +0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x07, 0x0a /* .. */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt9[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x44, 0x93, 0x00, 0x00, 0xff, 0x11, /* .ZD..... */ +0xd3, 0xf1, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0x63, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* c....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x6a, 0x03, 0x31, 0x30, 0x36, /* ...j.106 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt10[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x0a, 0x15, 0x00, 0x00, 0xff, 0x11, /* .~...... */ +0x08, 0xac, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt11[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x45, 0x44, 0x95, 0x00, 0x00, 0xff, 0x11, /* .ED..... */ +0xd5, 0x04, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xde, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .;...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt12[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x0a, 0x16, 0x00, 0x00, 0xff, 0x11, /* .E...... */ +0x08, 0xe4, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xd7, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt13[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x44, 0xab, 0x00, 0x00, 0xff, 0x11, /* .ZD..... */ +0xd3, 0xd9, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0x63, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* c....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x6a, 0x03, 0x31, 0x30, 0x36, /* ...j.106 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt14[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x0a, 0x17, 0x00, 0x00, 0xff, 0x11, /* .~...... */ +0x08, 0xaa, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt15[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x45, 0x28, 0x00, 0x00, 0xff, 0x11, /* .ZE(.... */ +0xd3, 0x5c, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .\...j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0x63, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* c....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x6a, 0x03, 0x31, 0x30, 0x36, /* ...j.106 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt16[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x0a, 0x18, 0x00, 0x00, 0xff, 0x11, /* .~...... */ +0x08, 0xa9, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt17[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x45, 0x45, 0x29, 0x00, 0x00, 0xff, 0x11, /* .EE).... */ +0xd4, 0x70, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .p...j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xde, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .;...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt18[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x0a, 0x19, 0x00, 0x00, 0xff, 0x11, /* .E...... */ +0x08, 0xe1, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xd7, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt19[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x45, 0x51, 0x00, 0x00, 0xff, 0x11, /* .ZEQ.... */ +0xd3, 0x33, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .3...j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0x63, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* c....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x6a, 0x03, 0x31, 0x30, 0x36, /* ...j.106 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt20[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x0a, 0x1a, 0x00, 0x00, 0xff, 0x11, /* .~...... */ +0x08, 0xa7, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt21[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x45, 0x45, 0x75, 0x00, 0x00, 0xff, 0x11, /* .EEu.... */ +0xd4, 0x24, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .$...j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xde, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .;...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (83 bytes) */ +static const unsigned char pkt22[83] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x45, 0x0a, 0x1b, 0x00, 0x00, 0xff, 0x11, /* .E...... */ +0x08, 0xdf, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x31, /* .......1 */ +0xd7, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x73, 0x6c, 0x65, 0x65, 0x70, 0x2d, 0x70, 0x72, /* sleep-pr */ +0x6f, 0x78, 0x79, 0x04, 0x5f, 0x75, 0x64, 0x70, /* oxy._udp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (88 bytes) */ +static const unsigned char pkt23[88] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x4a, 0x45, 0x7a, 0x00, 0x00, 0xff, 0x11, /* .JEz.... */ +0xd4, 0x1a, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x36, /* .......6 */ +0xfd, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (88 bytes) */ +static const unsigned char pkt24[88] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x4a, 0x0a, 0x1c, 0x00, 0x00, 0xff, 0x11, /* .J...... */ +0x08, 0xd9, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x36, /* .......6 */ +0xf6, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* cal..... */ +}; + +/* Frame (106 bytes) */ +static const unsigned char pkt25[106] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x33, 0xc1, 0xbd, 0x08, 0x00, 0x45, 0x00, /* s3....E. */ +0x00, 0x5c, 0x78, 0x77, 0x00, 0x00, 0xff, 0x11, /* .\xw.... */ +0xa1, 0x09, 0xc0, 0xa8, 0x00, 0x6c, 0xe0, 0x00, /* .....l.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x48, /* .......H */ +0x0a, 0xe9, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x0c, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0xc0, 0x23 /* .# */ +}; + +/* Frame (114 bytes) */ +static const unsigned char pkt26[114] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xe8, 0x39, /* ..^....9 */ +0x35, 0x44, 0xfe, 0xd4, 0x08, 0x00, 0x45, 0x00, /* 5D....E. */ +0x00, 0x64, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .d..@... */ +0xd9, 0xe2, 0xc0, 0xa8, 0x00, 0x02, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x50, /* .......P */ +0x42, 0x75, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* Bu...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x14, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0xc0, 0x23 /* .# */ +}; + +/* Frame (113 bytes) */ +static const unsigned char pkt27[113] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x9b, 0xc6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0x63, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .c..@... */ +0xd9, 0xd1, 0xc0, 0xa8, 0x00, 0x14, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4f, /* .......O */ +0x64, 0xfc, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* d....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x13, 0x0b, 0x5f, /* ......._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0x04, 0x5f, 0x74, 0x63, 0x70, 0xc0, /* sh._tcp. */ +0x23 /* # */ +}; + +/* Frame (126 bytes) */ +static const unsigned char pkt28[126] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x92, 0xa6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0x70, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .p..@... */ +0xd9, 0xc3, 0xc0, 0xa8, 0x00, 0x15, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x5c, /* .......\ */ +0x3e, 0x43, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* >C...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x0d, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0xc0, 0x23, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* p.#..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x07, 0x04, /* ........ */ +0x5f, 0x72, 0x66, 0x62, 0xc0, 0x3a /* _rfb.: */ +}; + +/* Frame (94 bytes) */ +static const unsigned char pkt29[94] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x50, 0x45, 0x7e, 0x00, 0x00, 0xff, 0x11, /* .PE~.... */ +0xd4, 0x10, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3c, /* .......< */ +0x60, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* `....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x0c, 0x5f, 0x77, 0x6f, 0x72, /* ...._wor */ +0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, /* kstation */ +0xc0, 0x11, 0x00, 0x0c, 0x00, 0x01 /* ...... */ +}; + +/* Frame (94 bytes) */ +static const unsigned char pkt30[94] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x50, 0x0a, 0x1d, 0x00, 0x00, 0xff, 0x11, /* .P...... */ +0x08, 0xd2, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3c, /* .......< */ +0x5a, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ZA...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x0c, 0x5f, 0x77, 0x6f, 0x72, /* ...._wor */ +0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, /* kstation */ +0xc0, 0x11, 0x00, 0x0c, 0x00, 0x01 /* ...... */ +}; + +/* Frame (332 bytes) */ +static const unsigned char pkt31[332] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x33, 0xc1, 0xbd, 0x08, 0x00, 0x45, 0x00, /* s3....E. */ +0x01, 0x3e, 0x78, 0x7d, 0x00, 0x00, 0xff, 0x11, /* .>x}.... */ +0xa0, 0x21, 0xc0, 0xa8, 0x00, 0x6c, 0xe0, 0x00, /* .!...l.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x2a, /* .......* */ +0x4f, 0xd5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* O....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0c, 0x09, 0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, /* ..Chenbo */ +0x2d, 0x50, 0x43, 0xc0, 0x0c, 0x09, 0x43, 0x68, /* -PC...Ch */ +0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, 0x43, 0x0c, /* enbo-PC. */ +0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, /* _device- */ +0x69, 0x6e, 0x66, 0x6f, 0xc0, 0x11, 0x00, 0x10, /* info.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0e, /* ........ */ +0x0d, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x3d, 0x57, /* .model=W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0xc0, 0x27, /* indows.' */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbd, /* ........ */ +0x09, 0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, /* .Chenbo- */ +0x50, 0x43, 0xc0, 0x16, 0xc0, 0x27, 0x00, 0x10, /* PC...'.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x23, /* .......# */ +0x11, 0x6e, 0x65, 0x74, 0x62, 0x69, 0x6f, 0x73, /* .netbios */ +0x3d, 0x43, 0x48, 0x45, 0x4e, 0x42, 0x4f, 0x2d, /* =CHENBO- */ +0x50, 0x43, 0x10, 0x64, 0x6f, 0x6d, 0x61, 0x69, /* PC.domai */ +0x6e, 0x3d, 0x57, 0x4f, 0x52, 0x4b, 0x47, 0x52, /* n=WORKGR */ +0x4f, 0x55, 0x50, 0xc0, 0x76, 0x00, 0x01, 0x80, /* OUP.v... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, /* ....x... */ +0xa8, 0x00, 0x6c, 0xc0, 0x76, 0x00, 0x1c, 0x80, /* ..l.v... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0x20, /* ....x.. */ +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xc0, /* ......1. */ +0x76, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, /* v....... */ +0x78, 0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, /* x....... */ +0x00, 0x00, 0x00, 0x01, 0x59, 0x44, 0x79, 0xe1, /* ....YDy. */ +0x0a, 0xd7, 0xf4, 0xc0, 0x27, 0x00, 0x2f, 0x80, /* ....'./. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x09, 0xc0, /* ....x... */ +0x27, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* '......@ */ +0xc0, 0x76, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* .v./.... */ +0x00, 0x78, 0x00, 0x08, 0xc0, 0x76, 0x00, 0x04, /* .x...v.. */ +0x40, 0x00, 0x00, 0x08 /* @... */ +}; + +/* Frame (242 bytes) */ +static const unsigned char pkt32[242] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xe8, 0x39, /* ..^....9 */ +0x35, 0x44, 0xfe, 0xd4, 0x08, 0x00, 0x45, 0x00, /* 5D....E. */ +0x00, 0xe4, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x62, 0xc0, 0xa8, 0x00, 0x02, 0xe0, 0x00, /* .b...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xd0, /* ........ */ +0xa0, 0xd5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x31, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, /* 1.server */ +0x2d, 0x48, 0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, /* -HP-Z210 */ +0x2d, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, /* -Worksta */ +0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, /* tion [e8 */ +0x3a, 0x33, 0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, /* :39:35:4 */ +0x34, 0x3a, 0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, /* 4:fe:d4] */ +0xc0, 0x0c, 0xc0, 0x2f, 0x00, 0x10, 0x80, 0x01, /* .../.... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, /* ........ */ +0x2f, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* /.!..... */ +0x78, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, /* x.#..... */ +0x09, 0x1a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, /* ..server */ +0x2d, 0x48, 0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, /* -HP-Z210 */ +0x2d, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, /* -Worksta */ +0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x1e, 0xc0, 0x7f, /* tion.... */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0xea, 0x39, 0x35, 0xff, 0xfe, 0x44, /* ...95..D */ +0xfe, 0xd4, 0xc0, 0x7f, 0x00, 0x01, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x02 /* .. */ +}; + +/* Frame (228 bytes) */ +static const unsigned char pkt33[228] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x9b, 0xc6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0xd6, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x5e, 0xc0, 0xa8, 0x00, 0x14, 0xe0, 0x00, /* .^...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc2, /* ........ */ +0x8a, 0x5a, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .Z...... */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x2a, 0x27, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* *'catro- */ +0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, /* OptiPlex */ +0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, 0x5b, 0x61, /* -3010 [a */ +0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, /* 4:1f:72: */ +0x35, 0x33, 0x3a, 0x39, 0x62, 0x3a, 0x63, 0x36, /* 53:9b:c6 */ +0x5d, 0xc0, 0x0c, 0xc0, 0x2f, 0x00, 0x10, 0x80, /* ].../... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, /* ........ */ +0xc0, 0x2f, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* ./.!.... */ +0x00, 0x78, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x09, 0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, /* -OptiPle */ +0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, 0x1e, /* x-3010.. */ +0xc0, 0x78, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, /* .x...... */ +0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, /* .x...... */ +0x00, 0x00, 0x00, 0x00, 0xa6, 0x1f, 0x72, 0xff, /* ......r. */ +0xfe, 0x53, 0x9b, 0xc6, 0xc0, 0x78, 0x00, 0x01, /* .S...x.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x14 /* .... */ +}; + +/* Frame (206 bytes) */ +static const unsigned char pkt34[206] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0xa0, 0xf7, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0xc0, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x75, 0xc0, 0xa8, 0x00, 0x13, 0xe0, 0x00, /* .u...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xac, /* ........ */ +0x17, 0x94, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, /* EL [a4:1 */ +0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, /* f:72:53: */ +0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, 0xc0, 0x0c, /* a0:f7].. */ +0xc0, 0x2f, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* ./...... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x2f, 0x00, /* ....../. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x08, /* ........ */ +0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, 0x45, 0x4c, /* catro-EL */ +0xc0, 0x1e, 0xc0, 0x6d, 0x00, 0x1c, 0x80, 0x01, /* ...m.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0x20, 0x01, /* ...x.. . */ +0x0d, 0xa8, 0x80, 0x08, 0x01, 0x27, 0x02, 0x0c, /* .....'.. */ +0x29, 0xff, 0xfe, 0xe5, 0x16, 0x93, 0xc0, 0x6d, /* )......m */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0xc0, 0xa8, 0x00, 0x13 /* ...... */ +}; + +/* Frame (160 bytes) */ +static const unsigned char pkt35[160] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x92, 0x67, 0xcc, 0x00, 0x00, 0xff, 0x11, /* ..g..... */ +0xb1, 0xe6, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x7e, /* .......~ */ +0xbc, 0x15, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x17, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0xc0, 0x23, 0xc0, 0x0c, 0x00, /* tcp.#... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0b, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, /* .._print */ +0x65, 0x72, 0xc0, 0x44, 0xc0, 0x0c, 0x00, 0x0c, /* er.D.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x08, /* ........ */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0xc0, 0x44 /* ._http.D */ +}; + +/* Frame (222 bytes) */ +static const unsigned char pkt36[222] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x92, 0xa6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0xd0, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x63, 0xc0, 0xa8, 0x00, 0x15, 0xe0, 0x00, /* .c...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbc, /* ........ */ +0x27, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* '....... */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x27, 0x24, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* '$dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, /* 10 [a4:1 */ +0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, /* f:72:53: */ +0x39, 0x32, 0x3a, 0x61, 0x36, 0x5d, 0xc0, 0x0c, /* 92:a6].. */ +0xc0, 0x2f, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* ./...... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x2f, 0x00, /* ....../. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x10, /* ........ */ +0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, /* dc-OptiP */ +0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, /* lex-3010 */ +0xc0, 0x1e, 0xc0, 0x75, 0x00, 0x1c, 0x80, 0x01, /* ...u.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x1f, /* ........ */ +0x72, 0xff, 0xfe, 0x53, 0x92, 0xa6, 0xc0, 0x75, /* r..S...u */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0xc0, 0xa8, 0x00, 0x15 /* ...... */ +}; + +/* Frame (202 bytes) */ +static const unsigned char pkt37[202] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x6a, 0x2e, 0x7a, 0x08, 0x00, 0x45, 0x00, /* )j.z..E. */ +0x00, 0xbc, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x11, 0xc0, 0xa8, 0x00, 0x7b, 0xe0, 0x00, /* .....{.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xa8, /* ........ */ +0x1d, 0xc5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x1d, 0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, /* ..ubuntu */ +0x20, 0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, /* [00:0c: */ +0x32, 0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, /* 29:6a:2e */ +0x3a, 0x37, 0x61, 0x5d, 0xc0, 0x0c, 0xc0, 0x2f, /* :7a].../ */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x01, 0x00, 0xc0, 0x2f, 0x00, 0x21, 0x80, /* ..../.!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x0f, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x09, 0x06, 0x75, 0x62, /* ......ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x1e, 0xc0, 0x6b, /* untu...k */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x6a, /* ....)..j */ +0x2e, 0x7a, 0xc0, 0x6b, 0x00, 0x01, 0x80, 0x01, /* .z.k.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x7b /* .{ */ +}; + +/* Frame (94 bytes) */ +static const unsigned char pkt38[94] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x50, 0x45, 0x81, 0x00, 0x00, 0xff, 0x11, /* .PE..... */ +0xd4, 0x0d, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3c, /* .......< */ +0x75, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* u....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x5f, /* ......._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* sh._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0xc0, 0x18, 0x00, 0x0c, 0x00, 0x01 /* ...... */ +}; + +/* Frame (94 bytes) */ +static const unsigned char pkt39[94] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x50, 0x0a, 0x1e, 0x00, 0x00, 0xff, 0x11, /* .P...... */ +0x08, 0xd1, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3c, /* .......< */ +0x6f, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* o^...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x5f, /* ......._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* sh._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0xc0, 0x18, 0x00, 0x0c, 0x00, 0x01 /* ...... */ +}; + +/* Frame (163 bytes) */ +static const unsigned char pkt40[163] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x9b, 0xc6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0x95, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x9f, 0xc0, 0xa8, 0x00, 0x14, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x81, /* ........ */ +0xd2, 0x1f, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x5f, /* ......._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* sh._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x16, /* ........ */ +0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, 0x4f, /* .catro-O */ +0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, /* ptiPlex- */ +0x33, 0x30, 0x31, 0x30, 0xc0, 0x0c, 0xc0, 0x2e, /* 3010.... */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x01, 0x00, 0xc0, 0x2e, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1c, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x16, 0x13, 0x63, 0x61, /* ......ca */ +0x74, 0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* tro-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x1d /* 0.. */ +}; + +/* Frame (141 bytes) */ +static const unsigned char pkt41[141] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0xa0, 0xf7, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0x7f, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0xb6, 0xc0, 0xa8, 0x00, 0x13, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6b, /* .......k */ +0x96, 0xe5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x5f, /* ......._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* sh._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0b, /* ........ */ +0x08, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, 0x45, /* .catro-E */ +0x4c, 0xc0, 0x0c, 0xc0, 0x2e, 0x00, 0x10, 0x80, /* L....... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, /* ........ */ +0xc0, 0x2e, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* ...!.... */ +0x00, 0x78, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x16, 0x08, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x45, 0x4c, 0xc0, 0x1d /* -EL.. */ +}; + +/* Frame (250 bytes) */ +static const unsigned char pkt42[250] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x92, 0xa6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0xec, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x47, 0xc0, 0xa8, 0x00, 0x15, 0xe0, 0x00, /* .G...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xd8, /* ........ */ +0x88, 0xc6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x0c, 0xc0, 0x28, 0x00, 0x10, /* 10...(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, /* ..(.!... */ +0x00, 0x00, 0x78, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x16, 0xa8, 0x10, 0x64, 0x63, 0x2d, 0x4f, /* ....dc-O */ +0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, /* ptiPlex- */ +0x33, 0x30, 0x31, 0x30, 0xc0, 0x17, 0x0b, 0x5f, /* 3010..._ */ +0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, 0x2d, 0x73, /* udisks-s */ +0x73, 0x68, 0xc0, 0x12, 0x00, 0x0c, 0x00, 0x01, /* sh...... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x13, 0x10, 0x64, /* .......d */ +0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, /* c-OptiPl */ +0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, /* ex-3010. */ +0x84, 0xc0, 0x9c, 0x00, 0x10, 0x80, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x9c, /* ........ */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, /* ........ */ +0xc0, 0x71 /* .q */ +}; + +/* Frame (97 bytes) */ +static const unsigned char pkt43[97] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x53, 0x45, 0x84, 0x00, 0x00, 0xff, 0x11, /* .SE..... */ +0xd4, 0x07, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3f, /* .......? */ +0x9a, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x72, 0x66, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* rfb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, 0x6c, /* ...._pdl */ +0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x72, /* -datastr */ +0x65, 0x61, 0x6d, 0xc0, 0x11, 0x00, 0x0c, 0x00, /* eam..... */ +0x01 /* . */ +}; + +/* Frame (97 bytes) */ +static const unsigned char pkt44[97] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x53, 0x0a, 0x1f, 0x00, 0x00, 0xff, 0x11, /* .S...... */ +0x08, 0xcd, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3f, /* .......? */ +0x94, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .7...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x72, 0x66, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* rfb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, 0x6c, /* ...._pdl */ +0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x72, /* -datastr */ +0x65, 0x61, 0x6d, 0xc0, 0x11, 0x00, 0x0c, 0x00, /* eam..... */ +0x01 /* . */ +}; + +/* Frame (173 bytes) */ +static const unsigned char pkt45[173] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xa4, 0x1f, /* ..^..... */ +0x72, 0x53, 0x92, 0xa6, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x00, 0x9f, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x94, 0xc0, 0xa8, 0x00, 0x15, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x8b, /* ........ */ +0x10, 0xea, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x72, 0x66, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* rfb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, 0x72, /* *'dc's r */ +0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, /* emote de */ +0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, /* sktop on */ +0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x0c, 0xc0, 0x27, 0x00, 0x10, 0x80, /* 0...'... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, /* ........ */ +0xc0, 0x27, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .'.!.... */ +0x00, 0x78, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x17, 0x0c, 0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, /* ...dc-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x16 /* 010.. */ +}; + +/* Frame (79 bytes) */ +static const unsigned char pkt46[79] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x41, 0x45, 0x8a, 0x00, 0x00, 0xff, 0x11, /* .AE..... */ +0xd4, 0x13, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2d, /* .......- */ +0xc4, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* al..... */ +}; + +/* Frame (79 bytes) */ +static const unsigned char pkt47[79] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x41, 0x0a, 0x20, 0x00, 0x00, 0xff, 0x11, /* .A. .... */ +0x08, 0xde, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2d, /* .......- */ +0xbe, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .H...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* al..... */ +}; + +/* Frame (562 bytes) */ +static const unsigned char pkt48[562] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x02, 0x24, 0x67, 0xcd, 0x00, 0x00, 0xff, 0x11, /* .$g..... */ +0xb0, 0x53, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* .S...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x02, 0x10, /* ........ */ +0x25, 0xc3, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* %....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, /* .....Can */ +0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* onMF4500 */ +0x77, 0xc0, 0x0c, 0x05, 0x5f, 0x68, 0x74, 0x74, /* w..._htt */ +0x70, 0xc0, 0x1c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* p....... */ +0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, /* ......Ca */ +0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, /* nonMF450 */ +0x30, 0x77, 0xc0, 0x41, 0x06, 0x72, 0x6f, 0x75, /* 0w.A.rou */ +0x74, 0x65, 0x72, 0xc0, 0x21, 0x00, 0x01, 0x80, /* ter.!... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, /* ....x... */ +0xa8, 0x00, 0x04, 0xc0, 0x32, 0x00, 0x21, 0x80, /* ....2.!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x23, 0x8c, 0xc0, 0x62, 0xc0, /* ...#..b. */ +0x32, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, /* 2....... */ +0x94, 0x01, 0x4e, 0x09, 0x74, 0x78, 0x74, 0x76, /* ..N.txtv */ +0x65, 0x72, 0x73, 0x3d, 0x31, 0x05, 0x6e, 0x6f, /* ers=1.no */ +0x74, 0x65, 0x3d, 0x08, 0x71, 0x74, 0x6f, 0x74, /* te=.qtot */ +0x61, 0x6c, 0x3d, 0x31, 0x0b, 0x70, 0x72, 0x69, /* al=1.pri */ +0x6f, 0x72, 0x69, 0x74, 0x79, 0x3d, 0x31, 0x30, /* ority=10 */ +0x11, 0x74, 0x79, 0x3d, 0x43, 0x61, 0x6e, 0x6f, /* .ty=Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x37, 0x30, /* n MF4570 */ +0x64, 0x77, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, /* dw.produ */ +0x63, 0x74, 0x3d, 0x28, 0x43, 0x61, 0x6e, 0x6f, /* ct=(Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* n MF4500 */ +0x77, 0x29, 0x1c, 0x70, 0x64, 0x6c, 0x3d, 0x61, /* w).pdl=a */ +0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, /* pplicati */ +0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, /* on/octet */ +0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2a, /* -stream* */ +0x61, 0x64, 0x6d, 0x69, 0x6e, 0x75, 0x72, 0x6c, /* adminurl */ +0x3d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, /* =http:// */ +0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x6c, /* router.l */ +0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x2f, 0x74, 0x5f, /* ocal./t_ */ +0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x2e, 0x63, /* welcom.c */ +0x67, 0x69, 0x0d, 0x75, 0x73, 0x62, 0x5f, 0x4d, /* gi.usb_M */ +0x46, 0x47, 0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* FG=Canon */ +0x27, 0x75, 0x73, 0x62, 0x5f, 0x4d, 0x44, 0x4c, /* 'usb_MDL */ +0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x20, 0x4d, /* =Canon M */ +0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0x20, 0x53, /* F4500w S */ +0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x28, 0x55, /* eries (U */ +0x46, 0x52, 0x49, 0x49, 0x20, 0x4c, 0x54, 0x29, /* FRII LT) */ +0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, /* .transpa */ +0x72, 0x65, 0x6e, 0x74, 0x3d, 0x46, 0x08, 0x42, /* rent=F.B */ +0x69, 0x6e, 0x61, 0x72, 0x79, 0x3d, 0x46, 0x06, /* inary=F. */ +0x54, 0x42, 0x43, 0x50, 0x3d, 0x46, 0x07, 0x43, /* TBCP=F.C */ +0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x46, 0x08, 0x43, /* olor=F.C */ +0x6f, 0x70, 0x69, 0x65, 0x73, 0x3d, 0x54, 0x08, /* opies=T. */ +0x44, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x3d, 0x54, /* Duplex=T */ +0x0d, 0x50, 0x61, 0x70, 0x65, 0x72, 0x43, 0x75, /* .PaperCu */ +0x73, 0x74, 0x6f, 0x6d, 0x3d, 0x54, 0x06, 0x42, /* stom=T.B */ +0x69, 0x6e, 0x64, 0x3d, 0x46, 0x09, 0x43, 0x6f, /* ind=F.Co */ +0x6c, 0x6c, 0x61, 0x74, 0x65, 0x3d, 0x54, 0x06, /* llate=T. */ +0x53, 0x6f, 0x72, 0x74, 0x3d, 0x54, 0x08, 0x53, /* Sort=T.S */ +0x74, 0x61, 0x70, 0x6c, 0x65, 0x3d, 0x46, 0x07, /* taple=F. */ +0x50, 0x75, 0x6e, 0x63, 0x68, 0x3d, 0x46, 0x11, /* Punch=F. */ +0x50, 0x61, 0x70, 0x65, 0x72, 0x4d, 0x61, 0x78, /* PaperMax */ +0x3d, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x41, /* =legal-A */ +0x34, 0xc0, 0x53, 0x00, 0x21, 0x80, 0x01, 0x00, /* 4.S.!... */ +0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0xc0, 0x62, 0xc0, 0x53, 0x00, /* ..P.b.S. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x01, 0x00 /* .. */ +}; + +/* Frame (468 bytes) */ +static const unsigned char pkt49[468] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0xc6, 0x45, 0x95, 0x00, 0x00, 0xff, 0x11, /* ..E..... */ +0xd2, 0x83, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0xb2, /* ........ */ +0x11, 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* ........ */ +0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0b, 0x5f, 0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, /* ._udisks */ +0x2d, 0x73, 0x73, 0x68, 0xc0, 0x33, 0x00, 0x0c, /* -ssh.3.. */ +0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0xc0, 0x33, 0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, /* .3...... */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x02, 0xc0, 0x2e, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, /* ........ */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0xc0, /* ation.3. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x50, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..P..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x07, 0x04, /* ........ */ +0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, 0xc0, 0x0c, /* _rfb.3.. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x12, 0x0f, 0x5f, 0x70, 0x64, 0x6c, 0x2d, /* ..._pdl- */ +0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x72, 0x65, /* datastre */ +0x61, 0x6d, 0xc0, 0x33, 0xc0, 0x0c, 0x00, 0x0c, /* am.3.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0b, /* ........ */ +0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, /* ._printe */ +0x72, 0xc0, 0x33, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* r.3..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x16, 0x13, /* ........ */ +0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, 0x4f, 0x70, /* catro-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, /* 010.>.>. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x45, 0x4c, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* EL.>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x13, /* ........ */ +0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* .dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x3e, 0xc0, 0x50, 0x00, 0x0c, 0x00, /* 0.>.P... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x2a, 0x27, /* ......*' */ +0x64, 0x63, 0x27, 0x73, 0x20, 0x72, 0x65, 0x6d, /* dc's rem */ +0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, 0x73, 0x6b, /* ote desk */ +0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, 0x20, 0x64, /* top on d */ +0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, /* c-OptiPl */ +0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, /* ex-3010. */ +0x50, 0xc0, 0x50, 0x00, 0x0c, 0x00, 0x01, 0x00, /* P.P..... */ +0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, /* ......Ca */ +0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, /* nonMF450 */ +0x30, 0x77, 0xc0, 0x50 /* 0w.P */ +}; + +/* Frame (468 bytes) */ +static const unsigned char pkt50[468] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x01, 0xc6, 0x0a, 0x21, 0x00, 0x00, 0xff, 0x11, /* ...!.... */ +0x07, 0x58, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* .X...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0xb2, /* ........ */ +0x0b, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* .9...... */ +0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0b, 0x5f, 0x75, 0x64, 0x69, 0x73, 0x6b, 0x73, /* ._udisks */ +0x2d, 0x73, 0x73, 0x68, 0xc0, 0x33, 0x00, 0x0c, /* -ssh.3.. */ +0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0xc0, 0x33, 0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, /* .3...... */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x02, 0xc0, 0x2e, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, /* ........ */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0xc0, /* ation.3. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x50, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..P..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x07, 0x04, /* ........ */ +0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, 0xc0, 0x0c, /* _rfb.3.. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x12, 0x0f, 0x5f, 0x70, 0x64, 0x6c, 0x2d, /* ..._pdl- */ +0x64, 0x61, 0x74, 0x61, 0x73, 0x74, 0x72, 0x65, /* datastre */ +0x61, 0x6d, 0xc0, 0x33, 0xc0, 0x0c, 0x00, 0x0c, /* am.3.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0b, /* ........ */ +0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, /* ._printe */ +0x72, 0xc0, 0x33, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* r.3..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x16, 0x13, /* ........ */ +0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, 0x4f, 0x70, /* catro-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, /* 010.>.>. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x45, 0x4c, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* EL.>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x13, /* ........ */ +0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* .dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x3e, 0xc0, 0x50, 0x00, 0x0c, 0x00, /* 0.>.P... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x2a, 0x27, /* ......*' */ +0x64, 0x63, 0x27, 0x73, 0x20, 0x72, 0x65, 0x6d, /* dc's rem */ +0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, 0x73, 0x6b, /* ote desk */ +0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, 0x20, 0x64, /* top on d */ +0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, /* c-OptiPl */ +0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, /* ex-3010. */ +0x50, 0xc0, 0x50, 0x00, 0x0c, 0x00, 0x01, 0x00, /* P.P..... */ +0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, /* ......Ca */ +0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, /* nonMF450 */ +0x30, 0x77, 0xc0, 0x50 /* 0w.P */ +}; + +/* Frame (447 bytes) */ +static const unsigned char pkt51[447] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0xb1, 0x45, 0x9f, 0x00, 0x00, 0xff, 0x11, /* ..E..... */ +0xd2, 0x8e, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x9d, /* ........ */ +0x79, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* yH...... */ +0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, /* ...._rfb */ +0xc0, 0x19, 0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xc0, 0x19, /* stream.. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, /* .......1 */ +0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, /* .server- */ +0x48, 0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, /* HP-Z210- */ +0x57, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* Workstat */ +0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, /* ion [e8: */ +0x33, 0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, /* 39:35:44 */ +0x3a, 0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, /* :fe:d4]. */ +0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x94, 0x00, 0x2a, 0x27, 0x63, 0x61, /* ....*'ca */ +0x74, 0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* tro-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, /* 0 [a4:1f */ +0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, /* :72:53:9 */ +0x62, 0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x0c, 0xc0, /* b:c6]... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, /* o-EL [a4 */ +0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, /* :1f:72:5 */ +0x33, 0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, /* 3:a0:f7] */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x27, 0x24, 0x64, /* .....'$d */ +0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, /* c-OptiPl */ +0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, /* ex-3010 */ +0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, /* [a4:1f:7 */ +0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, /* 2:53:92: */ +0x61, 0x36, 0x5d, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, /* a6]..... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x1d, 0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, /* ..ubuntu */ +0x20, 0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, /* [00:0c: */ +0x32, 0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, /* 29:6a:2e */ +0x3a, 0x37, 0x61, 0x5d, 0xc0, 0x0c, 0xc0, 0x29, /* :7a]...) */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x29, 0xc0, 0x34, 0x00, 0x0c, /* 10.).4.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x34 /* 4500w.4 */ +}; + +/* Frame (447 bytes) */ +static const unsigned char pkt52[447] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x01, 0xb1, 0x0a, 0x22, 0x00, 0x00, 0xff, 0x11, /* ...".... */ +0x07, 0x6c, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* .l...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x9d, /* ........ */ +0x72, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* r....... */ +0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5f, /* ......._ */ +0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* workstat */ +0x69, 0x6f, 0x6e, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ion._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, /* ...._rfb */ +0xc0, 0x19, 0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xc0, 0x19, /* stream.. */ +0x00, 0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, /* .......1 */ +0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, /* .server- */ +0x48, 0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, /* HP-Z210- */ +0x57, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, /* Workstat */ +0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, /* ion [e8: */ +0x33, 0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, /* 39:35:44 */ +0x3a, 0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, /* :fe:d4]. */ +0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x94, 0x00, 0x2a, 0x27, 0x63, 0x61, /* ....*'ca */ +0x74, 0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* tro-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, /* 0 [a4:1f */ +0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, /* :72:53:9 */ +0x62, 0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x0c, 0xc0, /* b:c6]... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, /* o-EL [a4 */ +0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, /* :1f:72:5 */ +0x33, 0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, /* 3:a0:f7] */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x27, 0x24, 0x64, /* .....'$d */ +0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, /* c-OptiPl */ +0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, /* ex-3010 */ +0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, /* [a4:1f:7 */ +0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, /* 2:53:92: */ +0x61, 0x36, 0x5d, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, /* a6]..... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x1d, 0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, /* ..ubuntu */ +0x20, 0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, /* [00:0c: */ +0x32, 0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, /* 29:6a:2e */ +0x3a, 0x37, 0x61, 0x5d, 0xc0, 0x0c, 0xc0, 0x29, /* :7a]...) */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x29, 0xc0, 0x34, 0x00, 0x0c, /* 10.).4.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x34 /* 4500w.4 */ +}; + +/* Frame (497 bytes) */ +static const unsigned char pkt53[497] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x01, 0xe3, 0x67, 0xce, 0x00, 0x00, 0xff, 0x11, /* ..g..... */ +0xb0, 0x93, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0xcf, /* ........ */ +0x46, 0x4d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FM...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, /* ......Ca */ +0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, /* nonMF450 */ +0x30, 0x77, 0xc0, 0x0c, 0x06, 0x72, 0x6f, 0x75, /* 0w...rou */ +0x74, 0x65, 0x72, 0xc0, 0x1a, 0x00, 0x01, 0x80, /* ter..... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, /* ....x... */ +0xa8, 0x00, 0x04, 0xc0, 0x2b, 0x00, 0x21, 0x80, /* ....+.!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x02, 0x03, 0xc0, 0x3a, 0xc0, /* ......:. */ +0x2b, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, /* +....... */ +0x94, 0x01, 0x56, 0x09, 0x74, 0x78, 0x74, 0x76, /* ..V.txtv */ +0x65, 0x72, 0x73, 0x3d, 0x31, 0x07, 0x72, 0x70, /* ers=1.rp */ +0x3d, 0x61, 0x75, 0x74, 0x6f, 0x05, 0x6e, 0x6f, /* =auto.no */ +0x74, 0x65, 0x3d, 0x08, 0x71, 0x74, 0x6f, 0x74, /* te=.qtot */ +0x61, 0x6c, 0x3d, 0x31, 0x0b, 0x70, 0x72, 0x69, /* al=1.pri */ +0x6f, 0x72, 0x69, 0x74, 0x79, 0x3d, 0x32, 0x30, /* ority=20 */ +0x11, 0x74, 0x79, 0x3d, 0x43, 0x61, 0x6e, 0x6f, /* .ty=Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x37, 0x30, /* n MF4570 */ +0x64, 0x77, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, /* dw.produ */ +0x63, 0x74, 0x3d, 0x28, 0x43, 0x61, 0x6e, 0x6f, /* ct=(Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* n MF4500 */ +0x77, 0x29, 0x1c, 0x70, 0x64, 0x6c, 0x3d, 0x61, /* w).pdl=a */ +0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, /* pplicati */ +0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, /* on/octet */ +0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2a, /* -stream* */ +0x61, 0x64, 0x6d, 0x69, 0x6e, 0x75, 0x72, 0x6c, /* adminurl */ +0x3d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, /* =http:// */ +0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x6c, /* router.l */ +0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x2f, 0x74, 0x5f, /* ocal./t_ */ +0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x2e, 0x63, /* welcom.c */ +0x67, 0x69, 0x0d, 0x75, 0x73, 0x62, 0x5f, 0x4d, /* gi.usb_M */ +0x46, 0x47, 0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* FG=Canon */ +0x27, 0x75, 0x73, 0x62, 0x5f, 0x4d, 0x44, 0x4c, /* 'usb_MDL */ +0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x20, 0x4d, /* =Canon M */ +0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0x20, 0x53, /* F4500w S */ +0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x28, 0x55, /* eries (U */ +0x46, 0x52, 0x49, 0x49, 0x20, 0x4c, 0x54, 0x29, /* FRII LT) */ +0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, /* .transpa */ +0x72, 0x65, 0x6e, 0x74, 0x3d, 0x46, 0x08, 0x42, /* rent=F.B */ +0x69, 0x6e, 0x61, 0x72, 0x79, 0x3d, 0x46, 0x06, /* inary=F. */ +0x54, 0x42, 0x43, 0x50, 0x3d, 0x46, 0x07, 0x43, /* TBCP=F.C */ +0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x46, 0x08, 0x43, /* olor=F.C */ +0x6f, 0x70, 0x69, 0x65, 0x73, 0x3d, 0x54, 0x08, /* opies=T. */ +0x44, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x3d, 0x54, /* Duplex=T */ +0x0d, 0x50, 0x61, 0x70, 0x65, 0x72, 0x43, 0x75, /* .PaperCu */ +0x73, 0x74, 0x6f, 0x6d, 0x3d, 0x54, 0x06, 0x42, /* stom=T.B */ +0x69, 0x6e, 0x64, 0x3d, 0x46, 0x09, 0x43, 0x6f, /* ind=F.Co */ +0x6c, 0x6c, 0x61, 0x74, 0x65, 0x3d, 0x54, 0x06, /* llate=T. */ +0x53, 0x6f, 0x72, 0x74, 0x3d, 0x54, 0x08, 0x53, /* Sort=T.S */ +0x74, 0x61, 0x70, 0x6c, 0x65, 0x3d, 0x46, 0x07, /* taple=F. */ +0x50, 0x75, 0x6e, 0x63, 0x68, 0x3d, 0x46, 0x11, /* Punch=F. */ +0x50, 0x61, 0x70, 0x65, 0x72, 0x4d, 0x61, 0x78, /* PaperMax */ +0x3d, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x41, /* =legal-A */ +0x34 /* 4 */ +}; + +/* Frame (360 bytes) */ +static const unsigned char pkt54[360] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x01, 0x5a, 0x45, 0xa1, 0x00, 0x00, 0xff, 0x11, /* .ZE..... */ +0xd2, 0xe3, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x46, /* .......F */ +0x63, 0x18, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* c....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x6a, 0x03, 0x31, 0x30, 0x36, /* ...j.106 */ +0x01, 0x30, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, /* .0.168.1 */ +0x39, 0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, /* 92.in-ad */ +0x64, 0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, /* dr.arpa. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, /* ........ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x01, 0x32, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .2.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x31, 0x01, 0x30, 0x01, 0x30, 0x01, 0x34, /* .1.0.0.4 */ +0x03, 0x69, 0x70, 0x36, 0xc0, 0x40, 0x00, 0x0c, /* .ip6.@.. */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x02, /* .....x.. */ +0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, /* ...x.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, /* .......p */ +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x41, /* I?Y.~..A */ +0x01, 0x42, 0x01, 0x45, 0x01, 0x37, 0x01, 0x39, /* .B.E.7.9 */ +0x01, 0x38, 0x01, 0x39, 0x01, 0x35, 0x01, 0x46, /* .8.9.5.F */ +0x01, 0x33, 0x01, 0x39, 0x01, 0x34, 0x01, 0x30, /* .3.9.4.0 */ +0x01, 0x37, 0x01, 0x44, 0x01, 0x39, 0x01, 0x30, /* .7.D.9.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, /* .0.0.0.0 */ +0x01, 0x38, 0x01, 0x45, 0x01, 0x46, 0xc0, 0xae, /* .8.E.F.. */ +0x00, 0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, /* ......./ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, /* .....x.. */ +0xc0, 0x0c, 0x00, 0x04, 0x40, 0x00, 0x00, 0x08 /* ....@... */ +}; + +/* Frame (140 bytes) */ +static const unsigned char pkt55[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x0a, 0x23, 0x00, 0x00, 0xff, 0x11, /* .~.#.... */ +0x08, 0x9e, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (106 bytes) */ +static const unsigned char pkt56[106] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x5c, 0x45, 0xa5, 0x00, 0x00, 0xff, 0x11, /* .\E..... */ +0xd3, 0xdd, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x48, /* .......H */ +0x7b, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* {....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0xc0, /* al...... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x0c /* .. */ +}; + +/* Frame (106 bytes) */ +static const unsigned char pkt57[106] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x5c, 0x0a, 0x24, 0x00, 0x00, 0xff, 0x11, /* .\.$.... */ +0x08, 0xbf, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x48, /* .......H */ +0x75, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* u-...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0xc0, /* al...... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x0c /* .. */ +}; + +/* Frame (850 bytes) */ +static const unsigned char pkt58[850] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x03, 0x44, 0x45, 0xac, 0x00, 0x00, 0xff, 0x11, /* .DE..... */ +0xd0, 0xee, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x03, 0x30, /* .......0 */ +0xfa, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* .n...... */ +0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0x00, /* ation.3. */ +0x0c, 0x00, 0x01, 0x0b, 0x5f, 0x75, 0x64, 0x69, /* ...._udi */ +0x73, 0x6b, 0x73, 0x2d, 0x73, 0x73, 0x68, 0xc0, /* sks-ssh. */ +0x33, 0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, /* 3....._h */ +0x74, 0x74, 0x70, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ttp.3... */ +0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, /* .._rfb.3 */ +0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, /* ....._pd */ +0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, /* l-datast */ +0x72, 0x65, 0x61, 0x6d, 0xc0, 0x33, 0x00, 0x0c, /* ream.3.. */ +0x00, 0x01, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, /* ..._prin */ +0x74, 0x65, 0x72, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ter.3... */ +0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x90, 0x00, 0x02, 0xc0, 0x2e, 0xc0, /* ........ */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x02, 0xc0, 0x51, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..Q..... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x02, 0xc0, /* ........ */ +0x63, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* c....... */ +0x00, 0x11, 0x91, 0x00, 0x02, 0xc0, 0x6f, 0xc0, /* ......o. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x02, 0xc0, 0x7a, 0xc0, 0x0c, 0x00, /* ....z... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x02, 0xc0, 0x90, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x31, 0x2e, /* ......1. */ +0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x48, /* server-H */ +0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, 0x57, /* P-Z210-W */ +0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, /* orkstati */ +0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, 0x33, /* on [e8:3 */ +0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, 0x3a, /* 9:35:44: */ +0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, 0x3e, /* fe:d4].> */ +0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* .>...... */ +0x11, 0x91, 0x00, 0x2a, 0x27, 0x63, 0x61, 0x74, /* ...*'cat */ +0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, /* ro-OptiP */ +0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, /* lex-3010 */ +0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, /* [a4:1f: */ +0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x62, /* 72:53:9b */ +0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, /* :c6].>.> */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, 0x3a, /* -EL [a4: */ +0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, /* 1f:72:53 */ +0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, 0xc0, /* :a0:f7]. */ +0x3e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, /* >.>..... */ +0x00, 0x11, 0x91, 0x00, 0x27, 0x24, 0x64, 0x63, /* ....'$dc */ +0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, /* -OptiPle */ +0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, 0x5b, /* x-3010 [ */ +0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, /* a4:1f:72 */ +0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, 0x61, /* :53:92:a */ +0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* 6].>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x1d, /* ........ */ +0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, /* .ubuntu */ +0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, 0x32, /* [00:0c:2 */ +0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, 0x3a, /* 9:6a:2e: */ +0x37, 0x61, 0x5d, 0xc0, 0x3e, 0xc0, 0x51, 0x00, /* 7a].>.Q. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x16, 0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, /* OptiPlex */ +0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, /* -3010.Q. */ +0x51, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* Q....... */ +0x91, 0x00, 0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0xc0, 0x51, 0xc0, 0x51, /* o-EL.Q.Q */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x13, 0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, /* ...dc-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, 0x63, 0x00, /* 010.Q.c. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, 0x72, /* *'dc's r */ +0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, /* emote de */ +0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, /* sktop on */ +0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x63, 0xc0, 0x63, 0x00, 0x0c, 0x00, /* 0.c.c... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0f, 0x0c, /* ........ */ +0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, /* CanonMF4 */ +0x35, 0x30, 0x30, 0x77, 0xc0, 0x63, 0xc0, 0x6f, /* 500w.c.o */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x6f, 0xc0, 0x7a, 0x00, 0x0c, /* 10.o.z.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x7a, 0xc0, /* 4500w.z. */ +0x90, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x92, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x90 /* .. */ +}; + +/* Frame (850 bytes) */ +static const unsigned char pkt59[850] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x03, 0x44, 0x0a, 0x25, 0x00, 0x00, 0xff, 0x11, /* .D.%.... */ +0x05, 0xd6, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x03, 0x30, /* .......0 */ +0xf3, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* ........ */ +0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0x00, /* ation.3. */ +0x0c, 0x00, 0x01, 0x0b, 0x5f, 0x75, 0x64, 0x69, /* ...._udi */ +0x73, 0x6b, 0x73, 0x2d, 0x73, 0x73, 0x68, 0xc0, /* sks-ssh. */ +0x33, 0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, /* 3....._h */ +0x74, 0x74, 0x70, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ttp.3... */ +0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, /* .._rfb.3 */ +0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, /* ....._pd */ +0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, /* l-datast */ +0x72, 0x65, 0x61, 0x6d, 0xc0, 0x33, 0x00, 0x0c, /* ream.3.. */ +0x00, 0x01, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, /* ..._prin */ +0x74, 0x65, 0x72, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ter.3... */ +0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x90, 0x00, 0x02, 0xc0, 0x2e, 0xc0, /* ........ */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x02, 0xc0, 0x51, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..Q..... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x02, 0xc0, /* ........ */ +0x63, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* c....... */ +0x00, 0x11, 0x91, 0x00, 0x02, 0xc0, 0x6f, 0xc0, /* ......o. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x02, 0xc0, 0x7a, 0xc0, 0x0c, 0x00, /* ....z... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x02, 0xc0, 0x90, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x31, 0x2e, /* ......1. */ +0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x48, /* server-H */ +0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, 0x57, /* P-Z210-W */ +0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, /* orkstati */ +0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, 0x33, /* on [e8:3 */ +0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, 0x3a, /* 9:35:44: */ +0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, 0x3e, /* fe:d4].> */ +0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* .>...... */ +0x11, 0x91, 0x00, 0x2a, 0x27, 0x63, 0x61, 0x74, /* ...*'cat */ +0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, /* ro-OptiP */ +0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, /* lex-3010 */ +0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, /* [a4:1f: */ +0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x62, /* 72:53:9b */ +0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, /* :c6].>.> */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, 0x3a, /* -EL [a4: */ +0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, /* 1f:72:53 */ +0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, 0xc0, /* :a0:f7]. */ +0x3e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, /* >.>..... */ +0x00, 0x11, 0x91, 0x00, 0x27, 0x24, 0x64, 0x63, /* ....'$dc */ +0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, /* -OptiPle */ +0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, 0x5b, /* x-3010 [ */ +0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, /* a4:1f:72 */ +0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, 0x61, /* :53:92:a */ +0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* 6].>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x1d, /* ........ */ +0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, /* .ubuntu */ +0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, 0x32, /* [00:0c:2 */ +0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, 0x3a, /* 9:6a:2e: */ +0x37, 0x61, 0x5d, 0xc0, 0x3e, 0xc0, 0x51, 0x00, /* 7a].>.Q. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x16, 0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, /* OptiPlex */ +0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, /* -3010.Q. */ +0x51, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* Q....... */ +0x91, 0x00, 0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0xc0, 0x51, 0xc0, 0x51, /* o-EL.Q.Q */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x13, 0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, /* ...dc-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, 0x63, 0x00, /* 010.Q.c. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, 0x72, /* *'dc's r */ +0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, /* emote de */ +0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, /* sktop on */ +0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x63, 0xc0, 0x63, 0x00, 0x0c, 0x00, /* 0.c.c... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0f, 0x0c, /* ........ */ +0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, /* CanonMF4 */ +0x35, 0x30, 0x30, 0x77, 0xc0, 0x63, 0xc0, 0x6f, /* 500w.c.o */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x6f, 0xc0, 0x7a, 0x00, 0x0c, /* 10.o.z.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x7a, 0xc0, /* 4500w.z. */ +0x90, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x92, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x90 /* .. */ +}; + +/* Frame (850 bytes) */ +static const unsigned char pkt60[850] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x03, 0x44, 0x45, 0xd0, 0x00, 0x00, 0xff, 0x11, /* .DE..... */ +0xd0, 0xca, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x03, 0x30, /* .......0 */ +0x81, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* ........ */ +0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0x00, /* ation.3. */ +0x0c, 0x00, 0x01, 0x0b, 0x5f, 0x75, 0x64, 0x69, /* ...._udi */ +0x73, 0x6b, 0x73, 0x2d, 0x73, 0x73, 0x68, 0xc0, /* sks-ssh. */ +0x33, 0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, /* 3....._h */ +0x74, 0x74, 0x70, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ttp.3... */ +0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, /* .._rfb.3 */ +0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, /* ....._pd */ +0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, /* l-datast */ +0x72, 0x65, 0x61, 0x6d, 0xc0, 0x33, 0x00, 0x0c, /* ream.3.. */ +0x00, 0x01, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, /* ..._prin */ +0x74, 0x65, 0x72, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ter.3... */ +0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x87, 0x00, 0x02, 0xc0, 0x2e, 0xc0, /* ........ */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x88, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x02, 0xc0, 0x51, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..Q..... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x02, 0xc0, /* ........ */ +0x63, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* c....... */ +0x00, 0x11, 0x88, 0x00, 0x02, 0xc0, 0x6f, 0xc0, /* ......o. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x88, 0x00, 0x02, 0xc0, 0x7a, 0xc0, 0x0c, 0x00, /* ....z... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x02, 0xc0, 0x90, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x31, 0x2e, /* ......1. */ +0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x48, /* server-H */ +0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, 0x57, /* P-Z210-W */ +0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, /* orkstati */ +0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, 0x33, /* on [e8:3 */ +0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, 0x3a, /* 9:35:44: */ +0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, 0x3e, /* fe:d4].> */ +0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* .>...... */ +0x11, 0x88, 0x00, 0x2a, 0x27, 0x63, 0x61, 0x74, /* ...*'cat */ +0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, /* ro-OptiP */ +0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, /* lex-3010 */ +0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, /* [a4:1f: */ +0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x62, /* 72:53:9b */ +0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, /* :c6].>.> */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, 0x3a, /* -EL [a4: */ +0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, /* 1f:72:53 */ +0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, 0xc0, /* :a0:f7]. */ +0x3e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, /* >.>..... */ +0x00, 0x11, 0x88, 0x00, 0x27, 0x24, 0x64, 0x63, /* ....'$dc */ +0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, /* -OptiPle */ +0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, 0x5b, /* x-3010 [ */ +0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, /* a4:1f:72 */ +0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, 0x61, /* :53:92:a */ +0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* 6].>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x1d, /* ........ */ +0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, /* .ubuntu */ +0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, 0x32, /* [00:0c:2 */ +0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, 0x3a, /* 9:6a:2e: */ +0x37, 0x61, 0x5d, 0xc0, 0x3e, 0xc0, 0x51, 0x00, /* 7a].>.Q. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x16, 0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, /* OptiPlex */ +0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, /* -3010.Q. */ +0x51, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* Q....... */ +0x88, 0x00, 0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0xc0, 0x51, 0xc0, 0x51, /* o-EL.Q.Q */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x13, 0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, /* ...dc-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, 0x63, 0x00, /* 010.Q.c. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, 0x72, /* *'dc's r */ +0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, /* emote de */ +0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, /* sktop on */ +0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x63, 0xc0, 0x63, 0x00, 0x0c, 0x00, /* 0.c.c... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0f, 0x0c, /* ........ */ +0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, /* CanonMF4 */ +0x35, 0x30, 0x30, 0x77, 0xc0, 0x63, 0xc0, 0x6f, /* 500w.c.o */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x6f, 0xc0, 0x7a, 0x00, 0x0c, /* 10.o.z.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x7a, 0xc0, /* 4500w.z. */ +0x90, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x89, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x90 /* .. */ +}; + +/* Frame (850 bytes) */ +static const unsigned char pkt61[850] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x03, 0x44, 0x0a, 0x26, 0x00, 0x00, 0xff, 0x11, /* .D.&.... */ +0x05, 0xd5, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x03, 0x30, /* .......0 */ +0x7b, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* {....... */ +0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0xc0, 0x23, 0x00, 0x0c, 0x00, 0x01, /* cp.#.... */ +0x0c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x74, /* ._workst */ +0x61, 0x74, 0x69, 0x6f, 0x6e, 0xc0, 0x33, 0x00, /* ation.3. */ +0x0c, 0x00, 0x01, 0x0b, 0x5f, 0x75, 0x64, 0x69, /* ...._udi */ +0x73, 0x6b, 0x73, 0x2d, 0x73, 0x73, 0x68, 0xc0, /* sks-ssh. */ +0x33, 0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, /* 3....._h */ +0x74, 0x74, 0x70, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ttp.3... */ +0x01, 0x04, 0x5f, 0x72, 0x66, 0x62, 0xc0, 0x33, /* .._rfb.3 */ +0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, 0x70, 0x64, /* ....._pd */ +0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x73, 0x74, /* l-datast */ +0x72, 0x65, 0x61, 0x6d, 0xc0, 0x33, 0x00, 0x0c, /* ream.3.. */ +0x00, 0x01, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, /* ..._prin */ +0x74, 0x65, 0x72, 0xc0, 0x33, 0x00, 0x0c, 0x00, /* ter.3... */ +0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* ........ */ +0x00, 0x11, 0x87, 0x00, 0x02, 0xc0, 0x2e, 0xc0, /* ........ */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x88, 0x00, 0x02, 0xc0, 0x3e, 0xc0, 0x0c, 0x00, /* ....>... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x02, 0xc0, 0x51, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ..Q..... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x02, 0xc0, /* ........ */ +0x63, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* c....... */ +0x00, 0x11, 0x88, 0x00, 0x02, 0xc0, 0x6f, 0xc0, /* ......o. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x88, 0x00, 0x02, 0xc0, 0x7a, 0xc0, 0x0c, 0x00, /* ....z... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x02, 0xc0, 0x90, 0xc0, 0x2e, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0c, 0x09, /* ........ */ +0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, /* Chenbo-P */ +0x43, 0xc0, 0x2e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, /* C...>... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x31, 0x2e, /* ......1. */ +0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2d, 0x48, /* server-H */ +0x50, 0x2d, 0x5a, 0x32, 0x31, 0x30, 0x2d, 0x57, /* P-Z210-W */ +0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x74, 0x69, /* orkstati */ +0x6f, 0x6e, 0x20, 0x5b, 0x65, 0x38, 0x3a, 0x33, /* on [e8:3 */ +0x39, 0x3a, 0x33, 0x35, 0x3a, 0x34, 0x34, 0x3a, /* 9:35:44: */ +0x66, 0x65, 0x3a, 0x64, 0x34, 0x5d, 0xc0, 0x3e, /* fe:d4].> */ +0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* .>...... */ +0x11, 0x88, 0x00, 0x2a, 0x27, 0x63, 0x61, 0x74, /* ...*'cat */ +0x72, 0x6f, 0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, /* ro-OptiP */ +0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, /* lex-3010 */ +0x20, 0x5b, 0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, /* [a4:1f: */ +0x37, 0x32, 0x3a, 0x35, 0x33, 0x3a, 0x39, 0x62, /* 72:53:9b */ +0x3a, 0x63, 0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, /* :c6].>.> */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x1f, 0x1c, 0x63, 0x61, 0x74, 0x72, 0x6f, /* ...catro */ +0x2d, 0x45, 0x4c, 0x20, 0x5b, 0x61, 0x34, 0x3a, /* -EL [a4: */ +0x31, 0x66, 0x3a, 0x37, 0x32, 0x3a, 0x35, 0x33, /* 1f:72:53 */ +0x3a, 0x61, 0x30, 0x3a, 0x66, 0x37, 0x5d, 0xc0, /* :a0:f7]. */ +0x3e, 0xc0, 0x3e, 0x00, 0x0c, 0x00, 0x01, 0x00, /* >.>..... */ +0x00, 0x11, 0x88, 0x00, 0x27, 0x24, 0x64, 0x63, /* ....'$dc */ +0x2d, 0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, /* -OptiPle */ +0x78, 0x2d, 0x33, 0x30, 0x31, 0x30, 0x20, 0x5b, /* x-3010 [ */ +0x61, 0x34, 0x3a, 0x31, 0x66, 0x3a, 0x37, 0x32, /* a4:1f:72 */ +0x3a, 0x35, 0x33, 0x3a, 0x39, 0x32, 0x3a, 0x61, /* :53:92:a */ +0x36, 0x5d, 0xc0, 0x3e, 0xc0, 0x3e, 0x00, 0x0c, /* 6].>.>.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x1d, /* ........ */ +0x1a, 0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, /* .ubuntu */ +0x5b, 0x30, 0x30, 0x3a, 0x30, 0x63, 0x3a, 0x32, /* [00:0c:2 */ +0x39, 0x3a, 0x36, 0x61, 0x3a, 0x32, 0x65, 0x3a, /* 9:6a:2e: */ +0x37, 0x61, 0x5d, 0xc0, 0x3e, 0xc0, 0x51, 0x00, /* 7a].>.Q. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x16, 0x13, 0x63, 0x61, 0x74, 0x72, 0x6f, 0x2d, /* ..catro- */ +0x4f, 0x70, 0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, /* OptiPlex */ +0x2d, 0x33, 0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, /* -3010.Q. */ +0x51, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* Q....... */ +0x88, 0x00, 0x0b, 0x08, 0x63, 0x61, 0x74, 0x72, /* ....catr */ +0x6f, 0x2d, 0x45, 0x4c, 0xc0, 0x51, 0xc0, 0x51, /* o-EL.Q.Q */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x13, 0x10, 0x64, 0x63, 0x2d, 0x4f, 0x70, /* ...dc-Op */ +0x74, 0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, /* tiPlex-3 */ +0x30, 0x31, 0x30, 0xc0, 0x51, 0xc0, 0x63, 0x00, /* 010.Q.c. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, /* ........ */ +0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, 0x72, /* *'dc's r */ +0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, 0x65, /* emote de */ +0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, 0x6e, /* sktop on */ +0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, 0x69, /* dc-Opti */ +0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, 0x31, /* Plex-301 */ +0x30, 0xc0, 0x63, 0xc0, 0x63, 0x00, 0x0c, 0x00, /* 0.c.c... */ +0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0f, 0x0c, /* ........ */ +0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, /* CanonMF4 */ +0x35, 0x30, 0x30, 0x77, 0xc0, 0x63, 0xc0, 0x6f, /* 500w.c.o */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x88, /* ........ */ +0x00, 0x2a, 0x27, 0x64, 0x63, 0x27, 0x73, 0x20, /* .*'dc's */ +0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x20, 0x64, /* remote d */ +0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x20, 0x6f, /* esktop o */ +0x6e, 0x20, 0x64, 0x63, 0x2d, 0x4f, 0x70, 0x74, /* n dc-Opt */ +0x69, 0x50, 0x6c, 0x65, 0x78, 0x2d, 0x33, 0x30, /* iPlex-30 */ +0x31, 0x30, 0xc0, 0x6f, 0xc0, 0x7a, 0x00, 0x0c, /* 10.o.z.. */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x88, 0x00, 0x0f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, 0x7a, 0xc0, /* 4500w.z. */ +0x90, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x89, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, /* ....Cano */ +0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* nMF4500w */ +0xc0, 0x90 /* .. */ +}; + + +MDNS_TEST_SEQ mdns_query_and_response_chaos[] = { + {TITLE, "Query and response", 18, 0}, + + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + {INJECT, (char*)&pkt4[0], sizeof(pkt4), 0}, + {INJECT, (char*)&pkt5[0], sizeof(pkt5), 0}, + {INJECT, (char*)&pkt6[0], sizeof(pkt6), 0}, + {INJECT, (char*)&pkt7[0], sizeof(pkt7), 0}, + {INJECT, (char*)&pkt8[0], sizeof(pkt8), 0}, + {INJECT, (char*)&pkt9[0], sizeof(pkt9), 0}, + {INJECT, (char*)&pkt10[0], sizeof(pkt10), 0}, + {INJECT, (char*)&pkt11[0], sizeof(pkt11), 0}, + {INJECT, (char*)&pkt12[0], sizeof(pkt12), 0}, + {INJECT, (char*)&pkt13[0], sizeof(pkt13), 0}, + {INJECT, (char*)&pkt14[0], sizeof(pkt14), 0}, + {INJECT, (char*)&pkt15[0], sizeof(pkt15), 0}, + {INJECT, (char*)&pkt16[0], sizeof(pkt16), 0}, + {INJECT, (char*)&pkt17[0], sizeof(pkt17), 0}, + {INJECT, (char*)&pkt18[0], sizeof(pkt18), 0}, + {INJECT, (char*)&pkt19[0], sizeof(pkt19), 0}, + {INJECT, (char*)&pkt20[0], sizeof(pkt20), 0}, + {INJECT, (char*)&pkt21[0], sizeof(pkt21), 0}, + {INJECT, (char*)&pkt22[0], sizeof(pkt22), 0}, + {INJECT, (char*)&pkt23[0], sizeof(pkt23), 0}, + {INJECT, (char*)&pkt24[0], sizeof(pkt24), 0}, + {INJECT, (char*)&pkt25[0], sizeof(pkt25), 0}, + {INJECT, (char*)&pkt26[0], sizeof(pkt26), 0}, + {INJECT, (char*)&pkt27[0], sizeof(pkt27), 0}, + {INJECT, (char*)&pkt28[0], sizeof(pkt28), 0}, + {INJECT, (char*)&pkt29[0], sizeof(pkt29), 0}, + {INJECT, (char*)&pkt30[0], sizeof(pkt30), 0}, + {INJECT, (char*)&pkt31[0], sizeof(pkt31), 0}, + {INJECT, (char*)&pkt32[0], sizeof(pkt32), 0}, + {INJECT, (char*)&pkt33[0], sizeof(pkt33), 0}, + {INJECT, (char*)&pkt34[0], sizeof(pkt34), 0}, + {INJECT, (char*)&pkt35[0], sizeof(pkt35), 0}, + {INJECT, (char*)&pkt36[0], sizeof(pkt36), 0}, + {INJECT, (char*)&pkt37[0], sizeof(pkt37), 0}, + {INJECT, (char*)&pkt38[0], sizeof(pkt38), 0}, + {INJECT, (char*)&pkt39[0], sizeof(pkt39), 0}, + {INJECT, (char*)&pkt40[0], sizeof(pkt40), 0}, + {INJECT, (char*)&pkt41[0], sizeof(pkt41), 0}, + {INJECT, (char*)&pkt42[0], sizeof(pkt42), 0}, + {INJECT, (char*)&pkt43[0], sizeof(pkt43), 0}, + {INJECT, (char*)&pkt44[0], sizeof(pkt44), 0}, + {INJECT, (char*)&pkt45[0], sizeof(pkt45), 0}, + {INJECT, (char*)&pkt46[0], sizeof(pkt46), 0}, + {INJECT, (char*)&pkt47[0], sizeof(pkt47), 0}, + {INJECT, (char*)&pkt48[0], sizeof(pkt48), 0}, + {INJECT, (char*)&pkt49[0], sizeof(pkt49), 0}, + {INJECT, (char*)&pkt50[0], sizeof(pkt50), 0}, + {INJECT, (char*)&pkt51[0], sizeof(pkt51), 0}, + {INJECT, (char*)&pkt52[0], sizeof(pkt52), 0}, + {INJECT, (char*)&pkt53[0], sizeof(pkt53), 0}, + {INJECT, (char*)&pkt54[0], sizeof(pkt54), 0}, + {INJECT, (char*)&pkt55[0], sizeof(pkt55), 0}, + {INJECT, (char*)&pkt56[0], sizeof(pkt56), 0}, + {INJECT, (char*)&pkt57[0], sizeof(pkt57), 0}, + {INJECT, (char*)&pkt58[0], sizeof(pkt58), 0}, + {INJECT, (char*)&pkt59[0], sizeof(pkt59), 0}, + {INJECT, (char*)&pkt60[0], sizeof(pkt60), 0}, + {INJECT, (char*)&pkt61[0], sizeof(pkt61), 0}, + {WAIT, NX_NULL, 0, 5}, +}; + +int mdns_query_and_response_chaos_size = sizeof(mdns_query_and_response_chaos) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_query_during_probing_test.c b/test/regression/mdns_test/mdns_query_during_probing_test.c new file mode 100644 index 00000000..c478cb37 --- /dev/null +++ b/test/regression/mdns_test/mdns_query_during_probing_test.c @@ -0,0 +1,337 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (226 bytes) */ +static const unsigned char pkt1[226] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xd4, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xda, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc0, /* ........ */ +0x6d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* m....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x04, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* .test._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, /* ..test._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00 /* .. */ +}; + +/* Frame (226 bytes) */ +static const unsigned char pkt2[226] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xd4, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd9, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc0, /* ........ */ +0x6d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* m....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x04, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* .test._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, /* ..test._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00 /* .. */ +}; + +/* Frame (226 bytes) */ +static const unsigned char pkt3[226] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xd4, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd8, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xc0, /* ........ */ +0x6d, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* m....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x04, 0x74, 0x65, /* ......te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* .test._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, /* ..test._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00 /* .. */ +}; + +/* Frame (338 bytes) */ +static const unsigned char pkt4[338] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x44, 0x00, 0x04, 0x40, 0x00, 0xff, 0x11, /* .D..@... */ +0x8f, 0x67, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .g...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x30, /* .......0 */ +0x12, 0x57, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .W...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, /* .@.test. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x16, 0x04, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, /* test._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1d, 0x04, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + +/* Frame (338 bytes) */ +static const unsigned char pkt5[338] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x44, 0x00, 0x05, 0x40, 0x00, 0xff, 0x11, /* .D..@... */ +0x8f, 0x66, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .f...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x30, /* .......0 */ +0x12, 0x57, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .W...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, /* .@.test. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x16, 0x04, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, /* test._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1d, 0x04, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + +/* Frame (338 bytes) */ +static const unsigned char pkt6[338] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x44, 0x00, 0x06, 0x40, 0x00, 0xff, 0x11, /* .D..@... */ +0x8f, 0x65, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .e...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x30, /* .......0 */ +0x12, 0x57, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .W...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x04, 0x74, 0x65, 0x73, 0x74, 0x04, /* .@.test. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x04, 0x5f, 0x69, 0x70, /* d...._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x16, 0x04, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, /* test._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1d, 0x04, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + +/* Frame (86 bytes) */ +static const unsigned char pkt7[86] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x48, 0x00, 0xf6, 0x00, 0x00, 0xff, 0x11, /* .H...... */ +0x12, 0x01, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x34, /* .......4 */ +0x9a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .e...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, /* est._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x00, 0x01, /* cal..!.. */ +0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01 /* ...... */ +}; + +/* Frame (289 bytes) */ +static const unsigned char pkt8[289] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x13, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x95, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xff, /* ........ */ +0x12, 0xde, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x04, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, /* est._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, /* test._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* B.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, /* ...x...A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x40, 0x04, 0x74, 0x65, 0x73, /* ...@.tes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1d, 0x04, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40 /* @ */ +}; + + + +static MDNS_SERVICE mdns_service = {"test", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_query_during_probing[] = { + {TITLE, "Query during probing", 20, 0}, + + /* Add a service. */ + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + + /* Wait for the first probing. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 1}, + + /* Inject a query. */ + {INJECT, (char*)&pkt7[0], sizeof(pkt7), 0}, + + /* No response is expected. */ + {MDNS_REJECT_DATA_V4, (char*)&pkt8[0], sizeof(pkt8), 1}, + + /* Wait probing and announcement finish. */ + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject a query. */ + {INJECT, (char*)&pkt7[0], sizeof(pkt7), 0}, + + /* A response is expected. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt8[0], sizeof(pkt8), 1}, +}; + +int mdns_query_during_probing_size = sizeof(mdns_query_during_probing) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_query_http_tcp_test.c b/test/regression/mdns_test/mdns_query_http_tcp_test.c new file mode 100644 index 00000000..2fdbc5c5 --- /dev/null +++ b/test/regression/mdns_test/mdns_query_http_tcp_test.c @@ -0,0 +1,91 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0xd9, 0xc1, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x2c, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ,....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (153 bytes) */ +static const unsigned char pkt2[153] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (135 bytes) */ +static const unsigned char pkt3[135] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x79, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .y..@... */ +0xd9, 0x85, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x65, /* .......e */ +0x31, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 1....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x1f, /* ........ */ +0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, /* .CanonMF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x05, 0x5f, 0x68, /* 4500w._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_http._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_query_http_tcp[] = { + {TITLE, "Query _http._tcp", 16, 0}, + + /* Add a query. */ + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 5}, + + /* Set callback for mask 2. */ + {MDNS_SET_SERVICE_CALLBACK, (UCHAR*)2, NX_MDNS_PEER_SERVICE_RECEIVED, 0}, + + /* Inject a response. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* Check query with known answer. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 5}, + + /* Check callback invoked. */ + {MDNS_SET_SERVICE_CALLBACK_STATE, NX_NULL, 0, 3}, +}; + +int mdns_query_http_tcp_size = sizeof(mdns_query_http_tcp) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_query_pdl_datastram_tcp_test.c b/test/regression/mdns_test/mdns_query_pdl_datastram_tcp_test.c new file mode 100644 index 00000000..1635f348 --- /dev/null +++ b/test/regression/mdns_test/mdns_query_pdl_datastram_tcp_test.c @@ -0,0 +1,153 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (86 bytes) */ +static const unsigned char pkt1[86] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x48, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .H..@... */ +0xd9, 0xb7, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x34, /* .......4 */ +0x03, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .,...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* l..... */ +}; + +/* Frame (496 bytes) */ +static const unsigned char pkt2[496] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x01, 0xe2, 0x77, 0x3a, 0x00, 0x00, 0xff, 0x11, /* ..w:.... */ +0xa1, 0x28, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* .(...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0xce, /* ........ */ +0xee, 0x32, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .2...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, /* .....Can */ +0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* onMF4500 */ +0x77, 0xc0, 0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, /* w...rout */ +0x65, 0x72, 0xc0, 0x21, 0x00, 0x01, 0x80, 0x01, /* er.!.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x04, 0xc0, 0x32, 0x00, 0x21, 0x80, 0x01, /* ...2.!.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, /* ...x.... */ +0x00, 0x00, 0x23, 0x8c, 0xc0, 0x41, 0xc0, 0x32, /* ..#..A.2 */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x01, 0x4e, 0x09, 0x74, 0x78, 0x74, 0x76, 0x65, /* .N.txtve */ +0x72, 0x73, 0x3d, 0x31, 0x05, 0x6e, 0x6f, 0x74, /* rs=1.not */ +0x65, 0x3d, 0x08, 0x71, 0x74, 0x6f, 0x74, 0x61, /* e=.qtota */ +0x6c, 0x3d, 0x31, 0x0b, 0x70, 0x72, 0x69, 0x6f, /* l=1.prio */ +0x72, 0x69, 0x74, 0x79, 0x3d, 0x31, 0x30, 0x11, /* rity=10. */ +0x74, 0x79, 0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ty=Canon */ +0x20, 0x4d, 0x46, 0x34, 0x35, 0x37, 0x30, 0x64, /* MF4570d */ +0x77, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, /* w.produc */ +0x74, 0x3d, 0x28, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* t=(Canon */ +0x20, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, /* MF4500w */ +0x29, 0x1c, 0x70, 0x64, 0x6c, 0x3d, 0x61, 0x70, /* ).pdl=ap */ +0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, /* plicatio */ +0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, /* n/octet- */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2a, 0x61, /* stream*a */ +0x64, 0x6d, 0x69, 0x6e, 0x75, 0x72, 0x6c, 0x3d, /* dminurl= */ +0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x72, /* http://r */ +0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x6c, 0x6f, /* outer.lo */ +0x63, 0x61, 0x6c, 0x2e, 0x2f, 0x74, 0x5f, 0x77, /* cal./t_w */ +0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x67, /* elcom.cg */ +0x69, 0x0d, 0x75, 0x73, 0x62, 0x5f, 0x4d, 0x46, /* i.usb_MF */ +0x47, 0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x27, /* G=Canon' */ +0x75, 0x73, 0x62, 0x5f, 0x4d, 0x44, 0x4c, 0x3d, /* usb_MDL= */ +0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x20, 0x4d, 0x46, /* Canon MF */ +0x34, 0x35, 0x30, 0x30, 0x77, 0x20, 0x53, 0x65, /* 4500w Se */ +0x72, 0x69, 0x65, 0x73, 0x20, 0x28, 0x55, 0x46, /* ries (UF */ +0x52, 0x49, 0x49, 0x20, 0x4c, 0x54, 0x29, 0x0d, /* RII LT). */ +0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, /* transpar */ +0x65, 0x6e, 0x74, 0x3d, 0x46, 0x08, 0x42, 0x69, /* ent=F.Bi */ +0x6e, 0x61, 0x72, 0x79, 0x3d, 0x46, 0x06, 0x54, /* nary=F.T */ +0x42, 0x43, 0x50, 0x3d, 0x46, 0x07, 0x43, 0x6f, /* BCP=F.Co */ +0x6c, 0x6f, 0x72, 0x3d, 0x46, 0x08, 0x43, 0x6f, /* lor=F.Co */ +0x70, 0x69, 0x65, 0x73, 0x3d, 0x54, 0x08, 0x44, /* pies=T.D */ +0x75, 0x70, 0x6c, 0x65, 0x78, 0x3d, 0x54, 0x0d, /* uplex=T. */ +0x50, 0x61, 0x70, 0x65, 0x72, 0x43, 0x75, 0x73, /* PaperCus */ +0x74, 0x6f, 0x6d, 0x3d, 0x54, 0x06, 0x42, 0x69, /* tom=T.Bi */ +0x6e, 0x64, 0x3d, 0x46, 0x09, 0x43, 0x6f, 0x6c, /* nd=F.Col */ +0x6c, 0x61, 0x74, 0x65, 0x3d, 0x54, 0x06, 0x53, /* late=T.S */ +0x6f, 0x72, 0x74, 0x3d, 0x54, 0x08, 0x53, 0x74, /* ort=T.St */ +0x61, 0x70, 0x6c, 0x65, 0x3d, 0x46, 0x07, 0x50, /* aple=F.P */ +0x75, 0x6e, 0x63, 0x68, 0x3d, 0x46, 0x11, 0x50, /* unch=F.P */ +0x61, 0x70, 0x65, 0x72, 0x4d, 0x61, 0x78, 0x3d, /* aperMax= */ +0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x41, 0x34 /* legal-A4 */ +}; + +/* Frame (165 bytes) */ +static const unsigned char pkt3[165] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x97, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x67, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .g...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x83, /* ........ */ +0x26, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* &3...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, /* l......_ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x93, 0x00, 0x29, 0x0c, 0x43, 0x61, 0x6e, /* ...).Can */ +0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* onMF4500 */ +0x77, 0x0f, 0x5f, 0x70, 0x64, 0x6c, 0x2d, 0x64, /* w._pdl-d */ +0x61, 0x74, 0x61, 0x73, 0x74, 0x72, 0x65, 0x61, /* atastrea */ +0x6d, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* m._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + +/* Frame (165 bytes) */ +static const unsigned char pkt4[165] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x97, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x66, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .f...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x83, /* ........ */ +0x26, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* &5...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x5f, /* ......._ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x0f, 0x5f, /* l......_ */ +0x70, 0x64, 0x6c, 0x2d, 0x64, 0x61, 0x74, 0x61, /* pdl-data */ +0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x04, 0x5f, /* stream._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x91, 0x00, 0x29, 0x0c, 0x43, 0x61, 0x6e, /* ...).Can */ +0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* onMF4500 */ +0x77, 0x0f, 0x5f, 0x70, 0x64, 0x6c, 0x2d, 0x64, /* w._pdl-d */ +0x61, 0x74, 0x61, 0x73, 0x74, 0x72, 0x65, 0x61, /* atastrea */ +0x6d, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* m._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_pdl-datastream._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_query_pdl_datastream_tcp[] = { + {TITLE, "Query _pdl-datastream._tcp", 26, 0}, + + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 5}, + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 5}, +}; + +int mdns_query_pdl_datastream_tcp_size = sizeof(mdns_query_pdl_datastream_tcp) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_query_printer_tcp_test.c b/test/regression/mdns_test/mdns_query_printer_tcp_test.c new file mode 100644 index 00000000..908c3466 --- /dev/null +++ b/test/regression/mdns_test/mdns_query_printer_tcp_test.c @@ -0,0 +1,146 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" +/* Frame (79 bytes) */ +static const unsigned char pkt1[79] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x41, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .A..@... */ +0xd9, 0xbe, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2d, /* .......- */ +0xc5, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* al..... */ +}; + +/* Frame (497 bytes) */ +static const unsigned char pkt2[497] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x01, 0xe3, 0x77, 0x9c, 0x00, 0x00, 0xff, 0x11, /* ..w..... */ +0xa0, 0xc5, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0xcf, /* ........ */ +0x46, 0x4d, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FM...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, /* ......Ca */ +0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, /* nonMF450 */ +0x30, 0x77, 0xc0, 0x0c, 0x06, 0x72, 0x6f, 0x75, /* 0w...rou */ +0x74, 0x65, 0x72, 0xc0, 0x1a, 0x00, 0x01, 0x80, /* ter..... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, /* ....x... */ +0xa8, 0x00, 0x04, 0xc0, 0x2b, 0x00, 0x21, 0x80, /* ....+.!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x02, 0x03, 0xc0, 0x3a, 0xc0, /* ......:. */ +0x2b, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, /* +....... */ +0x94, 0x01, 0x56, 0x09, 0x74, 0x78, 0x74, 0x76, /* ..V.txtv */ +0x65, 0x72, 0x73, 0x3d, 0x31, 0x07, 0x72, 0x70, /* ers=1.rp */ +0x3d, 0x61, 0x75, 0x74, 0x6f, 0x05, 0x6e, 0x6f, /* =auto.no */ +0x74, 0x65, 0x3d, 0x08, 0x71, 0x74, 0x6f, 0x74, /* te=.qtot */ +0x61, 0x6c, 0x3d, 0x31, 0x0b, 0x70, 0x72, 0x69, /* al=1.pri */ +0x6f, 0x72, 0x69, 0x74, 0x79, 0x3d, 0x32, 0x30, /* ority=20 */ +0x11, 0x74, 0x79, 0x3d, 0x43, 0x61, 0x6e, 0x6f, /* .ty=Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x37, 0x30, /* n MF4570 */ +0x64, 0x77, 0x17, 0x70, 0x72, 0x6f, 0x64, 0x75, /* dw.produ */ +0x63, 0x74, 0x3d, 0x28, 0x43, 0x61, 0x6e, 0x6f, /* ct=(Cano */ +0x6e, 0x20, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, /* n MF4500 */ +0x77, 0x29, 0x1c, 0x70, 0x64, 0x6c, 0x3d, 0x61, /* w).pdl=a */ +0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, /* pplicati */ +0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, /* on/octet */ +0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2a, /* -stream* */ +0x61, 0x64, 0x6d, 0x69, 0x6e, 0x75, 0x72, 0x6c, /* adminurl */ +0x3d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, /* =http:// */ +0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x2e, 0x6c, /* router.l */ +0x6f, 0x63, 0x61, 0x6c, 0x2e, 0x2f, 0x74, 0x5f, /* ocal./t_ */ +0x77, 0x65, 0x6c, 0x63, 0x6f, 0x6d, 0x2e, 0x63, /* welcom.c */ +0x67, 0x69, 0x0d, 0x75, 0x73, 0x62, 0x5f, 0x4d, /* gi.usb_M */ +0x46, 0x47, 0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* FG=Canon */ +0x27, 0x75, 0x73, 0x62, 0x5f, 0x4d, 0x44, 0x4c, /* 'usb_MDL */ +0x3d, 0x43, 0x61, 0x6e, 0x6f, 0x6e, 0x20, 0x4d, /* =Canon M */ +0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0x20, 0x53, /* F4500w S */ +0x65, 0x72, 0x69, 0x65, 0x73, 0x20, 0x28, 0x55, /* eries (U */ +0x46, 0x52, 0x49, 0x49, 0x20, 0x4c, 0x54, 0x29, /* FRII LT) */ +0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, /* .transpa */ +0x72, 0x65, 0x6e, 0x74, 0x3d, 0x46, 0x08, 0x42, /* rent=F.B */ +0x69, 0x6e, 0x61, 0x72, 0x79, 0x3d, 0x46, 0x06, /* inary=F. */ +0x54, 0x42, 0x43, 0x50, 0x3d, 0x46, 0x07, 0x43, /* TBCP=F.C */ +0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x46, 0x08, 0x43, /* olor=F.C */ +0x6f, 0x70, 0x69, 0x65, 0x73, 0x3d, 0x54, 0x08, /* opies=T. */ +0x44, 0x75, 0x70, 0x6c, 0x65, 0x78, 0x3d, 0x54, /* Duplex=T */ +0x0d, 0x50, 0x61, 0x70, 0x65, 0x72, 0x43, 0x75, /* .PaperCu */ +0x73, 0x74, 0x6f, 0x6d, 0x3d, 0x54, 0x06, 0x42, /* stom=T.B */ +0x69, 0x6e, 0x64, 0x3d, 0x46, 0x09, 0x43, 0x6f, /* ind=F.Co */ +0x6c, 0x6c, 0x61, 0x74, 0x65, 0x3d, 0x54, 0x06, /* llate=T. */ +0x53, 0x6f, 0x72, 0x74, 0x3d, 0x54, 0x08, 0x53, /* Sort=T.S */ +0x74, 0x61, 0x70, 0x6c, 0x65, 0x3d, 0x46, 0x07, /* taple=F. */ +0x50, 0x75, 0x6e, 0x63, 0x68, 0x3d, 0x46, 0x11, /* Punch=F. */ +0x50, 0x61, 0x70, 0x65, 0x72, 0x4d, 0x61, 0x78, /* PaperMax */ +0x3d, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x41, /* =legal-A */ +0x34 /* 4 */ +}; + +/* Frame (144 bytes) */ +static const unsigned char pkt3[144] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x82, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x7c, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .|...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6e, /* .......n */ +0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .<...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x08, /* al...... */ +0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, /* _printer */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x93, 0x00, 0x22, 0x0c, 0x43, /* .....".C */ +0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, /* anonMF45 */ +0x30, 0x30, 0x77, 0x08, 0x5f, 0x70, 0x72, 0x69, /* 00w._pri */ +0x6e, 0x74, 0x65, 0x72, 0x04, 0x5f, 0x74, 0x63, /* nter._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + +/* Frame (144 bytes) */ +static const unsigned char pkt4[144] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x82, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x7b, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .{...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6e, /* .......n */ +0x18, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .>...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x08, /* al...... */ +0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, /* _printer */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x91, 0x00, 0x22, 0x0c, 0x43, /* .....".C */ +0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, /* anonMF45 */ +0x30, 0x30, 0x77, 0x08, 0x5f, 0x70, 0x72, 0x69, /* 00w._pri */ +0x6e, 0x74, 0x65, 0x72, 0x04, 0x5f, 0x74, 0x63, /* nter._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_printer._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_query_printer_tcp[] = { + {TITLE, "Query _printer._tcp", 19, 0}, + + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 5}, + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 5}, +}; + +int mdns_query_printer_tcp_size = sizeof(mdns_query_printer_tcp) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_query_rr_timeout_test.c b/test/regression/mdns_test/mdns_query_rr_timeout_test.c new file mode 100644 index 00000000..f692e650 --- /dev/null +++ b/test/regression/mdns_test/mdns_query_rr_timeout_test.c @@ -0,0 +1,148 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (75 bytes) */ +static const unsigned char pkt1[75] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x3d, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* .=..@... */ +0x90, 0x93, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x29, /* .......) */ +0x66, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* f....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (276 bytes) */ +static const unsigned char pkt2[276] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x01, 0x06, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x1c, 0xc0, 0xa8, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xf2, /* ........ */ +0x15, 0xc4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x23, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* #.Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x04, 0x5f, 0x69, 0x70, 0x70, /* ver._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, 0x6d, /* cal..Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x04, 0x5f, /* Server._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x15, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x90, 0x07, /* ........ */ +0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x31, 0x05, /* ubuntu1. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, /* local..S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* x...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x07, /* sion=01. */ +0x75, 0x62, 0x75, 0x6e, 0x74, 0x75, 0x31, 0x05, /* ubuntu1. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x00, 0x1f /* .... */ +}; + +/* Frame (75 bytes) */ +static const unsigned char pkt3[75] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x3d, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* .=..@... */ +0x90, 0x93, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x29, /* .......) */ +0x66, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* f....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_ipp._tcp", NX_NULL}; +#define resonable_error 10 + +MDNS_TEST_SEQ mdns_query_rr_timeout[] = { + {TITLE, "RR timeout", 10, 0}, + + /* Waiting for probing and announcing. */ + {WAIT, NX_NULL, 0, 5}, + + /* Add query. */ + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 5}, + + /* Inject a response. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* Reset timer. */ + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* TTL is 120s. */ + /* Issue a query at 80%, 85%, 90%, 95% of the record lifetime. */ + {WAIT, NX_NULL, 0, 95}, + {DUMP, NX_NULL, 0, 0}, + + /* Check data. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 10}, + + /* Check timer in range 96~99s (80%-82%). */ + {MDNS_TIMER_CHECK, NX_NULL, 150 + resonable_error, 9750}, + {DUMP, NX_NULL, 0, 0}, + + /* Check data. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 10}, + + /* Check timer in range 102~105 (85%-87%). */ + {MDNS_TIMER_CHECK, NX_NULL, 150 + resonable_error, 10350}, + {DUMP, NX_NULL, 0, 0}, + + /* Check data. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 10}, + + /* Check timer in range 108~111 (90%-92%). */ + {MDNS_TIMER_CHECK, NX_NULL, 150 + resonable_error, 10950}, + {DUMP, NX_NULL, 0, 0}, + + /* Check data. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 10}, + + /* Check timer in range 114~117 (95%-97%). */ + {MDNS_TIMER_CHECK, NX_NULL, 150 + resonable_error, 11550}, + + /* The record should be deleted. */ + {WAIT, NX_NULL, 0, 7}, + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 0, 0}, + + /* Delete the query. */ + {MDNS_QUERY_DELETE, NX_NULL, 0, 0}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject a response. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* No cache maintenance is expected. */ + {MDNS_REJECT_ANY_V4, NX_NULL, 0, 120}, + + /* The record should be deleted. */ + {WAIT, NX_NULL, 0, 2}, + {MDNS_CHECK_RR_COUNT_REMOTE, NX_NULL, 0, 0}, +}; + +int mdns_query_rr_timeout_size = sizeof(mdns_query_rr_timeout) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_query_smb_tcp_test.c b/test/regression/mdns_test/mdns_query_smb_tcp_test.c new file mode 100644 index 00000000..971e4294 --- /dev/null +++ b/test/regression/mdns_test/mdns_query_smb_tcp_test.c @@ -0,0 +1,123 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" +/* Frame (75 bytes) */ +static const unsigned char pkt1[75] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x3d, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .=..@... */ +0xd9, 0xc2, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x29, /* .......) */ +0xb3, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (332 bytes) */ +static const unsigned char pkt2[332] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x33, 0xc1, 0xbd, 0x08, 0x00, 0x45, 0x00, /* s3....E. */ +0x01, 0x3e, 0x09, 0x17, 0x00, 0x00, 0xff, 0x11, /* .>...... */ +0x0f, 0x8f, 0xc0, 0xa8, 0x00, 0x65, 0xe0, 0x00, /* .....e.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x2a, /* .......* */ +0x56, 0xdc, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* V....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x0c, 0x09, 0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, /* ..Chenbo */ +0x2d, 0x50, 0x43, 0xc0, 0x0c, 0x09, 0x43, 0x68, /* -PC...Ch */ +0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, 0x43, 0x0c, /* enbo-PC. */ +0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, /* _device- */ +0x69, 0x6e, 0x66, 0x6f, 0xc0, 0x11, 0x00, 0x10, /* info.... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x0e, /* ........ */ +0x0d, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x3d, 0x57, /* .model=W */ +0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0xc0, 0x27, /* indows.' */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .!.....x */ +0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbd, /* ........ */ +0x09, 0x43, 0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, /* .Chenbo- */ +0x50, 0x43, 0xc0, 0x16, 0xc0, 0x27, 0x00, 0x10, /* PC...'.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x23, /* .......# */ +0x11, 0x6e, 0x65, 0x74, 0x62, 0x69, 0x6f, 0x73, /* .netbios */ +0x3d, 0x43, 0x48, 0x45, 0x4e, 0x42, 0x4f, 0x2d, /* =CHENBO- */ +0x50, 0x43, 0x10, 0x64, 0x6f, 0x6d, 0x61, 0x69, /* PC.domai */ +0x6e, 0x3d, 0x57, 0x4f, 0x52, 0x4b, 0x47, 0x52, /* n=WORKGR */ +0x4f, 0x55, 0x50, 0xc0, 0x76, 0x00, 0x01, 0x80, /* OUP.v... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, /* ....x... */ +0xa8, 0x00, 0x65, 0xc0, 0x76, 0x00, 0x1c, 0x80, /* ..e.v... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0x20, /* ....x.. */ +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xc0, /* ......1. */ +0x76, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, /* v....... */ +0x78, 0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, /* x....... */ +0x00, 0x00, 0x00, 0x01, 0x59, 0x44, 0x79, 0xe1, /* ....YDy. */ +0x0a, 0xd7, 0xf4, 0xc0, 0x27, 0x00, 0x2f, 0x80, /* ....'./. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x09, 0xc0, /* ....x... */ +0x27, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* '......@ */ +0xc0, 0x76, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* .v./.... */ +0x00, 0x78, 0x00, 0x08, 0xc0, 0x76, 0x00, 0x04, /* .x...v.. */ +0x40, 0x00, 0x00, 0x08 /* @... */ +}; + +/* Frame (129 bytes) */ +static const unsigned char pkt3[129] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x73, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* .s..@... */ +0xd9, 0x8b, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x5f, /* ......._ */ +0x9d, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x04, 0x5f, 0x73, 0x6d, 0x62, /* ...._smb */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x93, 0x00, 0x1b, 0x09, 0x43, /* .......C */ +0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, 0x43, /* henbo-PC */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00 /* . */ +}; + +/* Frame (129 bytes) */ +static const unsigned char pkt4[129] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x56, 0x08, 0x00, 0x45, 0x00, /* "3DV..E. */ +0x00, 0x73, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .s..@... */ +0xd9, 0x8a, 0xc0, 0xa8, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x5f, /* ......._ */ +0x9d, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, 0x63, 0x70, /* smb._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x04, 0x5f, 0x73, 0x6d, 0x62, /* ...._smb */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x91, 0x00, 0x1b, 0x09, 0x43, /* .......C */ +0x68, 0x65, 0x6e, 0x62, 0x6f, 0x2d, 0x50, 0x43, /* henbo-PC */ +0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, 0x5f, 0x74, /* ._smb._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00 /* . */ +}; + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_smb._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_query_smb_tcp[] = { + {TITLE, "Query _smb._tcp", 15, 0}, + + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 5}, + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 5}, +}; + +int mdns_query_smb_tcp_size = sizeof(mdns_query_smb_tcp) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_query_start_stop_test.c b/test/regression/mdns_test/mdns_query_start_stop_test.c new file mode 100644 index 00000000..4e85dd1b --- /dev/null +++ b/test/regression/mdns_test/mdns_query_start_stop_test.c @@ -0,0 +1,189 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (90 bytes) */ +static const unsigned char pkt1[90] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x4c, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .L..@... */ +0x90, 0x5c, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .\...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x38, /* .......8 */ +0x46, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* F....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x73, 0x75, 0x62, 0x05, 0x5f, 0x68, 0x74, /* _sub._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01 /* .. */ +}; + +/* Frame (199 bytes) */ +static const unsigned char pkt2[199] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0xb9, 0x1d, 0xbb, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0xf4, 0xca, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xa5, /* ........ */ +0x3b, 0x23, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ;#...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x73, 0x75, 0x62, 0x05, 0x5f, 0x68, 0x74, /* _sub._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x07, /* ........ */ +0x04, 0x74, 0x65, 0x73, 0x74, 0xc0, 0x1a, 0x08, /* .test... */ +0x43, 0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, /* Catro-PC */ +0xc0, 0x25, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* .%...... */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x07, 0x0a, /* .x...... */ +0xc0, 0x36, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .6.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x3d, 0xc0, 0x36, 0x00, 0x10, /* .P.=.6.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0xc0, 0x3d, 0x00, 0x2f, 0x80, 0x01, 0x00, /* ..=./... */ +0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, 0x3d, 0x00, /* ..x...=. */ +0x01, 0x40, 0xc0, 0x36, 0x00, 0x2f, 0x80, 0x01, /* .@.6./.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x09, 0xc0, 0x36, /* ...x...6 */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* ......@ */ +}; + +/* Frame (155 bytes) */ +static const unsigned char pkt3[155] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x8d, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x1a, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x79, /* .......y */ +0xd4, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .~...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x73, 0x75, 0x62, 0x05, 0x5f, 0x68, 0x74, /* _sub._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, /* ..._prin */ +0x74, 0x65, 0x72, 0x04, 0x5f, 0x73, 0x75, 0x62, /* ter._sub */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x93, 0x00, 0x17, 0x04, 0x74, 0x65, 0x73, /* .....tes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00 /* al. */ +}; + +/* Frame (81 bytes) */ +static const unsigned char pkt4[81] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x43, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* .C..@... */ +0x90, 0x63, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .c...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2f, /* ......./ */ +0x2f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* /....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, /* ocal.... */ +0x01 /* . */ +}; + +/* Frame (171 bytes) */ +static const unsigned char pkt5[171] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x9d, 0x1d, 0xbc, 0x00, 0x00, 0xff, 0x11, /* ........ */ +0xf4, 0xe5, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x89, /* ........ */ +0x2c, 0xb0, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ,....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x04, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x11, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x08, 0x43, 0x61, /* ....P.Ca */ +0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0xc0, 0x1c, /* tro-PC.. */ +0xc0, 0x0c, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x33, 0x00, /* ......3. */ +0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x04, 0xc0, 0xa8, 0x07, 0x0a, 0xc0, 0x33, 0x00, /* ......3. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x05, 0xc0, 0x33, 0x00, 0x01, 0x40, 0xc0, 0x0c, /* ..3..@.. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x09, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x00, /* ........ */ +0x80, 0x00, 0x40 /* ..@ */ +}; + +static MDNS_QUERY_INFO mdns_query_0 = {"test", "_http._tcp", NX_NULL}; +static MDNS_QUERY_INFO mdns_query_1 = {NX_NULL, "_http._tcp", "_printer"}; + +MDNS_TEST_SEQ mdns_query_start_stop[] = { + {TITLE, "Query start and stop", 20, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Add a query*/ + {MDNS_QUERY, (char*)&mdns_query_0, 0, 0}, + + /* Check the query packet. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt4), 5}, + + /* Delete the query. */ + {MDNS_QUERY_DELETE, NX_NULL, 0, 0}, + + /* Reject any queries. */ + {MDNS_REJECT_ANY_V4, NX_NULL, MDNS_FLAG_QUERY, 5}, + + /* Add a query*/ + {MDNS_QUERY, (char*)&mdns_query_0, 0, 0}, + + /* Check the query packet. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt4), 5}, + + /* Inject a response. */ + {INJECT, (char*)&pkt5[0], sizeof(pkt5), 0}, + + /* Reject any queries. */ + {MDNS_REJECT_ANY_V4, NX_NULL, MDNS_FLAG_QUERY, 5}, + + /* Delete the query. */ + {MDNS_QUERY_DELETE, NX_NULL, 0, 0}, + + + /* Add a query*/ + {MDNS_QUERY, (char*)&mdns_query_1, 0, 0}, + + /* Check the query packet. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 5}, + + /* Delete the query. */ + {MDNS_QUERY_DELETE, NX_NULL, 0, 0}, + + /* Reject any queries. */ + {MDNS_REJECT_ANY_V4, NX_NULL, MDNS_FLAG_QUERY, 5}, + + /* Add a query*/ + {MDNS_QUERY, (char*)&mdns_query_1, 0, 0}, + + /* Check the query packet. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 5}, + + /* Inject a response. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + + /* Check the query packet with known answer. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 5}, + + /* Delete the query. */ + {MDNS_QUERY_DELETE, NX_NULL, 0, 0}, + + /* Reject any queries. */ + {MDNS_REJECT_ANY_V4, NX_NULL, MDNS_FLAG_QUERY, 5}, + +}; + +int mdns_query_start_stop_size = sizeof(mdns_query_start_stop) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_query_with_tc_test.c b/test/regression/mdns_test/mdns_query_with_tc_test.c new file mode 100644 index 00000000..cb777fbb --- /dev/null +++ b/test/regression/mdns_test/mdns_query_with_tc_test.c @@ -0,0 +1,691 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x3e, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0x90, 0x6a, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .j...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (1437 bytes) */ +static const unsigned char pkt2[1437] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x05, 0x8f, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8b, 0x61, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* .a...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x7b, /* .......{ */ +0x26, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* &....... */ +0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* .,....._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x31, 0x2e, 0x30, 0x31, 0x20, 0x53, 0x69, /* .1.01 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0xc0, 0x0c, 0xc0, 0x28, 0x00, 0x10, 0x80, /* s...(... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, /* ........ */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0x06, 0x75, 0x62, 0x75, 0x6e, 0x74, /* .P.ubunt */ +0x75, 0xc0, 0x17, 0xc0, 0x78, 0x00, 0x1c, 0x80, /* u...x... */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0xfe, /* ....x... */ +0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x0c, 0x29, 0xff, 0xfe, 0x01, 0xd4, 0x8d, 0xc0, /* .)...... */ +0x78, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* x....... */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x01, 0xc0, /* x....... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x31, 0x2e, 0x31, 0x36, 0x20, 0x53, /* ..1.16 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0xc0, 0x0c, 0xc0, 0xb9, 0x00, 0x10, /* ts...... */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0xc0, 0xb9, 0x00, 0x21, 0x80, 0x01, 0x00, /* ....!... */ +0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, /* ..P.x... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x31, 0x2e, 0x31, 0x35, 0x20, 0x53, 0x69, 0x6d, /* 1.15 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0xc0, 0x0c, 0xc1, 0x17, 0x00, 0x10, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, 0xc1, /* ........ */ +0x17, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* x....... */ +0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* P.x..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, /* ......1. */ +0x31, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 13 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, /* ackets.. */ +0xc1, 0x75, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* .u...... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc1, 0x75, 0x00, /* ......u. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, /* ......P. */ +0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* x....... */ +0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, 0x30, 0x38, /* ....1.08 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, 0xc1, 0xd3, /* kets.... */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x01, 0x00, 0xc1, 0xd3, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, /* ....P.x. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x31, 0x2e, 0x31, 0x34, 0x20, 0x53, /* ..1.14 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0xc0, 0x0c, 0xc2, 0x31, 0x00, 0x10, /* ts...1.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0xc2, 0x31, 0x00, 0x21, 0x80, 0x01, 0x00, /* ..1.!... */ +0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, /* ..P.x... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x31, 0x2e, 0x31, 0x32, 0x20, 0x53, 0x69, 0x6d, /* 1.12 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0xc0, 0x0c, 0xc2, 0x8f, 0x00, 0x10, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, 0xc2, /* ........ */ +0x8f, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* x....... */ +0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* P.x..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, /* ......1. */ +0x31, 0x31, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 11 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, /* ackets.. */ +0xc2, 0xed, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc2, 0xed, 0x00, /* ........ */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, /* ......P. */ +0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* x....... */ +0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, 0x30, 0x39, /* ....1.09 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, 0xc3, 0x4b, /* kets...K */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x01, 0x00, 0xc3, 0x4b, 0x00, 0x21, 0x80, /* ....K.!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, /* ....P.x. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x31, 0x2e, 0x31, 0x30, 0x20, 0x53, /* ..1.10 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0xc0, 0x0c, 0xc3, 0xa9, 0x00, 0x10, /* ts...... */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0xc3, 0xa9, 0x00, 0x21, 0x80, 0x01, 0x00, /* ....!... */ +0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, /* ..P.x... */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x31, 0x2e, 0x30, 0x37, 0x20, 0x53, 0x69, 0x6d, /* 1.07 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0xc0, 0x0c, 0xc4, 0x07, 0x00, 0x10, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, 0xc4, /* ........ */ +0x07, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, /* x....... */ +0x50, 0xc0, 0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* P.x..... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, /* ......1. */ +0x30, 0x35, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 05 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, /* ackets.. */ +0xc4, 0x65, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* .e...... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc4, 0x65, 0x00, /* ......e. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, /* ......P. */ +0x78, 0xc0, 0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, /* x....... */ +0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, 0x30, 0x36, /* ....1.06 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, 0xc4, 0xc3, /* kets.... */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x01, 0x00, 0xc4, 0xc3, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x08, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, 0x78, 0xc0, /* ....P.x. */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x94, 0x00, 0x31, 0x2e, 0x30, 0x34, 0x20, 0x53, /* ..1.04 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0xc0, 0x0c, 0xc5, 0x21, 0x00, 0x10, /* ts...!.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0xc5, 0x21, 0x00, 0x21, 0x80, 0x01, 0x00, /* ..!.!... */ +0x00, 0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0xc0, 0x78 /* ..P.x */ +}; + +/* Frame (265 bytes) */ +static const unsigned char pkt3[265] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0xfb, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xf5, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xe7, /* ........ */ +0x83, 0xd5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x31, 0x2e, 0x30, 0x32, 0x20, 0x53, 0x69, /* .1.02 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0xc0, 0x0c, 0xc0, 0x28, 0x00, 0x10, 0x80, /* s...(... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, 0x00, /* ........ */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0x06, 0x75, 0x62, 0x75, 0x6e, 0x74, /* .P.ubunt */ +0x75, 0xc0, 0x17, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* u....... */ +0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x31, 0x2e, /* ......1. */ +0x30, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 03 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0xc0, 0x0c, /* ackets.. */ +0xc0, 0x8d, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x8d, 0x00, /* ........ */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* !.....x. */ +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xc0, /* ......P. */ +0x78 /* x */ +}; + +/* Frame (1471 bytes) */ +static const unsigned char pkt4[1471] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xb1, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xf6, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x9d, /* ........ */ +0xd6, 0x19, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, /* .......A */ +0x2e, 0x30, 0x31, 0x20, 0x53, 0x69, 0x6d, 0x70, /* .01 Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, /* erver Te */ +0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, /* st For M */ +0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, /* ultiple */ +0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, /* Packets. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* .._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x31, 0x36, /* ....A.16 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, /* kets._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, /* local.._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x41, 0x2e, 0x31, 0x35, 0x20, 0x53, 0x69, /* .A.15 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, /* al.._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, /* ......A. */ +0x31, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 13 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x93, 0x00, 0x41, 0x2e, 0x30, 0x38, 0x20, /* ...A.08 */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, /* r Test F */ +0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, /* or Multi */ +0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, /* ple Pack */ +0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ets._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, /* ocal.._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, /* ........ */ +0x41, 0x2e, 0x31, 0x34, 0x20, 0x53, 0x69, 0x6d, /* A.14 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* l.._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x31, /* .....A.1 */ +0x32, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* 2 Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, /* ver Test */ +0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, /* For Mul */ +0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, /* tiple Pa */ +0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, /* ckets._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x93, 0x00, 0x41, 0x2e, 0x31, 0x31, 0x20, 0x53, /* ..A.11 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ts._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, /* cal.._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, /* .......A */ +0x2e, 0x30, 0x39, 0x20, 0x53, 0x69, 0x6d, 0x70, /* .09 Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, /* erver Te */ +0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, /* st For M */ +0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, /* ultiple */ +0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, /* Packets. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* .._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x31, 0x30, /* ....A.10 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, /* kets._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, /* local.._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x41, 0x2e, 0x30, 0x37, 0x20, 0x53, 0x69, /* .A.07 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, /* al.._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, /* ......A. */ +0x30, 0x35, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 05 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x93, 0x00, 0x41, 0x2e, 0x30, 0x36, 0x20, /* ...A.06 */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, /* r Test F */ +0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, /* or Multi */ +0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, /* ple Pack */ +0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ets._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, /* ocal.._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, /* ........ */ +0x41, 0x2e, 0x30, 0x34, 0x20, 0x53, 0x69, 0x6d, /* A.04 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* l.._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x30, /* .....A.0 */ +0x32, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* 2 Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, /* ver Test */ +0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, /* For Mul */ +0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, /* tiple Pa */ +0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, /* ckets._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (147 bytes) */ +static const unsigned char pkt5[147] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x85, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x21, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .!...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x71, /* .......q */ +0xae, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x41, 0x2e, 0x30, 0x33, 0x20, 0x53, 0x69, /* .A.03 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00 /* al. */ +}; + +/* Frame (1471 bytes) */ +static const unsigned char pkt6[1471] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xb1, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xf4, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x9d, /* ........ */ +0xe4, 0x29, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, /* .)...... */ +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x41, /* .......A */ +0x2e, 0x30, 0x31, 0x20, 0x53, 0x69, 0x6d, 0x70, /* .01 Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, /* erver Te */ +0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, /* st For M */ +0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, /* ultiple */ +0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, /* Packets. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* .._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, 0x31, 0x36, /* ....A.16 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, /* kets._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, /* local.._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x41, 0x2e, 0x31, 0x35, 0x20, 0x53, 0x69, /* .A.15 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, /* al.._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, /* ......A. */ +0x31, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 13 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x91, 0x00, 0x41, 0x2e, 0x30, 0x38, 0x20, /* ...A.08 */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, /* r Test F */ +0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, /* or Multi */ +0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, /* ple Pack */ +0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ets._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, /* ocal.._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x41, 0x2e, 0x31, 0x34, 0x20, 0x53, 0x69, 0x6d, /* A.14 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* l.._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, 0x31, /* .....A.1 */ +0x32, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* 2 Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, /* ver Test */ +0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, /* For Mul */ +0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, /* tiple Pa */ +0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, /* ckets._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x91, 0x00, 0x41, 0x2e, 0x31, 0x31, 0x20, 0x53, /* ..A.11 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ts._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, /* cal.._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x41, /* .......A */ +0x2e, 0x30, 0x39, 0x20, 0x53, 0x69, 0x6d, 0x70, /* .09 Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, /* erver Te */ +0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, /* st For M */ +0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, /* ultiple */ +0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, /* Packets. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* .._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, 0x31, 0x30, /* ....A.10 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, /* kets._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, /* local.._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x41, 0x2e, 0x30, 0x37, 0x20, 0x53, 0x69, /* .A.07 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, /* al.._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, /* ......A. */ +0x30, 0x35, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 05 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x91, 0x00, 0x41, 0x2e, 0x30, 0x36, 0x20, /* ...A.06 */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, /* r Test F */ +0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, /* or Multi */ +0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, /* ple Pack */ +0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ets._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, /* ocal.._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, 0x00, /* ........ */ +0x41, 0x2e, 0x30, 0x34, 0x20, 0x53, 0x69, 0x6d, /* A.04 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* l.._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x91, 0x00, 0x41, 0x2e, 0x30, /* .....A.0 */ +0x32, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* 2 Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, /* ver Test */ +0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, /* For Mul */ +0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, /* tiple Pa */ +0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, /* ckets._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (147 bytes) */ +static const unsigned char pkt7[147] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x85, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x1f, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x71, /* .......q */ +0xae, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* . ...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x91, /* ........ */ +0x00, 0x41, 0x2e, 0x30, 0x33, 0x20, 0x53, 0x69, /* .A.03 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00 /* al. */ +}; + + + +static MDNS_QUERY_INFO mdns_query = {NX_NULL, "_http._tcp", NX_NULL}; + +MDNS_TEST_SEQ mdns_query_with_tc[] = { + {TITLE, "Query with TC", 13, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Add a query. */ + {MDNS_QUERY, (char*)&mdns_query, 0, 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 5}, + + /* Inject responses. */ + {INJECT, (char*)&pkt2[0], sizeof(pkt2), 0}, + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + + /* Check query with TC bit. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt4), 5}, + {MDNS_CHECK_DATA_V4, (char*)&pkt5[0], sizeof(pkt5), 5}, +}; + +int mdns_query_with_tc_size = sizeof(mdns_query_with_tc) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_response_aggregation_test.c b/test/regression/mdns_test/mdns_response_aggregation_test.c new file mode 100644 index 00000000..d3079aad --- /dev/null +++ b/test/regression/mdns_test/mdns_response_aggregation_test.c @@ -0,0 +1,216 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (140 bytes) */ +static const unsigned char pkt1[140] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x7e, 0x01, 0x4c, 0x00, 0x00, 0xff, 0x11, /* .~.L.... */ +0x11, 0x75, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* .u...... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x6a, /* .......j */ +0x06, 0xdb, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x08, 0x43, /* .......C */ +0x61, 0x74, 0x72, 0x6f, 0x2d, 0x50, 0x43, 0x05, /* atro-PC. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0xc0, 0xa8, 0x07, 0x0a, 0x02, 0x31, 0x30, 0x01, /* .....10. */ +0x37, 0x03, 0x31, 0x36, 0x38, 0x03, 0x31, 0x39, /* 7.168.19 */ +0x32, 0x07, 0x69, 0x6e, 0x2d, 0x61, 0x64, 0x64, /* 2.in-add */ +0x72, 0x04, 0x61, 0x72, 0x70, 0x61, 0x00, 0x00, /* r.arpa.. */ +0x0c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* ......x. */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x2f, 0x80, /* ....../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x05, 0xc0, /* ....x... */ +0x0c, 0x00, 0x01, 0x40 /* ...@ */ +}; + +/* Frame (79 bytes) */ +static const unsigned char pkt2[79] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x41, 0x01, 0x4d, 0x00, 0x00, 0xff, 0x11, /* .A.M.... */ +0x11, 0xb1, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2d, /* .......- */ +0xbe, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .H...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* al..... */ +}; + +/* Frame (79 bytes) */ +static const unsigned char pkt3[79] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x41, 0x01, 0x4e, 0x00, 0x00, 0xff, 0x11, /* .A.N.... */ +0x11, 0xb0, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2d, /* .......- */ +0xbe, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .H...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01 /* al..... */ +}; + +/* Frame (75 bytes) */ +static const unsigned char pkt4[75] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x3d, 0x01, 0x4f, 0x00, 0x00, 0xff, 0x11, /* .=.O.... */ +0x11, 0xb3, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x29, /* .......) */ +0xa9, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .&...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (632 bytes) */ +static const unsigned char pkt5[632] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x02, 0x6a, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .j..@... */ +0x8e, 0x3e, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .>...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x02, 0x56, /* .......V */ +0x66, 0x0b, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* f....... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x21, 0x0b, 0x41, 0x52, /* ..d.!.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, /* t._print */ +0x65, 0x72, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* er._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, /* local.._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x1d, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* STest._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, /* local..A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x08, 0x5f, /* NSTest._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, /* local..A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, /* st._prin */ +0x74, 0x65, 0x72, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ter._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* ...ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x08, 0x5f, /* NSTest._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x28, 0x0b, 0x41, 0x52, /* ..x.(.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x08, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, /* t._print */ +0x65, 0x72, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* er._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x0b, 0x41, 0x52, /* ....@.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, /* ocal..AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x0b, 0x41, 0x52, /* .d....AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* t._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x24, 0x0b, 0x41, 0x52, 0x4d, /* .x.$.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .......@ */ +}; + +/* Frame (101 bytes) */ +static const unsigned char pkt6[101] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x57, 0x01, 0x50, 0x00, 0x00, 0xff, 0x11, /* .W.P.... */ +0x11, 0x98, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x43, /* .......C */ +0x10, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x0c, 0x00, /* ........ */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x0e, 0x0b, /* ....d... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0xc0, 0x0c /* est.. */ +}; + +/* Frame (105 bytes) */ +static const unsigned char pkt7[105] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x5b, 0x01, 0x51, 0x00, 0x00, 0xff, 0x11, /* .[.Q.... */ +0x11, 0x93, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x47, /* .......G */ +0x26, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* &....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, /* ......._ */ +0x70, 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, /* printer. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0xc0, /* al...... */ +0x0c, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x63, 0x00, 0x0e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* c...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0xc0, /* DNSTest. */ +0x0c /* . */ +}; + +static MDNS_SERVICE mdns_service_0 = {"ARMMDNSTest", "_printer._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service_1 = {"ARMMDNSTest", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + + +MDNS_TEST_SEQ mdns_response_aggregation[] = { + {TITLE, "Response aggregation", 20, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service_0, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service_1, 0, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject two queries. */ + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 0}, + + /* Sleep 10ms. */ + {MDNS_WAIT_TICK, NX_NULL, 0, 1}, + + {INJECT, (char*)&pkt4[0], sizeof(pkt4), 0}, + + /* Check response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt5[0], sizeof(pkt5), 2}, +}; + +int mdns_response_aggregation_size = sizeof(mdns_response_aggregation) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_response_in_multiple_packets_test.c b/test/regression/mdns_test/mdns_response_in_multiple_packets_test.c new file mode 100644 index 00000000..4ea66210 --- /dev/null +++ b/test/regression/mdns_test/mdns_response_in_multiple_packets_test.c @@ -0,0 +1,479 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (75 bytes) */ +static const unsigned char pkt1[75] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x3d, 0x06, 0x3f, 0x00, 0x00, 0xff, 0x11, /* .=.?.... */ +0x0c, 0xc3, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x29, /* .......) */ +0xa9, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .&...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01 /* ... */ +}; + +/* Frame (1497 bytes) */ +static const unsigned char pkt2[1497] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xcb, 0x00, 0x1d, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xc7, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xb7, /* ........ */ +0x44, 0x6c, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* Dl...... */ +0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, /* ..test1. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 2._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* l.._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, /* ..d...te */ +0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st3._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, /* cal.._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, /* test4._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, /* local.._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x17, 0x05, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 6._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* l.._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x17, 0x05, 0x74, 0x65, /* ..d...te */ +0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st7._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, /* cal.._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x17, 0x05, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, /* local.._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x17, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, /* ..test9. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x18, 0x06, 0x74, 0x65, 0x73, 0x74, /* d...test */ +0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 10._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, /* al.._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x18, 0x06, 0x74, /* ...d...t */ +0x65, 0x73, 0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, /* est11._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, /* local.._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x18, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, /* ..test12 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* .._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x18, 0x06, 0x74, 0x65, 0x73, /* .d...tes */ +0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t13._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x04, 0x5f, 0x69, 0x70, /* cal.._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x18, 0x06, /* ....d... */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, /* test14._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, /* .local.. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, /* ..x...AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x01, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st1._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x05, /* ...d.... */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, 0x69, /* test1._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, /* .....x.. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x31, 0x04, 0x5f, /* .test1._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, /* .....@.t */ +0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, 0x69, 0x70, /* est2._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x32, 0x04, 0x5f, /* .test2._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x01, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x32, /* ...test2 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 2._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x33, 0x04, /* @.test3. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 3._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, /* .d....te */ +0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st3._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, /* ...x...t */ +0x65, 0x73, 0x74, 0x33, 0x04, 0x5f, 0x69, 0x70, /* est3._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, 0x73, /* ...@.tes */ +0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t4._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, 0x69, 0x70, /* est4._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, 0x5f, /* .test4._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x34, 0x04, /* ..test4. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, /* test5._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00 /* . */ +}; + +/* Frame (1490 bytes) */ +static const unsigned char pkt3[1490] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xc4, 0x00, 0x1e, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xcd, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0xb0, /* ........ */ +0x12, 0x0c, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x05, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, 0x69, 0x70, /* est5._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, /* ocal..!. */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, /* ....d... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, /* ....P.AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, 0x5f, /* .test5._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x35, 0x04, /* ..test5. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x05, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x36, 0x04, 0x5f, 0x69, /* test6._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x36, 0x04, /* ..test6. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x01, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, /* ....test */ +0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 6._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, /* .x...tes */ +0x74, 0x36, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t6._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40, 0x05, 0x74, 0x65, 0x73, 0x74, 0x37, /* .@.test7 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t7._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x05, 0x74, /* ..d....t */ +0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, 0x70, /* est7._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, /* ocal../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, /* ....x... */ +0x74, 0x65, 0x73, 0x74, 0x37, 0x04, 0x5f, 0x69, /* test7._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, /* local... */ +0x00, 0x00, 0x80, 0x00, 0x40, 0x05, 0x74, 0x65, /* ....@.te */ +0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st8._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x74, 0x65, 0x73, 0x74, 0x38, 0x04, 0x5f, 0x69, /* test8._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x38, 0x04, /* ..test8. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1e, 0x05, 0x74, 0x65, 0x73, 0x74, 0x38, /* ...test8 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* .......@ */ +0x05, 0x74, 0x65, 0x73, 0x74, 0x39, 0x04, 0x5f, /* .test9._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x05, 0x74, 0x65, 0x73, 0x74, 0x39, /* l..test9 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65, 0x73, /* d....tes */ +0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* t9._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, /* al../... */ +0x00, 0x00, 0x78, 0x00, 0x1e, 0x05, 0x74, 0x65, /* ..x...te */ +0x73, 0x74, 0x39, 0x04, 0x5f, 0x69, 0x70, 0x70, /* st9._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, /* cal..... */ +0x80, 0x00, 0x40, 0x06, 0x74, 0x65, 0x73, 0x74, /* ..@.test */ +0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 10._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, /* local..t */ +0x65, 0x73, 0x74, 0x31, 0x30, 0x04, 0x5f, 0x69, /* est10._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x30, /* ..test10 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x31, 0x30, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 10._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* .@.test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, /* ocal..te */ +0x73, 0x74, 0x31, 0x31, 0x04, 0x5f, 0x69, 0x70, /* st11._ip */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, /* ....d... */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x31, 0x04, /* .test11. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, /* ...test1 */ +0x31, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, /* 1._ipp._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, /* l....... */ +0x40, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, /* @.test12 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, /* ..!..... */ +0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* P.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, /* cal..tes */ +0x74, 0x31, 0x32, 0x04, 0x5f, 0x69, 0x70, 0x70, /* t12._ipp */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x06, /* ...d.... */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x32, 0x04, 0x5f, /* test12._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, /* ..test12 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, /* .......@ */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x06, 0x74, 0x65, 0x73, 0x74, /* al..test */ +0x31, 0x33, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 13._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x06, 0x74, /* ..d....t */ +0x65, 0x73, 0x74, 0x31, 0x33, 0x04, 0x5f, 0x69, /* est13._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, /* local../ */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x1f, /* .....x.. */ +0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x33, 0x04, /* .test13. */ +0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, /* _ipp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x40, 0x06, /* ......@. */ +0x74, 0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, /* test14._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* !.....d. */ +0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, /* ......P. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00 /* l. */ +}; + +/* Frame (154 bytes) */ +static const unsigned char pkt4[154] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x8c, 0x00, 0x1f, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x04, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x78, /* .......x */ +0xef, 0x93, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x01, /* .....d.. */ +0x00, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, /* ..test14 */ +0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, /* ._ipp._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, /* ../..... */ +0x78, 0x00, 0x1f, 0x06, 0x74, 0x65, 0x73, 0x74, /* x...test */ +0x31, 0x34, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* 14._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + + +static MDNS_SERVICE mdns_service1 = {"test1", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service2 = {"test2", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service3 = {"test3", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service4 = {"test4", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service5 = {"test5", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service6 = {"test6", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service7 = {"test7", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service8 = {"test8", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service9 = {"test9", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service10 = {"test10", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service11 = {"test11", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service12 = {"test12", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service13 = {"test13", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; +static MDNS_SERVICE mdns_service14 = {"test14", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_response_in_multiple_packets[] = { + {TITLE, "Response in multiple packets", 28, 0}, + + /* Add a service. */ + {MDNS_SERVICE_ADD, (char*)&mdns_service1, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service2, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service3, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service4, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service5, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service6, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service7, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service8, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service9, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service10, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service11, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service12, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service13, 0, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service14, 0, 0}, + + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject a query packet. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 1}, + + /* Wait for the response in multiple packets. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt4), 1}, +}; + +int mdns_response_in_multiple_packets_size = sizeof(mdns_response_in_multiple_packets) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_response_interval_test.c b/test/regression/mdns_test/mdns_response_interval_test.c new file mode 100644 index 00000000..e5d22999 --- /dev/null +++ b/test/regression/mdns_test/mdns_response_interval_test.c @@ -0,0 +1,275 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (76 bytes) */ +static const unsigned char pkt1_1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x3e, 0x01, 0x16, 0x00, 0x00, 0xff, 0x11, /* .>...... */ +0x11, 0xeb, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0x26, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* &/...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt1_2[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x28, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .(...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0xbf, 0xcd, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* ...ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* B.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, /* cal../.. */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, /* ...x...A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, /* ...@.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, /* ocal..AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x14, 0x08, 0x70, 0x61, /* ..d...pa */ +0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, /* per=A4.v */ +0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, /* ersion=0 */ +0x31, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* 1.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt2_1[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xaf, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (94 bytes) */ +static const unsigned char pkt2_16[94] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0xec, 0x17, /* ..^..... */ +0x2f, 0xbd, 0xa4, 0xb1, 0x08, 0x00, 0x45, 0x00, /* /.....E. */ +0x00, 0x50, 0x01, 0x2e, 0x00, 0x00, 0xff, 0x11, /* .P...... */ +0x11, 0xc1, 0xc0, 0xa8, 0x07, 0x0a, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x3c, /* .......< */ +0xa4, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* st._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x00, 0x01, /* cal..!.. */ +0xc0, 0x0c, 0x00, 0x10, 0x00, 0x01 /* ...... */ +}; + +/* Frame (340 bytes) */ +static const unsigned char pkt2_17[340] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x46, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .F..@... */ +0x8f, 0x62, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .b...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x32, /* .......2 */ +0xa4, 0x76, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .v...... */ +0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* st._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, /* .local.. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* =01.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0x0a, 0x00, 0x00, 0x42, 0x0b, 0x41, 0x52, 0x4d, /* ...B.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x16, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, 0x40, 0x0b, /* cal...@. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x2f, 0x80, /* ocal../. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x25, 0x0b, /* ....x.%. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40 /* ...@ */ +}; + +static MDNS_SERVICE mdns_service = {"ARMMDNSTest", "_http._tcp", NX_NULL, "paper=A4;version=01", 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_response_interval[] = { + {TITLE, "Response interval", 17, 0}, + + /* Add service. */ + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + + /* Reset timer. */ + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Inject a query. */ + {INJECT, (char*)&pkt1_1[0], sizeof(pkt1_1), 0}, + + /* Check the response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1_2[0], sizeof(pkt1_2), 1}, + + /* Check timer in range 20~120ms. */ + {MDNS_TIMER_CHECK, NX_NULL, 5, 7}, + + /* Wait 5 seconds. */ + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Reset timer. */ + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Inject a query. */ + {INJECT, (char*)&pkt1_1[0], sizeof(pkt1_1), 0}, + + /* Check the response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1_2[0], sizeof(pkt1_2), 1}, + + /* Check timer in range 20~120ms. */ + {MDNS_TIMER_CHECK, NX_NULL, 5, 7}, + + /* Reset timer. */ + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Inject a query immediately. */ + {INJECT, (char*)&pkt1_1[0], sizeof(pkt1_1), 0}, + + /* It MUST NOT answer in one second. */ + /* Check the response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1_2[0], sizeof(pkt1_2), 2}, + + /* Check timer in range 1s~. */ + {MDNS_TIMER_CHECK, NX_NULL, 100, 200}, + + /* Wait 5 seconds. */ + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Reset timer. */ + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Inject a query. */ + {INJECT, (char*)&pkt1_1[0], sizeof(pkt1_1), 0}, + + /* Check the response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1_2[0], sizeof(pkt1_2), 1}, + + /* Check timer in range 20~120ms. */ + {MDNS_TIMER_CHECK, NX_NULL, 5, 7}, + + + /* Reset timer. */ + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Inject a query. */ + {INJECT, (char*)&pkt2_16[0], sizeof(pkt2_16), 0}, + + /* Check the response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt2_17[0], sizeof(pkt2_17), 1}, + + /* Check timer in range 0~10ms. Resonable error is 30ms. */ + {MDNS_TIMER_MAX_CHECK, NX_NULL, 0, 1 + 3}, + + /* Reset timer. */ + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Inject a probing immediately. */ + {INJECT, (char*)&pkt2_1[0], sizeof(pkt2_1), 0}, + + /* It MUST answer at least 250ms. */ + /* Check the response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt2_17[0], sizeof(pkt2_17), 1}, + + /* Check timer in range 250~. */ + {MDNS_TIMER_CHECK, NX_NULL, 75, 100}, +}; + +int mdns_response_interval_size = sizeof(mdns_response_interval) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_response_no_delay_test.c b/test/regression/mdns_test/mdns_response_no_delay_test.c new file mode 100644 index 00000000..7abdf579 --- /dev/null +++ b/test/regression/mdns_test/mdns_response_no_delay_test.c @@ -0,0 +1,65 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (77 bytes) */ +static const unsigned char pkt1[77] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x3f, 0x48, 0x48, 0x00, 0x00, 0xff, 0x11, /* .?HH.... */ +0xd1, 0x57, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .W...j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2b, /* .......+ */ +0x9a, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .J...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x00, 0x01 /* ..... */ +}; + +/* Frame (138 bytes) */ +static const unsigned char pkt2[138] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x7c, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .|..@... */ +0x90, 0x2c, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .,...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x68, /* .......h */ +0xb9, 0x74, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .t...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40 /* .@ */ +}; + +MDNS_TEST_SEQ mdns_response_no_delay[] = { + {TITLE, "Response no delay", 17, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject a query. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + + /* Reset timer. */ + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Check the response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 1}, + + /* Check timer in range 0~10ms. Resonable error is 30ms. */ + {MDNS_TIMER_MAX_CHECK, NX_NULL, 0, 1 + 3}, +}; + +int mdns_response_no_delay_size = sizeof(mdns_response_no_delay) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_response_to_address_query_test.c b/test/regression/mdns_test/mdns_response_to_address_query_test.c new file mode 100644 index 00000000..61252cdb --- /dev/null +++ b/test/regression/mdns_test/mdns_response_to_address_query_test.c @@ -0,0 +1,72 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (77 bytes) */ +static const unsigned char pkt1[77] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x18, 0x03, /* ..^..... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x3f, 0x5c, 0xe5, 0x00, 0x00, 0xff, 0x11, /* .?\..... */ +0xbc, 0xba, 0xc0, 0xa8, 0x00, 0x6a, 0xe0, 0x00, /* .....j.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2b, /* .......+ */ +0x9a, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* .J...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x00, 0x01 /* ..... */ +}; + +/* Frame (186 bytes) */ +static const unsigned char pkt2[186] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xac, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xf9, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x98, /* ........ */ +0x17, 0x2c, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .,...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, /* .x...... */ +0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x22, 0xff, /* ......". */ +0xfe, 0x33, 0x44, 0x57, 0x0b, 0x41, 0x52, 0x4d, /* .3DW.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x19, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x04, 0x40, 0x00, /* cal...@. */ +0x00, 0x08 /* .. */ +}; + +MDNS_TEST_SEQ mdns_response_to_address_query[] = { + {TITLE, "Response to address query", 25, 0}, + + /* Add link local address. */ + {MDNS_LLA_ADD, NX_NULL, 0x00000011, 0x22334457}, + {WAIT, NX_NULL, 0, 5}, + + /* Recreate mDNS. */ + {MDNS_RECREATE, "ARMMDNSTest", 0, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject query. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 0}, + + /* Check response. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 1}, +}; + +int mdns_response_to_address_query_size = sizeof(mdns_response_to_address_query) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_response_with_tc_test.c b/test/regression/mdns_test/mdns_response_with_tc_test.c new file mode 100644 index 00000000..de5a4e30 --- /dev/null +++ b/test/regression/mdns_test/mdns_response_with_tc_test.c @@ -0,0 +1,341 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (76 bytes) */ +static const unsigned char pkt1[76] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0x90, 0xb2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Frame (554 bytes) */ +static const unsigned char pkt2[554] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x02, 0x1c, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8e, 0x8c, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x02, 0x08, /* ........ */ +0x00, 0x93, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x41, 0x2e, 0x30, 0x33, 0x20, 0x53, 0x69, /* .A.03 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, /* .....x.. */ +0x0a, 0x00, 0x00, 0x42, 0x0b, 0x41, 0x52, 0x4d, /* ...B.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x16, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, /* STest.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x01, 0x40, 0x2e, /* cal...@. */ +0x30, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 03 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x2e, 0x30, 0x33, 0x20, 0x53, /* al..03 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ts._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, /* cal..... */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x01, 0x00, 0x2e, /* ...d.... */ +0x30, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 03 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* ./.....x */ +0x00, 0x48, 0x2e, 0x30, 0x33, 0x20, 0x53, 0x69, /* .H.03 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, /* al...... */ +0x00, 0x40 /* .@ */ +}; + +/* Frame (1471 bytes) */ +static const unsigned char pkt3[1471] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0xb1, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8a, 0xf6, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x9d, /* ........ */ +0xd6, 0x19, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x05, 0x5f, 0x68, 0x74, /* ....._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, /* .......A */ +0x2e, 0x30, 0x31, 0x20, 0x53, 0x69, 0x6d, 0x70, /* .01 Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, /* erver Te */ +0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, /* st For M */ +0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, /* ultiple */ +0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, /* Packets. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* .._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x31, 0x36, /* ....A.16 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, /* kets._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, /* local.._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x41, 0x2e, 0x31, 0x35, 0x20, 0x53, 0x69, /* .A.15 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, /* al.._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, /* ......A. */ +0x31, 0x33, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 13 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x93, 0x00, 0x41, 0x2e, 0x30, 0x38, 0x20, /* ...A.08 */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, /* r Test F */ +0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, /* or Multi */ +0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, /* ple Pack */ +0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ets._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, /* ocal.._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, /* ........ */ +0x41, 0x2e, 0x31, 0x34, 0x20, 0x53, 0x69, 0x6d, /* A.14 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* l.._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x31, /* .....A.1 */ +0x32, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* 2 Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, /* ver Test */ +0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, /* For Mul */ +0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, /* tiple Pa */ +0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, /* ckets._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, /* .local.. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x93, 0x00, 0x41, 0x2e, 0x31, 0x31, 0x20, 0x53, /* ..A.11 S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, /* Test Fo */ +0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, /* r Multip */ +0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, /* le Packe */ +0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ts._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, /* cal.._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, /* local... */ +0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, /* .......A */ +0x2e, 0x30, 0x39, 0x20, 0x53, 0x69, 0x6d, 0x70, /* .09 Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, /* erver Te */ +0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, /* st For M */ +0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, /* ultiple */ +0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, /* Packets. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* .._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, /* al...... */ +0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x31, 0x30, /* ....A.10 */ +0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, /* Simple */ +0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, /* Web Serv */ +0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, /* er Test */ +0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, /* For Mult */ +0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, /* iple Pac */ +0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, /* kets._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, /* local.._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x41, 0x2e, 0x30, 0x37, 0x20, 0x53, 0x69, /* .A.07 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, /* al.._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, /* ......A. */ +0x30, 0x35, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* 05 Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, /* rver Tes */ +0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, /* t For Mu */ +0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, /* ltiple P */ +0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, /* ackets._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x93, 0x00, 0x41, 0x2e, 0x30, 0x36, 0x20, /* ...A.06 */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x46, /* r Test F */ +0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, /* or Multi */ +0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, /* ple Pack */ +0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ets._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x05, 0x5f, 0x68, /* ocal.._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, 0x00, /* ........ */ +0x41, 0x2e, 0x30, 0x34, 0x20, 0x53, 0x69, 0x6d, /* A.04 Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x54, /* Server T */ +0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, 0x20, /* est For */ +0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, /* Multiple */ +0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, /* Packets */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* l.._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x93, 0x00, 0x41, 0x2e, 0x30, /* .....A.0 */ +0x32, 0x20, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* 2 Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, /* ver Test */ +0x20, 0x46, 0x6f, 0x72, 0x20, 0x4d, 0x75, 0x6c, /* For Mul */ +0x74, 0x69, 0x70, 0x6c, 0x65, 0x20, 0x50, 0x61, /* tiple Pa */ +0x63, 0x6b, 0x65, 0x74, 0x73, 0x05, 0x5f, 0x68, /* ckets._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* .local. */ +}; + +/* Frame (147 bytes) */ +static const unsigned char pkt4[147] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x85, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x21, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .!...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x71, /* .......q */ +0xae, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x93, /* ........ */ +0x00, 0x41, 0x2e, 0x30, 0x33, 0x20, 0x53, 0x69, /* .A.03 Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, /* Server */ +0x54, 0x65, 0x73, 0x74, 0x20, 0x46, 0x6f, 0x72, /* Test For */ +0x20, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, /* Multipl */ +0x65, 0x20, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, /* e Packet */ +0x73, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* s._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00 /* al. */ +}; + + +static MDNS_SERVICE mdns_service = {"03 Simple Web Server Test For Multiple Packets", "_http._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +MDNS_TEST_SEQ mdns_response_with_tc[] = { + {TITLE, "Response with TC", 16, 0}, + + /* Add a service. */ + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Inject a query packet. */ + {INJECT, (char*)&pkt1[0], sizeof(pkt1), 1}, + + /* Check the response packet. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 1}, + + /* Inject a query packet with TC bit set. */ + {INJECT, (char*)&pkt3[0], sizeof(pkt3), 1}, + + /* Wait 390ms. */ + {MDNS_WAIT_TICK, NX_NULL, NX_NULL, 39}, + + /* Inject the known answer packet. */ + {INJECT, (char*)&pkt4[0], sizeof(pkt4), 1}, + + /* Check no response packet. */ + {MDNS_REJECT_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 3}, +}; + +int mdns_response_with_tc_size = sizeof(mdns_response_with_tc) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_server_announcement_with_txt_test.c b/test/regression/mdns_test/mdns_server_announcement_with_txt_test.c new file mode 100644 index 00000000..4226e475 --- /dev/null +++ b/test/regression/mdns_test/mdns_server_announcement_with_txt_test.c @@ -0,0 +1,328 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (269 bytes) */ +static const unsigned char pkt1[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xaf, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt2[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xae, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (269 bytes) */ +static const unsigned char pkt3[269] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xff, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xad, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xeb, /* ........ */ +0x13, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* .%...... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* t._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, /* al...... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, /* .x.....B */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, /* Test._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x10, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x14, 0x08, 0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, /* ..paper= */ +0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, /* A4.versi */ +0x6f, 0x6e, 0x3d, 0x30, 0x31 /* on=01 */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt4[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x04, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x2b, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .+...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt5[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x05, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x2a, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .*...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +/* Frame (398 bytes) */ +static const unsigned char pkt6[398] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x80, 0x00, 0x06, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x29, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .)...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x6c, /* .......l */ +0x46, 0x47, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x05, /* sion=01. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* d...ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x25, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* %.ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, /* STest._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x05, 0x00, 0x00, 0x80, 0x00, 0x40 /* .....@ */ +}; + +static MDNS_SERVICE mdns_service = {"ARMMDNSTest", "_http._tcp", NX_NULL, "paper=A4;version=01", 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + +#define resonable_error 5 + +MDNS_TEST_SEQ mdns_server_announcement_with_txt[] = { + {TITLE, "Server announcement with TXT", 28, 0}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + + /* The first probing. Interval between 0~260ms. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 1}, + {MDNS_TIMER_CHECK, NX_NULL, 13 + resonable_error, 13 + resonable_error}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* The second probing. Interval between 0~260ms. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 1}, + {MDNS_TIMER_CHECK, NX_NULL, 13 + resonable_error, 13 + resonable_error}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* The third probing. Interval between 0~260ms. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 1}, + {MDNS_TIMER_CHECK, NX_NULL, 13 + resonable_error, 13 + resonable_error}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Check announcement. Interval between 0~260ms. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt4), 1}, + {MDNS_TIMER_CHECK, NX_NULL, 13 + resonable_error, 13 + resonable_error}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Check announcement. Interval 1s. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt5[0], sizeof(pkt5), 1}, + {MDNS_TIMER_CHECK, NX_NULL, 3 + resonable_error, 100}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, + + /* Check announcement. Interval 2s. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt6[0], sizeof(pkt6), 2}, + {MDNS_TIMER_CHECK, NX_NULL, 3 + resonable_error, 200}, + {MDNS_TIMER_RESET, NX_NULL, 0, 0}, +}; + +int mdns_server_announcement_with_txt_size = sizeof(mdns_server_announcement_with_txt) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_server_interface_reset.c b/test/regression/mdns_test/mdns_server_interface_reset.c new file mode 100644 index 00000000..4b7b2f49 --- /dev/null +++ b/test/regression/mdns_test/mdns_server_interface_reset.c @@ -0,0 +1,670 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (287 bytes) */ +static const unsigned char pkt1[287] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x11, 0x00, 0x01, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x9d, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xfd, /* ........ */ +0x5b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* [....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x11, 0x53, 0x69, /* ......Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x11, 0x53, /* .....B.S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +/* Frame (287 bytes) */ +static const unsigned char pkt2[287] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x11, 0x00, 0x02, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x9c, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xfd, /* ........ */ +0x5b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* [....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x11, 0x53, 0x69, /* ......Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x11, 0x53, /* .....B.S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +/* Frame (287 bytes) */ +static const unsigned char pkt3[287] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x11, 0x00, 0x03, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x9b, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xfd, /* ........ */ +0x5b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* [....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x11, 0x53, 0x69, /* ......Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x11, 0x53, /* .....B.S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +/* Frame (428 bytes) */ +static const unsigned char pkt4[428] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x9e, 0x00, 0x04, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x0d, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x8a, /* ........ */ +0x40, 0x19, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .@.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x24, 0x11, /* ....d.$. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* r._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, /* al..Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, /* erver._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x2b, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* +.Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40 /* ...@ */ +}; + +/* Frame (428 bytes) */ +static const unsigned char pkt5[428] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x9e, 0x00, 0x05, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x0c, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x8a, /* ........ */ +0x40, 0x19, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .@.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x24, 0x11, /* ....d.$. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* r._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, /* al..Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, /* erver._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x2b, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* +.Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40 /* ...@ */ +}; + +/* Frame (428 bytes) */ +static const unsigned char pkt6[428] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x9e, 0x00, 0x06, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x0b, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x8a, /* ........ */ +0x40, 0x19, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .@.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x24, 0x11, /* ....d.$. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* r._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, /* al..Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, /* erver._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x2b, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* +.Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40 /* ...@ */ +}; + +/* Frame (288 bytes) */ +static const unsigned char pkt7[288] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x12, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x96, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xfe, /* ........ */ +0x8f, 0x3f, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .?...... */ +0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x11, /* ......B. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* r._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, /* local..S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x00, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, /* .....pap */ +0x65, 0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, /* er=A4.ve */ +0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, /* rsion=01 */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, /* l....... */ +0x00, 0x00, 0x00, 0x24, 0x11, 0x53, 0x69, 0x6d, /* ...$.Sim */ +0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, /* ple Web */ +0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, /* Server._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + +/* Frame (287 bytes) */ +static const unsigned char pkt8[287] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x11, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x96, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xfd, /* ........ */ +0x5b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* [....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x11, 0x53, 0x69, /* ......Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x11, 0x53, /* .....B.S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +/* Frame (287 bytes) */ +static const unsigned char pkt9[287] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x11, 0x00, 0x09, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x95, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xfd, /* ........ */ +0x5b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* [....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x11, 0x53, 0x69, /* ......Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x11, 0x53, /* .....B.S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +/* Frame (287 bytes) */ +static const unsigned char pkt10[287] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x11, 0x00, 0x0a, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x94, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xfd, /* ........ */ +0x5b, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* [....... */ +0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x11, 0x53, 0x69, /* ......Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0xff, 0x00, 0x01, 0x0b, 0x41, 0x52, /* ......AR */ +0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, /* MMDNSTes */ +0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* t.local. */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x11, 0x53, /* .....B.S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +/* Frame (428 bytes) */ +static const unsigned char pkt11[428] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x9e, 0x00, 0x0b, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x06, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x8a, /* ........ */ +0x40, 0x19, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .@.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x24, 0x11, /* ....d.$. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* r._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, /* al..Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, /* erver._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x2b, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* +.Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40 /* ...@ */ +}; + +/* Frame (428 bytes) */ +static const unsigned char pkt12[428] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x9e, 0x00, 0x0c, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x05, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x8a, /* ........ */ +0x40, 0x19, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .@.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x24, 0x11, /* ....d.$. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* r._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, /* al..Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, /* erver._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x2b, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* +.Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40 /* ...@ */ +}; + +/* Frame (428 bytes) */ +static const unsigned char pkt13[428] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x9e, 0x00, 0x0d, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0x04, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x8a, /* ........ */ +0x40, 0x19, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* @....... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .@.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, /* local..! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x19, /* .....d.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, /* .....P.A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* ..Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x24, 0x11, /* ....d.$. */ +0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, /* Simple W */ +0x65, 0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, /* eb Serve */ +0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, /* r._http. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, 0x6d, 0x70, /* al..Simp */ +0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, /* le Web S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, /* erver._h */ +0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ttp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x2f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, /* /.....x. */ +0x2b, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, /* +.Simple */ +0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, 0x72, /* Web Ser */ +0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, 0x74, /* ver._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x05, 0x00, /* ocal.... */ +0x00, 0x80, 0x00, 0x40 /* ...@ */ +}; + +static MDNS_SERVICE mdns_service = {"Simple Web Server", "_http._tcp", NX_NULL, "paper=A4;version=01", 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + + +MDNS_TEST_SEQ mdns_server_interface_reset[] = { + {TITLE, "Server interface reset", 22, 0}, + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + + /* Check probing and announcement. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt1[0], sizeof(pkt1), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt2[0], sizeof(pkt2), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt3[0], sizeof(pkt3), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt4[0], sizeof(pkt4), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt5[0], sizeof(pkt5), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt6[0], sizeof(pkt6), 2}, + + /* Disable the interface. */ + {MDNS_INTERFACE_DISABLE, NX_NULL, 0, 0}, + {MDNS_CHECK_DATA_V4, (char*)&pkt7[0], sizeof(pkt7), 1}, + + /* Enable the interface. */ + {MDNS_INTERFACE_ENABLE, NX_NULL, 0, 0}, + + /* Check probing and announcement. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt8[0], sizeof(pkt8), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt9[0], sizeof(pkt9), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt10[0], sizeof(pkt10), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt11[0], sizeof(pkt11), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt12[0], sizeof(pkt12), 1}, + {MDNS_CHECK_DATA_V4, (char*)&pkt13[0], sizeof(pkt13), 2}, +}; + +int mdns_server_interface_reset_size = sizeof(mdns_server_interface_reset) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/mdns_test/mdns_server_send_goodbye_test.c b/test/regression/mdns_test/mdns_server_send_goodbye_test.c new file mode 100644 index 00000000..6e30d6a8 --- /dev/null +++ b/test/regression/mdns_test/mdns_server_send_goodbye_test.c @@ -0,0 +1,62 @@ + +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ + +#include "netx_mdns_test.h" + +/* Frame (237 bytes) */ +static const unsigned char pkt7[237] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xdf, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xc9, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xcb, /* ........ */ +0x49, 0x59, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* IY...... */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* st._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, /* .local.. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, /* ........ */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0b, /* ........ */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + +static MDNS_SERVICE mdns_service = {"ARMMDNSTest", "_http._tcp", NX_NULL, "paper=A4;version=01", 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0}; + + +MDNS_TEST_SEQ mdns_server_send_goodbye[] = { + {TITLE, "Server send goodbye", 19, 0}, + + /* Add a service. */ + {MDNS_SERVICE_ADD, (char*)&mdns_service, 0, 0}, + {WAIT, NX_NULL, 0, 5}, + {DUMP, NX_NULL, 0, 0}, + + /* Delete all services. */ + {MDNS_SERVICE_DELETE, (char*)&mdns_service, 0, 0}, + + /* Check for the goodbye packet. */ + {MDNS_CHECK_DATA_V4, (char*)&pkt7[0], sizeof(pkt7), 1}, +}; + +int mdns_server_send_goodbye_size = sizeof(mdns_server_send_goodbye) / sizeof(MDNS_TEST_SEQ); + +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/mdns_test/mdns_test_setup.docx b/test/regression/mdns_test/mdns_test_setup.docx new file mode 100644 index 0000000000000000000000000000000000000000..0be0f8b23d6a53da20fa80d8d8ce7b1c6417dce1 GIT binary patch literal 42485 zcmeEtQ=8~uw`AM4ZSJ;h+qP}nwr$(CZQHhXchCOj%*D(zKjEBQ~T z6fg)102lxS0000X0Hh^3tS2AJn8eDfrc z#UN0@7S50*GCAGx6(Vjwb|4Jek_4?q+fsoT>Zm#G8v;lkXuJEIL4My7yc z$K~cDR3Rmu(e~6z03|1o#<>`!q%a-$RFv>nKDDUuDK3%`5})*v)3wC0E%(1K1Xn(K z@fUd&Er8SzWJLPc4a%eMwdc1xI+}=Q_yLIO$5x@tCaUvfCJH6{s@MgLLq0AP#s*kH%&~y{@ zSK(p6$^QKVE{XDl^qDSXv;!H?3|HU_H+Q|F0P?QF0;%JVD6ISLg-g$( zzOs>s5E{q=$O!r`Z&Pg~&7ZT#Q%pYAJ3@_Sy#qV!Y#o88f5i3wc;j9hH~@!Ed~?b>H6u}D01|10x`PoIN6!$=_k2vQRs~ls_PAm1goflu`y#=S;=09AV**`+o%tK4M3uAxu&x(GkJpw+ActW+^ z5nhf~#(qxuB_je5LL<95l)LWbcj5q6M)`9TfeFi5MHQ!Fh6QT1Y)MR*6CTB4b~6TUeNueXsLU4QEI+HBmLzr`syK%H;5-`0b~0S z7SM?Z>YYO4Y2s08$>~HgF&s<;fRW(xtzqU@Xay4B#t4>$-}C8>j^0fh43_ONer+05 zU)D~RTo)gk&T3Py7OHPVyL7I8sH+D-M++6v*FgNZ^zm|ANEsoazn5;3jyyM~MG*)w z6XP+&(}C~F4{@J@CH)|n?qx~9z z!*4A#YZHCXl0GQH4~{RSJc!%>TzCe)7=Tfga!1=|i!>^n%t=j@<(P9hGnx~M3u+@h z%weyr02PKNr9zm<#?wXhaOTaJh?1+yAhKC2cB7rfl>lA>*AMd}_n zVlS1y{gJA#kH5?uJfJ^L!1>Z*@~Lsh=x9#~TMUrA3ZJ6dUyiV?p7%{-(v~!1Wq^}@$=f4-Kh9jm$ z5a{>CnCsi|{h3yUhp4lA#d!9@>+#JmwQPPO*~;?7d?&M*4NHg^QW>wAQKbYrx|G_Jo+X;n@8R{fm~vW*R?YpS z__-G6vL7M#%PSBHxsfe5HxA(AYi8;D=bkpkmtPO6_7@a7kJ9JcW>V|{eHiMt$nYt; z56-qX`a?t&v^ znhisJ3`So5v*!W|$dL2RQv#IuKMf>oV~H8LY{m^ z2xqiCr*{4q^>2)owxaPjKKR}r z?p)vRS9h+DIL&gEo#bJ43)Tqo)AJm0$0J^1S41nKNw~;}d(M}orY`>dLlQYkwutH% zH6fSnL$bw2j`|#cU&ePE&$qK*cYe{|spr?Lqjz6Mj97dU2}Q}nfanc#X5Mm=4k;w+ zHDTq|*X`v#vC$66skRbnex-!&`nIFGI4+1( zf1;Vh;_s0V?%ltx+#_kWcG~LTjZ%rb$R+K+qh4{jv1o+$scB4WVb$Yo@&Ak- zeSO)z4Ug~oerq&(-+xM6PBYU{gWn+nn#9|Y?0teGeRmjlaU%JM^B+#v)fSvUXE(T* z!gn*^>#LZQkk0JR_kr@`x}79&9tKF}3ER)CQZ+2+PRGYk9<6#vt%xSN+i{LZvBYo% zPsW&8?mZA3m|C?5q{{Uj6t7{zxVtyX{mFeUbLQ>>L5CKbZ{-jJ*3mHl8L2)wVmj=z zJDh}0XA7g_DXswvhfL!Kbe*3ngbP72ptmlV?fyH-L!%P7+4|8Y@Apu z1$ift3_OOYg;C+s_UP#ikw>E6bAF;B)F4nq>?Lm5!7?VBY+yElWx$)T)SJOM^fBlW z&)UbLed8;I9(pKaHx_l572+<_Pp41vnigqw$;jZf7HgA|AQC0oR`+J$v9cv34%n%v z9{5VqwM*|nhOV**_ZvRDP7F1Wx_$XXX|paE&(m`!`#F0f+mY>Jb6I05etUbvZ!Lz< zD6kr#*;Rdgn;cJTfY#&BVD8!0_!X!WFpNaG>HuyG22Q^UE5E_D787IZ0XOw zU3?bjpm^tgds{zv0EX8<`&HCOXWWr(l&jAv<~tC0HL9)x3|!3oq;n&%0(-RKvk{`3 ztYVCZ;y`YF^ zU?Y98Qq3w>7aj)K(w*TB0`N=~zyT&veNGsT*%7rrhU7W@pT-JByBdaO?f@@INo{ge z`x$Z76jO`@q0n*Cw=Nbm*Fc!WSId1zZ3GEdN@Sb6+CFI5S4Z~Qqo8T?s>nvJRQv6v7$_(#7{|1hQq*kH})9( zX(j{-ckCmrkF2rZpkIGDmlk|y> zxZ8BHkDD$JfcDxCB6IMxJ34^$#hOd2RdLyeMH0GQEnK2*%iCW9f#?p@I3Nj71T?IO zC(7D5?i?ip!9c)4=D~j9?3K|GkO(*n)v?AgU_Q;i5Jzyo9ZC$oqDrO6khdWs?C(!v zy4Z%)j+O5=d}{=JA&aUb5C~e<6<@35cmA*u>3z-;m*T`vAD8D2Od<4wxG$%yjWrKQG?0ilzT+U#!8Bf3S;) zsL#~tcSxjkBa+f^Qs3{TXdAa0g<`SrYo4+Uw-I1Uu5aw%Kx1V6YB&)hT(h@YT2#_+ zT!z8XIHcD*yD@Rdaml3G(IP3eWOa(jh~UlY|oBsk6uU2lK*Y~ z#a!%5)g6)iRg|4l#|S1$BLHy?K)WtyM|`9t#02BjLg6e`4wp#a`WDj>+NNAl=$8OH zf1yWTXZi@9sU3)@b- z(QZizO{4e=wK8Pye4)w%0W3wjt`K^{fpqD~aZ{)PTgv!%edQ%(Y>kJvjup8RC1M7g z%A=p`GwgB&RZVEai6On~`NVO%ro5K-MP4>=ongI6wr~D>EPe1WbMXf1#K>t3`Xs`R zo%G3Cj|4w2guV+ua;4WUh$P6cL_Fn6A_bb`K(Zws{?@iY4pWoD9x%4-V-6$h51J74 z4R$19V2ao_qM>5`squ-BEc7o_$RnOJH396bG~^OaB-%okfl8-;j$9kab&_CezWK>} zZ$Q2`tpbNGWbxosVRX#jO-Hha37T4pYMNkS@MLZ5tG zQu`*Z0y}&d@pA;k=k-325jPAnN$)kwIn}kkW5g?$mNW<!a!lOMJ* zkTJsepI*kEwnh#H##K(hQ_fQq(VRntDU<&3bdL<$w2(dcZPMllhkFH;N9+U(_l2UF z3VptDCKqH%heL`vt46v4pQYY}F?FKg*G}So!e5FP`eN|SM$w*R`r@w%`ODYNNdH&u ziOZP58ZooHUwF*d`tBN3_jD34<**Z-DjR#U;7SJO>*2x?zn>y3mnR$j%{wpk&{rZ>M@ekoHJ zPS*_aeNq`Ms|GTiFp*xA19+V-5Vc4RWDE{W=W?Q9bUi$#zRLlbm~rc=s%hXQ3GLAeDvra)fqC z$W;d6!vk7UpGTsv(pbe_`^SD{MuN$>l_Q6Z%8`jle!gjA_c@tvv6lcmDA}JLZo`{yc&pQr!xSZM!6+1otk--vQ zU_^(~2Y)R5GKZOL48)#|V3V+fE)888{G<@#f2uVAZQp;c2MLkpasrli?Ga(NXbD}l z!lxF2KcYZ#Suoo8e1Gq_Ee^SC*Z-1zjYqZHtl6u${G?GH;-61R={oT+4E>JX{c=Np zYR*?Ek0&-2WPv)G6}N^R-0W-R_=FSpZB!EkkzE{Ek?jxN z%CK=W5Fnh9saIIVKBK5gDsV*^YNMQky>68-+uL98v96L?q$Bs5ENE>>`^v#2yvn4Q zOB|HD&+!X`Q0boeEnVq2u&ukh9^r=nnW_o8KlY3dv4qLo&x|04#;9Q| zD2tctp@a?k(#sDHXnGIlP)6nWT5Zg3^5bt~G}P4p=@*+pTuR+seCCDcG_*DAq^t~B ze@8WbO!$|R0``pc35zMU(NxS_63a{rh9H#xJ@=$|xhQ z;Iw^~J}Gw7vM17pJ!K~iC6=kk8W8R;HXY}hUie3>Syh7uU?Bi7Rf$K%^E|89KrtXZ z6n4pKfwggqWZvkkqjs=apx3a3rJMlJ@f77D8p4mXhXQW?bCBIsxJTqSkE_e58}{V< zrn+s5tk$4uwh|HJ>jkn{=tTkS?bkce=5Pa2Bt!|HZZR@7^WntELmdv~GoDzPfw3gz zEHYN?LO>Q>Sq0GqGTaAq@sYX5rGRAQ)W(wjbwUk8g*UG&2d`*YK?kfhTq@aNqA%aK zmN5*&mCnM?%=Q|`8K#>n9RG z>XmqQXx2ra^_N~INTaC)X&Jv%Z)){}Q7Up9z}P3QX1_ z&RfgFcXu@{;R~0z#}?ar#6w0O0*!{5afIZmvOO!RrRaRj;Z!)eVlKMj^2d+Lh@31i zX4gJK;}`|EQg>YVNabV@gDAZTH3d7(9X1d>_FO8g<_~I2NCtVS=kcR_WfiPWZYO|e za>yQ5zK-onu}2_2=J76#=j1f|69;~gru1~*W#%6kH+&pNV{u?(v8+u6^L#WPZf7iz zN_u&;-x=C>AQEis(@46qcxRH=g`w<6`+H*~T?T5;a6P{5-vtj8DyudzJiF;zHa249 zrdmK8t-0P#L!gH9N@Hp?e51e~`SD9TBOeMHGLQWZ@sSs&K$8YMx8EBM(MICM7aqF< zf2lS8?bLP~SKu5>%WSWeKeB*@r2OU&tAJ@`4D!o}cydw)xKdiS|8y6f8d#FJJd?pM z(dbZ2rkR4eh$OXo!z`lvrxHUA^0@UKc6j*T5T-3lwTtL>w~mg!FaOwMrc8>D!@jwKb%_rh%wp$&2t!}B1_{jM~Pt$}oyV}A?~23~l4E6ICfFn(wY~CPlkq zy9-;=(VM^%Mq6A-H5fJPuJRuoQ9@aO-ec~xF|h#KU=l%$`zR)iE0<;ue+KYj5h$0- zxOc&?gt3FwILPli@np>V*maBwTdjAX8t3cKBH2Eru@Ne(xw+<+k~j!}b1|a)Asety zD*vbvjL2@X?KfE~W=n(TKr2xz5C{prQ-nkxM+8B#&yFF*In5BDoo%Za3Oz$}I0WGl zriqu!jKDv5li%f5Td!~iz?7`P*#HxnqP&FUQseS9JeM+}#TLYo8!be*CnSojP;{x( zl;?itDV}xV#$A^+t_DDLGDz;Yh|v_792g1>+!UhRDv~Sl$`|XAFxN>!8%n*t-FZIw zjnSkU+ObzLw;Hi>GO;gBIBfi}O_PLkNN^A+PIgGAUxJ=?^Z4~^|F=`|0C|*S0XvWIO#!TCZh7}{; zn~y{UM-M`j(4L+_%klok+`d69mA(580X*c?%QA;>-adcw+=Bg6S%2JBRqT}@tUi_K zRzt9VDsW#+nfC<-cn9R?^I8LmPADkpNDbo>O$iLLBQnUF^eOW!58DFcFLd*mdLT6vG>^)ypRNiPTUsB+{5iw~D>6>FC7e~mc?yhAxCcO_>yvec997$V znv!v{BeihCqwY13ggp%*2OT4$imaB1_4_VodbG~?WN>d63Ead7N|MAj9Tv!=i_-gTthAJZ`_zcOu>_^Z+Ik za7SaZL-O-Fh3D%lxXBG28@AM$a3clEcyj9@T@)x@Q9>0;ca1LC8i7dwMPK=q3x>b5E#cSqkr*a47(OV_{0CtOHyL2!N$w?f+4VkmC7ZSX-Dkxjq? zKC-FZSdL}7w(z4VLF^@6b|fG>)aL_!Cz4SxZ?_i?#45Ztdg5=%g(|kLs5FR~46^yX z8EoA|k!^V+d=z75##9|@jwD`AlK$GwrNUli+G^5^1mvI z^e_6D9uaP|JJKB6jjfk=&2G0kvvZwyy+ScLLn`#eMK#Vv@90}!bfvitNC8z@h{wh0 z`SXnfZPf=$%w_U~@%$OIUW<5oudakWEQieubL(tW$2wt-a%gt6(;+G8up=NUM3=R| zW1Sv8P*ngmw=^4)ZCk@Wm?ko<(B zhwtl&Q6gM$m4hL!vkyyz;wuao@~n$YsaxJwE<8hkXwsWCGJCg--6SsPxWT>^8*>y< z_-YS+F4TmG*@x*sjHH8g&suabqhm*SD#<{x0<94sY0@1hSdCu*+8P%7q1jKingJpb ztc8wv>q*=d6Jxpay!kgvd4oJ`z&h+v(@uEgWMy4ew=P-r1T?_#5i8C^7=78diw(~S zUHNn(cj55niz550G7-5(rL_ND{1$n55LyM<)m5v!iiQg5AsB3N~ z)%!4I%ci6AQs;$9>SJ;T7Aa4tCvi)NQ!K-u&!!p$QoVf?$|CH5Xt}`4BV8Mfbf_i# z4--47jJg0+(yFy`PIwRrXUlr3wJnDfm8pacRV1eS8&Q98^ZZmE|E;z-{DG)`Gi*Aj zOVu8hoA`m7eNKnoxP0KsY}`mS=T~vO3Vr6)HXA~+J*i_(2*FNA6-vr_S-byO%C$18 z3(ZrU=pQ*ap(|nZJe}>Bo@e`~GEvpDl`IX8iEVR2qrZdGBWVpyPHshblv3cchKg!A zyXA)@GhG|`oc1HFh*`l^<>h7K%#l$8RKzB=E3D^YTnspHAL>uYvio43+1yDBv5M zVnD5ixF~&qh#R4-aHF7Fj${t!YyV=Suqf}j&DKpG(MB+$Eo+BN^sdlurRTy=nJpRq zNZe%@`Bt9zN#>*MkjC+=7)+B<1DD+v)|5p=F>`(g@l~1)hJVv@ouyco{1hB0RfeuVZ@%4iQT_FHtWz=Et9xU5 zS-*54)2`#UL5>0Ssl>5SVa=2>3N3{WDYJ`L?zwUWSGf%wBUg{<0}#Ds=gsJZVgZ+f z+-{5*yYU{eVcK{U3e6p!^K*3`TR&J*K|PbO+`5^HMvbo*YR$u;f6}f`o=gc0HgJ^u zFjx0!sRuWa+QBwP0NrJuSUu`G89Y11&}4Ee%hUv^o+PQ9dJbSf;5ky)Z7XabD)ONi4gw78 z48KoQkMqg?_8p+tco0^~}HP>mfvGFjz zw;Xg#m8@$naC=Ns9oN!;>lR-v(RKcHDBy>=jqUiR`9H;JRX%Zk9Qk>0DQaT5YTp^h z{Ro|WwFV7~VXMq*Y^GZK2Xws{H*7Ken;o#a+vNNv;4@aHN2w{ z1Kh}?POqI8?qi5eyTwWRlaWz!DTBo{3`h*kM zH$0GQK~gM@<+6W>LF|M2O8$qK?@qXEVf04s=NLOMX zKpWTxLsv&ovfzLb%fGr+(|IqqoSw%=n{R^D9|GOXjerQo>;QA@y#l82LmStug>+2&;$ zpHAo~%9LxMO$_;Vmq#?#>shd&{x)FU5h*+Llg*m(7^X6fSxG(7<=c)MJ$=geU+Oef z4|lOS87kd&y+6-A<%?p1%UBFS^Dppm)w7s|NLX0qc2wEW(p_>EJ-gD65MiwT0t-Z{ zov!^>w|Jr-G0anL);)sfEv;SiM)c;d#i-SeHX(VKbx6g5)w+qr(#2Vx^K@dAw@Y@l z$cgsRt!{HQt&rxG55|})H9c0RaLJFh8{|wc>6x^KsV8MPbTSE`g&K6p*LZbBKHMqk zW%d$+F1c?OVI4m|iL8nFsQ{H}I}uMU@@j9ws%1SJwBND0*`!((p0Vmk5NyoUh&I6i zU=D)&iA_j=Ahm<~)3A~hmQ$WiIxGA-VUX_bBZl=m(k4eQUJYY&KVb(JTX-?|thZ$m zfwHsTzjtWIYrw=tM}V(D4{Om&5T-UZ30fPQ)2tPQ_&X|fI?=0exccd2+XNGJ({cB2 zRi+3}Hb%{X%}=t=o%h-pcG0$|piRj_H_OupTgY?7R6cxNv-KMf3G@-X8oZY~87^*w zfn_$Hn+k%_yut36Us_?D4t? zzU9?MZbRicda~P!BE(NSXBKik*HloUD`=AH1~Hxd)K*w_h{9QzjOfL9+z*1f`T5Kb zq>0kG8JbSZP&Yb7{$rbxo-!yA#{-NwA%0LSMkwyqr=He1SX3c~dMu%4^MqZ_@E`IS zOhJ1QB^PlnJgV!`;ip2RZDbC=?pV=oq}sBiG3=&tGWN>Rl{yHuzea`u{jR`ycw5#B zbHca4Ft*=2+ZL;w=Mt;{;3jJh)HwLEblZk*WAWW`XOR-Jyz>5CAIR9M%(j!wCCR~u zz6mqVnpL`ou}~v%NG0U?d8HWWQI&^DIISraNM(6gQSZR|Q(IC!Jln5Z>odjbCX4u1 zk7Po7iFf-?`SFMB3<<{H`WkS&Lf5iyWG_#ppzfYbI`*wxiH^`r56*FO!1%fQ7!J70 z2L)P(`H!yRjI@Yh7DiMTnqrg^eo*6LWz4Cy(kjxg+UvT;C8x>L2Yzhm|8=+3%5usP zH#cg(bE-wQQ2ImhT`A!c_HS=ddS#2}cZK^%;XQ`|w`_*z@1}ShxulSwULgYl|0>H$ zS4#O1uZU#|bV{6d9Iz3$uv9F<#>vIo4+#;py^Uo^yq?F!DWLp;bXy3x&8_Il4Y1P- z)iEun9MXV+#j^5a+v6o>t(*Sm;GJa(t!w{2eEoj>$IqjOto;n3zS>VLE;+RTTpUqr zXL3F8d{3nSzfDY;7k8)iTAQ%HqFBcUA55p9DpED(X*6V`rN^O77<6Ia4K9u8Jua8JH69a{0Z9KqsPk6ZVvIyA zC_g&o^DwhRP;CaKi+BjlF6N?+nXT41S|Pe_@X9>yw8i!JE7h;u8% z-~rOmAU(ifTY-6Wy5Y!tngECZ(Vyen!%2zFLEI}Tm%A7ox9<1-yHBGfoIM=AHfnmP zOw2IV4=o=;R@($p+S~dEf#S~&_hjZnZ>`DRK?WZ&N8MW}8un0ND%8Afp4>Y6x-CMz zNQ!zup~6LPKzO+_I~6U+#jRTPVoq@!wQdaydL+8d8g@>1p-rc5e02^nA!7PLjx_iy z7>-+rI+WOO(WJ!%t8XKjod5e4u(<#tOL3N%^Y|R8YOcL)LQRP2BMOH$jZjdG?5Wp& zd^w<}EBXYiJt3Sf)I+XWXKdidGB3yJ)rRQGvS<#=e((%F?qM-{d7z9$+$3iLHxYw~ znOz0k;CLHMmhlYBRv-*;lkTW+UZw{C`YF4#Fr}3}TK~|46}rhwG%DV1Ga0R-HKA(1 z)`(5tNY&|^>zTbt7DU^^%Q-u?x;L^vOw;VU*jr87)Z5X)JKa#2A+0uC@_3N|3QG8) zSDEkoxR_p-*KfXR!o*vicPAZR&9OV8 z8PCXyU+&|g7TA@rdGc<}Po&Y}XM9^wNz1VeA5SeU$zykt62ti`0Saq| z;O^~bcZ|9Uzke{&scxYM7sy<3{3_CP+S-5v6}h*)J{(G~Nm46#!c-SngG0~RUL%8!|yS%vXGdEm$!+~BzW$bTD zpobtg#G?}3<_Ht03V*|%^nlPJ%Z|dJe|z^?_W=JY?TIrpY92sv5aiwNV8>x58K&Ixl^_^k` zG!|tqf<5c7kpv>lL=|ztG$X6M zBj6HPLzf_D;imut6iki&t4X?bAA1ZQ^P+m9uy@#$!70u8QO2pgF*=Qiv2kdDv!`65v9T;26$X>+-A<* z`mgW4MUNeOExXmGPIK~kbr>;{DQ1CPv=q1!)_Ve5WZ&kYa8)d-WuI~XwrbEDeyt<* zcuaoV%6{9hg2iZy>vJzUiKW4fSsT2f4;Qa82{zkb)b)n=eUF5I=H7KaFv3anj9!D8 z#0Z6KAh&remQcppEEUyMLD}@FWl?j9E#n)t)lNy+N%QSh;cUB~~o z1!`~>uHxW?`&Ex9K{3=3pAzAGbzn*oD*I{~+X>K6?D6;c8%KF_gYbSr_@kWBCp zHQ0SU0js|8&WWn z9-hTS5qe)jmq@mMBp|;Yy|czbP*~+~B1zor(rHFO#EG`YNee`&a_ERP)iV7a)G|r- zU}0UJi5<5(~l(&N|^DAq*|2}6>`O2=o+8o}u%M3^CdznruV~LZ1VQqngvw~At zkFce6ar^Kih?W0KR~+`GM{kbrwx{DkVk22wZ%+`7(mZ+nn0JJ+ENrSl24?^gwP>X}8w=^>Xku z$PtPlLubxL+rhFg_+LKZq(gCI_dx%j_{UF!MC+T9zqpZI_p)qR_>e!@ z_22vhsYh7uX@T>@?fv;7@rqWEZGP|1pKy(aVG=Ek~bOktMo`K;KdNML`q`9eZ63LAz#UKo;F*u zAW?oh8-^qP?QOxv24GmuieP%4^vZdSE@NBA%Q)>CG3T4%?{$KTaYL-xRG9YR(>2kj z(F5IrIehLg%(=KtTi1cl!oO_HSHR!NmIiT2z5&ehB{kH=EO@;|g0MjdCTayqeR*VSKTYYE5CV4&ncEY#E`cVYulVvzna_%D66gSkS$JQ<8btD8_gk=#VR z5~p=a?D!`Y&rrz@U_4q6kw;WC)Nxle05i?%3+~4IzP`fc##i|`)dAJLbCvTf_)XlZ z%oO-ZL6aV^*kj(D;U)@$jlH?NFyfrV6t0u;+XGPBGO8L}z1aPxnz7~W*Urq_1b2cm zxBvHxAuUEfIaF($I8t6BUpaRqYGpCX*%9ba6pQr`z?~oYUc>@SkEuGZMJ(8s3Sc*) ztCW}B>{)z}4?~0tLl8VV%Y)~I3z}4L=oRgv+x9(g-!bPp{F6C2K`<6`3dt)-%?b6` zXP10|9;v2B>mgZlUaaeJ?SCIj?I2T#VRQ(-8&Os4$=!%pEogd6UrhjQwE0*;YL}K58}`hbYQL#)4b& zVa0ce+(vP?1EKP)+ewKV-B{Dl6QgGB^`-~yx&tG=c7!O`UL8P!4TQd(-Zj z@yfW-%LwX6XJ8rUGp%Efyx~YT{uyQ}udjy=4)NRGgvL$Gwp^ctrvr3TDZ7z;liQE! zEb+XluY*sMZDwy;C=89uzfU4f;FRcn^r%g?N@R*lGvu(G6@Sc$&{+pp`qp$7)jNqo zIbZ2%_imp9>29gDLmA-Kd{o^nr^Dugi^3xOvT}&k z$N3%~^S@%VFH)OS_UM}W0znH+Ldjsl!;hsL!tHF%og&;^!e2!$OE`tx&RDv^IZ=D3 zG6UoIg=ZRvU2z7XvkdWwu=l>k#u0H5Q;^CAQ|_L8KOe6L4&HotEPAq4 zJCt(COSO5yAx&rY`eg?ICR96=W|myzypMKqFLk1^K|G-KWdm_Nq2LN`5Zd2C>w(vT z_m-JgNof`-Oo?1fd*09V@R;t;HTYe&gO2$oAh#F+WUK~PdR{@h$ko{X1eV{$&bVk$R$1|9Gs3WKEcb^GK_xtDtJBmIm87<(ZQT0XunP* z%78T+;^sCBxN9F18XK-ph}NFg%CZ_n#YHb*Z%aOP-v09!K3_u9JT~8UB~j9?&$^*} z4+{cotUU2|@Ze0nT}1M#kZRQ?%pK>i%_c=M#zH)p8{tv_Pzv2j=m04Y{C6av{?%|e zZ_mrc`C`TUmn0?rbRc6CU>7)jL^x?D>{BKM`Py#_?)6h`^*C!^PyG+HP$DQ9zkR<` z*c2jETk4bdd1jPcbd~9k_+E}sma<+7n*_-pF?y-mEkfgK^m-Ft$ zRtGgH8V<6vT2aA{VY`~_r@L*132q@k6`+G)w`A?=*h#_UqEl+9#kNqdqhQ!|f_4Y@ zFZ-x>L?c!PJjmadhS0E0NwdKa^e!F$Lu@CRg2z<+WFmat53nSppd{{HXk+L_JlFWE5+~ZurIA+)D zz2ux8856|A8<4^PKJ!n+n~Y?3?is$>EE*oyDrC0x`S_$p?tn#NOy~qSWO5ZBmEF~} zEk;~N=((gN`81D)sW6Z(FIf7)$A>6Z*or6Q@pR!^ zE$B$Kn_wE6TSSvo_3>6b(EYAk0JURE4X8y5gHdx&$9$xzd23Ka(?9HJOKQ zNvX#M)e;umV5i`@ty%{W!$t1!gLbJD%T_)mYzk7+q`rn(xa%eq$7J<7E@XF6Pn0IR z?i}iydwk?Ky^U7|)bA7{P|1ThcMIzmhDhgYgN6B8VG;(hubo785dXG~Ot*YfJTgyr zoTOWa?ZtUD-AZ8l#FL7WWMX$lm6#l%2&r6t*+3S3<*^QjqiQ#!RP`_*ZeRHkUI&@- z$wzYH`r&SSW6Jf#`r&c!{y@q2;obK7_+T^{sP>3&)$?~?8!C{=uV!bCOsYUKL59+t z|Fgk?^|t$2tSfYCosFCC9RXIS2yjaIzRdYo+u7tLu~fNIf@a}J!0e>a;}O?kw=~^{ zTy45*h0gOtgwbewk4x`>8yZI!G%3IJ+wQaK?i4!nJ+QM+RJ(;?M_)U!z}yj*3*w`y zvS0eVouCCaGK0NEZL~#lUKkmjPy-l_#^fmNm=Xw}NZQcpQDh|#AB>+!sxVmG&vtvc zZmG4s;2?L1*LcTbO6c}2pU8H`NNo*g-yCjoiBoWqzoewUN&H$sjLwB5DKyF0#asy4 zqZy3;DAsw>Mr#yQuf3>3np?A%f;?KlJW??Av|*#rV5_Q(<0h@{P_D+1%-r5t#Ec0- zJ0nGm>OCTlEzyXzsfA9w;m$?TQ=(4{WFvG5S|NtI>Xcat;ha^bt(Jj& z#<&TZp}f{qyjvvx>`4#NEI5GPEw+vp69WL1WK_h?cO== z-Z33dM}#T)N2*vJj!JKnE5Du#pN)U66J0&cEVGocoXH|>ugDEAKC`D1JD6ZR`T9Ni zG_H$uZwVZYD!fVd3>xqBIuK7iO?N03lY6MB(s6dEbYPxqPMHWWGl6w&!=4K|fqE+R z3psq4MP`qtrVnqTdkxk)#;Dm>PBkwDbw$yYo0)J@nppNiajVb6v9BzN7H~rzIRKKv z0b~>d-clYc_aRWG!JWwhcM<+Gk?zb}nhy?-#hH&7?q3J$5aH&a{i&_h@O80a%l;Sw z(%cH;cPV1!88!lS0>|*a4xAMy6P(z@>D{MY4dV!p+K*4zJJET7{vu6|`zjiO2Tz2xQ8c>uq2+D$z!rY)Xfm$Q_H;!H zR2z$?(W8F7MZ7&kCr4|nM3xLPhVE_)s}fyw`X-9kp_%P;IA(m<&?=u4_6qz(6P%K; zPyH*vw|+W(0kklpxq0A#`NI*LY}XdYbEHNqOKXND$W$_a-NU3KVmvBv{cCoo>4wdg z`dnp?4zY?HP2Q={2wx9IvcZX+oe^Oq7ymSuPclg+m=Gzx;owVi$^w+_6Ydk@lkAar zb7`xaX_>f#RObjEuOC`GUVB+rSyfq86&>UgQ6%Q#lFp_G(tj%mt_`G#5SKN?+g?Rm zV`gO`${qsZ#0=vG-_iWLQ`PF6W2g5kI12IH6GTpka(^-PFBh;LRJDd6|1hRfEH^|@ zX==3@A&A|$@EaN-P?W{Y;ok`hT0)F9{aKmZvGG|tzASF8DEK!JjC@R5Vdj}LD^2cA z1%yz>5w$$S;Y-AG1)sq|BVoC)Moj?6=!8W;s8E7IN)iGk5#3NmOI~6^lYipLm>Xhz2HLzn#z22w zqOB_q-i#zfZHkft*8F}>x)2~ZIjku=Gf+(c@dE~=u}^g-;#!*v!%lT#_jBQmCB(y@y zvOR)-SN5GBD3ozm*QaQXtx!lLT9YZ#VG*EN&ZyMr*zvL+xzCkzvj|m;H=MUR<=l-6 zcXs|ErI>C@rt|%X1%EFLT6`Uz@Y~E%f|lA3ygB7YEwLDAsWYI4oM)l&4%S7Xu11rF zhEWxogNB7%!?tK2QQKT<$Vsnky7&-~9dV!meKWRoW28oH@F;`hTqi_8H)?H z34C)kyJWURWd(^k^kZbJcKZoa=N;CI*C<)xSMtswH%<*~f_*N*ie*gcK#9hTOsh9! zm1%u?UGNlS6k^Ajy4Lrl?D`~;nF1}%8P+rNmGP_@b;UlLi~XxaC25rvn=3Bc9(6BM z0ilnfvVw#&t0GK_KsCb@mTBf3WC!#XaGAZtGuK@LwAA$D7TD(v*w?M4L}#Y-m|WOF zx_+!XUmdPkM&UJnm{Qv#4DF0C#KYR_ZXh38@{O^wjLDdbj*UM$8PzSl+bM;XS0uOA zT4lNE6jFRN!(In&I0mH7U&8&}ILvze0*(`zTe<-E>E7z-l_^^3oHtyFR(p&Mfw`GM z^cv$kKxv#@_zBz6f^CJ|M|;%B4rLmbk@$GgfJrek$Jxp~_a%DuiUWdlHY0@8!$h4` zlZ(3<xY%BISONZ_0_1Fv#Q2?dwO%$XApjz)KtM^wYuazZ?66rIaB#P z*;-`Ms_NDZdhNlidZ5F2qBUk6kB9UIuxX`;ncwVumz~Q3#nS{EB(XEuvewD#S9MmX zSc`W^$@LLDAvuyi7k6$q!Q2fZBe8Fz3Ihf)jAMSr&&u(AdaQlB9oWtp`z7HTuquo1 zEVp%Q!mq#eW2-7MvKW6VveLPBzfzi%qrAm#H;r~JYe(o6@!M5}WZ4^r&D*&2)-aU+ zE3@W$!={m`Mu$c$d`uFy?Jpq<=c#pYZ@di+6QhiowtG#^ulFP%INc&I!j{ExD zhQ=>P$Aku~$V%-#4eoHA6(4plR z#=!TssvFD&xnNCRS@D5ZNw3~Y;02XzfKz9iQLx}50W4x7*A1c%GG``0qJ^NdbcT6;}Z{R=LVmg%LGOYWA)xhm{9%t z9Ri~m5RvN{hsLjT-W}cwk?TbH@Y6-7d4y+(q^R&*fL5Ev6~W=Cm!kyW5rD8@Z~7IY zWj$+>mN>2*^F4LHv?+%SOe4{s1DR?z?(hYxjS1hiPAxg(sCAOB(K<8!sC9K|0R)XL z$T`-kVIXP{#DOmm!OuO6@Ap!avS}b85m?^v7M#Y!#QHS*m8Y4%g+S+9PeZo(3Cvny zW;V$BFUy2Mqi4GF`{swWolJFiBKf5i2t$yUjfN`=#EJpY)3rXRi&rLX;$3(lwz zxDGN&M8-)3j>*}cpdd$z1!-ujdl+mYe7HLOzN-r4447K3B=1T#7zb(h}zS_2z^=L7>J^+Cbm&3*5abbz?YF zqZ%ZBAk-In`w4I4VJtG3rfIH`_7wZRZA9c;80Jk8 z&siEjVRJie<@PgRyXxDLN+h#VLiTLLocz7L+xSLl=wd?rFDC+z_6G5Hn$PuUWzUzwwn0R*#4IVOq#v( z?_9GYJz3I)QCL$L-DY2bqbsyTD)zok&Jrk0;OuS?H-M2P#2@k@w;^9J6BWo5Q2Whb z7hdVPO%GWFn-356Ks;AcVQy3ptFr48s);Wmk+U z-Qf$0O14SOmr|ZbxE$}9aadyVBK5Q}6<{0e7kkd)#kQhBcot_rEmwa_Eryp z3~j)gu24H7nBa~Am$T}<2{B3ECY1>Ypgo}SJm3LTI-c@B5)L?VK4BNPd0ZO~*a&LV zpCA{4e2|KW;0IzX_D2&&#G#Ncy)$J={s;t!o6@Xkv??9OKuBuAFW)NAF3*H`na-t+ z+qnG?0t{W4LOw(09~@(sP@$RkIYJ9$YfQVn+AFN7*WG#=olj-Z5Jf0iL?^$Mc*5d(XW*me z#0?#_rk>r7gU8uzzFXie;`jBA$yP5O#a=NcWa8b+@Z1o!%Ffvt5Xur)eFVS7FUXG&NU_UNgdN0f1Rvp71D*0tGD(w9RhBsa9P z=5p%7&)IU+zWIa2g*(zGn)gWeZS&(=XIJ+Q>He!LJ0;^Ctg%7NlDS*FbS}~m&5?GD zjfoaQBva%q;MhbysN##Nfnii2&{O^@A;CmVCGLI!f4eGJpGfMDm*7&)Nt;c>w_oG@-AN6|jM!8C?eT6(F>xUxyZS|+HG;vRrT z)n-kPoh*yvfdjL9B#??L>Y3<$PCWN}njaVmhh@Qt3s9^^2A0Zjg@^EuFf^U>#^&>F z%NXr0Oq?A3z2A98{aO`Ss#|NpC%%nFR-6%k{(*7fqR5s5VoC4xepB7xzKng+M{OIUy}7l)?nP0iTV_lMx#ZV?^O z<+F+l$YMH7Ac=y%J=$eMV8aZOF$A(IbgybgIgXTP-kPaJrUm0%retzP%YEw zxRmGgTU6#9A8|RClPjJSC2y;#H)*#ED822bSR>Ap#1wZrB{hC-REN|xE4F6Ek+N+u zeWY!B>kh&J^M0h?|It1RUQXG2`$O11-0ajm{(j(m0@xbCY>&>#B!f5n-R{4|slQS<)g;5RkG+r7nPHz)t%zF!D zMi+CvCm>mcy;?W~s%2VY)6@b?Q=OSc;xdSPVNtfC!#ZpAB+*-wXJ!J!auT7>1+}ps!`NL z6^6o8p`(h-!!VyR3cWj-y?O)TwJar2;{_V{EtD;4vyqYsIr|1ea1bwW2{)9H{Dyuq zkge39tH$k%54%ALVoS@Z62?cCL3D=&D(&WRc8qAg3HE=G5~3fq?=MXz-#q^u5-GBX zisyF{+E`7nkDL2}Q(>gAspj^RUOA&^FJ0GjeSPlkf7fg;jUERI!T-JHvjJ(lk&oC!C9JL-MQBeWBm(~dUuM6e34l)7tXa~>uOFf1ibv`gS=DRdUw7ghpf6sJW>K%b^!0m~R>H#jC!9^St z;SUEgabEAbD0!vb9|}6i=t%Hfq1z2^j9S&L@K~59Li7s|+zShH5S7FDI&Gs_S?e_7 z7Y{|VV@)^ASI;PX%#6jg^zlT1!kq3Ap6 zDT2Sp7n?|F%j51yMVpTYy%pQqdTAWup3qmk*C@{o$g0zM^5y*#ety9s)D@DQl+b7G zcq2|}v}Q;g;4rQ?ibkt=*aaJjNH+ODWAizWAU_{ zv_#j}L<)1SwbEp=G7_cMZ6w=q_k9|EY`pljvSRmp&;NHI1ZuwO)WJ78O5^cKKJ15n z4!lG`1%XLv*FtrlDU%fNwFW%zvstuocasXuJp9@or8 z`XvC00UgfSrs`)*f+?qD4WRjm|`Z!`f6d%dFO&C3zJ!TXEHe-i}=r@0u<^qX!kbe z7TOkc$U^{4?JSzP?=}?La#(ItZH2e|5|;qq3d!!CMU11>X@?=}j(z#u)__!92eb2Y znVZVSqx07u1H;ubP;cWs00U@b*WT&cdNv4R;qK*@(uyE|MyLP^Fux*Y z|EhDidIvHs`~t&gca9a zWF1NpO6Q~5+zv?Ve0G|wtMjw`{XGTQWm$KCSKlfgs@{S+O6OUf#sYX1#1&+bD!+oP z`WTEx1e1(J#1A=f(#4dpkZuN*GGVy1ga@ADa6@|>)qJC%;lGE1TUuFC%kqfB+s(Cor}TYIcN046p~V%x+)_ekhWDjH&f=sJ=d2DrW9iz-L??wI^`vI zQpfjMVho>UH50?I6Snfj^C)w561GJ%yK)c)bBQg>!bzdo%7t{0NEUs7l8mq6$%dZ$ z$l?->>Rsvonm%7I&;ZC{pT@Fw(sa|Exk!xtSwjxghX7^k*;%k5>pC^3hMp-Xv>rc+ ztO~#~`fCBgIWf-99MlkqPWh)gZIUaA69;{LH>ie;}l(!p2&;6qJK1zSa%FOn`)k%;;La;3$B_ zvlv$=G&HmpHBgNaLcWO53&lBE%?E-&q9K@|9v0s-l$>GGwOKHJ+(oJ#c(^{MO-N4% zxttJs3IQ;6hXv%Xzq-x;TZ#Yx6&2JMqP5_8yKI(X7*67=0~EER+aLaL>1nACl8Szg zrqC+`IZh1r?VA9%8qpEULXnBv$}+!^XXX5Fw9={H0!;yqfm@mMWz)OVH0*UJ=7Dl> z%SFKVu91MTO68Ejv=ZeMa-sq5Sg{;8T;F&`<%STKV-u0|wF3SeB54UN$B|sXoA^1- z$hp&1w5QUO+D~{~2$<6>($XefxY5|BVD>W)f7g5_)Q~9^rC0Q<+KuAw;)dn3y`%56 zv(q`#P6LLVp2aqmz0!+^gbA^EwO5uVq@E3Q;S3`u3({yAn$~kUP#z%VIf$bP8zM z>;jmC*SLyfXK8W5av6)%JPEQha9ifSxxH|Yq4b?Bo3Udl3cT{147+Kie@L_^CVGLn zJL)L$eC(}!iwU0euYj<;;WoPF*bpxrevYvbSp4E;6Pdj%=$j9GW#;aPLe1Kcf`929!PQfZE&swn8g&RFp7@2N7oatd$Xcf6}1 zT902oftm%$Mqp6xM)}=xU126cur&4zxO#@?Te;Jck2mVo6F#GAi>7H51kvf_jy&8QVWun&Fi_#B-l;h*n9fI_yN(CB|?i;w(8(`{wn`25^D@ zG4wq9n!$Pq4-s)jlJD&iiQr|Wt(mcUzRfoB;?rELrb~M==-QlaJBCzCy8S_A+`i#i zE#kVBzJNo?LGHA8gmOB>j{>kw7xhSeJ$&3>V6d`oaum0OXn7-e znS7(0JsN*|>!QG*#6SZT@>mH{*+=rje?127*HK)$}B>;TFJY1foxNISu zCjT8{6j>C|DAg_3U89DvF-v5Cr~S~pzK_B5{qxeL8HV71A+A8IrlB^|=AdV*?3z5Q zy`@&4wd!@{ZkyT@?x1YuW*XKkex>^iLy2CAo*FxB?{Tx?%ArQzhCICzJvCa0E9tJB z5ZzVjiOpCgK*&57o0{^|s1)Gdw~>D7h8Ew(SF(70*0=+{S&)*ELzQdoO2z06F)xeE zfGPtn=n$5kOSE)k$RZf>KTyE+($Q71E?24?Cijpl{iy&W1SQ}hF15TNH$Y!|<#JRE zibee6ue7kezCQBwRur)HBO%!+{CsVl1nIW1ALM?NJnGc2d_wj%>LR6obf$)_UT@Ur zNH9YQ)i+(ha>-9;f%qNQDbRgcpdTjNQ#nP%NGXpU!Y1ThK6R9Jv)l}?xJI_1vMutOF!@C& zU=zq6Pl!};ZKtgRaVF@t1DuX~{30hkT_)##70hn)V>qn1b(J3C75LmB)K06Ed&6)!@ za>sgeHqD1JPy}=cbVz?soRXc|c@0Zfu5|B>-(QVP4NJfrtYaE1pzby?37i-32|WdU z-}ruj&vH;LB7~b+&ExKd{4Et`PrAMG^Wnj)jZ1B)g`+Yii%H zwzAZJBt?iAVO65901uI(u$N~O`MWE~z)otIJ)VXNLH%WmP{+D%@__n*tb88%Hq#5Mr-!;FbbO`auXV(SjqtX{Vg|tG)J^f_`HEdc- z?%iRFreo>-r>+@aJ11sh{~(>*b2(h2T0rT7{nt;h)er#f$c2Dz$*cFj0Av@zYs}1Q zLk^q$LvR%^q4XL4ALfN{pBDS)4(S8^t;i$OKz8U!|F?;+Z{zDFe$fH?H1u9W`GvsR z{yAR0Hw3OfCG6}dN*xudUi*t0hva<%738Ir<)yctOw4nd`IBkkHZNZ*%`31F;;0I* zvC6KK^Hd|=D_8O|Xy7r)*XOJpl}gDA^Dy-zS>;3BPuzEkh1Gq>T_2NElr@@AXkg^+ zuXa@a7*zOMu84XV;*VB&`fjepPYWwft_C7T!~f#jBL%xB-Y%oZ3U~)ESN^|zkc>6V z1h?(s5g$Wz>Q8QBILJ0!xT-q>Jh#1x@UQSB*!|FA6@q>vx8ni&IOH$5Z{4$C-oQoY zn3aW{rQP#h6S2k5P7YaHuV(af5{c6xcAZFG`=b&=US~edI#{c!#7vj62suP-KMr$1 zB86LlzL`Y-j3`=D4QxP~tJ)7(ex6_A6!)2Oa_+HY>aELQ2*jx(_T2C3G6pBYpLjSF zvuotTkb=-AY>s`nJVU=V4g!DOMSgDcVfYDW#}=Cd+iuW`<>bweyQ~o_>vKEVdh&A4 z`P^(>W#F14WoVu^9p&+uL$!Ek_~Eto^q6z&2(t)&KRp~^dbwBF_V}_8u;1Ram)e}t z#h-tQaJ7yHVzbpXvA#$34)Z(=|9x5OjqfuG^nb>QW))91!}*LL-T4Iw2pb3z_^&w8 ze+N_l_h`}o6IdPi^BoAEssI1|sYn|C^A3QZ3-NZLT`qftpZH3}=s|N-K@fHc%iX|1eUTd{3`?Ev$CNJydhsaT9%+M(VP?12A+RjUm_t{-*+;u|R#jEE|n81 zTGc&jPWzZvlmpVV_pWd3{UqC+wOvWLPaHNuXVM^LY|t}vnc?E}La$V%3{3|f-9uL6 zV9~;~+U~;`D0qWH;~*PFM~rjPl*bYf3{V>&Fj1*B*~dB`nT@#5UqGVD-^A%9dBdE= zA%8=&&}gQj;PrSfwf#Io=%s$bKNl4A61cj*P^a#L3d(uqTt@gudKvZlW*K~j=>HB4 z1oZVY#b5L?v9)!wv2`+b{1b7<9oQ_1VAkt9)+lsLkG1thdmFy|EBG;#FBP_kJHkqa#o(^z?bKnbd% zE=n;((pUjIR9@|EMpWK}#_BP82&eWiEdRx)VJ_}#CXZdjQ3}T3Jq^*XZ`XcZTkhy6 z2tWcs_H!cAHlpJ-s`J3o5dQqip||u=P6RE>^a^VvJn%%)zY3n{6^b*3n|~*pd_`k2 z{$fwhj71&xM1BkTJDvS~!tosbH>@dKh}{zdKayJ(q(Q=llv|%*A$3jxoCuA)zLCQ% zUe;^JZNWWXCnmxy+53udr5Qo0lk)CT4YosW!McO@u^mGac;qU0T^m}T%x<)HX@2(E zb@hq4c5xlpeZ22j*O2AjVz~U$jxhK3?zC7>jwkE)FG~7tS3l=6N!X6v{h9q*KvU&6 z>I<+$v!ufyxF^|D)Bzz{KBm%pfWj^5q?xXH5uO z&ai4&ct%`bHad5({~}}&8^;n;&d0Y&c6DwXVYJh<|3%2QegHbgQE-?hUPEBfTh~4Ir4H=8>!^q7WIH6fM6QRpgu~9>9)blX=(<#Qh3<88lm~2;pD-nH~C>0?Bj)BIgkaCm1brQhkT~D13OGaWohMUI!kK8q%1qo2WJ-`d;-w z0xcg{xi30o0jULS$hfs~6r-f(Lh_PHSZQOd^$wc+wa&04# z#qxfA*Q%E%{0Y4p3{kjG-6}r`S^(UK^E>J~n`E87%u0}Z%YC5slyyufuvTok$s@P< zL3tD*-(h{`(YxWG=>g^gwbNf&b={q8>7}pzEG&dbU~1Q$Dw*Ko8+iaG^iS9T2Z&cx z7m`cqP?fW4K{?{{lI|5oX;}Lae2i->zKHK!aMhPo|ISD9&;=`@>oI3jomV-O5PK~l zov5x)K9+zH)!DW|ISH! zbKU3p!ZmZ*1$&#fOC``e>GJuwKD=;7+xlbwT|9D6zGh=IGy1%{|{(4!1 zx}+_#70whF#3>?juygoU5?28yzh{^K`lL4qsWxEQcQp!pXas^u+ zCF^+p<6xik1|^#0N9ec7Q;!bA*zP!`LJ++6o5#1!*sNMQonKf?PQpP2+~)3$H_8a{ zeFwnOJt?mBn_SHRf>OJ$dIQKa*QCN8KbrVnw+J^Bkiwxro`r1yDd-f*Hp-MUp~lpc zH%Y`bY`cU5&_#q5UqJ9cH&d05=Z`%|2AHqp0u1#$4cQBL1-!>+R@ zho-aClEboM%-;&h7==PP1*wmMascz4C$^0U!AgQ*(NtUT>KMNm6yh6LKv{=ZneuXI z%OFM_hsXp42GlHATInp&JYoSUMz+{AuO2Nx`+)m-<57=0Q5a%%L~D4C)PETXiEQVZ zH)+)0k$hc5yUaLqX=^nHz>#CIqFrLm-wnvD_h8AfTG1YFZX7u+(6j>^_uhedUG(gG z^bTOj^_ekh@SnJ$#Z%x5O;oW1uz)sGNq@sCQy8m?=9Cz>qU~^L-2&+aM50Q^r56~5 zdH;5{<3>cW1a^zunvrSR9StU-fsxRiQfh3ERfI)l2yAzI-ia)ZogVHWBYW`SX!ZTr z-I#< zwSnhliXYk*hz{;%EedZ`pPD?xr3H%SZ=MPD447hR)y9fC^Z|)OG}-~J%V4tB>g4Au=qXwY|WuooJMusfaL}*D6$a30YQF<-M^$QC$kYJ>j-JOwsM~A2?yu1^G|6rCk^!qU2QP=# zY_sFkZ-i~hYe<*3mesO!tlHJmC_xAhnr zG#|z4A%G6Chkh-v;ZF^g7`;)p8KH`F-_Uc_SSXW(YZ5LHEYqgWj~cPs6Q)i((zRu6 zz?&EV5@XYlj%m_Fw1!YBpz_?u~g}(oy)Wg-g zo1P6>B3BQ})OLMCnfl>PS`9xo19`wB@#Ao=2i9gF7~Vuhp*nT^=slz;HGz*vam4&J zCM}N%J*LvqANSb~77^nJ+uB{LBuohXJJIpO7i{b(>M0ljb+cr|*)CQ~?cwPPTVrl1 zfo=|AoGC;o=qwqLfH?2u)hB3^#&)Xxmjrdg?T2IOuJ$s-> zbY^Qxk5(?7XE&f>yauz#Bmu(QKXAC?X#1_0fwJoRrP583B_5k&d9q&i`J6h{+;`dG*a5=QJ)v2ey9}yawzqZ!z@Qg0D9$X2o%bl$Gre^I zJsN$5JG%epn>2N6Q%Awi*~}p4zs*@3jh&p#ZA|}~L>FkT+F%VMc_YO6BHm)Fdv_tG zpnH$o=-CFCp}XV86GhSw6NDrg+s66I!qKJB6@y-w;I%8|93B7pD9$s{`99X@Xt!Ss zt~)HPXK-SzwJ)8ujpu2?WxVfS8+Nt50_Jl*Zm-RoP98ix ztXu^MS=*L9d>o%@Hf>E87u%kMy3SqbLae(8E`2Z-*R$WTH+8DpuGV+%EqE)M*L~cZ zwP+sjs=*BRuZc}sTD`E@>J!7t?;LpH+Wsf`BA0^BncoTvfAJr1=y44etJofiEv)-5k{l&PO`5SZkT<|wO z&G}#&)f3RPY?GknwqLw4U%;Zh)3*gsoDWVfPaMbZE|Bp%k@WUQ`!5ppWf-eU4@@0g z-Y$^yCkUN_ht9&|M7JaC4pySDiea7B^?;pPs7}z%M@pNIBV0**v?> zJfd2sZ-(f5Uoo%V?__d^x@7AASVXoHqnu_P>z(X)e6=34KQyE zeOdKxF77sIv+mNsVZHR4cP&_*Jw02hG(XAGg!e{!^L}Vq`IuQ>KM$qhx$PuERgOG>xp>=z(w#$Nd4Dfu? z`DSu8j;A~PRCha#Pa5`cGuW`&I=#=l0OVTbjCoN5GLJBs{2T|(D4oJtpPuF z=lUhf<=Bp%6TP_6A2goxBd>V4caN^Y>0-NP6X67p&j#;#oM7q=4>Sk%irbZw0WEYd z&F3|7%*!WYznt{R|uaMCepR+H~yGyV^ z9(Qt(UXxH%I0=kMgT12BxRD?_E}~F9Td60^88>!EO&*wt7=Ch&Nu>td-!rxlj3zBW zoSBvlk*XtDd?s%@S#seRHhwI~3O@p?eMP;0g+B^rDX(8CxUov=OM8)W>W$Ak=JY~y z+|ty~^h_CsQ_DU^D4w8M_^&kxrYkF=c!`=b;^v1CnM`CjqCtjgm_Kq2)?1|5aqX%c zf|~XPYe4d0R0Wj|ue82(U$Sd7P+J7C!SxZ75EwMtPq~s`qMG7wr?R*eH8eBf4yMIz z!SDN1g*L*sZ)^7uJ+Mc}1L=Q@O)MyL;~gdsw$4iHZi`2!#aUYonhP7GAWQ})6f(na zBDOlAY%s$Yl_ZbWinvD;ZZX3BPDE@G6-NYahO@Fn3$PC&wlox0Zx4i`coaq#L=Rz+ z8{uj>2}U9jz(ZAGfOGAz6J%*{8L+1wUsbsB%8O&~f#&o@xz&kRs&eB^TaI8EBE-aS z6($G)>QF@~XK7+_&kNiU&*RGVPgVOVLV^_Z#W^w462@9OtUq25I=*I5a@etZrl9fQ z_JB&*-n7={yLv2(93=&}Vqt5~j@bl^7MKLu?^kI|3QRQTh9Wh#L6(@SnR*PYuwm?2 zm}^2-=0~n#Ddexwpk5}%7Rj`E%~Kdd+y}FbDl1Kmy9F|o+&cG zQyyO`k7|rg<1}Y@P}LDW4X2z+^FKfi$JJ{Ssbb$np@cTg4J{EqqP;~-mg>WnFs8BJ zCF@oO_rjia~>>9aVy?R@yXsZIBENz8DP|fVCY+%ODiom2t=wk|`Tu1ni0WC|1gz z7DL!k_C$Koug-p9s3;Yf;c|g)=?Km|hNRDY&pnO$D ztC#~jm`IYc_o8i}YEV%R;h>gxHoTI8D`y9-7qtL;Dq$(x9vk|)dTHlfp@^Epw=i09 z#jYcwB~+U|@okN4%3>!uGD*>3oiOYE(x^_I6$4s?GJDGldk5GvFTY~=w>@?(FO2ux zv=)P;V`eglvtys9J)ZAE`3S%QcmF{ zW1cw1Qn)86!>Bb4)Kn%|w3flL8iLF*;#K4!j^9+>^Wjg*W?D8*${JfH4$>N1ern&HPKV86H zHS|bL-AQ$+PL}z@ZF{7JaHl*M7MB1Z_tG8q{m}|mfn=;2l%&dSFTeoWQBqLLj}`Je znwB-3lLb?YB#3dSn>S?mqZXuw#8?;wR8@sPVrZWRR_-_4L5#>9GkTTn5!sqwTa?b1 zGh3eH{9{;~kU{)WDAj^B-!`v<3Wz7-K-GaZ^N|w>7ihk%*Eln>Y$cB-sS5ckEFpfp#rR>bf`N#~NsqoS-^Y!=Xu86{o_ z@cPOGeZZ$!OWv(4u4RY4nScm27)YFC6wS+N6eXt<^aPL70HsQlpnz82T_80yl_!CG z5O|W-PKvpo8sQp6uTIk(MvZ#wfJ?Jh@4_#3Jh6A`^YFn9l}Vu^9mgvQdfBwo>J-Q1AkF7m zAWPZLjkwn9426xc`|D<*E?Q5W8K#gOQ=t_x0I-|12l#|0aY4kH-n+ysox1o1Xzjeq zZewDO`fx58Fq5f?$TNBytr+u{aRx*a3=YatTfE9pW7-alzW@;Pn6FJcL0hLa^xaqL z3aMp}GI@3xSL`CG105#ulx)m$MGUif6}|C!af3S#K@os&OhZuJ4^sVy5f^F^3}9X1 z>SjN-FmyBRksfk8{9K6$fSE2BJAD1DaoqbWiiAh%F~g7^Q;HG8`_tG7IJ(1>zW#Wm zO+pNHEJ|<>d`OW>La@w|?mjI=xt8b7p==073XhA}+@Vy)^y<>4Fzu-=bD#lRTUE9T zrs4~lTRJ4dnP4#EgzcJC-Mh6g1%+zCRVajfv<{&(?tdsoiG%LdC_h5`Mkq?DbyqTA zhh0sfq~6|Kj*P_gdfd=^k*XYl-}0S*Jeq6dxR{L+|Em*~hpHhE8<=B#CXX?|U;17h2n zw}Zk#Nn@4(u{ONYDcQVlZZ^mVO_SM)2dqzPMHAM?t;`;Y~Ii9x0^Cq**ZA9qR-pQP#L%zJ{0=XXKgpGJi1Q2 zZf~l;r0^ogf9&Qq<1M;QZu)hwQ+8^6o=SRa!fJb?&#vvlrmr%I)PF~|rhRt4W%{08 z!O;OUa7U(w2k=FwN`n{BDja!Ct`pP|vE56KY?6WKPJ(?qXkeSv{n`0U_m9gKHEpPt z$nZcwtaKp%-?D{`v$cV-!{;s6Ur*%L*KJnWF+;Cz!0vGafIv@irDziJj3CZotwu4O z80ytdCv^Ny*rOTV1I~!gwB8~VPMa8RSd9_{fAf;{mKx4@6?T>6WCb04yxO<2w`Ezo z-rOCZwR$9G=8UV%-tBqa0nVO$ed&Bpvvbbw6X*AgYIVjpvVGIfCVbzIs(p_(wJU5= zE=*UC!%gQg%GdkXO`h*xJ-RlvoH*N#?yNYLJJctNSMO}R8-1CyKf_m)mp?fzv})SY zadFB^y!mFFd2p_tmD!6X&Yu~%`tYsY?#zm|t;w91P1yWyVCu-WdZ>@h8Iz*;!(@?TDNl^IS`*LSu4{?EJrZ|c6W@0#uvrr)v)9N5 z_v%QiEThw@Y#tr%d_K4rGUZr)x37Py#dKp@p4^;7zj-UR7$fF_WlF1l4@;GwKVk2g z(E^W+b4@uJUGCAs6;L|UAE9w-B_ML zo3B-?c3Hd`zk=2sh*9yrdZr($RO&l(uy@;77v;HfaJO=&Oc#1`|6MHg@%~7MK0daG zqn2J?>2(c=`-Fdm7)yI*JU@C`?S4PMn;Pt3Vb^ZwCwcWCyqB@7Gt6;JAV^t z?^0i*f2yClUc7f8`DSwia5sN4ZtGn3!nJ;HpWg89yuVnpX4k8Dne%ohIn8EE`_PhQ zolmIA)M zOVmlrKX$LpQl47+1%agkTXkQ5X2+HB3dr6TRX+)S0gP&}DzxCnjdL8$+26QfPyLPQn!%t!$jO#6xldAg~+n;pOSErjOpuddg zXAjFlpM%SUQKDUyir0WkM0Eis6X=hd^}leQL$-?7pwcSig0`}NcU>!;pWEB zw!(&B``+k0?zIQ)jG#(qV8xSmGJGsF&X_o_>>4w;%R|QkXn`BPzm*48t$LivIyQZ82B}c{rjR6uQ z&Rv>^9)R4@`M^Rz{FHMiqaT*Ymw+|_5g`47JGV@hL@>xIU`QYW`Zyq9e4sCWTcssD z{C4G@?1)aBL&@VA!ysQ4KQAL2KtQ4X z2!SB8BUV7aG`j?WcHcrUq?f)c@4k98|MZnQxre?-K9YQoP#5J3b#EfsVV zArL+*DoN-oT1Yo(@(S6){FH%!hX0ZCf8wb@98_|KqMYYRi51}+m+NzjgoR?920IYU ziyOSdVWxAEw&(|~>sBAu-ad3!wjsPWe52#7$}7Xha+k}kKYBjdYxlgN-^M2v!=TGe z3M$&A7X7~3HpWzW;<;KYlYw1Cy|J!qH-f}wpM2s$!ZE=qd4jOo>5S~VtS+`z*2t%&ZBs-cVFpwZ8^rXjceuftmiD7Z4mL=xQ}N)$>RQe z*RP@5u}Pi#5<&8KQO~Fv?PEtcb1QOQFW>f+G8w*((R4PK_oC083>QayBm71t({;NY z`9Wze&vjdV^=sL2-o&{6pnlLlVc`vxEF-BL^EfN!{Rvdw{{|`=Dw#$ynf$8l>9e^$ zo9c2r;SbCvhlo8?&;%Byg2}5h7I$Nlh%@@CmYPwqgWGPTorpb>o2&vL;y_UNz{Fp& z2;we%qk^8r@QLE$P@AxCECc_cqH(DC5;mz2jtu1c&qfb}C;rp$zyzPXibq_##-$Bn zq?$JyqT~KgX&x)toP_*tZ-d!C@&>VyBUhzkE(XR2P#gP6DyM%Z6=Gv$o=QG3mdV|I z(PwR5)hFP8tn@>~O$kEOk%yFDr97sdv}SATY9{)!_$m49wtqA2v)d992wRtzw24ga z8uAJq5`7AB{;yE1^o1iRFO5df4(`()e}CaWHsODf6`}bmIM)>MYf7E70W$ahsO1?X zr<;i+NDiG??DgaS3L}FM8;kSgwJYnUOa8Ik0L=}eAbN~K5r+SUM{yp5OXglk*XWcO zBqRZ6++QjMeflX8!LSv@>7{PDy99kE&3_~d4{CI!&6@h~=cAL)Z2!Ce%6n3#Q!|lH z7yYANf^*psCUF@BQ?GXiyq{o9|8Foph3w=`u0xXqxBt=pdG|`py>%x(8M*&Z@)?rg zF*qEWpau?JmS*Qa+r*%(UNll?W`afaMfp&^Is-1|4^Kade5oAtw_8Av6ojlM|I*wZ z3e%m=&5(|h_>cA#t?S1ZrTiD<7;s8*aih*H#UQH$K7pnGKfp5Jlw~)93H}37&Pr2b zu5%k%E&mIFiw!s_*Tf)qOqw9OSw3O^bpC&{^e?yh344(-n<-rL>mf z$y)5e>XW+$=$3yon7y)uN3bLjn;-}1G0y!<|Ec89xZw9nV{JtF(VhRr$()s{ ztv5)rl-aD_{exzI=a+0YREW*_zh3B8JGiFIxW+&{F40HhP*n&J z@3Vj9^Gxrn+jV>8qmo|i-JVn0?B`XWd+*kzb(jJ}r}~jJK=k&j2XG4YhRO4Y5UG@H zk#umDI*;U2k^i~k)=ou0KdzG*>x}Z%@PrTbUQLXEvD8T_Iqn+`E*1f^$|-rDD0K5z zgITZ9i`p1L8-*jrIYFBO=te}WBVr2z*3uSUiQ4#pvchChZe~F%MhbvNM0CTF83F5e zFA)m1?IT2o{C;EIq3HMk!=NpUqb&>qju~@iK|4lsC^iMVz8FC}g(E8r0`~9RC4zPh z4a}GX?4@q+g0YEOtr`CdSP!Xcv`aPt~f%9V_S% zV+&}<3Em|?;xIkn52Aj=n63%3&Nnsf+;@_hx9jnkH>Mqdd0a3B+vR!E11FZ0 z7p7--zvkxr+3MowjxmP>$k*B+To+ukg{R}uoR8DUHgxrO#ObjeKVna$m(VPcY&u=1 zwzRIF48z&AB+`#R98(5}5AbF)Z2q72&cm&#W$VKckN^UL6d`~}@6v)&qDT=ziuBNt zUZe#=2}O!Dr70Z*k&c8e9YT>NU7B=|u1N0?$`{V@9F=>&|KRRC&q^{o@7nWZuh}z` zJ--!&{_!ElUW?7h`5ErekH@Js(?7z*2%>JM79B!%zH@9t`4t_lrWLK4UvRfm&IoW> zxhh(^audaJY+J={Dz&LJhRDU|@t-gNT2fO=Lc6yuY6Wv2Tx;n@-#vuV+5(tppU?wZ zpHY3KGHLndC?6K3LTj#WToM#N)2oqs`Vv*xx_V$m&XMvI2;vJG{-iNBTWYfIO zSGjmjxQB1k2T6>4f0=Afe;7wE3m+Ms=B-Eyma(x7k#$tFOK+d5c|R53)YH~7)&8{D zsbht!j>CQ>uzypqJyS*9`;~C_vH*9R)j_S$z~Lq`jc9 zDvkB>Y@}H^;_jUIv91e%Y|6d8SQj#GAK1if)B~el6Z*4XF_=QbIhxz+6@xe0pBj<8 zFf9Do-IIA}FRx{YNb7he@#2%R!5P2gZTf(b>y!y!#;q5ZRi+mTmBm1iq42=RW$Art ztFi<$94=r)E*%}FjCrwbLM0w&r;dbig6Q4aEY)D}B2{zXB2}sXB2|XpB2~1{A{7>0 zH-9sKq6wZF4x2?C2SM2rdMZpx;2MwcqPexV*H$WPEC6C_YyS3algZPol{EuZbgr&@ z<#TIFU)=192e)ojc16~fbu5N1;CH@{8$j=YBOPM7$0s(LGajn3CBuC<1l}YD>kfD_ zim!*0aHygWA=d*i8SADXwc44rWA@_?iJtFB3v2FP!%12qiSPG}0m(G8W~qs0b0~T) z3lvRCJYf08f^=KFc{^^tl{$pgcW#F3g;L~4(RYZGS`tQlIvi((cg%s6tW?)Izry-eTc(n3P!EH9&Xhh0M?9Es_#RlyIjvn<0~^MfBl z=gwa!_R)sDNh_nT_`w%p`f?abce2>Fro_lfTv}n*2CkLEGX#{T*bVZlt-s8eXJzRO zU?Wz5n(W>)*>~#l1Fny?B$cyP=?r(0h|HjfqcqT$Cex~}4JR(i8a#c=?>m0Lm3LLjGAH2CYVu?W}1cgAg7 zozXfY8ch%FyFHJT-ekWb)}iJ<`=SWC=dINr9cNaNFK5C1a)gd(f;1b^@ltDmrJh&6 zUv`UkZo$tqH7}-|q&xd)iyY-D7n?5zr+Cc=o2!WP;Kyg`og|n&KH7?L?T$_BBFCP? zb?e$nYUznzmi@{*H89FM3El|4-q`*;ed>mYD1_OFE%muv*3IGu(igmfP0VnCphr`M z-`C3+x|p&d;mCk4~{6q8es+)&ySIBLB| zv^$<%J>2EwX!@<2Gp>z(K^3Y~(^O{2YBMv&OPX=#aOdXiu!Kd0!>U+KfYZ=uRIsVG zB_zPQ+i7Sra;dt0HAK9{gj9YB`Dqdmd*6ad3oDt3Aw&}vS+!C;FS1fJU$s`)^y)PP z7&Onk4z;2Zb_(>b+Vc0Wa(s??_VpKWzK`aDgSF6|=jN$1L3}!k53Uo1g;KWnLkk2r z9*Mb|28FR270fDp)N2|2I+(sKVu(}o#u%J|j30Ql#+t~Sy&0Lw?B(F^N!>>?`xRg% zQG;2JKXI!ua+c8!C<_Y}b*vn@x zp4kbtQR&WP1&p%;mqV};K}V+L3%gsTl{|B>Z8Jd--JU1K6t|;&wHE#AF#p_?QfJAN zX@PN6Q!YP!-2Mmk1pWS-dM##BGu`BK5>6)6eY&kpldW%JnqwDoQduUJ+$t8#V`|Mr ztSs^O5uZP+F2g%Zl&)qoqw)#;<@As9oak2KudIjX)r7SCXg9px(Fvr0!Nrr z6m_4lTmtDgo68nBdgXq5l{S}GZA&OJMof{ENPuA4rej0s{VNoVpCxUJRr#2dB`+^( zN(PXZDl=g5s0U;A+-h);4A>J+mGq!Vm3$ed%y9YdatslG_xHy-%TRq2k8)o5QF2PZ z3m_o1Ozqe;zJei=lv7a{qDAKSeUdmjIV8U4AN42b%J(PWuuT0~WDP^6qLfqbD&>5h z!XU;>>ar4lRqdYxo!5u)KdPwlmfMCw-7wSgCcap=aI3Y+H}6iO#7Av% z0YvbagO2`EhdiS)+r8W`NSI@=Ow zK9RK_7VqZF2!{<1$6-n83tRiYNKn2W`x$B`8u-z287!Fke!t5<%MMJYd@B$~zpxB`(Btys85Q*86 zwK7Y(J`uhaR0`|M(5oj4);`6qLeknbptNN@o`^J?D$s&aH*E#p03nR5#5`EOCo%Ow zS%$W*raY*zM8~g=(<>Yq3(ro#S43H`f}PV7e73SlpS$K!2kaG5W8CYNsV`W2q$XmH zFqg}cj)V=V=Ko_NM~5n{-*^0N_S#1kiX4RsbaI{lF#2pzs4MM)J)Dl%!Nwyv)sX_gJ4;MqQLtTcX`*6Ohb}Ny@h9L zm@}zE?tN~MaxL?y*zMsgzIqrba*9rJRfm-8)wHp*-x$yJ*$TRzBt8E$TiOJ&i^aQJ z&M|84?5=T|Y+j42S^s?(w`oQWwp@y|bT~WpyVC%DoGP$d4+K4NYsj-{W_9Q=MD|S* zYH!x$UqafN-NGs>2=Hnmp4&`Gs z8R$V=#(|J-qBp1yVcBzIjfmhI|d8*rM3lchQ9(X!ePlE^1 z6jD5eVpd`ui!Qb=Oa~$*G~_!xl7C3`aVNGrKtz@0Ms_sCPLf@kc7d3*fDR~-p8-YO z3vzym11%J3mE5y*Mh4OdvdJlCfp6|n)p_rX!RilHnu;OB^JhN}qQxm5H)viBMZ1k~ zyp3;c3)@#KAob#J*{JU&K5EMr&}<3Ybex?biXKo(c>m}g)n4P5P8>yS-o2RMeeOKj z3_l5{ws5FWq`kGl5PKcCE*IA6xScCgeCT$PDs5YVkK!39MGnFM6Pt(AXU981_TpaqcSSvNM2m`{ zUAGR-h~F|eraVtoT?ak|mC3x1o%Hk~qLrhW!n32}$@M-J?eKiqprTYL@hfV}68CN0 z0l=m=!K=kfv(U?*yuJ4=;67brK-oj+-ohDXp7x(JIY7_nyi$zlO%ezIkpDB2b2T$o z`)vW{N=&!X+_{QL7L8Fcf#rOorAuWgBz3GFdqRBX6m+hPn~d5?A&!zgqbaL_jylA8 zvzwu3^9EF%|6PcILk%uWM*zGrlLr5A&cI}`%A;zTfT2za)J3Q#5Pu3Hh-*S zae&zA8E{0uGo?`(TJl@`Ah98BGsu&05|_9V=qDuFjcq&0`DFrSvr={67V#=mU0`L_ zD$>-Zp|Vi9s36lvjGTsu6@E10%g6|-kNvW4)eW^Is_qaa|9W>QU88qEFVR)O9f8%a zD!ii=gij%8I+!Z^mNhwZ=#qmFG2h)wrjnX-RHF^Sa){m!_ zR$V&nF`0_93eYZPwUZLe5HoRP6qcCQeZtsXxNUV$zQ*mv&{{!=ZB^QL6WEW;!vk#R z5sxU>_2+u|XEVv!bhv22fs2WKt@UL~I!%t3p7SU(gfUIytdK6V ze}HvtNy*HWu2pXF_a7+3?Vs5^OzbLw-|qgtTkxlz{&B6D!v*m~NF8h>Y zH_JSqd%)#`!hpl_;isM<_5bxOlUYeVvBl_uPOs_v`*_sgGUfo{!rA$<-QbX3x!77O_r3+q&QviW?`AI zu)5|4X4Kg$s5Gud)9;Ju#D%Xp8QNPPOYMeO>|*-2CAm66eFZ~m_sIM^lNCwmsPUD` z1UR`o9OBI%_7G$NM|P#_?oh!6@gfL~JC-IPv#m`*3BY@S&L5~tZ<}+C;3E9O#kn*3 zO=F*vz1#c>e=Asi=29#dMPncoD}8^E?0T2m)x52HoDvyV*n`yrFOz&=Mff@3@w9qD z8c2^NzdiU=;R}~5HTsfA++3DK+PH0tv|jpwOJLA%hAe!s=#strYUT=+Rsyxs=ew=K zwU5=*xg`9u-sxQhx`tgFE1M9sjy_dt)J*MZL*bTPb-q_ar8Q6}M@yOznbZpwmtu6r zu?g{!8hPRWzLI}Zt`?mvO{IT!{hD~a*Wu;~5?f+x>r$ypTZA5@U@XGDncc^x@jjd7 zxSUMW0Xb6%rv{sJx5$x)^o&D%d7HR2d9$|!`RKcXcE+2~PYI^Q3#xHpJSleVTO}op zn?@zlsfw}5#&Z5>r!x_48U0S&TW&FAPPi>}H>prXcK(TiUN0ZC-m!UxkH?iUV0eEp z0zFYkWSl87fJt=KGz-ET}Yhv&CS8U!)!}*^y7t^jiBPAYx!Sn`lLZkPO#SF1bl3R9Qf5!+&c=@=c^j zJy>3k|Fk96$3)T&h98cu%*`)94pHW?Kn)R}!o zADu4Q2A!U?d^`UI^FMn=3bm7=O-xwsVuF_B_pmf_a5%qW{x2#qUmIpiQd6`a=OaX2 z9r5Oa+pl9oyt4b2s*Bxh+ncB$_R&=C)!@z1LVB}`f|AuzOfKTx9ck5_#X;l> zUXOe_mp}>yGd7O`lQZ;n+tH69p?1%&)iWKIIiIK@RYvsUpOXbC^H?CzLkoc5ebk-#$w+tA?C zV>PexoHk1$lm-NVzVSF$+eGs5_KVCie7&I(V7V6MW%I1~H8e)PE;OdyHc zT~5lKSIAxK)@yo(Bd1!Yi5n1I-t=~k439<%n_|+ug%0fQX?%Aegc#9gR_aFhhAH@o z-r@o;?Y5t(cxBK?-Amf4C_SJ+Y*?dD%x+_`4sO7h8l<6=yT!3(QRkynYErrIwbuc-442W={I&Ek{}YPX{+%gDTcBkP@Z?xbg@50n_&W&e!l)j)se1NlsM! zp*8@3SjYKG?)-}#z|`e0IsWf?9xmd4rib_i0|4kJKk@%3S;R$87c&9;@}*<)-|_-n zKW#i~PkKO22sZm;W68-`h(U;fr&aU+|6ipYVkl%|#Cv$H%`s;3WR^V2%mne@Dv~ y`9Fs+zi0p;H3> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for host name register. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + + /* Test default timer parameters. */ + t = 100; + p = 1; + k = 1; + retrans_interval = 0; + period_interval = 0xFFFFFFFF; + max_time = 3; + retransmit_count = p; + cycle_count = max_time; + first_packet = NX_TRUE; + nx_mdns_service_announcement_timing_set(&mdns_0, t, p, k, retrans_interval, period_interval, max_time); + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Add a service. */ + nx_mdns_service_add(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Sleep 5 seconds for service announcement. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check whether all packets are transmitted. */ + if(retransmit_count || cycle_count) + error_counter++; + + advanced_packet_process_callback = NX_NULL; + nx_mdns_service_delete(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL); + + /* Sleep 1 seconds for goodbye. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + + /* Change time parameter t from 100 to 200. */ + /* Test default timer parameters. */ + t = 200; + p = 1; + k = 1; + retrans_interval = 0; + period_interval = 0xFFFFFFFF; + max_time = 3; + retransmit_count = p; + cycle_count = max_time; + first_packet = NX_TRUE; + nx_mdns_service_announcement_timing_set(&mdns_0, t, p, k, retrans_interval, period_interval, max_time); + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Add a service. */ + nx_mdns_service_add(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Sleep 10 seconds for service announcement. */ + tx_thread_sleep(10 * NX_IP_PERIODIC_RATE); + + /* Check whether all packets are transmitted. */ + if(retransmit_count || cycle_count) + error_counter++; + + advanced_packet_process_callback = NX_NULL; + nx_mdns_service_delete(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL); + + /* Sleep 1 seconds for goodbye. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + + /* Change time parameter p from 1 to 2. */ + /* Test default timer parameters. */ + t = 100; + p = 2; + k = 1; + retrans_interval = 0; + period_interval = 0xFFFFFFFF; + max_time = 3; + retransmit_count = p; + cycle_count = max_time; + first_packet = NX_TRUE; + nx_mdns_service_announcement_timing_set(&mdns_0, t, p, k, retrans_interval, period_interval, max_time); + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Add a service. */ + nx_mdns_service_add(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Sleep 5 seconds for service announcement. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check whether all packets are transmitted. */ + if(retransmit_count || cycle_count) + error_counter++; + + advanced_packet_process_callback = NX_NULL; + nx_mdns_service_delete(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL); + + /* Sleep 1 seconds for goodbye. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + + /* Change time parameter k from 1 to 2. */ + /* Test default timer parameters. */ + t = 100; + p = 1; + k = 2; + retrans_interval = 0; + period_interval = 0xFFFFFFFF; + max_time = 3; + retransmit_count = p; + cycle_count = max_time; + first_packet = NX_TRUE; + nx_mdns_service_announcement_timing_set(&mdns_0, t, p, k, retrans_interval, period_interval, max_time); + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Add a service. */ + nx_mdns_service_add(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Sleep 10 seconds for service announcement. */ + tx_thread_sleep(10 * NX_IP_PERIODIC_RATE); + + /* Check whether all packets are transmitted. */ + if(retransmit_count || cycle_count) + error_counter++; + + advanced_packet_process_callback = NX_NULL; + nx_mdns_service_delete(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL); + + /* Sleep 1 seconds for goodbye. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + + /* Change time parameter p from 1 to 2, retrans_interval from 0 to 100. */ + /* Test default timer parameters. */ + t = 100; + p = 2; + k = 1; + retrans_interval = 100; + period_interval = 0xFFFFFFFF; + max_time = 3; + retransmit_count = p; + cycle_count = max_time; + first_packet = NX_TRUE; + nx_mdns_service_announcement_timing_set(&mdns_0, t, p, k, retrans_interval, period_interval, max_time); + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Add a service. */ + nx_mdns_service_add(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Sleep 10 seconds for service announcement. */ + tx_thread_sleep(10 * NX_IP_PERIODIC_RATE); + + /* Check whether all packets are transmitted. */ + if(retransmit_count || cycle_count) + error_counter++; + + advanced_packet_process_callback = NX_NULL; + nx_mdns_service_delete(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL); + + /* Sleep 1 seconds for goodbye. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + + /* Change time parameter max time from 3 to 5. */ + /* Test default timer parameters. */ + t = 100; + p = 1; + k = 1; + retrans_interval = 0; + period_interval = 0xFFFFFFFF; + max_time = 5; + retransmit_count = p; + cycle_count = max_time; + first_packet = NX_TRUE; + nx_mdns_service_announcement_timing_set(&mdns_0, t, p, k, retrans_interval, period_interval, max_time); + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Add a service. */ + nx_mdns_service_add(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Sleep 20 seconds for service announcement. */ + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + + /* Check whether all packets are transmitted. */ + if(retransmit_count || cycle_count) + error_counter++; + + advanced_packet_process_callback = NX_NULL; + nx_mdns_service_delete(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL); + + /* Sleep 1 seconds for goodbye. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + + /* Change time parameter period_interval from forever to 100, max_time from 3 to forever. */ + /* Test default timer parameters. */ + t = 100; + p = 1; + k = 1; + retrans_interval = 0; + period_interval = 100; + max_time = 0xFF; + retransmit_count = p; + cycle_count = 300; + first_packet = NX_TRUE; + nx_mdns_service_announcement_timing_set(&mdns_0, t, p, k, retrans_interval, period_interval, max_time); + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Add a service. */ + nx_mdns_service_add(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Sleep 310 seconds for service announcement. */ + tx_thread_sleep(310 * NX_IP_PERIODIC_RATE); + + /* Check whether all packets are transmitted. */ + if(retransmit_count || cycle_count) + error_counter++; + + advanced_packet_process_callback = NX_NULL; + nx_mdns_service_delete(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL); + + /* Sleep 1 seconds for goodbye. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +UCHAR *pointer; +UINT current_tick; +UINT expected_tick_diff; +UINT i; +UINT base; + + /* Get protocol. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 9; + + /* Check UDP packets only. */ + if(*pointer != NX_PROTOCOL_UDP) + return NX_TRUE; + + /* Get port. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check UDP port 5353 only. */ + if((((*pointer << 8) + *(pointer + 1)) != 5353) || + (((*(pointer + 2) << 8) + *(pointer + 3)) != 5353)) + return NX_TRUE; + + /* Get flag. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 30; + + /* Check whether this packet is the announcement. */ + if(((*pointer << 8) + *(pointer + 1)) == (NX_MDNS_RESPONSE_FLAG | NX_MDNS_AA_FLAG)) + { + + /* It is an announcement packet. */ + current_tick = tx_time_get(); + + if(first_packet == NX_FALSE) + { + + /* Check the timer interval. */ + if((p - retransmit_count > 0) && retransmit_count) + { + + /* The packet is retransmitted in one cycle. */ + expected_tick_diff = retrans_interval; + } + else + { + + /* The packet is retransmitted in a new cycle. */ + expected_tick_diff = t; + base = 1 << k; + for(i = (max_time - cycle_count); i > 1; i--) + { + expected_tick_diff *= base; + + /* Whether the max interval reaches. */ + if(expected_tick_diff >= period_interval) + { + expected_tick_diff = period_interval; + break; + } + } + } + + /* Check time interval. */ + if(((int)((current_tick - last_tick) - expected_tick_diff) > TOLERANCE) || + ((int)(expected_tick_diff - (current_tick - last_tick)) > TOLERANCE)) + error_counter++; + } + else + first_packet = NX_FALSE; + + /* Store the current tick. */ + last_tick = current_tick; + + /* Update the count. */ + if(retransmit_count) + retransmit_count--; + if(retransmit_count == 0) + { + if(cycle_count) + cycle_count--; + if(cycle_count) + retransmit_count = p; + } + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_announcement_repeat_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Announcement Repeat Test.............................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_SERVER */ diff --git a/test/regression/mdns_test/netx_mdns_bad_packet_test.c b/test/regression/mdns_test/netx_mdns_bad_packet_test.c new file mode 100644 index 00000000..f199ca7b --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_bad_packet_test.c @@ -0,0 +1,623 @@ +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_IPV4 && !defined NX_MDNS_DISABLE_CLIENT && !defined NX_MDNS_DISABLE_SERVER +#include "nxd_mdns.h" +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_stack[DEMO_STACK_SIZE]; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); + +static VOID cache_full_notify(NX_MDNS *mdns_ptr, UINT state, UINT cache_tye); + +/* Bad packet 1: pointer pass the end of the packet. */ +static unsigned char bad_packet1[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x7f, /* ........ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Bad packet 2: pointer points to itself. */ +static unsigned char bad_packet2[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x0c, /* ........ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Bad packet 3: pointer points to another pointer that + points back to the first pointer. */ +static unsigned char bad_packet3[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x0e, /* ........ */ +0xc0, 0x0c, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* ..tp._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Bad packet 4 */ +static unsigned char bad_packet4[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, /* ........ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Bad packet 5, for _nx_mdns_txt_string_decode. */ +static unsigned char bad_packet5[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x05, 0x8a, 0x00, 0x1f, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8b, 0x06, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x05, 0x76, /* .......x */ +0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x74, /* .......t */ +0x65, 0x73, 0x74, 0x31, 0x34, 0x04, 0x5f, 0x69, /* est14._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, /* local... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x08, /* .....d.. */ +0x09, 0x06, 0x74, 0x65, 0x73, 0x74, 0x31, 0x34, /* ..test14 */ +0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x3f, 0x3f, 0x3f, /* ........ */ +}; + +static UCHAR packet_pool[1048576]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_bad_packet_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + memset(packet_pool, 0x3b, sizeof(packet_pool)); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, packet_pool, sizeof(packet_pool)); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet1; +UCHAR loop; + + printf("NetX Test: MDNS Bad Packet Test......................................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set link local address. */ + status = nx_ip_interface_physical_address_set(&ip_0, 0, 0x00000011, 0x22334456, NX_TRUE); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a MDNS instance. */ + current_buffer_size = 2048; + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, 88, buffer + current_buffer_size, 8, NX_NULL); + pointer += DEMO_STACK_SIZE; + + /* Cache notify test. */ + status = _nx_mdns_cache_notify_set(&mdns_0, cache_full_notify); + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for probing and announcing. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + + for (loop = 112; loop < 254; loop++) + { + bad_packet1[55] = loop; + + /* Inject bad packets. */ + status = nx_packet_allocate(&pool_0, &my_packet1, 16, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the data. */ + status = nx_packet_data_append(my_packet1, bad_packet1 + 14, sizeof(bad_packet1) - 14, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface and receive the packet. */ + my_packet1 -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_receive(&ip_0, my_packet1); + } + + /* Inject bad packet 2. */ + status = nx_packet_allocate(&pool_0, &my_packet1, 16, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the data. */ + status = nx_packet_data_append(my_packet1, bad_packet2 + 14, sizeof(bad_packet2) - 14, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface and receive the packet. */ + my_packet1 -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_receive(&ip_0, my_packet1); + + + /* Inject bad packet 3. */ + status = nx_packet_allocate(&pool_0, &my_packet1, 16, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the data. */ + status = nx_packet_data_append(my_packet1, bad_packet3 + 14, sizeof(bad_packet3) - 14, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface and receive the packet. */ + my_packet1 -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_receive(&ip_0, my_packet1); + + + /* Inject bad packet 4. */ + status = nx_packet_allocate(&pool_0, &my_packet1, 16, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the data. */ + status = nx_packet_data_append(my_packet1, bad_packet4 + 14, sizeof(bad_packet4) - 14, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface and receive the packet. */ + my_packet1 -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_receive(&ip_0, my_packet1); + + + nx_mdns_disable(&mdns_0, 0); + nx_mdns_delete(&mdns_0); + + current_buffer_size = 2048; + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer += DEMO_STACK_SIZE; + + /* Cache notify test. */ + status = _nx_mdns_cache_notify_set(&mdns_0, cache_full_notify); + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Inject bad packet 5. */ + status = nx_packet_allocate(&pool_0, &my_packet1, 16, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the data. */ + status = nx_packet_data_append(my_packet1, bad_packet5 + 14, sizeof(bad_packet5) - 14, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface and receive the packet. */ + my_packet1 -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_receive(&ip_0, my_packet1); + + + /* Determine if the test was successful. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static VOID cache_full_notify(NX_MDNS *mdns_ptr, UINT state, UINT cache_type) +{ + + /* The response packet is malformed and should not be added to the cache. */ + printf("ERROR!\n"); + test_control_return(1); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_bad_packet_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Bad Packet Test......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_buffer_size_test.c b/test/regression/mdns_test/netx_mdns_buffer_size_test.c new file mode 100644 index 00000000..cab2a7f1 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_buffer_size_test.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_buffer_size_test(void *first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, (ULONG)(pointer + DEMO_STACK_SIZE), + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +CHAR *pointer = (CHAR*)thread_input; +NX_MDNS_RR *rr; + + printf("NetX Test: MDNS Buffer Size Test....................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + for(current_buffer_size = 8; current_buffer_size < 1000; current_buffer_size += 60) + { + + /* Create */ + nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + +#ifndef NX_MDNS_DISABLE_SERVER + /* Use local buffer. */ + nx_mdns_service_add(&mdns_0, (CHAR *)"ARMMDNSTest", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); +#endif /* NX_MDNS_DISABLE_SERVER */ + +#ifndef NX_MDNS_DISABLE_CLIENT + /* Use remote buffer. */ + nx_mdns_service_continuous_query(&mdns_0, "_printer", "_tcp.local", NX_NULL); + + /* Wait two seconds for probing and announcement. */ + tx_thread_sleep(200); + + /* Delete the query. */ + nx_mdns_service_query_stop(&mdns_0, "_printer", "_tcp.local", NX_NULL); +#endif /* NX_MDNS_DISABLE_CLIENT */ + +#ifndef NX_MDNS_DISABLE_SERVER + nx_mdns_service_delete(&mdns_0, (CHAR *)"ARMMDNSTest", (CHAR *)"_ipp._tcp", NX_NULL); +#endif /* NX_MDNS_DISABLE_SERVER */ + + /* Delete the mDNS. */ + nx_mdns_delete(&mdns_0); + + /* Wait one second for goodbye packets sent. */ + tx_thread_sleep(100); + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_buffer_size_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Buffer Size Test.....................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_create_delete_test.c b/test/regression/mdns_test/netx_mdns_create_delete_test.c new file mode 100644 index 00000000..a9f6fd82 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_create_delete_test.c @@ -0,0 +1,212 @@ +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_create_delete_test(void *first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, (ULONG)(pointer + DEMO_STACK_SIZE), + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +CHAR *pointer = (CHAR*)thread_input; +UINT i; + + printf("NetX Test: MDNS Create Delete Test..................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set pointer. */ + pointer = (CHAR*)thread_input; + + /* Create */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + +#ifndef NX_DISABLE_ERROR_CHECKING + + /* Create 5 times to check whether system crashes. */ + for(i = 0; i < 5; i++) + { + + /* Since it has been created, it should not been created again. */ + if(nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL) == NX_SUCCESS) + error_counter++; + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + status = nx_mdns_delete(&mdns_0); + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + +#ifndef NX_DISABLE_ERROR_CHECKING + + /* Delete 5 times to check whether system crashes. */ + for(i = 0; i < 5; i++) + { + + /* Since it has been deleted, it should not been deleted again. */ + if(nx_mdns_delete(&mdns_0) == NX_SUCCESS) + error_counter++; + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + + /* Sleep 5 seconds then delete. */ + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + tx_thread_sleep(500); + status += nx_mdns_delete(&mdns_0); + + /* Loop 5 times to create and delete. */ + for(i = 0; i < 5; i++) + { + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + status += nx_mdns_delete(&mdns_0); + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_create_delete_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Create Delete Test...................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_domain_name_test.c b/test/regression/mdns_test/netx_mdns_domain_name_test.c new file mode 100644 index 00000000..017d7e5a --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_domain_name_test.c @@ -0,0 +1,284 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR *current_domain; +static USHORT current_flag; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_domain_name_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + printf("NetX Test: MDNS Domain Name Test....................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + +#ifndef NX_MDNS_DISABLE_SERVER + /* Add services with default domain 'local'. */ + current_flag = (NX_MDNS_RESPONSE_FLAG | NX_MDNS_AA_FLAG); + NX_CHANGE_USHORT_ENDIAN(current_flag); + current_domain = "local"; + nx_mdns_service_add(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Sleep 2 seconds. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Add services with specified domain 'home'. */ + current_domain = "home.local"; + + /* Set the domain. */ + status = nx_mdns_domain_name_set(&mdns_0, current_domain); + + nx_mdns_service_add(&mdns_0, "test", (CHAR *)"_printer._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); +#endif /* NX_MDNS_DISABLE_SERVER */ + + /* Sleep 5 seconds. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + +#ifndef NX_MDNS_DISABLE_CLIENT + /* Query on 'local' domain. */ + current_flag = NX_MDNS_QUERY_FLAG; + NX_CHANGE_USHORT_ENDIAN(current_flag); + current_domain = "local"; + + /* Set the domain. */ + status = nx_mdns_domain_name_set(&mdns_0, current_domain); + + /* Start to query. */ + nx_mdns_service_continuous_query(&mdns_0, NX_NULL, "_workstation._tcp", NX_NULL); + + /* Sleep 5 seconds. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Stop querying. */ + nx_mdns_service_query_stop(&mdns_0, NX_NULL, "_workstation._tcp", NX_NULL); + + /* Query on 'home' domain. */ + current_domain = "home.local"; + + /* Set the domain. */ + status = nx_mdns_domain_name_set(&mdns_0, current_domain); + + /* Start to query. */ + nx_mdns_service_continuous_query(&mdns_0, NX_NULL, "_workstation._tcp", NX_NULL); + + /* Sleep 5 seconds. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Stop querying. */ + nx_mdns_service_query_stop(&mdns_0, NX_NULL, "_workstation._tcp", NX_NULL); + + current_domain = "local"; + + /* Set the domain. */ + status = nx_mdns_domain_name_set(&mdns_0, current_domain); +#endif /* NX_MDNS_DISABLE_CLIENT */ + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +UCHAR *string, *domain; +USHORT flag; +UCHAR *pointer; +UINT domain_length = strlen(current_domain); + + /* Get protocol. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 9; + + /* Check UDP packets only. */ + if(*pointer != NX_PROTOCOL_UDP) + return NX_TRUE; + + /* Get port. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check UDP port 5353 only. */ + if((((*pointer << 8) + *(pointer + 1)) != 5353) || + (((*(pointer + 2) << 8) + *(pointer + 3)) != 5353)) + return NX_TRUE; + + /* Get flag. */ + flag = *((USHORT*)(packet_ptr -> nx_packet_prepend_ptr + 30)); + + /* Check whether this packet is the one need to verify. */ + if(flag != current_flag) + return NX_TRUE; + + string = packet_ptr -> nx_packet_prepend_ptr + 40; + + /* Find start position of domain. */ + for(domain = string + strlen(string) - 1; domain >= string; domain--) + { + domain_length--; + if(domain_length == 0) + break; + + /* Convert to dot. */ + if(*domain < 64) + *domain = '.'; + } + + if(*domain < 64) + domain++; + + if(strcmp(domain, current_domain)) + error_counter++; + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_domain_name_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Domain Name Test.....................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_interface_test.c b/test/regression/mdns_test/netx_mdns_interface_test.c new file mode 100644 index 00000000..684548c6 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_interface_test.c @@ -0,0 +1,253 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_data[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, /* )..y..E. */ +0x00, 0xd1, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0xd9, 0x0e, 0xc0, 0xa8, 0x00, 0x69, 0xe0, 0x00, /* .....i.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbd, /* ........ */ +0xc6, 0xe4, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x1e, 0x00, /* ........ */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x0f, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x06, 0x75, 0x62, /* ....P.ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x29, 0xc0, 0x5b, /* untu.).[ */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x01, /* ....)... */ +0xd4, 0x79, 0xc0, 0x5b, 0x00, 0x01, 0x80, 0x01, /* .y.[.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x69, 0x09, 0x5f, 0x73, 0x65, 0x72, 0x76, /* .i._serv */ +0x69, 0x63, 0x65, 0x73, 0x07, 0x5f, 0x64, 0x6e, /* ices._dn */ +0x73, 0x2d, 0x73, 0x64, 0x04, 0x5f, 0x75, 0x64, /* s-sd._ud */ +0x70, 0xc0, 0x29, 0x00, 0x0c, 0x00, 0x01, 0x00, /* p.)..... */ +0x00, 0x11, 0x94, 0x00, 0x02, 0xc0, 0x1e /* ....... */ +}; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +static void check_empty_buffer(UCHAR *buffer_ptr, ULONG buffer_size, UCHAR expect_empty); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_interface_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + printf("NetX Test: MDNS Interface Test......................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 1); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Inject mDNS response to primary interface of ip_0. */ + status = nx_packet_allocate(&pool_0, &my_packet, 16, 100); + status += nx_packet_data_append(my_packet, mdns_data + 14, sizeof(mdns_data) - 14, &pool_0, 100); + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Check status. */ + if(status) + error_counter++; + + /* Sleep one second to then check whether it is received. */ + tx_thread_sleep(100); + check_empty_buffer(buffer + current_buffer_size, current_buffer_size, NX_TRUE); + + /* Enable secondary interface for ip_0. */ + nx_mdns_disable(&mdns_0, 1); + nx_mdns_enable(&mdns_0, 0); + + /* Inject mDNS response to primary interface of ip_0. */ + status = nx_packet_allocate(&pool_0, &my_packet, 16, 100); + status += nx_packet_data_append(my_packet, mdns_data + 14, sizeof(mdns_data) - 14, &pool_0, 100); + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Check status. */ + if(status) + error_counter++; + + /* Sleep one second to then check whether it is received. */ + tx_thread_sleep(100); + check_empty_buffer(buffer + current_buffer_size, current_buffer_size, NX_FALSE); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void check_empty_buffer(UCHAR *buffer_ptr, ULONG buffer_size, UCHAR expect_empty) +{ + +ULONG *tail, *head; + + tx_mutex_get(&mdns_0.nx_mdns_mutex, TX_WAIT_FOREVER); + + /* Check head. */ + head = (ULONG*)buffer_ptr; + if((*head == (ULONG)(head + 1)) && (expect_empty == NX_FALSE)) + error_counter++; + else if((*head != (ULONG)(head + 1)) && (expect_empty == NX_TRUE)) + error_counter++; + + /* Check tail. */ + tail = (ULONG*)buffer_ptr + (buffer_size >> 2) - 1; + if((tail == (ULONG*)(*tail)) && (expect_empty == NX_FALSE)) + error_counter++; + else if((tail != (ULONG*)(*tail)) && (expect_empty == NX_TRUE)) + error_counter++; + + tx_mutex_put(&mdns_0.nx_mdns_mutex); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_interface_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Interface Test.......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_internal_function_test.c b/test/regression/mdns_test/netx_mdns_internal_function_test.c new file mode 100644 index 00000000..8e74982c --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_internal_function_test.c @@ -0,0 +1,1182 @@ +#include "tx_api.h" +#include "nx_api.h" +#include + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1[5]; +static TX_THREAD ntest_2[5]; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static TX_SEMAPHORE sema_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_stack[DEMO_STACK_SIZE]; +static ULONG buffer_org_head; +static ULONG buffer_org_tail; +static ULONG free_buffer_size; +static UINT cache_state; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_2_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); +static void check_empty_buffer(UCHAR *buffer_ptr, UINT buffer_size); +static void empty_buffer_init(UCHAR *buffer_ptr, UINT buffer_size); +static VOID cache_full_notify(NX_MDNS *mdns_ptr, UINT state, UINT cache_tye); + +extern UINT _nx_mdns_cache_add_resource_record(NX_MDNS *mdns_ptr, UINT cache_type, NX_MDNS_RR *record_ptr, NX_MDNS_RR **insert_ptr, UCHAR *is_present, UINT interface_index); +extern UINT _nx_mdns_cache_delete_resource_record(NX_MDNS *mdns_ptr, UINT cache_type, NX_MDNS_RR *record_ptr); +extern UINT _nx_mdns_cache_add_string(NX_MDNS *mdns_ptr, UINT cache_type, VOID *string_ptr, UINT string_len, VOID **insert_ptr, UCHAR find_string, UCHAR add_name); +extern UINT _nx_mdns_cache_delete_string(NX_MDNS *mdns_ptr, UINT cache_type, VOID *string_ptr, UINT string_len); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_internal_function_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create semaphore. */ + status = tx_semaphore_create(&sema_0, "SEMA 0", 0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, (ULONG)(pointer + DEMO_STACK_SIZE), + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +CHAR *pointer = (CHAR*)thread_input; +UINT i; +NX_MDNS_RR *last_inserted; +NX_MDNS_RR *inserted[3]; +ULONG head; +NX_MDNS_RR rr[3]; +UCHAR *last_inserted_string; +CHAR test_string[32]; +UCHAR *inserted_strings[4]; +CHAR *test_strings[] = {"First", "Second", "Third", "M"}; +ULONG tail; +NX_MDNS_RR peer_rr; +UINT rr_count; +UCHAR *insert_ptr[30]; +CHAR *cache_string[] = { + "Hello0", + "World0", + "Hello world0", + "Hello world00", + "Hello world000", + "Hello world0000", + "Hello world00000", + "Hello world000000", + "Hello world0000000", + "Hello world00000000", + "Hello world000000000", + "Hello world0000000000", + "Hello world00000000000", + "Hello world000000000000", + "Hello world0000000000000", + "Hello world00000000000000", + "Hello world000000000000000", + "Hello world0000000000000000", + "Hello world00000000000000000", + "Hello world00000000000000000000000000000000000000000000000000000000000000000111111111111111111111122222222222222"}; + + + printf("NetX Test: MDNS Internal Function Test..............................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set pointer. */ + pointer = (CHAR*)thread_input; + + + /**********************************************************/ + /* Test Local and Peer cache notify */ + /**********************************************************/ + + /* Create a MDNS instance. */ + memset(buffer, 0xFF, BUFFER_SIZE); + current_buffer_size = 512; + status = _nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + pointer += DEMO_STACK_SIZE; + + /* Cache notify test. */ + status = _nx_mdns_cache_notify_set(&mdns_0, cache_full_notify); + + /* Check status. */ + if(status) + error_counter++; + +#ifndef NX_MDNS_DISABLE_SERVER + /* Test the local buffer full notify. */ + /* Loop to add string to local buffer until full. */ + i = 0; + while(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE) == NX_SUCCESS) + { + i++; + } + + /* Check the cache state. */ + if (cache_state != 1) + error_counter++; + + /* Deleted the strings. */ + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, insert_ptr[0], 0); + + /* Add the string. */ + _nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE); + + /* Check the cache state. */ + if (cache_state != 1) + error_counter++; + + /* Delete the string. */ + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, insert_ptr[2], 0); + + /* Add the string. */ + _nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE); + + /* Check the cache state. */ + if (cache_state != 1) + error_counter++; + + /* Delete the string. */ + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, insert_ptr[4], 0); + + /* Add the string. */ + _nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE); + + /* Check the cache state. */ + if (cache_state != 1) + error_counter++; + + /* Delete the string. */ + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, insert_ptr[6], 0); + + /* Add the string. */ + _nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE); + + /* Check the cache state. */ + if (cache_state != 1) + error_counter++; + + /* Delete the string. */ + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, insert_ptr[8], 0); + + /* Add the string. */ + _nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE); + + /* Check the cache state. */ + if (cache_state != 2) + error_counter++; +#endif /* NX_MDNS_DISABLE_SERVER */ + +#ifndef NX_MDNS_DISABLE_CLIENT + /* Test the peer buffer full notify. */ + /* Loop to add string to local buffer until full. */ + i = 0; + while(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, + cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE) == NX_SUCCESS) + { + i++; + } + + /* Check the cache state. */ + if (cache_state != 1) + error_counter++; + + /* Deleted the strings. */ + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, insert_ptr[0], 0); + + /* Add the string. */ + _nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE); + + /* Check the cache state. */ + if (cache_state != 1) + error_counter++; + + /* Delete the string. */ + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, insert_ptr[2], 0); + + /* Add the string. */ + _nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE); + + /* Check the cache state. */ + if (cache_state != 1) + error_counter++; + + /* Delete the string. */ + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, insert_ptr[4], 0); + + /* Add the string. */ + _nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE); + + /* Check the cache state. */ + if (cache_state != 1) + error_counter++; + + /* Delete the string. */ + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, insert_ptr[6], 0); + + /* Add the string. */ + _nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE); + + /* Check the cache state. */ + if (cache_state != 1) + error_counter++; + + /* Delete the string. */ + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, insert_ptr[8], 0); + + /* Add the string. */ + _nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, cache_string[i], strlen(cache_string[i]), (VOID **)&insert_ptr[i], NX_FALSE, NX_TRUE); + + /* Check the cache state. */ + if (cache_state != 2) + error_counter++; +#endif /* NX_MDNS_DISABLE_CLIENT */ + + /* Delet the MDNS instance. */ + _nx_mdns_delete(&mdns_0); + +#ifndef NX_MDNS_DISABLE_SERVER + /**********************************************************/ + /* Cache String Test */ + /**********************************************************/ + + /* Basic string test. */ + /* Initialize the buffer. */ + current_buffer_size = 512; + memset(buffer, 0xFF, BUFFER_SIZE); + status = _nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + pointer += DEMO_STACK_SIZE; + + /* Check status. */ + if(status) + error_counter++; + + empty_buffer_init(buffer, current_buffer_size); + + /* Create 5 threads to test string functions. */ + for(i = 0; i < 5; i++) + { + tx_thread_create(&ntest_2[i], "thread 2", ntest_2_entry, i + 1, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + } + + /* Wait until all threads finish. */ + for(i = 0; i < 5; i++) + { + if(tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE)) + { + error_counter++; + break; + } + } + + check_empty_buffer(buffer, current_buffer_size); + _nx_mdns_delete(&mdns_0); +#endif /* NX_MDNS_DISABLE_SERVER */ + + +#ifndef NX_MDNS_DISABLE_CLIENT + /**********************************************************/ + /* Function Test */ + /**********************************************************/ + + /* Initialize random. */ + srand((UINT)time(0)); + + /* Basic RR test. */ + /* Create a MDNS instance. */ + current_buffer_size = 512; + memset(buffer, 0xFF, BUFFER_SIZE); + status = _nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + pointer += DEMO_STACK_SIZE; + + /* Check status. */ + if(status) + error_counter++; + + empty_buffer_init(buffer + current_buffer_size, current_buffer_size); + + /* Create 5 threads to test string functions. */ + for(i = 0; i < 5; i++) + { + tx_thread_create(&ntest_1[i], "thread 1", ntest_1_entry, i + 1, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + } + + /* Wait until all threads finish. */ + for(i = 0; i < 5; i++) + { + if(tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE)) + { + error_counter++; + break; + } + } + + check_empty_buffer(buffer + current_buffer_size, current_buffer_size); + _nx_mdns_delete(&mdns_0); +#endif /* NX_MDNS_DISABLE_CLIENT */ + + +#ifndef NX_MDNS_DISABLE_SERVER + /**********************************************************/ + /* Local Cache RR Test */ + /**********************************************************/ + + /* RR full test. */ + /* Initialize the buffer. */ + current_buffer_size = BUFFER_SIZE >> 1; + memset(buffer, 0xFF, BUFFER_SIZE); + status = _nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + pointer += DEMO_STACK_SIZE; + + /* Check status. */ + if(status) + error_counter++; + + empty_buffer_init(buffer, current_buffer_size); + + /* Loop to add resource record to local buffer until full. */ + i = 0; + memset(&rr[0], 0, sizeof(NX_MDNS_RR)); + do + { + rr[0].nx_mdns_rr_name = (UCHAR *)"test"; + rr[0].nx_mdns_rr_type = NX_MDNS_RR_TYPE_A; + rr[0].nx_mdns_rr_class = (USHORT)i; + rr[0].nx_mdns_rr_ttl = i; + rr[0].nx_mdns_rr_rdata_length = (USHORT)i; + rr[0].nx_mdns_rr_timer_count = 0; + rr[0].nx_mdns_rr_retransmit_count = (UCHAR)(i + 1); + rr[0].nx_mdns_rr_state = NX_MDNS_RR_STATE_VALID; + i++; + }while(_nx_mdns_cache_add_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + &rr[0], &last_inserted, NX_NULL, 0) == NX_SUCCESS); + + i--; + + /* HEAD and TAIL take 4 bytes each. */ + if(i != (free_buffer_size / sizeof(NX_MDNS_RR))) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != i) + error_counter++; + if(mdns_0.nx_mdns_local_string_count != 0) + error_counter++; + if(mdns_0.nx_mdns_local_string_bytes != 0) + error_counter++; + + /* Delete all inserted resource records. */ + while(i > 0) + { + + /* Add it again. */ + i--; + rr[0].nx_mdns_rr_name = (UCHAR *)"test"; + rr[0].nx_mdns_rr_type = NX_MDNS_RR_TYPE_A; + rr[0].nx_mdns_rr_class = (USHORT)i; + rr[0].nx_mdns_rr_ttl = i; + rr[0].nx_mdns_rr_rdata_length = (USHORT)i; + rr[0].nx_mdns_rr_timer_count = 0; + rr[0].nx_mdns_rr_retransmit_count = (UCHAR)(i + 1); + rr[0].nx_mdns_rr_state = NX_MDNS_RR_STATE_VALID; + + if(_nx_mdns_cache_add_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + &rr[0], &last_inserted, NX_NULL, 0)) + { + + /* No error is expected. */ + error_counter++; + break; + } + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != i + 1) + error_counter++; + + if(_nx_mdns_cache_delete_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, last_inserted)) + { + + /* No error is expected. */ + error_counter++; + break; + } + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != i) + error_counter++; + } + + check_empty_buffer(buffer, current_buffer_size); + _nx_mdns_delete(&mdns_0); + + + /* RR middle usage test. */ + /* Initialize the buffer. */ + current_buffer_size = BUFFER_SIZE >> 1; + memset(buffer, 0xFF, BUFFER_SIZE); + status = _nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + pointer += DEMO_STACK_SIZE; + + /* Check status. */ + if(status) + error_counter++; + + empty_buffer_init(buffer, current_buffer_size); + + /* Initialize RRs. */ + memset(&rr, 0, sizeof(rr)); + for(i = 0; i < 3; i++) + { + rr[i].nx_mdns_rr_name = (UCHAR *)"test"; + rr[i].nx_mdns_rr_type = NX_MDNS_RR_TYPE_A; + rr[i].nx_mdns_rr_class = (USHORT)i; + rr[i].nx_mdns_rr_ttl = i; + rr[i].nx_mdns_rr_rdata_length = (USHORT)i; + rr[i].nx_mdns_rr_timer_count = 0; + rr[i].nx_mdns_rr_retransmit_count = (UCHAR)(i + 1); + rr[i].nx_mdns_rr_state = NX_MDNS_RR_STATE_VALID; + } + + /* Add two RRs. */ + if(_nx_mdns_cache_add_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, &rr[0], &inserted[0], NX_NULL, 0)) + error_counter++; + + if(_nx_mdns_cache_add_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, &rr[1], &inserted[1], NX_NULL, 0)) + error_counter++; + + /* Store HEAD. */ + head = *((ULONG*)buffer); + + /* Delete the first resource record. */ + if(_nx_mdns_cache_delete_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, inserted[0])) + error_counter++; + + /* Add the third RR. */ + if(_nx_mdns_cache_add_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, &rr[2], &inserted[2], NX_NULL, 0)) + error_counter++; + + /* Check HEAD. */ + if(head != *((ULONG*)buffer)) + error_counter++; + + /* Delete all RRs. */ + if(_nx_mdns_cache_delete_resource_record(&mdns_0,NX_MDNS_CACHE_TYPE_LOCAL, inserted[1])) + error_counter++; + if(_nx_mdns_cache_delete_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, inserted[2])) + error_counter++; + + check_empty_buffer(buffer, current_buffer_size); + _nx_mdns_delete(&mdns_0); +#endif /* NX_MDNS_DISABLE_SERVER */ + + +#ifndef NX_MDNS_DISABLE_CLIENT + /**********************************************************/ + /* Peer Cache RR Test */ + /**********************************************************/ + + /* Create a MDNS instance. */ + memset(buffer, 0xFF, BUFFER_SIZE); + current_buffer_size = 512; + status = _nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + pointer += DEMO_STACK_SIZE; + + /* Enable the MDNS function. */ + _nx_mdns_enable(&mdns_0, 0); + + /* Loop to add resource record to peer buffer. */ + memset(&peer_rr, 0, sizeof(NX_MDNS_RR)); + for (i = 0; i < 100; i++) + { + if(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, "test", strlen("test"), (VOID **)&(peer_rr.nx_mdns_rr_name), NX_FALSE, NX_TRUE)) + error_counter++; + peer_rr.nx_mdns_rr_type = NX_MDNS_RR_TYPE_A; + peer_rr.nx_mdns_rr_class = (USHORT)i; + peer_rr.nx_mdns_rr_ttl = i; + peer_rr.nx_mdns_rr_rdata_length = (USHORT)i; + peer_rr.nx_mdns_rr_timer_count = 0; + peer_rr.nx_mdns_rr_retransmit_count = (UCHAR)(i + 1); + peer_rr.nx_mdns_rr_state = NX_MDNS_RR_STATE_VALID; + if (_nx_mdns_cache_add_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, + &peer_rr, &last_inserted, NX_NULL, 0)) + error_counter++; + + rr_count = (current_buffer_size - mdns_0.nx_mdns_peer_string_bytes - 2 * sizeof(ULONG)) / sizeof(NX_MDNS_RR); + if (i > (rr_count - 1)) + { + + /* Check mdns information. */ + if(mdns_0.nx_mdns_peer_rr_count != rr_count) + error_counter++; + } + else + { + + /* Check mdns information. */ + if(mdns_0.nx_mdns_peer_rr_count != i + 1) + error_counter++; + } + } + + if(_nx_mdns_cache_delete_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, last_inserted)) + { + + /* No error is expected. */ + error_counter++; + } + + /* Check mdns information. */ + if(mdns_0.nx_mdns_peer_rr_count != (rr_count - 1)) + error_counter++; + + /* Disable the MDNS function. */ + _nx_mdns_disable(&mdns_0, 0); + + /* Delet the MDNS instance. */ + _nx_mdns_delete(&mdns_0); +#endif /* NX_MDNS_DISABLE_CLIENT */ + + +#ifndef NX_MDNS_DISABLE_SERVER + /* String full test. */ + /* Initialize the buffer. */ + current_buffer_size = BUFFER_SIZE >> 1; + memset(buffer, 0xFF, BUFFER_SIZE); + status = _nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + pointer += DEMO_STACK_SIZE; + + /* Check status. */ + if(status) + error_counter++; + + empty_buffer_init(buffer, current_buffer_size); + /* Loop to add string to local buffer until full. */ + i = 0; + sprintf(test_string, "%.15d", i); + while(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + test_string, 15, (VOID **)&last_inserted_string, NX_FALSE, NX_TRUE) == NX_SUCCESS) + { + i++; + sprintf(test_string, "%.15d", i); + } + + /* HEAD and TAIL take 4 bytes each. Each string take 5 extra bytes. */ + if(i != (free_buffer_size / 20)) + error_counter++; + + /* HEAD and TAIL take 4 bytes each. Each string take 5 extra bytes. */ + if(i != (free_buffer_size / 20)) + error_counter++; + + if(mdns_0.nx_mdns_local_rr_count != 0) + error_counter++; + if(mdns_0.nx_mdns_local_string_count != i) + error_counter++; + if(mdns_0.nx_mdns_local_string_bytes != i * 20) + error_counter++; + /* Delete all inserted strings. */ + while(i > 0) + { + + /* Add it again. */ + sprintf(test_string, "%.15d", i - 1); + + if(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + test_string, 15, (VOID **)&last_inserted_string, NX_FALSE, NX_TRUE)) + { + + /* No error is expected. */ + error_counter++; + break; + } + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_string_count != i) + error_counter++; + if(mdns_0.nx_mdns_local_string_bytes != i * 20) + error_counter++; + + /* Delete the string twice. */ + if(_nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, last_inserted_string, 0)) + { + + /* No error is expected. */ + error_counter++; + break; + } + if(_nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, last_inserted_string, 0)) + { + + /* No error is expected. */ + error_counter++; + break; + } + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_string_count != (i - 1)) + error_counter++; + if(mdns_0.nx_mdns_local_string_bytes != (i - 1) * 20) + error_counter++; + + i--; + } + + check_empty_buffer(buffer, current_buffer_size); + + _nx_mdns_delete(&mdns_0); + +#endif /* NX_MDNS_DISABLE_SERVER */ + +#ifndef NX_MDNS_DISABLE_CLIENT + + /* String full test. */ + /* Initialize the buffer. */ + current_buffer_size = BUFFER_SIZE >> 1; + memset(buffer, 0xFF, BUFFER_SIZE); + status = _nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + pointer += DEMO_STACK_SIZE; + + /* Check status. */ + if(status) + error_counter++; + + empty_buffer_init(buffer + current_buffer_size, current_buffer_size); + + /* Loop to add string to peer buffer until full. */ + i = 0; + sprintf(test_string, "%.15d", i); + while(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, + test_string, 15, (VOID **)&last_inserted_string, NX_FALSE, NX_TRUE) == NX_SUCCESS) + { + i++; + sprintf(test_string, "%.15d", i); + } + + /* HEAD and TAIL take 4 bytes each. Each string take 5 extra bytes. */ + if(i != (free_buffer_size / 20)) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_peer_rr_count != 0) + error_counter++; + if(mdns_0.nx_mdns_peer_string_count != i) + error_counter++; + if(mdns_0.nx_mdns_peer_string_bytes != i * 20) + error_counter++; + + /* Delete all inserted strings. */ + while(i > 0) + { + + /* Add it again. */ + sprintf(test_string, "%.15d", i - 1); + + if(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, + test_string, 15, (VOID **)&last_inserted_string, NX_FALSE, NX_TRUE)) + { + + /* No error is expected. */ + error_counter++; + break; + } + + /* Check mdns information. */ + if(mdns_0.nx_mdns_peer_string_count != i) + error_counter++; + if(mdns_0.nx_mdns_peer_string_bytes != i * 20) + error_counter++; + + /* Delete the string twice. */ + if(_nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, last_inserted_string, 0)) + { + + /* No error is expected. */ + error_counter++; + break; + } + if(_nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, last_inserted_string, 0)) + { + + /* No error is expected. */ + error_counter++; + break; + } + /* Check mdns information. */ + if(mdns_0.nx_mdns_peer_string_count != (i - 1)) + error_counter++; + if(mdns_0.nx_mdns_peer_string_bytes != (i - 1) * 20) + error_counter++; + + i--; + } + + check_empty_buffer(buffer + current_buffer_size, current_buffer_size); + + _nx_mdns_delete(&mdns_0); +#endif /* NX_MDNS_DISABLE_CLIENT */ + + +#ifndef NX_MDNS_DISABLE_SERVER + /* String middle usage. */ + /* Initialize the buffer. */ + current_buffer_size = 512; + memset(buffer, 0xFF, BUFFER_SIZE); + status = _nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + pointer += DEMO_STACK_SIZE; + + /* Check status. */ + if(status) + error_counter++; + + empty_buffer_init(buffer, current_buffer_size); + + /* Insert 3 strings. */ + for(i = 0; i < 3; i++) + { + if(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + test_strings[i], strlen(test_strings[i]), (VOID **)&inserted_strings[i], NX_FALSE, NX_TRUE)) + { + + /* No error is expected. */ + error_counter++; + break; + } + } + + /* Store TAIL. */ + tail = *((ULONG*)buffer + (current_buffer_size >> 2) - 1); + + /* Delete the string in middle. */ + if(_nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, inserted_strings[1], 0)) + error_counter++; + + /* Insert a string that is less than deleted one. */ + if(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + test_strings[i], strlen(test_strings[i]), (VOID **)&inserted_strings[i], NX_FALSE, NX_TRUE)) + error_counter++; + + /* Check TAIL. */ + if(tail != *((ULONG*)buffer + (current_buffer_size >> 2) - 1)) + error_counter++; + + /* Deleted all strings. */ + for(i = 0; i < 4; i++) + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, inserted_strings[i], 0); + + check_empty_buffer(buffer, current_buffer_size); + _nx_mdns_delete(&mdns_0); +#endif /* NX_MDNS_DISABLE_SERVER */ + + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ +CHAR *test_strings[] = { + "1", + "a", + "b", + "c", + "MDNS", + "Hello world0", + "Hello world1", + "Hello world1 Hello", + "Hello hello Hello", + "Hello Hello Hello Hello", + "abcdefghijklmnopqrstuvwxyz", + "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", +}; +UINT string_count= sizeof(test_strings) / sizeof(CHAR*); +INT loop_count = 1000; +UINT add_count; +NX_MDNS_RR rr[5]; +NX_MDNS_RR *inserted_rr[5]; +UCHAR *inserted_strings[5]; +UINT index; + + + + /* Loop 1000 times to add and delete strings */ + while(loop_count > 0) + { + if ((loop_count == 0x00000232) && + (thread_input == 1)) + thread_input = thread_input; + + if ((loop_count == 0x00000235) && + (thread_input == 5)) + thread_input = thread_input; + + /* Initialize variables. */ + add_count = 0; + memset(rr, 0, sizeof(rr)); + memset(inserted_strings, 0, sizeof(inserted_strings)); + memset(inserted_rr, 0, sizeof(inserted_strings)); + + /* Insert records. */ + while(add_count < thread_input) + { + + tx_mutex_get(&mdns_0.nx_mdns_mutex, TX_WAIT_FOREVER); + if(add_count & 1) + { + + /* Insert same RR when add_count is odd. */ + memcpy(&rr[add_count], &rr[add_count - 1], sizeof(NX_MDNS_RR)); + if(rr[add_count].nx_mdns_rr_name) + { + if(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + test_strings[index], strlen(test_strings[index]), (VOID **)&rr[add_count].nx_mdns_rr_name, NX_FALSE, NX_TRUE) == NX_SUCCESS) + { + inserted_strings[add_count] = rr[add_count].nx_mdns_rr_name; + + /* Insert rr. */ + if(_nx_mdns_cache_add_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + &rr[add_count], &inserted_rr[add_count], NX_NULL, 0)) + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, inserted_strings[add_count], 0); + + } + } + } + else + { + index = rand() % string_count; + if(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + test_strings[index], strlen(test_strings[index]), (VOID **)&rr[add_count].nx_mdns_rr_name, NX_FALSE, NX_TRUE) == NX_SUCCESS) + { + + /* Set random values. */ + inserted_strings[add_count] = rr[add_count].nx_mdns_rr_name; + rr[add_count].nx_mdns_rr_type = NX_MDNS_RR_TYPE_A; + rr[add_count].nx_mdns_rr_class = (USHORT)thread_input; + rr[add_count].nx_mdns_rr_ttl = add_count + 100; + rr[add_count].nx_mdns_rr_rdata_length = rand() % 0xFFFF; + rr[add_count].nx_mdns_rr_timer_count = 0; + rr[add_count].nx_mdns_rr_retransmit_count = (UCHAR)(rand() % 0xFFFF); + rr[add_count].nx_mdns_rr_state = NX_MDNS_RR_STATE_VALID; + + /* Insert rr. */ + if(_nx_mdns_cache_add_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + &rr[add_count], &inserted_rr[add_count], NX_NULL, 0)) + _nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, inserted_strings[add_count], 0); + + } + } + + add_count++; + loop_count--; + tx_mutex_put(&mdns_0.nx_mdns_mutex); + tx_thread_relinquish(); + + } + + /* Delete all inserted strings and records. */ + while(add_count--) + { + + /* No error is expected. */ + tx_mutex_get(&mdns_0.nx_mdns_mutex, TX_WAIT_FOREVER); + if ((inserted_rr[add_count]) && (inserted_rr[add_count] -> nx_mdns_rr_name)) + { + _nx_mdns_cache_delete_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, inserted_rr[add_count]); + } + tx_mutex_put(&mdns_0.nx_mdns_mutex); + tx_thread_relinquish(); + } + } + tx_semaphore_put(&sema_0); + +} + + +static void ntest_2_entry(ULONG thread_input) +{ +CHAR *test_strings[] = { + "1", + "a", + "b", + "c", + "MDNS", + "Hello world0", + "Hello world1", + "Hello world1 Hello", + "Hello hello Hello", + "Hello Hello Hello Hello", + "abcdefghijklmnopqrstuvwxyz", + "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", +}; +UINT string_count= sizeof(test_strings) / sizeof(CHAR*); +INT loop_count = 1000; +UINT add_count; +UCHAR *inserted_strings[5]; +UINT index; + + /* Loop 1000 times to add and delete strings */ + while(loop_count > 0) + { + + /* Initialize variables. */ + add_count = 0; + memset(inserted_strings, 0, sizeof(inserted_strings)); + + /* Insert strings. */ + while(add_count < thread_input) + { + index = rand() % string_count; + tx_mutex_get(&mdns_0.nx_mdns_mutex, TX_WAIT_FOREVER); + if(_nx_mdns_cache_add_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, + test_strings[index], strlen(test_strings[index]), (VOID **)&inserted_strings[add_count], NX_FALSE, NX_TRUE)) + { + + /* Only the last string exceed the buffer. */ + if(index != (string_count - 1)) + { + tx_mutex_put(&mdns_0.nx_mdns_mutex); + error_counter++; + tx_semaphore_put(&sema_0); + return; + } + } + else + { + add_count++; + loop_count--; + } + tx_mutex_put(&mdns_0.nx_mdns_mutex); + tx_thread_relinquish(); + } + + /* Delete all inserted strings. */ + while(add_count--) + { + + /* No error is expected. */ + tx_mutex_get(&mdns_0.nx_mdns_mutex, TX_WAIT_FOREVER); + if(_nx_mdns_cache_delete_string(&mdns_0, NX_MDNS_CACHE_TYPE_LOCAL, inserted_strings[add_count], 0)) + { + tx_mutex_put(&mdns_0.nx_mdns_mutex); + error_counter++; + tx_semaphore_put(&sema_0); + return; + } + tx_mutex_put(&mdns_0.nx_mdns_mutex); + tx_thread_relinquish(); + } + } + + tx_semaphore_put(&sema_0); +} + + +VOID cache_full_notify(NX_MDNS *mdns_ptr, UINT state, UINT cache_type) +{ + + switch(state) + { + case NX_MDNS_CACHE_STATE_FULL: + { + + cache_state = 1; + break; + } + case NX_MDNS_CACHE_STATE_FRAGMENTED: + { + cache_state = 2; + break; + } + default: + { + cache_state = 0; + break; + } + } +} + +static void check_empty_buffer(UCHAR *buffer_ptr, UINT buffer_size) +{ + +ULONG *tail, *head; +UINT i; + + /* Check the head of buffer. */ + head = (ULONG*)buffer_ptr; + if(*head != buffer_org_head) + error_counter++; + + /* Check the tail of buffer. */ + /* Since all strings are deleted, tail should pointer to the end of buffer. */ + tail = (ULONG*)buffer_ptr + (buffer_size >> 2) - 1; + if(*tail != buffer_org_tail) + error_counter++; + + /* Check buffer overflow. */ + for(i = (buffer_size << 1); i < buffer_size; i++) + { + if(buffer_ptr[i] != 0xFF) + { + error_counter++; + break; + } + } +} + +static void empty_buffer_init(UCHAR *buffer_ptr, UINT buffer_size) +{ +ULONG *tail, *head; + + head = (ULONG*)buffer_ptr; + buffer_org_head = *head; + + tail = (ULONG*)buffer_ptr + (buffer_size >> 2) - 1; + buffer_org_tail = *tail; + + free_buffer_size = buffer_org_tail - buffer_org_head; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_internal_function_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Internal Function Test...............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_ipv6_string_test.c b/test/regression/mdns_test/netx_mdns_ipv6_string_test.c new file mode 100644 index 00000000..f5f7db3c --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_ipv6_string_test.c @@ -0,0 +1,429 @@ +#include "tx_api.h" +#include "nx_api.h" +#include + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_IPV4 && !defined NX_MDNS_DISABLE_CLIENT && defined NX_MDNS_ENABLE_IPV6 +#include "nxd_mdns.h" +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_stack[DEMO_STACK_SIZE]; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern UINT _nx_mdns_cache_add_string(NX_MDNS *mdns_ptr, UINT cache_type, VOID *string_ptr, UINT string_len, VOID **insert_ptr, UCHAR find_string, UCHAR add_name); +extern VOID _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); +extern UINT _nx_mdns_cache_delete_resource_record(NX_MDNS *mdns_ptr, UINT cache_type, NX_MDNS_RR *record_ptr); + +/* Frame (185 bytes) */ +static unsigned char response1[185] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* 33...... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x86, 0xdd, 0x60, 0x00, /* ..z...`. */ +0x00, 0x00, 0x00, 0x83, 0x11, 0x40, 0xfe, 0x80, /* .....@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1e, /* ........ */ +0x8f, 0xff, 0xfe, 0xb1, 0x7a, 0xd4, 0xff, 0x02, /* ....z... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x00, 0x83, 0x30, 0x75, 0x00, 0x00, /* ....0u.. */ +0x84, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* ..._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, /* .......C */ +0x61, 0x6e, 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, /* anonMF45 */ +0x30, 0x30, 0x77, 0xc0, 0x0c, 0x06, 0x72, 0x6f, /* 00w...ro */ +0x75, 0x74, 0x65, 0x72, 0xc0, 0x17, 0x00, 0x1c, /* uter.... */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x10, /* .....x.. */ +0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x02, 0x1e, 0x8f, 0xff, 0xfe, 0xb1, 0x7a, 0xd4, /* ......z. */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + +/* Frame (126 bytes) */ +static unsigned char response2[126] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x15, /* 33...... */ +0x5d, 0x64, 0x17, 0x05, 0x86, 0xdd, 0x60, 0x02, /* ]d....`. */ +0xe9, 0x46, 0x00, 0x48, 0x11, 0xff, 0x20, 0x01, /* .F.H.. . */ +0x04, 0x70, 0xf4, 0xde, 0x30, 0x00, 0x00, 0x00, /* .p..0... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x14, 0xe9, /* ........ */ +0x14, 0xe9, 0x00, 0x48, 0x63, 0xa9, 0x00, 0x00, /* ...Hc... */ +0x84, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x09, 0x5f, 0x73, 0x65, 0x72, 0x76, /* ..._serv */ +0x69, 0x63, 0x65, 0x73, 0x07, 0x5f, 0x64, 0x6e, /* ices._dn */ +0x73, 0x2d, 0x73, 0x64, 0x04, 0x5f, 0x75, 0x64, /* s-sd._ud */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0c, 0x04, 0x5f, 0x73, 0x6d, 0x62, 0x04, /* ..._smb. */ +0x5f, 0x74, 0x63, 0x70, 0xc0, 0x23 /* _tcp.# */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_ipv6_string_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + status = nxd_ipv6_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_MDNS_RR *p; +ULONG *head; +ULONG *tail; +ULONG temp_tail; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_MDNS_RR *ptr = NX_NULL; +NX_MDNS_RR *aaaa = NX_NULL; +NX_MDNS_RR *srv = NX_NULL; +NX_MDNS_RR *txt = NX_NULL; +NX_MDNS_RR *dns_sd_ptr = NX_NULL; +UINT dns_sd_ptr_string_len = 0; + + + printf("NetX Test: MDNS IPv6 String Test....................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set link local address. */ + status = nx_ip_interface_physical_address_set(&ip_0, 0, 0x00000011, 0x22334456, NX_TRUE); + status += nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a MDNS instance. */ + current_buffer_size = 2048; + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer += DEMO_STACK_SIZE; + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for probing and announcing. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Inject two packet to store the response in peer cache. + If the IPv6 address is added into cache as string, + The logic for deleting string in _nx_mdns_cache_delete_string() is incorrect. + For example, + Step1. Add ipv6_address_string (0x000080fe, ...). into cache. + Step2. Add string1 into cache.The strings in cache are string1, ipv6_address_string. + Step3. Delete string1 from cache. + After step3, the ipv6_address_string may also be deleted in some case since string_len = strlen(string_ptr), cnt are 0. */ + + /* Inject mDNS response1 to primary interface of ip_0. */ + status = nx_packet_allocate(&pool_0, &my_packet1, 16, NX_NO_WAIT); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the data. */ + status = nx_packet_data_append(my_packet1, response1 + 14, sizeof(response1) - 14, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface and receive the packet. */ + my_packet1 -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_receive(&ip_0, my_packet1); + + /* After process this packet, the IPv6 address string in cache is the last string . */ + + + /* Inject mDNS response2 to primary interface of ip_0. */ + status = nx_packet_allocate(&pool_0, &my_packet2, 16, NX_NO_WAIT); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the data. */ + status = nx_packet_data_append(my_packet2, response2 + 14, sizeof(response2) - 14, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface and receive the packet. */ + my_packet2 -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_receive(&ip_0, my_packet2); + + /* After process this packet, the dns PTR string in cache is after IPv6 address string. */ + + + /* Wait for process response. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + head = (ULONG*)mdns_0.nx_mdns_peer_service_cache; + tail = (ULONG*)(*head); + + /* Delete TXT resource record. */ + for (p = (NX_MDNS_RR*)(head + 1); (ULONG*)p < tail; p++) + { + + /* Check the entry type. */ + if (p -> nx_mdns_rr_state == NX_MDNS_RR_STATE_INVALID) + continue; + + /* Check the type. */ + if (p -> nx_mdns_rr_type == NX_MDNS_RR_TYPE_PTR) + { + if (memcmp(p -> nx_mdns_rr_name, "_services._dns-sd._udp.local", strlen("_services._dns-sd._udp.local"))) + ptr = p; + else + dns_sd_ptr = p; + } + else if (p -> nx_mdns_rr_type == NX_MDNS_RR_TYPE_AAAA) + aaaa = p; + else if (p -> nx_mdns_rr_type == NX_MDNS_RR_TYPE_SRV) + srv = p; + else if (p -> nx_mdns_rr_type == NX_MDNS_RR_TYPE_TXT) + txt = p; + } + + /* Check the rr count (PTR, AAAA, SRV, TXT, dns-sd PTR). */ + if ((mdns_0.nx_mdns_peer_rr_count != 5) || + (ptr == NX_NULL) || + (aaaa == NX_NULL) || + (srv == NX_NULL) || + (txt == NX_NULL) || + (dns_sd_ptr == NX_NULL)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check dns PTR info. */ + if ((memcmp(dns_sd_ptr -> nx_mdns_rr_name, "_services._dns-sd._udp.local", strlen("_services._dns-sd._udp.local"))) || + (memcmp(dns_sd_ptr -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_ptr.nx_mdns_rr_ptr_name, "_smb._tcp.local", strlen("_smb._tcp.local")))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the string tail info. */ + tail = (ULONG*)mdns_0.nx_mdns_peer_service_cache + (mdns_0.nx_mdns_peer_service_cache_size >> 2) - 1; + temp_tail = (ULONG)(*tail); + + /* The tail should be dns-sd PTR string. */ + if (dns_sd_ptr -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_ptr.nx_mdns_rr_ptr_name != (UCHAR*)(*tail)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Compute the string length. */ + dns_sd_ptr_string_len = ((strlen((const char*)dns_sd_ptr -> nx_mdns_rr_name) & 0xFFFFFFFC) + 8) & 0xFFFFFFFF; + dns_sd_ptr_string_len += ((strlen((const char*)dns_sd_ptr -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_ptr.nx_mdns_rr_ptr_name) & 0xFFFFFFFC) + 8) & 0xFFFFFFFF; + + /* Check the string length. */ + if (dns_sd_ptr_string_len != 56) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the TXT info. */ + if (memcmp(txt -> nx_mdns_rr_name, "CanonMF4500w._http._tcp.local", strlen("CanonMF4500w._http._tcp.local"))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check SRV info. */ + if ((memcmp(srv -> nx_mdns_rr_name, "CanonMF4500w._http._tcp.local", strlen("CanonMF4500w._http._tcp.local"))) || + (memcmp(srv -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_srv.nx_mdns_rr_srv_target, "router.local", strlen("router.local"))) || + (srv -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_srv.nx_mdns_rr_srv_port != 80) || + (srv -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_srv.nx_mdns_rr_srv_priority != 0) || + (srv -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_srv.nx_mdns_rr_srv_weights != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check AAAA info. */ + if ((memcmp(aaaa -> nx_mdns_rr_name, "router.local", strlen("router.local"))) || + (aaaa -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_aaaa.nx_mdns_rr_aaaa_address[0] != 0xfe800000) || + (aaaa -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_aaaa.nx_mdns_rr_aaaa_address[1] != 0x00000000) || + (aaaa -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_aaaa.nx_mdns_rr_aaaa_address[2] != 0x021e8fff)|| + (aaaa -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_aaaa.nx_mdns_rr_aaaa_address[3] != 0xfeb17ad4)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check PTR info. */ + if ((memcmp(ptr -> nx_mdns_rr_name, "_http._tcp.local", strlen("_http._tcp.local"))) || + (memcmp(ptr -> nx_mdns_rr_rdata.nx_mdns_rr_rdata_ptr.nx_mdns_rr_ptr_name, "CanonMF4500w._http._tcp.local", strlen("CanonMF4500w._http._tcp.local")))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete dns-sd PTR record. */ + _nx_mdns_cache_delete_resource_record(&mdns_0, NX_MDNS_CACHE_TYPE_PEER, dns_sd_ptr); + + /* Check the string tail info. */ + tail = (ULONG*)mdns_0.nx_mdns_peer_service_cache + (mdns_0.nx_mdns_peer_service_cache_size >> 2) - 1; + + /* The tail should be dns PTR string. */ + if (*tail != temp_tail + dns_sd_ptr_string_len) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_ipv6_string_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS IPv6 String Test.....................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_local_cache_continuous_query_test.c b/test/regression/mdns_test/netx_mdns_local_cache_continuous_query_test.c new file mode 100644 index 00000000..ea07621f --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_local_cache_continuous_query_test.c @@ -0,0 +1,298 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_CLIENT && !defined NX_MDNS_DISABLE_SERVER && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; +static CHAR host_registered = NX_FALSE; +static CHAR service_registered = NX_FALSE; +static CHAR query_received; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static VOID probing_notify(struct NX_MDNS_STRUCT *mdns_ptr, UCHAR *name, UINT state); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_local_cache_continuous_query_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192, 168, 0, 31), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + + NX_PARAMETER_NOT_USED(thread_input); + + printf("NetX Test: MDNS Local Cache Continuous Query Test...................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR*)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, probing_notify); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for host probing. */ + while(host_registered == NX_FALSE) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + /* Add a service. */ + if(nx_mdns_service_add(&mdns_0, (UCHAR*)"test", (UCHAR *)"_http._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for service probing. */ + while(service_registered == NX_FALSE) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + /* Initialize the query received. */ + query_received = 0; + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Start one-shot query. */ + if(nx_mdns_service_continuous_query(&mdns_0, NX_NULL, (UCHAR*)"_http._tcp", NX_NULL)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for query. */ + while(query_received == 0) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +UCHAR *packet_pointer; +USHORT mdns_flags; +USHORT question_count; +USHORT answer_count; + + + + NX_PARAMETER_NOT_USED(ip_ptr); + NX_PARAMETER_NOT_USED(operation_ptr); + NX_PARAMETER_NOT_USED(delay_ptr); + + /* Get protocol. */ + packet_pointer = packet_ptr -> nx_packet_prepend_ptr + 9; + + /* Check UDP packets only. */ + if(*packet_pointer != NX_PROTOCOL_UDP) + return NX_TRUE; + + /* Get port. */ + packet_pointer = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check UDP port 5353 only. */ + if((((*packet_pointer << 8) + *(packet_pointer + 1)) != 5353) || + (((*(packet_pointer + 2) << 8) + *(packet_pointer + 3)) != 5353)) + return NX_TRUE; + + /* Point to mDNS message. */ + packet_pointer = packet_ptr -> nx_packet_prepend_ptr + 28; + + /* Extract the message type which should be the first byte. */ + mdns_flags = NX_MDNS_GET_USHORT_DATA(packet_pointer + NX_MDNS_FLAGS_OFFSET); + + /* Check whether this packet is the query. */ + if(mdns_flags != NX_MDNS_QUERY_FLAG) + return NX_TRUE; + + /* Increase the query count. */ + query_received++; + + /* Get the question count. */ + question_count = NX_MDNS_GET_USHORT_DATA(packet_pointer + NX_MDNS_QDCOUNT_OFFSET); + + /* Determine if we have any 'answers' to our DNS query. */ + answer_count = NX_MDNS_GET_USHORT_DATA(packet_pointer + NX_MDNS_ANCOUNT_OFFSET); + + /* Check the question count and answer count. */ + if ((question_count != 1) || (answer_count != 1)) + error_counter++; + + return NX_TRUE; +} + +static VOID probing_notify(struct NX_MDNS_STRUCT *mdns_ptr, UCHAR *name, UINT state) +{ + + NX_PARAMETER_NOT_USED(mdns_ptr); + NX_PARAMETER_NOT_USED(name); + + switch(state) + { + case NX_MDNS_LOCAL_SERVICE_REGISTERED_SUCCESS: + { + service_registered = NX_TRUE; + break; + } + case NX_MDNS_LOCAL_SERVICE_REGISTERED_FAILURE: + { + service_registered = NX_FALSE; + break; + } + case NX_MDNS_LOCAL_HOST_REGISTERED_SUCCESS: + { + host_registered = NX_TRUE; + break; + } + case NX_MDNS_LOCAL_HOST_REGISTERED_FAILURE: + { + host_registered = NX_FALSE; + break; + } + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_local_cache_continuous_query_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Local Cache Continuous Query Test....................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_CLIENT */ + diff --git a/test/regression/mdns_test/netx_mdns_local_cache_one_shot_query_test.c b/test/regression/mdns_test/netx_mdns_local_cache_one_shot_query_test.c new file mode 100644 index 00000000..548af151 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_local_cache_one_shot_query_test.c @@ -0,0 +1,204 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_CLIENT && !defined NX_MDNS_DISABLE_SERVER && !defined NX_DISABLE_IPV4 + +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static NX_MDNS_SERVICE service_instance; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_local_cache_one_shot_query_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192,168,0,31), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + printf("NetX Test: MDNS Local Cache One Shot Query Test......................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Add service to send probing. */ + nx_mdns_service_add(&mdns_0, (CHAR *)"ARMMDNSTest", (CHAR *)"_ipp._tcp", NX_NULL, (CHAR *)"paper=A4", 4500, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Sleep two seconds for probing. */ + tx_thread_sleep(200); + + /* One shot query. The answer is in local cache. */ + status = nx_mdns_service_one_shot_query(&mdns_0, "ARMMDNSTest", "_ipp._tcp", NX_NULL, &service_instance, 1); + + if(status) + error_counter++; + else + { + + /* Check every field. */ + if(service_instance.interface_index != 0) + error_counter++; + if(strcmp(service_instance.service_domain, "local") != 0) + error_counter++; + if(strcmp(service_instance.service_host, "NETX-MDNS.local") != 0) + error_counter++; + if(service_instance.service_ipv4 != IP_ADDRESS(192,168,0,31)) + error_counter++; + if(strcmp(service_instance.service_name, "ARMMDNSTest") != 0) + error_counter++; + if(service_instance.service_port != 80) + error_counter++; + if(service_instance.service_priority != 0) + error_counter++; + if(strcmp(service_instance.service_text, "paper=A4") != 0) + error_counter++; + if(service_instance.service_text_valid == NX_FALSE) + error_counter++; + if(strcmp(service_instance.service_type, "_ipp._tcp") != 0) + error_counter++; + if(service_instance.service_weight != 0) + error_counter++; + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_local_cache_one_shot_query_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Local Cache One Shot Query Test......................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_CLIENT */ diff --git a/test/regression/mdns_test/netx_mdns_multiple_answers_test.c b/test/regression/mdns_test/netx_mdns_multiple_answers_test.c new file mode 100644 index 00000000..7ca11d6d --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_multiple_answers_test.c @@ -0,0 +1,262 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_SERVER && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static ULONG answer_received; +static UCHAR mdns_data[] = +{ +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x0c, /* ..^..... */ +0x29, 0x01, 0xd4, 0x8d, 0x08, 0x00, 0x45, 0x00, /* ).....E. */ +0x00, 0x3e, 0x00, 0x00, 0x40, 0x00, 0xff, 0x11, /* .>..@... */ +0x90, 0xb2, 0x0a, 0x00, 0x00, 0x01, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x2a, /* .......* */ +0xe3, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01 /* .... */ +}; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; +static NX_PACKET *current_packet; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_multiple_answers_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NXD_ADDRESS address; + + printf("NetX Test: MDNS Multiple Answers Test................................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create two services. */ + status = nx_mdns_service_add(&mdns_0, (CHAR *)"ARMMDNSTest", (CHAR *)"_http._tcp", NX_NULL, "paper=A4;version=01", 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + status += nx_mdns_service_add(&mdns_0, (CHAR *)"Simple Web Server", (CHAR *)"_http._tcp", NX_NULL, "paper=A4;version=01", 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + if(status) + error_counter++; + + /* Sleep 5 seconds for probing and announcement. */ + tx_thread_sleep(500); + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Reset the counter. */ + answer_received = 0; + + /* Send MULTICAST address. */ + address.nxd_ip_version = NX_IP_VERSION_V4; + address.nxd_ip_address.v4 = NX_MDNS_IPV4_MULTICAST_ADDRESS; + + /* Allocate a query packet. */ + status = nx_packet_allocate(&pool_0, ¤t_packet, NX_IPv4_UDP_PACKET, 100); + status += nx_packet_data_append(current_packet, mdns_data + 42, sizeof(mdns_data) - 42, &pool_0, 100); + status += nxd_udp_socket_send(&mdns_0.nx_mdns_socket, current_packet, &address, 5353); + current_packet = NX_NULL; + + if(status) + error_counter++; + + /* Sleep one second and check received answers. */ + tx_thread_sleep(100); + if(answer_received != 2) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UCHAR *pointer; + + if(packet_ptr == current_packet) + { + + /* Inject it to IP layer. */ + packet_ptr -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + return NX_FALSE; + } + + /* Get protocol. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 9; + + /* Check UDP packets only. */ + if(*pointer != NX_PROTOCOL_UDP) + return NX_TRUE; + + /* Get port. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check UDP port 5353 only. */ + if((((*pointer << 8) + *(pointer + 1)) != 5353) || + (((*(pointer + 2) << 8) + *(pointer + 3)) != 5353)) + return NX_TRUE; + + /* Get flag. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 30; + + /* Check whether this packet is the response. */ + if(((*pointer << 8) + *(pointer + 1)) != (NX_MDNS_RESPONSE_FLAG | NX_MDNS_AA_FLAG)) + { + + /* It is not a response packet. */ + return NX_TRUE; + } + + /* Get the answer RRs. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 34; + answer_received = (*pointer << 8) + *(pointer + 1); + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_multiple_answers_test(void *first_unused_memory) +#endif +{ + + printf("NetX Test: MDNS Multiple Answers Test................................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_SERVER */ diff --git a/test/regression/mdns_test/netx_mdns_name_test.c b/test/regression/mdns_test/netx_mdns_name_test.c new file mode 100644 index 00000000..d98b402e --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_name_test.c @@ -0,0 +1,217 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_stack[DEMO_STACK_SIZE]; +static UCHAR name_buffer[100]; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +static VOID build_name(UINT length); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_name_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +ULONG name_length; + + printf("NetX Test: MDNS Name Test............................................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, mdns_stack, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + + nx_mdns_enable(&mdns_0, 0); + + /* Test max length instance name, (NX_MDNS_LABEL_MAX - 4). */ + name_length = (NX_MDNS_LABEL_MAX - 4); + build_name(name_length); + +#ifndef NX_MDNS_DISABLE_SERVER + /* Total length is 59. */ + status += nx_mdns_service_add(&mdns_0, name_buffer, (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); +#endif /* NX_MDNS_DISABLE_SERVER */ + +#ifndef NX_MDNS_DISABLE_CLIENT + /* Total length is 59. */ + status += nx_mdns_service_continuous_query(&mdns_0, name_buffer, "_ipp._tcp", NX_NULL); +#endif /* NX_MDNS_DISABLE_CLIENT */ + + /* Check status. */ + if(status) + error_counter++; + + /* Test strings exceed max length, (NX_MDNS_LABEL_MAX - 4) + 1. */ + name_length = (NX_MDNS_LABEL_MAX - 4) + 1; + build_name(name_length); + +#ifndef NX_DISABLE_ERROR_CHECKING +#ifndef NX_MDNS_DISABLE_SERVER + /* Total length is 60. */ + status = nx_mdns_service_add(&mdns_0, name_buffer, (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Check status. */ + if(!status) + error_counter++; +#endif /* NX_MDNS_DISABLE_SERVER */ +#endif /* NX_DISABLE_ERROR_CHECKING */ + +#ifndef NX_MDNS_DISABLE_CLIENT + /* Total length is 60. */ + status = nx_mdns_service_continuous_query(&mdns_0, name_buffer, "_ipp._tcp", NX_NULL); + + /* Check status. */ + if(status) + error_counter++; +#endif /* NX_MDNS_DISABLE_CLIENT */ + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static VOID build_name(UINT length) +{ + +UINT i; + + /* Add lower case character. */ + for(i = 1; i <= length; i++) + { + if(i % 64 == 0 ) + name_buffer[i - 1] = '.'; + else + name_buffer[i - 1] = 'a' + i % 26; + } + + name_buffer[i] = 0; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_name_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Name Test............................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_one_shot_query_test.c b/test/regression/mdns_test/netx_mdns_one_shot_query_test.c new file mode 100644 index 00000000..5a11370d --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_one_shot_query_test.c @@ -0,0 +1,284 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_CLIENT && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static CHAR mdns_data[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xf1, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xd9, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xdd, /* ........ */ +0xf0, 0xbc, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, /* .......d */ +0x00, 0x24, 0x11, 0x53, 0x69, 0x6d, 0x70, 0x6c, /* .$.Simpl */ +0x65, 0x20, 0x57, 0x65, 0x62, 0x20, 0x53, 0x65, /* e Web Se */ +0x72, 0x76, 0x65, 0x72, 0x05, 0x5f, 0x68, 0x74, /* rver._ht */ +0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* tp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, /* local..S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* l..!.... */ +0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, /* .d...... */ +0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .P.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, /* NSTest.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x11, 0x53, 0x69, /* ocal..Si */ +0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, 0x62, /* mple Web */ +0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x05, /* Server. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x14, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 /* sion=01 */ +}; + +static UINT query_received; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_one_shot_query_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192, 168, 0, 31), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_MDNS_SERVICE service; + + printf("NetX Test: MDNS One Shot Query Test.................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for probing and announcement. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Initialize the query received. */ + query_received = 0; + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Start one-shot query. */ + if(nx_mdns_service_one_shot_query(&mdns_0, NX_NULL, "_http._tcp", NX_NULL, &service, 5 * NX_IP_PERIODIC_RATE)) + error_counter++; + + /* Sleep 5 seconds and check whether more queries are sent. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start one-shot query. */ + if(nx_mdns_service_one_shot_query(&mdns_0, NX_NULL, "_http._tcp", NX_NULL, &service, 5 * NX_IP_PERIODIC_RATE)) + error_counter++; + + /* Sleep 1 second and check whether more queries are sent. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +UCHAR *pointer; +NX_PACKET *my_packet; +UINT status; + + + + /* Get protocol. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 9; + + /* Check UDP packets only. */ + if(*pointer != NX_PROTOCOL_UDP) + return NX_TRUE; + + /* Get port. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check UDP port 5353 only. */ + if((((*pointer << 8) + *(pointer + 1)) != 5353) || + (((*(pointer + 2) << 8) + *(pointer + 3)) != 5353)) + return NX_TRUE; + + /* Get flag. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 30; + + /* Check whether this packet is the query. */ + if(((*pointer << 8) + *(pointer + 1)) != NX_MDNS_QUERY_FLAG) + return NX_TRUE; + + query_received++; + + /* Do not reply response for the first two queries. */ + if(query_received < 3) + return NX_TRUE; + + /* Only one query is expected. */ + if(query_received > 3) + { + error_counter++; + return NX_TRUE; + } + else + { + + /* Inject a response packet for the third query. */ + status = nx_packet_allocate(&pool_0, &my_packet, 16, 100); + status += nx_packet_data_append(my_packet, mdns_data + 14, sizeof(mdns_data) - 14, &pool_0, 100); + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_one_shot_query_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS One Shot Query Test..................................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_CLIENT */ + diff --git a/test/regression/mdns_test/netx_mdns_peer_service_change_notify_test.c b/test/regression/mdns_test/netx_mdns_peer_service_change_notify_test.c new file mode 100644 index 00000000..94ef76cb --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_peer_service_change_notify_test.c @@ -0,0 +1,381 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_CLIENT && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; + +/* Frame (350 bytes) */ +static unsigned char response[350] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x32, 0x5e, 0x5b, 0x58, 0x08, 0x00, 0x45, 0x00, /* 2^[X..E. */ +0x01, 0x50, 0x52, 0x05, 0x40, 0x00, 0xff, 0x11, /* .PR.@... */ +0x22, 0xed, 0xc0, 0xa8, 0x64, 0x06, 0xe0, 0x00, /* "...d... */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x01, 0x3c, /* .......< */ +0x54, 0x86, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* T....... */ +0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0c, 0x09, 0x44, 0x75, 0x6e, 0x63, 0x68, /* ...Dunch */ +0x75, 0x61, 0x6e, 0x67, 0xc0, 0x0c, 0xc0, 0x28, /* uang...( */ +0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0xaa, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, /* ...vendo */ +0x72, 0x3d, 0x53, 0x79, 0x6e, 0x6f, 0x6c, 0x6f, /* r=Synolo */ +0x67, 0x79, 0x0c, 0x6d, 0x6f, 0x64, 0x65, 0x6c, /* gy.model */ +0x3d, 0x44, 0x53, 0x32, 0x31, 0x36, 0x6a, 0x14, /* =DS216j. */ +0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x3d, 0x31, /* serial=1 */ +0x36, 0x36, 0x30, 0x4e, 0x4e, 0x4e, 0x35, 0x34, /* 660NNN54 */ +0x34, 0x34, 0x30, 0x33, 0x0f, 0x76, 0x65, 0x72, /* 4403.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x61, 0x6a, /* sion_maj */ +0x6f, 0x72, 0x3d, 0x36, 0x0f, 0x76, 0x65, 0x72, /* or=6.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x69, 0x6e, /* sion_min */ +0x6f, 0x72, 0x3d, 0x30, 0x12, 0x76, 0x65, 0x72, /* or=0.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x75, 0x69, /* sion_bui */ +0x6c, 0x64, 0x3d, 0x37, 0x33, 0x39, 0x33, 0x0f, /* ld=7393. */ +0x61, 0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x70, 0x6f, /* admin_po */ +0x72, 0x74, 0x3d, 0x35, 0x30, 0x30, 0x30, 0x16, /* rt=5000. */ +0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x61, /* secure_a */ +0x64, 0x6d, 0x69, 0x6e, 0x5f, 0x70, 0x6f, 0x72, /* dmin_por */ +0x74, 0x3d, 0x35, 0x30, 0x30, 0x31, 0x1d, 0x6d, /* t=5001.m */ +0x61, 0x63, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, /* ac_addre */ +0x73, 0x73, 0x3d, 0x30, 0x30, 0x3a, 0x31, 0x31, /* ss=00:11 */ +0x3a, 0x33, 0x32, 0x3a, 0x35, 0x65, 0x3a, 0x35, /* :32:5e:5 */ +0x62, 0x3a, 0x35, 0x38, 0xc0, 0x28, 0x00, 0x21, /* b:58.(.! */ +0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x12, /* .....x.. */ +0x00, 0x00, 0x00, 0x00, 0x13, 0x88, 0x09, 0x44, /* .......D */ +0x75, 0x6e, 0x63, 0x68, 0x75, 0x61, 0x6e, 0x67, /* unchuang */ +0xc0, 0x17, 0xc0, 0xfc, 0x00, 0x1c, 0x80, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x10, 0x20, 0x01, /* ...x.. . */ +0x04, 0x70, 0xf4, 0xde, 0x30, 0x00, 0x02, 0x11, /* .p..0... */ +0x32, 0xff, 0xfe, 0x5e, 0x5b, 0x58, 0xc0, 0xfc, /* 2..^[X.. */ +0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x04, 0xc0, 0xa8, 0x64, 0x06 /* ....d. */ +}; +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; +static CHAR host_registered = NX_FALSE; +static CHAR serivce_received = 0; +static CHAR serivce_updated = 0; +static CHAR serivce_deleted = 0; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +static VOID probing_notify(struct NX_MDNS_STRUCT *mdns_ptr, UCHAR *name, UINT state); +static VOID service_change_notify(NX_MDNS *mdns_ptr, NX_MDNS_SERVICE *service_ptr, UINT state); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_peer_service_change_notify_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; +NX_MDNS_SERVICE service_instance; + + NX_PARAMETER_NOT_USED(thread_input); + + printf("NetX Test: MDNS Peer Service Change Notify Test......................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Inject mDNS response to primary interface of ip_0. */ + status = nx_packet_allocate(&pool_0, &my_packet, 16, NX_NO_WAIT); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(my_packet, response + 14, sizeof(response) - 14, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_receive(&ip_0, my_packet); + + /* Sleep 1s. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the flag. */ + if ((serivce_received != 0) || (serivce_updated !=0) || (serivce_deleted !=0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Service lookup. */ + status = nx_mdns_service_lookup(&mdns_0, NX_NULL, (UCHAR *)"_http._tcp", NX_NULL, 0, &service_instance); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the service info. */ + if ((strcmp((const char*)service_instance.service_name, (const char*)"Dunchuang")) || + (strcmp((const char*)service_instance.service_type, (const char*)"_http._tcp"))|| + (strcmp((const char*)service_instance.service_domain, (const char*)"local"))|| + (strcmp((const char*)service_instance.service_host, (const char*)"Dunchuang.local"))|| + (service_instance.service_text_valid != 1) || + (service_instance.service_port != 5000) || + (service_instance.service_weight != 0) || + (service_instance.service_priority != 0) || + (service_instance.service_ipv4 != 0xc0a86406) || + (service_instance.service_ipv6[0][0] != 0x20010470) || + (service_instance.service_ipv6[0][1] != 0xf4de3000) || + (service_instance.service_ipv6[0][2] != 0x021132ff) || + (service_instance.service_ipv6[0][3] != 0xfe5e5b58)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the cache. */ + status = nx_mdns_peer_cache_clear(&mdns_0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the serivce change notify for _http. */ + status = nx_mdns_service_notify_set(&mdns_0, 0x02, service_change_notify); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Inject mDNS response to primary interface of ip_0. */ + status = nx_packet_allocate(&pool_0, &my_packet, 16, NX_NO_WAIT); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(my_packet, response + 14, sizeof(response) - 14, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_receive(&ip_0, my_packet); + + /* Check the flag. */ + if ((serivce_received == 0) || (serivce_updated == 0) || (serivce_deleted != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Service lookup. */ + status = nx_mdns_service_lookup(&mdns_0, NX_NULL, (UCHAR *)"_http._tcp", NX_NULL, 0, &service_instance); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the service info. */ + if ((strcmp((const char*)service_instance.service_name, (const char*)"Dunchuang")) || + (strcmp((const char*)service_instance.service_type, (const char*)"_http._tcp"))|| + (strcmp((const char*)service_instance.service_domain, (const char*)"local"))|| + (strcmp((const char*)service_instance.service_host, (const char*)"Dunchuang.local"))|| + (service_instance.service_text_valid != 1) || + (service_instance.service_port != 5000) || + (service_instance.service_weight != 0) || + (service_instance.service_priority != 0) || + (service_instance.service_ipv4 != 0xc0a86406) || + (service_instance.service_ipv6[0][0] != 0x20010470) || + (service_instance.service_ipv6[0][1] != 0xf4de3000) || + (service_instance.service_ipv6[0][2] != 0x021132ff) || + (service_instance.service_ipv6[0][3] != 0xfe5e5b58)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static VOID service_change_notify(NX_MDNS *mdns_ptr, NX_MDNS_SERVICE *service_ptr, UINT state) +{ + + NX_PARAMETER_NOT_USED(mdns_ptr); + NX_PARAMETER_NOT_USED(service_ptr); + + switch(state) + { + case NX_MDNS_PEER_SERVICE_RECEIVED: + { + serivce_received++; + break; + } + case NX_MDNS_PEER_SERVICE_UPDATED: + { + serivce_updated++; + break; + } + case NX_MDNS_PEER_SERVICE_DELETED: + { + serivce_deleted++; + break; + } + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_peer_service_change_notify_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Peer Service Change Notify Test......................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_ram_test.c b/test/regression/mdns_test/netx_mdns_ram_test.c new file mode 100644 index 00000000..7507c877 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_ram_test.c @@ -0,0 +1,299 @@ +#include "nx_api.h" +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_IPV4 +#include "netx_mdns_test.h" + +#define DEMO_STACK_SIZE 2048 +#define LOCAL_BUFFER_SIZE 5120 +#define PEER_BUFFER_SIZE 5120 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR local_buffer[LOCAL_BUFFER_SIZE]; +static UCHAR peer_buffer[PEER_BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_stack[DEMO_STACK_SIZE]; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define the test threads. */ +extern MDNS_TEST_SEQ mdns_response_with_tc[]; +extern MDNS_TEST_SEQ mdns_query_with_tc[]; +extern MDNS_TEST_SEQ mdns_announcement_in_multiple_packets[]; +extern MDNS_TEST_SEQ mdns_response_in_multiple_packets[]; +extern MDNS_TEST_SEQ mdns_address_change[]; +extern MDNS_TEST_SEQ mdns_case_insensitivity[]; +extern MDNS_TEST_SEQ mdns_poof[]; +extern MDNS_TEST_SEQ mdns_query_during_probing[]; +extern MDNS_TEST_SEQ mdns_server_interface_reset[]; +extern MDNS_TEST_SEQ mdns_server_send_goodbye[]; +extern MDNS_TEST_SEQ mdns_dns_sd_query[]; +extern MDNS_TEST_SEQ mdns_dns_sd_response[]; +extern MDNS_TEST_SEQ mdns_server_announcement_with_txt[]; +extern MDNS_TEST_SEQ mdns_probing_conflict[]; +extern MDNS_TEST_SEQ mdns_response_no_delay[]; +extern MDNS_TEST_SEQ mdns_response_interval[]; +extern MDNS_TEST_SEQ mdns_response_aggregation[]; +extern MDNS_TEST_SEQ mdns_known_answer_ignored[]; +extern MDNS_TEST_SEQ mdns_known_answer_suppression_query[]; +extern MDNS_TEST_SEQ mdns_known_answer_suppression_query_half_ttl[]; +extern MDNS_TEST_SEQ mdns_known_answer_suppression_response[]; +extern MDNS_TEST_SEQ mdns_known_answer_suppression_unique[]; +extern MDNS_TEST_SEQ mdns_duplicate_question_suppression[]; +extern MDNS_TEST_SEQ mdns_duplicate_answer_suppression[]; +extern MDNS_TEST_SEQ mdns_one_shot_query[]; +extern MDNS_TEST_SEQ mdns_continuous_query[]; +extern MDNS_TEST_SEQ mdns_continuous_query_a[]; +extern MDNS_TEST_SEQ mdns_continuous_query_unique_answer[]; +extern MDNS_TEST_SEQ mdns_continuous_query_interval[]; +extern MDNS_TEST_SEQ mdns_query_start_stop[]; +extern MDNS_TEST_SEQ mdns_query_http_tcp[]; +extern MDNS_TEST_SEQ mdns_query_pdl_datastream_tcp[]; +extern MDNS_TEST_SEQ mdns_query_printer_tcp[]; +extern MDNS_TEST_SEQ mdns_query_smb_tcp[]; +extern MDNS_TEST_SEQ mdns_query_and_response_chaos[]; +extern MDNS_TEST_SEQ mdns_multiple_questions_per_query[]; +extern MDNS_TEST_SEQ mdns_basic_ipv6_query[]; +extern MDNS_TEST_SEQ mdns_basic_ipv6_response[]; +extern MDNS_TEST_SEQ mdns_basic_ipv6_announcement[]; +extern MDNS_TEST_SEQ mdns_response_to_address_query[]; +extern MDNS_TEST_SEQ mdns_client_passive[]; +extern MDNS_TEST_SEQ mdns_client_passive_02[]; +extern MDNS_TEST_SEQ mdns_query_rr_timeout[]; + +extern int mdns_response_with_tc_size; +extern int mdns_query_with_tc_size; +extern int mdns_announcement_in_multiple_packets_size; +extern int mdns_response_in_multiple_packets_size; +extern int mdns_address_change_size; +extern int mdns_case_insensitivity_size; +extern int mdns_poof_size; +extern int mdns_query_during_probing_size; +extern int mdns_server_interface_reset_size; +extern int mdns_server_send_goodbye_size; +extern int mdns_dns_sd_query_size; +extern int mdns_dns_sd_response_size; +extern int mdns_server_announcement_with_txt_size; +extern int mdns_probing_conflict_size; +extern int mdns_response_no_delay_size; +extern int mdns_response_interval_size; +extern int mdns_response_aggregation_size; +extern int mdns_known_answer_ignored_size; +extern int mdns_known_answer_suppression_query_size; +extern int mdns_known_answer_suppression_query_half_ttl_size; +extern int mdns_known_answer_suppression_response_size; +extern int mdns_known_answer_suppression_unique_size; +extern int mdns_duplicate_question_suppression_size; +extern int mdns_duplicate_answer_suppression_size; +extern int mdns_one_shot_query_size; +extern int mdns_continuous_query_size; +extern int mdns_continuous_query_a_size; +extern int mdns_continuous_query_unique_answer_size; +extern int mdns_continuous_query_interval_size; +extern int mdns_query_start_stop_size; +extern int mdns_query_http_tcp_size; +extern int mdns_query_pdl_datastream_tcp_size; +extern int mdns_query_printer_tcp_size; +extern int mdns_query_smb_tcp_size; +extern int mdns_query_and_response_chaos_size; +extern int mdns_multiple_questions_per_query_size; +extern int mdns_basic_ipv6_query_size; +extern int mdns_basic_ipv6_response_size; +extern int mdns_basic_ipv6_announcement_size; +extern int mdns_response_to_address_query_size; +extern int mdns_client_passive_size; +extern int mdns_client_passive_size_02; +extern int mdns_query_rr_timeout_size; + +static MDNS_TEST_SUITE test_suite[] = +{ + +#ifndef NX_MDNS_DISABLE_SERVER + {&mdns_address_change[0], &mdns_address_change_size}, + {&mdns_case_insensitivity[0], &mdns_case_insensitivity_size}, + {&mdns_query_during_probing[0], &mdns_query_during_probing_size}, + {&mdns_server_interface_reset[0], &mdns_server_interface_reset_size}, + {&mdns_server_send_goodbye[0], &mdns_server_send_goodbye_size}, + {&mdns_dns_sd_response[0], &mdns_dns_sd_response_size}, + {&mdns_probing_conflict[0], &mdns_probing_conflict_size}, + {&mdns_server_announcement_with_txt[0], &mdns_server_announcement_with_txt_size}, + {&mdns_response_no_delay[0], &mdns_response_no_delay_size}, + {&mdns_response_interval[0], &mdns_response_interval_size}, + {&mdns_response_aggregation[0], &mdns_response_aggregation_size}, + {&mdns_response_with_tc[0], &mdns_response_with_tc_size}, + {&mdns_known_answer_suppression_response[0], &mdns_known_answer_suppression_response_size}, + {&mdns_known_answer_suppression_unique[0], &mdns_known_answer_suppression_unique_size}, + {&mdns_duplicate_answer_suppression[0], &mdns_duplicate_answer_suppression_size}, +#if (NX_PHYSICAL_HEADER < 48) /* If the header is too large, the RRs in one packet will be different with the message captured. */ + {&mdns_announcement_in_multiple_packets[0], &mdns_announcement_in_multiple_packets_size}, +#endif +#ifdef NX_MDNS_ENABLE_IPV6 + {&mdns_response_in_multiple_packets[0], &mdns_response_in_multiple_packets_size}, + {&mdns_basic_ipv6_response[0], &mdns_basic_ipv6_response_size}, + {&mdns_basic_ipv6_announcement[0], &mdns_basic_ipv6_announcement_size}, + {&mdns_response_to_address_query[0], &mdns_response_to_address_query_size}, +#endif /* NX_MDNS_ENABLE_IPV6 */ +#endif /* NX_MDNS_DISABLE_SERVER */ + +#ifndef NX_MDNS_DISABLE_CLIENT + {&mdns_poof[0], &mdns_poof_size}, + {&mdns_dns_sd_query[0], &mdns_dns_sd_query_size}, + {&mdns_known_answer_ignored[0], &mdns_known_answer_ignored_size}, + {&mdns_known_answer_suppression_query[0], &mdns_known_answer_suppression_query_size}, + {&mdns_known_answer_suppression_query_half_ttl[0], &mdns_known_answer_suppression_query_half_ttl_size}, + {&mdns_duplicate_question_suppression[0], &mdns_duplicate_question_suppression_size}, + {&mdns_continuous_query[0], &mdns_continuous_query_size}, + {&mdns_continuous_query_unique_answer[0], &mdns_continuous_query_unique_answer_size}, + {&mdns_continuous_query_interval[0], &mdns_continuous_query_interval_size}, + {&mdns_query_start_stop[0], &mdns_query_start_stop_size}, + {&mdns_query_http_tcp[0], &mdns_query_http_tcp_size}, + {&mdns_query_pdl_datastream_tcp[0], &mdns_query_pdl_datastream_tcp_size}, + {&mdns_query_printer_tcp[0], &mdns_query_printer_tcp_size}, + {&mdns_query_smb_tcp[0], &mdns_query_smb_tcp_size}, + {&mdns_query_and_response_chaos[0], &mdns_query_and_response_chaos_size}, + {&mdns_query_with_tc[0], &mdns_query_with_tc_size}, + {&mdns_query_rr_timeout[0], &mdns_query_rr_timeout_size}, + {&mdns_multiple_questions_per_query[0], &mdns_multiple_questions_per_query_size}, + {&mdns_client_passive[0], &mdns_client_passive_size}, +#ifdef NX_MDNS_ENABLE_IPV6 + {&mdns_basic_ipv6_query[0], &mdns_basic_ipv6_query_size}, +#endif /* NX_MDNS_ENABLE_IPV6 */ +#endif /* NX_MDNS_DISABLE_CLIENT */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_ram_test_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*32); + pointer = pointer + 1536*32; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(10, 0, 0, 66), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable UDP processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + /* Enable igmp processing for IP Instance 0. */ + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + +#if defined FEATURE_NX_IPV6 && defined NX_ENABLE_IPV6_MULTICAST + /* Enable IPv6 processing for IP Instance 0. */ + status = nxd_ipv6_enable(&ip_0); +#endif /* FEATURE_NX_IPV6 && NX_ENABLE_IPV6_MULTICAST */ + + /* Check status. */ + if(status) + error_counter++; + +} + +static void thread_0_entry(ULONG thread_input) +{ +int num_suite; +int i; + + num_suite = sizeof(test_suite) / sizeof(MDNS_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + + /* Create mDNS. */ + if(nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, mdns_stack, DEMO_STACK_SIZE, "ARMMDNSTest", + local_buffer, LOCAL_BUFFER_SIZE, peer_buffer, PEER_BUFFER_SIZE, netx_mdns_probing_notify)) + error_counter++; + + /* Make sure the service probing and host probing in one packet for some test cases. */ + mdns_0.nx_mdns_first_probing_delay = NX_MDNS_PROBING_TIMER_COUNT; + + /* Enable interface. */ + if(nx_mdns_enable(&mdns_0, 0)) + error_counter++; + + /* Run test case. */ + if(test_suite[i].test_case) + netx_mdns_run_test_case(&ip_0, &mdns_0, test_suite[i].test_case, *(test_suite[i].test_case_size)); + + /* Delete mDNS. */ + if(nx_mdns_delete(&mdns_0)) + error_counter++; + } + + test_control_return(0xdeadbeef); +} +#endif /* __PRODUCT_NETXDUO__ && !NX_DISABLE_IPV4 */ diff --git a/test/regression/mdns_test/netx_mdns_read_overflow_test.c b/test/regression/mdns_test/netx_mdns_read_overflow_test.c new file mode 100644 index 00000000..0c6ca152 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_read_overflow_test.c @@ -0,0 +1,406 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_CLIENT && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR type[256]; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; + +static CHAR invalid_data_1[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x6a, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static CHAR invalid_data_2[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x6d, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x01, 0xc0, 0x28, 0x00 /* . */ +}; + +static CHAR invalid_data_3[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0C, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x6e, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0xc0, 0x28, 0x00, /* . */ +}; + +static unsigned char invalid_data_4[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* FG...... */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* st.local */ +0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, 0x42, 0x0b, /* x.....B. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* est.loca */ +0x6c, 0x00, 0x00, 0x2f, 0x80, 0x01, 0x00, 0x00, /* l../.... */ +0x00, 0x78, 0x00, 0x16, 0x0b, 0x41, 0x52, 0x4d, /* .x...ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x01, 0x40, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, /* .@.ARMMD */ +0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, 0x5f, /* NSTest._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x21, 0x80, 0x01, 0x00, 0x00, 0x00, 0x64, /* .!.....d */ +0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, /* .......P */ +0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, /* .ARMMDNS */ +0x54, 0x65, 0x73, 0x74, 0x05, 0x6c, 0x6f, 0x63, /* Test.loc */ +0x61, 0x6c, 0x00, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* al..ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, /* _http._t */ +0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, /* cp.local */ +0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x64, 0x00, 0x1e, 0x08, 0x70, 0x61, 0x70, 0x65, /* d...pape */ +0x72, 0x3d, 0x41, 0x34, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31, 0x0a, 0x76, 0x65, 0x72, /* r=A4.ver */ +0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x30, 0x31 +}; + +static unsigned char invalid_data_5[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x35, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x5f, 0x30, 0x05, 0x6c, 0x6f, 0x63, /* st_0.loc */ +0x61, 0x6c, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x78, 0x00, 0x04, 0x0a, 0x00, 0x00, /* ..x..... */ +0x42 /* B */ +}; + +static unsigned char invalid_data_6[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x41, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x5f, 0x30, 0x05, 0x6c, 0x6f, 0x63, /* st_0.loc */ +0x61, 0x6c, 0x00, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x11, 0x22, 0xff, 0xfe, 0x33, /* ...."..3 */ +0x44, 0x57, +}; + +static CHAR mdns_data[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_read_overflow_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192,168,0,31), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +#define MDNS_START_OFFSET (34) + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *response_packet; +UCHAR *invalid_responses[] = +{ + invalid_data_1, + invalid_data_2, + invalid_data_3, + invalid_data_4, + invalid_data_5, + invalid_data_6, +}; +UINT invalid_responses_len[] = +{ + sizeof(invalid_data_1), + sizeof(invalid_data_2), + sizeof(invalid_data_3), + sizeof(invalid_data_4), + sizeof(invalid_data_5), + sizeof(invalid_data_6), +}; +UCHAR *response_ptr; +UINT response_len; +UINT i; +UINT test_num = sizeof(invalid_responses_len) / sizeof(UINT); +NX_IPV4_HEADER *ip_header_ptr; +UCHAR test_tail_len[] = +{ + 15, 3, 2, 11, 2, 2, +}; + + printf("NetX Test: MDNS Read Overflow Test..................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + nx_udp_socket_checksum_disable(&(mdns_0.nx_mdns_socket)); + + /* Send test packet. */ + for (i = 0; i < test_num; i ++) + { + + nx_mdns_peer_cache_clear(&mdns_0); + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + response_ptr = invalid_responses[i]; + response_len = invalid_responses_len[i]; + + /* Write the DNS response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, response_ptr, response_len); + response_len -= test_tail_len[i]; + + ip_header_ptr = (NX_IPV4_HEADER *)(response_packet -> nx_packet_prepend_ptr + 14); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + response_packet -> nx_packet_ip_header = response_packet -> nx_packet_prepend_ptr + 14; + + /* Adjust the write pointer. */ + response_packet -> nx_packet_prepend_ptr += MDNS_START_OFFSET; + response_packet -> nx_packet_length = response_len - MDNS_START_OFFSET; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + response_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + + /* Send the UDP packet with the correct port. */ + _nx_udp_packet_receive(&ip_0, response_packet); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + if ((i < 3 && mdns_0.nx_mdns_peer_rr_count == 0x04) || + (i == 3 && mdns_0.nx_mdns_peer_rr_count == 0x03) || + (i == 4 && mdns_0.nx_mdns_peer_rr_count == 0x01) || + (i == 5 && mdns_0.nx_mdns_peer_rr_count == 0x01)) + { + error_counter++; + } + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_read_overflow_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Read Overflow Test...................................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_CLIENT */ diff --git a/test/regression/mdns_test/netx_mdns_responder_cooperating_test.c b/test/regression/mdns_test/netx_mdns_responder_cooperating_test.c new file mode 100644 index 00000000..e7288df0 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_responder_cooperating_test.c @@ -0,0 +1,431 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_SERVER && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_query; +static UCHAR mdns_response; +static UCHAR mdns_stack[DEMO_STACK_SIZE]; + +/* A DNS-SD response + rdata: "_http._tcp.local" + TTL: 4500 */ +/* Frame (112 bytes) */ +static UCHAR mdns_data_1[] = +{ +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0x62, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* .b..@... */ +0x90, 0x46, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .F...B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x4e, /* .......N */ +0x17, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5f, /* ......._ */ +0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, /* services */ +0x07, 0x5f, 0x64, 0x6e, 0x73, 0x2d, 0x73, 0x64, /* ._dns-sd */ +0x04, 0x5f, 0x75, 0x64, 0x70, 0x05, 0x6c, 0x6f, /* ._udp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, /* cal..... */ +0x00, 0x00, 0x11, 0x94, 0x00, 0x12, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* p.local. */ +}; + +/* A service response + Service: "ARMMDNSTest._ipp._tcp.local" + type: SRV + TTL: 120 */ +static UCHAR mdns_data_2[] = +{ +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x07, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xa1, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xf3, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x78, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* local. */ +}; + +/* A service response + Service: "ARMMDNSTest._ipp._tcp.local" + type: SRV + TTL: 60 */ +static UCHAR mdns_data_3[] = +{ +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x07, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xa1, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xf3, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x3c, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* local. */ +}; + +/* A service response + Service: "ARMMDNSTest._ipp._tcp.local" + type: SRV + TTL: 59 */ +static UCHAR mdns_data_4[] = +{ +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x01, 0x07, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xa1, 0x0a, 0x00, 0x00, 0x42, 0xe0, 0x00, /* .....B.. */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xf3, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x3b, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..x..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00 /* local. */ +}; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; +static NX_PACKET *current_packet; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_responder_cooperating_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NXD_ADDRESS address; + + printf("NetX Test: MDNS Responder Cooperating Test..........................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Send MULTICAST address. */ + address.nxd_ip_version = NX_IP_VERSION_V4; + address.nxd_ip_address.v4 = NX_MDNS_IPV4_MULTICAST_ADDRESS; + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, mdns_stack, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + + nx_mdns_enable(&mdns_0, 0); + + + /* Create a service. */ + status += nx_mdns_service_add(&mdns_0, (CHAR *)"ARMMDNSTest", (CHAR *)"_ipp._tcp", NX_NULL, "paper=A4;version=01", 120, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Sleep 5 seconds for probing and announcement. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Reset counter. */ + mdns_query = 0; + mdns_response = 0; + + /* Inject a RR with same name(_services._dns-sd._udp), rrtype(PTR) and rrclass(1), but different rdata(_http._tcp.local). */ + /* Allocate a packet and add data with mDNS response. */ + status = nx_packet_allocate(&pool_0, ¤t_packet, NX_IPv4_UDP_PACKET, 100); + status += nx_packet_data_append(current_packet, mdns_data_1 + 42, sizeof(mdns_data_1) - 42, &pool_0, 100); + status += nxd_udp_socket_send(&mdns_0.nx_mdns_socket, current_packet, &address, 5353); + current_packet = NX_NULL; + + if(status) + error_counter++; + + /* Sleep one second and check whether any mDNS packet is sent. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* For shared RR, no action is required. */ + if(mdns_query || mdns_response) + error_counter++; + + + /* Reset counter. */ + mdns_query = 0; + mdns_response = 0; + + /* Inject a RR with the same name(ARMMDNSTest._ipp._tcp), rrtype(SRV) and rrclass(1), but different rdata(ARMMDNSTest.local). */ + /* Allocate a packet and add data with mDNS response. */ + status = nx_packet_allocate(&pool_0, ¤t_packet, NX_IPv4_UDP_PACKET, 100); + status += nx_packet_data_append(current_packet, mdns_data_2 + 42, sizeof(mdns_data_2) - 42, &pool_0, 100); + status += nxd_udp_socket_send(&mdns_0.nx_mdns_socket, current_packet, &address, 5353); + current_packet = NX_NULL; + + if(status) + error_counter++; + + /* Sleep one second and check whether any mDNS packet is sent. */ + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + /* For unique RR, probing and announcing are required. */ + if((mdns_query != 3) || (mdns_response == 0)) + error_counter++; + + /* Delete the service. */ + nx_mdns_service_delete(&mdns_0, (CHAR *)"ARMMDNSTest", (CHAR *)"_ipp._tcp", NX_NULL); + + /* Delete mdns. */ + nx_mdns_delete(&mdns_0); + + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, mdns_stack, DEMO_STACK_SIZE, "ARMMDNSTest", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + + nx_mdns_enable(&mdns_0, 0); + + + /* Create a service with the same name, rrtype and rrclass and rdata. */ + /* The received TTL is at least half the true TTL from local RR. */ + status += nx_mdns_service_add(&mdns_0, (CHAR *)"ARMMDNSTest", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 120, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Sleep 5 seconds for probing and announcement. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Reset counter. */ + mdns_query = 0; + mdns_response = 0; + + /* Inject a RR with the same name(ARMMDNSTest._ipp._tcp), rrtype(SRV) and rrclass(1) and rdata(ARMMDNSTest.local). */ + /* The received TTL(60) is at least half the true TTL(120) from local RR. */ + /* Allocate a packet and add data with mDNS response. */ + status = nx_packet_allocate(&pool_0, ¤t_packet, NX_IPv4_UDP_PACKET, 100); + status += nx_packet_data_append(current_packet, mdns_data_3 + 42, sizeof(mdns_data_3) - 42, &pool_0, 100); + status += nxd_udp_socket_send(&mdns_0.nx_mdns_socket, current_packet, &address, 5353); + current_packet = NX_NULL; + + if(status) + error_counter++; + + /* Sleep one second and check whether any mDNS packet is sent. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* No action is required. */ + if(mdns_query || mdns_response) + error_counter++; + + + /* Reset counter. */ + mdns_query = 0; + mdns_response = 0; + + /* Inject a RR with the same name(ARMMDNSTest._ipp._tcp), rrtype(SRV) and rrclass(1) and rdata(ARMMDNSTest.local). */ + /* The received TTL(59) is at least half the true TTL(120) from local RR. */ + /* Allocate a packet and add data with mDNS response. */ + status = nx_packet_allocate(&pool_0, ¤t_packet, NX_IPv4_UDP_PACKET, 100); + status += nx_packet_data_append(current_packet, mdns_data_4 + 42, sizeof(mdns_data_4) - 42, &pool_0, 100); + status += nxd_udp_socket_send(&mdns_0.nx_mdns_socket, current_packet, &address, 5353); + current_packet = NX_NULL; + + if(status) + error_counter++; + + /* Sleep one second and check whether any mDNS packet is sent. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Response is required. */ + if(mdns_query || (mdns_response == 0)) + error_counter++; + + /* Delete the service. */ + nx_mdns_service_delete(&mdns_0, (CHAR *)"ARMMDNSTest", (CHAR *)"_ipp._tcp", NX_NULL); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UCHAR *pointer; + + if(packet_ptr == current_packet) + { + + /* It is a packet need to inject. */ + /* Inject it to IP layer. */ + packet_ptr -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + return NX_FALSE; + } + + /* Get protocol. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 9; + + /* Check UDP packets only. */ + if(*pointer != NX_PROTOCOL_UDP) + return NX_TRUE; + + /* Get port. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check UDP port 5353 only. */ + if((((*pointer << 8) + *(pointer + 1)) != 5353) || + (((*(pointer + 2) << 8) + *(pointer + 3)) != 5353)) + return NX_TRUE; + + /* Get flag. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 30; + + /* Check whether this packet is the response. */ + if(((*pointer << 8) + *(pointer + 1)) == (NX_MDNS_RESPONSE_FLAG | NX_MDNS_AA_FLAG)) + mdns_response++; + else + mdns_query++; + + return NX_TRUE; + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_responder_cooperating_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Responder Cooperating Test...........................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_SERVER */ + diff --git a/test/regression/mdns_test/netx_mdns_response_with_question_test.c b/test/regression/mdns_test/netx_mdns_response_with_question_test.c new file mode 100644 index 00000000..c90b9690 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_response_with_question_test.c @@ -0,0 +1,255 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_SERVER && !defined NX_MDNS_DISABLE_CLIENT && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_data[] = +{ + 0x00, 0x00, 0x84, 0x00, 0x00, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x5f, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, 0x5f, 0x74, + 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x00, 0x00, 0x0c, 0x00, 0x01, 0x08, 0x5f, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x04, 0x5f, + 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, + 0x11, 0x94, 0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, + 0x6f, 0x6e, 0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, + 0x77, 0xc0, 0x0c +}; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; +static NX_PACKET *current_packet; +static ULONG response_received; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_response_with_question_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + response_received = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NXD_ADDRESS address; + + printf("NetX Test: MDNS Response With Question Test.........................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Add a service. */ + status += nx_mdns_service_add(&mdns_0, (CHAR *)"ARMMDNSTest", (CHAR *)"_printer._tcp", NX_NULL, "paper=A4;version=01", 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Sleep 5 seconds for probing and announcement. */ + tx_thread_sleep(500); + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Send MULTICAST address. */ + address.nxd_ip_version = NX_IP_VERSION_V4; + address.nxd_ip_address.v4 = NX_MDNS_IPV4_MULTICAST_ADDRESS; + + /* Allocate a packet and add data with mDNS response with question. */ + status = nx_packet_allocate(&pool_0, ¤t_packet, NX_IPv4_UDP_PACKET, 100); + status += nx_packet_data_append(current_packet, mdns_data, sizeof(mdns_data), &pool_0, 100); + status += nxd_udp_socket_send(&mdns_0.nx_mdns_socket, current_packet, &address, 5353); + current_packet = NX_NULL; + + if(status) + error_counter++; + + /* Sleep one second and check whether RR is stored. */ + tx_thread_sleep(100); + + if(mdns_0.nx_mdns_peer_rr_count != 1) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || response_received) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +UCHAR *pointer; + + if(packet_ptr == current_packet) + { + + /* It is a response packet. */ + /* Inject it to IP layer. */ + packet_ptr -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + return NX_FALSE; + } + + /* Get protocol. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 9; + + /* Check UDP packets only. */ + if(*pointer != NX_PROTOCOL_UDP) + return NX_TRUE; + + /* Get port. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check UDP port 5353 only. */ + if((((*pointer << 8) + *(pointer + 1)) != 5353) || + (((*(pointer + 2) << 8) + *(pointer + 3)) != 5353)) + return NX_TRUE; + + /* Get flag. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 30; + + /* Check whether this packet is the response. */ + if(((*pointer << 8) + *(pointer + 1)) == (NX_MDNS_RESPONSE_FLAG | NX_MDNS_AA_FLAG)) + response_received = 1; + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_response_with_question_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Response With Question Test..........................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_SERVER */ diff --git a/test/regression/mdns_test/netx_mdns_run_test_case.c b/test/regression/mdns_test/netx_mdns_run_test_case.c new file mode 100644 index 00000000..56b689d4 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_run_test_case.c @@ -0,0 +1,829 @@ +#include "tx_api.h" +#include "nx_api.h" + +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_IPV4 +#include "netx_mdns_test.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +#ifdef FEATURE_NX_IPV6 +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#endif /* FEATURE_NX_IPV6 */ + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define MAX_PACKET_SIZE 1600 + +/* Define the ThreadX and NetX object control blocks... */ + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +extern void test_control_return(UINT status); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT in_cleanup_process; +static TX_MUTEX pkt_capture_mutex; +static TX_SEMAPHORE pkt_count_sem; +static int pkt_capture_flag = 0; +static NX_PACKET *assemble_pkt; +static UCHAR assemble_pkt_data[MAX_PACKET_SIZE]; +static UINT fragment_cnt = 0; +static UINT service_callback_invoked; +static UINT service_callback_state; +static UINT probing_callback_invoked; +static UINT probing_callback_state; +static UCHAR mdns_stack[DEMO_STACK_SIZE]; + + +static NX_PACKET *incoming_pkts = NX_NULL; +static NX_PACKET *incoming_pkts_tail = NX_NULL; + +static VOID service_change_notify(NX_MDNS *mdns_ptr, NX_MDNS_SERVICE *service_ptr, UINT state) +{ + + /* Check state. */ + if(service_callback_state == state) + service_callback_invoked++; +} + +static void perform_check(char *pkt_data, int pkt_size, int timeout) +{ +UINT status; +NX_PACKET *current_pkt; +ULONG start_time, current_time, time_remaining; + + /* Compute the amount of time to wait for. */ + start_time = current_time = tx_time_get(); + + /* timeout value is expressed in terms of seconds. Convert it to ticks. */ + time_remaining = timeout - (current_time - start_time); + + + while(time_remaining > 0) + { + /* Wait for a packet. */ + status = tx_semaphore_get(&pkt_count_sem, time_remaining); + + if(status == NX_SUCCESS) + { + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + current_pkt = incoming_pkts; + if(incoming_pkts) + { + incoming_pkts = incoming_pkts -> nx_packet_queue_next; + } + else + { + incoming_pkts_tail = NX_NULL; + } + tx_mutex_put(&pkt_capture_mutex); + + if(current_pkt) + { + + /* A packet has been queued. Examine the content of the packet. */ + if(((pkt_size - 14) != current_pkt -> nx_packet_length) || + (memcmp(pkt_data + 14, current_pkt -> nx_packet_prepend_ptr, current_pkt -> nx_packet_length) != 0)) + { + /* Not a match. */ + + /* Compute new timeout value. */ + current_time = tx_time_get(); + time_remaining = timeout - (current_time - start_time); + if(time_remaining > 0x80000000) + { + /* Underflow */ + time_remaining = 0; + error_counter = 1; + } + nx_packet_release(current_pkt); + continue; + } + else + { + /* Packet is a match. Get out of this CHECK state. */ + time_remaining = 0; + nx_packet_release(current_pkt); + continue; + } + } + } + else + { + /* Timeout */ + error_counter = 1; + time_remaining = 0; + } + } +} + +static void decode_mdns_data(ULONG *current_len, CHAR **org_data) +{ +CHAR *character = *org_data; +CHAR compressed = NX_FALSE; +UINT labelSize; + + /* As long as we haven't found a zero terminating label */ + while(*character != '\0') + { + + labelSize = *character++; + + /* Is this a compression pointer or a count. */ + if(labelSize <= NX_MDNS_LABEL_MAX) + { + + *(assemble_pkt_data + *current_len) = *(character - 1); + *current_len = *current_len + 1; + + /* Simple count, check for space and copy the label. */ + while(labelSize > 0) + { + + *(assemble_pkt_data + *current_len) = *character++; + *current_len = *current_len + 1; + labelSize--; + } + } + else if((labelSize & NX_MDNS_COMPRESS_MASK) == NX_MDNS_COMPRESS_VALUE) + { + + /* This is a pointer, just adjust the source. */ + if(compressed == NX_FALSE) + *org_data = character + 1; + compressed = NX_TRUE; + character = assemble_pkt_data + ((labelSize & NX_MDNS_LABEL_MAX) << 8) + *character; + } + else + { + + /* Not defined, just fail */ + return; + } + } + + /* Null terminate name. */ + *(assemble_pkt_data + *current_len) = '\0'; + *current_len = *current_len + 1; + + if(compressed == NX_FALSE) + *org_data = character + 1; +} + +static void perform_check_mdns_data(char *pkt_data, int pkt_size, int timeout, int cmd) +{ +UINT status; +NX_PACKET *current_pkt; +ULONG start_time, current_time, time_remaining; +ULONG offset, assemble_len; +USHORT question_cnt; +USHORT answer_cnt; +USHORT tmp; +USHORT type; +USHORT data_len; +UCHAR *data_len_ptr; +UCHAR expect_pkt; + + /* Calculate offset. */ + if((cmd == MDNS_CHECK_DATA_V4) || (cmd == MDNS_REJECT_DATA_V4)) + offset = 28; + else + offset = 48; + + /* Whether this packet is expected. */ + if((cmd == MDNS_REJECT_DATA_V4) || (cmd == MDNS_REJECT_DATA_V6)) + expect_pkt = NX_FALSE; + else + expect_pkt = NX_TRUE; + + /* Copy DNS header. */ + memcpy(assemble_pkt_data, pkt_data + 14 + offset, 12); + assemble_len = 12; + pkt_data += (26 + offset); + + /* Get counts of question and answer. */ + question_cnt = *((USHORT*)(assemble_pkt_data + 4)); + NX_CHANGE_USHORT_ENDIAN(question_cnt); + answer_cnt = *((USHORT*)(assemble_pkt_data + 6)); + NX_CHANGE_USHORT_ENDIAN(answer_cnt); + tmp = *((USHORT*)(assemble_pkt_data + 8)); + NX_CHANGE_USHORT_ENDIAN(tmp); + answer_cnt += tmp; + tmp = *((USHORT*)(assemble_pkt_data + 10)); + NX_CHANGE_USHORT_ENDIAN(tmp); + answer_cnt += tmp; + + /* Decode questions. */ + while(question_cnt) + { + decode_mdns_data(&assemble_len, &pkt_data); + + /* Copy fixed data. */ + memcpy(assemble_pkt_data + assemble_len, pkt_data, 4); + assemble_len += 4; + pkt_data += 4; + + question_cnt--; + } + + /* Decode answers. */ + while(answer_cnt) + { + decode_mdns_data(&assemble_len, &pkt_data); + + /* Get type. */ + type = *pkt_data; + type = (type << 8) + *(pkt_data + 1); + + /* Copy fixed data. */ + memcpy(assemble_pkt_data + assemble_len, pkt_data, 10); + assemble_len += 10; + pkt_data += 10; + + /* Get data length pointer. */ + data_len_ptr = assemble_pkt_data + assemble_len - 2; + + if((type == NX_MDNS_RR_TYPE_PTR) || + (type == NX_MDNS_RR_TYPE_SRV)) + { + + /* Need decode. */ + if(type == NX_MDNS_RR_TYPE_SRV) + { + + /* The first 6 bytes of SRV are fixed. */ + memcpy(assemble_pkt_data + assemble_len, pkt_data, 6); + assemble_len += 6; + pkt_data += 6; + } + + decode_mdns_data(&assemble_len, &pkt_data); + + /* Calculate decoded data length. */ + data_len = (USHORT)(assemble_pkt_data + assemble_len - data_len_ptr) - 2; + *((USHORT*)data_len_ptr) = data_len; + NX_CHANGE_USHORT_ENDIAN(*((USHORT*)data_len_ptr)); + } + else + { + + /* Nothing to decode. */ + data_len = (*data_len_ptr << 8) | *(data_len_ptr + 1); + memcpy(assemble_pkt_data + assemble_len, pkt_data, data_len); + assemble_len += data_len; + pkt_data += data_len; + } + + answer_cnt--; + } + + /* Compute the amount of time to wait for. */ + start_time = current_time = tx_time_get(); + + /* timeout value is expressed in terms of seconds. Convert it to ticks. */ + time_remaining = timeout - (current_time - start_time); + + + while(time_remaining > 0) + { + /* Wait for a packet. */ + status = tx_semaphore_get(&pkt_count_sem, time_remaining); + + if(status == NX_SUCCESS) + { + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + current_pkt = incoming_pkts; + if(incoming_pkts) + { + incoming_pkts = incoming_pkts -> nx_packet_queue_next; + } + else + { + incoming_pkts_tail = NX_NULL; + } + tx_mutex_put(&pkt_capture_mutex); + + if(current_pkt) + { + + /* A packet has been queued. Examine the content of the packet. */ + if((assemble_len != current_pkt -> nx_packet_length - offset) || + (memcmp(assemble_pkt_data, current_pkt -> nx_packet_prepend_ptr + offset, assemble_len) != 0)) + { + /* Not a match. */ + + /* Compute new timeout value. */ + current_time = tx_time_get(); + time_remaining = timeout - (current_time - start_time); + if((time_remaining > 0x80000000) && (expect_pkt == NX_TRUE)) + { + /* Underflow */ + time_remaining = 0; + error_counter = 1; + } + nx_packet_release(current_pkt); + continue; + } + else + { + /* Packet is a match. Get out of this CHECK state. */ + time_remaining = 0; + nx_packet_release(current_pkt); + + if(expect_pkt == NX_FALSE) + error_counter = 1; + continue; + } + } + } + else + { + /* Timeout */ + if(expect_pkt == NX_TRUE) + error_counter = 1; + time_remaining = 0; + } + } +} + +static void perform_check_mdns_any(int pkt_size, int timeout, int cmd) +{ +UINT status; +NX_PACKET *current_pkt; +ULONG start_time, current_time, time_remaining; +ULONG offset; +USHORT target_flags = pkt_size; +USHORT pkt_flags; +USHORT src_port, dst_port; +UCHAR expect_pkt; + + /* Calculate offset. */ + if((cmd == MDNS_CHECK_ANY_V4) || (cmd == MDNS_REJECT_ANY_V4)) + offset = 20; + else + offset = 40; + + /* Whether this packet is expected. */ + if((cmd == MDNS_REJECT_ANY_V4) || (cmd == MDNS_REJECT_ANY_V6)) + expect_pkt = NX_FALSE; + else + expect_pkt = NX_TRUE; + + /* Compute the amount of time to wait for. */ + start_time = current_time = tx_time_get(); + + /* timeout value is expressed in terms of seconds. Convert it to ticks. */ + time_remaining = timeout - (current_time - start_time); + + + while(time_remaining > 0) + { + /* Wait for a packet. */ + status = tx_semaphore_get(&pkt_count_sem, time_remaining); + + if(status == NX_SUCCESS) + { + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + current_pkt = incoming_pkts; + if(incoming_pkts) + { + incoming_pkts = incoming_pkts -> nx_packet_queue_next; + } + else + { + incoming_pkts_tail = NX_NULL; + } + tx_mutex_put(&pkt_capture_mutex); + + if(current_pkt) + { + + /* Get UDP port. */ + src_port = *((USHORT*)(current_pkt -> nx_packet_prepend_ptr + offset)); + dst_port = *((USHORT*)(current_pkt -> nx_packet_prepend_ptr + offset + 2)); + + /* Change endian. */ + NX_CHANGE_USHORT_ENDIAN(src_port); + NX_CHANGE_USHORT_ENDIAN(dst_port); + + /* Get flags in packet. */ + pkt_flags = *((USHORT*)(current_pkt -> nx_packet_prepend_ptr + offset + 10)); + + /* Change endian. */ + NX_CHANGE_USHORT_ENDIAN(pkt_flags); + + /* A packet has been queued. Examine the content of the packet. */ + if((src_port != 5353) || + (dst_port != 5353) || + (pkt_flags != target_flags)) + { + /* Not a match. */ + + /* Compute new timeout value. */ + current_time = tx_time_get(); + time_remaining = timeout - (current_time - start_time); + if((time_remaining > 0x80000000) && (expect_pkt == NX_TRUE)) + { + /* Underflow */ + time_remaining = 0; + error_counter = 1; + } + nx_packet_release(current_pkt); + continue; + } + else + { + /* Packet is a match. Get out of this CHECK state. */ + time_remaining = 0; + nx_packet_release(current_pkt); + + if(expect_pkt == NX_FALSE) + error_counter = 1; + continue; + } + } + } + else + { + /* Timeout */ + if(expect_pkt == NX_TRUE) + error_counter = 1; + time_remaining = 0; + } + } +} + +static void perform_mdns_rr_check(NX_MDNS *mdns_ptr, int pkt_size, int cmd) +{ + +ULONG *head; +NX_MDNS_RR *p; +UCHAR *record_buffer; +UINT buffer_size; +UINT rr_count; + + tx_mutex_get(&mdns_ptr -> nx_mdns_mutex, TX_WAIT_FOREVER); + + /* Get buffer. */ + if(cmd == MDNS_CHECK_RR_COUNT_REMOTE) + { + record_buffer = mdns_ptr -> nx_mdns_peer_service_cache; + buffer_size = mdns_ptr -> nx_mdns_peer_service_cache_size; + } + else + { + record_buffer = mdns_ptr -> nx_mdns_local_service_cache; + buffer_size = mdns_ptr -> nx_mdns_local_service_cache_size; + } + + rr_count = 0; + + /* Get head. */ + head = (ULONG*)record_buffer; + head = (ULONG*)(*head); + + /* Loop to find record. */ + for(p = (NX_MDNS_RR*)((ULONG*)record_buffer + 1); (ULONG*)p < head; p++) + { + + /* Check whether the resource record is valid. */ + if ((p -> nx_mdns_rr_state == NX_MDNS_RR_STATE_VALID) || + (p -> nx_mdns_rr_state == NX_MDNS_RR_STATE_DELETE)) + rr_count++; + } + + if(pkt_size != rr_count) + error_counter = 1; + + tx_mutex_put(&mdns_ptr -> nx_mdns_mutex); +} + + +#ifndef NX_MDNS_DISABLE_CLIENT +static void perform_mdns_rr_data_check(NX_MDNS *mdns_ptr, char *pkt_data, int pkt_size) +{ +MDNS_RR_DATA *rr_data_ptr = (MDNS_RR_DATA*)pkt_data; +UCHAR *buffer = assemble_pkt_data; +UINT index = 0; +NX_MDNS_SERVICE service; + + /* Loop to check RR data. */ + while(pkt_size > 0) + { + + /* Get service by type and domain. */ + if(nx_mdns_service_lookup(mdns_ptr, NX_NULL, rr_data_ptr -> mdns_rr_data_type, NX_NULL, index, &service)) + error_counter++; + else + { + index++; + + /* Check name fileds. */ + if(strcmp(service.service_name, rr_data_ptr -> mdns_rr_data_name)) + error_counter++; + } + + pkt_size--; + rr_data_ptr++; + } +} +#endif /* NX_MDNS_DISABLE_CLIENT */ + + +static void inject_packet(NX_IP *ip_ptr, char *pkt_data, int pkt_size) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Now, this packet is a received one, allocate the packet and let the IP stack receives it. */ + /* Allocate a packet. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet, 0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + my_packet -> nx_packet_length = pkt_size - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length); + + /* Mark the packet as IPv6 */ + my_packet -> nx_packet_ip_version = NX_IP_VERSION_V6; + + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + + _nx_ip_packet_deferred_receive(ip_ptr, my_packet); + +} + +static void dump_packets(void) +{ + + NX_PACKET *tmp_pkt; + + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + tmp_pkt = incoming_pkts; + + while(tmp_pkt) + { + tx_semaphore_get(&pkt_count_sem, 0); + incoming_pkts = tmp_pkt -> nx_packet_queue_next; + nx_packet_release(tmp_pkt); + tmp_pkt = incoming_pkts; + } + incoming_pkts = NX_NULL; + + tx_mutex_put(&pkt_capture_mutex); +} + +void netx_mdns_probing_notify(struct NX_MDNS_STRUCT *mdns_ptr, UCHAR *name, UINT state) +{ + + + /* Check state. */ + if(probing_callback_state == state) + probing_callback_invoked++; +} + +extern ULONG test_control_successful_tests; +extern ULONG test_control_failed_tests; +void netx_mdns_run_test_case(NX_IP *ip_ptr, NX_MDNS *mdns_ptr, MDNS_TEST_SEQ *test_case, int test_case_size) +{ + +int steps; +int i; +MDNS_SERVICE *mdns_service; +MDNS_QUERY_INFO *query; +ULONG current_time; +ULONG v4_address; + + /* Init the semaphore and mutex. */ + tx_mutex_create(&pkt_capture_mutex, "TAHI PKT CAPTURE", 0); + tx_semaphore_create(&pkt_count_sem, "TAHI_PKT COUNT SEM", 0); + + + packet_process_callback = packet_process; + + in_cleanup_process = 0; + error_counter = 0; + service_callback_state = 0; + service_callback_invoked = 0; + for(steps = 0; steps < test_case_size; steps++) + { + /* If error has occured, skip all the test steps and start the cleanup process. */ + if(error_counter && !in_cleanup_process) + { + if(test_case[steps].command != CLEANUP) + continue; + } + + switch(test_case[steps].command) + { + case CLEANUP: + /* This is a marker. Nothing needs to be done here. */ + in_cleanup_process = 1; + continue; + + case TITLE: + printf("NetX Test: MDNS %s TEST", test_case[steps].pkt_data); + + /* Align the output. */ + for (i = test_case[steps].pkt_size; i <= 47; i++) + printf("."); + + /* Set the flag to queue up packets. */ + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + pkt_capture_flag = 1; + tx_mutex_put(&pkt_capture_mutex); + break; + case INJECT: + inject_packet(ip_ptr, test_case[steps].pkt_data, test_case[steps].pkt_size); + break; + case WAIT: + tx_thread_sleep(test_case[steps].timeout * NX_IP_PERIODIC_RATE); + break; + case MDNS_WAIT_TICK: + tx_thread_sleep(test_case[steps].timeout * NX_IP_PERIODIC_RATE / 100); + break; + case CHECK: + perform_check(test_case[steps].pkt_data, test_case[steps].pkt_size, test_case[steps].timeout* NX_IP_PERIODIC_RATE + NX_MDNS_TIMER_COUNT_RANGE); + break; + case MDNS_SET_IPV4_ADDRESS: + nx_ip_address_set(ip_ptr, test_case[steps].pkt_size, 0xFF000000); + break; +#if defined FEATURE_NX_IPV6 && defined NX_ENABLE_IPV6_MULTICAST + case MDNS_LLA_ADD: + nx_ip_interface_physical_address_set(ip_ptr, 0, test_case[steps].pkt_size, test_case[steps].timeout, NX_TRUE); + nxd_ipv6_address_set(ip_ptr, 0, NX_NULL, 10, NX_NULL); + break; + case MDNS_LLA_DELETE: + nxd_ipv6_address_delete(ip_ptr, 0); + break; +#endif /* FEATURE_NX_IPV6 && NX_ENABLE_IPV6_MULTICAST */ + case MDNS_CHECK_DATA_V4: + case MDNS_CHECK_DATA_V6: + case MDNS_REJECT_DATA_V4: + case MDNS_REJECT_DATA_V6: + perform_check_mdns_data(test_case[steps].pkt_data, test_case[steps].pkt_size, test_case[steps].timeout* NX_IP_PERIODIC_RATE + NX_MDNS_TIMER_COUNT_RANGE, test_case[steps].command); + break; + case MDNS_CHECK_ANY_V4: + case MDNS_CHECK_ANY_V6: + case MDNS_REJECT_ANY_V4: + case MDNS_REJECT_ANY_V6: + perform_check_mdns_any(test_case[steps].pkt_size, test_case[steps].timeout* NX_IP_PERIODIC_RATE + NX_MDNS_TIMER_COUNT_RANGE, test_case[steps].command); + break; +#ifndef NX_MDNS_DISABLE_CLIENT + case MDNS_QUERY: + query = (MDNS_QUERY_INFO *)test_case[steps].pkt_data; + nx_mdns_service_continuous_query(mdns_ptr, query -> name, query -> type, query -> sub_type); + break; + case MDNS_QUERY_HOST_ADDRESS: + nx_mdns_host_address_get(mdns_ptr, test_case[steps].pkt_data, &v4_address, NX_NULL, test_case[steps].timeout* NX_IP_PERIODIC_RATE); + break; + case MDNS_QUERY_DELETE: + nx_mdns_service_query_stop(mdns_ptr, query -> name, query -> type, query -> sub_type); + break; + case MDNS_SET_SERVICE_CALLBACK_STATE: + service_callback_state = test_case[steps].pkt_size; + service_callback_invoked = test_case[steps].timeout; + break; + case MDNS_SET_SERVICE_CALLBACK: + service_callback_state = test_case[steps].pkt_size; + service_callback_invoked = test_case[steps].timeout; + nx_mdns_service_notify_set(mdns_ptr, (ULONG)test_case[steps].pkt_data, service_change_notify); + break; + case MDNS_CHECK_SERVICE_CALLBACK_INVOKED: + if(service_callback_invoked != test_case[steps].timeout) + error_counter++; + break; + case MDNS_CHECK_RR_DATA: + perform_mdns_rr_data_check(mdns_ptr, test_case[steps].pkt_data, test_case[steps].pkt_size); + break; +#endif /* NX_MDNS_DISABLE_CLIENT */ +#ifndef NX_MDNS_DISABLE_SERVER + case MDNS_SERVICE_DELETE: + mdns_service = (MDNS_SERVICE*)test_case[steps].pkt_data; + nx_mdns_service_delete(mdns_ptr, mdns_service -> name, mdns_service -> type, mdns_service -> sub_type); + break; + case MDNS_SERVICE_ADD: + mdns_service = (MDNS_SERVICE*)test_case[steps].pkt_data; + nx_mdns_service_add(mdns_ptr, mdns_service -> name, mdns_service -> type, mdns_service -> sub_type, mdns_service -> txt, + mdns_service -> ttl, mdns_service -> priority, mdns_service -> weights, mdns_service -> port, + mdns_service -> set, mdns_service -> if_index); + break; +#endif /* NX_MDNS_DISABLE_SERVER */ + case MDNS_SET_PROBING_CALLBACK_STATE: + probing_callback_state = test_case[steps].pkt_size; + probing_callback_invoked = test_case[steps].timeout; + break; + case MDNS_CHECK_PROBING_CALLBACK_INVOKED: + if(probing_callback_invoked != test_case[steps].timeout) + error_counter++; + break; + case MDNS_TIMER_RESET: + tx_time_set(0); + break; + case MDNS_TIMER_CHECK: + current_time = tx_time_get(); + if((current_time < (ULONG)((test_case[steps].timeout - test_case[steps].pkt_size) * NX_IP_PERIODIC_RATE / 100)) || + (current_time > (ULONG)((test_case[steps].timeout + test_case[steps].pkt_size) * NX_IP_PERIODIC_RATE / 100))) + error_counter++; + break; + case MDNS_TIMER_MAX_CHECK: + current_time = tx_time_get(); + if(current_time > (ULONG)(test_case[steps].timeout * NX_IP_PERIODIC_RATE / 100)) + error_counter++; + break; + case MDNS_INTERFACE_DISABLE: + nx_mdns_disable(mdns_ptr, 0); + break; + case MDNS_INTERFACE_ENABLE: + nx_mdns_enable(mdns_ptr, 0); + break; + case MDNS_RECREATE: + { + NX_PACKET_POOL *pool_ptr = mdns_ptr -> nx_mdns_packet_pool_ptr; + UCHAR *local_buffer = mdns_ptr -> nx_mdns_local_service_cache; + UCHAR *remote_buffer = mdns_ptr -> nx_mdns_peer_service_cache; + UINT local_buffer_size = mdns_ptr -> nx_mdns_local_service_cache_size; + UINT remote_buffer_size = mdns_ptr -> nx_mdns_peer_service_cache_size; + + nx_mdns_delete(mdns_ptr); + nx_mdns_create(mdns_ptr, ip_ptr, pool_ptr, 2, mdns_stack, DEMO_STACK_SIZE, + test_case[steps].pkt_data, local_buffer, local_buffer_size, remote_buffer, remote_buffer_size, netx_mdns_probing_notify); + nx_mdns_enable(mdns_ptr, 0); + + }break; + case MDNS_CHECK_RR_COUNT_REMOTE: + case MDNS_CHECK_RR_COUNT_LOCAL: + perform_mdns_rr_check(mdns_ptr, test_case[steps].pkt_size, test_case[steps].command); + break; + case DUMP: + dump_packets(); + break; + default: + break; + } + } + /* Set the flag to queue up packets. */ + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + pkt_capture_flag = 0; + packet_process_callback = NX_NULL; + tx_mutex_put(&pkt_capture_mutex); + dump_packets(); + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + + tx_mutex_delete(&pkt_capture_mutex); + tx_semaphore_delete(&pkt_count_sem); +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + if(pkt_capture_flag == 0) + { + nx_packet_release(packet_ptr); + tx_mutex_put(&pkt_capture_mutex); + return NX_NULL; + } + + if(incoming_pkts == NX_NULL) + { + incoming_pkts = packet_ptr; + } + else + { + incoming_pkts_tail -> nx_packet_queue_next = packet_ptr; + } + incoming_pkts_tail = packet_ptr; + + packet_ptr -> nx_packet_queue_next = NX_NULL; + + tx_mutex_put(&pkt_capture_mutex); + + tx_semaphore_put(&pkt_count_sem); + + return NX_NULL; +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_second_interface_test.c b/test/regression/mdns_test/netx_mdns_second_interface_test.c new file mode 100644 index 00000000..516afd80 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_second_interface_test.c @@ -0,0 +1,282 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined NX_DISABLE_IPV4 && !defined NX_MDNS_DISABLE_SERVER && !defined NX_MDNS_DISABLE_CLIENT +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; +static CHAR host_registered = NX_FALSE; +static CHAR service_registered = NX_FALSE; +static CHAR packet_count = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static VOID probing_notify(NX_MDNS *mdns_ptr, UCHAR *name, UINT state); + + +/* Define service. */ + +#define SERVICE_INSTANCE_NAME "NETXDUO_MDNS_Test1" +#define SERVICE_TYPE_HTTP "_http._tcp" +#define SERVICE_SUB_TYPE_NULL NX_NULL +#define SERVICE_TXT_NULL NX_NULL +#define SERVICE_TTL 120 +#define SERVICE_PRIORITY 0 +#define SERVICE_WEIGHTS 0 +#define SERVICE_PORT 80 + +#define SERVICE_TYPE_IPP "_ipp._tcp" + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_second_interface_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + /* Enable IGMP processing for both IP instances. */ + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "mDNS Client", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +void thread_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + + NX_PARAMETER_NOT_USED(thread_input); + + printf("NetX Test: MDNS Second Interface Test................................"); + + /* Check early error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + advanced_packet_process_callback = my_packet_process; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_interface_status_check(&ip_0, 1, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, (UCHAR *)"NETX-MDNS-CLIENT", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, probing_notify); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 1); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register service. */ + status = nx_mdns_service_add(&mdns_0, (UCHAR *)SERVICE_INSTANCE_NAME, (UCHAR *)SERVICE_TYPE_HTTP, SERVICE_SUB_TYPE_NULL, + SERVICE_TXT_NULL, SERVICE_TTL, (USHORT)SERVICE_PRIORITY, (USHORT)SERVICE_WEIGHTS, + (USHORT)SERVICE_PORT, NX_TRUE, 1); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for host register and service register. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((packet_count == 0) || (host_registered != NX_TRUE) || (service_registered != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset packet count. */ + packet_count = 0; + + /* Perform mDNS continuous query. */ + status = nx_mdns_service_continuous_query(&mdns_0, NX_NULL, (UCHAR *)SERVICE_TYPE_IPP, NX_NULL); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Determine if the test was successful. */ + if((error_counter) || (packet_count == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + + NX_PARAMETER_NOT_USED(delay_ptr); + + /* Check the packet interface. */ + if (packet_ptr -> nx_packet_address.nx_packet_interface_ptr != &ip_ptr -> nx_ip_interface[1]) + error_counter++; + + packet_count++; + + *operation_ptr = NX_NULL; + return NX_TRUE; +} + +static VOID probing_notify(struct NX_MDNS_STRUCT *mdns_ptr, UCHAR *name, UINT state) +{ + + NX_PARAMETER_NOT_USED(mdns_ptr); + NX_PARAMETER_NOT_USED(name); + + switch(state) + { + case NX_MDNS_LOCAL_SERVICE_REGISTERED_SUCCESS: + { + service_registered = NX_TRUE; + break; + } + case NX_MDNS_LOCAL_SERVICE_REGISTERED_FAILURE: + { + service_registered = NX_FALSE; + break; + } + case NX_MDNS_LOCAL_HOST_REGISTERED_SUCCESS: + { + host_registered = NX_TRUE; + break; + } + case NX_MDNS_LOCAL_HOST_REGISTERED_FAILURE: + { + + host_registered = NX_FALSE; + break; + } + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_second_interface_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Second Interface Test................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_service_add_delete_test.c b/test/regression/mdns_test/netx_mdns_service_add_delete_test.c new file mode 100644 index 00000000..6106b610 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_service_add_delete_test.c @@ -0,0 +1,399 @@ +#include "tx_api.h" +#include "nx_api.h" +#include +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_SERVER && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_stack[DEMO_STACK_SIZE]; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_service_add_delete_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, (ULONG)(pointer + DEMO_STACK_SIZE), + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +CHAR *pointer = (CHAR*)thread_input; + + printf("NetX Test: MDNS Service Add And Delete Test.........................."); + + /* Initialize random. */ + srand((UINT)time(0)); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set pointer. */ + pointer = (CHAR*)thread_input; + + /* Initialize the buffer. */ + current_buffer_size = BUFFER_SIZE >> 1; + memset(buffer, 0xFF, BUFFER_SIZE); + + /* Create a MDNS instance. */ + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer += DEMO_STACK_SIZE; + + /* Check status. */ + if(status) + error_counter++; + + /*********************************************************/ + /* Delete the service when the MDNS function is disable. */ + /*********************************************************/ + + status = nx_mdns_service_add(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST1", (UCHAR *)"_ipp._tcp", NX_NULL, "paper=A4;version=01", 120, 0, 0, 8080, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Add duplicate service. */ + status = nx_mdns_service_add(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST1", (UCHAR *)"_ipp._tcp", NX_NULL, "paper=A4;version=01", 120, 0, 0, 8080, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status == NX_SUCCESS) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 5) + error_counter++; + + status = nx_mdns_service_add(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST2", (UCHAR *)"_ipp._tcp", "_http", "paper=A4;version=01", 120, 0, 0, 8080, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 10) + error_counter++; + + status = nx_mdns_service_add(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST3", (UCHAR *)"_http._tcp", NX_NULL, "paper=A4;version=01", 120, 0, 0, 8080, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 15) + error_counter++; + + status = nx_mdns_service_add(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST4", (UCHAR *)"_smb._tcp", NX_NULL, "paper=A4;version=01", 120, 0, 0, 8080, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 20) + error_counter++; + + status = nx_mdns_service_add(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST5", (UCHAR *)"_smb._tcp", NX_NULL, "paper=A4;version=01", 120, 0, 0, 8080, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 24) + error_counter++; + + /* Delete the service when the MDNS function is disable. */ + status = nx_mdns_service_delete(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST1", (UCHAR *)"_ipp._tcp", NX_NULL); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 20) + error_counter++; + + status = nx_mdns_service_delete(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST2", (UCHAR *)"_ipp._tcp", NX_NULL); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 14) + error_counter++; + + status = nx_mdns_service_delete(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST3", (UCHAR *)"_http._tcp", NX_NULL); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 9) + error_counter++; + + status = nx_mdns_service_delete(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST4", (UCHAR *)"_smb._tcp", NX_NULL); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 5) + error_counter++; + + status = nx_mdns_service_delete(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST5", (UCHAR *)"_smb._tcp", NX_NULL); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 0) + error_counter++; + + + /*********************************************************/ + /* Delete the service when the MDNS function is enable. */ + /*********************************************************/ + + /* Enable the MDNS function. */ + nx_mdns_enable(&mdns_0, 0); + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 2) + error_counter++; + + status = nx_mdns_service_add(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST1", (UCHAR *)"_ipp._tcp", NX_NULL, "paper=A4;version=01", 120, 0, 0, 8080, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 7) + error_counter++; + + status = nx_mdns_service_add(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST2", (UCHAR *)"_ipp._tcp", "_http", "paper=A4;version=01", 120, 0, 0, 8080, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 12) + error_counter++; + + status = nx_mdns_service_add(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST3", (UCHAR *)"_http._tcp", NX_NULL, "paper=A4;version=01", 120, 0, 0, 8080, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 17) + error_counter++; + + status = nx_mdns_service_add(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST4", (UCHAR *)"_smb._tcp", NX_NULL, "paper=A4;version=01", 120, 0, 0, 8080, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 22) + error_counter++; + + status = nx_mdns_service_add(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST5", (UCHAR *)"_smb._tcp", NX_NULL, "paper=A4;version=01", 120, 0, 0, 8080, NX_MDNS_RR_SET_UNIQUE, 0); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 26) + error_counter++; + + /* Delete the service when the MDNS function is enable. */ + status = nx_mdns_service_delete(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST1", (UCHAR *)"_ipp._tcp", NX_NULL); + + if(status) + error_counter++; + + /* Wait for sending the goodbye. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 22) + error_counter++; + + status = nx_mdns_service_delete(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST2", (UCHAR *)"_ipp._tcp", NX_NULL); + + if(status) + error_counter++; + + /* Disable the MDNS function. */ + nx_mdns_disable(&mdns_0, 0); + + /* Enable the MDNS function. */ + nx_mdns_enable(&mdns_0, 0); + + /* Wait for sending the goodbye. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 16) + error_counter++; + + /* Disable the MDNS function. */ + nx_mdns_disable(&mdns_0, 0); + + status = nx_mdns_service_delete(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST3", (UCHAR *)"_http._tcp", NX_NULL); + + if(status) + error_counter++; + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 11) + error_counter++; + + /* Enable the MDNS function. */ + nx_mdns_enable(&mdns_0, 0); + + status = nx_mdns_service_delete(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST4", (UCHAR *)"_smb._tcp", NX_NULL); + + if(status) + error_counter++; + + /* Wait for sending the goodbye. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 7) + error_counter++; + + status = nx_mdns_service_delete(&mdns_0, (UCHAR *)"NETXDUO_MDNS_TEST5", (UCHAR *)"_smb._tcp", NX_NULL); + + if(status) + error_counter++; + + /* Wait for sending the goodbye. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 2) + error_counter++; + + /* Disable the MDNS function. */ + nx_mdns_disable(&mdns_0, 0); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_service_add_delete_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Service Add And Delete Test..........................N/A\n"); + test_control_return(3); +} +#endif + diff --git a/test/regression/mdns_test/netx_mdns_service_lookup_test.c b/test/regression/mdns_test/netx_mdns_service_lookup_test.c new file mode 100644 index 00000000..fa450a9c --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_service_lookup_test.c @@ -0,0 +1,271 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_CLIENT && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR type[256]; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static CHAR mdns_data[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x1e, /* ..^..... */ +0x8f, 0xb1, 0x7a, 0xd4, 0x08, 0x00, 0x45, 0x00, /* ..z...E. */ +0x00, 0x8b, 0x76, 0xbf, 0x00, 0x00, 0xff, 0x11, /* ..v..... */ +0xa2, 0xfa, 0xc0, 0xa8, 0x00, 0x04, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0x77, /* .......w */ +0xe2, 0xa6, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x05, 0x5f, /* ......._ */ +0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, 0x74, 0x63, /* http._tc */ +0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, /* p.local. */ +0x00, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, /* ........ */ +0x00, 0x0f, 0x0c, 0x43, 0x61, 0x6e, 0x6f, 0x6e, /* ...Canon */ +0x4d, 0x46, 0x34, 0x35, 0x30, 0x30, 0x77, 0xc0, /* MF4500w. */ +0x0c, 0x06, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, /* ..router */ +0xc0, 0x17, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, /* ........ */ +0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x00, 0x04, /* .x...... */ +0xc0, 0x28, 0x00, 0x21, 0x80, 0x01, 0x00, 0x00, /* .(.!.... */ +0x00, 0x78, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, /* .x...... */ +0x00, 0x50, 0xc0, 0x37, 0xc0, 0x28, 0x00, 0x10, /* .P.7.(.. */ +0x80, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, 0x01, /* ........ */ +0x00 /* . */ +}; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_service_lookup_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192,168,0,31), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; +NX_MDNS_SERVICE service; +UINT i; +ULONG ipv4_address; + + printf("NetX Test: MDNS Service Lookup Test.................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Inject a response packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, 16, 100); + status += nx_packet_data_append(my_packet, mdns_data + 14, sizeof(mdns_data) - 14, &pool_0, 100); + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Check status. */ + if(status) + error_counter++; + + /* The service name is CanonMF4500w._http._tcp.local. */ + if(nx_mdns_service_lookup(&mdns_0, NX_NULL, "_http._tcp", NX_NULL, 0, &service) == NX_SUCCESS) + { + if(strcmp(service.service_name, "CanonMF4500w")) + error_counter++; + if(strcmp(service.service_type, "_http._tcp")) + error_counter++; + if(strcmp(service.service_domain, "local")) + error_counter++; + } + else + error_counter++; + + /* Look by wrong type. */ + if(nx_mdns_service_lookup(&mdns_0, NX_NULL, "_http1._tcp", NX_NULL, 0, &service) == NX_SUCCESS) + error_counter++; + + /* Look by wrong index. */ + for(i = 1; i < 1000; i++) + { + if(nx_mdns_service_lookup(&mdns_0, NX_NULL, "_http._tcp", NX_NULL, i, &service) == NX_SUCCESS) + error_counter++; + } + + /* Look by name and type. */ + if(nx_mdns_service_lookup(&mdns_0, "CanonMF4500w", "_http._tcp", NX_NULL, 0, &service) == NX_SUCCESS) + { + if(strcmp(service.service_name, "CanonMF4500w")) + error_counter++; + if(strcmp(service.service_type, "_http._tcp")) + error_counter++; + if(strcmp(service.service_domain, "local")) + error_counter++; + } + else + error_counter++; + + /* Look by wrong name. */ + if(nx_mdns_service_lookup(&mdns_0, "CanonMF4500w1", "_http._tcp", NX_NULL, 0, &service) == NX_SUCCESS) + error_counter++; + + /* Look by wrong index. */ + for(i = 1; i < 1000; i++) + { + if(nx_mdns_service_lookup(&mdns_0, "CanonMF4500w", "_http._tcp", NX_NULL, i, &service) == NX_SUCCESS) + error_counter++; + } + + /* Look all services. */ + if(nx_mdns_service_lookup(&mdns_0, NX_NULL, NX_NULL, NX_NULL, 0, &service) == NX_SUCCESS) + { + if(strcmp(service.service_name, "CanonMF4500w")) + error_counter++; + if(strcmp(service.service_type, "_http._tcp")) + error_counter++; + if(strcmp(service.service_domain, "local")) + error_counter++; + } + else + error_counter++; + + /* Look by wrong index. */ + for(i = 1; i < 1000; i++) + { + if(nx_mdns_service_lookup(&mdns_0, NX_NULL, NX_NULL, NX_NULL, i, &service) == NX_SUCCESS) + error_counter++; + } + + /* Check IPv4 address. */ + if(nx_mdns_host_address_get(&mdns_0, "router.local", &ipv4_address, NX_NULL, NX_NO_WAIT) == NX_SUCCESS) + { + if(ipv4_address != IP_ADDRESS(192, 168, 0, 4)) + error_counter++; + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_service_lookup_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Service Lookup Test..................................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_CLIENT */ diff --git a/test/regression/mdns_test/netx_mdns_source_address_test.c b/test/regression/mdns_test/netx_mdns_source_address_test.c new file mode 100644 index 00000000..2831433a --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_source_address_test.c @@ -0,0 +1,299 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_CLIENT && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET socket_1; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_stack[DEMO_STACK_SIZE]; +static UCHAR mdns_data[] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x11, +0x22, 0x33, 0x44, 0x58, 0x08, 0x00, 0x45, 0x00, +0x00, 0xd1, 0x00, 0x01, 0x00, 0x00, 0x80, 0x11, +0x31, 0x0f, 0x01, 0x02, 0x03, 0x05, 0x02, 0x02, +0x03, 0x04, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xbd, +0x5f, 0xe5, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x11, 0x53, /* .......S */ +0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x57, 0x65, /* imple We */ +0x62, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* b Server */ +0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, 0x04, 0x5f, /* ._http._ */ +0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, 0x61, /* tcp.loca */ +0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00, /* l....... */ +0x11, 0x94, 0x00, 0x01, 0x00, 0xc0, 0x1e, 0x00, /* ........ */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x11, 0x94, 0x00, /* ........ */ +0x02, 0xc0, 0x0c, 0xc0, 0x0c, 0x00, 0x21, 0x80, /* ......!. */ +0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x0f, 0x00, /* ....x... */ +0x00, 0x00, 0x00, 0x00, 0x50, 0x06, 0x75, 0x62, /* ....P.ub */ +0x75, 0x6e, 0x74, 0x75, 0xc0, 0x29, 0xc0, 0x5b, /* untu.).[ */ +0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, /* .......x */ +0x00, 0x10, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x02, 0x0c, 0x29, 0xff, 0xfe, 0x01, /* ....)... */ +0xd4, 0x79, 0xc0, 0x5b, 0x00, 0x01, 0x80, 0x01, /* .y.[.... */ +0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, /* ...x.... */ +0x00, 0x69, 0x09, 0x5f, 0x73, 0x65, 0x72, 0x76, /* .i._serv */ +0x69, 0x63, 0x65, 0x73, 0x07, 0x5f, 0x64, 0x6e, /* ices._dn */ +0x73, 0x2d, 0x73, 0x64, 0x04, 0x5f, 0x75, 0x64, /* s-sd._ud */ +0x70, 0xc0, 0x29, 0x00, 0x0c, 0x00, 0x01, 0x00, /* p.)..... */ +0x00, 0x11, 0x94, 0x00, 0x02, 0xc0, 0x1e /* ....... */ +}; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +static void check_empty_buffer(UCHAR *buffer_ptr, ULONG buffer_size, UCHAR expect_empty); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_source_address_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; +NXD_ADDRESS address; + + printf("NetX Test: MDNS Source Address Test.................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set callback function pointer to discard the probing and annoucning packet. */ + advanced_packet_process_callback = my_packet_process; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the UDP socket to the IP port. */ + status += nx_udp_socket_bind(&socket_1, 5353, TX_WAIT_FOREVER); + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, mdns_stack, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + + nx_mdns_enable(&mdns_0, 0); + nx_mdns_enable(&mdns_0, 1); + + /* Inject mDNS response from 1.2.3.5 to 2.2.3.4. This packet MUST be rejected. */ + /* Secion 11, page 38, RFC 6762. */ + status = nx_packet_allocate(&pool_0, &my_packet, 16, 100); + status += nx_packet_data_append(my_packet, mdns_data + 14, sizeof(mdns_data) - 14, &pool_0, 100); + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[1]; + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Check status. */ + if(status) + error_counter++; + + /* Sleep one second to then check whether it is received. */ + tx_thread_sleep(100); + check_empty_buffer(buffer + current_buffer_size, current_buffer_size, NX_TRUE); + nx_mdns_delete(&mdns_0); + + /* Initialize the buffer. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, mdns_stack, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + + nx_mdns_enable(&mdns_0, 0); + nx_mdns_enable(&mdns_0, 1); + + /* Send unicase response. */ + address.nxd_ip_version = NX_IP_VERSION_V4; + address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 4); + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv4_UDP_PACKET, 100); + status += nx_packet_data_append(my_packet, mdns_data + 42, sizeof(mdns_data) - 42, &pool_0, 100); + status += nxd_udp_socket_send(&socket_1, my_packet, &address, 5353); + + /* Check status. */ + if(status) + error_counter++; + + /* Sleep one second to then check whether it is received. */ + tx_thread_sleep(100); + check_empty_buffer(buffer + current_buffer_size, current_buffer_size, NX_FALSE); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void check_empty_buffer(UCHAR *buffer_ptr, ULONG buffer_size, UCHAR expect_empty) +{ + +ULONG *tail, *head; + + tx_mutex_get(&mdns_0.nx_mdns_mutex, TX_WAIT_FOREVER); + + /* Check head. */ + head = (ULONG*)buffer_ptr; + if((*head == (ULONG)(head + 1)) && (expect_empty == NX_FALSE)) + error_counter++; + else if((*head != (ULONG)(head + 1)) && (expect_empty == NX_TRUE)) + error_counter++; + + /* Check tail. */ + tail = (ULONG*)buffer_ptr + (buffer_size >> 2) - 1; + if((tail == (ULONG*)(*tail)) && (expect_empty == NX_FALSE)) + error_counter++; + else if((tail != (ULONG*)(*tail)) && (expect_empty == NX_TRUE)) + error_counter++; + + tx_mutex_put(&mdns_0.nx_mdns_mutex); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_IPV4_HEADER *ip_header_ptr; + + ip_header_ptr = (NX_IPV4_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + + /* Check the destination address. */ + if (ip_header_ptr -> nx_ip_header_destination_ip == NX_MDNS_IPV4_MULTICAST_ADDRESS) + { + + /* Discard probing and annoucning message to avoid affecting test. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + + return(NX_TRUE); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_source_address_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Source Address Test..................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_source_port_test.c b/test/regression/mdns_test/netx_mdns_source_port_test.c new file mode 100644 index 00000000..f505cb0c --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_source_port_test.c @@ -0,0 +1,249 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_CLIENT && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_UDP_SOCKET socket_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_data[] = +{ +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xc8, 0x00, 0x08, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x90, 0x02, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xb4, /* ........ */ +0x5a, 0xe8, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* Z....... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x04, 0x5f, /* ......._ */ +0x69, 0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, /* ipp._tcp */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, /* .local.. */ +0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x64, 0x00, /* ......d. */ +0x1d, 0x0b, 0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, /* ..ARMMDN */ +0x53, 0x54, 0x65, 0x73, 0x74, 0x04, 0x5f, 0x69, /* STest._i */ +0x70, 0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, /* pp._tcp. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, /* local..A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, 0x00, /* al..!... */ +0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, 0x00, /* ..d..... */ +0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, 0x4d, /* ..P.ARMM */ +0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, 0x05, /* DNSTest. */ +0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, 0x41, /* local..A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x04, 0x5f, 0x69, 0x70, 0x70, 0x04, /* st._ipp. */ +0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, 0x63, /* _tcp.loc */ +0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, /* al...... */ +0x00, 0x00, 0x64, 0x00, 0x01, 0x00 /* ..d... */ +}; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; +static NX_PACKET *current_packet; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_source_port_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NXD_ADDRESS address; +NX_MDNS_SERVICE service; + + + printf("NetX Test: MDNS Source Port Test....................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the UDP socket to the IP port. */ + status += nx_udp_socket_bind(&socket_0, 53, TX_WAIT_FOREVER); + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Send MULTICAST address. */ + address.nxd_ip_version = NX_IP_VERSION_V4; + address.nxd_ip_address.v4 = NX_MDNS_IPV4_MULTICAST_ADDRESS; + + /* Allocate a packet and add data with mDNS response. */ + status = nx_packet_allocate(&pool_0, ¤t_packet, NX_IPv4_UDP_PACKET, 100); + status += nx_packet_data_append(current_packet, mdns_data + 42, sizeof(mdns_data) - 42, &pool_0, 100); + status += nxd_udp_socket_send(&socket_0, current_packet, &address, 5353); + current_packet = NX_NULL; + + if(status) + error_counter++; + + /* Sleep one second and check whether RR is stored. */ + /* Multicast DNS implementations MUST silently ignore any + Multicast DNS responses they receive where the source UDP port is not 5353. */ + tx_thread_sleep(100); + + if(nx_mdns_service_lookup(&mdns_0, NX_NULL, NX_NULL, NX_NULL, 0, &service) == NX_SUCCESS) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + if(packet_ptr == current_packet) + { + + /* It is a response packet. */ + /* Inject it to IP layer. */ + packet_ptr -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + return NX_FALSE; + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_source_port_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Source Port Test.....................................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_CLIENT */ diff --git a/test/regression/mdns_test/netx_mdns_test.h b/test/regression/mdns_test/netx_mdns_test.h new file mode 100644 index 00000000..c236271a --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_test.h @@ -0,0 +1,145 @@ +#ifndef _NETX_MDNS_TEST_H_ +#define _NETX_MDNS_TEST_H_ + + +#include "tx_api.h" +#include "nx_api.h" + +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_mdns.h" + +#ifndef NX_MDNS_RR_SET_UNIQUE +#define NX_MDNS_RR_SET_UNIQUE 0 +#endif + +/* Define the test command. */ +/* basic command. */ +#define TITLE 1 /* This entry contains the name of the test. */ +#define INJECT 2 /* This entry contains packet that needs to be injected into the system.*/ +#define CHECK 3 /* This entry contains packet that needs to be matched. */ +#define WAIT 4 /* This entry is to place a wait. */ +#define DUMP 5 /* This entry flushes the incoming packet queue. */ +#define CLEANUP 6 /* This is a marker, indicating the beginning sequeuence of cleanup procedure. */ +#define N_CHECK 7 /* This entry contains packet that do not want to be received. */ + +#ifdef NX_IPSEC_ENABLE +#define D_CHECK 8 /* This entry contains packet that needs to be matched after decryption. */ +#define ASSEMBLE 9 /* This entry contains packet that needs to be assembled. */ +#define AD_CHECK 10 /* This entry contains packet that needs to be assembled and be matched after decryption. */ +#define TD_CHECK 11 /* This entry contains packet that needs to be matched after decryption which is tunneled. */ +#endif + +#define NS 12 /* NS packet. */ +#define NA 13 /* NA packet. */ +#define RS 14 /* RS packet. */ +#define ER 15 /* ECHO REPLY packet. */ +#define CLEAN_HOP_LIMIT 16 /* This is a marker, indicating the hop limit should be initial to 0xff. */ +#define NS_UNSPEC 17 /* This is a marker, indicating the NS is being check. */ +#define CHECK_V6REQUEST 18 /* This is a marker, indicating the ping6_request has been send. */ +#define REBOOT 19 /* This is a marker, indicating the reboot process. */ + +/*mDNS command. */ +#define MDNS_CHECK_DATA_V4 0x50 /* This entry contains packet that needs to be matched by IPv4 UDP data. */ +#define MDNS_CHECK_DATA_V6 0x51 /* This entry contains packet that needs to be matched by IPv6 UDP data. */ +#define MDNS_CHECK_RR_COUNT_REMOTE 0x52 /* This entry checks remote resource record count. */ +#define MDNS_CHECK_RR_COUNT_LOCAL 0x53 /* This entry checks local resource record count. */ +#define MDNS_CHECK_RR_DATA 0x54 /* This entry checks local resource record data. */ +#define MDNS_CHECK_ANY_V4 0x55 /* This entry contains packet that needs to be matched by IPv4 mDNS data. */ +#define MDNS_CHECK_ANY_V6 0x56 /* This entry contains packet that needs to be matched by IPv6 mDNS data. */ +#define MDNS_CHECK_PROBING_CALLBACK_INVOKED 0x57 /* This entry checks the value of probing callback invoked. */ +#define MDNS_CHECK_SERVICE_CALLBACK_INVOKED 0x58 /* This entry checks the value of callback invoked. */ +#define MDNS_REJECT_DATA_V4 0x59 /* This entry contains packet that is not expected matched by IPv4 UDP data. */ +#define MDNS_REJECT_DATA_V6 0x5A /* This entry contains packet that is not expected matched by IPv6 UDP data. */ +#define MDNS_REJECT_ANY_V4 0x5B /* This entry contains packet that is not expected matched by IPv4 mDNS data. */ +#define MDNS_REJECT_ANY_V6 0x5C /* This entry contains packet that is not expected matched by IPv6 mDNS data. */ +#define MDNS_SET_IPV4_ADDRESS 0x5D /* This entry sets the ipv4 address. */ +#define MDNS_SET_SERVICE_CALLBACK 0x5E /* This entry sets the service callback function. */ +#define MDNS_SET_SERVICE_CALLBACK_STATE 0x5F /* This entry sets the callback state. */ +#define MDNS_SET_PROBING_CALLBACK_STATE 0x60 /* This entry sets the probing state. */ +#define MDNS_TIMER_RESET 0x61 /* This entry resets the timer. */ +#define MDNS_TIMER_CHECK 0x62 /* This entry checks the timer. */ +#define MDNS_TIMER_MAX_CHECK 0x63 /* This entry checks the max timer. */ +#define MDNS_QUERY 0x64 /* This entry adds query to mDNS. */ +#define MDNS_QUERY_ONESHOT 0x65 /* This entry adds one-shot query to mDNS. */ +#define MDNS_QUERY_DELETE 0x66 /* This entry deletes query to mDNS. */ +#define MDNS_QUERY_HOST_ADDRESS 0x67 /* This entry adds query to mDNS. */ +#define MDNS_SERVICE_ADD 0x68 /* This entry adds a service to mDNS. */ +#define MDNS_SERVICE_DELETE 0x69 /* This entry deletes all services to mDNS. */ +#define MDNS_INTERFACE_DISABLE 0x6A /* This entry disable interface. */ +#define MDNS_INTERFACE_ENABLE 0x6B /* This entry enable interface. */ +#define MDNS_LLA_ADD 0x6C /* This entry adds link local address. */ +#define MDNS_LLA_DELETE 0x6D /* This entry deletes link local address. */ +#define MDNS_RECREATE 0x6F /* This entry deletes and creates mdns instance. */ +#define MDNS_WAIT_TICK 0x70 /* This entry sleep specified ticks. */ + + +#define MDNS_FLAG_QUERY 0x0000 /* Define flag for standard query. */ +#define MDNS_FLAG_RESPONSE 0x8400 /* Define flag for standard query response, No error. */ + + +typedef struct MDNS_TEST_SEQ_struct +{ + /* The command. Only INJECT and CHECK carries valid pkt_data and pkt_size. */ + int command; + + /* Only INJECT and CHECK carries valid pkt_data and pkt_size. */ + /* For TITLE, pkt_data carries a const string, which is used as the name of the test case. */ + char *pkt_data; + int pkt_size; + + /* Used for CHECK and WAIT. */ + /* WAIT command: wait this amount of time. */ + /* CHECK command: during the timeout period, check any incoming packets against the pkt_data in this entry. */ + int timeout; + + /*Used in D_CHECK to lookup the sa */ + /* Next layer protocol*/ + UCHAR protocol; + + /* Used when the next layer protocol is UDP*/ + ULONG src_port; + ULONG dst_port; + + /*Used when the next layer protocol is ICMP or ICMPv6*/ + UINT option; +} MDNS_TEST_SEQ; + +typedef struct MDNS_TEST_SUITE_struct +{ + MDNS_TEST_SEQ *test_case; + int *test_case_size; +} MDNS_TEST_SUITE; + +typedef struct MDNS_RR_DATA_STRUCT +{ + char *mdns_rr_data_name; + char *mdns_rr_data_type; + char *mdns_rr_data_domain_name; +}MDNS_RR_DATA; + +typedef struct MDNS_SERVICE_STRUCT +{ + char *name; + char *type; + char *sub_type; + UCHAR *txt; + ULONG ttl; + USHORT priority; + USHORT weights; + USHORT port; + UCHAR set; + UINT if_index; +}MDNS_SERVICE; + +typedef struct MDNS_QUERY_INFO_STRUCT +{ + char *name; + char *type; + char *sub_type; +}MDNS_QUERY_INFO; + +void netx_mdns_run_test_case(NX_IP *ip_ptr, NX_MDNS *mdns_ptr, MDNS_TEST_SEQ *test_case, int test_case_size); +void netx_mdns_probing_notify(struct NX_MDNS_STRUCT *mdns_ptr, UCHAR *name, UINT state); + +#endif /* __PRODUCT_NETXDUO__ */ +#endif diff --git a/test/regression/mdns_test/netx_mdns_ttl_test.c b/test/regression/mdns_test/netx_mdns_ttl_test.c new file mode 100644 index 00000000..9643e7ed --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_ttl_test.c @@ -0,0 +1,225 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_SERVER && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; +static UCHAR warning; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_ttl_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + warning = NX_FALSE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192,168,0,31), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + printf("NetX Test: MDNS TTL Test............................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increase error_counter incase packets are not received. */ + error_counter++; + + /* Set callback function pointer. */ + advanced_packet_process_callback = my_packet_process; + + /* Add service to send probing. */ + nx_mdns_service_add(&mdns_0, (CHAR *)"ARMMDNSTest", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Sleep one second. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(warning == NX_TRUE) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UCHAR ttl; +UCHAR *pointer; + + /* Get protocol. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 9; + + /* Check UDP packets only. */ + if(*pointer != NX_PROTOCOL_UDP) + return NX_TRUE; + + /* Get port. */ + pointer = packet_ptr -> nx_packet_prepend_ptr + 20; + + /* Check UDP port 5353 only. */ + if((((*pointer << 8) + *(pointer + 1)) != 5353) || + (((*(pointer + 2) << 8) + *(pointer + 3)) != 5353)) + return NX_TRUE; + + /* Packets received. */ + error_counter--; + + /* Get TTL. */ + ttl = *(packet_ptr -> nx_packet_prepend_ptr + 8); + + /* All Multicast DNS responses SHOULD be sent with IP TTL set to 255. */ + /* Section 11, page 38, RFC 6762. */ + if(ttl == 255) + warning = NX_FALSE; + else + warning = NX_TRUE; + + /* Set callback function pointer. */ + advanced_packet_process_callback = NX_NULL; + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_ttl_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS TTL Test.............................................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_SERVER */ diff --git a/test/regression/mdns_test/netx_mdns_two_buffer_test.c b/test/regression/mdns_test/netx_mdns_two_buffer_test.c new file mode 100644 index 00000000..6d81975d --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_two_buffer_test.c @@ -0,0 +1,304 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_SERVER && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static UCHAR mdns_stack[DEMO_STACK_SIZE]; +static ULONG buffer_org_head; +static ULONG buffer_org_tail; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); +static void check_empty_buffer(UCHAR *buffer_ptr, ULONG buffer_size, UCHAR expect_empty); +static void empty_buffer_init(); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_two_buffer_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192,168,0,31), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, (ULONG)(pointer + DEMO_STACK_SIZE), + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +CHAR *pointer = (CHAR*)thread_input; + + printf("NetX Test: MDNS Two Buffer Test......................................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set pointer. */ + pointer = (CHAR*)thread_input; + /* Create */ + current_buffer_size = 160; + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + + empty_buffer_init(); + +#ifndef NX_MDNS_DISABLE_SERVER + /* Buffer is too small to add a service. */ + nx_mdns_service_add(&mdns_0, (CHAR *)"ARMMDNSTest", (CHAR *)"_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Check local buffer. It must be empty. */ + check_empty_buffer(buffer, current_buffer_size, NX_TRUE); + + if(mdns_0.nx_mdns_local_rr_count != 0) + error_counter++; +#endif /* NX_MDNS_DISABLE_SERVER */ + +#ifndef NX_MDNS_DISABLE_CLIENT + /* Check remote buffer. It must be empty. */ + check_empty_buffer(buffer + current_buffer_size, current_buffer_size, NX_TRUE); + + /* Check mdns information. */ + if(mdns_0.nx_mdns_peer_rr_count != 0) + error_counter++; +#endif /* NX_MDNS_DISABLE_CLIENT */ + + /* Delete */ + nx_mdns_delete(&mdns_0); + + /* Initialize the buffer. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + + /* Enable mDNS. */ + nx_mdns_enable(&mdns_0, 0); + + empty_buffer_init(); + +#ifndef NX_MDNS_DISABLE_SERVER + /* Use local buffer. */ + nx_mdns_service_add(&mdns_0, "ARMMDNSTest", "_ipp._tcp", NX_NULL, NX_NULL, 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Check local buffer. It must not be empty. */ + check_empty_buffer(buffer, current_buffer_size, NX_FALSE); + + /* Delete the service. */ + nx_mdns_service_delete(&mdns_0, "ARMMDNSTest", "_ipp._tcp", NX_NULL); + + /* Sleep 1 second for goodbye packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check local buffer. It must be empty. */ + check_empty_buffer(buffer, current_buffer_size, NX_TRUE); + + /* Check mdns information. */ + if(mdns_0.nx_mdns_local_rr_count != 2) + error_counter++; +#endif /* NX_MDNS_DISABLE_SERVER */ + +#ifndef NX_MDNS_DISABLE_CLIENT + /* Check remote buffer. It must be empty. */ + check_empty_buffer(buffer + current_buffer_size, current_buffer_size, NX_TRUE); + + if(mdns_0.nx_mdns_peer_rr_count != 0) + error_counter++; + + /* Use remote buffer. */ + nx_mdns_service_continuous_query(&mdns_0, NX_NULL, "_printer._tcp", NX_NULL); + + /* Check local buffer. It must be empty. */ + check_empty_buffer(buffer, current_buffer_size, NX_TRUE); + + /* Check remote buffer. It must be empty. */ + check_empty_buffer(buffer + current_buffer_size, current_buffer_size, NX_FALSE); + + /* Check mdns information. */ + if(mdns_0.nx_mdns_peer_rr_count != 1) + error_counter++; + + /* Clear the peer cache. */ + nx_mdns_peer_cache_clear(&mdns_0); + + /* Check local buffer. It must be empty. */ + check_empty_buffer(buffer, current_buffer_size, NX_TRUE); + + /* Check remote buffer. It must be empty. */ + check_empty_buffer(buffer + current_buffer_size, current_buffer_size, NX_TRUE); + + /* Check mdns information. */ + if(mdns_0.nx_mdns_peer_rr_count != 0) + error_counter++; +#endif /* NX_MDNS_DISABLE_CLIENT */ + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void check_empty_buffer(UCHAR *buffer_ptr, ULONG buffer_size, UCHAR expect_empty) +{ + +ULONG *tail, *head; +ULONG expected_head, expected_tail; + + tx_mutex_get(&mdns_0.nx_mdns_mutex, TX_WAIT_FOREVER); + + head = (ULONG*)buffer_ptr; + tail = (ULONG*)buffer_ptr + (buffer_size >> 2) - 1; + + /* Get expected head and tail. */ + if(buffer_ptr == buffer) + { + expected_head = buffer_org_head; + expected_tail = buffer_org_tail; + } + else + { + expected_head = (ULONG)(head + 1); + expected_tail = (ULONG)tail; + } + + /* Check head. */ + if((*head == expected_head) && (expect_empty == NX_FALSE)) + error_counter++; + else if((*head != expected_head) && (expect_empty == NX_TRUE)) + error_counter++; + + /* Check tail. */ + if((*tail == expected_tail) && (expect_empty == NX_FALSE)) + error_counter++; + else if((*tail != expected_tail) && (expect_empty == NX_TRUE)) + error_counter++; + + tx_mutex_put(&mdns_0.nx_mdns_mutex); +} + +static void empty_buffer_init() +{ +ULONG *tail, *head; + + head = (ULONG*)buffer; + buffer_org_head = *head; + + tail = (ULONG*)buffer + (current_buffer_size >> 2) - 1; + buffer_org_tail = *tail; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_two_buffer_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS Two Buffer Test......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/mdns_test/netx_mdns_txt_notation_test.c b/test/regression/mdns_test/netx_mdns_txt_notation_test.c new file mode 100644 index 00000000..f756af7b --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_txt_notation_test.c @@ -0,0 +1,225 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_CLIENT && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static CHAR *txt = "paper=A4;version=01"; +static CHAR mdns_data[] = { +0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb, 0x00, 0x11, /* ..^..... */ +0x22, 0x33, 0x44, 0x57, 0x08, 0x00, 0x45, 0x00, /* "3DW..E. */ +0x00, 0xdf, 0x00, 0x07, 0x40, 0x00, 0xff, 0x11, /* ....@... */ +0x8f, 0xec, 0x0a, 0x00, 0x00, 0x1f, 0xe0, 0x00, /* ........ */ +0x00, 0xfb, 0x14, 0xe9, 0x14, 0xe9, 0x00, 0xcb, /* ........ */ +0x81, 0x17, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x41, /* .......A */ +0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, /* RMMDNSTe */ +0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, 0x70, /* st._http */ +0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, 0x6f, /* ._tcp.lo */ +0x63, 0x61, 0x6c, 0x00, 0x00, 0x21, 0x80, 0x01, /* cal..!.. */ +0x00, 0x00, 0x00, 0x64, 0x00, 0x19, 0x00, 0x00, /* ...d.... */ +0x00, 0x00, 0x00, 0x50, 0x0b, 0x41, 0x52, 0x4d, /* ...P.ARM */ +0x4d, 0x44, 0x4e, 0x53, 0x54, 0x65, 0x73, 0x74, /* MDNSTest */ +0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x00, 0x0b, /* .local.. */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x10, 0x80, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x14, 0x08, /* ....d... */ +0x70, 0x61, 0x70, 0x65, 0x72, 0x3d, 0x41, 0x34, /* paper=A4 */ +0x0a, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, /* .version */ +0x3d, 0x30, 0x31, 0x05, 0x5f, 0x68, 0x74, 0x74, /* =01._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00, 0x00, 0x0c, 0x00, /* ocal.... */ +0x01, 0x00, 0x00, 0x00, 0x64, 0x00, 0x1e, 0x0b, /* ....d... */ +0x41, 0x52, 0x4d, 0x4d, 0x44, 0x4e, 0x53, 0x54, /* ARMMDNST */ +0x65, 0x73, 0x74, 0x05, 0x5f, 0x68, 0x74, 0x74, /* est._htt */ +0x70, 0x04, 0x5f, 0x74, 0x63, 0x70, 0x05, 0x6c, /* p._tcp.l */ +0x6f, 0x63, 0x61, 0x6c, 0x00 /* ocal. */ +}; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_txt_notation_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_MDNS_SERVICE service; +NX_PACKET *my_packet; + + printf("NetX Test: MDNS TXT Notation Test...................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Inject a response with TXT. */ + status = nx_packet_allocate(&pool_0, &my_packet, 16, 100); + status += nx_packet_data_append(my_packet, mdns_data + 14, sizeof(mdns_data) - 14, &pool_0, 100); + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Check status. */ + if(status) + error_counter++; + + /* Sleep one second. */ + tx_thread_sleep(100); + + /* Lookup service. */ + status = nx_mdns_service_lookup(&mdns_0, NX_NULL, "_http._tcp", NX_NULL, 0, &service); + + /* Check RR and TXT. */ + if(status) + error_counter++; + else if(service.service_text == NX_NULL) + error_counter++; + else if(strcmp(service.service_text, txt)) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_txt_notation_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS TXT Notation Test....................................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_CLIENT */ diff --git a/test/regression/mdns_test/netx_mdns_txt_test.c b/test/regression/mdns_test/netx_mdns_txt_test.c new file mode 100644 index 00000000..c6b3bf58 --- /dev/null +++ b/test/regression/mdns_test/netx_mdns_txt_test.c @@ -0,0 +1,189 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && !defined NX_MDNS_DISABLE_SERVER && !defined NX_DISABLE_IPV4 +#include "nxd_mdns.h" + +#define DEMO_STACK_SIZE 2048 +#define BUFFER_SIZE 10240 +#define LOCAL_FULL_SERVICE_COUNT 16 +#define PEER_FULL_SERVICE_COUNT 16 +#define PEER_PARTIAL_SERVICE_COUNT 32 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the NetX MDNS object control blocks. */ + +static NX_MDNS mdns_0; +static UCHAR buffer[BUFFER_SIZE]; +static ULONG current_buffer_size; +static CHAR *test_strings[] = { + + /* Total length 255. */ + "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ0abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ0abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ0abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTU=12345678", + + /* Total length 256. */ + "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ0abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ0abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ0abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTU=123456789" +}; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_txt_test(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Create the test thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, NX_NULL, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + printf("NetX Test: MDNS TXT Test............................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create mDNS. */ + current_buffer_size = (BUFFER_SIZE >> 1); + status = nx_mdns_create(&mdns_0, &ip_0, &pool_0, 2, pointer, DEMO_STACK_SIZE, "NETX-MDNS", + buffer, current_buffer_size, buffer + current_buffer_size, current_buffer_size, NX_NULL); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable mDNS. */ + status = nx_mdns_enable(&mdns_0, 0); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Add services. */ + /* The TXT length is 255. */ + status = nx_mdns_service_add(&mdns_0, "test", (CHAR *)"_ipp._tcp", NX_NULL, test_strings[0], 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Check status. */ + if(status) + error_counter++; + +#ifndef NX_DISABLE_ERROR_CHECKING + /* The TXT length is 256. */ + status = nx_mdns_service_add(&mdns_0, "test1", (CHAR *)"_ipp._tcp", NX_NULL, test_strings[1], 100, 0, 0, 80, NX_MDNS_RR_SET_UNIQUE, 0); + + /* Check status. */ + if(!status) + error_counter++; +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mdns_txt_test(void *first_unused_memory) +#endif +{ + printf("NetX Test: MDNS TXT Test.............................................N/A\n"); + test_control_return(3); +} +#endif /* NX_MDNS_DISABLE_SERVER */ diff --git a/test/regression/mqtt_test/netx_mqtt_api_test.c b/test/regression/mqtt_test/netx_mqtt_api_test.c new file mode 100644 index 00000000..a1206e74 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_api_test.c @@ -0,0 +1,318 @@ +/* This NetX test concentrates on the basic IP operation. */ + +#include "nxd_mqtt_client.h" +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *ip_0_memory_ptr; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern ULONG simulated_address_msw; +extern ULONG simulated_address_lsw; +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create IP instances. */ + ip_0_memory_ptr = pointer; + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + + + +/* Define the test threads. */ +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static NXD_MQTT_CLIENT my_client; +static ULONG mqtt_stack_space[DEMO_STACK_SIZE / sizeof(ULONG)]; +static ULONG client_memory; +static void ntest_0_entry(ULONG thread_input) +{ +NXD_ADDRESS server_ip; + +UINT status; +UCHAR message[4]; + + /* Print out test information banner. */ + printf("NetX Test: MQTT API Test ............................................"); + + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test MQTT_CLIENT control block being NULL */ + status = nxd_mqtt_client_create(NX_NULL, NX_NULL, NX_NULL, 0, &ip_0, &pool_0, mqtt_stack_space, sizeof(mqtt_stack_space), MQTT_CLIENT_THREAD_PRIORITY, NX_NULL, 0); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Test IP control block being NULL */ + status = nxd_mqtt_client_create(&my_client, NX_NULL, NX_NULL, 0, /* &ip_0*/NX_NULL, &pool_0, mqtt_stack_space, sizeof(mqtt_stack_space), MQTT_CLIENT_THREAD_PRIORITY, NX_NULL, 0); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Test packet_pool control block being NULL */ + status = nxd_mqtt_client_create(&my_client, NX_NULL, NX_NULL, 0, &ip_0, NX_NULL/*&pool_0*/, mqtt_stack_space, sizeof(mqtt_stack_space), MQTT_CLIENT_THREAD_PRIORITY, NX_NULL, 0); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Test stack space being NULL */ + status = nxd_mqtt_client_create(&my_client, NX_NULL, NX_NULL, 0, &ip_0, &pool_0, NX_NULL/*mqtt_stack_space*/, sizeof(mqtt_stack_space), MQTT_CLIENT_THREAD_PRIORITY, NX_NULL, 0); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Test stack size being 0 */ + status = nxd_mqtt_client_create(&my_client, NX_NULL, NX_NULL, 0, &ip_0, &pool_0, mqtt_stack_space, 0, MQTT_CLIENT_THREAD_PRIORITY, NX_NULL, 0); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Test ip_id != NX_IP_ID */ + ip_0.nx_ip_id = 0; + status = nxd_mqtt_client_create(&my_client, NX_NULL, NX_NULL, 0, &ip_0, &pool_0, mqtt_stack_space, sizeof(mqtt_stack_space), MQTT_CLIENT_THREAD_PRIORITY, NX_NULL, 0); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + ip_0.nx_ip_id = NX_IP_ID; + + /* Test client connect API. */ + server_ip.nxd_ip_version = 4; + /* Test MQTT_CLIENT control block being NULL */ + status = nxd_mqtt_client_connect(NX_NULL, &server_ip, NXD_MQTT_PORT, 0, 0, 0); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Test server_ip being NULL */ + status = nxd_mqtt_client_connect(&my_client, NX_NULL, NXD_MQTT_PORT, 0, 0, 0); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Test invalid port number */ + status = nxd_mqtt_client_connect(&my_client, &server_ip, 0, 0, 0, 0); + if(status != NX_INVALID_PORT) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Test invalid IP version number */ + server_ip.nxd_ip_version = 3; + status = nxd_mqtt_client_connect(&my_client, &server_ip, NXD_MQTT_PORT, 0, 0, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Restore the IP version number */ + server_ip.nxd_ip_version = 6; + + /* Test invalid username/password combination. */ + status = nxd_mqtt_client_login_set(&my_client, NX_NULL, 8, NX_NULL, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Test invalid username/password combination. */ + status = nxd_mqtt_client_login_set(&my_client, NX_NULL, 0, NX_NULL, 8); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Test invalid client_ptr. */ + status = nxd_mqtt_client_login_set(NX_NULL, NX_NULL, 0, NX_NULL, 8); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* MQTT 5.10sp4: The following test was removed because MQTT shall + allow user name being set and password not being set. */ +#if 0 + status = nxd_mqtt_client_login_set(&my_client, "username", 8, NX_NULL, 0); + if (status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + + /* Validate nxd_mqtt_client_publish */ + status = nxd_mqtt_client_publish(NX_NULL, "topic", 5, "message", 7, 0, 0, 0); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Validate topic name */ + status = nxd_mqtt_client_publish(&my_client, NX_NULL, 5, "message", 7, 0, 0, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + status = nxd_mqtt_client_publish(&my_client, "topic", 0, "message", 7, 0, 0, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Validate message length. */ + status = nxd_mqtt_client_publish(&my_client, "topic", 5, "message", 0, 0, 0, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Validate message empty and non-zero length. */ + status = nxd_mqtt_client_publish(&my_client, "topic", 5, NX_NULL, 2, 0, 0, 0); + if(status != NXD_MQTT_NOT_CONNECTED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Validate message empty and zero length. */ + status = nxd_mqtt_client_publish(&my_client, "topic", 5, NX_NULL, 0, 0, 0, 0); + if(status != NXD_MQTT_NOT_CONNECTED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Validate QoS value. */ + status = nxd_mqtt_client_publish(&my_client, "topic", 5, "message", 7, 0, 4, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + + /* Validate nxd_mqtt_client_subscribe. */ + status = nxd_mqtt_client_subscribe(NX_NULL, "topic", 5, 0); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + status = nxd_mqtt_client_subscribe(&my_client, NX_NULL, 5, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_subscribe(&my_client, "topic", 0, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_subscribe(&my_client, "topic", 5, 3); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + /* validate nxd_mqtt_client_unsubscribe. */ + status = nxd_mqtt_client_unsubscribe(NX_NULL, "topic", 5); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + status = nxd_mqtt_client_unsubscribe(&my_client, NX_NULL, 5); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_unsubscribe(&my_client, "topic", 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + + /* Validate nxd_mqtt_client_receive_notify_set. */ + status = nxd_mqtt_client_receive_notify_set(NX_NULL, NX_NULL); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Validate nxd_mqtt_client_receive_notify_set. */ + status = nxd_mqtt_client_receive_notify_set(&my_client, NX_NULL); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Validate nxd_mqtt_client_disconnect_notify_set NULL client_ptr behavior. */ + status = nxd_mqtt_client_disconnect_notify_set(NX_NULL, NX_NULL); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Validate nxd_mqtt_client_disconnect */ + status = nxd_mqtt_client_disconnect(NX_NULL); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Validate nxd_mqtt_client_delete */ + status = nxd_mqtt_client_delete(NX_NULL); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Validate nxd_mqtt_client_message_get. */ + status = nxd_mqtt_client_message_get(NX_NULL, NX_NULL, 0, NX_NULL, message, sizeof(message), NX_NULL); + if(status != NX_PTR_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_message_get(&my_client, NX_NULL, 0, NX_NULL, NX_NULL, 0, NX_NULL); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + status = nxd_mqtt_client_message_get(&my_client, NX_NULL, 0, NX_NULL, message, sizeof(message), NX_NULL); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_will_message_set(NX_NULL, NX_NULL, 0, NX_NULL, 0, 0, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + status = nxd_mqtt_client_will_message_set(&my_client, NX_NULL, 2, NX_NULL, 0, 0, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + status = nxd_mqtt_client_will_message_set(&my_client, "ab", 0, NX_NULL, 0, 0, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + status = nxd_mqtt_client_will_message_set(&my_client, "Ab", 2, NX_NULL, 0, 0, 4); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_will_message_set(&my_client, "Ab", 2, NX_NULL, 0, 2, 0); + if(status != NXD_MQTT_INVALID_PARAMETER) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} diff --git a/test/regression/mqtt_test/netx_mqtt_branch_test.c b/test/regression/mqtt_test/netx_mqtt_branch_test.c new file mode 100644 index 00000000..b33a2418 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_branch_test.c @@ -0,0 +1,398 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "tx_mutex.h" +#include "tx_thread.h" +#include "tx_timer.h" +#include "tx_event_flags.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC1 "topic1" +#define MESSAGE1 "message1" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_2; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static NXD_MQTT_CLIENT *client_ptr_test; +static UCHAR *client_memory; +static UCHAR *client_memory_test; +static CHAR *stack_ptr; +static CHAR *stack_ptr_test; +static UCHAR filler_data[PACKET_SIZE] = { 0 }; +#define CLIENT_MEMORY_SIZE 1024 +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_branch_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + status = tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a packet pool for test create. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance for test create. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 3), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + // status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; + + /* Make room for create test client memory and control block. */ + pointer += sizeof(NXD_MQTT_CLIENT); + + stack_ptr_test = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory_test = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr_test = (NXD_MQTT_CLIENT*)pointer; +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT QoS; +/* Define the test threads. */ +/* This thread sets up MQTT client and performs multiple branch tests on different APIs. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Branch Test ......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NXD_MQTT_CLOUD_ENABLE + /* Test create internal mutex already created. */ + TX_MUTEX* old_mutex_create_ptr = _tx_mutex_created_ptr; + _tx_mutex_created_ptr = &(client_ptr_test -> nxd_mqtt_protection); + status = nxd_mqtt_client_create(client_ptr_test, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_2, &pool_1, + stack_ptr_test, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory_test, CLIENT_MEMORY_SIZE); + if(status != NXD_MQTT_INTERNAL_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + _tx_mutex_created_ptr = old_mutex_create_ptr; + + /* Test create internal thread already created. */ + TX_THREAD* old_thread_create_ptr = _tx_thread_created_ptr; + _tx_thread_created_ptr = &(client_ptr_test -> nxd_mqtt_thread); + status = nxd_mqtt_client_create(client_ptr_test, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_2, &pool_1, + stack_ptr_test, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory_test, CLIENT_MEMORY_SIZE); + if(status != NXD_MQTT_INTERNAL_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + _tx_thread_created_ptr = old_thread_create_ptr; + + + /* Test create internal event flags already created. */ + TX_EVENT_FLAGS_GROUP* old_event_flags_create_ptr = _tx_event_flags_created_ptr; + _tx_event_flags_created_ptr = &(client_ptr_test -> nxd_mqtt_events); + status = nxd_mqtt_client_create(client_ptr_test, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_2, &pool_1, + stack_ptr_test, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory_test, CLIENT_MEMORY_SIZE); + if(status != NXD_MQTT_INTERNAL_ERROR) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + _tx_event_flags_created_ptr = old_event_flags_create_ptr; +#endif + + /* Create client for following tests. */ + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Set client state to connected. */ + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTED; + + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + QoS = 1; + + /* Test invalid mutex ptr on login_set. */ + client_ptr -> nxd_mqtt_client_mutex_ptr -> tx_mutex_id = 0; + status = nxd_mqtt_client_login_set(client_ptr, "test_user", 10, "test_pass", 10); + if(status != NXD_MQTT_MUTEX_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + client_ptr -> nxd_mqtt_client_mutex_ptr->tx_mutex_id = TX_MUTEX_ID; + + /* Test invalid mutex ptr on sub_unsub. */ + client_ptr -> nxd_mqtt_client_mutex_ptr -> tx_mutex_id = 0; + status = nxd_mqtt_client_subscribe(client_ptr, "topic", 6, 0); + if(status != NXD_MQTT_MUTEX_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + client_ptr -> nxd_mqtt_client_mutex_ptr->tx_mutex_id = TX_MUTEX_ID; + + /* Validate sub_unsub packet_allocate behavior. */ + ULONG temp_payload_size = client_ptr -> nxd_mqtt_client_packet_pool_ptr -> nx_packet_pool_payload_size; + client_ptr -> nxd_mqtt_client_packet_pool_ptr -> nx_packet_pool_payload_size = 0; + status = nxd_mqtt_client_subscribe(client_ptr, "topic", 6, 0); + if(status != NXD_MQTT_PACKET_POOL_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + client_ptr -> nxd_mqtt_client_packet_pool_ptr -> nx_packet_pool_payload_size = temp_payload_size; + + /* Validate client_connect tx_mutex_get behavior. */ + client_ptr -> nxd_mqtt_client_mutex_ptr -> tx_mutex_id = 0; + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, keepalive_value, + cleansession_value, NX_IP_PERIODIC_RATE); + if(status != NXD_MQTT_MUTEX_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + client_ptr -> nxd_mqtt_client_mutex_ptr->tx_mutex_id = TX_MUTEX_ID; + + /* Validate client_connect client already connected behavior. */ + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, keepalive_value, + cleansession_value, NX_IP_PERIODIC_RATE); + if(status != NXD_MQTT_ALREADY_CONNECTED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + // /* Validate client_connect client connecting behavior. */ + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_CONNECTING; + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, keepalive_value, + cleansession_value, NX_IP_PERIODIC_RATE); + if(status != NXD_MQTT_CONNECTING) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + // /* Validate client_connect client not idle behavior. */ + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_INITIALIZE; + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, keepalive_value, + cleansession_value, NX_IP_PERIODIC_RATE); + if(status != NXD_MQTT_INVALID_STATE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + // /* Set client state to idle for remaining connect tests. */ + client_ptr -> nxd_mqtt_client_state = NXD_MQTT_CLIENT_STATE_IDLE; + + /* Validate socket_connect NX_IN_PROGRESS */ + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, keepalive_value, + cleansession_value, NX_IP_PERIODIC_RATE); + if(status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + // /* Validate socket_connect NOT NX_SUCCESS */ + UINT old_tcp_socket_state = client_ptr -> nxd_mqtt_client_socket . nx_tcp_socket_state; + client_ptr -> nxd_mqtt_client_socket . nx_tcp_socket_state = NX_TCP_SYN_SENT; + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, keepalive_value, + cleansession_value, NX_IP_PERIODIC_RATE); + if(status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + // /* Validate wait option == 0 behavior and tcp_client_socket_connect not NX_SUCCUSS && not NX_IN_PROGRESS. */ + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, keepalive_value, + cleansession_value, 0); + if(status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Reset tcp socket state for remaining tests. */ + client_ptr -> nxd_mqtt_client_socket . nx_tcp_socket_state = old_tcp_socket_state; + + /* Validate wait option == 0 NX_IN_PROGRESS behavior. */ +#ifdef NX_SECURE_ENABLE + client_ptr -> nxd_mqtt_client_use_tls = 1; +#endif + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, keepalive_value, + cleansession_value, 0); + if(status != NX_IN_PROGRESS) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + \ No newline at end of file diff --git a/test/regression/mqtt_test/netx_mqtt_connack_error_test.c b/test/regression/mqtt_test/netx_mqtt_connack_error_test.c new file mode 100644 index 00000000..5e1840cd --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_connack_error_test.c @@ -0,0 +1,487 @@ +/* MQTT connect test. This test case validates MQTT client process error CONNACK. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connack_error_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connack Error Test .................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, + mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + +#ifndef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_ERROR_NOT_AUTHORIZED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + + if (status != NXD_MQTT_ERROR_NOT_AUTHORIZED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_semaphore_put(&semaphore_client_stop); + } + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xf; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xf); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 5; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} \ No newline at end of file diff --git a/test/regression/mqtt_test/netx_mqtt_connect_auth_empty_test.c b/test/regression/mqtt_test/netx_mqtt_connect_auth_empty_test.c new file mode 100644 index 00000000..93fcee40 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_connect_auth_empty_test.c @@ -0,0 +1,655 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static CHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_auth_empty_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 24, 24, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 23, 23, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +UINT keepalive_value; +UINT cleansession_value; +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect Authentication Empty Test...................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifndef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_ERROR_NOT_AUTHORIZED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_login_set(client_ptr, "", 0, "", 0); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_disconnect(client_ptr); + + /* Make sure the connection fails but TCP connnection successes. */ + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status != NXD_MQTT_COMMUNICATION_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status != NXD_MQTT_ERROR_NOT_AUTHORIZED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_login_set(client_ptr, "", 0, "", 0); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_disconnect(client_ptr); + + /* Make sure the connection fails but TCP connnection successes. */ + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status != NXD_MQTT_COMMUNICATION_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + tx_semaphore_put(&semaphore_client_stop); + } + + status += nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UCHAR *buf; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xF; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xF); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with error */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 5; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + tx_thread_sleep(1); + } +#endif + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + if ((status != NX_SUCCESS) && (status != NX_CONNECTION_PENDING)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the connect message. */ + + /* Byte 8 flag: username and password should be set. */ + content[9] |= 0xC0; + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xFF; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xFF); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + buf = content + sizeof(fixed_header) + 2 + strlen(CLIENT_ID); + *buf = 0; + *(buf + 1) = 0; + buf = buf + 2; + *buf = 0; + *(buf + 1) = 0; + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID) + 4); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, content[1] + 2)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[3] = 0; + byte[4] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(1); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + tx_thread_sleep(1); + + /* Disconnect. */ + nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_connect_auth_test.c b/test/regression/mqtt_test/netx_mqtt_connect_auth_test.c new file mode 100644 index 00000000..78ed25bc --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_connect_auth_test.c @@ -0,0 +1,663 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define USERNAME "username" +#define PASSWORD "password" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static CHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_auth_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 24, 24, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 23, 23, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +UINT keepalive_value; +UINT cleansession_value; +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect Authentication Test ........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifndef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_ERROR_NOT_AUTHORIZED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_login_set(client_ptr, USERNAME, strlen(USERNAME), PASSWORD, strlen(PASSWORD)); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_disconnect(client_ptr); + + /* Make sure the connection fails but TCP connnection successes. */ + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status != NXD_MQTT_COMMUNICATION_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status != NXD_MQTT_ERROR_NOT_AUTHORIZED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_login_set(client_ptr, USERNAME, strlen(USERNAME), PASSWORD, strlen(PASSWORD)); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_disconnect(client_ptr); + + /* Make sure the connection fails but TCP connnection successes. */ + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status != NXD_MQTT_COMMUNICATION_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + tx_semaphore_put(&semaphore_client_stop); + } + + status += nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UCHAR *buf; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xF; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xF); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with error */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 5; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + tx_thread_sleep(1); + } +#endif + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + if ((status != NX_SUCCESS) && (status != NX_CONNECTION_PENDING)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the connect message. */ + + /* Byte 8 flag: username and password should be set. */ + content[9] |= 0xC0; + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xFF; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xFF); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + buf = content + sizeof(fixed_header) + 2 + strlen(CLIENT_ID); + *buf = (strlen(USERNAME) >> 8) & 0xFF; + *(buf + 1) = (strlen(USERNAME)) & 0xFF; + memcpy(buf + 2, USERNAME, strlen(USERNAME)); + buf = buf + 2 + strlen(USERNAME); + *buf = (strlen(PASSWORD) >> 8) & 0xFF; + *(buf + 1) = (strlen(PASSWORD)) & 0xFF; + memcpy(buf + 2, PASSWORD, strlen(PASSWORD)); + + + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID) + 4 + strlen(USERNAME) + strlen(PASSWORD)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, content[1] + 2)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[3] = 0; + byte[4] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(1); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + tx_thread_sleep(1); + + /* Disconnect. */ + nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_connect_non_block_2_test.c b/test/regression/mqtt_test/netx_mqtt_connect_non_block_2_test.c new file mode 100644 index 00000000..017f785c --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_connect_non_block_2_test.c @@ -0,0 +1,489 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_EXTENDED_NOTIFY_SUPPORT +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 4 +#else +#define TEST_LOOP 2 +#endif + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG connected = NX_FALSE; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); +static void mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr, UINT status, VOID *context); +static void mqtt_disconnect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_non_block_2_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UCHAR content[100]; +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect Non Block Test 2............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, NX_NULL, 0); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + client_ptr -> nxd_mqtt_connect_notify = mqtt_connect_notify; + nxd_mqtt_client_disconnect_notify_set(client_ptr, mqtt_disconnect_notify); + + for (i = 0; i < TEST_LOOP; i++) + { + + if (i < 2) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, 0); + +#ifndef NXD_MQTT_REQUIRE_TLS + if (status != NX_IN_PROGRESS) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, 0); + + if (status != NX_IN_PROGRESS) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i >= 2) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i >= 2) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i < 2) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i >= 2) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xf; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xf); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i >= 2) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + + if (i % 2 == 0) + { + + /* Response with SUCCESS */ + byte[3] = 0; + } + else + { + + /* Response with ERROR */ + byte[3] = 3; + } + + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i < 2) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i >= 2) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + if (i % 2 == 0) + { + + /* Check connected flag. */ + if (connected == NX_FALSE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + if (connected == NX_TRUE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + nxd_mqtt_client_disconnect(client_ptr); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr, UINT status, VOID *context) +{ + + /* Check status. */ + if (status == NXD_MQTT_SUCCESS) + { + connected = NX_TRUE; + } +} + +static void mqtt_disconnect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr) +{ + + /* Check status. */ + connected = NX_FALSE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_non_block_2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect Non Block Test 2.............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/mqtt_test/netx_mqtt_connect_non_block_test.c b/test/regression/mqtt_test/netx_mqtt_connect_non_block_test.c new file mode 100644 index 00000000..79fc24cc --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_connect_non_block_test.c @@ -0,0 +1,526 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_EXTENDED_NOTIFY_SUPPORT +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG connected = NX_FALSE; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); +static void mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr, UINT status, VOID *context); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_non_block_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect Non Block Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, NX_NULL, 0); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + client_ptr-> nxd_mqtt_connect_notify = mqtt_connect_notify; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, 0); + +#ifndef NXD_MQTT_REQUIRE_TLS + if (status != NX_IN_PROGRESS) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, 0); + + if (status != NX_IN_PROGRESS) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + { + + /* Wait for connecting. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check connected flag. */ + if (connected == NX_FALSE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + nxd_mqtt_client_disconnect(client_ptr); + } + + tx_semaphore_put(&semaphore_client_stop); + } + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xf; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xf); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + + +static void mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr, UINT status, VOID *context) +{ + + /* Check status. */ + if (status == NXD_MQTT_SUCCESS) + { + connected = NX_TRUE; + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_non_block_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect Non Block Test...............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/mqtt_test/netx_mqtt_connect_packet_send_failure_test.c b/test/regression/mqtt_test/netx_mqtt_connect_packet_send_failure_test.c new file mode 100644 index 00000000..ef7d1c95 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_connect_packet_send_failure_test.c @@ -0,0 +1,383 @@ +/* MQTT connect packet send test. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 1 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +static UCHAR filler_data[PACKET_SIZE] = { 0 }; +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_packet_send_failure_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect Packet Send Failure Test ........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, + mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + /* Validate invalid length behavior. */ + client_ptr -> nxd_mqtt_client_will_topic = "hacker_topic\r\n"; + client_ptr -> nxd_mqtt_client_will_topic_length = 127 * 127 * 127 * 127; + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + /* Post test cleanup... */ + client_ptr -> nxd_mqtt_client_will_topic = ""; + client_ptr -> nxd_mqtt_client_will_topic_length = 0; + } + + tx_semaphore_put(&semaphore_client_stop); + } + nxd_mqtt_client_delete(client_ptr); + + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +// #ifdef NXD_MQTT_REQUIRE_TLS +// if (i == 1) +// #endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + + tx_thread_sleep(1); + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} \ No newline at end of file diff --git a/test/regression/mqtt_test/netx_mqtt_connect_test.c b/test/regression/mqtt_test/netx_mqtt_connect_test.c new file mode 100644 index 00000000..608284be --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_connect_test.c @@ -0,0 +1,507 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +static UINT disconnect_notify_called = 0; + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static VOID disconnect_notify(NXD_MQTT_CLIENT *client_ptr); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect Test ........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, + mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + nxd_mqtt_client_disconnect_notify_set(client_ptr, disconnect_notify); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + +#ifndef NXD_MQTT_REQUIRE_TLS + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + nxd_mqtt_client_delete(client_ptr); + + /* Verify disconnect callback function. */ + if (disconnect_notify_called == 0) + { + error_counter++; + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xf; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xf); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(1); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + +static VOID disconnect_notify(NXD_MQTT_CLIENT *client_ptr) +{ + disconnect_notify_called++; +} \ No newline at end of file diff --git a/test/regression/mqtt_test/netx_mqtt_connect_v6_test.c b/test/regression/mqtt_test/netx_mqtt_connect_v6_test.c new file mode 100644 index 00000000..4c2d79a0 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_connect_v6_test.c @@ -0,0 +1,555 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); +#define DEMO_STACK_SIZE 2048 + + +#define NUM_PACKETS 30 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define CLIENT_ID "1234" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; +static UCHAR pool_area[PACKET_POOL_SIZE]; + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +#define PRIMARY_INTERFACE 0 + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_v6_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + +UINT ip0_primary_linklocal_address_index; +UINT ip0_primary_global_address_index; + + +UINT ip1_primary_linklocal_address_index; +UINT ip1_primary_global_address_index; + + +NXD_ADDRESS ip_address; +//NXD_ADDRESS ip1_primary_global_address; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pool_area, PACKET_POOL_SIZE); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + nxd_ipv6_enable(&ip_0); + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable IPv6 */ + nxd_ipv6_enable(&ip_1); + + + /* Set IPv6 address on ip_1. */ + + /* Set ip_0 primary link local address. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, NX_NULL, 10, &ip0_primary_linklocal_address_index); + if (status) + error_counter++; + + /* Set ip_1 primary link local address. */ + status = nxd_ipv6_address_set(&ip_1, PRIMARY_INTERFACE, NX_NULL, 10, &ip1_primary_linklocal_address_index); + if (status) + error_counter++; + + + + /* Set ip_0 primary interface global address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x20010000; + ip_address.nxd_ip_address.v6[1] = 0; + ip_address.nxd_ip_address.v6[2] = 0; + ip_address.nxd_ip_address.v6[3] = 4; + + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &ip_address, 64, &ip0_primary_global_address_index); + + if (status) + error_counter++; + + /* Set ip_1 primary interface global address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x20010000; + ip_address.nxd_ip_address.v6[1] = 0; + ip_address.nxd_ip_address.v6[2] = 0; + ip_address.nxd_ip_address.v6[3] = 5; + + status = nxd_ipv6_address_set(&ip_1, PRIMARY_INTERFACE, &ip_address, 64, &ip1_primary_global_address_index); + + if (status) + error_counter++; + + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect V6 Test ....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait 5 seconds for the IP thread to finish its initilization and + for the IPv6 stack to finish DAD process. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, + mqtt_memory, sizeof(mqtt_memory)); + if(status) + error_counter++; + tx_thread_sleep(1); + + server_address.nxd_ip_version = 6; + server_address.nxd_ip_address.v6[0] = 0x20010000; + server_address.nxd_ip_address.v6[1] = 0; + server_address.nxd_ip_address.v6[2] = 0; + server_address.nxd_ip_address.v6[3] = 5; + + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifndef NXD_MQTT_REQUIRE_TLS + if (status) + error_counter++; +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + error_counter++; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + + if (status) + error_counter++; + } +#endif + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + nxd_mqtt_client_delete(client_ptr); + + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + /* Accept a connection from client socket. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE * 2); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + error_counter++; + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + error_counter++; + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xf; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xf); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + error_counter++; + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + error_counter++; + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + error_counter++; + + tx_thread_sleep(1); + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + diff --git a/test/regression/mqtt_test/netx_mqtt_connect_will_message_test.c b/test/regression/mqtt_test/netx_mqtt_connect_will_message_test.c new file mode 100644 index 00000000..8efad1c6 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_connect_will_message_test.c @@ -0,0 +1,525 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_will_message_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +#define WILL_TOPIC "topic" +#define WILL_MESSAGE "message" +static UINT will_QoS = 1; +static UINT will_retain = 1; + +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect Will Message Test ..........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, + mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + /* Set will topic with Will topic with message. */ + status = nxd_mqtt_client_will_message_set(client_ptr, WILL_TOPIC, strlen(WILL_TOPIC), WILL_MESSAGE, + strlen(WILL_MESSAGE), will_retain, will_QoS); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifndef NXD_MQTT_REQUIRE_TLS + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +int index; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xff; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xff); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + index = sizeof(fixed_header) + 2 + strlen(CLIENT_ID); + + /* Append Will Topic and Will Mesage. */ + content[index] = (strlen(WILL_TOPIC) >> 8) & 0xFF; + content[index + 1] = (strlen(WILL_TOPIC)) & 0xFF; + memcpy(content + index + 2, WILL_TOPIC, strlen(WILL_TOPIC)); + + index = index + 2 + strlen(WILL_TOPIC); + + content[index] = (strlen(WILL_MESSAGE) >> 8) & 0xFF; + content[index + 1] = (strlen(WILL_MESSAGE)) & 0xFF; + memcpy(content + index + 2, WILL_MESSAGE, strlen(WILL_MESSAGE)); + index = index + 2 + strlen(WILL_MESSAGE); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID) + strlen(WILL_MESSAGE) + strlen(WILL_TOPIC) + 4); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + if (will_retain) + content[9] = content[9] | (1 << 5); + + /* Set the QoS value. */ + content[9] = content[9] | (will_QoS << 3); + + /* Set the will flag. */ + content[9] = content[9] | (1 << 2); + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, index)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(1); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_connect_will_topic_only_test.c b/test/regression/mqtt_test/netx_mqtt_connect_will_topic_only_test.c new file mode 100644 index 00000000..0aa84b31 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_connect_will_topic_only_test.c @@ -0,0 +1,527 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_will_topic_only_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +#define WILL_TOPIC "topic" +#define WILL_MESSAGE "message" +static UINT will_QoS = 1; +static UINT will_retain = 1; + +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect Will Topic Only Test ........................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, + mqtt_memory, sizeof(mqtt_memory)); + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + /* Test again with no will message, no Will RETAIN flag, and QoS set to 0 */ + will_retain = 0; + will_QoS = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + /* Set will topic with Will topic with message. */ + status = nxd_mqtt_client_will_message_set(client_ptr, WILL_TOPIC, strlen(WILL_TOPIC), NX_NULL, + 0, will_retain, will_QoS); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifndef NXD_MQTT_REQUIRE_TLS + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +int index; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xff; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xff); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + index = sizeof(fixed_header) + 2 + strlen(CLIENT_ID); + + /* Append Will Topic and Will Mesage. */ + content[index] = (strlen(WILL_TOPIC) >> 8) & 0xFF; + content[index + 1] = (strlen(WILL_TOPIC)) & 0xFF; + memcpy(content + index + 2, WILL_TOPIC, strlen(WILL_TOPIC)); + + index = index + 2 + strlen(WILL_TOPIC); + content[index++] = 0; + content[index++] = 0; + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID) + strlen(WILL_TOPIC) + 2 + 2); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + if (will_retain) + content[9] = content[9] | (1 << 5); + + /* Set the QoS value. */ + content[9] = content[9] | (will_QoS << 3); + + /* Set the will flag. */ + content[9] = content[9] | (1 << 2); + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, index)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(1); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_connect_with_auth_will_test.c b/test/regression/mqtt_test/netx_mqtt_connect_with_auth_will_test.c new file mode 100644 index 00000000..1c8737b6 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_connect_with_auth_will_test.c @@ -0,0 +1,553 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define USERNAME "username" +#define PASSWORD "password" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +#define WILL_TOPIC "topic" +#define WILL_MESSAGE "message" +static UINT will_QoS = 1; +static UINT will_retain = 1; + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static CHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_connect_auth_will_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 24, 24, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 23, 23, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +UINT keepalive_value; +UINT cleansession_value; +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Connect Authentication And Will Test................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_mqtt_client_login_set(client_ptr, USERNAME, strlen(USERNAME), PASSWORD, strlen(PASSWORD)); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Set will topic with Will topic with message. */ + status = nxd_mqtt_client_will_message_set(client_ptr, WILL_TOPIC, strlen(WILL_TOPIC), WILL_MESSAGE, + strlen(WILL_MESSAGE), will_retain, will_QoS); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifndef NXD_MQTT_REQUIRE_TLS + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UCHAR *buf; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xF; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xF); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Byte 8 flag: username and password should be set. */ + content[9] |= 0xC0; + + if (will_retain) + content[9] = content[9] | (1 << 5); + + /* Set the QoS value. */ + content[9] = content[9] | (will_QoS << 3); + + /* Set the will flag. */ + content[9] = content[9] | (1 << 2); + + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xFF; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xFF); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + buf = content + sizeof(fixed_header) + 2 + strlen(CLIENT_ID); + *buf = (strlen(WILL_TOPIC) >> 8) & 0xFF; + *(buf + 1) = (strlen(WILL_TOPIC)) & 0xFF; + memcpy(buf + 2, WILL_TOPIC, strlen(WILL_TOPIC)); + + buf += (2 + strlen(WILL_TOPIC)); + *buf = (strlen(WILL_MESSAGE) >> 8) & 0xFF; + *(buf + 1) = (strlen(WILL_MESSAGE)) & 0xFF; + memcpy(buf + 2, WILL_MESSAGE, strlen(WILL_MESSAGE)); + + buf += (2 + strlen(WILL_MESSAGE)); + + *buf = (strlen(USERNAME) >> 8) & 0xFF; + *(buf + 1) = (strlen(USERNAME)) & 0xFF; + memcpy(buf + 2, USERNAME, strlen(USERNAME)); + buf = buf + 2 + strlen(USERNAME); + *buf = (strlen(PASSWORD) >> 8) & 0xFF; + *(buf + 1) = (strlen(PASSWORD)) & 0xFF; + memcpy(buf + 2, PASSWORD, strlen(PASSWORD)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID) + 4 + strlen(USERNAME) + strlen(PASSWORD)); + /* Add will topic and will message. */ + content[1] += strlen(WILL_MESSAGE) + strlen(WILL_TOPIC) + 4; + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, content[1] + 2)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with success */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[3] = 0; + byte[4] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(1); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_keepalive_test.c b/test/regression/mqtt_test/netx_mqtt_keepalive_test.c new file mode 100644 index 00000000..5b30cc20 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_keepalive_test.c @@ -0,0 +1,656 @@ +/* MQTT connect test. This test case validates MQTT client keepalive feature. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC1 "topic1" +#define MESSAGE1 "message1" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +#define CLIENT_MEMORY_SIZE 1024 +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_keepalive_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT connection_flag_value; +static UINT QoS; +static UINT retain; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Keepalive Test ......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 1; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + QoS = 1; + retain = 0; + + if (i == 0) + { + /* Sleep for 60 ticks */ + tx_thread_sleep(60); + } + + /* Issue a subscribe command. */ + status = nxd_mqtt_client_publish(client_ptr, TOPIC1, strlen(TOPIC1), MESSAGE1, strlen(MESSAGE1), retain, QoS, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Sleep for 150 ticks, expect MQTT PINGREQ */ + tx_thread_sleep(150); + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +USHORT packet_id; +UINT publish_time; +UINT ping_time; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 100); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + publish_time = tx_time_get(); + + /* construct the publish message. */ + byte = content; + *byte++ = 0x30 | ((*(packet_ptr->nx_packet_prepend_ptr) & 0x0F)); /* Publish */ + byte++; /* Skip the length field. */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + byte += strlen(TOPIC1); + if (((content[0] & 6) >> 1) != 0) + { + packet_id = packet_ptr->nx_packet_prepend_ptr[byte - content];/* Fill in packet ID MSB. */ + packet_id = (packet_id << 8) | packet_ptr->nx_packet_prepend_ptr[byte - content + 1];/* Fill in packet ID MSB. */ + *byte++ = ((packet_id >> 8) & 0xFF); + *byte++ = (packet_id & 0xFF); + } + /* Fill in the message being pulished. */ + memcpy(byte, MESSAGE1, strlen(MESSAGE1)); + byte += strlen(MESSAGE1); + + /* Fill in the QoS and Retain information. */ + content[0] = content[0] & 0xF8; + content[0] = content[0] | (QoS << 1); + if (retain) + content[0] = content[0] | 1; + + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT pubish request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + if (((content[0] & 0x6) >> 1) == 1) + { + /* QoS 1: Respond with PUBACK */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x40; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) == 2) + { + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x50; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) != 0) + { + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + { + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + nx_packet_release(packet_ptr); + } + } + + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 100); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + ping_time = tx_time_get(); + if ((packet_ptr->nx_packet_prepend_ptr[0] == 0xc0) && (packet_ptr->nx_packet_prepend_ptr[1] == 0)) + { + /* This is the ping message. */ + if ((ping_time - publish_time) > (keepalive_value * TX_TIMER_TICKS_PER_SECOND)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + packet_ptr->nx_packet_prepend_ptr[1] = 0x00; + packet_ptr->nx_packet_length = 2; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 2; + } +#endif + packet_ptr->nx_packet_prepend_ptr[0] = 0xD0; + + /* Validate that ping was sent. */ + if (client_ptr->nxd_mqtt_ping_not_responded != NX_TRUE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* response with pingresp. */ + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + { + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + nx_packet_release(packet_ptr); + } + + tx_thread_sleep(1); + + if (client_ptr->nxd_mqtt_ping_not_responded == NX_TRUE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_keepalive_timeout_test.c b/test/regression/mqtt_test/netx_mqtt_keepalive_timeout_test.c new file mode 100644 index 00000000..e4c5ec59 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_keepalive_timeout_test.c @@ -0,0 +1,641 @@ +/* MQTT connect test. This test case validates MQTT client keepalive feature. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC1 "topic1" +#define MESSAGE1 "message1" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +static int client_disconnected = 0; + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +#define CLIENT_MEMORY_SIZE 1024 +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_keepalive_timeout_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT connection_flag_value; +static UINT QoS; +static UINT retain; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Keepalive Timeout Test .............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + for (i = 0; i < TEST_LOOP; i++) + { + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 1; + cleansession_value = 0; + client_disconnected = 0; + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + QoS = 1; + retain = 0; + + if (i == 0) + { + /* Sleep for 60 ticks */ + tx_thread_sleep(60); + } + + /* Issue a subscribe command. */ + status = nxd_mqtt_client_publish(client_ptr, TOPIC1, strlen(TOPIC1), MESSAGE1, strlen(MESSAGE1), retain, QoS, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Sleep for 150 ticks, expect MQTT PINGREQ */ + tx_thread_sleep(150); + + if (client_disconnected == 0) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + + +static void ntest_1_disconnect_callback(NX_TCP_SOCKET *server_socket_ptr) +{ + + client_disconnected = 1; + + +} +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +USHORT packet_id; +UINT publish_time; +UINT ping_time; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, ntest_1_disconnect_callback); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 100); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + publish_time = tx_time_get(); + + /* construct the publish message. */ + byte = content; + *byte++ = 0x30 | ((*(packet_ptr->nx_packet_prepend_ptr) & 0x0F)); /* Publish */ + byte++; /* Skip the length field. */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + byte += strlen(TOPIC1); + if (((content[0] & 6) >> 1) != 0) + { + packet_id = packet_ptr->nx_packet_prepend_ptr[byte - content];/* Fill in packet ID MSB. */ + packet_id = (packet_id << 8) | packet_ptr->nx_packet_prepend_ptr[byte - content + 1];/* Fill in packet ID MSB. */ + *byte++ = ((packet_id >> 8) & 0xFF); + *byte++ = (packet_id & 0xFF); + } + /* Fill in the message being pulished. */ + + memcpy(byte, MESSAGE1, strlen(MESSAGE1)); + byte += strlen(MESSAGE1); + + /* Fill in the QoS and Retain information. */ + content[0] = content[0] & 0xF8; + content[0] = content[0] | (QoS << 1); + if (retain) + content[0] = content[0] | 1; + + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT pubish request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + if (((content[0] & 0x6) >> 1) == 1) + { + /* QoS 1: Respond with PUBACK */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x40; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) == 2) + { + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x50; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) != 0) + { + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + { + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + nx_packet_release(packet_ptr); + } + } + + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 100); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + ping_time = tx_time_get(); + if ((packet_ptr->nx_packet_prepend_ptr[0] == 0xc0) && (packet_ptr->nx_packet_prepend_ptr[1] == 0)) + { + /* This is the ping message. */ + if ((ping_time - publish_time) > (keepalive_value * TX_TIMER_TICKS_PER_SECOND)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Validate that ping was sent. */ + if (client_ptr->nxd_mqtt_ping_not_responded != NX_TRUE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* In this test the server does not send a pingresp. This should force the client to + timeout and closes the connection. */ + + + if (client_ptr->nxd_mqtt_ping_not_responded == NX_FALSE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(50); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_multiple_receive_test.c b/test/regression/mqtt_test/netx_mqtt_multiple_receive_test.c new file mode 100644 index 00000000..7ad46fdb --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_multiple_receive_test.c @@ -0,0 +1,751 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC "topic" +#define MESSAGE_QOS0 "MESSAGE_QOS0" +#define MESSAGE_QOS1 "MESSAGE_QOS11" +#define MESSAGE_QOS2 "MESSAGE_QOS222" + +static UINT packet_identifier = 0xbeef; + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +//NXD_MQTT_CLIENT my_client; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_multiple_receive_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + //client_ptr = &my_client; + +} + + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +static UINT keepalive_value; +static UINT cleansession_value; +#define DEMO_TIMER_EVENT 1 +#define DEMO_MESSAGE_EVENT 2 +#define DEMO_ALL_EVENTS 3 + +TX_EVENT_FLAGS_GROUP mqtt_app_flag; + +static VOID my_notify_func(NXD_MQTT_CLIENT* client_ptr, UINT number_of_messages) +{ + + tx_event_flags_set(&mqtt_app_flag, DEMO_MESSAGE_EVENT, TX_OR); + return; + +} + +static UCHAR topic[100], message[100]; +#define MQTT_CLIENT_THREAD_PRIORITY 2 +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +ULONG events; +UINT topic_length, message_length; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Multiple Receive Test................................"); + + status = tx_event_flags_create(&mqtt_app_flag, "my app event"); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + status = nxd_mqtt_client_receive_notify_set(client_ptr, my_notify_func); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Wait for incoming message. */ + tx_event_flags_get(&mqtt_app_flag, DEMO_ALL_EVENTS, TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + + status = nxd_mqtt_client_message_get(client_ptr, topic, sizeof(topic), &topic_length, message, sizeof(message), &message_length); + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if (topic_length != strlen(TOPIC) || strncmp(TOPIC, topic, topic_length) || (message_length != strlen(MESSAGE_QOS0)) || + strncmp(message, MESSAGE_QOS0, message_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Wait for incoming message. */ + tx_event_flags_get(&mqtt_app_flag, DEMO_ALL_EVENTS, TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + + status = nxd_mqtt_client_message_get(client_ptr, topic, sizeof(topic), &topic_length, message, sizeof(message), &message_length); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if (topic_length != strlen(TOPIC) || strncmp(TOPIC, topic, topic_length) || (message_length != strlen(MESSAGE_QOS1)) || + strncmp(message, MESSAGE_QOS1, message_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#if 0 + /* Wait for incoming message. */ + tx_event_flags_get(&mqtt_app_flag, DEMO_ALL_EVENTS, TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + + + status = nxd_mqtt_client_message_get(client_ptr, topic, sizeof(topic), &topic_length, message, sizeof(message), &message_length); + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if ((topic_length != strlen(TOPIC)) || strncmp(TOPIC, topic, topic_length) || (message_length != strlen(MESSAGE_QOS2)) || + strncmp(message, MESSAGE_QOS2, message_length)) + { + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + /* Check for error. */ + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT index = 0; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xf; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xf); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(50); + + /* Send a publish message with QoS 0 */ + if (i == 0) + { + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x30; + + index = 2; + byte[index++] = ((strlen(TOPIC)) >> 8) & 0xFF; + byte[index++] = (strlen(TOPIC)) & 0xFF; + memcpy(byte + index, TOPIC, strlen(TOPIC)); + + index += strlen(TOPIC); + + memcpy(byte + index, MESSAGE_QOS0, strlen(MESSAGE_QOS0)); + index += strlen(MESSAGE_QOS0); + + byte[1] = index - 2; + packet_ptr->nx_packet_length = index; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + index; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(5); + /* We dont expect anything back for QoS 0. */ + + /* Send a publish message with QoS 1 */ + if (i == 0) + { + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x32; + + index = 2; + byte[index++] = (strlen(TOPIC) >> 8) & 0xFF; + byte[index++] = strlen(TOPIC) & 0xFF; + memcpy(byte + index, TOPIC, strlen(TOPIC)); + + index += strlen(TOPIC); + byte[index++] = packet_identifier >> 8; + byte[index++] = packet_identifier & 0xFF; + + memcpy(byte + index, MESSAGE_QOS1, strlen(MESSAGE_QOS1)); + index += strlen(MESSAGE_QOS1); + + byte[1] = index - 2; + packet_ptr->nx_packet_length = index; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + index; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Expect PUBBACK */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 50); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Expect PUBBACK */ + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr->nx_packet_prepend_ptr; + if (packet_ptr->nx_packet_length != 4) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if ((byte[0] != 0x40) || (byte[1] != 2) || (byte[2] != (packet_identifier >> 8)) || (byte[3] != (packet_identifier & 0xFF))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* All deon, release the packet. */ + status = nx_packet_release(packet_ptr); + + /* Increment the packet id */ + packet_identifier++; + +#if 0 + /* Send a publish message with QoS 2 */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x34; + + index = 2; + byte[index++] = (strlen(TOPIC) >> 8) & 0xFF; + byte[index++] = strlen(TOPIC) & 0xFF; + memcpy(byte + index, TOPIC, strlen(TOPIC)); + + index += strlen(TOPIC); + byte[index++] = packet_identifier >> 8; + byte[index++] = packet_identifier & 0xFF; + + memcpy(byte + index, MESSAGE_QOS2, strlen(MESSAGE_QOS2)); + index += strlen(MESSAGE_QOS2); + + byte[1] = index - 2; + packet_ptr->nx_packet_length = index; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + index; + + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Expect PUBBACK */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr->nx_packet_prepend_ptr; + if (packet_ptr->nx_packet_length != 4) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if ((byte[0] != 0x50) || (byte[1] != 2) || (byte[2] != (packet_identifier >> 8)) || (byte[3] != (packet_identifier & 0xFF))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + /* Respond with PUBREL */ + byte[0] = 0x60; + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Expect PUBCOMP */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr->nx_packet_prepend_ptr; + if (packet_ptr->nx_packet_length != 4) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if ((byte[0] != 0x70) || (byte[1] != 2) || (byte[2] != (packet_identifier >> 8)) || (byte[3] != (packet_identifier & 0xFF))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* All deon, release the packet. */ + status = nx_packet_release(packet_ptr); + +#endif + + tx_thread_sleep(10); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_not_connected_test.c b/test/regression/mqtt_test/netx_mqtt_not_connected_test.c new file mode 100644 index 00000000..2d6454a6 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_not_connected_test.c @@ -0,0 +1,160 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_not_connected_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + +} + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +#define TOPIC "topic" +#define MESSAGE "message" +static UINT keepalive_value; +static UINT cleansession_value; +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Not Connect Test ...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, + mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + status = nxd_mqtt_client_publish(client_ptr, TOPIC, strlen(TOPIC), MESSAGE, strlen(MESSAGE), 0, 0, 1); + if(status != NXD_MQTT_NOT_CONNECTED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_subscribe(client_ptr, TOPIC, strlen(TOPIC), 0); + if(status != NXD_MQTT_NOT_CONNECTED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + status = nxd_mqtt_client_unsubscribe(client_ptr, TOPIC, strlen(TOPIC)); + if(status != NXD_MQTT_NOT_CONNECTED) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + + diff --git a/test/regression/mqtt_test/netx_mqtt_null_password_test.c b/test/regression/mqtt_test/netx_mqtt_null_password_test.c new file mode 100644 index 00000000..de4a0b92 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_null_password_test.c @@ -0,0 +1,147 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_null_password_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + + tx_thread_resume(&ntest_0); + +} + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; + + /* Print out test information banner. */ + printf("NetX Test: MQTT NULL Password Test .................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, + mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nxd_mqtt_client_login_set(client_ptr, "username", 8, NX_NULL, 0); + if (status != NX_SUCCESS) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + + diff --git a/test/regression/mqtt_test/netx_mqtt_packet_leak_test.c b/test/regression/mqtt_test/netx_mqtt_packet_leak_test.c new file mode 100644 index 00000000..e0ad23aa --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_packet_leak_test.c @@ -0,0 +1,554 @@ +/* This test case tests the packet leak issue when MQTT client received invalid packet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC1 "topic1" +#define MESSAGE1 "message1" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +#define CLIENT_MEMORY_SIZE 1024 +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_packet_leak_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT QoS; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Packet Leak Test ...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + QoS = 1; + + /* Issue a subscribe command. */ + status = nxd_mqtt_client_subscribe(client_ptr, TOPIC1, strlen(TOPIC1), QoS); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Check packet leak. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + error_counter++; + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the subscribe message. */ + byte = content; + *byte++ = 0x82; /* Subscribe */ + byte++; /* Skip the length field. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[2];/* Fill in packet ID MSB. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[3];/* Fill in packet ID LSB. */ + /* Fill in subscribe topic length MSB and LSB */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + /* Fill in the QoS byte. */ + byte += strlen(TOPIC1); + *byte++ = QoS & 0x3; + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT subscribe request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + /* Set length to an invalid value. */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x90; + byte[1] = 0x04; + byte[2] = content[2]; + byte[3] = content[3]; + byte[4] = QoS & 0x3; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 5; + packet_ptr->nx_packet_length = 5; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(5); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_publish_non_zero_packet_id_test.c b/test/regression/mqtt_test/netx_mqtt_publish_non_zero_packet_id_test.c new file mode 100644 index 00000000..d6193788 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_publish_non_zero_packet_id_test.c @@ -0,0 +1,815 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC1 "topic1" +#define MESSAGE1 "message1" +#define MESSAGE2 "message2" +#define MESSAGE3 "message3" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +#define CLIENT_MEMORY_SIZE 1024 +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_publish_non_zero_packet_id_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT connection_flag_value; +static UINT QoS; +static UINT retain; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Publish Non-Zero Packet ID Test ....................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + memset(client_ptr, 0, sizeof(NXD_MQTT_CLIENT)); + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + QoS = 1; + retain = 0; + /* Issue a publish command. */ + status = nxd_mqtt_client_publish(client_ptr, TOPIC1, strlen(TOPIC1), MESSAGE1, strlen(MESSAGE1), retain, QoS, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Set packet id 0xFFFF */ + client_ptr->nxd_mqtt_client_packet_identifier = 0xffff; + + /* Issue a publish command. */ + status = nxd_mqtt_client_publish(client_ptr, TOPIC1, strlen(TOPIC1), MESSAGE2, strlen(MESSAGE2), retain, QoS, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Issue a publish command. */ + status = nxd_mqtt_client_publish(client_ptr, TOPIC1, strlen(TOPIC1), MESSAGE3, strlen(MESSAGE3), retain, QoS, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +//static UCHAR fixed_header[] = {0x80, 0x00, /* MQTT Control Packet Type, remaining length */ +// 0x00, 0x00}; /* Packet identifier, MSB, and LSB */ + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +USHORT packet_id; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /*************************** 1st PUBLISH Message ****************************/ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the publish message. */ + byte = content; + *byte++ = 0x30 | ((*(packet_ptr->nx_packet_prepend_ptr) & 0x0F)); /* Publish */ + byte++; /* Skip the length field. */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + byte += strlen(TOPIC1); + if (((content[0] & 6) >> 1) != 0) + { + packet_id = packet_ptr->nx_packet_prepend_ptr[byte - content];/* Fill in packet ID MSB. */ + packet_id = (packet_id << 8) | packet_ptr->nx_packet_prepend_ptr[byte - content + 1];/* Fill in packet ID MSB. */ + *byte++ = ((packet_id >> 8) & 0xFF); + *byte++ = (packet_id & 0xFF); + + if (packet_id == 0) + { + printf("1st pubilsh: packet_id is zero.\n"); + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + } + /* Fill in the message being pulished. */ + memcpy(byte, MESSAGE1, strlen(MESSAGE1)); + byte += strlen(MESSAGE1); + + /* Fill in the QoS and Retain information. */ + content[0] = content[0] & 0xF8; + content[0] = content[0] | (QoS << 1); + if (retain) + content[0] = content[0] | 1; + + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT pubish request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + if (((content[0] & 0x6) >> 1) == 1) + { + /* QoS 1: Respond with PUBACK */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x40; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) == 2) + { + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x50; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) != 0) + { + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + + /*************************** 2nd PUBLISH Message ****************************/ + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the publish message. */ + byte = content; + *byte++ = 0x30 | ((*(packet_ptr->nx_packet_prepend_ptr) & 0x0F)); /* Publish */ + byte++; /* Skip the length field. */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + byte += strlen(TOPIC1); + if (((content[0] & 6) >> 1) != 0) + { + packet_id = packet_ptr->nx_packet_prepend_ptr[byte - content];/* Fill in packet ID MSB. */ + packet_id = (packet_id << 8) | packet_ptr->nx_packet_prepend_ptr[byte - content + 1];/* Fill in packet ID MSB. */ + *byte++ = ((packet_id >> 8) & 0xFF); + *byte++ = (packet_id & 0xFF); + + if (packet_id != 0xFFFF) + { + printf("2nd pubilsh: packet_id is not 0xFFFF.\n"); + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + } + /* Fill in the message being pulished. */ + memcpy(byte, MESSAGE2, strlen(MESSAGE2)); + byte += strlen(MESSAGE2); + + /* Fill in the QoS and Retain information. */ + content[0] = content[0] & 0xF8; + content[0] = content[0] | (QoS << 1); + if (retain) + content[0] = content[0] | 1; + + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT pubish request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + if (((content[0] & 0x6) >> 1) == 1) + { + /* QoS 1: Respond with PUBACK */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x40; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) == 2) + { + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x50; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) != 0) + { + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + + /*************************** 3rd PUBLISH Message ****************************/ + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the publish message. */ + byte = content; + *byte++ = 0x30 | ((*(packet_ptr->nx_packet_prepend_ptr) & 0x0F)); /* Publish */ + byte++; /* Skip the length field. */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + byte += strlen(TOPIC1); + if (((content[0] & 6) >> 1) != 0) + { + packet_id = packet_ptr->nx_packet_prepend_ptr[byte - content];/* Fill in packet ID MSB. */ + packet_id = (packet_id << 8) | packet_ptr->nx_packet_prepend_ptr[byte - content + 1];/* Fill in packet ID MSB. */ + *byte++ = ((packet_id >> 8) & 0xFF); + *byte++ = (packet_id & 0xFF); + + if (packet_id == 0) + { + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + } + /* Fill in the message being pulished. */ + memcpy(byte, MESSAGE3, strlen(MESSAGE3)); + byte += strlen(MESSAGE3); + + /* Fill in the QoS and Retain information. */ + content[0] = content[0] & 0xF8; + content[0] = content[0] | (QoS << 1); + if (retain) + content[0] = content[0] | 1; + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT pubish request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + if (((content[0] & 0x6) >> 1) == 1) + { + /* QoS 1: Respond with PUBACK */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x40; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) == 2) + { + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x50; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) != 0) + { + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + /*************************** End of Test ************************************/ + + tx_thread_sleep(1); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_publish_packet_chain_test.c b/test/regression/mqtt_test/netx_mqtt_publish_packet_chain_test.c new file mode 100644 index 00000000..0b11c9f4 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_publish_packet_chain_test.c @@ -0,0 +1,431 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); + +#if !defined(NXD_MQTT_REQUIRE_TLS) + +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC_LEN 256 +#define MESSAGE_LEN 256 +#define CLIENT_MEMORY_SIZE 1024 +#define PACKET_BUFFER_SIZE 1024 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 32 +#define PACKET_SIZE 128 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +static TX_SEMAPHORE semaphore_server_received; +static TX_SEMAPHORE semaphore_client_sent; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +static UCHAR *packet_buffer; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_publish_packet_chain_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_received, "semaphore server received", 0); + tx_semaphore_create(&semaphore_client_sent, "semaphore client sent", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + packet_buffer = pointer; + pointer += PACKET_BUFFER_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT QoS; +static UINT retain; +static UCHAR *topic; +static UCHAR *message; + +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; +NX_PACKET *temp_packets[NUM_PACKETS]; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Publish Packet Chain Test............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + error_counter++; + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + topic = packet_buffer; + message = packet_buffer + TOPIC_LEN; + + for (i = 0; i < TOPIC_LEN; i++) + { + topic[i] = i & 0xff; + message[i] = 0xff - (i & 0xff); + } + + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + QoS = 1; + retain = 0; + + for (i = 0 ; i < NUM_PACKETS - 2; i++) + { + status = nx_packet_allocate(&pool_0, &(temp_packets[i]), NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + break; + } + } + + /* Fail to append topic. */ + status = nxd_mqtt_client_publish(client_ptr, topic, TOPIC_LEN, message, MESSAGE_LEN, retain, QoS, NX_IP_PERIODIC_RATE); + if (status != NXD_MQTT_INTERNAL_ERROR) + error_counter++; + + /* Fail to append QOS. */ + status = nxd_mqtt_client_publish(client_ptr, topic, 195, message, MESSAGE_LEN, retain, QoS, NX_IP_PERIODIC_RATE); + if (status != NXD_MQTT_INTERNAL_ERROR) + error_counter++; + + /* Fail to append message. */ + status = nxd_mqtt_client_publish(client_ptr, topic, 66, message, MESSAGE_LEN, retain, QoS, NX_IP_PERIODIC_RATE); + if (status != NXD_MQTT_INTERNAL_ERROR) + error_counter++; + + for (i = 0 ; i < NUM_PACKETS - 2; i++) + { + nx_packet_release(temp_packets[i]); + } + + /* Issue a subscribe command. */ + status = nxd_mqtt_client_publish(client_ptr, topic, TOPIC_LEN, message, MESSAGE_LEN, retain, QoS, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + tx_semaphore_put(&semaphore_client_sent); + + tx_semaphore_get(&semaphore_server_received, NX_WAIT_FOREVER); + + nxd_mqtt_client_disconnect(client_ptr); + + nxd_mqtt_client_delete(client_ptr); + + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +USHORT packet_id; +UINT len, packet_len; +UCHAR control_header; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + tx_thread_sleep(1); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + if (status) + { + error_counter++; + } + else + { + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + packet_ptr = NX_NULL; + packet_len = 0; + + tx_semaphore_get(&semaphore_client_sent, NX_WAIT_FOREVER); + + while (1) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + if (status) + break; + + nx_packet_data_retrieve(packet_ptr, packet_buffer + packet_len, (ULONG *)&len); + packet_len += len; + + nx_packet_release(packet_ptr); + } + + tx_semaphore_put(&semaphore_server_received); + + /* Check the publish message. */ + + control_header = 0x30 | (packet_buffer[0] & 0x0F); /* Publish */ + len = 1 + 2 + 2 + TOPIC_LEN; /* Control header 1 + remaining length 2 + topic length 2 + topic */ + + for (i = 0 ; i < TOPIC_LEN; i++) + { + if (packet_buffer[5 + i] != (i & 0xff)) + { + error_counter++; + break; + } + } + + if (((control_header & 6) >> 1) != 0) + { + packet_id = packet_buffer[len];/* Fill in packet ID MSB. */ + packet_id = (packet_id << 8) | packet_buffer[len + 1];/* Fill in packet ID MSB. */ + len += 2; + } + + /* Check the message being pulished. */ + for (i = 0 ; i < MESSAGE_LEN; i++) + { + if (packet_buffer[len + i] != (0xff - (i & 0xff))) + { + error_counter++; + break; + } + } + + len += MESSAGE_LEN; + + /* Fill in the QoS and Retain information. */ + control_header = control_header & 0xF8; + control_header = control_header | (QoS << 1); + if (retain) + control_header = control_header | 1; + + /* Now validate message length */ + if (packet_len != len) + error_counter++; + + /* Validate the MQTT publish request. */ + if (packet_buffer[0] != control_header) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_publish_packet_chain_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: MQTT Publish Packet Chain Test............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/mqtt_test/netx_mqtt_publish_qos0_test.c b/test/regression/mqtt_test/netx_mqtt_publish_qos0_test.c new file mode 100644 index 00000000..b9065e2f --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_publish_qos0_test.c @@ -0,0 +1,582 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC1 "topic1" +#define MESSAGE1 "message1" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +#define CLIENT_MEMORY_SIZE 1024 +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_publish_QoS0_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT connection_flag_value; +static UINT QoS; +static UINT retain; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Publish QoS 0 Test..................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + error_counter++; + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + error_counter++; + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + + if (status) + error_counter++; + + QoS = 0; + retain = 0; + + /* Issue a publish command. */ + status = nxd_mqtt_client_publish(client_ptr, TOPIC1, strlen(TOPIC1), MESSAGE1, strlen(MESSAGE1), retain, QoS, 1); + if (status) + error_counter++; + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +//static UCHAR fixed_header[] = {0x80, 0x00, /* MQTT Control Packet Type, remaining length */ +// 0x00, 0x00}; /* Packet identifier, MSB, and LSB */ + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +USHORT packet_id; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + error_counter++; + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + error_counter++; + } + else + { + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + error_counter++; + } +#endif + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + error_counter++; + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + error_counter++; + + /* construct the publish message. */ + byte = content; + *byte++ = 0x30 | ((*(packet_ptr->nx_packet_prepend_ptr) & 0x0F)); /* Publish */ + byte++; /* Skip the length field. */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + byte += strlen(TOPIC1); + if (((content[0] & 6) >> 1) != 0) + { + packet_id = packet_ptr->nx_packet_prepend_ptr[byte - content];/* Fill in packet ID MSB. */ + packet_id = (packet_id << 8) | packet_ptr->nx_packet_prepend_ptr[byte - content + 1];/* Fill in packet ID MSB. */ + *byte++ = ((packet_id >> 8) & 0xFF); + *byte++ = (packet_id & 0xFF); + } + /* Fill in the message being pulished. */ + memcpy(byte, MESSAGE1, strlen(MESSAGE1)); + byte += strlen(MESSAGE1); + + /* Fill in the QoS and Retain information. */ + content[0] = content[0] & 0xF8; + content[0] = content[0] | (QoS << 1); + if (retain) + content[0] = content[0] | 1; + + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + error_counter++; + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT pubish request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + error_counter++; + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + error_counter++; + } +#endif + + if (((content[0] & 0x6) >> 1) == 1) + { + /* QoS 1: Respond with PUBACK */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x40; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) == 2) + { + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x50; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) != 0) + { + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + error_counter++; + } + + + tx_thread_sleep(1); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + diff --git a/test/regression/mqtt_test/netx_mqtt_publish_qos1_test.c b/test/regression/mqtt_test/netx_mqtt_publish_qos1_test.c new file mode 100644 index 00000000..4d160c5e --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_publish_qos1_test.c @@ -0,0 +1,580 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC1 "topic1" +#define MESSAGE1 "message1" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +#define CLIENT_MEMORY_SIZE 1024 +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_publish_QoS1_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT connection_flag_value; +static UINT QoS; +static UINT retain; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Publish QoS 1 Test..................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + error_counter++; + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + error_counter++; + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + if (status) + error_counter++; + + QoS = 1; + retain = 0; + /* Issue a subscribe command. */ + status = nxd_mqtt_client_publish(client_ptr, TOPIC1, strlen(TOPIC1), MESSAGE1, strlen(MESSAGE1), retain, QoS, 1); + if (status) + error_counter++; + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +//static UCHAR fixed_header[] = {0x80, 0x00, /* MQTT Control Packet Type, remaining length */ +// 0x00, 0x00}; /* Packet identifier, MSB, and LSB */ + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +USHORT packet_id; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + error_counter++; + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + error_counter++; + } + else + { + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + error_counter++; + } +#endif + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + error_counter++; + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + error_counter++; + + /* construct the publish message. */ + byte = content; + *byte++ = 0x30 | ((*(packet_ptr->nx_packet_prepend_ptr) & 0x0F)); /* Publish */ + byte++; /* Skip the length field. */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + byte += strlen(TOPIC1); + if (((content[0] & 6) >> 1) != 0) + { + packet_id = packet_ptr->nx_packet_prepend_ptr[byte - content];/* Fill in packet ID MSB. */ + packet_id = (packet_id << 8) | packet_ptr->nx_packet_prepend_ptr[byte - content + 1];/* Fill in packet ID MSB. */ + *byte++ = ((packet_id >> 8) & 0xFF); + *byte++ = (packet_id & 0xFF); + } + /* Fill in the message being pulished. */ + memcpy(byte, MESSAGE1, strlen(MESSAGE1)); + byte += strlen(MESSAGE1); + + /* Fill in the QoS and Retain information. */ + content[0] = content[0] & 0xF8; + content[0] = content[0] | (QoS << 1); + if (retain) + content[0] = content[0] | 1; + + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + error_counter++; + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT pubish request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + error_counter++; + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + error_counter++; + } +#endif + + if (((content[0] & 0x6) >> 1) == 1) + { + /* QoS 1: Respond with PUBACK */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x40; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) == 2) + { + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x50; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + } + if (((content[0] & 0x6) >> 1) != 0) + { + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + error_counter++; + } + + + tx_thread_sleep(1); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + diff --git a/test/regression/mqtt_test/netx_mqtt_publish_qos2_test.c b/test/regression/mqtt_test/netx_mqtt_publish_qos2_test.c new file mode 100644 index 00000000..5211d539 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_publish_qos2_test.c @@ -0,0 +1,363 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC1 "topic1" +#define MESSAGE1 "message1" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +#define CLIENT_MEMORY_SIZE 1024 +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_publish_QoS2_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT QoS; +static UINT retain; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Publish QoS 2 Test .................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + error_counter++; + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, 5); +#ifndef NXD_MQTT_REQUIRE_TLS + if(status) + error_counter++; + + QoS = 2; + retain = 0; + /* Issue a subscribe command. */ + status = nxd_mqtt_client_publish(client_ptr, TOPIC1, strlen(TOPIC1), MESSAGE1, strlen(MESSAGE1), retain, QoS, 2); + if(status) + error_counter++; + + tx_thread_sleep(10); +#else + if(status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + nxd_mqtt_client_disconnect(client_ptr); + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +USHORT packet_id; + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_sleep(1); + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Response with Connect SUCCESS */ + byte = packet_ptr -> nx_packet_prepend_ptr ; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + 4; + packet_ptr -> nx_packet_length = 4; + + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if(status) + error_counter++; + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + if(status) + error_counter++; + + /* construct the publish message. */ + byte = content; + *byte++ = 0x30 | ((*(packet_ptr -> nx_packet_prepend_ptr) & 0x0F)); /* Publish */ + byte++; /* Skip the length field. */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + byte += strlen(TOPIC1); + if(((content[0] & 6) >> 1) != 0) + { + packet_id = packet_ptr -> nx_packet_prepend_ptr[byte - content];/* Fill in packet ID MSB. */ + packet_id = (packet_id << 8) | packet_ptr -> nx_packet_prepend_ptr[byte - content + 1];/* Fill in packet ID MSB. */ + *byte++ += ((packet_id >> 8) & 0xFF ); + *byte++ += (packet_id & 0xFF); + } + /* Fill in the message being pulished. */ + memcpy(byte, MESSAGE1, strlen(MESSAGE1)); + byte += strlen(MESSAGE1); + + /* Fill in the QoS and Retain information. */ + content[0] = content[0] & 0xF8; + content[0] = content[0] | (QoS << 1); + if(retain) + content[0] = content[0] | 1; + + + /* Now validate message length */ + if(packet_ptr -> nx_packet_length != (byte - content)) + error_counter++; + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr -> nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT pubish request. */ + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, content, packet_ptr -> nx_packet_length)) + error_counter++; + + if(((content[0] & 0x6) >> 1) == 1) + { + /* QoS 1: Respond with PUBACK */ + byte = packet_ptr -> nx_packet_prepend_ptr ; + byte[0] = 0x40; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + 4; + packet_ptr -> nx_packet_length = 4; + } + if(((content[0] & 0x6) >> 1) == 2) + { + byte = packet_ptr -> nx_packet_prepend_ptr ; + byte[0] = 0x50; + byte[1] = 0x02; + byte[2] = (packet_id >> 8) & 0xFF; + byte[3] = packet_id & 0xFF; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + 4; + packet_ptr -> nx_packet_length = 4; + } + if(((content[0] & 0x6) >> 1) != 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if(status) + error_counter++; + } + + /* Now expect PUBREL */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 10); + if(status) + error_counter++; + + byte = packet_ptr -> nx_packet_prepend_ptr; + if((byte[0] != 0x60) || (byte[1] != 2) || (byte[2] != ((packet_id >> 8) & 0xFF)) || (byte[3] != (packet_id & 0xFF))) + error_counter++; + + /* Response with PUBCOMP*/ + byte[0] = 0x70; + + + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + error_counter++; + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + diff --git a/test/regression/mqtt_test/netx_mqtt_receive_qos0_test.c b/test/regression/mqtt_test/netx_mqtt_receive_qos0_test.c new file mode 100644 index 00000000..8d042fec --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_receive_qos0_test.c @@ -0,0 +1,587 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC "topic" +#define MESSAGE_QOS0 "MESSAGE_QOS0" +#define MESSAGE_QOS1 "MESSAGE_QOS11" +#define MESSAGE_QOS2 "MESSAGE_QOS222" + +static UINT packet_identifier = 0xbeef; +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +//NXD_MQTT_CLIENT my_client; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_receive_QoS0_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + //client_ptr = &my_client; + +} + + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +static UINT keepalive_value; +static UINT cleansession_value; +#define DEMO_TIMER_EVENT 1 +#define DEMO_MESSAGE_EVENT 2 +#define DEMO_ALL_EVENTS 3 + +TX_EVENT_FLAGS_GROUP mqtt_app_flag; + +static VOID my_notify_func(NXD_MQTT_CLIENT* client_ptr, UINT number_of_messages) +{ + + tx_event_flags_set(&mqtt_app_flag, DEMO_MESSAGE_EVENT, TX_OR); + return; + +} + +static UCHAR topic[100], message[100]; + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +ULONG events; +UINT topic_length, message_length; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Receive QoS 0 Test .................................."); + + status = tx_event_flags_create(&mqtt_app_flag, "my app event"); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, + mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + status = nxd_mqtt_client_receive_notify_set(client_ptr, my_notify_func); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Wait for incoming message. */ + tx_event_flags_get(&mqtt_app_flag, DEMO_ALL_EVENTS, TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + + status = nxd_mqtt_client_message_get(client_ptr, topic, sizeof(topic), &topic_length, message, sizeof(message), &message_length); + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if (topic_length != strlen(TOPIC) || strncmp(TOPIC, topic, topic_length) || (message_length != strlen(MESSAGE_QOS0)) || + strncmp(message, MESSAGE_QOS0, message_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + /* Check for error. */ + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT index = 0; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xf; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xf); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(50); + + /* Send a publish message with QoS 0 */ + if (i == 0) + { + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x30; + + index = 2; + byte[index++] = ((strlen(TOPIC)) >> 8) & 0xFF; + byte[index++] = (strlen(TOPIC)) & 0xFF; + memcpy(byte + index, TOPIC, strlen(TOPIC)); + + index += strlen(TOPIC); + + memcpy(byte + index, MESSAGE_QOS0, strlen(MESSAGE_QOS0)); + index += strlen(MESSAGE_QOS0); + + byte[1] = index - 2; + packet_ptr->nx_packet_length = index; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + index; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(5); + /* We dont expect anything back for QoS 0. */ + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_receive_qos1_test.c b/test/regression/mqtt_test/netx_mqtt_receive_qos1_test.c new file mode 100644 index 00000000..97bb7d99 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_receive_qos1_test.c @@ -0,0 +1,606 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC "topic" +#define MESSAGE_QOS0 "MESSAGE_QOS0" +#define MESSAGE_QOS1 "MESSAGE_QOS11" +#define MESSAGE_QOS2 "MESSAGE_QOS222" + +static UINT packet_identifier = 0xbeef; + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +//NXD_MQTT_CLIENT my_client; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_receive_QoS1_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + //client_ptr = &my_client; + +} + + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +static UINT keepalive_value; +static UINT cleansession_value; +#define DEMO_TIMER_EVENT 1 +#define DEMO_MESSAGE_EVENT 2 +#define DEMO_ALL_EVENTS 3 + +TX_EVENT_FLAGS_GROUP mqtt_app_flag; + +static VOID my_notify_func(NXD_MQTT_CLIENT* client_ptr, UINT number_of_messages) +{ + + tx_event_flags_set(&mqtt_app_flag, DEMO_MESSAGE_EVENT, TX_OR); + return; + +} + +UCHAR mqtt_memory[8192]; +static UCHAR topic[100], message[100]; + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +ULONG events; +UINT topic_length, message_length; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Receive QoS 1 Test .................................."); + + status = tx_event_flags_create(&mqtt_app_flag, "my app event"); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + status = nxd_mqtt_client_receive_notify_set(client_ptr, my_notify_func); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Wait for incoming message. */ + tx_event_flags_get(&mqtt_app_flag, DEMO_ALL_EVENTS, TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + + status = nxd_mqtt_client_message_get(client_ptr, topic, sizeof(topic), &topic_length, message, sizeof(message), &message_length); + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if (topic_length != strlen(TOPIC) || strncmp(TOPIC, topic, topic_length) || (message_length != strlen(MESSAGE_QOS1)) || + strncmp(message, MESSAGE_QOS1, message_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(1); + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + /* Check for error. */ + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +UCHAR *byte; +NX_PACKET *packet_ptr; +UINT index = 0; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xf; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xf); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(50); + + /* Send a publish message with QoS 1 */ + if (i == 0) + { + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x32; + + index = 2; + byte[index++] = (strlen(TOPIC) >> 8) & 0xFF; + byte[index++] = strlen(TOPIC) & 0xFF; + memcpy(byte + index, TOPIC, strlen(TOPIC)); + + index += strlen(TOPIC); + byte[index++] = packet_identifier >> 8; + byte[index++] = packet_identifier & 0xFF; + + memcpy(byte + index, MESSAGE_QOS1, strlen(MESSAGE_QOS1)); + index += strlen(MESSAGE_QOS1); + + byte[1] = index - 2; + packet_ptr->nx_packet_length = index; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + index; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Expect PUBBACK */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 50); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Expect PUBBACK */ + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr->nx_packet_prepend_ptr; + if (packet_ptr->nx_packet_length != 4) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if ((byte[0] != 0x40) || (byte[1] != 2) || (byte[2] != (packet_identifier >> 8)) || (byte[3] != (packet_identifier & 0xFF))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* All deon, release the packet. */ + status = nx_packet_release(packet_ptr); + + tx_thread_sleep(5); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_receive_qos2_test.c b/test/regression/mqtt_test/netx_mqtt_receive_qos2_test.c new file mode 100644 index 00000000..8293a5a5 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_receive_qos2_test.c @@ -0,0 +1,410 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC "topic" +#define MESSAGE_QOS0 "MESSAGE_QOS0" +#define MESSAGE_QOS1 "MESSAGE_QOS11" +#define MESSAGE_QOS2 "MESSAGE_QOS222" + +static UINT packet_identifier = 0xbeef; + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef CTEST +static +#else /* CTEST */ +extern +#endif /* CTEST */ +UCHAR mqtt_memory[8192]; +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +//NXD_MQTT_CLIENT my_client; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_receive_QoS2_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + //client_ptr = &my_client; + +} + + + +static UINT keepalive_value; +static UINT cleansession_value; +#define DEMO_TIMER_EVENT 1 +#define DEMO_MESSAGE_EVENT 2 +#define DEMO_ALL_EVENTS 3 + +TX_EVENT_FLAGS_GROUP mqtt_app_flag; + +static VOID my_notify_func(NXD_MQTT_CLIENT* client_ptr, UINT number_of_messages) +{ + + tx_event_flags_set(&mqtt_app_flag, DEMO_MESSAGE_EVENT, TX_OR); + return; + +} + +static UCHAR topic[100], message[100]; + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +ULONG events; +UINT topic_length, message_length; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Receive QoS 2 Test .................................."); + + status = tx_event_flags_create(&mqtt_app_flag, "my app event"); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + status = nxd_mqtt_client_receive_notify_set(client_ptr, my_notify_func); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, 5); +#ifndef NXD_MQTT_REQUIRE_TLS + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Wait for incoming message. */ + tx_event_flags_get(&mqtt_app_flag, DEMO_ALL_EVENTS, TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + + status = nxd_mqtt_client_message_get(client_ptr, topic, sizeof(topic), &topic_length, message, sizeof(message), &message_length); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + if ((topic_length != strlen(TOPIC)) || strncmp(TOPIC, topic, topic_length) || (message_length != strlen(MESSAGE_QOS2)) || + strncmp(message, MESSAGE_QOS2, message_length)) + { + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + nx_packet_release(packet_ptr); + + tx_thread_sleep(3); +#else + if(status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + + nxd_mqtt_client_disconnect(client_ptr); + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + /* Check for error. */ + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT index = 0; + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_resume(&ntest_0); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(1); + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xf; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xf); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if(cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Response with SUCCESS */ + byte = packet_ptr -> nx_packet_prepend_ptr ; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + 4; + packet_ptr -> nx_packet_length = 4; + + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(50); + + /* Send a publish message with QoS 2 */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr -> nx_packet_prepend_ptr; + byte[0] = 0x34; + + index = 2; + byte[index++] = (strlen(TOPIC) >> 8)&0xFF; + byte[index++] = strlen(TOPIC) & 0xFF; + memcpy(byte + index, TOPIC, strlen(TOPIC)); + + index += strlen(TOPIC); + byte[index++] = packet_identifier >> 8; + byte[index++] = packet_identifier & 0xFF; + + byte[index++] = ((strlen(MESSAGE_QOS2)) >> 8) & 0xFF; + byte[index++] = (strlen(MESSAGE_QOS2)) & 0xFF; + + memcpy(byte + index, MESSAGE_QOS2, strlen(MESSAGE_QOS2)); + index += strlen(MESSAGE_QOS2); + + byte[1] = index - 2; + packet_ptr -> nx_packet_length = index; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + index; + + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Expect PUBBACK */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr -> nx_packet_prepend_ptr; + if(packet_ptr -> nx_packet_length != 4) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if((byte[0] != 0x50) || (byte[1] != 2) || (byte[2] != (packet_identifier >> 8)) || (byte[3] != (packet_identifier & 0xFF))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + /* Respond with PUBREL */ + byte[0] = 0x60; + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Expect PUBCOMP */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + byte = packet_ptr -> nx_packet_prepend_ptr; + if(packet_ptr -> nx_packet_length != 4) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if((byte[0] != 0x70) || (byte[1] != 2) || (byte[2] != (packet_identifier >> 8)) || (byte[3] != (packet_identifier & 0xFF))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* All deon, release the packet. */ + status = nx_packet_release(packet_ptr); + + + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_receive_span_test.c b/test/regression/mqtt_test/netx_mqtt_receive_span_test.c new file mode 100644 index 00000000..6632ac75 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_receive_span_test.c @@ -0,0 +1,619 @@ +/* MQTT receive test. This test case validates MQTT message span multple packets. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC "topic" +#define MESSAGE_QOS0 "MESSAGE_QOS0" +#define MESSAGE_QOS1 "MESSAGE_QOS11" +#define MESSAGE_QOS2 "MESSAGE_QOS222" + +static UINT packet_identifier = 0xbeef; +UCHAR mqtt_memory[8192]; + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void publish_mqtt_message(UINT i, UCHAR *data, UINT size); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +//NXD_MQTT_CLIENT my_client; +static UCHAR *stack_ptr; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_receive_span_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + //client_ptr = &my_client; + +} + + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +static UINT keepalive_value; +static UINT cleansession_value; +#define DEMO_TIMER_EVENT 1 +#define DEMO_MESSAGE_EVENT 2 +#define DEMO_ALL_EVENTS 3 + +TX_EVENT_FLAGS_GROUP mqtt_app_flag; + +static VOID my_notify_func(NXD_MQTT_CLIENT* client_ptr, UINT number_of_messages) +{ + + tx_event_flags_set(&mqtt_app_flag, DEMO_MESSAGE_EVENT, TX_OR); + return; + +} + +static UCHAR topic[100], message[100]; + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +ULONG events; +UINT topic_length, message_length; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Receive Span Test...................................."); + + status = tx_event_flags_create(&mqtt_app_flag, "my app event"); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, + mqtt_memory, sizeof(mqtt_memory)); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + status = nxd_mqtt_client_receive_notify_set(client_ptr, my_notify_func); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Wait for incoming message. */ + tx_event_flags_get(&mqtt_app_flag, DEMO_ALL_EVENTS, TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + + status = nxd_mqtt_client_message_get(client_ptr, topic, sizeof(topic), &topic_length, message, sizeof(message), &message_length); + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if (topic_length != strlen(TOPIC) || strncmp(TOPIC, topic, topic_length) || (message_length != strlen(MESSAGE_QOS0)) || + strncmp(message, MESSAGE_QOS0, message_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Wait for another incoming message. */ + tx_event_flags_get(&mqtt_app_flag, DEMO_ALL_EVENTS, TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + + status = nxd_mqtt_client_message_get(client_ptr, topic, sizeof(topic), &topic_length, message, sizeof(message), &message_length); + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if (topic_length != strlen(TOPIC) || strncmp(TOPIC, topic, topic_length) || (message_length != strlen(MESSAGE_QOS0)) || + strncmp(message, MESSAGE_QOS0, message_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + /* Check for error. */ + +static UCHAR content[100]; + +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +UCHAR *byte; +NX_PACKET *packet_ptr; +UINT index = 0; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + + /* construct the connect message. */ + memcpy(content, fixed_header, sizeof(fixed_header)); + /* Append client ID */ + content[sizeof(fixed_header)] = (strlen(CLIENT_ID) >> 8) & 0xf; + content[sizeof(fixed_header) + 1] = (strlen(CLIENT_ID) & 0xf); + memcpy(content + sizeof(fixed_header) + 2, CLIENT_ID, strlen(CLIENT_ID)); + + content[1] = (UCHAR)(sizeof(fixed_header) + strlen(CLIENT_ID)); + + /* Fill in the connection_flag, keepalive, and cleansession flags. */ + content[10] = keepalive_value >> 8; + content[11] = keepalive_value & 0xFF; + if (cleansession_value) + content[9] = content[9] | 2; + + /* Validate the MQTT connect request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, sizeof(fixed_header) + strlen(CLIENT_ID))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(50); + + /* Construct MQTT message. */ + byte = content; + byte[0] = 0x30; + index = 2; + byte[index++] = ((strlen(TOPIC)) >> 8) & 0xFF; + byte[index++] = (strlen(TOPIC)) & 0xFF; + memcpy(byte + index, TOPIC, strlen(TOPIC)); + index += strlen(TOPIC); + memcpy(byte + index, MESSAGE_QOS0, strlen(MESSAGE_QOS0)); + index += strlen(MESSAGE_QOS0); + byte[1] = index - 2; + + /* Duplicate MQTT message. */ + memcpy(byte + index, byte, index); + + /* 1. Send fixed_header field. */ + publish_mqtt_message(i, content, 1); + + /* 2. Send length field. */ + publish_mqtt_message(i, content + 1, 1); + + /* 3. Send another byte. */ + publish_mqtt_message(i, content + 2, 1); + + /* 4. Send remaining bytes of first message plus one bytes of second message. */ + publish_mqtt_message(i, content + 3, index - 2); + + /* 5. Send remaining bytes of second message. */ + publish_mqtt_message(i, content + index + 1, index - 1); + + tx_thread_sleep(5); + /* We dont expect anything back for QoS 0. */ + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + +static void publish_mqtt_message(UINT i, UCHAR *data, UINT size) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Send a publish message with QoS 0 */ + if (i == 0) + { + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + memcpy(packet_ptr->nx_packet_prepend_ptr, data, size); + packet_ptr->nx_packet_length = size; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + size; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +} diff --git a/test/regression/mqtt_test/netx_mqtt_remaining_length_test.c b/test/regression/mqtt_test/netx_mqtt_remaining_length_test.c new file mode 100644 index 00000000..fa55a600 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_remaining_length_test.c @@ -0,0 +1,210 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" + +extern UINT _nxd_mqtt_read_remaining_length(NX_PACKET *packet_ptr, UINT *remaining_length, ULONG *offset); +extern UINT _nxd_mqtt_client_set_fixed_header(NXD_MQTT_CLIENT *client_ptr, NX_PACKET *packet_ptr, UCHAR control_header, UINT length, UINT wait_option); + +static ULONG error_counter; +extern void test_control_return(UINT status); +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef CTEST +void test_application_define(void * first_unused_memory) +#else /* CTEST */ +void netx_mqtt_remaining_length_test(void * first_unused_memory) +#endif /* CTEST */ +{ +CHAR *pointer; +NX_PACKET_POOL pool_0; +NXD_MQTT_CLIENT *client_ptr; +NX_PACKET *packet_ptr; +UINT status; +UINT remaining_length; +ULONG offset; +int i; +UCHAR *byte; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Remaining Length Test ..............................."); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + pointer = pointer + PACKET_POOL_SIZE; + + client_ptr = (NXD_MQTT_CLIENT *)pointer; + client_ptr -> nxd_mqtt_client_packet_pool_ptr = &pool_0; + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Test set function, remaining length <= 127 */ + for(i = 1; i < 128; i++) + { + packet_ptr->nx_packet_length = 0; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr; + packet_ptr->nx_packet_next = 0; + memset(packet_ptr->nx_packet_prepend_ptr, 0, 10); + status = _nxd_mqtt_client_set_fixed_header(client_ptr, packet_ptr, 0, i, NX_WAIT_FOREVER); + /* Verify the value. */ + if((status != 0) || (packet_ptr -> nx_packet_length != 2) || ((*(packet_ptr -> nx_packet_prepend_ptr + 1)) != i)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + packet_ptr->nx_packet_length += i; + packet_ptr->nx_packet_append_ptr += i; + status = _nxd_mqtt_read_remaining_length(packet_ptr, &remaining_length, &offset); + if((status != 0) || (remaining_length != i) || (offset != 2)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + /* test 128 */ + packet_ptr->nx_packet_length = 0; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr; + memset(packet_ptr->nx_packet_prepend_ptr, 0, 10); + status = _nxd_mqtt_client_set_fixed_header(client_ptr, packet_ptr, 0, 128, NX_WAIT_FOREVER); + /* Verify the value. */ + if((status != 0) || (packet_ptr -> nx_packet_length != 3) || + ((*(packet_ptr -> nx_packet_prepend_ptr + 1) != 0x80) && (*(packet_ptr -> nx_packet_prepend_ptr + 2) != 0x01))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + packet_ptr->nx_packet_length += 128; + packet_ptr->nx_packet_append_ptr += 128; + status = _nxd_mqtt_read_remaining_length(packet_ptr, &remaining_length, &offset); + if((status != 0) || (remaining_length != 128) || (offset != 3)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + /* test 16383 */ + packet_ptr->nx_packet_length = 0; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr; + memset(packet_ptr->nx_packet_prepend_ptr, 0, 10); + status = _nxd_mqtt_client_set_fixed_header(client_ptr, packet_ptr, 0, 16383, NX_WAIT_FOREVER); + /* Verify the value. */ + if((status != 0) || (packet_ptr -> nx_packet_length != 3) || + ((*(packet_ptr -> nx_packet_prepend_ptr + 1) != 0xFF) && (*(packet_ptr -> nx_packet_prepend_ptr + 2) != 0x7F))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + packet_ptr->nx_packet_length += 16383; + packet_ptr->nx_packet_append_ptr += 16383; + status = _nxd_mqtt_read_remaining_length(packet_ptr, &remaining_length, &offset); + if((status != 0) || (remaining_length != 16383) || (offset != 3)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* test 16384 */ + packet_ptr->nx_packet_length = 0; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr; + memset(packet_ptr->nx_packet_prepend_ptr, 0, 10); + status = _nxd_mqtt_client_set_fixed_header(client_ptr, packet_ptr, 0, 16384, NX_WAIT_FOREVER); + /* Verify the value. */ + if((status != 0) || (packet_ptr -> nx_packet_length != 4) || + ((*(packet_ptr -> nx_packet_prepend_ptr + 1) != 0x80) && (*(packet_ptr -> nx_packet_prepend_ptr + 2) != 0x80)) && + ((*(packet_ptr -> nx_packet_prepend_ptr + 3) != 0x01))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + packet_ptr->nx_packet_length += 16384; + packet_ptr->nx_packet_append_ptr += 16384; + status = _nxd_mqtt_read_remaining_length(packet_ptr, &remaining_length, &offset); + if((status != 0) || (remaining_length != 16384) || (offset != 4)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* test 2 097 151 */ + packet_ptr->nx_packet_length = 0; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr; + memset(packet_ptr->nx_packet_prepend_ptr, 0, 10); + status = _nxd_mqtt_client_set_fixed_header(client_ptr, packet_ptr, 0, 2097151, NX_WAIT_FOREVER); + /* Verify the value. */ + if((status != 0) || (packet_ptr -> nx_packet_length != 4) || + ((*(packet_ptr -> nx_packet_prepend_ptr + 1) != 0xFF) && (*(packet_ptr -> nx_packet_prepend_ptr + 2) != 0xFF)) && + ((*(packet_ptr -> nx_packet_prepend_ptr + 3) != 0x7f))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + packet_ptr->nx_packet_length += 2097151; + packet_ptr->nx_packet_append_ptr += 2097151; + status = _nxd_mqtt_read_remaining_length(packet_ptr, &remaining_length, &offset); + if((status != 0) || (remaining_length != 2097151) || (offset != 4)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* test 2 097 152 */ + packet_ptr->nx_packet_length = 0; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr; + memset(packet_ptr->nx_packet_prepend_ptr, 0, 10); + status = _nxd_mqtt_client_set_fixed_header(client_ptr, packet_ptr, 0, 2097152, NX_WAIT_FOREVER); + /* Verify the value. */ + if((status != 0) || (packet_ptr -> nx_packet_length != 5) || + ((*(packet_ptr -> nx_packet_prepend_ptr + 1) != 0x80) && (*(packet_ptr -> nx_packet_prepend_ptr + 2) != 0x80)) && + ((*(packet_ptr -> nx_packet_prepend_ptr + 3) != 0x80)) && ((*(packet_ptr -> nx_packet_prepend_ptr + 4) != 0x1))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + packet_ptr->nx_packet_length += 2097152; + packet_ptr->nx_packet_append_ptr += 2097152; + status = _nxd_mqtt_read_remaining_length(packet_ptr, &remaining_length, &offset); + if((status != 0) || (remaining_length != 2097152) || (offset != 5)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* test 268 435 455 */ + packet_ptr->nx_packet_length = 0; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr; + memset(packet_ptr->nx_packet_prepend_ptr, 0, 10); + status = _nxd_mqtt_client_set_fixed_header(client_ptr, packet_ptr, 0, 268435455, NX_WAIT_FOREVER); + /* Verify the value. */ + if((status != 0) || (packet_ptr -> nx_packet_length != 5) || + ((*(packet_ptr -> nx_packet_prepend_ptr + 1) != 0xff) && (*(packet_ptr -> nx_packet_prepend_ptr + 2) != 0xff)) && + ((*(packet_ptr -> nx_packet_prepend_ptr + 3) != 0xff)) && ((*(packet_ptr -> nx_packet_prepend_ptr + 4) != 0x7f))) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + packet_ptr->nx_packet_length += 268435455; + packet_ptr->nx_packet_append_ptr += 268435455; + status = _nxd_mqtt_read_remaining_length(packet_ptr, &remaining_length, &offset); + if((status != 0) || (remaining_length != 268435455) || (offset != 5)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Test for invalid length */ + packet_ptr->nx_packet_length = 6; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 6; + + byte = packet_ptr -> nx_packet_prepend_ptr + 1; + *byte = 0x80; byte++; + *byte = 0x80; byte++; + *byte = 0x80; byte++; + *byte = 0x80; byte++; + *byte = 0x7f; byte++; + status = _nxd_mqtt_read_remaining_length(packet_ptr, &remaining_length, &offset); + if(status == 0) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + nx_packet_release(packet_ptr); + + nx_packet_pool_delete(&pool_0); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} diff --git a/test/regression/mqtt_test/netx_mqtt_subscribe_non_zero_packet_id_test.c b/test/regression/mqtt_test/netx_mqtt_subscribe_non_zero_packet_id_test.c new file mode 100644 index 00000000..d3c1d0dc --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_subscribe_non_zero_packet_id_test.c @@ -0,0 +1,723 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC1 "topic1" +#define MESSAGE1 "message1" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +#define CLIENT_MEMORY_SIZE 1024 +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_subscribe_non_zero_packet_id_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT QoS; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Subscribe Non-Zero Packet ID Test ..................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + memset(client_ptr, 0, sizeof(NXD_MQTT_CLIENT)); + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + QoS = 1; + /* Issue the 1st subscribe command. */ + status = nxd_mqtt_client_subscribe(client_ptr, TOPIC1, strlen(TOPIC1), QoS); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Force packet ID to be 0xFFFF */ + client_ptr->nxd_mqtt_client_packet_identifier = 0xffff; + + /* Issue the 2nd subscribe command. */ + status = nxd_mqtt_client_subscribe(client_ptr, TOPIC1, strlen(TOPIC1), QoS); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Issue the 3rd subscribe command. */ + status = nxd_mqtt_client_subscribe(client_ptr, TOPIC1, strlen(TOPIC1), QoS); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +USHORT packet_id; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /*************************** Test 1st subscribe message *******************************/ + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the subscribe message. */ + byte = content; + *byte++ = 0x82; /* Subscribe */ + byte++; /* Skip the length field. */ + packet_id = (packet_ptr->nx_packet_prepend_ptr[2] << 8) + (packet_ptr->nx_packet_prepend_ptr[3]); + + *byte++ = packet_ptr->nx_packet_prepend_ptr[2];/* Fill in packet ID MSB. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[3];/* Fill in packet ID LSB. */ + /* Fill in subscribe topic length MSB and LSB */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + /* Fill in the QoS byte. */ + byte += strlen(TOPIC1); + *byte++ = QoS & 0x3; + + if (packet_id == 0) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x90; + byte[1] = 0x03; + byte[2] = content[2]; + byte[3] = content[3]; + byte[4] = QoS & 0x3; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 5; + packet_ptr->nx_packet_length = 5; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + + /*************************** Test 2nd subscribe message *******************************/ + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 50); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the subscribe message. */ + byte = content; + *byte++ = 0x82; /* Subscribe */ + byte++; /* Skip the length field. */ + packet_id = (packet_ptr->nx_packet_prepend_ptr[2] << 8) + (packet_ptr->nx_packet_prepend_ptr[3]); + + *byte++ = packet_ptr->nx_packet_prepend_ptr[2];/* Fill in packet ID MSB. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[3];/* Fill in packet ID LSB. */ + /* Fill in subscribe topic length MSB and LSB */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + /* Fill in the QoS byte. */ + byte += strlen(TOPIC1); + *byte++ = QoS & 0x3; + + if (packet_id != 0xFFFF) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x90; + byte[1] = 0x03; + byte[2] = content[2]; + byte[3] = content[3]; + byte[4] = QoS & 0x3; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 5; + packet_ptr->nx_packet_length = 5; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + + + /*************************** Test 3rd subscribe message *******************************/ + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the subscribe message. */ + byte = content; + *byte++ = 0x82; /* Subscribe */ + byte++; /* Skip the length field. */ + packet_id = (packet_ptr->nx_packet_prepend_ptr[2] << 8) + (packet_ptr->nx_packet_prepend_ptr[3]); + + *byte++ = packet_ptr->nx_packet_prepend_ptr[2];/* Fill in packet ID MSB. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[3];/* Fill in packet ID LSB. */ + /* Fill in subscribe topic length MSB and LSB */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + + if (packet_id == 0) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + /* Fill in the QoS byte. */ + byte += strlen(TOPIC1); + *byte++ = QoS & 0x3; + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x90; + byte[1] = 0x03; + byte[2] = content[2]; + byte[3] = content[3]; + byte[4] = QoS & 0x3; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 5; + packet_ptr->nx_packet_length = 5; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + + + + + /*************************** End of the Test ******************************************/ + + tx_thread_sleep(5); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_subscribe_packet_chain_test.c b/test/regression/mqtt_test/netx_mqtt_subscribe_packet_chain_test.c new file mode 100644 index 00000000..608e3976 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_subscribe_packet_chain_test.c @@ -0,0 +1,393 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); + +#if !defined(NXD_MQTT_REQUIRE_TLS) + +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC_LEN 256 +#define CLIENT_MEMORY_SIZE 1024 +#define PACKET_BUFFER_SIZE 1024 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 32 +#define PACKET_SIZE 128 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +static TX_SEMAPHORE semaphore_server_received; +static TX_SEMAPHORE semaphore_client_sent; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +static UCHAR *packet_buffer; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_subscribe_packet_chain_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_received, "semaphore server received", 0); + tx_semaphore_create(&semaphore_client_sent, "semaphore client sent", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + packet_buffer = pointer; + pointer += PACKET_BUFFER_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT connection_flag_value; +static UINT QoS; +static UCHAR *topic; + +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Subscribe Packet Chain Test.........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + error_counter++; + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + topic = packet_buffer; + + for (i = 0; i < TOPIC_LEN; i++) + { + topic[i] = i & 0xff; + } + + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + QoS = 1; + +#if 0 +NX_PACKET *temp_packets[NUM_PACKETS]; + + for (i = 0 ; i < NUM_PACKETS - 2; i++) + { + status = nx_packet_allocate(&pool_0, &(temp_packets[i]), NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + break; + } + } + + /* Fail to append topic. */ + status = nxd_mqtt_client_subscribe(client_ptr, topic, TOPIC_LEN, QoS); + if (status != NXD_MQTT_PACKET_POOL_FAILURE) + error_counter++; + + for (i = 0 ; i < NUM_PACKETS - 2; i++) + { + nx_packet_release(temp_packets[i]); + } +#endif + + /* Issue a subscribe command. */ + status = nxd_mqtt_client_subscribe(client_ptr, topic, TOPIC_LEN, QoS); + if (status) + error_counter++; + + tx_semaphore_put(&semaphore_client_sent); + + tx_semaphore_get(&semaphore_server_received, NX_WAIT_FOREVER); + + nxd_mqtt_client_disconnect(client_ptr); + + nxd_mqtt_client_delete(client_ptr); + + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT len, packet_len; +UCHAR control_header; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + tx_thread_sleep(1); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + if (status) + { + error_counter++; + } + else + { + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + packet_ptr = NX_NULL; + packet_len = 0; + + tx_semaphore_get(&semaphore_client_sent, NX_WAIT_FOREVER); + + while (1) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + if (status) + break; + + nx_packet_data_retrieve(packet_ptr, packet_buffer + packet_len, (ULONG *)&len); + packet_len += len; + + nx_packet_release(packet_ptr); + } + + tx_semaphore_put(&semaphore_server_received); + + /* Check the subscribe message. */ + + control_header = 0x82; /* Subscribe */ + len = 1 + 2 + 2 + 2 + TOPIC_LEN + 1; /* Control header 1 + remaining length 2 + packet ID 2 + topic length 2 + topic + QoS 1 */ + + for (i = 0 ; i < TOPIC_LEN; i++) + { + if (packet_buffer[7 + i] != (i & 0xff)) + { + error_counter++; + break; + } + } + + /* Now validate message length */ + if (packet_len != len) + error_counter++; + + /* Validate the MQTT subscribe request. */ + if ((packet_buffer[0] != control_header) || (packet_buffer[packet_len -1] != (QoS & 0x3))) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_subscribe_packet_chain_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: MQTT Subscribe Packet Chain Test..........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/mqtt_test/netx_mqtt_subscribe_test.c b/test/regression/mqtt_test/netx_mqtt_subscribe_test.c new file mode 100644 index 00000000..3df64568 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_subscribe_test.c @@ -0,0 +1,595 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC1 "topic1" +#define MESSAGE1 "message1" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +#define CLIENT_MEMORY_SIZE 1024 +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_subscribe_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT QoS; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Subscribe Test ......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + QoS = 1; + + /* Issue a subscribe command. */ + status = nxd_mqtt_client_subscribe(client_ptr, TOPIC1, strlen(TOPIC1), QoS); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +//static UCHAR fixed_header[] = {0x80, 0x00, /* MQTT Control Packet Type, remaining length */ +// 0x00, 0x00}; /* Packet identifier, MSB, and LSB */ + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the subscribe message. */ + byte = content; + *byte++ = 0x82; /* Subscribe */ + byte++; /* Skip the length field. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[2];/* Fill in packet ID MSB. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[3];/* Fill in packet ID LSB. */ + /* Fill in subscribe topic length MSB and LSB */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + /* Fill in the QoS byte. */ + byte += strlen(TOPIC1); + *byte++ = QoS & 0x3; + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT subscribe request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x90; + byte[1] = 0x03; + byte[2] = content[2]; + byte[3] = content[3]; + byte[4] = QoS & 0x3; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 5; + packet_ptr->nx_packet_length = 5; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#if 0 + /* Expect Unsub */ + tx_thread_sleep(1); + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the unsubscribe message. */ + byte = content; + *byte++ = 0xA0; /* Unsubscribe */ + byte++; /* Skip the length field. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[2];/* Fill in packet ID MSB. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[3];/* Fill in packet ID LSB. */ + /* Fill in subscribe topic length MSB and LSB */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + byte += strlen(TOPIC1); + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT unsubscribe request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0xb0; + byte[1] = 0x02; + byte[2] = content[2]; + byte[3] = content[3]; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + tx_thread_sleep(5); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_testcontrol.c b/test/regression/mqtt_test/netx_mqtt_testcontrol.c new file mode 100644 index 00000000..a483b5db --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_testcontrol.c @@ -0,0 +1,506 @@ +/* This is the test control routine the NetX TCP/IP stack. All tests are dispatched from this routine. */ + +#include "tx_api.h" +#include "nx_api.h" +#include +#include +#include "nx_ram_network_driver_test_1500.h" + +/* +#define NETXTEST_TIMEOUT_DISABLE +*/ + +#define TEST_STACK_SIZE 4096 + +/* 1 minute. */ +#define TEST_TIMEOUT_LOW (60 * NX_IP_PERIODIC_RATE) +/* 15 minutes. */ +#define TEST_TIMEOUT_MID (900 * NX_IP_PERIODIC_RATE) +/* 120 minutes. */ +#define TEST_TIMEOUT_HIGH (7200 * NX_IP_PERIODIC_RATE) + +/* Define the test control ThreadX objects... */ + +TX_THREAD test_control_thread; +#ifndef NETXTEST_TIMEOUT_DISABLE +TX_SEMAPHORE test_control_sema; +#endif + +/* Define the test control global variables. */ + +ULONG test_control_return_status; +ULONG test_control_successful_tests; +ULONG test_control_failed_tests; +ULONG test_control_warning_tests; +ULONG test_control_na_tests; + +/* Remember the start of free memory. */ + +UCHAR *test_free_memory_ptr; + +extern volatile UINT _tx_thread_preempt_disable; + +/* Define test entry pointer type. */ + +typedef struct TEST_ENTRY_STRUCT +{ + VOID (*test_entry)(void *); + UINT timeout; +} TEST_ENTRY; + + +/* Define the prototypes for the test entry points. */ +void netx_mqtt_api_test_application_define(void*); +void netx_mqtt_client_connect_application_define(void*); +void netx_mqtt_client_connect_packet_send_failure_application_define(void*); +void netx_mqtt_client_connect_v6_application_define(void*); +void netx_mqtt_client_connect_non_block_application_define(void*); +void netx_mqtt_client_connect_non_block_2_application_define(void*); +void netx_mqtt_client_connect_auth_application_define(void*); +void netx_mqtt_client_connect_auth_empty_application_define(void*); +void netx_mqtt_client_null_password_application_define(void *); +void netx_mqtt_client_subscribe_application_define(void*); +void netx_mqtt_client_unsubscribe_application_define(void*); +void netx_mqtt_client_publish_QoS0_application_define(void *); +void netx_mqtt_client_publish_QoS1_application_define(void *); +void netx_mqtt_client_publish_QoS2_application_define(void *); +void netx_mqtt_client_receive_QoS0_application_define(void *); +void netx_mqtt_client_receive_QoS1_application_define(void *); +void netx_mqtt_client_receive_QoS2_application_define(void *); +void netx_mqtt_client_connect_will_message_application_define(void *); +void netx_mqtt_client_connect_auth_will_application_define(void *); +void netx_mqtt_client_connect_will_topic_only_application_define(void *); +void netx_mqtt_not_connected_application_define(void *); +void netx_mqtt_client_keepalive_application_define(void*); +void netx_mqtt_client_keepalive_timeout_application_define(void*); +void netx_mqtt_client_multiple_receive_application_define(void*); +void netx_mqtt_remaining_length_test(void *); +void netx_mqtt_client_publish_non_zero_packet_id_application_define(void*); +void netx_mqtt_client_subscribe_non_zero_packet_id_application_define(void*); +void netx_mqtt_client_packet_leak_application_define(void *); +void netx_mqtt_client_receive_span_application_define(void *first_unused_memory); +void netx_mqtt_client_publish_packet_chain_application_define(void *); +void netx_mqtt_client_subscribe_packet_chain_application_define(void *); +void netx_mqtt_client_connack_error_application_define(void *); +void netx_mqtt_client_branch_application_define(void *); +void netx_mqtt_websocket_non_block_test_application_define(void *); +void netx_mqtt_websocket_block_test_application_define(void *); +#ifdef CTEST +void test_application_define(void *); +#endif + + +/* Define the array of test entry points. */ + +TEST_ENTRY test_control_tests[] = +{ +#ifdef CTEST + {test_application_define, TEST_TIMEOUT_LOW}, +#else /* CTEST */ + {netx_mqtt_remaining_length_test, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_receive_QoS0_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_receive_QoS1_application_define, TEST_TIMEOUT_LOW}, + /*{netx_mqtt_client_receive_QoS2_application_define, TEST_TIMEOUT_LOW},*/ + {netx_mqtt_client_publish_QoS0_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_publish_QoS1_application_define, TEST_TIMEOUT_LOW}, + /* {netx_mqtt_client_publish_QoS2_application_define, TEST_TIMEOUT_LOW}, */ + {netx_mqtt_client_subscribe_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_unsubscribe_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_connect_auth_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_connect_auth_empty_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_connect_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_connect_v6_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_connect_non_block_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_connect_non_block_2_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_null_password_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_api_test_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_connect_will_message_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_connect_will_topic_only_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_connect_auth_will_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_not_connected_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_keepalive_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_keepalive_timeout_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_multiple_receive_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_publish_non_zero_packet_id_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_subscribe_non_zero_packet_id_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_packet_leak_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_receive_span_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_publish_packet_chain_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_subscribe_packet_chain_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_connack_error_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_client_branch_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_websocket_non_block_test_application_define, TEST_TIMEOUT_LOW}, + {netx_mqtt_websocket_block_test_application_define, TEST_TIMEOUT_LOW}, +#endif /* CTEST */ + + {TX_NULL, TEST_TIMEOUT_LOW}, +}; + +/* Define thread prototypes. */ + +void test_control_thread_entry(ULONG thread_input); +void test_control_return(UINT status); +void test_control_cleanup(void); +void _nx_ram_network_driver_reset(void); + +/* Define necessary external references. */ + +#ifdef __ghs +extern TX_MUTEX __ghLockMutex; +#endif + +extern TX_TIMER *_tx_timer_created_ptr; +extern ULONG _tx_timer_created_count; +#ifndef TX_TIMER_PROCESS_IN_ISR +extern TX_THREAD _tx_timer_thread; +#endif +extern TX_THREAD *_tx_thread_created_ptr; +extern ULONG _tx_thread_created_count; +extern TX_SEMAPHORE *_tx_semaphore_created_ptr; +extern ULONG _tx_semaphore_created_count; +extern TX_QUEUE *_tx_queue_created_ptr; +extern ULONG _tx_queue_created_count; +extern TX_MUTEX *_tx_mutex_created_ptr; +extern ULONG _tx_mutex_created_count; +extern TX_EVENT_FLAGS_GROUP *_tx_event_flags_created_ptr; +extern ULONG _tx_event_flags_created_count; +extern TX_BYTE_POOL *_tx_byte_pool_created_ptr; +extern ULONG _tx_byte_pool_created_count; +extern TX_BLOCK_POOL *_tx_block_pool_created_ptr; +extern ULONG _tx_block_pool_created_count; + +extern NX_PACKET_POOL * _nx_packet_pool_created_ptr; +extern ULONG _nx_packet_pool_created_count; +extern NX_IP * _nx_ip_created_ptr; +extern ULONG _nx_ip_created_count; + +/* Define main entry point. */ + +int main() +{ + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); + + + return 0; +} + +//#define TEST_FREE_MEMORY_POOL_SIZE (100 * 1024) +//static ULONG test_free_memory_pool[TEST_FREE_MEMORY_POOL_SIZE / sizeof(ULONG)]; +/* Define what the initial system looks like. */ + +void tx_application_define(void *first_unused_memory) +{ + UCHAR *pointer; + + /* Setup a pointer to the first unused memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the test control thread. */ + tx_thread_create(&test_control_thread, "test control thread", test_control_thread_entry, 0, + pointer, TEST_STACK_SIZE, + 0, 0, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + TEST_STACK_SIZE; + +#ifndef NETXTEST_TIMEOUT_DISABLE + /* Create the test control semaphore. */ + tx_semaphore_create(&test_control_sema, "Test control semaphore", 0); +#endif + + /* Remember the free memory pointer. */ + //test_free_memory_ptr = (UCHAR*)test_free_memory_pool; + test_free_memory_ptr = pointer; +} + +/* Define the test control thread. This thread is responsible for dispatching all of the +tests in the ThreadX test suite. */ + +void test_control_thread_entry(ULONG thread_input) +{ + UINT i; + + /* Loop to process all tests... */ + i = 0; + while (test_control_tests[i].test_entry != TX_NULL) + { + + /* Dispatch the test. */ + (test_control_tests[i++].test_entry)(test_free_memory_ptr); + + if (test_control_return_status != 3) + { + +#ifdef NETXTEST_TIMEOUT_DISABLE + /* Suspend control test to allow test to run. */ + tx_thread_suspend(&test_control_thread); +#else + if(tx_semaphore_get(&test_control_sema, test_control_tests[i - 1].timeout)) + { + + /* Test case timeouts. */ + printf("ERROR!\n"); + test_control_failed_tests++; + + } +#endif + } + else + test_control_return_status = 0; + + /* Test finished, cleanup in preparation for the next test. */ + test_control_cleanup(); + fflush(stdout); + } + + /* Finished with all tests, print results and return! */ + printf("**** Testing Complete ****\n"); + 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); +#if 0 + fclose(stream); +#endif +#ifdef BATCH_TEST + exit(test_control_failed_tests); +#endif + + +} + +void test_control_return(UINT status) +{ + UINT old_posture = TX_INT_ENABLE; + + /* Save the status in a global. */ + test_control_return_status = status; + + /* Ensure interrupts are enabled. */ + old_posture = tx_interrupt_control(TX_INT_ENABLE); + + /* Determine if it was successful or not. */ + if((status == 1) || (_tx_thread_preempt_disable) || (old_posture == TX_INT_DISABLE)) + test_control_failed_tests++; + else if(status == 2) + test_control_warning_tests++; + else if(status == 0) + test_control_successful_tests++; + else if(status == 3) + test_control_na_tests++; + +#ifdef NETXTEST_TIMEOUT_DISABLE + /* Resume the control thread to fully exit the test. */ + tx_thread_resume(&test_control_thread); +#else + if(test_control_return_status != 3) + tx_semaphore_put(&test_control_sema); +#endif +} + +void test_control_cleanup(void) +{ + TX_MUTEX *mutex_ptr; + TX_THREAD *thread_ptr; + + /* Clean timer used by RAM driver. */ + _nx_ram_network_driver_timer_clean(); + + /* Delete all IP instances. */ + while (_nx_ip_created_ptr) + { + + /* Delete all UDP sockets. */ + while (_nx_ip_created_ptr -> nx_ip_udp_created_sockets_ptr) + { + + /* Make sure the UDP socket is unbound. */ + nx_udp_socket_unbind(_nx_ip_created_ptr -> nx_ip_udp_created_sockets_ptr); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(_nx_ip_created_ptr -> nx_ip_udp_created_sockets_ptr); + } + + /* Delete all TCP sockets. */ + while (_nx_ip_created_ptr -> nx_ip_tcp_created_sockets_ptr) + { + + /* Disconnect. */ + nx_tcp_socket_disconnect(_nx_ip_created_ptr -> nx_ip_tcp_created_sockets_ptr, NX_NO_WAIT); + + /* Make sure the TCP client socket is unbound. */ + nx_tcp_client_socket_unbind(_nx_ip_created_ptr -> nx_ip_tcp_created_sockets_ptr); + + /* Make sure the TCP server socket is unaccepted. */ + nx_tcp_server_socket_unaccept(_nx_ip_created_ptr -> nx_ip_tcp_created_sockets_ptr); + + /* Delete the TCP socket. */ + nx_tcp_socket_delete(_nx_ip_created_ptr -> nx_ip_tcp_created_sockets_ptr); + } + + /* Clear all listen requests. */ + while (_nx_ip_created_ptr -> nx_ip_tcp_active_listen_requests) + { + + /* Make sure the TCP server socket is unlistened. */ + nx_tcp_server_socket_unlisten(_nx_ip_created_ptr, (_nx_ip_created_ptr -> nx_ip_tcp_active_listen_requests) -> nx_tcp_listen_port); + } + + /* Delete the IP instance. */ + nx_ip_delete(_nx_ip_created_ptr); + } + + /* Delete all the packet pools. */ + while (_nx_packet_pool_created_ptr) + { + nx_packet_pool_delete(_nx_packet_pool_created_ptr); + } + + /* Reset the RAM driver. */ + _nx_ram_network_driver_reset(); + + /* Delete all queues. */ + while(_tx_queue_created_ptr) + { + + /* Delete queue. */ + tx_queue_delete(_tx_queue_created_ptr); + } + + /* Delete all semaphores. */ + while(_tx_semaphore_created_ptr) + { +#ifndef NETXTEST_TIMEOUT_DISABLE + if(_tx_semaphore_created_ptr != &test_control_sema) + { + + /* Delete semaphore. */ + tx_semaphore_delete(_tx_semaphore_created_ptr); + } + else if(_tx_semaphore_created_count == 1) + break; + else + { + /* Delete semaphore. */ + tx_semaphore_delete(_tx_semaphore_created_ptr -> tx_semaphore_created_next); + } +#else + /* Delete semaphore. */ + tx_semaphore_delete(_tx_semaphore_created_ptr); +#endif + } + + /* Delete all event flag groups. */ + while(_tx_event_flags_created_ptr) + { + + /* Delete event flag group. */ + tx_event_flags_delete(_tx_event_flags_created_ptr); + } + + /* Delete all byte pools. */ + while(_tx_byte_pool_created_ptr) + { + + /* Delete byte pool. */ + tx_byte_pool_delete(_tx_byte_pool_created_ptr); + } + + /* Delete all block pools. */ + while(_tx_block_pool_created_ptr) + { + + /* Delete block pool. */ + tx_block_pool_delete(_tx_block_pool_created_ptr); + } + + /* Delete all timers. */ + while(_tx_timer_created_ptr) + { + + /* Deactivate timer. */ + tx_timer_deactivate(_tx_timer_created_ptr); + + /* Delete timer. */ + tx_timer_delete(_tx_timer_created_ptr); + } + + /* Delete all mutexes (except for system mutex). */ + while(_tx_mutex_created_ptr) + { + + /* Setup working mutex pointer. */ + mutex_ptr = _tx_mutex_created_ptr; + +#ifdef __ghs + + /* Determine if the mutex is the GHS system mutex. If so, don't delete! */ + if(mutex_ptr == &__ghLockMutex) + { + + /* Move to next mutex. */ + mutex_ptr = mutex_ptr -> tx_mutex_created_next; + } + + /* Determine if there are no more mutexes to delete. */ + if(_tx_mutex_created_count == 1) + break; +#endif + + /* Delete mutex. */ + tx_mutex_delete(mutex_ptr); + } + + /* Delete all threads, except for timer thread, and test control thread. */ + while (_tx_thread_created_ptr) + { + + /* Setup working pointer. */ + thread_ptr = _tx_thread_created_ptr; + +#ifdef TX_TIMER_PROCESS_IN_ISR + + /* Determine if there are more threads to delete. */ + if(_tx_thread_created_count == 1) + break; + + /* Determine if this thread is the test control thread. */ + if(thread_ptr == &test_control_thread) + { + + /* Move to the next thread pointer. */ + thread_ptr = thread_ptr -> tx_thread_created_next; + } +#else + + /* Determine if there are more threads to delete. */ + if(_tx_thread_created_count == 2) + break; + + /* Move to the thread not protected. */ + while ((thread_ptr == &_tx_timer_thread) || (thread_ptr == &test_control_thread)) + { + + /* Yes, move to the next thread. */ + thread_ptr = thread_ptr -> tx_thread_created_next; + } +#endif + + /* First terminate the thread to ensure it is ready for deletion. */ + tx_thread_terminate(thread_ptr); + + /* Delete the thread. */ + tx_thread_delete(thread_ptr); + } + + /* At this point, only the test control thread and the system timer thread and/or mutex should still be + in the system. */ + + +} + +void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number) +{ + *error_counter = (*error_counter) + 1; + + printf("Error: File %s:%d\n", filename, line_number); + + + +} diff --git a/test/regression/mqtt_test/netx_mqtt_transmit_queue_depth_test.c b/test/regression/mqtt_test/netx_mqtt_transmit_queue_depth_test.c new file mode 100644 index 00000000..419dc0fc --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_transmit_queue_depth_test.c @@ -0,0 +1,360 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); + +#if !defined(NXD_MQTT_REQUIRE_TLS) && defined(NXD_MQTT_MAXIMUM_TRANSMIT_QUEUE_DEPTH) + +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC_LEN 256 +#define MESSAGE_LEN 256 +#define CLIENT_MEMORY_SIZE 1024 +#define PACKET_BUFFER_SIZE 1024 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 128 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +static TX_SEMAPHORE semaphore_server_received; +static TX_SEMAPHORE semaphore_client_sent; +static UCHAR pool_area[PACKET_POOL_SIZE]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +static UCHAR *packet_buffer; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_transmit_queue_depth_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_received, "semaphore server received", 0); + tx_semaphore_create(&semaphore_client_sent, "semaphore client sent", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pool_area, PACKET_POOL_SIZE); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + packet_buffer = pointer; + pointer += PACKET_BUFFER_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT QoS; +static UINT retain; +static UCHAR *topic; +static UCHAR *message; + +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Transmit Queue Depth Test............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + error_counter++; + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + topic = packet_buffer; + message = packet_buffer + TOPIC_LEN; + + for (i = 0; i < TOPIC_LEN; i++) + { + topic[i] = i & 0xff; + message[i] = 0xff - (i & 0xff); + } + + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + QoS = 1; + retain = 0; + + /* Send telemetry to fill the transmit queue. */ + for (i = 0 ; i < NXD_MQTT_MAXIMUM_TRANSMIT_QUEUE_DEPTH; i++) + { + + /* Send telemetry */ + status = nxd_mqtt_client_publish(client_ptr, topic, TOPIC_LEN, message, MESSAGE_LEN, retain, QoS, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + } + + /* Send telemetry */ + status = nxd_mqtt_client_publish(client_ptr, topic, TOPIC_LEN, message, MESSAGE_LEN, retain, QoS, 5 * NX_IP_PERIODIC_RATE); + if (status == NXD_MQTT_SUCCESS) + error_counter++; + + tx_semaphore_put(&semaphore_client_sent); + + tx_semaphore_get(&semaphore_server_received, NX_WAIT_FOREVER); + + nxd_mqtt_client_disconnect(client_ptr); + + nxd_mqtt_client_delete(client_ptr); + + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +USHORT packet_id; +UINT len, packet_len; +UCHAR control_header; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + tx_thread_sleep(1); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + if (status) + { + error_counter++; + } + else + { + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + packet_ptr = NX_NULL; + packet_len = 0; + + tx_semaphore_get(&semaphore_client_sent, NX_WAIT_FOREVER); + + while (1) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + if (status) + break; + + nx_packet_release(packet_ptr); + } + + tx_semaphore_put(&semaphore_server_received); + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_transmit_queue_depth_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: MQTT Transmit Queue Depth Test............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/mqtt_test/netx_mqtt_unsubscribe_test.c b/test/regression/mqtt_test/netx_mqtt_unsubscribe_test.c new file mode 100644 index 00000000..005193d8 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_unsubscribe_test.c @@ -0,0 +1,626 @@ +/* MQTT connect test. This test case validates MQTT client connect without username/password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_ID "1234" +#define TOPIC1 "topic1" +#define MESSAGE1 "message1" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 2 +#else +#define TEST_LOOP 1 +#endif + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + + +/* Define what the initial system looks like. */ +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *client_memory; +static CHAR *stack_ptr; +#define CLIENT_MEMORY_SIZE 1024 +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_client_unsubscribe_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 23,23, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 23, 23, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + + client_memory = pointer; + pointer += CLIENT_MEMORY_SIZE; + + client_ptr = (NXD_MQTT_CLIENT*)pointer; +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +static UINT QoS; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Unsubscribe Test ...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, client_memory, CLIENT_MEMORY_SIZE); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i == 0) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); +#ifdef NXD_MQTT_REQUIRE_TLS + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_semaphore_put(&semaphore_client_stop); + continue; +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_IP_PERIODIC_RATE); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(1); + QoS = 1; + /* Issue a subscribe command. */ + status = nxd_mqtt_client_subscribe(client_ptr, TOPIC1, strlen(TOPIC1), QoS); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + + /* Issue an unsubscribe command. */ + status = nxd_mqtt_client_unsubscribe(client_ptr, TOPIC1, strlen(TOPIC1)); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + tx_thread_sleep(1); + + nxd_mqtt_client_disconnect(client_ptr); + + tx_semaphore_put(&semaphore_client_stop); + } + + nxd_mqtt_client_delete(client_ptr); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; + +//static UCHAR fixed_header[] = {0x80, 0x00, /* MQTT Control Packet Type, remaining length */ +// 0x00, 0x00}; /* Packet identifier, MSB, and LSB */ + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *byte; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + //tx_thread_sleep(1); + if (i == 0) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i == 1) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with Connect SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x20; + byte[1] = 0x02; + byte[2] = 0; + byte[3] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the subscribe message. */ + byte = content; + *byte++ = 0x82; /* Subscribe */ + byte++; /* Skip the length field. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[2];/* Fill in packet ID MSB. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[3];/* Fill in packet ID LSB. */ + /* Fill in subscribe topic length MSB and LSB */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + /* Fill in the QoS byte. */ + byte += strlen(TOPIC1); + *byte++ = QoS & 0x3; + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT subscribe request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0x90; + byte[1] = 0x03; + byte[2] = content[2]; + byte[3] = content[3]; + byte[4] = QoS & 0x3; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 5; + packet_ptr->nx_packet_length = 5; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Expect Unsub */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 50); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Expect Unsub */ + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* construct the unsubscribe message. */ + byte = content; + *byte++ = 0xA2; /* Unsubscribe */ + byte++; /* Skip the length field. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[2];/* Fill in packet ID MSB. */ + *byte++ = packet_ptr->nx_packet_prepend_ptr[3];/* Fill in packet ID LSB. */ + /* Fill in subscribe topic length MSB and LSB */ + *byte++ = (strlen(TOPIC1) >> 8) & 0xFF; + *byte++ = strlen(TOPIC1) & 0xFF; + /* Fill in the topic string. */ + memcpy(byte, TOPIC1, strlen(TOPIC1)); + byte += strlen(TOPIC1); + + /* Now validate message length */ + if (packet_ptr->nx_packet_length != (byte - content)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Fill in the remaining length field. */ + content[1] = (packet_ptr->nx_packet_length - 2) & 0xFF; + + /* Validate the MQTT unsubscribe request. */ + if (memcmp(packet_ptr->nx_packet_prepend_ptr, content, packet_ptr->nx_packet_length)) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + byte = packet_ptr->nx_packet_prepend_ptr; + byte[0] = 0xb0; + byte[1] = 0x02; + byte[2] = content[2]; + byte[3] = content[3]; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 4; + packet_ptr->nx_packet_length = 4; + + if (i == 0) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, 1); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Disconnect. */ + tx_thread_sleep(1); + +#ifdef NX_SECURE_ENABLE + if (i == 1) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + diff --git a/test/regression/mqtt_test/netx_mqtt_websocket_block_test.c b/test/regression/mqtt_test/netx_mqtt_websocket_block_test.c new file mode 100644 index 00000000..bcc445f1 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_websocket_block_test.c @@ -0,0 +1,739 @@ +/* MQTT over websocket connect test. This test case validates MQTT client connect over websocket in blocking mode. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +#include "nx_websocket_client.h" +#include "nx_sha1.h" + +extern void test_control_return(UINT status); +#if defined(NXD_MQTT_OVER_WEBSOCKET) + +/* Define the ThreadX and NetX object control blocks... */ +#define DEMO_STACK_SIZE 2048 +#define CLIENT_ID "1234" +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define HOST_NAME "test.host.org" +#define TEST_CONNECT_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" +#define TEST_CONNECT_GUID_SIZE (sizeof(TEST_CONNECT_GUID) - 1) +#define TEST_CONNECT_DIGEST_SIZE 21 /* The length of SHA-1 hash is 20 bytes, with 1 extra byte for base64 encode calculation */ +#define TEST_CONNECT_KEY_SIZE 32 /* Make it larger than the minimum length (28 bytes )for the encoded key */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +static UCHAR connect_key[TEST_CONNECT_KEY_SIZE]; +static UINT connect_key_size; + +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 4 +#else +#define TEST_LOOP 2 +#endif + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_websocket_block_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Websocket Block Test................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, NX_NULL, 0); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if ((status = nxd_mqtt_client_websocket_set(client_ptr, (UCHAR *)HOST_NAME, sizeof(HOST_NAME) - 1, (UCHAR *)"/mqtt", sizeof("/mqtt") - 1))) + { + printf("Error setting MQTT websocket: 0x%02x\r\n", status); + return; + } + + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i < 2) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, NX_WAIT_FOREVER); + +#ifndef NXD_MQTT_REQUIRE_TLS + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, NX_WAIT_FOREVER); + + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + +#ifdef NXD_MQTT_REQUIRE_TLS + if (i >= 2) +#endif + { + nxd_mqtt_client_disconnect(client_ptr); + } + + tx_semaphore_put(&semaphore_client_stop); + } + nxd_mqtt_client_delete(client_ptr); + + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + error_counter++; + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; +static UCHAR server_switch_101[] = +{ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x31, 0x30, 0x31, 0x20, 0x53, 0x77, 0x69, /* HTTP/1.1 101 Swi */ +0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, /* tching Protocols */ +0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x57, 0x65, 0x62, 0x53, 0x6f, /* ..Upgrade: WebSo */ +0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, /* cket..Connection */ +0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, /* : Upgrade..Sec-W */ +0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, /* ebSocket-Accept: */ +0x20, 0x64, 0x4f, 0x32, 0x68, 0x36, 0x5a, 0x4c, 0x46, 0x33, 0x71, 0x54, 0x74, 0x4d, 0x48, 0x7a, /* dO2h6ZLF3qTtMHz */ +0x47, 0x4b, 0x69, 0x59, 0x76, 0x53, 0x52, 0x45, 0x57, 0x6a, 0x76, 0x55, 0x3d, 0x0d, 0x0a, 0x53, /* GKiYvSREWjvU=..S */ +0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x50, 0x72, 0x6f, /* ec-WebSocket-Pro */ +0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x3a, 0x20, 0x6d, 0x71, 0x74, 0x74, 0x0d, 0x0a, 0x0d, 0x0a, /* tocol: mqtt.... */ +}; + + +static UINT _server_connect_response_process(NX_PACKET *packet_ptr) +{ +UCHAR *buffer_ptr; +UINT offset = 0; +UCHAR *field_name; +UINT field_name_length; +UCHAR *field_value; +UINT field_value_length; +NX_SHA1 SH; +UCHAR digest[TEST_CONNECT_DIGEST_SIZE]; + + buffer_ptr = packet_ptr -> nx_packet_prepend_ptr; + + /* Skip over the first Command line (GET /xxx HTTP/1.1\r\n). */ + while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && + (*buffer_ptr != '\r') && (*(buffer_ptr + 1) != '\n')) + { + buffer_ptr++; + offset++; + } + + /* Skip over the CR,LF. */ + buffer_ptr += 2; + offset += 2; + + /* Skip over the first Host line (Host: xxx\r\n). */ + while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && + (*buffer_ptr != '\r') && (*(buffer_ptr + 1) != '\n')) + { + buffer_ptr++; + offset++; + } + + /* Skip over the CR,LF. */ + buffer_ptr += 2; + offset += 2; + + /* Loop until we find the "cr,lf,cr,lf" token. */ + while (((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != 0)) + { + + /* Check for the token. This signals a blank line, which also + specifies the start of the content. */ + if ((*buffer_ptr == '\r') && + (*(buffer_ptr + 1) == '\n')) + { + + /* Adjust the offset. */ + offset = offset + 2; + break; + } + + /* We haven't seen the so we are still processing header data. + Extract the field name and it's value. */ + field_name = buffer_ptr; + field_name_length = 0; + + /* Look for the ':' that separates the field name from its value. */ + while(*buffer_ptr != ':') + { + buffer_ptr++; + field_name_length++; + } + offset += field_name_length; + + /* Skip ':'. */ + buffer_ptr++; + offset++; + + /* Now skip over white space. */ + while ((buffer_ptr < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' ')) + { + buffer_ptr++; + offset++; + } + + /* Now get the field value. */ + field_value = buffer_ptr; + field_value_length = 0; + + /* Loop until we see a . */ + while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != '\r') && (*(buffer_ptr+1) != '\n')) + { + buffer_ptr++; + field_value_length++; + } + offset += field_value_length; + + /* Skip over the CR,LF. */ + buffer_ptr += 2; + offset += 2; + + /* Check the upgrade. */ + if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Upgrade", sizeof("Upgrade") - 1) == NX_SUCCESS) + { + if (_nx_websocket_client_name_compare((UCHAR *)field_value, field_value_length, (UCHAR *)"websocket", sizeof("websocket") - 1)) + { + return(NX_WEBSOCKET_INVALID_PACKET); + } + } + else if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Connection", sizeof("Connection") - 1) == NX_SUCCESS) + { + if (_nx_websocket_client_name_compare((UCHAR *)field_value, field_value_length, (UCHAR *)"Upgrade", sizeof("Upgrade") - 1)) + { + return(NX_WEBSOCKET_INVALID_PACKET); + } + } + else if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Sec-WebSocket-Key", sizeof("Sec-WebSocket-Key") - 1) == NX_SUCCESS) + { + + /* Calculate the SHA-1 hash of the concatenation of the client key and the Globally Unique Identifier (GUID) + Referenced in RFC 6455, Section 1.3, Page 6 */ + _nx_sha1_initialize(&SH); + _nx_sha1_update(&SH, field_value, field_value_length); + _nx_sha1_update(&SH, (UCHAR*)TEST_CONNECT_GUID, TEST_CONNECT_GUID_SIZE); + _nx_sha1_digest_calculate(&SH, digest); + + /* Set the last extra byte of the digest to be zero, since the function _nx_utility_base64_encode will use this byte for calculation */ + digest[20] = 0; + + /* Encode the hash and compare it with the field value from the server. */ + _nx_utility_base64_encode(digest, (TEST_CONNECT_DIGEST_SIZE - 1), connect_key, TEST_CONNECT_KEY_SIZE, &connect_key_size); + } + } + + /* Check if the all fields are processed. */ + if (offset != packet_ptr -> nx_packet_length) + { + return(NX_WEBSOCKET_INVALID_PACKET); + } + + return(NX_SUCCESS); +} + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *buffer_ptr; +UINT i, j; +UINT length; +UINT packet_count; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i >= 2) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i >= 2) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + + /* Receive websocket connect. */ + if (i < 2) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Get connect_key. */ + _server_connect_response_process(packet_ptr); + memcpy(&server_switch_101[97], connect_key, 28); + nx_packet_release(packet_ptr); + + if (i % 2 == 0) + { + packet_count = 1; + } + else + { + packet_count = 3; + } + + buffer_ptr = server_switch_101; + for (j = 0; j < packet_count; j++) + { + + if ((packet_count == 3) && (j < 2)) + { + length = 50; + } + else + { + length = sizeof(server_switch_101) - 50 * j; + } + + if (i < 2) + { + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#ifdef NX_SECURE_ENABLE + else + { + + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Append response 101. */ + status = nx_packet_data_append(packet_ptr, buffer_ptr, length, &pool_0, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Send websocket connect response. */ + if (i < 2) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + buffer_ptr += length; + } + + /* Receive MQTT connect. */ + if (i < 2) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i >= 2) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + +#ifdef NX_SECURE_ENABLE + if (i >= 2) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + buffer_ptr = packet_ptr->nx_packet_prepend_ptr; + buffer_ptr[0] = 0x82; + buffer_ptr[1] = 0x04; + buffer_ptr[2] = 0x20; + buffer_ptr[3] = 0x02; + buffer_ptr[4] = 0; + buffer_ptr[5] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 6; + packet_ptr->nx_packet_length = 6; + + if (i < 2) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i >= 2) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_websocket_block_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: MQTT Websocket Block Test.................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/mqtt_test/netx_mqtt_websocket_non_block_test.c b/test/regression/mqtt_test/netx_mqtt_websocket_non_block_test.c new file mode 100644 index 00000000..300cfd96 --- /dev/null +++ b/test/regression/mqtt_test/netx_mqtt_websocket_non_block_test.c @@ -0,0 +1,762 @@ +/* MQTT over websocket connect test. This test case validates MQTT client connect over websocket in non-blocking mode. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nxd_mqtt_client.h" +#include "nx_websocket_client.h" +#include "nx_sha1.h" + +extern void test_control_return(UINT status); +#if defined(NX_ENABLE_EXTENDED_NOTIFY_SUPPORT) && defined(NXD_MQTT_OVER_WEBSOCKET) + +/* Define the ThreadX and NetX object control blocks... */ +#define DEMO_STACK_SIZE 2048 +#define CLIENT_ID "1234" +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define HOST_NAME "test.host.org" +#define TEST_CONNECT_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" +#define TEST_CONNECT_GUID_SIZE (sizeof(TEST_CONNECT_GUID) - 1) +#define TEST_CONNECT_DIGEST_SIZE 21 /* The length of SHA-1 hash is 20 bytes, with 1 extra byte for base64 encode calculation */ +#define TEST_CONNECT_KEY_SIZE 32 /* Make it larger than the minimum length (28 bytes )for the encoded key */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET server_socket; + + +static UCHAR connect_key[TEST_CONNECT_KEY_SIZE]; +static UINT connect_key_size; + +static NXD_MQTT_CLIENT *client_ptr; +static UCHAR *stack_ptr; + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_stop; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG connected = NX_FALSE; + +#ifdef NX_SECURE_ENABLE + +#include "../web_test/test_device_cert.c" +#include "../web_test/test_ca_cert.c" + +/* Declare external cryptosuites. */ +extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers; + +static NX_SECURE_TLS_SESSION tls_server_session; +static NX_SECURE_X509_CERT server_local_certificate; + +/* Define crypto metadata buffer. */ +static UCHAR client_metadata[5*4096]; +static UCHAR server_metadata[5*4096]; + +/* For remote certificate. */ +static NX_SECURE_X509_CERT remote_certificate, remote_issuer, ca_certificate; +static UCHAR remote_cert_buffer[2000]; +static UCHAR remote_issuer_buffer[2000]; +static UCHAR tls_packet_buffer[2][4096]; + +#define TEST_LOOP 4 +#else +#define TEST_LOOP 2 +#endif + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void SET_ERROR_COUNTER(ULONG *error_counter, CHAR *filename, int line_number); +static void mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr, UINT status, VOID *context); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_websocket_non_block_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_stop, "semaphore client stop", 0); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + stack_ptr = pointer; + pointer += DEMO_STACK_SIZE; + client_ptr = (NXD_MQTT_CLIENT*)pointer; + +} + +#ifdef NX_SECURE_ENABLE + +/* Define the callback function for tls connection. */ +static UINT client_tls_setup(NXD_MQTT_CLIENT* client_ptr, NX_SECURE_TLS_SESSION* tls_session, + NX_SECURE_X509_CERT* certificate, NX_SECURE_X509_CERT* trusted_certificate) +{ +UINT status; + + /* Create a tls session. */ + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + client_metadata, + sizeof(client_metadata)); + + if (status) + { + return status; + } + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[0], sizeof(tls_packet_buffer[0])); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer)); + nx_secure_tls_remote_certificate_allocate(tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer)); + + nx_secure_x509_certificate_initialize(&ca_certificate, test_ca_cert_der, test_ca_cert_der_len, + NX_NULL, 0, NX_NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); + nx_secure_tls_trusted_certificate_add(tls_session, &ca_certificate); + + return(NX_SUCCESS); +} + +static UINT server_tls_setup(NX_SECURE_TLS_SESSION *tls_session) +{ +UINT status; + + status = nx_secure_tls_session_create(tls_session, + &nx_crypto_tls_ciphers, + server_metadata, + sizeof(server_metadata)); + if (status) + { + return status; + } + + memset(&server_local_certificate, 0, sizeof(server_local_certificate)); + nx_secure_x509_certificate_initialize(&server_local_certificate, + test_device_cert_der, test_device_cert_der_len, + NX_NULL, 0, test_device_cert_key_der, + test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER); + + nx_secure_tls_local_certificate_add(tls_session, &server_local_certificate); + + nx_secure_tls_session_packet_buffer_set(tls_session, tls_packet_buffer[1], sizeof(tls_packet_buffer[1])); + + return(NX_SUCCESS); +} +#endif + +#define MQTT_CLIENT_THREAD_PRIORITY 2 +static UINT keepalive_value; +static UINT cleansession_value; +/* Define the test threads. */ +/* This thread sets up MQTT client and makes a connect request without username/password. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS server_address; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: MQTT Websocket Non Block Test............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_mqtt_client_create(client_ptr, "my client", CLIENT_ID, strlen(CLIENT_ID), &ip_0, &pool_0, + stack_ptr, DEMO_STACK_SIZE, MQTT_CLIENT_THREAD_PRIORITY, NX_NULL, 0); + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + if ((status = nxd_mqtt_client_websocket_set(client_ptr, (UCHAR *)HOST_NAME, sizeof(HOST_NAME) - 1, (UCHAR *)"/mqtt", sizeof("/mqtt") - 1))) + { + printf("Error setting MQTT websocket: 0x%02x\r\n", status); + return; + } + + tx_thread_sleep(1); + + server_address.nxd_ip_version = 4; + server_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + keepalive_value = 0; + cleansession_value = 0; + + client_ptr-> nxd_mqtt_connect_notify = mqtt_connect_notify; + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + if (i < 2) + { + status = nxd_mqtt_client_connect(client_ptr, &server_address, NXD_MQTT_PORT, + keepalive_value, cleansession_value, 0); + +#ifndef NXD_MQTT_REQUIRE_TLS + if (status != NX_IN_PROGRESS) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#else + if (status != NXD_MQTT_CONNECT_FAILURE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +#endif + } +#ifdef NX_SECURE_ENABLE + else + { + status = nxd_mqtt_client_secure_connect(client_ptr, &server_address, NXD_MQTT_PORT, + client_tls_setup, + keepalive_value, cleansession_value, 0); + + if (status != NX_IN_PROGRESS) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + +#ifdef NXD_MQTT_REQUIRE_TLS + if (i >= 2) +#endif + { + + /* Wait for connecting. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check connected flag. */ + if (connected == NX_FALSE) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + nxd_mqtt_client_disconnect(client_ptr); + } + + tx_semaphore_put(&semaphore_client_stop); + } + nxd_mqtt_client_delete(client_ptr); + + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + error_counter++; + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UCHAR content[100]; +static UCHAR fixed_header[] = {0x10, 0x00, 0x00, 0x04, 'M', 'Q', 'T', 'T', 0x4, 0x0, 0x0, 0x0}; +static UCHAR server_switch_101[] = +{ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x31, 0x30, 0x31, 0x20, 0x53, 0x77, 0x69, /* HTTP/1.1 101 Swi */ +0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, /* tching Protocols */ +0x0d, 0x0a, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x3a, 0x20, 0x57, 0x65, 0x62, 0x53, 0x6f, /* ..Upgrade: WebSo */ +0x63, 0x6b, 0x65, 0x74, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, /* cket..Connection */ +0x3a, 0x20, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x0d, 0x0a, 0x53, 0x65, 0x63, 0x2d, 0x57, /* : Upgrade..Sec-W */ +0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, /* ebSocket-Accept: */ +0x20, 0x64, 0x4f, 0x32, 0x68, 0x36, 0x5a, 0x4c, 0x46, 0x33, 0x71, 0x54, 0x74, 0x4d, 0x48, 0x7a, /* dO2h6ZLF3qTtMHz */ +0x47, 0x4b, 0x69, 0x59, 0x76, 0x53, 0x52, 0x45, 0x57, 0x6a, 0x76, 0x55, 0x3d, 0x0d, 0x0a, 0x53, /* GKiYvSREWjvU=..S */ +0x65, 0x63, 0x2d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2d, 0x50, 0x72, 0x6f, /* ec-WebSocket-Pro */ +0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x3a, 0x20, 0x6d, 0x71, 0x74, 0x74, 0x0d, 0x0a, 0x0d, 0x0a, /* tocol: mqtt.... */ +}; + + +static UINT _server_connect_response_process(NX_PACKET *packet_ptr) +{ +UCHAR *buffer_ptr; +UINT offset = 0; +UCHAR *field_name; +UINT field_name_length; +UCHAR *field_value; +UINT field_value_length; +NX_SHA1 SH; +UCHAR digest[TEST_CONNECT_DIGEST_SIZE]; + + buffer_ptr = packet_ptr -> nx_packet_prepend_ptr; + + /* Skip over the first Command line (GET /xxx HTTP/1.1\r\n). */ + while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && + (*buffer_ptr != '\r') && (*(buffer_ptr + 1) != '\n')) + { + buffer_ptr++; + offset++; + } + + /* Skip over the CR,LF. */ + buffer_ptr += 2; + offset += 2; + + /* Skip over the first Host line (Host: xxx\r\n). */ + while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && + (*buffer_ptr != '\r') && (*(buffer_ptr + 1) != '\n')) + { + buffer_ptr++; + offset++; + } + + /* Skip over the CR,LF. */ + buffer_ptr += 2; + offset += 2; + + /* Loop until we find the "cr,lf,cr,lf" token. */ + while (((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != 0)) + { + + /* Check for the token. This signals a blank line, which also + specifies the start of the content. */ + if ((*buffer_ptr == '\r') && + (*(buffer_ptr + 1) == '\n')) + { + + /* Adjust the offset. */ + offset = offset + 2; + break; + } + + /* We haven't seen the so we are still processing header data. + Extract the field name and it's value. */ + field_name = buffer_ptr; + field_name_length = 0; + + /* Look for the ':' that separates the field name from its value. */ + while(*buffer_ptr != ':') + { + buffer_ptr++; + field_name_length++; + } + offset += field_name_length; + + /* Skip ':'. */ + buffer_ptr++; + offset++; + + /* Now skip over white space. */ + while ((buffer_ptr < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr == ' ')) + { + buffer_ptr++; + offset++; + } + + /* Now get the field value. */ + field_value = buffer_ptr; + field_value_length = 0; + + /* Loop until we see a . */ + while(((buffer_ptr + 1) < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr != '\r') && (*(buffer_ptr+1) != '\n')) + { + buffer_ptr++; + field_value_length++; + } + offset += field_value_length; + + /* Skip over the CR,LF. */ + buffer_ptr += 2; + offset += 2; + + /* Check the upgrade. */ + if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Upgrade", sizeof("Upgrade") - 1) == NX_SUCCESS) + { + if (_nx_websocket_client_name_compare((UCHAR *)field_value, field_value_length, (UCHAR *)"websocket", sizeof("websocket") - 1)) + { + return(NX_WEBSOCKET_INVALID_PACKET); + } + } + else if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Connection", sizeof("Connection") - 1) == NX_SUCCESS) + { + if (_nx_websocket_client_name_compare((UCHAR *)field_value, field_value_length, (UCHAR *)"Upgrade", sizeof("Upgrade") - 1)) + { + return(NX_WEBSOCKET_INVALID_PACKET); + } + } + else if (_nx_websocket_client_name_compare((UCHAR *)field_name, field_name_length, (UCHAR *)"Sec-WebSocket-Key", sizeof("Sec-WebSocket-Key") - 1) == NX_SUCCESS) + { + + /* Calculate the SHA-1 hash of the concatenation of the client key and the Globally Unique Identifier (GUID) + Referenced in RFC 6455, Section 1.3, Page 6 */ + _nx_sha1_initialize(&SH); + _nx_sha1_update(&SH, field_value, field_value_length); + _nx_sha1_update(&SH, (UCHAR*)TEST_CONNECT_GUID, TEST_CONNECT_GUID_SIZE); + _nx_sha1_digest_calculate(&SH, digest); + + /* Set the last extra byte of the digest to be zero, since the function _nx_utility_base64_encode will use this byte for calculation */ + digest[20] = 0; + + /* Encode the hash and compare it with the field value from the server. */ + _nx_utility_base64_encode(digest, (TEST_CONNECT_DIGEST_SIZE - 1), connect_key, TEST_CONNECT_KEY_SIZE, &connect_key_size); + } + } + + /* Check if the all fields are processed. */ + if (offset != packet_ptr -> nx_packet_length) + { + return(NX_WEBSOCKET_INVALID_PACKET); + } + + return(NX_SUCCESS); +} + +/* This thread acts as MQTT server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UCHAR *buffer_ptr; +UINT i, j; +UINT length; +UINT packet_count; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, NXD_MQTT_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + /* Session setup. */ + server_tls_setup(&tls_server_session); +#endif + + tx_thread_resume(&ntest_0); + + for (i = 0; i < TEST_LOOP; i++) + { + + tx_semaphore_put(&semaphore_server_start); + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i >= 2) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + if (i >= 2) + { + status = nx_secure_tls_session_start(&tls_server_session, &server_socket, NX_WAIT_FOREVER); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + tx_thread_sleep(1); + + /* Receive websocket connect. */ + if (i < 2) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Get connect_key. */ + _server_connect_response_process(packet_ptr); + memcpy(&server_switch_101[97], connect_key, 28); + nx_packet_release(packet_ptr); + + if (i % 2 == 0) + { + packet_count = 1; + } + else + { + packet_count = 3; + } + + buffer_ptr = server_switch_101; + for (j = 0; j < packet_count; j++) + { + + if ((packet_count == 3) && (j < 2)) + { + length = 50; + } + else + { + length = sizeof(server_switch_101) - 50 * j; + } + + if (i < 2) + { + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#ifdef NX_SECURE_ENABLE + else + { + + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Append response 101. */ + status = nx_packet_data_append(packet_ptr, buffer_ptr, length, &pool_0, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Send websocket connect response. */ + if (i < 2) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + buffer_ptr += length; + } + + /* Receive MQTT connect. */ + if (i < 2) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_receive(&tls_server_session, &packet_ptr, NX_WAIT_FOREVER); + } +#endif + + if (status) + { +#ifdef NXD_MQTT_REQUIRE_TLS + if (i >= 2) +#endif + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + else + { + +#ifdef NX_SECURE_ENABLE + if (i >= 2) + { + nx_packet_release(packet_ptr); + status = nx_secure_tls_packet_allocate(&tls_server_session, &pool_0, &packet_ptr, NX_NO_WAIT); + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } +#endif + + /* Response with SUCCESS */ + buffer_ptr = packet_ptr->nx_packet_prepend_ptr; + buffer_ptr[0] = 0x82; + buffer_ptr[1] = 0x04; + buffer_ptr[2] = 0x20; + buffer_ptr[3] = 0x02; + buffer_ptr[4] = 0; + buffer_ptr[5] = 0; + + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + 6; + packet_ptr->nx_packet_length = 6; + + if (i < 2) + { + status = nx_tcp_socket_send(&server_socket, packet_ptr, NX_IP_PERIODIC_RATE); + } +#ifdef NX_SECURE_ENABLE + else + { + status = nx_secure_tls_session_send(&tls_server_session, packet_ptr, NX_WAIT_FOREVER); + } +#endif + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + +#ifdef NX_SECURE_ENABLE + if (i >= 2) + { + /* End session. */ + nx_secure_tls_session_end(&tls_server_session, NX_NO_WAIT); + } +#endif + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + + tx_semaphore_get(&semaphore_client_stop, NX_WAIT_FOREVER); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Prepare to accept another connection. */ + status = nx_tcp_server_socket_relisten(&ip_1, NXD_MQTT_PORT, &server_socket); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + } + +#ifdef NX_SECURE_ENABLE + /* Delete the session. */ + nx_secure_tls_session_delete(&tls_server_session); +#endif + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, NXD_MQTT_PORT); + + /* Check for error. */ + if (status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + SET_ERROR_COUNTER(&error_counter, __FILE__, __LINE__); +} + + +static void mqtt_connect_notify(struct NXD_MQTT_CLIENT_STRUCT *client_ptr, UINT status, VOID *context) +{ + + /* Check status. */ + if (status == NXD_MQTT_SUCCESS) + { + connected = NX_TRUE; + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_mqtt_websocket_non_block_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: MQTT Websocket Non Block Test.............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/nat_test/netx_nat_entry_removed_after_timeout_test.c b/test/regression/nat_test/netx_nat_entry_removed_after_timeout_test.c new file mode 100644 index 00000000..fb83e00a --- /dev/null +++ b/test/regression/nat_test/netx_nat_entry_removed_after_timeout_test.c @@ -0,0 +1,554 @@ + +/* This NetX test concentrates on the NAT TCP operation and + the NX_NAT_NON_TCP_SESSION_TIMEOUT and NX_NAT_TCP_SESSION_TIMEOUT + expirations. This test verifies the entries are removed when + the table checks for expired entries. + + Note that NX_NAT_ENABLE_REPLACEMENT is not necessary for this test. + +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_nat.h" + +extern void test_control_return(UINT status); + +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) + + +#define DEMO_STACK_SIZE 2048 + +static UINT error_counter = 0; + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_PACKET_POOL nat_packet_pool; +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_TCP_SOCKET tcp_socket; +NX_UDP_SOCKET udp_socket; + + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT entries memory size. Should be 5 entries. */ +#define NX_NAT_ENTRY_CACHE_SIZE 148 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +#define CONNECT_PEER_PORT 0x89 +#define CONNECT_LOCAL_PORT 0x69 + +/* Set up counters */ +static UINT found_entries = 0; +static UINT removed_entries = 0; +static UINT time_lapse = 0; + +/* This is based on the NAT Non TCP Session default timeout of 120 ticks + and TCP Session timeout of 300 ticks for regression testing. */ +#define TIME_SLICE 25 + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define thread prototypes. */ +static void thread_client_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_entry_removed_after_timeout_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; +UINT error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the first client thread. */ + tx_thread_create(&thread_client, "client thread", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + } + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP isntance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP isntance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&local_ip); + status += nx_icmp_enable(&local_ip); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; +} + +/* Define the test threads. */ + +static void thread_client_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +UINT peer_port; +UINT local_port; +UINT found; +NX_PACKET *my_packet; +UINT time_to_search; +NX_NAT_TRANSLATION_ENTRY search_entry; +NX_NAT_TRANSLATION_ENTRY *entry_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: NAT Remove Expired_Entries Test.............................\n"); + + /* Check error status on set up. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); + + /* Create a TCP local socket. */ + status = nx_tcp_socket_create(&local_ip, &tcp_socket, "TCP Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP local socket. */ + status = nx_udp_socket_create(&local_ip, &udp_socket, "UDP Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + peer_port = CONNECT_PEER_PORT; + local_port = CONNECT_LOCAL_PORT; + + /* Iterate enough time for all three entries to expire. */ + for (i = 0; i < 8; i++) + { + + /* Check if we have found 3 expired entries in the NAT table. */ + if (found_entries == 3) + { + break; + } + + /* Fill up NAT table for 4 different entries. */ + + if ((i == 1) || (i == 0)) + { + + /* Bind the UDP socket to a new local port. */ + status = nx_udp_socket_bind(&udp_socket, local_port, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + error_counter++; + break; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + error_counter++; + break; + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet to a different peer port. */ + status = nx_udp_socket_send(&udp_socket, my_packet, NX_NAT_EXTERNAL_HOST, peer_port); + + /* Check status. */ + if (status) + { + + error_counter++; + break; + } + + status = nx_udp_socket_unbind(&udp_socket); + + /* Check status. */ + if (status) + { + + error_counter++; + break; + } + + tx_thread_sleep(2*TIME_SLICE); + + } + else if (i == 2) + { + + /* Bind the socket to the next highest local port from the last entry in the table. */ + status = nx_tcp_client_socket_bind(&tcp_socket, local_port, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + break; + } + + /* Attempt to connect the socket to the external host on a destination port higher than the last entry in the table. */ + status = nx_tcp_client_socket_connect(&tcp_socket, NX_NAT_EXTERNAL_HOST, peer_port, TIME_SLICE); // jlc use symbols + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&tcp_socket); + + /* Check for error. */ + if (status) + { + /* If an error, abort test. */ + error_counter++; + break; + } + + tx_thread_sleep(TIME_SLICE); + + } + else + { + + /* Just wait for another entry to expire. */ + tx_thread_sleep(2*TIME_SLICE); + + } + + /* Check if we have an entry timeout */ + time_lapse = tx_time_get(); + time_to_search = NX_TRUE; + + /* Check if the TCP entry has expired. */ + if (time_lapse >= ((2*TIME_SLICE)*2 + NX_NAT_TCP_SESSION_TIMEOUT)) + { + /* The TCP entry should have expired. */ + search_entry.protocol = NX_PROTOCOL_TCP; + search_entry.local_port = CONNECT_LOCAL_PORT+2; + search_entry.peer_port = CONNECT_PEER_PORT+2; + } + /* Check if the second UDP entry has expired. Ignore if it has already + expired and been removed.*/ + else if ((time_lapse >= (2*TIME_SLICE + NX_NAT_NON_TCP_SESSION_TIMEOUT) && + found_entries == 1)) + { + + /* Second UDP entry should be expired. */ + search_entry.protocol = NX_PROTOCOL_UDP; + search_entry.local_port = CONNECT_LOCAL_PORT+1; + search_entry.peer_port = CONNECT_PEER_PORT+1; + } + + /* Check if the first UDP entry has expired. Ignore if it + has already expired and been removed. */ + else if ((time_lapse > NX_NAT_NON_TCP_SESSION_TIMEOUT) && + (found_entries == 0)) + { + + /* First TCP entry should be expired. */ + search_entry.protocol = NX_PROTOCOL_UDP; + search_entry.local_port = CONNECT_LOCAL_PORT; + search_entry.peer_port = CONNECT_PEER_PORT; + } + else + { + + /* No entries expired in this loop iteration. */ + time_to_search = NX_FALSE; + } + + /* Do we expect an entry expiration*/ + if (time_to_search) + { + + /* Yes, search for this entry in the table. */ + + /* Fill in the rest of the record with addresses. */ + search_entry.local_ip_address = NX_NAT_LOCAL_HOST1; + search_entry.peer_ip_address = NX_NAT_EXTERNAL_HOST; + + /* Get the start of the NAT list of dynamic entries. */ + entry_ptr = nat_server.nx_nat_dynamic_active_entry_head; + + found = NX_FALSE; + + /* Search the whole table until a match is found. */ + while (entry_ptr) + { + + /* Do sender and entry protocols match? */ + if ((search_entry.protocol == entry_ptr -> protocol) && + (search_entry.peer_ip_address == entry_ptr -> peer_ip_address) && + (search_entry.peer_port == entry_ptr -> peer_port) && + (search_entry.local_ip_address == entry_ptr -> local_ip_address) && + (search_entry.local_port == entry_ptr -> local_port)) + { + + /* We have a matching entry. */ + found_entries++; + found = NX_TRUE; + break; + } + + entry_ptr = entry_ptr -> next_entry_ptr; + } + + /* If not found, the test failed. */ + if (!found) + { + error_counter++; + break; + } + + /* Send a ping so we force NAT to check the table for expired entries. */ + nx_icmp_ping(&local_ip, NX_NAT_EXTERNAL_HOST + i, "ABC", 3, &my_packet, 1); + + /* Get the start of the NAT list of dynamic entries. */ + entry_ptr = nat_server.nx_nat_dynamic_active_entry_head; + + found = NX_FALSE; + + /* Search the table again to verify the entry is removed. */ + while (entry_ptr) + { + + /* Do search and entry protocols match? */ + if ((search_entry.protocol == entry_ptr -> protocol) && + (search_entry.peer_ip_address == entry_ptr -> peer_ip_address) && + (search_entry.peer_port == entry_ptr -> peer_port) && + (search_entry.local_ip_address == entry_ptr -> local_ip_address) && + (search_entry.local_port == entry_ptr -> local_port)) + { + + /* We have a matching entry. */ + found = NX_TRUE; + break; + } + + entry_ptr = entry_ptr -> next_entry_ptr; + } + + /* If found, the test failed, the entry was not removed. */ + if (found) + { + error_counter++; + break; + } + else + { + removed_entries++; + } + } + + if (i < 3) + { + + /* Increment the connection port only if we are still adding entries. */ + local_port ++; + peer_port ++; + } + } + + /* All three of the original UDP and TCP entries should have been found removed. */ + while (found_entries < 3) + { + error_counter++; + } + + /* Final check on error status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_entry_removed_after_timeout_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT Remove Expired_Entries Test...........................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/nat_test/netx_nat_icmp_test.c b/test/regression/nat_test/netx_nat_icmp_test.c new file mode 100644 index 00000000..243c7219 --- /dev/null +++ b/test/regression/nat_test/netx_nat_icmp_test.c @@ -0,0 +1,492 @@ + +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_udp.h" + +extern void test_control_return(UINT status); +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined(NX_DISABLE_IPV4) +#include "nx_nat.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_PACKET_POOL nat_packet_pool; + + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT entries memory size. */ +#define NX_NAT_ENTRY_CACHE_SIZE 1024 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +/* Create NAT structures for preloading NAT tables with static + entries for local server hosts. */ +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_icmp; + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_icmp_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UINT error_counter = 0; +UCHAR *pointer; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + return; + + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for external network IP instance */ + status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for External IP instance. */ + status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP isntance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP isntance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for External IP isntance. */ + status = nx_arp_enable(&external_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ICMP. */ + nx_icmp_enable(&nat_ip); + nx_icmp_enable(&local_ip); + nx_icmp_enable(&external_ip); + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: NAT ICMP Processing Test.................................."); + + /* Local IP ping NAT Local address. */ + status = nx_icmp_ping(&local_ip, NX_NAT_LOCAL_IPADR, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&local_ip, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 1) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check the NAT forwarded count. */ +#ifndef NX_DISABLE_NAT_INFO + if ((nat_server.forwarded_packets_received != 0) || (nat_server.forwarded_packets_sent != 0) ||(nat_server.forwarded_packets_dropped != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Local IP ping External Host address. */ + status = nx_icmp_ping(&local_ip, NX_NAT_EXTERNAL_HOST, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&local_ip, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 1) || (pings_sent != 2) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check the NAT forwarded count. */ +#ifndef NX_DISABLE_NAT_INFO + if ((nat_server.forwarded_packets_received != 0) || (nat_server.forwarded_packets_sent != 0) ||(nat_server.forwarded_packets_dropped != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* External IP ping NAT External address. */ + status = nx_icmp_ping(&external_ip, NX_NAT_EXTERNAL_IPADR, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&external_ip, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 1) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check the NAT forwarded count. */ +#ifndef NX_DISABLE_NAT_INFO + if ((nat_server.forwarded_packets_received != 0) || (nat_server.forwarded_packets_sent != 0) ||(nat_server.forwarded_packets_dropped != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); + + /* Local IP ping External Host address. */ + status = nx_icmp_ping(&local_ip, NX_NAT_EXTERNAL_HOST, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&local_ip, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 1) || (pings_sent != 3) || (ping_responses_received != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check the NAT forwarded count. */ +#ifndef NX_DISABLE_NAT_INFO + if ((nat_server.forwarded_packets_received != 2) || (nat_server.forwarded_packets_sent != 2) ||(nat_server.forwarded_packets_dropped != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* External IP ping NAT External address. */ + status = nx_icmp_ping(&external_ip, NX_NAT_EXTERNAL_IPADR, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&external_ip, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 2) || (ping_responses_received != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check the NAT forwarded count. */ +#ifndef NX_DISABLE_NAT_INFO + if ((nat_server.forwarded_packets_received != 3) || (nat_server.forwarded_packets_sent != 2) ||(nat_server.forwarded_packets_dropped != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Calling NAT API to preload a static entry. */ + status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_icmp, NX_NAT_LOCAL_HOST1, 0, 0, NX_PROTOCOL_ICMP); + + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* External IP ping NAT External address. */ + status = nx_icmp_ping(&external_ip, NX_NAT_EXTERNAL_IPADR, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&external_ip, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 3) || (ping_responses_received != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check the NAT forwarded count. */ +#ifndef NX_DISABLE_NAT_INFO + if ((nat_server.forwarded_packets_received != 5) || (nat_server.forwarded_packets_sent != 4) ||(nat_server.forwarded_packets_dropped != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_icmp_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT ICMP Processing Test..................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/nat_test/netx_nat_invalid_header_test.c b/test/regression/nat_test/netx_nat_invalid_header_test.c new file mode 100644 index 00000000..0b59d57e --- /dev/null +++ b/test/regression/nat_test/netx_nat_invalid_header_test.c @@ -0,0 +1,489 @@ + +/* This NetX test concentrates on the UCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_udp.h" + +extern void test_control_return(UINT status); +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined(NX_DISABLE_IPV4) +#include "nx_nat.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_PACKET_POOL nat_packet_pool; +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_UDP_SOCKET local_socket; +NX_UDP_SOCKET external_socket; + + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT entries memory size. */ +#define NX_NAT_ENTRY_CACHE_SIZE 1024 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +/* Create NAT structures for preloading NAT tables with static + entries for local server hosts. */ +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_udp; + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_invalid_header_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; +UINT error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + return; + + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for external network IP instance */ + status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for External IP instance. */ + status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP instance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP instance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for External IP instance. */ + status = nx_arp_enable(&external_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&nat_ip); + status += nx_udp_enable(&local_ip); + status += nx_udp_enable(&external_ip); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: NAT Invalid Header Test..................................."); + + /* Create a UDP local socket. */ + status = nx_udp_socket_create(&local_ip, &local_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port 0x88. */ + status = nx_udp_socket_bind(&local_socket, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP External socket. */ + status = nx_udp_socket_create(&external_ip, &external_socket, "External Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Bind the UDP socket to the IP port 0x89. */ + status = nx_udp_socket_bind(&external_socket, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); + + advanced_packet_process_callback = packet_process; + + /***********************************************************************/ + /* External Socket sends udp packet to Local Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&external_socket, my_packet, NX_NAT_EXTERNAL_IPADR, 0x88); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP local socket. */ + status = nx_udp_socket_unbind(&local_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP Local socket. */ + status = nx_udp_socket_delete(&local_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP external socket. */ + status = nx_udp_socket_unbind(&external_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP external socket. */ + status = nx_udp_socket_delete(&external_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check invalid packet release. */ + if (nat_packet_pool.nx_packet_pool_invalid_releases != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_IPV4_HEADER *ip_header_ptr; +ULONG ip_header_length; +ULONG checksum; +ULONG val; + + if ((ip_ptr != &external_ip) || (packet_ptr -> nx_packet_length < 30)) + { + + /* Not the target packet. */ + return NX_TRUE; + } + + /* Trim the packet length to be less than UDP header. */ + /* Adjust the append pointer and length. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + 27; + packet_ptr -> nx_packet_length = 27; + + /* Get the IPv4 header. */ + ip_header_ptr = (NX_IPV4_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + ip_header_ptr -> nx_ip_header_word_0 = ((ip_header_ptr -> nx_ip_header_word_0) & 0xFFFF0000) | 27; + ip_header_length = ((ip_header_ptr -> nx_ip_header_word_0 & NX_IP_LENGTH_MASK) >> 24) * sizeof(ULONG); + + /* Clear the checksum. */ + ip_header_ptr -> nx_ip_header_word_2 &= 0xFFFF0000; + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, + /* Length is the size of IP header, including options */ + ip_header_length, + /* IPv4 header checksum does not use src/dest addresses */ + NULL, NULL); + + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + + advanced_packet_process_callback = NX_NULL; + return NX_TRUE; +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_invalid_header_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT Invalid Header Test...................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/nat_test/netx_nat_tcp_fragment_test.c b/test/regression/nat_test/netx_nat_tcp_fragment_test.c new file mode 100644 index 00000000..4f60019d --- /dev/null +++ b/test/regression/nat_test/netx_nat_tcp_fragment_test.c @@ -0,0 +1,671 @@ + +/* This NetX test concentrates on the TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined (NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#include "nx_nat.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_PACKET_POOL nat_packet_pool; +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_TCP_SOCKET local_socket; +NX_TCP_SOCKET external_socket; + +static UCHAR message[1024]; +static UCHAR buffer[1024]; + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT entries memory size. */ +#define NX_NAT_ENTRY_CACHE_SIZE 1024 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +/* Create NAT structures for preloading NAT tables with static + entries for local server hosts. */ +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_tcp; + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_fragment_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; +UINT error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + return; + + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_256, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_512); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_256, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for external network IP instance */ + status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_512, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for External IP instance. */ + status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP isntance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP isntance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for External IP isntance. */ + status = nx_arp_enable(&external_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable TCP traffic. */ + status += nx_tcp_enable(&local_ip); + status += nx_tcp_enable(&external_ip); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Enable the fragment function. */ + status = nx_ip_fragment_enable(&nat_ip); + status += nx_ip_fragment_enable(&local_ip); + status += nx_ip_fragment_enable(&external_ip); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +UINT data_size = 0; +ULONG bytes_copied; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: NAT TCP Fragment Processing Test.........................."); + + /* Clear the message. */ + for (i = 0; i < 1024; i ++) + message[i] = (UCHAR)rand(); + + /* Create a TCP local socket. */ + status = nx_tcp_socket_create(&local_ip, &local_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket to the IP port 0x88. */ + status = nx_tcp_client_socket_bind(&local_socket, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket sends tcp packet to External Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&local_socket, NX_NAT_EXTERNAL_HOST, 0x89, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&local_socket, NX_TCP_ESTABLISHED, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &message[0], 400); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 400; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 400; + + /* Send the TCP packet. */ + status = nx_tcp_socket_send(&local_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Suspend thread to let peer socket receive the data. */ + tx_thread_suspend(&thread_0); + + /***********************************************************************/ + /* Local Socket receives the tcp packet from External Socket */ + /***********************************************************************/ + /* Loop to receive TCP message from the socket. */ + while(1) + { + + /* Receive packet. */ + status = nx_tcp_socket_receive(&local_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status == NX_SUCCESS) + { + + /* Retrieve the data. */ + status = nx_packet_data_retrieve(my_packet, &buffer[data_size], &bytes_copied); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Update the data size. */ + data_size += bytes_copied; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + else + { + break; + } + } + + /* Check for data size. */ + if (data_size != 800) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Compare the data. */ + if (memcmp(buffer, &message[0], 800)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&local_socket, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&local_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&local_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +UINT data_size = 0; +ULONG bytes_copied; +NX_PACKET *my_packet; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&external_ip, &external_socket, "External Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* External Socket receives the tcp packet from Local Socket */ + /***********************************************************************/ + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&external_ip, 0x89, &external_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&external_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Loop to receive TCP message from the socket. */ + while(1) + { + + /* Receive packet. */ + status = nx_tcp_socket_receive(&external_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status == NX_SUCCESS) + { + + /* Retrieve the data. */ + status = nx_packet_data_retrieve(my_packet, &buffer[data_size], &bytes_copied); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Update the data size. */ + data_size += bytes_copied; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + else + { + break; + } + } + + /* Check for data size. */ + if (data_size != 400) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Compare the data. */ + if (memcmp(buffer, &message[0], 400)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Resume thread 0 to receive data. */ + tx_thread_resume(&thread_0); + + /***********************************************************************/ + /* External Socket sends tcp packet to Local Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &message[0], 800); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 800; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 800; + + /* Send the TCP packet. */ + status = nx_tcp_socket_send(&external_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&external_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&external_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&external_ip, 0x89); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&external_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_fragment_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT TCP Fragment Processing Test..........................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/nat_test/netx_nat_tcp_port_test.c b/test/regression/nat_test/netx_nat_tcp_port_test.c new file mode 100644 index 00000000..186c7cdb --- /dev/null +++ b/test/regression/nat_test/netx_nat_tcp_port_test.c @@ -0,0 +1,639 @@ + +/* This NetX test concentrates on the TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined(NX_DISABLE_IPV4) +#include "nx_nat.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_PACKET_POOL nat_packet_pool; +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_TCP_SOCKET local_socket; +NX_TCP_SOCKET nat_socket; +NX_TCP_SOCKET external_socket; + + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT entries memory size. */ +#define NX_NAT_ENTRY_CACHE_SIZE 1024 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +/* Create NAT structures for preloading NAT tables with static + entries for local server hosts. */ +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_tcp1; +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_tcp2; + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_port_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; +UINT error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + return; + + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for external network IP instance */ + status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for External IP instance. */ + status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP isntance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP isntance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for External IP isntance. */ + status = nx_arp_enable(&external_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable TCP traffic. */ + status += nx_tcp_enable(&local_ip); + status += nx_tcp_enable(&nat_ip); + status += nx_tcp_enable(&external_ip); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + + /* Print out test information banner. */ + printf("NetX Test: NAT TCP Port Processing Test.............................."); + + /* Create a TCP socket for NAT IP instance. */ + status = nx_tcp_socket_create(&nat_ip, &nat_socket, "NAT Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket to the IP port as NX_NAT_START_TCP_PORT. */ + status = nx_tcp_client_socket_bind(&nat_socket, NX_NAT_START_TCP_PORT, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Preload a NAT entry with same external TCP port of NAT socket. */ + status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_tcp1, NX_NAT_LOCAL_HOST1, NX_NAT_START_TCP_PORT, NX_NAT_START_TCP_PORT, NX_PROTOCOL_TCP); + + /* Check status. */ + if (status != NX_NAT_PORT_UNAVAILABLE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Preload a NAT entry with different external TCP port of NAT socket. */ + status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_tcp1, NX_NAT_LOCAL_HOST1, NX_NAT_START_TCP_PORT - 1, NX_NAT_START_TCP_PORT, NX_PROTOCOL_TCP); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Preload a NAT entry with same external TCP port of NAT entry. */ + status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_tcp2, NX_NAT_LOCAL_HOST1, NX_NAT_START_TCP_PORT - 1, NX_NAT_START_TCP_PORT, NX_PROTOCOL_TCP); + + /* Check status. */ + if (status != NX_NAT_PORT_UNAVAILABLE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the inbound entry. */ + status = nx_nat_inbound_entry_delete(&nat_server, &server_inbound_entry_tcp1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP local socket. */ + status = nx_tcp_socket_create(&local_ip, &local_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket to the IP port 0x88. */ + status = nx_tcp_client_socket_bind(&local_socket, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket sends tcp packet to External Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&local_socket, NX_NAT_EXTERNAL_HOST, 0x89, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&local_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the TCP packet. */ + status = nx_tcp_socket_send(&local_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&local_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&local_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&local_socket, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + + if((packets_sent != 1) || (bytes_sent != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check for errors. */ + if ((status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&local_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the NAT forwarded count. */ +#ifndef NX_DISABLE_NAT_INFO + if ((nat_server.forwarded_packets_received != 8) || (nat_server.forwarded_packets_sent != 8) ||(nat_server.forwarded_packets_dropped != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG peer_ip_address; +ULONG peer_port; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&external_ip, &external_socket, "External Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* External Socket receives the udp packet from Local Socket */ + /***********************************************************************/ + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&external_ip, 0x89, &external_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&external_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the peer socket port. */ + status = nx_tcp_socket_peer_info_get(&external_socket, &peer_ip_address, &peer_port); + + /* Check status. */ + if ((status) || (peer_ip_address != NX_NAT_EXTERNAL_IPADR) || (peer_port != NX_NAT_START_TCP_PORT + 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&external_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&external_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&external_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&external_ip, 0x89); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&external_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_port_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT TCP Port Processing Test..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/nat_test/netx_nat_tcp_port_test2.c b/test/regression/nat_test/netx_nat_tcp_port_test2.c new file mode 100644 index 00000000..d1abaa7c --- /dev/null +++ b/test/regression/nat_test/netx_nat_tcp_port_test2.c @@ -0,0 +1,640 @@ + +/* This NetX test concentrates on the TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined(NX_DISABLE_IPV4) +#include "nx_nat.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_PACKET_POOL nat_packet_pool; +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_TCP_SOCKET local_socket; +NX_TCP_SOCKET nat_socket; +NX_TCP_SOCKET nat_socket_1; +NX_TCP_SOCKET external_socket; + + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT entries memory size. */ +#define NX_NAT_ENTRY_CACHE_SIZE 1024 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +/* Create NAT structures for preloading NAT tables with static + entries for local server hosts. */ +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_tcp1; +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_tcp2; + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_port_test2_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; +UINT error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + return; + + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for external network IP instance */ + status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for External IP instance. */ + status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP isntance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP isntance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for External IP isntance. */ + status = nx_arp_enable(&external_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable TCP traffic. */ + status += nx_tcp_enable(&local_ip); + status += nx_tcp_enable(&nat_ip); + status += nx_tcp_enable(&external_ip); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + + /* Print out test information banner. */ + printf("NetX Test: NAT TCP Port Processing Test2............................."); + + /* Preload a NAT entry. */ + status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_tcp1, NX_NAT_LOCAL_HOST1, NX_NAT_START_TCP_PORT, NX_NAT_START_TCP_PORT, NX_PROTOCOL_TCP); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket for NAT IP instance. */ + status = nx_tcp_socket_create(&nat_ip, &nat_socket, "NAT Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket to the IP port as NX_NAT_START_TCP_PORT. */ + status = nx_tcp_client_socket_bind(&nat_socket, NX_NAT_START_TCP_PORT, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_PORT_UNAVAILABLE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket to the IP port as NX_NAT_START_TCP_PORT. */ + status = nx_tcp_client_socket_bind(&nat_socket, NX_NAT_START_TCP_PORT + 1, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&nat_ip, &nat_socket_1, "NAT Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&nat_ip, NX_NAT_START_TCP_PORT, &nat_socket_1, 5, NX_NULL); + + /* Check for error. */ + if (status != NX_DUPLICATE_LISTEN) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP local socket. */ + status = nx_tcp_socket_create(&local_ip, &local_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket to the IP port 0x88. */ + status = nx_tcp_client_socket_bind(&local_socket, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket sends tcp packet to External Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&local_socket, NX_NAT_EXTERNAL_HOST, 0x89, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&local_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the TCP packet. */ + status = nx_tcp_socket_send(&local_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&local_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&local_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&local_socket, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + + if((packets_sent != 1) || (bytes_sent != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check for errors. */ + if ((status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&local_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the NAT forwarded count. */ +#ifndef NX_DISABLE_NAT_INFO + if ((nat_server.forwarded_packets_received != 8) || (nat_server.forwarded_packets_sent != 8) ||(nat_server.forwarded_packets_dropped != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG peer_ip_address; +ULONG peer_port; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&external_ip, &external_socket, "External Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* External Socket receives the udp packet from Local Socket */ + /***********************************************************************/ + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&external_ip, 0x89, &external_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&external_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the peer socket port. */ + status = nx_tcp_socket_peer_info_get(&external_socket, &peer_ip_address, &peer_port); + + /* Check status. */ + if ((status) || (peer_ip_address != NX_NAT_EXTERNAL_IPADR) || (peer_port != NX_NAT_START_TCP_PORT + 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&external_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&external_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&external_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&external_ip, 0x89); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&external_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_port_test2_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT TCP Port Processing Test2.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/nat_test/netx_nat_tcp_remove_oldest_udp_entry_test.c b/test/regression/nat_test/netx_nat_tcp_remove_oldest_udp_entry_test.c new file mode 100644 index 00000000..38bcb820 --- /dev/null +++ b/test/regression/nat_test/netx_nat_tcp_remove_oldest_udp_entry_test.c @@ -0,0 +1,618 @@ + +/* This NetX test concentrates on the NAT TCP operation and + NX_NAT_ENABLE_REPLACMENT feature. This test creates five + test cases where the NAT table is manually filled in with a variety of + non TCP and TCP entries. The non TCP response timeouts use the standard NAT timeout + defined by NX_NAT_NON_TCP_SESSION_TIMEOUT. The TCP timeouts use the extended timeout + NX_NAT_TCP_SESSION_TIMEOUT. None of the entries should timeout. + + Once the table is filled, the TCP client attempts to make a connection on a + new port to an external host (we don't create the TCP server). + The outbound SYN packet will require an entry for this outbound packet. + + The success case is if NAT removes the oldest non TCP entry and inerts the new + TCP entry at the head of the list. + + Each test case varies with respect to where the oldest entry is to verify + that the removal of the link leaves the remaining entries properly linked + and the NAT available list parameters updated. + +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_nat.h" + +extern void test_control_return(UINT status); + +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && defined NX_NAT_ENABLE_REPLACMENT + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static UINT error_counter = 0; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_PACKET_POOL nat_packet_pool; +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_TCP_SOCKET local_socket; +NX_TCP_SOCKET external_socket; + + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT table size large enough for 5 entries. */ +#define NX_NAT_ENTRY_CACHE_SIZE 148 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +#define CONNECT_PEER_PORT 0x89 +#define CONNECT_LOCAL_PORT 0x69 + +static void *dynamic_cache_ptr; +static UINT dynamic_entries; + + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static UINT add_nat_entry(UINT protocol, ULONG local_ip_address , ULONG peer_ip_address , UINT local_port, UINT peer_port, ULONG response_timeout, UINT timestamp); + +/* Define thread prototypes. */ + +static void thread_client_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_remove_oldest_udp_entry_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; +UINT error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the first client thread. */ + tx_thread_create(&thread_client, "client thread", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + } + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP isntance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP isntance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&local_ip); + status += nx_icmp_enable(&local_ip); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + dynamic_cache_ptr = (void **) pointer; + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; +} + +/* Define the test threads. */ + +static void thread_client_entry(ULONG thread_input) +{ + +UINT status; +UINT temp1, temp2, oldest_local_port; +UINT i, j; +ULONG timeout = NX_NAT_NON_TCP_SESSION_TIMEOUT; +UINT peer_port; +UINT local_port; +ULONG local_ip_address; +ULONG peer_ip_address; +UINT protocol; +UINT timestamp; +UINT found; +NX_NAT_TRANSLATION_ENTRY search_entry; +NX_NAT_TRANSLATION_ENTRY *entry_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: NAT TCP Remove Oldest UDP Entry Test........................"); + + /* Check error status on set up. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); + + /* Create a TCP local socket. */ + status = nx_tcp_socket_create(&local_ip, &local_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + temp1 = tx_time_get(); + for (j = 0; j < 4; j++) + { + + /* Fill up NAT table for 4 different test cases. */ + + /* Starting parameters for entries we will add directly: */ + timeout = NX_NAT_NON_TCP_SESSION_TIMEOUT; + protocol= NX_PROTOCOL_TCP; + peer_port = CONNECT_PEER_PORT; + local_port = CONNECT_LOCAL_PORT; + peer_ip_address = NX_NAT_EXTERNAL_IPADR; + local_ip_address = NX_NAT_LOCAL_HOST1; + + /* Add 5 entries to the table for each test case. */ + for (i = 0; i < 5; i++) + { + + switch (j) + { + + case 0: + /* Oldest UDP entry the next entry after the dynamic list head. */ + { + if ((i != 2) && (i != 4)) + { + /* Add a few long timeouts. */ + timeout = NX_NAT_NON_TCP_SESSION_TIMEOUT; + protocol = NX_PROTOCOL_UDP; + timestamp = 10 - i; + } + else + { + timeout = NX_NAT_TCP_SESSION_TIMEOUT; + protocol = NX_PROTOCOL_TCP; + timestamp = i; + } + + /* Oldest_entry = 3; */ + if (i == 3) + { + oldest_local_port = local_port; + } + + break; + } + case 1: + /* Oldest UDP entry is the tail of the dynamic list */ + { + if ((i != 2) && (i != 4)) + { + /* Add a few long timeouts. */ + timeout = NX_NAT_NON_TCP_SESSION_TIMEOUT; + protocol = NX_PROTOCOL_UDP; + timestamp = i; + } + else + { + timeout = NX_NAT_TCP_SESSION_TIMEOUT; + protocol = NX_PROTOCOL_TCP; + timestamp = 10 - i; + } + + /* Oldest_entry = 0; */ + if (i == 0) + { + oldest_local_port = local_port; + } + /* Now add in the elapsed time. */ + timestamp += temp2 - temp1; + + break; + } + case 2: + /* Oldest UDP entry is the head of the dynamic list */ + { + if ((i != 2) && (i != 4)) + { + /* Add a few long timeouts. */ + timeout = NX_NAT_TCP_SESSION_TIMEOUT; + protocol = NX_PROTOCOL_TCP; + timestamp = i; + } + else + { + timeout = NX_NAT_NON_TCP_SESSION_TIMEOUT; + protocol = NX_PROTOCOL_UDP; + timestamp = 10 - i; + } + + /* Oldest_entry = 4; */ + if (i == 4) + { + oldest_local_port = local_port; + } + /* Now add in the elapsed time. */ + timestamp += temp2 - temp1; + + break; + } + case 3: + /* Oldest UDP entry is in the middle of the list */ + { + + if ((i != 2) && (i != 3)) + { + /* Add a few long timeouts. */ + timeout = NX_NAT_TCP_SESSION_TIMEOUT; + protocol = NX_PROTOCOL_TCP; + timestamp = i; + } + else + { + timeout = NX_NAT_NON_TCP_SESSION_TIMEOUT; + protocol = NX_PROTOCOL_UDP; + + /* Throw in an ICMP entry. */ + if (i == 2) + { + protocol = NX_PROTOCOL_ICMP; + } + + timestamp = 10 - i; + } + + /* Oldest_entry = 3; */ + if (i == 3) + { + oldest_local_port = local_port; + } + + /* Now add in the elapsed time. */ + timestamp += temp2 - temp1; + break; + } + default: + { + break; + } + } + + status = add_nat_entry(protocol, local_ip_address , peer_ip_address , local_port, peer_port, timeout, timestamp); + if (status) + { + error_counter++; + } + + local_port ++; + peer_port ++; + } + + /* Make sure our timestamps are less than the current time! */ + tx_thread_sleep(50); + + /* Assign separate ports for another TCP Connection */ + local_port += 100; + peer_port += 100; + + /* Bind the socket to a local port. */ + status = nx_tcp_client_socket_bind(&local_socket, local_port, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Attempt to connect the socket to the external host on a destination port higher than the last entry in the table. */ + status = nx_tcp_client_socket_connect(&local_socket, NX_NAT_EXTERNAL_HOST, peer_port, 20); + + /* Create the translation record to find in the NAT table. This should + correspond to the TCP connection attemp (SYN packet outbound). */ + memset(&search_entry, 0, sizeof(NX_NAT_TRANSLATION_ENTRY)); + search_entry.protocol = NX_PROTOCOL_TCP; + search_entry.local_ip_address = NX_NAT_LOCAL_HOST1; + search_entry.peer_ip_address = NX_NAT_EXTERNAL_HOST; + search_entry.local_port = local_port; + search_entry.peer_port = peer_port; + + /* Get the start of the NAT list of dynamic entries. */ + entry_ptr = nat_server.nx_nat_dynamic_active_entry_head; + + found = NX_FALSE; + + /* Search the whole table until a match is found. */ + while (entry_ptr) + { + + /* Check if the oldest UDP entry has been removed. */ + if ((entry_ptr -> local_port == oldest_local_port) && (entry_ptr -> protocol == NX_PROTOCOL_UDP)) + { + error_counter++; + } + + /* Do sender and entry protocols match? */ + if ((search_entry.protocol == entry_ptr -> protocol) && + (search_entry.peer_ip_address == entry_ptr -> peer_ip_address) && + (search_entry.peer_port == entry_ptr -> peer_port) && + (search_entry.local_ip_address == entry_ptr -> local_ip_address) && + (search_entry.local_port == entry_ptr -> local_port)) + { + + /* We have a matching entry. */ + found = NX_TRUE; + } + + entry_ptr = entry_ptr -> next_entry_ptr; + } + + /* If not found, the test failed. */ + if (!found) + { + error_counter++; + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&local_socket); + + /* Check for error. */ + if (status) + { + + /* If an error, abort test. */ + error_counter++; + break; + } + + /* Check the active and available list parameters */ + if ((nat_server.nx_nat_dynamic_available_entry_head != NX_NULL) || + (nat_server.nx_nat_dynamic_available_entries != 0) || + (nat_server.nx_nat_dynamic_active_entries != 5)) + { + error_counter++; + } + + /* Clear the NAT table and table counters. */ + + /* Clear the entry cache. */ + memset((void *) dynamic_cache_ptr, 0, NX_NAT_ENTRY_CACHE_SIZE); + + /* Pickup starting address of the available entry list. */ + entry_ptr = (NX_NAT_TRANSLATION_ENTRY *) dynamic_cache_ptr; + + /* Determine how many NAT daynamic entries will fit in this cache area. */ + dynamic_entries = NX_NAT_ENTRY_CACHE_SIZE / sizeof(NX_NAT_TRANSLATION_ENTRY); + + /* Initialize the pointers of available NAT entries. */ + for (i = 0; i < (dynamic_entries - 1); i++) + { + /* Setup each entry to point to the next entry. */ + entry_ptr -> next_entry_ptr = entry_ptr + 1; + entry_ptr ++; + } + + /* Setup the head pointers of the available and dynamic (active) lists in the NAT Device. */ + nat_server.nx_nat_dynamic_available_entry_head = (NX_NAT_TRANSLATION_ENTRY *) dynamic_cache_ptr; + nat_server.nx_nat_dynamic_active_entry_head = NX_NULL; + nat_server.nx_nat_dynamic_available_entries = dynamic_entries; + nat_server.nx_nat_dynamic_active_entries = 0; + nat_server.nx_nat_static_active_entries = 0; + + temp2 = tx_time_get(); + + } /* Try the next test case */ + + /* Final check on error status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT external_port = 20000; + +static UINT add_nat_entry(UINT protocol, ULONG local_ip_address , ULONG peer_ip_address , UINT local_port, UINT peer_port, ULONG response_timeout, UINT timestamp) +{ + +NX_NAT_TRANSLATION_ENTRY *insert_entry_ptr; + + + external_port++; + + /* Get one available entry. */ + insert_entry_ptr = (nat_server.nx_nat_dynamic_available_entry_head); + + /* Update the entry head. */ + nat_server.nx_nat_dynamic_available_entry_head = insert_entry_ptr -> next_entry_ptr; + + /* Initialize the allocated memory to NULL. */ + memset(insert_entry_ptr, 0, sizeof(NX_NAT_TRANSLATION_ENTRY)); + + /* Assign the entry attributes. */ + insert_entry_ptr -> protocol = protocol; + insert_entry_ptr -> local_ip_address = local_ip_address; + insert_entry_ptr -> peer_ip_address = peer_ip_address; + insert_entry_ptr -> local_port = local_port; + insert_entry_ptr -> external_port = external_port; + insert_entry_ptr -> peer_port = peer_port; + insert_entry_ptr -> response_timeout = response_timeout; + + /* Set the entry timestamp. */ + insert_entry_ptr -> response_timestamp = timestamp; + + /* Set entry type to dynamically created. */ + insert_entry_ptr -> translation_type = NX_NAT_DYNAMIC_ENTRY; + + /* Update the table counters. */ + nat_server.nx_nat_dynamic_active_entries ++; + nat_server.nx_nat_dynamic_available_entries --; + + /* Add this entry onto the table entry list. */ + insert_entry_ptr -> next_entry_ptr = nat_server.nx_nat_dynamic_active_entry_head; + nat_server.nx_nat_dynamic_active_entry_head = insert_entry_ptr; + + return NX_SUCCESS; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_remove_oldest_udp_entry_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT TCP Remove Oldest UDP Entry Test......................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/nat_test/netx_nat_tcp_test1.c b/test/regression/nat_test/netx_nat_tcp_test1.c new file mode 100644 index 00000000..90187752 --- /dev/null +++ b/test/regression/nat_test/netx_nat_tcp_test1.c @@ -0,0 +1,560 @@ + +/* This NetX test concentrates on the TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined(NX_DISABLE_IPV4) +#include "nx_nat.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_PACKET_POOL nat_packet_pool; +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_TCP_SOCKET local_socket; +NX_TCP_SOCKET external_socket; + + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT entries memory size. */ +#define NX_NAT_ENTRY_CACHE_SIZE 1024 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +/* Create NAT structures for preloading NAT tables with static + entries for local server hosts. */ +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_tcp; + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_test1_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; +UINT error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + return; + + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for external network IP instance */ + status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for External IP instance. */ + status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP isntance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP isntance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for External IP isntance. */ + status = nx_arp_enable(&external_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable TCP traffic. */ + status += nx_tcp_enable(&local_ip); + status += nx_tcp_enable(&external_ip); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + + /* Print out test information banner. */ + printf("NetX Test: NAT TCP Processing Test1.................................."); + + /* Create a TCP local socket. */ + status = nx_tcp_socket_create(&local_ip, &local_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket to the IP port 0x88. */ + status = nx_tcp_client_socket_bind(&local_socket, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&local_socket, NX_NAT_EXTERNAL_HOST, 0x89, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); + + /***********************************************************************/ + /* Local Socket sends tcp packet to External Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&local_socket, NX_NAT_EXTERNAL_HOST, 0x89, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&local_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the TCP packet. */ + status = nx_tcp_socket_send(&local_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&local_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&local_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&local_socket, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + + if((packets_sent != 1) || (bytes_sent != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check for errors. */ + if ((status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&local_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the NAT forwarded count. */ +#ifndef NX_DISABLE_NAT_INFO + if ((nat_server.forwarded_packets_received != 8) || (nat_server.forwarded_packets_sent != 8) ||(nat_server.forwarded_packets_dropped != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&external_ip, &external_socket, "External Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* External Socket receives the tcp packet from Local Socket */ + /***********************************************************************/ + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&external_ip, 0x89, &external_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&external_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&external_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&external_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&external_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&external_ip, 0x89); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&external_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_test1_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT TCP Processing Test1..................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/nat_test/netx_nat_tcp_test2.c b/test/regression/nat_test/netx_nat_tcp_test2.c new file mode 100644 index 00000000..6e963230 --- /dev/null +++ b/test/regression/nat_test/netx_nat_tcp_test2.c @@ -0,0 +1,573 @@ + +/* This NetX test concentrates on the TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined(NX_DISABLE_IPV4) +#include "nx_nat.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_PACKET_POOL nat_packet_pool; +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_TCP_SOCKET local_socket; +NX_TCP_SOCKET external_socket; + + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT entries memory size. */ +#define NX_NAT_ENTRY_CACHE_SIZE 1024 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +/* Create NAT structures for preloading NAT tables with static + entries for local server hosts. */ +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_tcp; + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_test2_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; +UINT error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + return; + + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for external network IP instance */ + status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for External IP instance. */ + status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP isntance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP isntance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for External IP isntance. */ + status = nx_arp_enable(&external_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable TCP traffic. */ + status += nx_tcp_enable(&local_ip); + status += nx_tcp_enable(&external_ip); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + + /* Print out test information banner. */ + printf("NetX Test: NAT TCP Processing Test2.................................."); + + /* Create a TCP external socket. */ + status = nx_tcp_socket_create(&external_ip, &external_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket to the IP port 0x89. */ + status = nx_tcp_client_socket_bind(&external_socket, 0x89, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&external_socket, NX_NAT_EXTERNAL_IPADR, 0x88, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&external_socket, NX_NAT_EXTERNAL_IPADR, 0x88, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Calling NAT API to preload a static entry. */ + status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_tcp, NX_NAT_LOCAL_HOST1, 0x88, 0x88, NX_PROTOCOL_TCP); + + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket sends tcp packet to External Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&external_socket, NX_NAT_EXTERNAL_IPADR, 0x88, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&external_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the TCP packet. */ + status = nx_tcp_socket_send(&external_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&external_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&external_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&external_socket, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + + if((packets_sent != 1) || (bytes_sent != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check for errors. */ + if ((status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&external_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&local_ip, &local_socket, "External Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket receives the tcp packet from External Socket */ + /***********************************************************************/ + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&local_ip, 0x88, &local_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&local_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&local_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&local_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&local_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&local_ip, 0x88); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&local_socket); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_tcp_test2_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT TCP Processing Test2..................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/nat_test/netx_nat_udp_fragment_test.c b/test/regression/nat_test/netx_nat_udp_fragment_test.c new file mode 100644 index 00000000..d426f346 --- /dev/null +++ b/test/regression/nat_test/netx_nat_udp_fragment_test.c @@ -0,0 +1,545 @@ + +/* This NetX test concentrates on the UCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_udp.h" + +extern void test_control_return(UINT status); +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined (NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#include "nx_nat.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_PACKET_POOL nat_packet_pool; +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_UDP_SOCKET local_socket; +NX_UDP_SOCKET external_socket; + +static UCHAR message[1024]; +static UCHAR buffer[1024]; + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT entries memory size. */ +#define NX_NAT_ENTRY_CACHE_SIZE 1024 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +/* Create NAT structures for preloading NAT tables with static + entries for local server hosts. */ +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_udp; + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_udp_fragment_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; +UINT error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + return; + + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_256, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_512); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_256, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for external network IP instance */ + status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_512, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for External IP instance. */ + status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP isntance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP isntance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for External IP isntance. */ + status = nx_arp_enable(&external_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&nat_ip); + status += nx_udp_enable(&local_ip); + status += nx_udp_enable(&external_ip); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Enable the fragment function. */ + status = nx_ip_fragment_enable(&nat_ip); + status += nx_ip_fragment_enable(&local_ip); + status += nx_ip_fragment_enable(&external_ip); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: NAT UDP Fragment Processing Test.........................."); + + /* Create a UDP local socket. */ + status = nx_udp_socket_create(&local_ip, &local_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port 0x88. */ + status = nx_udp_socket_bind(&local_socket, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP External socket. */ + status = nx_udp_socket_create(&external_ip, &external_socket, "External Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port 0x89. */ + status = nx_udp_socket_bind(&external_socket, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the message. */ + for (i = 0; i < 1024; i ++) + message[i] = (UCHAR)rand(); + + /***********************************************************************/ + /* Local Socket sends udp packet to External Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &message[0], 400); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 400; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 400; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&local_socket, my_packet, NX_NAT_EXTERNAL_HOST, 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Calling NAT API to preload a static entry. */ + status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_udp, NX_NAT_LOCAL_HOST1, 0x88, 0x88, NX_PROTOCOL_UDP); + + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* External Socket sends udp packet to Local Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &message[0], 800); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 800; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 800; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&external_socket, my_packet, NX_NAT_EXTERNAL_IPADR, 0x88); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG bytes_copied; +NX_PACKET *my_packet; + + + /***********************************************************************/ + /* External Socket receives the udp packet from Local Socket */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&external_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((status != NX_SUCCESS) || (my_packet -> nx_packet_length != 400)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Retrieve the data. */ + status = nx_packet_data_retrieve(my_packet, buffer, &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || (bytes_copied != 400)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Compare the data. */ + if (memcmp(buffer, &message[0], 400)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket receives the udp packet from External Socket */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&local_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((status != NX_SUCCESS) || (my_packet ->nx_packet_length != 800)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Retrieve the data. */ + status = nx_packet_data_retrieve(my_packet, buffer, &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || (bytes_copied != 800)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Compare the data. */ + if (memcmp(buffer, &message[0], 800)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_udp_fragment_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT UDP Fragment Processing Test..........................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/nat_test/netx_nat_udp_port_test.c b/test/regression/nat_test/netx_nat_udp_port_test.c new file mode 100644 index 00000000..f733a8d4 --- /dev/null +++ b/test/regression/nat_test/netx_nat_udp_port_test.c @@ -0,0 +1,630 @@ + +/* This NetX test concentrates on the UCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_udp.h" + +extern void test_control_return(UINT status); +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined(NX_DISABLE_IPV4) +#include "nx_nat.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_PACKET_POOL nat_packet_pool; +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_UDP_SOCKET local_socket; +NX_UDP_SOCKET nat_socket; +NX_UDP_SOCKET external_socket; +NX_UDP_SOCKET test_socket; + + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT entries memory size. */ +#define NX_NAT_ENTRY_CACHE_SIZE 1024 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +/* Create NAT structures for preloading NAT tables with static + entries for local server hosts. */ +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_udp1; +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_udp2; + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_udp_port_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; +UINT error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + return; + + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for external network IP instance */ + status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for External IP instance. */ + status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP isntance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP isntance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for External IP isntance. */ + status = nx_arp_enable(&external_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&nat_ip); + status += nx_udp_enable(&local_ip); + status += nx_udp_enable(&external_ip); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Print out test information banner. */ + printf("NetX Test: NAT UDP Port Processing Test.............................."); + + /* Create a UDP local socket. */ + status = nx_udp_socket_create(&nat_ip, &nat_socket, "NAT Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port as NX_NAT_START_UDP_PORT. */ + status = nx_udp_socket_bind(&nat_socket, NX_NAT_START_UDP_PORT, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Preload a NAT entry with same external UDP port of local socket. */ + status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_udp1, NX_NAT_LOCAL_HOST1, NX_NAT_START_UDP_PORT, NX_NAT_START_UDP_PORT, NX_PROTOCOL_UDP); + + /* Check status. */ + if (status != NX_NAT_PORT_UNAVAILABLE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Preload a NAT entry with different external UDP port of local socket. */ + status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_udp1, NX_NAT_LOCAL_HOST1, NX_NAT_START_UDP_PORT - 1, NX_NAT_START_UDP_PORT, NX_PROTOCOL_UDP); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Preload a NAT entry with same external UDP port of NAT entry1. */ + status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_udp2, NX_NAT_LOCAL_HOST1, NX_NAT_START_UDP_PORT - 1, NX_NAT_START_UDP_PORT, NX_PROTOCOL_UDP); + + /* Check status. */ + if (status != NX_NAT_PORT_UNAVAILABLE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create a UDP test socket. */ + status = nx_udp_socket_create(&nat_ip, &test_socket, "TEST Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the same external UDP port of NAT entry 1. NX_NAT_START_UDP_PORT - 1. */ + status = nx_udp_socket_bind(&test_socket, NX_NAT_START_UDP_PORT - 1, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_PORT_UNAVAILABLE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the test socket. */ + status = nx_udp_socket_delete(&test_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the inbound entry. */ + status = nx_nat_inbound_entry_delete(&nat_server, &server_inbound_entry_udp1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP local socket. */ + status = nx_udp_socket_create(&local_ip, &local_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port 0x88. */ + status = nx_udp_socket_bind(&local_socket, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP External socket. */ + status = nx_udp_socket_create(&external_ip, &external_socket, "External Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Bind the UDP socket to the IP port 0x89. */ + status = nx_udp_socket_bind(&external_socket, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket sends udp packet to External Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&local_socket, my_packet, NX_NAT_EXTERNAL_HOST, 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Check the NAT forwarded count. */ +#ifndef NX_DISABLE_NAT_INFO + if ((nat_server.forwarded_packets_received != 1) || (nat_server.forwarded_packets_sent != 1) ||(nat_server.forwarded_packets_dropped != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Get UDP Local socket information. */ + status = nx_udp_socket_info_get(&local_socket, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != 1) || (bytes_sent != 28) || (packets_received != 0) || (bytes_received != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + /* Check status. */ + if ((receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP nat socket. */ + status = nx_udp_socket_unbind(&nat_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP nat socket. */ + status = nx_udp_socket_delete(&nat_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP local socket. */ + status = nx_udp_socket_unbind(&local_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP Local socket. */ + status = nx_udp_socket_delete(&local_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP external socket. */ + status = nx_udp_socket_unbind(&external_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP external socket. */ + status = nx_udp_socket_delete(&external_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG peer_ip_address; +UINT peer_port; + + + /***********************************************************************/ + /* External Socket receives the udp packet from Local Socket */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&external_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the peer socket port. */ + status = nx_udp_source_extract(my_packet, &peer_ip_address, &peer_port); + + /* Check status. */ + if ((status) || (peer_ip_address != NX_NAT_EXTERNAL_IPADR) || (peer_port != NX_NAT_START_TCP_PORT + 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_udp_port_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT UDP Port Processing Test..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/nat_test/netx_nat_udp_test.c b/test/regression/nat_test/netx_nat_udp_test.c new file mode 100644 index 00000000..cee0324c --- /dev/null +++ b/test/regression/nat_test/netx_nat_udp_test.c @@ -0,0 +1,817 @@ + +/* This NetX test concentrates on the UCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_udp.h" + +extern void test_control_return(UINT status); +#if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined(NX_DISABLE_IPV4) +#include "nx_nat.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +/* Set up the NAT components. */ + +/* Create a NAT instance, packet pool and translation table. */ + +NX_PACKET_POOL nat_packet_pool; +NX_NAT_DEVICE nat_server; +NX_IP nat_ip; +NX_IP local_ip; +NX_IP external_ip; +NX_UDP_SOCKET local_socket; +NX_UDP_SOCKET external_socket; + + +/* Configure the NAT network parameters. */ + +/* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of + the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */ +#define NX_NAT_PACKET_SIZE 1536 + + +/* Set the size of the NAT IP packet pool. */ +#define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10) + +/* Set NetX IP helper thread stack size. */ +#define NX_NAT_IP_THREAD_STACK_SIZE 2048 + +/* Set the server IP thread priority */ +#define NX_NAT_IP_THREAD_PRIORITY 2 + +/* Set ARP cache size of a NAT ip instance. */ +#define NX_NAT_ARP_CACHE_SIZE 1024 + +/* Set NAT entries memory size. */ +#define NX_NAT_ENTRY_CACHE_SIZE 1024 + +/* Define NAT IP addresses, local host private IP addresses and external host IP address. */ +#define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3)) +#define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10)) +#define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1)) +#define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) +#define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10)) +#define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100)) +#define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1)) +#define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0)) + +/* Create NAT structures for preloading NAT tables with static + entries for local server hosts. */ +NX_NAT_TRANSLATION_ENTRY server_inbound_entry_udp; + +/* Set up generic network driver for demo program. */ +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_udp_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *pointer; +UINT error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Setup the pointer to unallocated memory. */ + pointer = (UCHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create NAT packet pool. */ + status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool", + NX_NAT_PACKET_SIZE, pointer, + NX_NAT_PACKET_POOL_SIZE); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_PACKET_POOL_SIZE; + + /* Check status. */ + if (status) + return; + + /* Create IP instances for NAT server (global network) */ + status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the private interface(private network). */ + status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for Local network IP instance */ + status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create IP instances for external network IP instance */ + status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK, + &nat_packet_pool, _nx_ram_network_driver_1500, pointer, + NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY); + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE; + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for NAT IP instance. */ + status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for Local IP instance. */ + status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Set the global network gateway for External IP instance. */ + status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + + /* Enable ARP and supply ARP cache memory for NAT IP isntance. */ + status = nx_arp_enable(&nat_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for Local IP isntance. */ + status = nx_arp_enable(&local_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable ARP and supply ARP cache memory for External IP isntance. */ + status = nx_arp_enable(&external_ip, (void **) pointer, + NX_NAT_ARP_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ARP_CACHE_SIZE; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&nat_ip); + status += nx_udp_enable(&local_ip); + status += nx_udp_enable(&external_ip); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Create a NetX NAT server and cache with a global interface index. */ + status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Update pointer to unallocated (free) memory. */ + pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Print out test information banner. */ + printf("NetX Test: NAT UDP Processing Test..................................."); + + /* Create a UDP local socket. */ + status = nx_udp_socket_create(&local_ip, &local_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port 0x88. */ + status = nx_udp_socket_bind(&local_socket, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP External socket. */ + status = nx_udp_socket_create(&external_ip, &external_socket, "External Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Bind the UDP socket to the IP port 0x89. */ + status = nx_udp_socket_bind(&external_socket, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket sends udp packet to External Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&local_socket, my_packet, NX_NAT_EXTERNAL_HOST, 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* External Socket sends udp packet to Local Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&external_socket, my_packet, NX_NAT_EXTERNAL_IPADR, 0x88); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the NAT service. */ + nx_nat_enable(&nat_server); + + /***********************************************************************/ + /* Local Socket sends udp packet to External Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&local_socket, my_packet, NX_NAT_EXTERNAL_HOST, 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* External Socket sends udp packet to Local Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&external_socket, my_packet, NX_NAT_EXTERNAL_IPADR, 0x88); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Calling NAT API to preload a static entry. */ + status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_udp, NX_NAT_LOCAL_HOST1, 0x88, 0x88, NX_PROTOCOL_UDP); + + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket sends udp packet to External Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&local_socket, my_packet, NX_NAT_EXTERNAL_HOST, 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* External Socket sends udp packet to Local Socket */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&external_socket, my_packet, NX_NAT_EXTERNAL_IPADR, 0x88); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Check the NAT forwarded count. */ +#ifndef NX_DISABLE_NAT_INFO + if ((nat_server.forwarded_packets_received != 4) || (nat_server.forwarded_packets_sent != 3) ||(nat_server.forwarded_packets_dropped != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Get UDP Local socket information. */ + status = nx_udp_socket_info_get(&local_socket, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != 3) || (bytes_sent != 3 * 28) || (packets_received != 1) || (bytes_received != 1 * 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + /* Check status. */ + if ((receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP external socket information. */ + status = nx_udp_socket_info_get(&external_socket, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != 3) || (bytes_sent != 3 * 28) || (packets_received != 2) || (bytes_received != 2 * 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + /* Check status. */ + if ((receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP local socket. */ + status = nx_udp_socket_unbind(&local_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP Local socket. */ + status = nx_udp_socket_delete(&local_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP external socket. */ + status = nx_udp_socket_unbind(&external_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP external socket. */ + status = nx_udp_socket_delete(&external_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /***********************************************************************/ + /* External Socket receives the udp packet from Local Socket */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&external_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket receives the udp packet from External Socket */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&local_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + /***********************************************************************/ + /* External Socket receives the udp packet from Local Socket */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&external_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket receives the udp packet from External Socket */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&local_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + /***********************************************************************/ + /* External Socket receives the udp packet from Local Socket */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&external_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Local Socket receives the udp packet from External Socket */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&local_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nat_udp_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NAT UDP Processing Test...................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_101_17_test.c b/test/regression/netxduo_test/netx_101_17_test.c new file mode 100644 index 00000000..01e4b788 --- /dev/null +++ b/test/regression/netxduo_test/netx_101_17_test.c @@ -0,0 +1,282 @@ +/* 101.17 IW,the initial value of cwnd, MUST be less than or equal to 4*SMSS bytes and MUST NOT be more than 4 segments. */ +/* Page 4, RFC 5681. */ + +/* Procedure + 1.Connection successfully + 2.To check if sender's CWND > 2 * MSS */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#define DEMO_STACK_SIZE 2048 +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_101_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 101.17 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if((client_socket.nx_tcp_socket_tx_window_congestion > 4 * client_socket.nx_tcp_socket_connect_mss) || + (server_socket.nx_tcp_socket_tx_window_congestion > 4 * server_socket.nx_tcp_socket_connect_mss)) + { + error_counter++; + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_101_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 101.17 Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_101_18_test.c b/test/regression/netxduo_test/netx_101_18_test.c new file mode 100644 index 00000000..51283af8 --- /dev/null +++ b/test/regression/netxduo_test/netx_101_18_test.c @@ -0,0 +1,398 @@ +/* 101.18 During slow start, a TCP increments cwnd by at most SMSS bytes for each ACK received that acknowledges new data. */ + +/* Procedure + 1.Connection successfully + 2.When receiving an ACK packet check if CWND <= present_cwnd + SMSS */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "----------abcdefgh20----------ABCDEFGH40----------klmnopqr60----------KLMNOPQR80--------------------" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG ack_counter; + +/* Save the original cwnd.. */ +static ULONG congestion_window; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_101_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_101_18_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Check whether the ACK packet is received. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_101_18; + + /* Save the original cwnd. */ + congestion_window = client_socket.nx_tcp_socket_tx_window_congestion; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG, 60, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Let the thread sleep for 1 second to wait for the ACK packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + congestion_window = client_socket.nx_tcp_socket_tx_window_congestion; + + /* Create the second tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet2, MSG, 55, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Let the thread sleep for 1 second to wait for the ACK packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (data_packet_counter != 2) || (ack_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 101.18 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status != NX_SUCCESS) + error_counter++; + else + { + /* Check data length and payload */ + if((packet_ptr -> nx_packet_length == 60) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr, MSG, 60))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Let the thread sleep for 1 second to wait for the ACK packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status != NX_SUCCESS) + error_counter++; + else + { + /* Check data length and payload */ + if((packet_ptr -> nx_packet_length == 55) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr, MSG, 55))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Let the thread sleep for 1 second to wait for the ACK packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_101_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + ack_counter++; + + /* Check whether the TCP increments cwnd by at most SMSS bytes for each ACK received that cumulatively acknowledges new data. */ + if(client_socket.nx_tcp_socket_tx_window_congestion > (congestion_window + client_socket.nx_tcp_socket_connect_mss)) + error_counter++; + + if(ack_counter == 2) + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_101_18_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 101.18 Test......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_102_18_test.c b/test/regression/netxduo_test/netx_102_18_test.c new file mode 100644 index 00000000..fcf2325e --- /dev/null +++ b/test/regression/netxduo_test/netx_102_18_test.c @@ -0,0 +1,325 @@ +/* 102.18 The TCP output routine never sends more than cwnd if cwnd less than the receiver's advertised window. */ + +/* Procedure + 1.Connect + 2.Client sends a packet with 100 length to server + 3.Server should receive two packet, one with 88 data and another with 12 data + (client's MSS is 88, advertised window is 100) */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG congestion_window; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_18_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + congestion_window = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +char *msg = MSG; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + client_socket.nx_tcp_socket_tx_window_congestion = server_socket.nx_tcp_socket_rx_window_last_sent - 10; + + congestion_window = client_socket.nx_tcp_socket_tx_window_congestion; + + + /* Allocate packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, msg, congestion_window+20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (data_packet_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *rcv_packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.18 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while(!nx_tcp_socket_receive(&server_socket, &rcv_packet_ptr, NX_IP_PERIODIC_RATE)) + { + /* Check the length of the packet received. */ + if(rcv_packet_ptr->nx_packet_length <= congestion_window) + data_packet_counter++; + else + error_counter++; + } + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_18_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.18 Test......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_102_19_test.c b/test/regression/netxduo_test/netx_102_19_test.c new file mode 100644 index 00000000..5f2bdf34 --- /dev/null +++ b/test/regression/netxduo_test/netx_102_19_test.c @@ -0,0 +1,309 @@ +/* 102.19 The TCP output routine never sends more than receiver's advertised window if receiver's advertised window less than the cwnd. */ + +/* Procedure + 1.Connect + 2.Client sends a packet with 100 length to Server + 3.Client should not send the packet out(client's MSS is 88, advertised window is 80) */ + +/* Question + If the packet length is bigger than advertised window, it will wait until advertised window is bigger than or equal to the packet length */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_19_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.19 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(client_socket.nx_tcp_socket_rx_window_last_sent > server_socket.nx_tcp_socket_tx_window_congestion) + client_socket.nx_tcp_socket_rx_window_last_sent = server_socket.nx_tcp_socket_tx_window_congestion - 10; + + /* Allocate packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, client_socket.nx_tcp_socket_rx_window_last_sent + 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_NO_WAIT); + + if(status != NX_WINDOW_OVERFLOW) + error_counter++; + else + nx_packet_release(my_packet); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 80, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_19_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.19 Test......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_102_20_test.c b/test/regression/netxduo_test/netx_102_20_test.c new file mode 100644 index 00000000..1588ca09 --- /dev/null +++ b/test/regression/netxduo_test/netx_102_20_test.c @@ -0,0 +1,451 @@ +/* 102.20 When congestion occurs, one-half of the current window size is saved in ssthresh. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG ack_counter; +static ULONG seq_number; +static ULONG ack_counter; +static ULONG duplicate_ack_counter; +static ULONG is_set; +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_102_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_102_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_20_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + ack_counter = 0; + seq_number = 0; + duplicate_ack_counter = 0; + is_set = NX_FALSE; + + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +NX_PACKET *my_packet4; + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.20 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_102_20; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_102_20; + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet2, MSG+20, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet3, MSG+40, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet4, MSG+60, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet4, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + while(!(status = nx_tcp_socket_receive(&client_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE))) + { + + if((packet_ptr -> nx_packet_length == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr, (MSG + data_packet_counter * 20), 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 4) || (duplicate_ack_counter != 3) || (is_set != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_102_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + + if((packet_ptr -> nx_packet_length-40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr+40, MSG, 20))) + { + if(server_socket.nx_tcp_socket_timeout_retries == 0) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + seq_number = tcp_header_ptr -> nx_tcp_sequence_number; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + else if(server_socket.nx_tcp_socket_timeout_retries == 1) + { + if((server_socket.nx_tcp_socket_tx_slow_start_threshold == server_socket.nx_tcp_socket_tx_outstanding_bytes / 2) || (server_socket.nx_tcp_socket_tx_slow_start_threshold == server_socket.nx_tcp_socket_connect_mss * 2)) + is_set = NX_TRUE; + + advanced_packet_process_callback = NX_NULL; + } + } + return NX_TRUE; +} + +static void my_tcp_packet_receive_102_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(tcp_header_ptr ->nx_tcp_acknowledgment_number == seq_number) + duplicate_ack_counter++; + + if(duplicate_ack_counter == 3) + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_20_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.20 Test......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_102_21_test.c b/test/regression/netxduo_test/netx_102_21_test.c new file mode 100644 index 00000000..698bb35a --- /dev/null +++ b/test/regression/netxduo_test/netx_102_21_test.c @@ -0,0 +1,451 @@ +/* 102.21 When congestion occurs, one-half of the current window size, but at least 2 segments is saved in ssthresh. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG ack_counter; +static ULONG seq_number; +static ULONG ack_counter; +static ULONG duplicate_ack_counter; +static ULONG is_set; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_102_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_102_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_21_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + ack_counter = 0; + seq_number = 0; + duplicate_ack_counter = 0; + is_set = NX_FALSE; + + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +NX_PACKET *my_packet4; + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.21 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_102_21; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_102_21; + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet2, MSG+20, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet3, MSG+40, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet4, MSG+60, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet4, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + while(!(status = nx_tcp_socket_receive(&client_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE))) + { + + if((packet_ptr -> nx_packet_length == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr, (MSG + data_packet_counter * 20), 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 4) || (duplicate_ack_counter != 3) || (is_set != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_102_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + + if((packet_ptr -> nx_packet_length-40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr+40, MSG, 20))) + { + if(server_socket.nx_tcp_socket_timeout_retries == 0) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + seq_number = tcp_header_ptr -> nx_tcp_sequence_number; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + else if(server_socket.nx_tcp_socket_timeout_retries == 1) + { + if((server_socket.nx_tcp_socket_tx_slow_start_threshold == server_socket.nx_tcp_socket_tx_outstanding_bytes / 2) || (server_socket.nx_tcp_socket_tx_slow_start_threshold >= server_socket.nx_tcp_socket_connect_mss * 2)) + is_set = NX_TRUE; + + advanced_packet_process_callback = NX_NULL; + } + } + return NX_TRUE; +} + +static void my_tcp_packet_receive_102_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(tcp_header_ptr ->nx_tcp_acknowledgment_number == seq_number) + duplicate_ack_counter++; + + if(duplicate_ack_counter == 3) + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_21_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.21 Test......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_102_22_test.c b/test/regression/netxduo_test/netx_102_22_test.c new file mode 100644 index 00000000..685629ce --- /dev/null +++ b/test/regression/netxduo_test/netx_102_22_test.c @@ -0,0 +1,348 @@ +/* 102.22 Upon a timeout cwnd MUST be set to no more than the loss window, LW, which equals 1 full-sized segment (regardless of the value of IW). */ + +/* Procedure + 1. Connection. + 2. Client sends a data packet to Server. + 3. Drop the packet. + 4. Client starts congestion, after Server receives the packet, check cwnd <= mss. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG is_set; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_102_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_22_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + is_set = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_102_22; + + /* Allocate packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Let the client socket sleep for 1 second to wait for the retransmittion. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (data_packet_counter != 1) || (is_set != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *rcv_packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.22 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Waiting for client socket retransmit the packet in 5 seconds. */ + status = nx_tcp_socket_receive(&server_socket, &rcv_packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + if(!status) + { + /* Check the length and data of the packet received. */ + if((rcv_packet_ptr->nx_packet_length == 20) && !(memcmp(rcv_packet_ptr->nx_packet_prepend_ptr, MSG, 20))) + data_packet_counter++; + } + else + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static UINT my_packet_process_102_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + /* Check if it is a data packet. */ + if((packet_ptr->nx_packet_length == 60) && !(memcmp(packet_ptr->nx_packet_prepend_ptr + 40, MSG, 20))) + { + if(client_socket.nx_tcp_socket_timeout_retries == 0) + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + else if(client_socket.nx_tcp_socket_timeout_retries == 1) + { + if(client_socket.nx_tcp_socket_tx_window_congestion <= client_socket.nx_tcp_socket_connect_mss) + is_set = NX_TRUE; + + advanced_packet_process_callback = NX_NULL; + } + } + + return NX_TRUE; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_22_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.22 Test......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_102_23_test.c b/test/regression/netxduo_test/netx_102_23_test.c new file mode 100644 index 00000000..bb7f842b --- /dev/null +++ b/test/regression/netxduo_test/netx_102_23_test.c @@ -0,0 +1,400 @@ +/* 102.23 Slow start continues until TCP is halfway to where it was when congestion occurred. */ + +/* Procedure + 1. Connection. + 2. Client sends a data packet. + 3. Server receives the packet and replies an ACK packet. + 4. Check cwnd += min(N, MSS). N is acked bytes. + 5. Client sends a data packet again. + 6. Set ssthresh = cwnd - 10. + 7. Server starts congestion, after receives the packet, check cwnd = cwnd + MSS * MSS / cwnd. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG ack_counter; +static ULONG ack_number_1; +static ULONG ack_number_2; +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_102_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_23_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +ULONG cwnd; + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.23 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 3000, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_102_23; + + /* Record the value of cwnd. */ + cwnd = server_socket.nx_tcp_socket_tx_window_congestion; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Record the tx_sequence. */ + ack_number_1 = server_socket.nx_tcp_socket_tx_sequence; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE/2); + + /* Check whether the cwnd = cwnd + MSS. */ + if((ack_counter != 1) || (server_socket.nx_tcp_socket_tx_window_congestion != 20 + cwnd)) + error_counter++; + + /* Let server congestion. */ + server_socket.nx_tcp_socket_tx_slow_start_threshold = server_socket.nx_tcp_socket_tx_window_congestion - 10; + + /* Record the value of cwnd. */ + cwnd = server_socket.nx_tcp_socket_tx_window_congestion; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet2, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ack_number_2 = server_socket.nx_tcp_socket_tx_sequence; + + /* Send the second packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE/2); + + /* Check whether the cwnd = cwnd + SMSS*SMSS/ cwnd. */ + if((ack_counter != 2) || (server_socket.nx_tcp_socket_tx_window_congestion != server_socket.nx_tcp_socket_connect_mss * server_socket.nx_tcp_socket_connect_mss / cwnd + cwnd)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *rcv_packet_ptr; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 3000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while(!nx_tcp_socket_receive(&client_socket, &rcv_packet_ptr, 5 * NX_IP_PERIODIC_RATE)) + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == 20) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 2) || (ack_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_102_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if((tcp_header_ptr ->nx_tcp_acknowledgment_number == (ack_number_1 + 20)) || (tcp_header_ptr ->nx_tcp_acknowledgment_number == (ack_number_2 + 20))) + ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(ack_counter == 2) + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_23_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Spec 102.23 Test......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_102_24_test.c b/test/regression/netxduo_test/netx_102_24_test.c new file mode 100644 index 00000000..2a4e36e7 --- /dev/null +++ b/test/regression/netxduo_test/netx_102_24_test.c @@ -0,0 +1,360 @@ +/* 102.24 Formula commonly used to update cwnd during congestion avoidance is cwnd += SMSS*SMSS/ cwnd executed on every incoming non-duplicate ACK. */ + +/* Procedure + 1. Connection. + 2. Set ssthresh = cwnd - 10. + 3. Client sends a data packet. + 4. Server starts congestion, after receives the packet, check cwnd = cwnd + MSS * MSS / cwnd. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG ack_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +static void my_tcp_packet_receive_102_24(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_24_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter =0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +ULONG cwnd; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client congestion. */ + client_socket.nx_tcp_socket_tx_slow_start_threshold = client_socket.nx_tcp_socket_tx_window_congestion - 10; + + /* Record the value of client socket's cwnd. */ + cwnd = client_socket.nx_tcp_socket_tx_window_congestion; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_102_24; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check whether the cwnd = cwnd + MSS * MSS / cwnd. */ + if((ack_counter != 1) || (client_socket.nx_tcp_socket_tx_window_congestion != client_socket.nx_tcp_socket_connect_mss2 / cwnd + cwnd)) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 1) || (ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *rcv_packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.24 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_receive(&server_socket, &rcv_packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == 28) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, 28))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_102_24(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + + if(client_socket.nx_tcp_socket_duplicated_ack_received == 0) + ack_counter++; + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_24_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Spec 102.24 Test......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_102_25_test.c b/test/regression/netxduo_test/netx_102_25_test.c new file mode 100644 index 00000000..388cbe63 --- /dev/null +++ b/test/regression/netxduo_test/netx_102_25_test.c @@ -0,0 +1,399 @@ +/* 102.25 The increase in cwnd should be at most one segment each round-trip time (regardless how many ACKs are received in that RTT). */ + +/* Procedure + 1. Connection. + 2. Client sends a data packet. + 3. Server receives the packet and replies an ACK packet. + 4. Check cwnd <= cwnd + MSS. + 5. Client sends a data packet again. + 6. Set ssthresh = cwnd - 10. + 7. Server starts congestion, after receives the packet, check cwnd <= cwnd + MSS. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG ack_counter; +static ULONG ack_number_1; +static ULONG ack_number_2; +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_102_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_25_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +ULONG cwnd; + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 102.25 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_102_25; + + /* Record the value of cwnd. */ + cwnd = server_socket.nx_tcp_socket_tx_window_congestion; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Record the tx_sequence. */ + ack_number_1 = server_socket.nx_tcp_socket_tx_sequence; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the cwnd <= cwnd + MSS. */ + if((ack_counter != 1) || (server_socket.nx_tcp_socket_tx_window_congestion > server_socket.nx_tcp_socket_connect_mss + cwnd)) + error_counter++; + + /* Let server congestion. */ + server_socket.nx_tcp_socket_tx_slow_start_threshold = server_socket.nx_tcp_socket_tx_window_congestion - 10; + + /* Record the value of cwnd. */ + cwnd = server_socket.nx_tcp_socket_tx_window_congestion; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet2, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ack_number_2 = server_socket.nx_tcp_socket_tx_sequence; + + /* Send the second packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the cwnd <= cwnd + MSS. */ + if((ack_counter != 2) || (server_socket.nx_tcp_socket_tx_window_congestion > server_socket.nx_tcp_socket_connect_mss + cwnd)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *rcv_packet_ptr; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while(!nx_tcp_socket_receive(&client_socket, &rcv_packet_ptr, 5 * NX_IP_PERIODIC_RATE)) + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == 20) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 2) || (ack_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_102_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if((tcp_header_ptr ->nx_tcp_acknowledgment_number == (ack_number_1 + 20)) || (tcp_header_ptr ->nx_tcp_acknowledgment_number == (ack_number_2 + 20))) + ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(ack_counter == 2) + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_102_25_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Spec 102.25 Test......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_103_17_test.c b/test/regression/netxduo_test/netx_103_17_test.c new file mode 100644 index 00000000..9aa12396 --- /dev/null +++ b/test/regression/netxduo_test/netx_103_17_test.c @@ -0,0 +1,482 @@ +/* 103.17 After receiving 3 duplicate ACKs, TCP performs a retransmission of missing segment, without waiting for retransmission timer to expire. */ + +/* Procedure +1. Client connect with Server. +2. Client send segment to Server. +3. Drop it in the driver. +4. Client sends three segments. +5. Client retransmits the first segment. +6. Server receives the segment and check the segments data. +7. Disconnect. +8. Print the result. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_packet.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG seq_number; +static ULONG ack_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_103_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_103_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_103_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + seq_number = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +NX_PACKET *my_packet4; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 103.17 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_103_17; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_103_17; + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet2, MSG+20, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet3, MSG+40, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet4, MSG+60, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Check receive queue of client is not ready. */ + if (client_socket.nx_tcp_socket_receive_queue_head) + { + + /* No packet is ready since the first packet is dropped. */ + if (client_socket.nx_tcp_socket_receive_queue_head -> nx_packet_queue_next == ((NX_PACKET*)NX_PACKET_READY)) + { + error_counter++; + } + } + else + { + + /* Packet out of order should be in queue. */ + error_counter++; + } + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet4, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + if(ack_counter != 3) + error_counter++; + + /* Check receive queue of client is ready. */ + if (client_socket.nx_tcp_socket_receive_queue_head) + { + + /* Packet is ready since the fast retransmit is performed. */ + if (client_socket.nx_tcp_socket_receive_queue_head -> nx_packet_queue_next != ((NX_PACKET*)NX_PACKET_READY)) + { + error_counter++; + } + } + else + { + + /* Packet out of order should be in queue. */ + error_counter++; + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while(!(status = nx_tcp_socket_receive(&client_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE))) + { + + if((packet_ptr -> nx_packet_length == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr, (MSG + data_packet_counter * 20), 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 4) || (ack_counter != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_103_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + + if((packet_ptr -> nx_packet_length-40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr+40, MSG, 20))) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + seq_number = tcp_header_ptr -> nx_tcp_sequence_number; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + advanced_packet_process_callback = NULL; + } + return NX_TRUE; +} + +static void my_tcp_packet_receive_103_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(tcp_header_ptr ->nx_tcp_acknowledgment_number == seq_number) + ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(ack_counter == 3) + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_103_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 103.17 Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_104_17_test.c b/test/regression/netxduo_test/netx_104_17_test.c new file mode 100644 index 00000000..315f4bcc --- /dev/null +++ b/test/regression/netxduo_test/netx_104_17_test.c @@ -0,0 +1,459 @@ +/* 104.17 When next ACK arrives that acknowledges previously unacknowledged data, set cwnd to ssthresh (the value set in step 2). This is termed `'deflating' the window. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG seq_number; +static ULONG ack_counter; +static ULONG duplicate_ack_counter; +static ULONG ssthresh; +static ULONG cwnd; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_104_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_104_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_104_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + seq_number = 0; + ack_counter = 0; + duplicate_ack_counter = 0; + ssthresh = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +NX_PACKET *my_packet4; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 104.17 Test......................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_104_17; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_104_17; + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet2, MSG+20, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet3, MSG+40, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet4, MSG+60, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet4, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + ssthresh = server_socket.nx_tcp_socket_tx_outstanding_bytes / 2; + if(ssthresh < 2 * server_socket.nx_tcp_socket_connect_mss) + ssthresh = 2 * server_socket.nx_tcp_socket_connect_mss; + + cwnd = server_socket.nx_tcp_socket_tx_window_congestion; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + if(ack_counter == 1) + { + /* Check whether the cwnd += SMSS*SMSS/ cwnd or cwnd = mss + ssthresh, but cwnd shall never exceed the advertised window. */ + if((server_socket.nx_tcp_socket_tx_window_congestion != server_socket.nx_tcp_socket_connect_mss2 / cwnd + cwnd) && (server_socket.nx_tcp_socket_tx_window_congestion != ssthresh + server_socket.nx_tcp_socket_connect_mss) && + (server_socket.nx_tcp_socket_tx_window_congestion != server_socket.nx_tcp_socket_tx_window_advertised)) + error_counter++; + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + while(!(status = nx_tcp_socket_receive(&client_socket, &packet_ptr, NX_IP_PERIODIC_RATE))) + { + + if((packet_ptr -> nx_packet_length == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr, (MSG + data_packet_counter * 20), 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 4) || (duplicate_ack_counter != 3) || (ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_104_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + + if((packet_ptr -> nx_packet_length-40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr+40, MSG, 20))) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + seq_number = tcp_header_ptr -> nx_tcp_sequence_number; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + advanced_packet_process_callback = NULL; + } + return NX_TRUE; +} + +static void my_tcp_packet_receive_104_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(tcp_header_ptr ->nx_tcp_acknowledgment_number == seq_number) + duplicate_ack_counter++; + else + { + ack_counter++; + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_104_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 104.17 Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_106_17_test.c b/test/regression/netxduo_test/netx_106_17_test.c new file mode 100644 index 00000000..2073ad9a --- /dev/null +++ b/test/regression/netxduo_test/netx_106_17_test.c @@ -0,0 +1,396 @@ +/* 12.18:TCP MUST be able to receive MSS option in SYN segment and calculate the effective send segment size appropriately. */ + +/* Procedure +1.Connect +2.Server_socket's connect_MSS should equal client_socket's MSS.(client_socket's MSS = 88, server_socket's MSS = 1460) +3. A packet should be intercepted by function my_tcp_packet_receive_106_17 which is sent from client socket to server socket. +4. Check: the packet should be a SYN packet, increment the syn_counter. Whether or not calling the defaulted packet receiving function. +5. Check if all of the packets we have catched can connected to the my_packet we send*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + + +static TX_THREAD ntest_1; +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_1; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_counter; +static ULONG packet_length_106_17; +static ULONG mss_option_106_17; + + +static UCHAR rcv_buffer[200]; +static UINT rcv_length; + + +/* Define thread prototypes. */ + +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_106_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_106_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_counter = 0; + packet_length_106_17 = 0; + mss_option_106_17 = 0; + rcv_length = 0; + + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 512*16); + pointer = pointer + 512*16; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_106_17; + + packet_length_106_17 = server_socket.nx_tcp_socket_connect_mss + 20; + mss_option_106_17 = server_socket.nx_tcp_socket_connect_mss; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, MSG, packet_length_106_17, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +ULONG bytes_copied; + + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 106.17 Test......................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while(!(nx_tcp_socket_receive(&client_socket, &my_packet, NX_IP_PERIODIC_RATE))) + { + /*Check if the packet is fragmented by TCP layer.*/ + if(my_packet -> nx_packet_length > mss_option_106_17) + error_counter++; + + /* Retrieve data from packet to the receive buffer. */ + status = nx_packet_data_retrieve(my_packet, &rcv_buffer[rcv_length], &bytes_copied); + if(status) + error_counter++; + + rcv_length += bytes_copied; + } + + /*Check if the content which connected by all the received packets is the data_106_17 sent from the client socket*/ + if(!memcmp(rcv_buffer, MSG, packet_length_106_17)) + data_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status += nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter !=0) || (data_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static UINT my_packet_process_106_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + +#if defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#else +NX_IP_HEADER *ip_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#endif + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + if((packet_ptr -> nx_packet_length) > 40) + { + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /*Check if the packet is fragmented by IP layer.*/ + if(!(ip_header_ptr -> nx_ip_header_word_1 & NX_IP_FRAGMENT_MASK)) + { + /*Check if the packet is fragmented by TCP layer*/ + if(packet_ptr -> nx_packet_length > (mss_option_106_17 + 40)) + error_counter++; + } + else + error_counter++; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + } + else + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + return NX_TRUE; +} + + + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_106_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 106.17 Test......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_10_23_01_test.c b/test/regression/netxduo_test/netx_10_23_01_test.c new file mode 100644 index 00000000..d327602c --- /dev/null +++ b/test/regression/netxduo_test/netx_10_23_01_test.c @@ -0,0 +1,363 @@ +/* 10.23.01 TCP, in LISTEN state, Send RST message when recieved a FIN + ACK. */ + +/* Procedure + 1.When the Server has been on the LISTEN state, Client sends a FIN to Server + 2.Check if the state has been changed. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; +static ULONG fin_counter; +static ULONG rst_for_fin_ack; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_10_23_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_10_23_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_10_23_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_23_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_10_23_01; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + if(server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_10_23_01; + + tx_thread_suspend(&ntest_0); + + if((fin_counter != 1) || (server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE)) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.23.01 Test...................................."); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_10_23_01_2; + + /* Send FIN packet. */ + _nx_tcp_packet_send_fin(&client_socket, client_socket.nx_tcp_socket_tx_sequence); + + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + tx_thread_resume(&ntest_0); + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (rst_counter != 1) || (fin_counter != 1) || (rst_for_fin_ack != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_10_23_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_10_23_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + fin_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_10_23_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check the fin counter. */ + if(fin_counter == 1) + { + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + rst_for_fin_ack ++; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let client receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_23_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.23.01 Test....................................N/A\n"); + test_control_return(3); + +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_10_23_02_test.c b/test/regression/netxduo_test/netx_10_23_02_test.c new file mode 100644 index 00000000..dd0db165 --- /dev/null +++ b/test/regression/netxduo_test/netx_10_23_02_test.c @@ -0,0 +1,444 @@ +/* 10.23.02 TCP, in CLOSED, Send RST for FIN +ACK, in SYN-SENT state, ignore the FIN+ACK.. */ + +/* Procedure + 1.When the Client has been on the CLOSED , Server sends a FIN + ACK to Client + 2.When the Client has been on the SYN_SENT, Server sends a FIN + ACK to Client. + 3.Check if the state has been changed. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; +static ULONG syn_counter; +static ULONG fin_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *, ULONG, UINT, ULONG *, ULONG *); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_10_23_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_10_23_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_10_23_02_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_23_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + syn_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_10_23_02; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_10_23_02; + + tx_thread_resume(&ntest_1); + + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + if(client_socket.nx_tcp_socket_state != NX_TCP_SYN_SENT) + error_counter++; + + tx_thread_resume(&ntest_1); + + if(client_socket.nx_tcp_socket_state != NX_TCP_SYN_SENT) + error_counter++; + + tx_thread_resume(&ntest_1); + + /* Let the client socket disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (rst_counter != 1) || (syn_counter != 1) || (fin_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.23.02 Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_10_23_02_2; + + /* Send FIN packet. */ + _nx_tcp_packet_send_fin(&server_socket, server_socket.nx_tcp_socket_tx_sequence); + + tx_thread_suspend(&ntest_1); + + /* Send FIN packet. */ + _nx_tcp_packet_send_fin(&server_socket, server_socket.nx_tcp_socket_tx_sequence); + + tx_thread_suspend(&ntest_1); + + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + + /* Let the server socket disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_10_23_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; + +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#else +ULONG source_ip, dest_ip; +#endif + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + + if (fin_counter) + rst_counter++; + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + else if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) + { + syn_counter++; + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + else if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (fin_counter == 1)) + { + /* Modify the acknowledgement number. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + tcp_header_ptr -> nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_tx_sequence; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &server_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &server_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + advanced_packet_process_callback = NX_NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_10_23_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + fin_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(fin_counter == 2) + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_10_23_02_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + if(fin_counter != 0) + error_counter++; + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_23_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.23.02 Test....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_10_24_01_test.c b/test/regression/netxduo_test/netx_10_24_01_test.c new file mode 100644 index 00000000..ff64e92a --- /dev/null +++ b/test/regression/netxduo_test/netx_10_24_01_test.c @@ -0,0 +1,331 @@ +/* 10.24 TCP, in CLOSE-WAIT, CLOSING or LAST-ACK state, MUST not change state after receiving a FIN. */ +/*This is 10.24_01 in CLOSE-WAIT state*/ +/* Procedure + 1.Connection successfully + 2.Disconnect the Server socket. + 3.Drop the ACK packet sent form the Client to the Sever. + 4.The Server will retransmit the FIN packet. + 5.Check whether the state of the client socket has been changed. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_10_24_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_10_24_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_24_01_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_10_24_01; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_10_24_01; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Sleep two seconds to wait for the retransmission of the FIN packet. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + if((client_socket.nx_tcp_socket_state != NX_TCP_CLOSE_WAIT) || (fin_counter != 2)) + error_counter++; + + /* Return error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.24.01 Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE * 2); + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + + +static UINT my_packet_process_10_24_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Drop the ACK packet in order to let the server socket retransmit a FIN packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (fin_counter == 1)) + { + *operation_ptr = NX_RAMDRIVER_OP_DROP; + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; + +} + +void my_tcp_packet_receive_10_24_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (fin_counter == 0)) + { + fin_counter++; + } + + /* Check wether receive a FIN in CLOSE_WAIT state */ + else if (client_socket.nx_tcp_socket_state == NX_TCP_CLOSE_WAIT && fin_counter == 1) + { + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + fin_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_24_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.24.01 Test....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_10_24_02_test.c b/test/regression/netxduo_test/netx_10_24_02_test.c new file mode 100644 index 00000000..6af5d55a --- /dev/null +++ b/test/regression/netxduo_test/netx_10_24_02_test.c @@ -0,0 +1,362 @@ +/* 10.24 TCP, in CLOSE-WAIT, CLOSING or LAST-ACK state, MUST not change state after receiving a FIN. */ +/*This is 10.24_02 in CLOSING state*/ + +/* Procedure + 1.Connection successfully + 2.Disconnect the Server socket. + 3.Drop the FIN packet sent form the Sever to the Client. + 4.Disconnect the Client socket. + 5.Drop the ACK packet sent form the Sever to the Client. + 6.The Client will retransmit the FIN packet. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +#define DEMO_STACK_SIZE 2048 + +extern void test_control_return(UINT status); +#if defined NX_DISABLE_RESET_DISCONNECT && !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; + + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); + + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_10_24_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_10_24_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_24_02_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.24.02 Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_10_24_02; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_10_24_02; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* sleep to wait for the retransmission of FIN */ + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + /* Check the server socket state and fin_counter. */ + if((server_socket.nx_tcp_socket_state != NX_TCP_CLOSING) || (fin_counter != 3)) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (fin_counter != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* CLOSE_WAIT.. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 3 * NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + + +static UINT my_packet_process_10_24_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (fin_counter == 0)) + { + fin_counter++; + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + /* Drop the ACK packet in order to let the client socket retransmit a FIN packet. */ + else if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (ip_ptr == &ip_0)) + { + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; + +} + +void my_tcp_packet_receive_10_24_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (fin_counter == 1)) + { + fin_counter++; + } + /* Check wether receive a FIN in CLOSE_WAIT state */ + else if (server_socket.nx_tcp_socket_state == NX_TCP_CLOSING && fin_counter == 2) + { + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + fin_counter++; + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_24_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.24.02 Test....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_10_24_03_test.c b/test/regression/netxduo_test/netx_10_24_03_test.c new file mode 100644 index 00000000..0c1adf54 --- /dev/null +++ b/test/regression/netxduo_test/netx_10_24_03_test.c @@ -0,0 +1,347 @@ +/* 10.24 TCP, in CLOSE-WAIT, CLOSING or LAST-ACK state, MUST not change state after receiving a FIN. */ +/*This is 10.24_03 in LAST-ACK state*/ + +/* Procedure + 1.Connection successfully + 2.Disconnect the Server socket. + 3.Drop the packet sent form the Client to the Sever. + 4.Disconnect the Client socket. + 5.Drop the packet sent form the Client to the Sever. + 6.The Server will retransmit the FIN packet. + 7.Check whether the state of the client socket has been changed. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#if defined NX_DISABLE_RESET_DISCONNECT && !defined(NX_DISABLE_IPV4) + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; + + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_10_24_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_10_24_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_24_03_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* sleep to wait for the retransmission of FIN */ + tx_thread_sleep(NX_IP_PERIODIC_RATE * 3); + + if((client_socket.nx_tcp_socket_state != NX_TCP_LAST_ACK) || (fin_counter != 3)) + error_counter++; + + /* Return error. */ + if((error_counter) || (fin_counter != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.24.03 Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_10_24_03; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_10_24_03; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE * 3); + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + + + +static UINT my_packet_process_10_24_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Drop the ACK packet from client socket to let server socket retransmit FIN. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (fin_counter == 1)) + { + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + /* Drop the FIN packet from client socket in order to keep the client socket in NX_TCP_LAST_ACK state. */ + else if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (ip_ptr == &ip_0)) + { + + if (fin_counter == 1) + fin_counter++; + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; + +} + +void my_tcp_packet_receive_10_24_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (fin_counter == 0)) + { + fin_counter++; + } + + /* Check wether receive a FIN in NX_TCP_LAST_ACK state */ + else if ((client_socket.nx_tcp_socket_state == NX_TCP_LAST_ACK) && (fin_counter == 2)) + { + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + fin_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_24_03_application_define(void *first_unused_memory) +#endif +{ + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.24.03 Test....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_10_25_test.c b/test/regression/netxduo_test/netx_10_25_test.c new file mode 100644 index 00000000..96304782 --- /dev/null +++ b/test/regression/netxduo_test/netx_10_25_test.c @@ -0,0 +1,384 @@ +/* 10.25 TCP, in ESTABLISHED state, SHOULD piggyback acknowledgement with +a segment being transmitted (whenever possible) without incurring undue delay. */ + +/* Procedure + 1. Client connects to server. + 2. Client sends a packet to Server. + 3. When receives packet, Server sends a packet to client immediately. + 4. Check the packet server sending to client,if it acknowledges packet of client. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_counter; +static ULONG ack_counter; + +static UCHAR data_10_25[20]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT my_packet_process_10_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_10_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_25_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.25 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_10_25; + packet_process_callback = my_packet_process_10_25; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = _nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + srand((unsigned)time(NULL)); + for(i = 0;i < 20;i++) + { + data_10_25[i] = rand() % 256; + } + + status = nx_packet_data_append(my_packet, data_10_25, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (data_counter != 1) || (ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void my_tcp_packet_receive_10_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + if( (server_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) && (packet_ptr->nx_packet_length == 40) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, data_10_25, 20))) + { + data_counter ++; + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT my_packet_process_10_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if( server_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) + { + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Check whether piggyback acknowledgment with a segment being transmitted. */ + if((tcp_header_ptr ->nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (tcp_header_ptr -> nx_tcp_acknowledgment_number == client_socket.nx_tcp_socket_tx_sequence)) + ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + + packet_process_callback = NULL; + } + + return NX_TRUE; + +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_25_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.25 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_10_26_test.c b/test/regression/netxduo_test/netx_10_26_test.c new file mode 100644 index 00000000..13eb69c3 --- /dev/null +++ b/test/regression/netxduo_test/netx_10_26_test.c @@ -0,0 +1,394 @@ +/* 10.26 TCP, in ESTABLISHED state, MUST ignore a dupli-cate ACK. */ + +/* Procedure + 1. Connection. + 2. Client sends a packet, then Server replies with an ACK packet + 3. Record client's tx_sequence. + 4. Server sends a same ACK packet and check whether receives a reply. Check client's tx_sequence dosen't change. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +static UCHAR data_10_26[20]; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ack_counter; + +static ULONG tx_sequence; +static ULONG acknowledgment_number; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_10_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_26_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + acknowledgment_number = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_10_26; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + srand((unsigned)time(NULL)); + for(i = 0;i < 20;i++) + { + data_10_26[i] = rand() % 256; + } + + status = nx_packet_data_append(my_packet, data_10_26, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + if(tx_sequence != client_socket.nx_tcp_socket_tx_sequence) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (ack_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 10.26 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + nx_packet_release(my_packet); + + /* Let the thread sleep to wait for the the delay confirmation */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Send the duplicate ACK packet. */ + _nx_tcp_packet_send_ack(&server_socket,server_socket.nx_tcp_socket_tx_sequence); + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void my_tcp_packet_receive_10_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if (client_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check whether the packet is a ACK one. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && + (ack_counter == 0)) + { + ack_counter++; + tx_sequence = client_socket.nx_tcp_socket_tx_sequence; + acknowledgment_number = tcp_header_ptr -> nx_tcp_acknowledgment_number; + } + + /* Check whether the packet is a duplicate ACK. */ + else if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && + (acknowledgment_number == tcp_header_ptr -> nx_tcp_acknowledgment_number) && + (ack_counter == 1)) + { + ack_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_10_26_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 10.26 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_11_18_test.c b/test/regression/netxduo_test/netx_11_18_test.c new file mode 100644 index 00000000..f1cea786 --- /dev/null +++ b/test/regression/netxduo_test/netx_11_18_test.c @@ -0,0 +1,330 @@ +/* 11.18 TCP, if starts as an active connection and reaches SYN-RCVD state MUST go to CLOSED state on RESET. */ + +/* Procedure +1. Client_1 sends a SYN to Client_2. +2. Use my_packet_process_11_18 function to drop the SYN packet. +3. Client_2 sends a SYN to Client_1. +4. Client_1 sends a SYN+ACK to Client_2. +5. Use my_packet_process_11_18 function to drop the SYN+ACK packet. +6. Client_2 sends a RST to Client_1. +7. Check the Client_1 state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_1_socket; +static NX_TCP_SOCKET client_2_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_11_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_11_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_18_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.18 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_1_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_1_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the SYN packet with my routing */ + advanced_packet_process_callback = my_packet_process_11_18; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_11_18; + + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_1_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check the Client_1's state. */ + if((rst_counter != 1) || (client_1_socket.nx_tcp_socket_state != NX_TCP_CLOSED)) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_1_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_1_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_TCP_HEADER header_ptr; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_2_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_bind(&client_2_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_2_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_NO_WAIT); + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + header_ptr.nx_tcp_acknowledgment_number = client_1_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = client_1_socket.nx_tcp_socket_tx_sequence + 1; + + _nx_tcp_packet_send_rst(&client_2_socket, &header_ptr); + + tx_thread_sleep(NX_IP_PERIODIC_RATE/20); + + /* Disconnect the socket. */ + status = nx_tcp_socket_disconnect(&client_2_socket, NX_NO_WAIT); + + status = nx_tcp_client_socket_unbind(&client_2_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_2_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (syn_counter != 2 ) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process_11_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* Check if it is a SYN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (syn_counter == 0)) + { + syn_counter++; + + /*Drop the packet*/ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + /* Check if it is a SYN+ACK packet. */ + else if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (syn_counter == 2)) + { + /*Drop the packet*/ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + advanced_packet_process_callback = NX_NULL; + } + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_11_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a SYN one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (syn_counter == 1)) + syn_counter++; + else if(client_1_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) + { + /* Check the packet is a RST one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let client1 receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_18_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.18 Test.......................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_11_19_test.c b/test/regression/netxduo_test/netx_11_19_test.c new file mode 100644 index 00000000..16db4269 --- /dev/null +++ b/test/regression/netxduo_test/netx_11_19_test.c @@ -0,0 +1,317 @@ +/* 11.19 TCP, in ESTABLISHED state MUST inform the application in case of aborting from remote site. */ + +/* Procedure + 1. Client connects to server. + 2. Client sends a RST packet to serve. + 3. Check if server is notified. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; + +static UINT is_notified; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_11_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_19_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client checks the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_11_19; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if (is_notified == NX_FALSE) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_TCP_HEADER header_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.19 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + is_notified = NX_FALSE; + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + /* Send a RST packet */ + header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_rst(&server_socket, &header_ptr); + + /* let ntest_0 to check*/ + tx_thread_sleep(1); + + status = nx_tcp_socket_disconnect(&server_socket,NX_IP_PERIODIC_RATE); + + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (rst_counter != 1) ) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_tcp_packet_receive_11_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if(client_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) + { + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a RST one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + /* Check for proper disconnected socket. */ + if(socket != &client_socket) + error_counter++; + + is_notified = NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_19_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.19 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_11_23_test.c b/test/regression/netxduo_test/netx_11_23_test.c new file mode 100644 index 00000000..1a8a902f --- /dev/null +++ b/test/regression/netxduo_test/netx_11_23_test.c @@ -0,0 +1,380 @@ +/* 11.23 Local user initiates the close, a FIN segment can be constructed and placed on the outgoing segment queue. */ + +/* Procedure + 1 Establish the connection; + 2 Let the server socket send segments until the rx_window of the client socket reduce to 0; + 3 Call the disconnect API, check whether a FIN packet is sent out in the callback function; + 4 Let the client socket receive the packet; + 5 Check whether the FIN packet is received in the tcp packet receive function we defined.0 */ + +/* Warning: FIN segment is not placed on the outgoing segment queue. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; + +static UCHAR data_11_23[88]; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_11_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_23_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for error. */ + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for error. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.23 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 88, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + srand((unsigned)time(NULL)); + for(i = 0;i < 88;i++) + { + data_11_23[i] = rand() % 256; + } + + status = nx_packet_data_append(my_packet, data_11_23, 88, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(client_socket.nx_tcp_socket_rx_window_current != 0) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 88, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = _nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_11_23; + + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&client_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + if(client_socket.nx_tcp_socket_rx_window_current == 0) + error_counter++; + + nx_packet_release(my_packet); + } + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if (fin_counter != 1) + { + printf("WARNING!\n"); + test_control_return(2); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +void my_tcp_packet_receive_11_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + fin_counter++; + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_23_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.23 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_11_24_test.c b/test/regression/netxduo_test/netx_11_24_test.c new file mode 100644 index 00000000..8f0d6297 --- /dev/null +++ b/test/regression/netxduo_test/netx_11_24_test.c @@ -0,0 +1,346 @@ +/* 11.24 Local user initiates the close, TCP enters the FIN-WAIT-1 state. RECEIVEs are allowed in this state. */ + +/* Procedure + 1.Connection successfully + 2.Let Server's state to FIN_WAIT_1 + 3.Client sends some data to Server + 4.Check if Server receives data successfully. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include +#include "nx_ram_network_driver_test_1500.h" +#define DEMO_STACK_SIZE 2048 + +extern void test_control_return(UINT status); +#if defined NX_DISABLE_RESET_DISCONNECT && !defined(NX_DISABLE_IPV4) + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_counter; + +static UCHAR data_11_24[20]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_11_24(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_24_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.24 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_11_24; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + if(server_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_1) + { + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status != NX_SUCCESS) + error_counter++; + else + { + /* Check data length and payload */ + if((my_packet -> nx_packet_length == 20) && (!memcmp(my_packet -> nx_packet_prepend_ptr, data_11_24, 20))) + data_counter++; + + /* Release the packet. */ + nx_packet_release(my_packet); + } + } + else + error_counter++; + + advanced_packet_process_callback = NX_NULL; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + srand((unsigned)time(NULL)); + for(i = 0;i < 20;i++) + { + data_11_24[i] = rand() % 256; + } + + status = nx_packet_data_append(my_packet, data_11_24, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (data_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +static UINT my_packet_process_11_24(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + /*Drop the packet*/ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; + +} + + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_24_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.24 Test.......................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_11_25_test.c b/test/regression/netxduo_test/netx_11_25_test.c new file mode 100644 index 00000000..a55374fc --- /dev/null +++ b/test/regression/netxduo_test/netx_11_25_test.c @@ -0,0 +1,322 @@ +/* 11.25 TCP enters the FIN-WAIT-2 state. RECEIVEs are allowed in this state. */ + +/* Procedure + 1. Client connects to server. + 2. Client sends a packet to server. + 3. Server calls disconnect function. + 4. When server receives ACK packet from client, call receive function. + 5. Check if server receives data successfully. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include +#define DEMO_STACK_SIZE 2048 + +extern void test_control_return(UINT status); +#if defined NX_DISABLE_RESET_DISCONNECT && !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_counter; + +static UCHAR data_11_25[20]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_25_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.25 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + if(server_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_2) + { + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status != NX_SUCCESS) + error_counter++; + else + { + /* Check data length and payload */ + if((my_packet -> nx_packet_length == 20) && (!memcmp(my_packet -> nx_packet_prepend_ptr, data_11_25, 20))) + data_counter++; + + /* Release the packet. */ + nx_packet_release(my_packet); + } + } + else + error_counter++; + + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = _nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + srand((unsigned)time(NULL)); + for(i = 0;i < 20;i++) + { + data_11_25[i] = rand() % 256; + } + + status = nx_packet_data_append(my_packet, data_11_25, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (data_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_25_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.25 Test.......................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_11_26_test.c b/test/regression/netxduo_test/netx_11_26_test.c new file mode 100644 index 00000000..cd1b1053 --- /dev/null +++ b/test/regression/netxduo_test/netx_11_26_test.c @@ -0,0 +1,354 @@ +/* 11.26:If an unsolicited FIN arrives from the network, TCP enters the CLOSE_WAIT state. TCP can send any remaining data. */ + +/* Procedure + 1. Client connects to server. + 2. Disconnect the server socket, then the client socket's state is ClOSE_WAIT + 3. Client socket sends segment, it should return SUCCESS. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_counter; +static ULONG fin_counter; + +static UCHAR data_11_26[20]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_11_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_11_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_26_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_11_26; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + srand((unsigned)time(NULL)); + for(i = 0;i < 20;i++) + { + data_11_26[i] = rand() % 256; + } + + status = nx_packet_data_append(my_packet, data_11_26, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_11_26; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (data_counter != 1) || (fin_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 11.26 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 100,NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +void my_tcp_packet_receive_11_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT)) + { + fin_counter++; + + /* Point to default function */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static UINT my_packet_process_11_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UCHAR *data_ptr; + + if(client_socket.nx_tcp_socket_state == NX_TCP_CLOSE_WAIT) + { + data_ptr = packet_ptr -> nx_packet_prepend_ptr + 40; + + if(memcmp(data_ptr, data_11_26, 20) == 0) + data_counter++; + + advanced_packet_process_callback = NX_NULL; + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_26_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.26 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_11_27_test.c b/test/regression/netxduo_test/netx_11_27_test.c new file mode 100644 index 00000000..7453bbe0 --- /dev/null +++ b/test/regression/netxduo_test/netx_11_27_test.c @@ -0,0 +1,349 @@ +/* 11.27 TCP, FINWAIT-1 state MUST inform the application in case of aborting from remote site. */ + +/* Procedure + 1. Client connects to server. + 2. Server calls disconnect function. + 3. Drop the FIN packet. + 4. Send a RST packet to server. + 5. Check if server is notified. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_11_27(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_11_27(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_27_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.27 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_11_27; + advanced_packet_process_callback = my_packet_process_11_27; + + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + if((rst_counter != 1) || (status!= NX_DISCONNECT_FAILED)) + error_counter++; + + advanced_packet_process_callback = NX_NULL; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_TCP_HEADER header_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + header_ptr.nx_tcp_acknowledgment_number = server_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = server_socket.nx_tcp_socket_tx_sequence + 1; + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; + +} + +static void my_tcp_packet_receive_11_27(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if (server_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + + +static UINT my_packet_process_11_27(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + /*Drop the packet*/ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_27_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.27 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_11_28_test.c b/test/regression/netxduo_test/netx_11_28_test.c new file mode 100644 index 00000000..c434eac8 --- /dev/null +++ b/test/regression/netxduo_test/netx_11_28_test.c @@ -0,0 +1,318 @@ +/* 11.28 TCP, FINWAIT-2 state MUST inform the application in case of aborting from remote site. */ + +/* Procedure + 1. Client connects to server. + 2. Server calls disconnect function. + 2. When server receives ACK packet, client sends a RST packet to server. + 3. Check if server is notified. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_11_28(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_28_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.28 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_11_28; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + if((rst_counter != 1) || (status!= NX_DISCONNECT_FAILED)) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_TCP_HEADER header_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Attempt to connect the socket. */ + status = _nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + /* Send a RST packet */ + header_ptr.nx_tcp_acknowledgment_number = server_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = server_socket.nx_tcp_socket_tx_sequence + 1; + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_11_28(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if(server_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_2) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_28_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.28 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_11_29_test.c b/test/regression/netxduo_test/netx_11_29_test.c new file mode 100644 index 00000000..e19cf17b --- /dev/null +++ b/test/regression/netxduo_test/netx_11_29_test.c @@ -0,0 +1,318 @@ +/* 11.29 TCP, in CLOSE-WAIT state MUST inform the appli-cation in case of aborting from remote site. */ + +/* Procedure + 1. Client connects to Server. + 2. Server calls disconnect function. + 2. When Client receives FIN packet, Server sends a RST packet to Client. + 3. Check if Client is notified. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_11_29(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_29_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup function pointer. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_11_29; + + /* Attempt to connect the socket. */ + status = _nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + tx_thread_resume(&ntest_1); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_TCP_HEADER header_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.29 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + /* Send a RST packet */ + header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence + 1; + _nx_tcp_packet_send_rst(&server_socket, &header_ptr); + + tx_thread_suspend(&ntest_1); + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_11_29(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if(client_socket.nx_tcp_socket_state == NX_TCP_CLOSE_WAIT) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_11_29_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 11.29 Test.......................................N/A\n"); + test_control_return(3); + +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_12_01_test.c b/test/regression/netxduo_test/netx_12_01_test.c new file mode 100644 index 00000000..17a80239 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_01_test.c @@ -0,0 +1,422 @@ +/* 12.01 TCP MUST be prepared to handle an illegal option length for MSS, in a SYN segment, without crashing; + a suggested procedure is to reset the connection and log the reason. */ + +/* Procedure + 1. Client send SYN to server. + 2. When server receives SYN packet, modify the length of MSS in 'my_tcp_packet_process_12_01'. + 3. Pass the SYN packet to the default function . + 4. Check whether client received the RST packet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG syn_counter; +static ULONG rst_counter; +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_01_1(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_12_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *packet_ptr, ULONG protocol, + UINT data_length, ULONG* src_ip_addr, + ULONG* dest_ip_addr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_tcp_enable(&ip_1); + if(status) + error_counter++; + +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.01 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_01_1; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*To handle the syn packet.*/ + advanced_packet_process_callback = my_packet_process_12_01; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_01_2; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Clean up the Server socket. */ + tx_thread_sleep(TX_TIMER_TICKS_PER_SECOND); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter != 0) || (syn_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + +static UINT my_packet_process_12_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG checksum; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* Chcek whether it is a SYN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Modify the MSS length to 0*/ + *option_word_1 = *option_word_1 & 0xFF00FFFF; + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Put the packet pointer to tcp*/ +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket. nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + return NX_TRUE; + } + +static void my_tcp_packet_receive_12_01_1(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; +ULONG *option_word_1; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + option_word_1 = (ULONG *)(header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Server receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + if((*option_word_1 & 0x00FF0000) == 0) + syn_counter++; + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass the packet to the default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_12_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Server receives a RST packet. */ + if(!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + rst_counter++; + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass the packet to the default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.01 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_12_02_test.c b/test/regression/netxduo_test/netx_12_02_test.c new file mode 100644 index 00000000..22e6e561 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_02_test.c @@ -0,0 +1,409 @@ +/* 12.02 TCP MUST be able to receive No Operation and End of Options List options in SYN segment. */ + +/* Procedure + 1. Client sends SYN to server. + 2. When server receives SYN packet, modify the option kind to 'No Operation' and 'End of Options List'. + 3. Pass the SYN packet to the default function . + 4. Check whether client connect to server successfully. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *packet_ptr, int protocol, + UINT data_length, ULONG* src_ip_addr, + ULONG* dest_ip_addr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0;; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.02 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_02; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + if(syn_counter == 1) + { + /*Check whether the connection has crashed*/ + if((client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) || (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + error_counter++; + } + else + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*To handle the syn packet.*/ + advanced_packet_process_callback = my_packet_process_12_02; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Disconnect this socket. */ + status= nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || syn_counter != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +static UINT my_packet_process_12_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; +UCHAR *option; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* Check whether receives a SYN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + /* Set len to length address. */ + option = packet_ptr -> nx_packet_prepend_ptr + 40; + + /* Modify option data. */ + *(ULONG*)option = NX_TCP_OPTION_END; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /*Put the packet pointer to tcp*/ +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + /*Put the packet pointer to tcp*/ +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + return NX_TRUE; + +} + +static void my_tcp_packet_receive_12_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; +UCHAR *option; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + /* Set len to length address. */ + option = packet_ptr -> nx_packet_prepend_ptr + 20; + + if(*(ULONG*)option == NX_TCP_OPTION_END) + syn_counter++; + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass the packet to the default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.02 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_12_03_test.c b/test/regression/netxduo_test/netx_12_03_test.c new file mode 100644 index 00000000..0bf4c92a --- /dev/null +++ b/test/regression/netxduo_test/netx_12_03_test.c @@ -0,0 +1,425 @@ +/* 12.03 TCP MUST ignore without error any TCP option it does not implement. */ + +/* Procedure +1. Client send SYN to server. +2. When server receives SYN packet, modify the TCP option to error in 'my_tcp_packet_process_12_03'. +3. Pass the SYN packet to the default function . +4. Check if client connect to server successfully. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG syn_counter; + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *packet_ptr, int protocol, + UINT data_length, ULONG* src_ip_addr, + ULONG* dest_ip_addr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_03_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + if(status) + error_counter++; + status = nx_tcp_enable(&ip_1); + if(status) + error_counter++; + +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.03 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_03; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + if(syn_counter == 1) + { + /*Check whether the connection has crashed*/ + if((client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) || (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + error_counter++; + } + else + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*To handle the syn packet.*/ + advanced_packet_process_callback = my_packet_process_12_03; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter != 0) || (syn_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + +static UINT my_packet_process_12_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG checksum; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* Client receives a SYN+ACK packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /* Modify the TCP option to unkown option with crrect option length. */ + *option_word_1 = 0x05040002; + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /* Put the packet pointer to tcp. */ +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket. nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + + checksum = ~checksum & NX_LOWER_16_MASK; + +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + return NX_TRUE; +} + +static void my_tcp_packet_receive_12_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; +ULONG *option_word_1; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + option_word_1 = (ULONG *)(header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Server receives a SYN packet. */ + if ((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + if (*option_word_1 == 0x05040002) + syn_counter++; + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass the packet to the default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_03_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.03 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_12_04_test.c b/test/regression/netxduo_test/netx_12_04_test.c new file mode 100644 index 00000000..6550ad04 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_04_test.c @@ -0,0 +1,420 @@ +/* 12.04 TCP MUST be prepared to handle an illegal option length for MSS, in a SYN segment; a suggested procedure is to reset the connection. */ + +/* Procedure +1.Intercept the SYN packet +2.Modify the option_words to the 1220 +3.Check whether the connection is reset */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_12_04_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *packet_ptr, int protocol, + UINT data_length, ULONG* src_ip_addr, + ULONG* dest_ip_addr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_04_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.04 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_04; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_04_2; + + /*To handle the syn packet.*/ + advanced_packet_process_callback = my_packet_process_12_04; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Clean up the Server socket. */ + tx_thread_sleep(TX_TIMER_TICKS_PER_SECOND); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if ((error_counter != 0) && (syn_counter != 1) && (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_12_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG checksum; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + + /* Check whether receives a SYN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Modify the MSS length to 0*/ + *option_word_1 = *option_word_1 & 0xFF00FFFF; + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket. nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + } + return NX_TRUE; +} + +static void my_tcp_packet_receive_12_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; +ULONG *option_word_1; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + option_word_1 = (ULONG *)(header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Server receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + if((*option_word_1 & 0x00FF0000) == 0) + syn_counter++; + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass the packet to the default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +static void my_tcp_packet_receive_12_04_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + + /*Check whether the connection is reset.*/ + if(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + rst_counter++; + + /*If connection havn't been reset, give back, restore the TCP receive function.*/ + else if(header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass the packet to the default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_04_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.04 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_12_17_test.c b/test/regression/netxduo_test/netx_12_17_test.c new file mode 100644 index 00000000..7fade9b6 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_17_test.c @@ -0,0 +1,418 @@ +/* 12.17 TCP MUST be prepared to handle an illegal option length for MSS, in a SYN,ACK segment, without crashing. */ + +/* Procedure + + 1. Client sends SYN to server and server returns SYN+ACK. + 2. When client receives SYN+ACK packet, modify the length of MSS in 'my_tcp_packet_receive_12_17'. + 3. Pass the SYN+ACK packet to the default function . + 4. Check whether the connection is reset */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif +#define DEMO_STACK_SIZE 2048 +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG syn_ack_counter; +static ULONG rst_counter; +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_17_1(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_12_17_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *packet_ptr, int protocol, + UINT data_length, ULONG* src_ip_addr, + ULONG* dest_ip_addr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + if(status) + error_counter++; + status = nx_tcp_enable(&ip_1); + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.17 Test......................................."); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_17_1; + + /*To handle the syn,ack packet.*/ + advanced_packet_process_callback = my_packet_process_12_17; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter != 0) || (syn_ack_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status...*/ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_17_2; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + +static UINT my_packet_process_12_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG checksum; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN+ACK packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Modify the MSS length to 0*/ + *option_word_1 = *option_word_1 & 0xFF00FFFF; + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Put the packet pointer to tcp*/ +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &server_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &server_socket. nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + +#elif defined(__PRODUCT_NETX__) + dest_ip = server_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + + return NX_TRUE; +} + +static void my_tcp_packet_receive_12_17_1(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; +ULONG *option_word_1; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + option_word_1 = (ULONG *)(header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN+ACK packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + if((*option_word_1 & 0x00FF0000) == 0) + syn_ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass the packet to the default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_12_17_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Server receives a RST packet. */ + if(!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + rst_counter++; + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass the packet to the default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.17 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_12_18_test.c b/test/regression/netxduo_test/netx_12_18_test.c new file mode 100644 index 00000000..d7ce2734 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_18_test.c @@ -0,0 +1,447 @@ +/* 12.18:TCP MUST be able to receive MSS option in SYN segment and calculate the effective send segment size appropriately. */ + +/* Procedure +1.Connect +2.Server_socket's connect_MSS should equal client_socket's MSS.(client_socket's MSS = 88, server_socket's MSS = 1460) +3. A packet should be intercepted by function my_tcp_packet_receive_12_18 which is sent from client socket to server socket. +4. Check: the packet should be a SYN packet, increment the syn_counter. Whether or not calling the defaulted packet receiving function. +5. Check if all of the packets we have catched can connected to the my_packet we send*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif +#include +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +static TX_THREAD ntest_1; +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_1; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG data_counter; +static ULONG mss_option_12_18; +static ULONG packet_length_12_18; + +static UCHAR callback_rcv_buffer[200]; +static UINT callback_rcv_length; +static UCHAR rcv_buffer[200]; +static UINT rcv_length; +static UCHAR data_12_18[200]; + +/* Define thread prototypes. */ + +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +static void rand_12_18(); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_18_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + data_counter = 0; + mss_option_12_18 = 0; + callback_rcv_length = 0; + rcv_length = 0; + packet_length_12_18 = 200; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 512*16); + pointer = pointer + 512*16; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /*Let the server socket to check the SYN segment*/ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_18; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*Check if the MSS option of server socket has calculated to the appropriate 88(client_socket's MSS) which the SYN packet from client socket carried*/ + if(server_socket.nx_tcp_socket_connect_mss != mss_option_12_18) + error_counter++; + + + advanced_packet_process_callback = my_packet_process_12_18; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Create a 200-byte length message randomly. */ + rand_12_18(); + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, data_12_18, packet_length_12_18, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /*Check if the content of the callback_rcv_buffer which appended by all the received packets' payload is the data_12_18 sent before*/ + if(!memcmp(callback_rcv_buffer, data_12_18, packet_length_12_18)) + data_counter++; + + advanced_packet_process_callback = NX_NULL; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +ULONG bytes_copied; + + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.18 Test......................................."); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while(!(nx_tcp_socket_receive(&client_socket, &my_packet, NX_IP_PERIODIC_RATE))) + { + /*Check if the packet is fragmented by TCP layer.*/ + if(my_packet -> nx_packet_length > mss_option_12_18) + error_counter++; + + /* Retrieve data from packet to the receive buffer. */ + status = nx_packet_data_retrieve(my_packet, &rcv_buffer[rcv_length], &bytes_copied); + if(status) + error_counter++; + + rcv_length += bytes_copied; + } + + /*Check if the content which connected by all the received packets is the data_12_18 sent from the client socket*/ + if(!memcmp(rcv_buffer, data_12_18, packet_length_12_18)) + data_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status += nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter !=0) || (syn_counter != 1) || (data_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void rand_12_18() +{ +UINT flag; +UINT j, k = 0; + + srand((unsigned)time(NULL)); + for(j = 0;j < 200;j++) + { + flag = rand() & 1; + if(flag) + data_12_18[k++] = 'A' + rand() % 26; + else + data_12_18[k++] = 'a' + rand() % 26; + } +} + +static UINT my_packet_process_12_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +#if defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#else +NX_IP_HEADER *ip_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#endif + + if((packet_ptr -> nx_packet_length) > 40) + { + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /*Check if the packet is fragmented by IP layer.*/ + if(!(ip_header_ptr -> nx_ip_header_word_1 & NX_IP_FRAGMENT_MASK)) + { + /*Check if the packet is fragmented by TCP layer*/ + if((packet_ptr -> nx_packet_length - 40) > mss_option_12_18) + error_counter++; + } + else + error_counter++; + + /* Append the intercepted packet's content to the receive buffer. */ + memcpy(&callback_rcv_buffer[callback_rcv_length], packet_ptr -> nx_packet_prepend_ptr + 40, packet_ptr -> nx_packet_length - 40); + callback_rcv_length = callback_rcv_length + packet_ptr -> nx_packet_length - 40; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + } + + return NX_TRUE; +} + + + +static void my_tcp_packet_receive_12_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *header_ptr; +ULONG option_words; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Server receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + /* It is a SYN packet. */ + syn_counter++; + + /*Get the option kind*/ + option_words = (header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + /*Get the MSS option form the SYN packet.*/ + _nx_tcp_mss_option_get((packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_HEADER)), option_words*sizeof(ULONG), &mss_option_12_18); + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_18_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.18 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_12_19_test.c b/test/regression/netxduo_test/netx_12_19_test.c new file mode 100644 index 00000000..817a3ec1 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_19_test.c @@ -0,0 +1,439 @@ +/* 12.19:TCP MUST assume a default send MSS of 536 if MSS option is not received at connection setup. */ + +/* Procedure + 1.Client_socket connect server_socket. + 2.When server_socket received SYN, then clean the MSS option, deal the packet with default receive function. + 3.Check the connect_mss of server_socket has been changed to be 536. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; + + +/* Define thread prototypes. */ + + +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *packet_ptr, int protocol, + UINT data_length, ULONG* src_ip_addr, + ULONG* dest_ip_addr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_19_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Point to my routing */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_19; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(syn_counter == 1) + { + /*Check if the connection has established*/ + if((client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) || (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + error_counter++; + } + else + error_counter++; + + if(server_socket.nx_tcp_socket_connect_mss != 536) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + + + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 12.19 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_12_19; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter != 0 ) || (syn_counter != 1 )) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + + + +static UINT my_packet_process_12_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG checksum; + +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* Modify the syn packet */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Clean the MSS option*/ + *option_word_1 = *option_word_1 & 0x00000000; + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + tcp_header_ptr -> nx_tcp_header_word_4 = tcp_header_ptr -> nx_tcp_header_word_4 & 0xFFFF0000; + + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket. nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + return NX_TRUE; + +} + + +static void my_tcp_packet_receive_12_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; +ULONG *option_word_1; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + option_word_1 = (ULONG *)(header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Server receives a syn packet */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Check whether the packet have the MSS option*/ + if(!(*option_word_1)) + syn_counter++; + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /* Point to default function */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Deal with default function */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_19_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.19 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_12_20_test.c b/test/regression/netxduo_test/netx_12_20_test.c new file mode 100644 index 00000000..d85adbf1 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_20_test.c @@ -0,0 +1,535 @@ +/* 12.20:TCP MUST ignore MSS option in data segment. */ + +/* Procedure + 1.Connect + 2.Allocate a data packet with MSS_OPTION but not SYN packet + 3.Client socket sends the packet to server socket + 4.Check whether server_socket's connect_mss changed or not */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif +#include + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG mss_option_12_20; +static ULONG data_packet_counter; +static UCHAR data_12_20[20]; + +/* Define thread prototypes. */ + + +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_12_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *packet_ptr, int protocol, + UINT data_length, ULONG* src_ip_addr, + ULONG* dest_ip_addr); +static void rand_12_20(); +extern UINT _nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size,NX_PACKET_POOL *pool_ptr, ULONG wait_option); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_20_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + mss_option_12_20 = 20; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 1", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 0", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + if(status) + error_counter++; + + status = nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + + + + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Let server checks the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_20; + + status = nx_tcp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((my_packet -> nx_packet_length == 20) && (!memcmp(my_packet -> nx_packet_prepend_ptr, data_12_20, 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /*Check if the mss of client socket has changed*/ + if(server_socket.nx_tcp_socket_connect_mss == mss_option_12_20) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + + + +static void ntest_1_entry(ULONG thread_input) +{ + UINT status; + + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 12.20 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_12_20; + _nx_tcp_packet_send_syn(&client_socket,client_socket.nx_tcp_socket_tx_sequence); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check for error. */ + if((error_counter != 0) || (data_packet_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + +static void rand_12_20() +{ + UINT flag; + UINT j,k=0; + + srand((unsigned)time(NULL)); + for(j=0;j<20;j++) + { + flag=rand()%2; + if(flag) data_12_20[k++]='A'+rand()%26; + else data_12_20[k++]='a'+rand()%26; + } +} + +static UINT my_packet_process_12_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; + + +ULONG val; +ULONG checksum; +ULONG checksum_ip; +ULONG temp; +#if defined(__PRODUCT_NETXDUO__) + NX_IPV4_HEADER *ip_header_ptr; +#else + NX_IP_HEADER *ip_header_ptr; +#endif + +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + +#if defined(__PRODUCT_NETXDUO__) + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#else + ip_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#endif + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Construct a data segment with mss option based on the SYN packet*/ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + /*Delete the SYN bit.*/ + tcp_header_ptr -> nx_tcp_header_word_3 = tcp_header_ptr -> nx_tcp_header_word_3 ^ NX_TCP_SYN_BIT; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Modify the MSS option value to 20*/ + *option_word_1 = *option_word_1 & 0xFFFF0000; + *option_word_1 = *option_word_1 | 0x00000014; + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + rand_12_20(); + nx_packet_data_append(packet_ptr, data_12_20, 20, &pool_0, NX_IP_PERIODIC_RATE); + + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + tcp_header_ptr -> nx_tcp_header_word_4 = tcp_header_ptr -> nx_tcp_header_word_4 & 0xFFFF0000; + + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket. nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + /*Modify the packet length in ip header.*/ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + ip_header_ptr -> nx_ip_header_word_0 = ip_header_ptr -> nx_ip_header_word_0 & 0xFFFF0000; + ip_header_ptr -> nx_ip_header_word_0 = ip_header_ptr -> nx_ip_header_word_0 | 0x00000044; + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 & 0x0000FFFF; + + + temp = ip_header_ptr -> nx_ip_header_word_0; + checksum_ip = (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_word_1; + checksum_ip += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_word_2; + checksum_ip += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_source_ip; + checksum_ip += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_destination_ip; + checksum_ip += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + + /* Fold a 4-byte value into a two byte value */ + checksum_ip = (checksum_ip >> 16) + (checksum_ip & 0xFFFF); + + /* Do it again in case previous operation generates an overflow */ + checksum_ip = (checksum_ip >> 16) + (checksum_ip & 0xFFFF); + + /* Convert to host byte order. */ + NX_CHANGE_USHORT_ENDIAN(checksum_ip); + + val = (ULONG)(~checksum_ip); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + + /* Modify the new sequence of client socket. */ + client_socket.nx_tcp_socket_tx_sequence += 20; + + advanced_packet_process_callback = NX_NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + + + +static void my_tcp_packet_receive_12_20 (NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG option_words; +ULONG mss; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + /*Check if both the sockets are in ESTABLISHED state*/ + if(server_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) + { + + /*Get the option kind*/ + option_words = (tcp_header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + /*Get the MSS option form the SYN packet.*/ + _nx_tcp_mss_option_get((packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_HEADER)), option_words*sizeof(ULONG), &mss); + + if(mss == mss_option_12_20) + data_packet_counter++; + + /* Point to default function */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + /* Deal with default function */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_20_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.20 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_12_21_test.c b/test/regression/netxduo_test/netx_12_21_test.c new file mode 100644 index 00000000..a6c0b444 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_21_test.c @@ -0,0 +1,443 @@ +/* 12.21:TCP MUST be able to receive MSS option in SYN,ACK segment and calculate the effective send segment size appropriately. */ + +/* Procedure + 1.Connect + 2.Client_socket's connect_MSS should equal server_socket's MSS.(client_socket's MSS = 1460, server_socket's MSS = 88) + 3. A packet should be intercepted by function my_tcp_packet_receive_12_21 which is sent from client socket to server socket. + 4. Check: the packet should be a SYN packet, increment the syn_counter. Whether or not calling the defaulted packet receiving function. + 5. Check if all of the packets we catched can connected to the my_packet we send*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif +#include +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the counters used in the demo application... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo applicaton... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; +static ULONG data_counter; +static ULONG mss_option_12_21; +static ULONG packet_length_12_21; + +static UCHAR callback_rcv_buffer[200]; +static UINT callback_rcv_length; +static UCHAR rcv_buffer[200]; +static UINT rcv_length; +static UCHAR data_12_21[200]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +static void rand_12_21(); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_21_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + data_counter = 0; + mss_option_12_21 = 0; + packet_length_12_21 = 200; + rcv_length = 0; + callback_rcv_length = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.21 Test......................................."); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_21; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*Check if the MSS option of server socket has calculated to the appropriate 88(server_socket's MSS) which the SYN,ACK packet from client socket carried*/ + if(client_socket.nx_tcp_socket_connect_mss != mss_option_12_21) + error_counter++; + + advanced_packet_process_callback = my_packet_process_12_21; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Create a 200-byte length message randomly. */ + rand_12_21(); + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, data_12_21, packet_length_12_21, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*Check if the content of the callback_rcv_buffer which appended by all the received packets' payload is the data_12_18 sent before*/ + if(!memcmp(callback_rcv_buffer, data_12_21, packet_length_12_21)) + data_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status += nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Check for error. */ + if((error_counter !=0) || (syn_ack_counter != 1) || (data_counter != 2)) + { + printf("ERROR\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; +ULONG bytes_copied; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while(!(nx_tcp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE))) + { + /*Check if the packet is fragmented by TCP layer.*/ + if(my_packet -> nx_packet_length > mss_option_12_21) + error_counter++; + + /* Retrieve data from packet to the receive buffer. */ + status = nx_packet_data_retrieve(my_packet, &rcv_buffer[rcv_length], &bytes_copied); + if(status) + error_counter++; + + rcv_length += bytes_copied; + } + + /*Check if the content which connected by all the received packets is the data_12_21 sent from the client socket*/ + if(!memcmp(rcv_buffer, data_12_21, packet_length_12_21)) + data_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void rand_12_21() +{ +UINT flag; +UINT j, k = 0; + + srand((unsigned)time(NULL)); + for(j = 0;j < 200;j++) + { + flag = rand() & 1; + if(flag) + data_12_21[k++] = 'A' + rand() % 26; + else + data_12_21[k++] = 'a' + rand() % 26; + } +} + + +static UINT my_packet_process_12_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +#if defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#else +NX_IP_HEADER *ip_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#endif + + if((packet_ptr -> nx_packet_length) > 40) + { + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /*Check if the packet is fragmented by IP layer.*/ + if(!(ip_header_ptr->nx_ip_header_word_1& NX_IP_FRAGMENT_MASK)) + { + /*Check if the packet is fragmented by TCP layer*/ + if((packet_ptr->nx_packet_length - 40) > mss_option_12_21) + error_counter++; + } + else + error_counter++; + + /* Append the intercepted packet's content to the receive buffer. */ + memcpy(&callback_rcv_buffer[callback_rcv_length], packet_ptr->nx_packet_prepend_ptr + 40, packet_ptr -> nx_packet_length - 40); + callback_rcv_length = callback_rcv_length + packet_ptr -> nx_packet_length - 40; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + } + + return NX_TRUE; +} + +static void my_tcp_packet_receive_12_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; +ULONG option_words; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN+ACK packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + /* It is a SYN+ACK packet. */ + syn_ack_counter++; + + /*Get the MSS option kind*/ + option_words = (header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + /*Get the MSS option form the SYN packet.*/ + _nx_tcp_mss_option_get((packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_HEADER)), option_words*sizeof(ULONG), &mss_option_12_21); + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_21_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.21 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_12_23_test.c b/test/regression/netxduo_test/netx_12_23_test.c new file mode 100644 index 00000000..9f548825 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_23_test.c @@ -0,0 +1,315 @@ +/* 12.23 TCP MUST implement sending the MSS option. */ + +/* RFC 1122, Section 4.2.2.6, page 85, Maximum Segment Size Option: RFC-793 Section 3.1. +TCP MUST implement both sending and receiving the Maximum Segment Size option. */ + +/* Procedure +1. Client send a SYN to Server. +2. Check whether the packet during establishing the connection have the MSS option +*/ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; + + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_23_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.23 Test......................................."); + + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_23; + + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter !=0 || syn_ack_counter != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_12_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG kind; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* This packet is from TCP ,this program is to check the MSS option. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + kind = (tcp_header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + if(kind == 2) + syn_ack_counter++; + + /* Point to default function */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Deal with default function */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_23_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.23 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_12_24_test.c b/test/regression/netxduo_test/netx_12_24_test.c new file mode 100644 index 00000000..2e0a93c9 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_24_test.c @@ -0,0 +1,375 @@ +/* 12.24 TCP SHOULD send MSS option in every SYN segment + when its receive MSS differs from the default 536. */ + +/* Procedure + 1. Client send a SYN to Server. + 2. Use advanced_packet_process function to receive and deal with the SYN packet, + then change the MSS. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG syn_ack_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_24(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_12_24_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_24_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + syn_ack_counter = 0; + + + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 1", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 0", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /*Let the server socket to check the SYN segment*/ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_24; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.24 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*Let the client socket to check the SYN+ACK segment*/ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_24_2; + + + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter !=0) || (syn_counter != 1) || (syn_ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + +static void my_tcp_packet_receive_12_24(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *header_ptr; +ULONG option_words; +ULONG mss_option; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + /* It is a SYN packet. */ + option_words = (header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + /*Get the MSS option form the SYN packet.*/ + _nx_tcp_mss_option_get((packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_HEADER)), option_words*sizeof(ULONG), &mss_option); + + if(mss_option != 536) + syn_counter++; + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +static void my_tcp_packet_receive_12_24_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *header_ptr; +ULONG option_words; + + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN,ACK packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + /* It is a SYN,ACK packet. */ + option_words = (header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + if(option_words == 2) + syn_ack_counter++; + + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_24_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.24 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_12_25_test.c b/test/regression/netxduo_test/netx_12_25_test.c new file mode 100644 index 00000000..12de964f --- /dev/null +++ b/test/regression/netxduo_test/netx_12_25_test.c @@ -0,0 +1,454 @@ +/* 12.25 TCP MAY send MSS option in every SYN segment + even when its receive MSS value is same as the default 536. */ + +/* Procedure + 1. Client send a SYN to Server. + 2. Use packet_process function to receive and deal with the SYN packet, + then change the MSS to 536. + 3. Use packet_process function to receive and deal with the SYN packet, + Judge the MSS options. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG syn_ack_counter; + + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_12_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_12_25_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_25_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + syn_ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 1", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 0", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /*Let the server socket to check the SYN segment*/ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_25; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.25 Test......................................."); + + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + + /* Deal the SYN packet with my routing */ + advanced_packet_process_callback = my_packet_process_12_25; + + /*Let the client socket to check the SYN+ACK segment*/ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_25_2; + + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter !=0) || (syn_counter != 1) || (syn_ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_12_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG checksum; + +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* This packet is the first incoming packet,this program is to send a SYN to Server. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /* Change the MSS. */ + *option_word_1 = *option_word_1 & 0xFFFF0000; + *option_word_1 = *option_word_1 | 536; + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + + tcp_header_ptr -> nx_tcp_header_word_4 = tcp_header_ptr -> nx_tcp_header_word_4 & 0xFFFF0000; + + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket. nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + return NX_TRUE; +} + +static void my_tcp_packet_receive_12_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *header_ptr; +ULONG option_words; +ULONG mss_option; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + /* It is a SYN packet. */ + option_words = (header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + /*Get the MSS option form the SYN packet.*/ + _nx_tcp_mss_option_get((packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_HEADER)), option_words*sizeof(ULONG), &mss_option); + + if(mss_option == 536) + syn_counter++; + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +static void my_tcp_packet_receive_12_25_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *header_ptr; +ULONG option_words; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + option_words = (header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + if(option_words == 2) + syn_ack_counter++; + + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_25_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.25 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_12_26_test.c b/test/regression/netxduo_test/netx_12_26_test.c new file mode 100644 index 00000000..67b2da51 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_26_test.c @@ -0,0 +1,472 @@ +/* 12.26 TCP over IPv6 MUST assume a default send MSS of 1220 if MSS + option is not received at connection setup When using TCP over IPv6, + the MSS must be computed as the maximum packet size minus 60 octets. */ + +/* Procedure + 1. Client send a SYN to Server. + 2. Use packet_process function to receive and deal with the SYN packet, + then change the MSS option. + 3. Use packet_process function to receive and deal with the SYN+ACK packet, + Check the MSS. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv6.h" +#else +#include "nx_ip.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; + +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_12_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_26_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "ntest 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + /* Create the main thread. */ + tx_thread_create(&ntest_1, "ntest 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_2,64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_26; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /*Check if the packet has been received successfully*/ + if(syn_counter == 1) + { + /*Check if the connection has crashed*/ + if((client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) || (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + error_counter++; + } + else + error_counter++; + + if(server_socket.nx_tcp_socket_connect_mss != 1220) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.26 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Determine if the timeout error occurred. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Deal the SYN packet with my routing */ + advanced_packet_process_callback = my_packet_process_12_26; + + /* Call connect to send a SYN */ + status = nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_2, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter != 0 ) || (syn_counter != 1 )) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + + + + +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_12_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG *source_ip; +ULONG *dest_ip; +ULONG checksum; +ULONG mss; +ULONG option_words; + + /*The length of ipv6 header is 40.*/ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 40); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Modify the syn packet */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /*Get the option kind*/ + option_words = (tcp_header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + /*Get the MSS option form the SYN packet.*/ + _nx_tcp_mss_option_get((packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_HEADER) + sizeof(NX_IPV6_HEADER)), option_words*sizeof(ULONG), &mss); + + /*The MSS must be com-puted as the maximum packet size minus 60 octets.*/ + if( mss != 1440) + error_counter++; + + /* Point to the TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 40); + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /* Change the MSS. */ + *option_word_1 = *option_word_1 & 0x00000000; + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + /* Modify the nx_packet_prepend_ptr. */ + packet_ptr -> nx_packet_prepend_ptr += 40; + + /* Get the TCP packet length. */ + packet_ptr -> nx_packet_length -= 40; + + dest_ip = client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v6; + source_ip = client_socket.nx_tcp_socket_ipv6_addr -> nxd_ipv6_address; + + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr->nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + + + + /* Return to the nx_packet_prepend_ptr. */ + packet_ptr -> nx_packet_prepend_ptr -= 40; + + /* Return to the IP packet length. */ + packet_ptr -> nx_packet_length += 40; + + advanced_packet_process_callback = NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + + + +static void my_tcp_packet_receive_12_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; +ULONG *option_word_1; + + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + option_word_1 = (ULONG *)(header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Server receive syn packet */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Check if the packet don't have the mss option*/ + if(!(*option_word_1)) + syn_counter++; + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /* Point to default function */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Deal with default function */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_26_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.26 Test.......................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_12_27_test.c b/test/regression/netxduo_test/netx_12_27_test.c new file mode 100644 index 00000000..0c807efb --- /dev/null +++ b/test/regression/netxduo_test/netx_12_27_test.c @@ -0,0 +1,491 @@ +/* 12.27 TCP MUST ignore MSS option in data segment When using TCP over IPv6, + the MSS must be computed as the maximum packet size minus 60 octets. */ + +/* Procedure + 1. Client connect with Server. + 2. Client sends a packet containing MSS options to Server. + 3. Judge the packet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_counter; +static UCHAR data_12_27[20]; +static ULONG mss_option_12_27; + +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_27(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_27(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_27_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_counter = 0; + mss_option_12_27 = 20; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 1", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 0", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + status = nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_1,64, NX_NULL); + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_2,64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_27; + status = nx_tcp_socket_receive(&server_socket,&my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((my_packet -> nx_packet_length == 20) && (!memcmp(my_packet -> nx_packet_prepend_ptr, data_12_27, 20))) + data_counter++; + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + + /* Check whether the server ignore the MSS options. */ + if(server_socket.nx_tcp_socket_connect_mss == mss_option_12_27) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + +} + + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.27 Test......................................."); + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send a SYN. */ + status = nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_2, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_12_27; + _nx_tcp_packet_send_syn(&client_socket,client_socket.nx_tcp_socket_tx_sequence ); + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check for error. */ + if((error_counter != 0) || (data_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + + +static void rand_12_27() +{ +UINT flag; +UINT j,k=0; + + srand((unsigned)time(NULL)); + for(j=0;j<20;j++) + { + flag=rand()%2; + if(flag) data_12_27[k++]='A'+rand()%26; + else data_12_27[k++]='a'+rand()%26; + } +} + +static UINT my_packet_process_12_27(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG checksum; +NX_IPV6_HEADER *ip_header_ptr; +ULONG *source_ip, *dest_ip; +ULONG mss; +ULONG option_words; + + /*Create a data seg with mss option*/ + + ip_header_ptr = (NX_IPV6_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 40); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Construct a data segment with mss option based on the SYN packet*/ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + /*Get the option kind*/ + option_words = (tcp_header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + /*Get the MSS option form the SYN packet.*/ + _nx_tcp_mss_option_get((packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_HEADER) + sizeof(NX_IPV6_HEADER)), option_words*sizeof(ULONG), &mss); + + /*The MSS must be com-puted as the maximum packet size minus 60 octets.*/ + if( mss != 1440) + error_counter++; + + /*Delete the SYN bit.*/ + tcp_header_ptr -> nx_tcp_header_word_3 = tcp_header_ptr -> nx_tcp_header_word_3 ^ NX_TCP_SYN_BIT; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Modify the MSS option value to 20*/ + *option_word_1 = *option_word_1 & 0xFFFF0000; + *option_word_1 = *option_word_1 | 0x00000014; + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + rand_12_27(); + nx_packet_data_append(packet_ptr, data_12_27, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /*Modify the payload length of the IPv6 header.*/ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr->nx_ip_header_word_1); + ip_header_ptr->nx_ip_header_word_1 = ip_header_ptr->nx_ip_header_word_1 & 0x0000FFFF; + ip_header_ptr->nx_ip_header_word_1 = ip_header_ptr->nx_ip_header_word_1 | 0x00300000; + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr->nx_ip_header_word_1); + + + + + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV6_HEADER); + + + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + + dest_ip = client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v6; + source_ip = client_socket.nx_tcp_socket_ipv6_addr -> nxd_ipv6_address; + + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr->nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV6_HEADER); + + /* Modify the new sequence of client socket. */ + client_socket.nx_tcp_socket_tx_sequence += 20; + + advanced_packet_process_callback = NX_NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + + return NX_TRUE; +} + + +static void my_tcp_packet_receive_12_27(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG option_words; +ULONG mss; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + /*Check if both the sockets are in ESTABLISHED state*/ + if(server_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) + { + /*Get the option kind*/ + option_words = (tcp_header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + /*Get the MSS option form the SYN packet.*/ + _nx_tcp_mss_option_get((packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_HEADER)), option_words*sizeof(ULONG), &mss); + + if(mss == mss_option_12_27) + data_counter++; + + /* Point to default function */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + /* Deal with default function */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_27_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.27 Test.......................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_12_30_test.c b/test/regression/netxduo_test/netx_12_30_test.c new file mode 100644 index 00000000..8262fcac --- /dev/null +++ b/test/regression/netxduo_test/netx_12_30_test.c @@ -0,0 +1,470 @@ +/* 12.30 TCP MAY send MSS option in every SYN segment even when its receive + MSS value is same as the default 1220 When using TCP over IPv6, the MSS + must be computed as the maximum packet size minus 60 octets. */ + +/* Update + nx_ram_network_driver_test.c and nx_ram_network_driver_test_1500.c */ + +/* Procedure + 1.Connect + 2.Validate the Client's connection_mss and the Server's connection_mss ?= 1500-60 */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) + +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG syn_ack_counter; + + + +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_30(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_12_30(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_12_30_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_30_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + syn_ack_counter = 0; + + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "ntest 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + /* Create the main thread. */ + tx_thread_create(&ntest_1, "ntest 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_2,64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_30; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.30 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + + /* Deal the SYN packet with my routing */ + advanced_packet_process_callback = my_packet_process_12_30; + + /*Let the client socket to check the SYN+ACK segment*/ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_30_2; + + /* Call connect to send a SYN */ + status = nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_2, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter != 0 ) || (syn_counter != 1) || (syn_ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process_12_30(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG checksum; +ULONG option_words; +ULONG *source_ip, *dest_ip; +ULONG mss; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 40); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + + /* This packet is the first incoming packet,this program is to send a SYN to Server. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /*Get the option kind*/ + option_words = (tcp_header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + /*Get the MSS option form the SYN packet.*/ + _nx_tcp_mss_option_get((packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_HEADER) + sizeof(NX_IPV6_HEADER)), option_words*sizeof(ULONG), &mss); + + /*The MSS must be com-puted as the maximum packet size minus 60 octets.*/ + if( mss != 1440) + error_counter++; + + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /* Change the MSS. */ + *option_word_1 = *option_word_1 & 0xFFFF0000; + *option_word_1 = *option_word_1 | 1220; + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + /* Modify the nx_packet_prepend_ptr. */ + packet_ptr -> nx_packet_prepend_ptr += 40; + + /* Get the TCP packet length. */ + packet_ptr -> nx_packet_length -= 40; + + dest_ip = client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v6; + source_ip = client_socket.nx_tcp_socket_ipv6_addr -> nxd_ipv6_address; + + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr->nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + + /* Return to the nx_packet_prepend_ptr. */ + packet_ptr -> nx_packet_prepend_ptr -= 40; + + /* Return to the IP packet length. */ + packet_ptr -> nx_packet_length += 40; + + advanced_packet_process_callback = NX_NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + + return NX_TRUE; +} + +static void my_tcp_packet_receive_12_30(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *header_ptr; +ULONG option_words; +ULONG mss_option; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + /* It is a SYN packet. */ + + option_words = (header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + /*Get the MSS option form the SYN packet.*/ + _nx_tcp_mss_option_get((packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_HEADER)), option_words*sizeof(ULONG), &mss_option); + + if(mss_option == 1220) + syn_counter++; + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + + + +static void my_tcp_packet_receive_12_30_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *header_ptr; +ULONG option_words; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + option_words = (header_ptr -> nx_tcp_header_word_3 >> 28) - 5; + + if(option_words == 2) + syn_ack_counter++; + + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_30_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.30 Test.......................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_12_31_test.c b/test/regression/netxduo_test/netx_12_31_test.c new file mode 100644 index 00000000..2df0daa7 --- /dev/null +++ b/test/regression/netxduo_test/netx_12_31_test.c @@ -0,0 +1,411 @@ +/* 12.31 TCP MUST be prepared to handle an illegal option length for MSS, in a SYN,ACK segment; a suggested procedure is to reset the connection. */ + +/* Procedure + 1.Intercept the ACK + SYN packet + 2.Modify the option_words to the 1220 + 3.Check whether the connection is reset */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_12_31(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_12_31_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *packet_ptr, int protocol, + UINT data_length, ULONG* src_ip_addr, + ULONG* dest_ip_addr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_12_31(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_31_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.31 Test......................................."); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 310, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_31; + + /*To handle the syn,ack packet.*/ + advanced_packet_process_callback = my_packet_process_12_31; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if ((error_counter != 0) || (syn_ack_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_12_31_2; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_12_31(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG checksum; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN+ACK packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Modify the MSS length to 0*/ + *option_word_1 = *option_word_1 & 0xFF00FFFF; + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /*Put the packet pointer to tcp*/ +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &server_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &server_socket. nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = server_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + + return NX_TRUE; +} + +static void my_tcp_packet_receive_12_31(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; +ULONG *option_word_1; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + option_word_1 = (ULONG *)(header_ptr + 1); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN+ACK packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + if((*option_word_1 & 0x00FF0000) == 0) + syn_ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass the packet to the default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +static void my_tcp_packet_receive_12_31_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + + /*Check if the connection has been reset.*/ + if(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + rst_counter++; + + /*If connection havn't been reset, give back, restore the TCP receive function.*/ + else if(header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass the packet to the default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_12_31_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 12.31 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_13_01_test.c b/test/regression/netxduo_test/netx_13_01_test.c new file mode 100644 index 00000000..f3c92847 --- /dev/null +++ b/test/regression/netxduo_test/netx_13_01_test.c @@ -0,0 +1,420 @@ +/* 13.01 A full-sized segment MUST be acknowledged within a time of 0.5 sec. */ + +/* RFC 1122, Section 4.2.3.2, page 96, When to Send an ACK Segment. + A TCP SHOULD implement a delayed ACK, but an ACK should not be excessively delayed; + in particular, the delay MUST be less than 0.5 seconds, and in a stream of full-sized + segments there SHOULD be an ACK for at least every second segment. */ + +/* Procedure + 1. Client connects to server. + 2. Client sends a full-sized packet to server. + 3. When server receives packet, activate timer. + 4. When server sends ACK packet, wake up server and client thread. + 5. When timer expired, check if segment has been acknowledged. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static TX_TIMER my_timer; +static UINT ack_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_13_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_13_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_timer_entry(ULONG); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_13_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + /* Check status. */ + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check status. */ + if(status) + error_counter++; + + /* Create an application timer. */ + status = tx_timer_create(&my_timer, "my time", + my_timer_entry, (ULONG) 0, + NX_IP_PERIODIC_RATE / 2, + NX_IP_PERIODIC_RATE / 2, + TX_NO_ACTIVATE); + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *rcv_packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 13.01 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_13_01; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_13_01; + + status = nx_tcp_socket_receive(&server_socket, &rcv_packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == ip_1.nx_ip_interface[0].nx_interface_ip_mtu_size - 40) && + (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, ip_1.nx_ip_interface[0].nx_interface_ip_mtu_size - 40))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete timer. */ + tx_timer_delete(&my_timer); +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a full-sized packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, ip_1.nx_ip_interface[0].nx_interface_ip_mtu_size - 40, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Wait until client receives ACK packet. */ + tx_thread_suspend(&ntest_1); + + /* Call disconnect to send a FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (ack_counter != 1) || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_timer_entry(ULONG l) +{ + /* Check if segment has been acknowledged. */ + if(ack_counter == 0) + error_counter++; + + /* Wake up the client thread. */ + tx_thread_resume(&ntest_1); +} + +static UINT my_packet_process_13_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check if it is an ACK packet. */ + if(!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + ack_counter++; + + /* ACK packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_13_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is a SEG. */ + if(packet_ptr -> nx_packet_length == (ip_1.nx_ip_interface[0].nx_interface_ip_mtu_size - 20) && + (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, ip_1.nx_ip_interface[0].nx_interface_ip_mtu_size - 40))) + { + /* Start timer. */ + tx_timer_activate(&my_timer); + + /* Restore function pointer. */ + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass current packet to default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_13_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 13.01 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_13_02_test.c b/test/regression/netxduo_test/netx_13_02_test.c new file mode 100644 index 00000000..b3d14178 --- /dev/null +++ b/test/regression/netxduo_test/netx_13_02_test.c @@ -0,0 +1,414 @@ +/* 13.02 TCP SHOULD implement a delayed ACK, but the delay MUST be less than 0.5 sec. */ + +/* Procedure + 1. Client connects to server. + 2. Client sends a packet to server. + 3. When server receives packet, activate timer. + 4. When server sends ACK packet, wake up server and client thread. + 5. When timer expired, check if segment has been acknowledged. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static TX_TIMER my_timer; +static UINT ack_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_13_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_13_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_timer_entry(ULONG); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_13_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + /* Check status. */ + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check status. */ + if(status) + error_counter++; + + /* Create an application timer. */ + status = tx_timer_create(&my_timer, "my timer", + my_timer_entry, (ULONG) 0, + NX_IP_PERIODIC_RATE / 2, + NX_IP_PERIODIC_RATE / 2, + TX_NO_ACTIVATE); + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *rcv_packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 13.02 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_13_02; + + advanced_packet_process_callback = my_packet_process_13_02; + + status = nx_tcp_socket_receive(&server_socket, &rcv_packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == 20) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 2); + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete timer. */ + tx_timer_delete(&my_timer); + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a full-sized packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Wait until client receives ACK packet. */ + tx_thread_suspend(&ntest_1); + + /* Call disconnect to send a FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (ack_counter != 1) || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_timer_entry(ULONG l) +{ + /* Check if segment has been acknowledged. */ + if(ack_counter == 0) + error_counter++; + + /* Wake up the client thread. */ + tx_thread_resume(&ntest_1); +} + +static UINT my_packet_process_13_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check if it is an ACK packet. */ + if(!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + ack_counter++; + + /* ACK packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_13_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is a SEG. */ + if((packet_ptr -> nx_packet_length - 20 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, 20))) + { + /* Restore function pointer. */ + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Start timer. */ + tx_timer_activate(&my_timer); + + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass current packet to default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_13_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 13.02 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_13_04_test.c b/test/regression/netxduo_test/netx_13_04_test.c new file mode 100644 index 00000000..e26b54ae --- /dev/null +++ b/test/regression/netxduo_test/netx_13_04_test.c @@ -0,0 +1,404 @@ +/* 13.04 TCP SHOULD be capable of queuing out-of-order segments. */ + +/* Procedure + 1. Client connects to server. + 2. Client sends a packet that is out of order. + 3. Client sends a packet that is in order. + 5. Server receives packets successfully. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static UCHAR data_13_04[50]; +static UCHAR rcv_buffer[50]; +static UINT rcv_length; +/* Define thread prototypes. */ + +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void rand_13_04(); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_13_04_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + rcv_length = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + if(status) + error_counter++; + + status = nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + + + + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Established the connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while(!(nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE))) + { + data_packet_counter++; + + /* Retrieve data from packet to the receive buffer. */ + status = nx_packet_data_retrieve(packet_ptr, &rcv_buffer[rcv_length], &bytes_copied); + if(status) + error_counter++; + + rcv_length += bytes_copied; + bytes_copied = 0; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if((data_packet_counter != 2) || (rcv_length != 40) || (memcmp(rcv_buffer, (void*)data_13_04, rcv_length))) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +UINT old_threshold; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 13.04 Test......................................."); + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a 40-byte length message randomly. */ + rand_13_04(); + + /* Modify tx_sequence. */ + client_socket.nx_tcp_socket_tx_sequence += 20; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, &data_13_04[20], 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Modify tx_sequence. */ + client_socket.nx_tcp_socket_tx_sequence -= 40; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, data_13_04, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disable preemption from IP thread. */ + tx_thread_preemption_change(&ntest_1, 0, &old_threshold); + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Modify tx_sequence. */ + client_socket.nx_tcp_socket_tx_sequence += 20; + + /* Enable preemption from IP thread. */ + tx_thread_preemption_change(&ntest_1, old_threshold, &old_threshold); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter != 0) || (data_packet_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void rand_13_04() +{ +UINT flag; +UINT j,k=0; + + srand((unsigned)time(NULL)); + for(j=0;j<40;j++) + { + flag=rand()%2; + if(flag) data_13_04[k++]='A'+rand()%26; + else data_13_04[k++]='a'+rand()%26; + } + +} + + + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_13_04_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 13.04 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_13_05_test.c b/test/regression/netxduo_test/netx_13_05_test.c new file mode 100644 index 00000000..e92224cc --- /dev/null +++ b/test/regression/netxduo_test/netx_13_05_test.c @@ -0,0 +1,439 @@ +/* 13.05 TCP MAY send an ACK segment acknowledging RCV.NXT for valid out-of-order data segments. */ + +/* Procedure + 1. Client connects to server. + 2. Client sends a packet out of order. + 3. Check if server replies an ACK segment acknowledging RCV.NXT. + 4. Client sends a packet in order. + 5. Check if server receives data successfully. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static UCHAR data_13_05[50]; +static UCHAR rcv_buffer[50]; +static UINT rcv_length; +static ULONG is_acked; +static ULONG expected_seq; +/* Define thread prototypes. */ + +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_13_05(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void rand_13_05(); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_13_05_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + rcv_length = 0; + is_acked = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + if(status) + error_counter++; + + status = nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + + + + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +ULONG bytes_copied; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Established the connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while(!(nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE))) + { + data_packet_counter++; + + /* Retrieve data from packet to the receive buffer. */ + status = nx_packet_data_retrieve(packet_ptr, &rcv_buffer[rcv_length], &bytes_copied); + if(status) + error_counter++; + + rcv_length += bytes_copied; + bytes_copied = 0; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if((data_packet_counter != 2) || (rcv_length != 40) || (memcmp(rcv_buffer, (void*)data_13_05, rcv_length))) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +UINT old_threshold; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 13.05 Test......................................."); + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_13_05; + + /* Record expected sequence of client. */ + expected_seq = client_socket.nx_tcp_socket_tx_sequence; + + /* Create a 40-byte length message randomly. */ + rand_13_05(); + + /* Modify tx_sequence. */ + client_socket.nx_tcp_socket_tx_sequence += 20; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, &data_13_05[20], 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Modify tx_sequence. */ + client_socket.nx_tcp_socket_tx_sequence -= 40; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, data_13_05, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disable preemption from IP thread. */ + tx_thread_preemption_change(&ntest_1, 0, &old_threshold); + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Modify tx_sequence. */ + client_socket.nx_tcp_socket_tx_sequence += 20; + + /* Enable preemption from IP thread. */ + tx_thread_preemption_change(&ntest_1, old_threshold, &old_threshold); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter != 0) || (data_packet_counter != 2) || (is_acked != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void rand_13_05() +{ +UINT flag; +UINT j,k=0; + + srand((unsigned)time(NULL)); + for(j=0;j<40;j++) + { + flag=rand()%2; + if(flag) data_13_05[k++]='A'+rand()%26; + else data_13_05[k++]='a'+rand()%26; + } + +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_13_05(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + if(!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + if(expected_seq == header_ptr -> nx_tcp_acknowledgment_number) + is_acked = NX_TRUE; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Deal with default function */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_13_05_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 13.05 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_13_17_test.c b/test/regression/netxduo_test/netx_13_17_test.c new file mode 100644 index 00000000..90102c31 --- /dev/null +++ b/test/regression/netxduo_test/netx_13_17_test.c @@ -0,0 +1,402 @@ +/* 13.17 In a stream of full-sized segments there SHOULD be an ACK for at least every second segment. */ + +/* Procedure + 1. Client connects to server. + 2. Server sends a stream of full-sized segments(4 segments) to Client. + 3. Check if client sends more than 2 ACK packet to Server. */ + +/* The check logic of ACK packets is incorrect. NetXDuo implements it by defining NX_TCP_ACK_EVERY_N_PACKETS to 2. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif +#include + +extern void test_control_return(UINT status); + +#if 0 +/*#ifndef NX_TCP_ACK_EVERY_N_PACKETS*/ + +#define DEMO_STACK_SIZE 2048 + + + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG ack_counter; +static INT is_acked_every_2seg; + +static UCHAR rcv_buffer[352]; +static UINT rcv_length; +static UCHAR data_13_17[352]; +static ULONG mss_option_13_17; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *client_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *client_socket); +static void rand_13_17(); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_13_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_13_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + rcv_length = 0; + is_acked_every_2seg = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 512*16); + pointer = pointer + 512*16; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +static void ntest_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet; + ULONG bytes_copied; + + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 13.17 Test......................................."); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while(!(nx_tcp_socket_receive(&client_socket, &my_packet, NX_IP_PERIODIC_RATE))) + { + + /* Retrieve data from packet to the receive buffer. */ + status = nx_packet_data_retrieve(my_packet, &rcv_buffer[rcv_length], &bytes_copied); + if(status) + error_counter++; + + rcv_length += bytes_copied; + } + + /*Check if the content which connected by all the received packets is the data_13_17 sent from the client socket*/ + if(memcmp(rcv_buffer, data_13_17, rcv_length)) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + status += nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter ==0) && (is_acked_every_2seg == NX_TRUE) && (ack_counter >= 2)) + { + printf("SUCCESS!\n"); + test_control_return(0); + + } + else + { + printf("ERROR!\n"); + test_control_return(1); + } + +} + + +/* Define the test threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*Let the server socket to check the ACK segment*/ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_13_17; + + mss_option_13_17 = server_socket.nx_tcp_socket_connect_mss; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, 80, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Create a 4*mss_option_13_17 length message randomly. */ + rand_13_17(); + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, data_13_17, 4*mss_option_13_17, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + + + +static void rand_13_17() +{ +UINT flag; +UINT j, k = 0; + + srand((unsigned)time(NULL)); + for(j = 0;j < 4*mss_option_13_17;j++) + { + flag = rand() & 1; + if(flag) + data_13_17[k++] = 'A' + rand() % 26; + else + data_13_17[k++] = 'a' + rand() % 26; + } +} + + + +static void my_tcp_packet_receive_13_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Server receives a ACK packet. */ + if(!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT)) + { + + ack_counter++; + + if(ack_counter >= (server_socket.nx_tcp_socket_packets_sent >> 1)) + is_acked_every_2seg = NX_TRUE; + } + else if(header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_13_17_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Spec 13.17 Test.......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_14_19_test.c b/test/regression/netxduo_test/netx_14_19_test.c new file mode 100644 index 00000000..31805f8f --- /dev/null +++ b/test/regression/netxduo_test/netx_14_19_test.c @@ -0,0 +1,345 @@ +/* 14.19 TCP MUST include an SWS avoidance algorithm in the receiver when effective send MSS < (1/ 2)*RCV_BUFF. */ + +/* Procedure + 1.Connection successfully + 2.First Client sends 40 data to Server, then check if the last_sent changed + 3.Then Client sends more 20 data to Server, also check if the last_sent changed + 4.If the last_sent changed, the SWS avoidance algorithm has not been used. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "----------abcdefgh20----------ABCDEFGH40----------klmnopqr60----------KLMNOPQR80--------------------" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static UINT is_included; +static ULONG mss_option; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_14_19_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + is_included = NX_FALSE; + mss_option = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *rcv_packet_ptr; +ULONG window_last_sent; +ULONG rcv_length; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 14.19 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + tx_thread_suspend(&ntest_0); + + window_last_sent = server_socket.nx_tcp_socket_rx_window_last_sent; + + status = nx_tcp_socket_receive(&server_socket, &rcv_packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == mss_option - 20) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, mss_option - 20))) + data_packet_counter++; + + rcv_length = rcv_packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + /* Check whether the premise 'effective send MSS < (1/ 2)*RCV_BUFF' is satisfied. */ + if((data_packet_counter == 1) && (rcv_length <= server_socket.nx_tcp_socket_connect_mss) && (server_socket.nx_tcp_socket_connect_mss < (0.5 * server_socket.nx_tcp_socket_rx_window_default))) + if(window_last_sent == server_socket.nx_tcp_socket_rx_window_last_sent) + is_included = NX_TRUE; + + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +char *msg = MSG; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + mss_option = client_socket.nx_tcp_socket_connect_mss; + + + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, msg, mss_option - 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the my_packet0 */ + status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 1) || (is_included != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_14_19_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 14.19 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_14_20_test.c b/test/regression/netxduo_test/netx_14_20_test.c new file mode 100644 index 00000000..94a03aa3 --- /dev/null +++ b/test/regression/netxduo_test/netx_14_20_test.c @@ -0,0 +1,343 @@ +/* 14.19 TCP MUST include an SWS avoidance algorithm in the receiver when effective send MSS < (1/ 2)*RCV_BUFF. */ + +/* Procedure + 1.Connection successfully + 2.First Client sends 40 data to Server, then check if the last_sent changed + 3.Then Client sends more 20 data to Server, also check if the last_sent changed + 4.If the last_sent changed, the SWS avoidance algorithm has not been used. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "----------abcdefgh20----------ABCDEFGH40----------klmnopqr60----------KLMNOPQR80--------------------" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static UINT is_included; +static ULONG mss_option; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_14_20_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + is_included = NX_FALSE; + mss_option = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *rcv_packet_ptr; +ULONG window_last_sent; +ULONG rcv_length; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 14.20 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_0); + + window_last_sent = server_socket.nx_tcp_socket_rx_window_last_sent; + + status = nx_tcp_socket_receive(&server_socket, &rcv_packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == mss_option) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, mss_option))) + data_packet_counter++; + + rcv_length = rcv_packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + if((data_packet_counter == 1) && (rcv_length <= server_socket.nx_tcp_socket_connect_mss) && (server_socket.nx_tcp_socket_connect_mss >= (0.5 * server_socket.nx_tcp_socket_rx_window_default))) + if(window_last_sent != server_socket.nx_tcp_socket_rx_window_last_sent) + is_included = NX_TRUE; + + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +char *msg = MSG; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + mss_option = client_socket.nx_tcp_socket_connect_mss; + + + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, msg, mss_option, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the my_packet0 */ + status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 1) || (is_included != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_14_20_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 14.20 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_15_03_test.c b/test/regression/netxduo_test/netx_15_03_test.c new file mode 100644 index 00000000..7e1d56eb --- /dev/null +++ b/test/regression/netxduo_test/netx_15_03_test.c @@ -0,0 +1,394 @@ +/* 15.03 If a retransmitted packet is identical to the original packet, then the same IP identification field MAY be used. */ + +/* Procedure +1. Set 'nx_ipv4_packet_receive' pointer of server ip instance to 'my_ipv4_packet_receive_15_03' to deal with ip packet. +2. Client sends data to server. +3. Server drop the data packet in 'my_ipv4_packet_receive_15_03'. +4. Client retransmits data to server. +5. Server compares the TCP data and in 'my_ipv4_packet_receive_15_03' IP identification field. */ + +/* Warning: NetX does not use the same IP identification. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if !defined(NX_ENABLE_INTERFACE_CAPABILITY) && !defined(NX_DISABLE_TCP_TX_CHECKSUM) && !defined(NX_DISABLE_TCP_RX_CHECKSUM) && !defined(NX_DISABLE_IPV4) +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG expected_id; +static ULONG drop_counter; +static ULONG is_identical_id; +static ULONG data_counter; +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_15_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_03_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + drop_counter = 0; + is_identical_id = NX_FALSE; + data_counter = 0; + expected_id = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + if(status) + error_counter++; + + status = nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 15.03 Test......................................."); + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_15_03; + + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_0); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Determine if the test was successful. */ + if((error_counter !=0) || (drop_counter != 1) || (data_counter == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(is_identical_id != NX_TRUE) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, the connection has established. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + if((packet_ptr -> nx_packet_length == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr, MSG, 20))) + data_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + + +static UINT my_packet_process_15_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +#if defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#else +NX_IP_HEADER *ip_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#endif + + /* Drop the packet. */ + if ((packet_ptr -> nx_packet_length - 40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 40, MSG, 20))) + { + if(drop_counter == 0) + { + /* Record the packet's IP identification. */ + expected_id = (ip_header_ptr -> nx_ip_header_word_1 & NX_LOWER_16_MASK); + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + drop_counter++; + } + else + { + if(expected_id == (ip_header_ptr -> nx_ip_header_word_1 & NX_LOWER_16_MASK)) + is_identical_id = NX_TRUE; + + advanced_packet_process_callback = NX_NULL; + + /* Wake up server and client threads. */ + tx_thread_resume(&ntest_0); + tx_thread_resume(&ntest_1); + + } + } + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_03_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Spec 15.03 Test.......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_15_20_test.c b/test/regression/netxduo_test/netx_15_20_test.c new file mode 100644 index 00000000..470602df --- /dev/null +++ b/test/regression/netxduo_test/netx_15_20_test.c @@ -0,0 +1,460 @@ +/* 15.20 If a retransmitted packet differs from the original packet in the window value,then the same IP identification field MUST NOT be used. */ + +/* Procedure + 1.Connection successfully + 2.Record the 1st coming IP_ID to ip_id_15_20 + 3.Drop this packet and wait for the retransmitted packet + 4.Modify retransmitted packet's WINDOW value + 5.Check the retransmitted packet's IP_ID ?= ip_id_15_20 */ + +/*The NetX doesn't judge the acknowledgement field of the retransmitted packet, it uses the different IP identification when send every packet.*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG retrans_packet_counter; +static UINT is_different; + +static ULONG ip_id_15_20; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_15_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_15_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_20_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + retrans_packet_counter = 0; + is_different = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet1; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 2 * NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(client_socket.nx_tcp_socket_transmit_sent_head, MSG + 20, 20, &pool_0, NX_IP_PERIODIC_RATE); + + client_socket.nx_tcp_socket_tx_sequence += 20; + + /* Increase the window size so the retransmitted packet is different from the original one. */ + client_socket.nx_tcp_socket_rx_window_current++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (retrans_packet_counter != 1) || (data_packet_counter != 1) || (is_different != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 15.20 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_15_20; + advanced_packet_process_callback = my_packet_process_15_20; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((my_packet -> nx_packet_length == 40) && (!memcmp(my_packet -> nx_packet_prepend_ptr, MSG, 40))) + retrans_packet_counter++; + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_15_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; + +#if defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header_ptr; +ULONG *source_ip, *dest_ip; +ip_header_ptr = (NX_IPV4_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); +#elif defined(__PRODUCT_NETX__) +NX_IP_HEADER *ip_header_ptr; +ULONG source_ip, dest_ip; +ip_header_ptr = (NX_IP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); +#else +#error "NetX Product undefined." +#endif + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + if ((packet_ptr -> nx_packet_length - 40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 40, MSG, 20))) + { + ip_id_15_20 = (ip_header_ptr -> nx_ip_header_word_1 & NX_LOWER_16_MASK); + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + data_packet_counter++; + } + + else if ((packet_ptr -> nx_packet_length - 40 == 40) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 40, MSG, 40))) + { +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_0.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_15_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +#if defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header_ptr; +ip_header_ptr = (NX_IPV4_HEADER *)(packet_ptr -> nx_packet_prepend_ptr - 20); +#else +NX_IP_HEADER *ip_header_ptr; +ip_header_ptr = (NX_IP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr - 20); +#endif + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + if ((packet_ptr -> nx_packet_length - 20 == 40) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, 40))) + { + if(ip_id_15_20 != (ip_header_ptr -> nx_ip_header_word_1 & NX_LOWER_16_MASK)) + is_different = NX_TRUE; + + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_20_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 15.20 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_15_21_test.c b/test/regression/netxduo_test/netx_15_21_test.c new file mode 100644 index 00000000..0a55893d --- /dev/null +++ b/test/regression/netxduo_test/netx_15_21_test.c @@ -0,0 +1,469 @@ +/* 15.21 If a retransmitted packet differs from the original packet in the acknowledgement field, the same IP identification field MUST NOT be used. */ + +/* Procedure + 1.Connection successfully + 2.Record the 1st coming IP_ID to ip_id_15_21 + 3.Drop this packet and wait for the retransmitted packet + 4.Modify retransmitted packet's Acknowledgement field + 5.Check the retransmitted packet's IP_ID ?= ip_id_15_21 */ + +/*The NetX doesn't judge the acknowledgement field of the retransmitted packet, it uses the different IP identification when send every packet.*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#else +#include "nx_ip.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +#define MSG "----------abcdefgh20----------ABCDEFGH40----------klmnopqr60----------KLMNOPQR80----------" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG drop_counter; +static ULONG ip_id_15_21; +static UINT is_different; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *, int, UINT, ULONG *, ULONG *); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_15_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_21_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + drop_counter = 0; + is_different = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; +NX_TCP_HEADER *retransmit_header; + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 15.21 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_15_21; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&server_socket , my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(server_socket.nx_tcp_socket_transmit_sent_head) + { + retransmit_header = (NX_TCP_HEADER *)(server_socket.nx_tcp_socket_transmit_sent_head -> nx_packet_prepend_ptr); + + NX_CHANGE_ULONG_ENDIAN(retransmit_header -> nx_tcp_acknowledgment_number); + + /* Modify the packet's acknowledgement field*/ + retransmit_header -> nx_tcp_acknowledgment_number --; + + NX_CHANGE_ULONG_ENDIAN(retransmit_header -> nx_tcp_acknowledgment_number); + + } + else + { + error_counter++; + } + + tx_thread_suspend(&ntest_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *rcv_packet_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + status = nx_tcp_socket_receive(&client_socket, &rcv_packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == 20) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (drop_counter != 1) || (data_packet_counter != 1) || (is_different != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_15_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum = 0; +#if defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header_ptr; +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +NX_IP_HEADER *ip_header_ptr; +#else +#error "NetX Product undefined." +#endif + + if (packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + +#if defined(__PRODUCT_NETXDUO__) + ip_header_ptr = (NX_IPV4_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); +#elif defined(__PRODUCT_NETX__) + ip_header_ptr = (NX_IP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); +#endif + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr+20); + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + if ((packet_ptr -> nx_packet_length - 40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 40, MSG, 20))) + { + if (drop_counter == 0) + { + ip_id_15_21 = (ip_header_ptr -> nx_ip_header_word_1 & (~NX_LOWER_16_MASK)); + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + drop_counter ++; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + return NX_TRUE; + + } + else + { + if(ip_id_15_21 != (ip_header_ptr -> nx_ip_header_word_1 & (~NX_LOWER_16_MASK))) + is_different = NX_TRUE; + + advanced_packet_process_callback = NX_NULL; + tx_thread_resume(&ntest_0); + tx_thread_resume(&ntest_1); + + } + + } + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + + checksum = ~checksum & NX_LOWER_16_MASK; + +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_21_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 15.21 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_15_24_test.c b/test/regression/netxduo_test/netx_15_24_test.c new file mode 100644 index 00000000..b6b79508 --- /dev/null +++ b/test/regression/netxduo_test/netx_15_24_test.c @@ -0,0 +1,375 @@ +/* 15.24 TCP MUST include 'exponential backoff' (check that it increases) for successive RTO values for sending data segments. */ + +/* Procedure + 1. Client sends data to server. + 2. When server receives packet for the first three times, check RTO and drop the packet. + 3. Check if server receives data successfully. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG drop_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_15_24(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_24_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + drop_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 15.24 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, the connection has established. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Init transmit configure. */ + status = nx_tcp_socket_transmit_configure(&server_socket, server_socket.nx_tcp_socket_transmit_queue_maximum, + server_socket.nx_tcp_socket_timeout_rate, server_socket.nx_tcp_socket_timeout_max_retries, 1); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_15_24; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&server_socket , my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Wait for the retransmit. */ + tx_thread_suspend(&ntest_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *rcv_packet_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Wait until retransmit. */ + tx_thread_suspend(&ntest_1); + + status = nx_tcp_socket_receive(&client_socket, &rcv_packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == 20) && + (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (drop_counter != 2) || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_15_24(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + /* Drop packet three times. */ + if ((packet_ptr -> nx_packet_length - 40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 40, MSG, 20))) + { + + if(drop_counter < 2) + { + + /* Check if successive RTO increases as 'exponential backoff'. */ + if(server_socket.nx_tcp_socket_timeout != (server_socket.nx_tcp_socket_timeout_rate << (drop_counter * server_socket.nx_tcp_socket_timeout_shift))) + { + error_counter++; + } + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + drop_counter++; + } + else + { + advanced_packet_process_callback = NX_NULL; + + /* Wake up server and client thread. */ + tx_thread_resume(&ntest_0); + tx_thread_resume(&ntest_1); + } + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_24_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 15.24 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_15_25_test.c b/test/regression/netxduo_test/netx_15_25_test.c new file mode 100644 index 00000000..b2ffed65 --- /dev/null +++ b/test/regression/netxduo_test/netx_15_25_test.c @@ -0,0 +1,344 @@ +/* 15.25 TCP MUST include exponential backoff(check that it increases) for successive RTO values for sending SYN segments. */ + +/* Procedure + 1. Client sends SYN to server. + 2. When server receives SYN packet for the first three times, check RTO and drop the packet. + 3. Check if client connects to server successfully. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG drop_counter; +static ULONG syn_counter; + +/* Define thread prototypes. */ + +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_15_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_25_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + drop_counter = 0; + syn_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Init transmit configure. */ + status = nx_tcp_socket_transmit_configure(&client_socket, client_socket.nx_tcp_socket_transmit_queue_maximum, + client_socket.nx_tcp_socket_timeout_rate, client_socket.nx_tcp_socket_timeout_max_retries, 1); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_15_25; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 100 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (drop_counter != 1) || (syn_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 15.25 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, the connection has established. */ + status = nx_tcp_server_socket_accept(&server_socket, 100 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_15_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* Drop packet three times. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + syn_counter++; + + if(drop_counter == 0) + { + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + drop_counter++; + } + else + { + /* Check if successive RTO increases as 'exponential backoff'. */ + if(client_socket.nx_tcp_socket_timeout != (client_socket.nx_tcp_socket_timeout_rate << (drop_counter * client_socket.nx_tcp_socket_timeout_shift))) + { + error_counter++; + } + + advanced_packet_process_callback = NX_NULL; + + /* Wake up server and client thread. */ + tx_thread_resume(&ntest_0); + tx_thread_resume(&ntest_1); + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + } + } + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_25_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 15.25 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_15_26_test.c b/test/regression/netxduo_test/netx_15_26_test.c new file mode 100644 index 00000000..ab70efd1 --- /dev/null +++ b/test/regression/netxduo_test/netx_15_26_test.c @@ -0,0 +1,321 @@ +/* 15.26 TCP SHOULD use RTO = 3 sec initially. */ + +/* Procedure + 1. Client sends SYN packet to server. + 2. When the packet passed to driver, check RTO of client. */ + +/* Warning: TCP SHOULD use RTO = 1 sec initially. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_system.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UINT need_warning; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_15_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_26_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + need_warning = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Capture the packet send to server. */ + advanced_packet_process_callback = my_packet_process_15_26; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(need_warning == NX_TRUE) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 15.26 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_15_26(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG three_second; + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + three_second = NX_IP_PERIODIC_RATE; + three_second += (NX_IP_PERIODIC_RATE << 1); + + /* Check if RTO = 3 sec. */ + if(client_socket.nx_tcp_socket_timeout != three_second) + need_warning = NX_TRUE; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + advanced_packet_process_callback = NULL; + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_15_26_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 15.26 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_16_02_test.c b/test/regression/netxduo_test/netx_16_02_test.c new file mode 100644 index 00000000..c96f85ce --- /dev/null +++ b/test/regression/netxduo_test/netx_16_02_test.c @@ -0,0 +1,370 @@ +/* 16.02 Even if the receive window is closed indefinitely, the sending TCP MUST allow the connection to stay open as long as probes are acknowledged. */ + +/* Update + 1. nx_tcp_fast_periodic_processing.c between line 199 and line 271. + 2. nx_tcp_socket_state_ack_check.c between line 436 and 441, line 536. */ + +/* Procedure + 1. Set 'nx_ip_tcp_packet_receive' pointer of client ip instance to 'my_tcp_packet_receive_16_02' to deal with ACK packet. + 2. Client sends data to server whose length equals window size of server . + 3. Server sends back ACK with window size 0. + 4. Client sends probe to server. + 5. Server sends back ACK with window size 0. + 6. Server receives data and window size is back to original. + 7. Check if connection is still open. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG server_window; +static ULONG ack_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_16_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_16_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup function pointer to deal with ACK packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_16_02; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, server_window, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check if connection is still open. */ + if((ack_counter != 1) || (client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + error_counter++; + + tx_thread_resume(&ntest_1); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (ack_counter != 1) || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *rcv_packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 16.02 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 20, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + server_window = server_socket.nx_tcp_socket_rx_window_current; + + tx_thread_suspend(&ntest_1); + + status = nx_tcp_socket_receive(&server_socket, &rcv_packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == server_window) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, server_window))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_16_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + /* Check the window size. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_LOWER_16_MASK) == 0) + ack_counter++; + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Pass current packet to default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_16_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 16.02 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_16_17_test.c b/test/regression/netxduo_test/netx_16_17_test.c new file mode 100644 index 00000000..48a1ea36 --- /dev/null +++ b/test/regression/netxduo_test/netx_16_17_test.c @@ -0,0 +1,315 @@ +/* 16.17 A TCP MAY keep its offered receive window closed indefinitely. */ + +/* Procedure + 1. Client connect to Server. + 2. Client send a packet to Server,the size of packet is same as Server's receive window size. + 3. Check the Server's receive window size. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG server_window; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_16_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 16.17 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + server_window = server_socket.nx_tcp_socket_rx_window_current; + + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_rx_window_current != 0) + error_counter++; + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send a SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, server_window, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_16_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 16.17 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_16_19_test.c b/test/regression/netxduo_test/netx_16_19_test.c new file mode 100644 index 00000000..04e6bf8a --- /dev/null +++ b/test/regression/netxduo_test/netx_16_19_test.c @@ -0,0 +1,360 @@ +/* 16.19 A sending TCP MUST be robust against window shrinking, which may cause the "usable window" to become negative. */ + +/* Procedure + 1.Connection successfully. + 2.Modify the rx window size of the server socket to 20. + 3.Client sends 40 data to Server. + 4.Check whether Server socket receive the packet and whether the server socket's state change. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG queue_count; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_16_19_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +UINT data_counter; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 16.19 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + server_socket.nx_tcp_socket_rx_window_current = 20; + + queue_count = server_socket.nx_tcp_socket_receive_queue_count; + + + tx_thread_suspend(&ntest_0); + + /* Check whether the packet is queued. */ + if(server_socket.nx_tcp_socket_receive_queue_count != (queue_count + 1)) + error_counter++; + + /* Check Client socket's state. */ + if(server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + /* Receive the first part data that in window, then upate the window. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter ++; + } + else + { + data_counter = packet_ptr -> nx_packet_length; + nx_packet_release(packet_ptr); + } + + /* Receive the second part data that out of window, the data out of window should be retransmitted. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + data_counter += packet_ptr -> nx_packet_length; + nx_packet_release(packet_ptr); + } + + /* Check the data counter. */ + if (data_counter != 40) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 3 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 40, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Let ntest_0 receive the data. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 3 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_16_19_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 16.19 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_16_21_test.c b/test/regression/netxduo_test/netx_16_21_test.c new file mode 100644 index 00000000..483a07b5 --- /dev/null +++ b/test/regression/netxduo_test/netx_16_21_test.c @@ -0,0 +1,385 @@ +/* 16.21 TCP SHOULD send the first zero window probe when the receiver window size remains zero for the retransmission timeout period. */ + +/* Procedure + 1. Set 'nx_ip_tcp_packet_receive' pointer of client ip instance to 'my_tcp_packet_receive_16_21' to deal with ACK packet. + 2. Client sends data whose length equals window size of server to server. + 3. Server sends back ACK with window size 0. + 4. Client sends probe to server. + 5. Server sends back ACK with window size 0. + 6. Server receives data and window size is back to original. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if !defined(__PRODUCT_NETXDUO__) || defined(NX_DISABLE_IPV4) +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_16_21_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Spec 16.21 Test.......................................N/A\n"); + test_control_return(3); +} +#else + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG server_window; +static ULONG ack_counter; +static ULONG data_packet_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_16_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_16_21_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup function pointer to deal with ACK packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_16_21; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, server_window, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a packet to send one byte. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 1, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_NO_WAIT); + + /* Send should fail since window is zero. */ + if(!status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check if connection is still open. */ + if(ack_counter != 1) + error_counter++; + + + tx_thread_resume(&ntest_1); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (ack_counter != 1) || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *rcv_packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 16.21 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 20, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + server_window = server_socket.nx_tcp_socket_rx_window_current; + + tx_thread_suspend(&ntest_1); + + status = nx_tcp_socket_receive(&server_socket, &rcv_packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == server_window) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, server_window))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_16_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + /* Check the window size. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_LOWER_16_MASK) == 0) + ack_counter++; + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Pass current packet to default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#endif diff --git a/test/regression/netxduo_test/netx_16_22_test.c b/test/regression/netxduo_test/netx_16_22_test.c new file mode 100644 index 00000000..8c134fdb --- /dev/null +++ b/test/regression/netxduo_test/netx_16_22_test.c @@ -0,0 +1,391 @@ +/* 16.22 TCP SHOULD increase exponentially the interval between successive zero window probes. */ + +/* Procedure + 1. Set 'nx_ip_tcp_packet_receive' pointer of client ip instance to 'my_tcp_packet_receive_16_21' to deal with ACK packet. + 2. Client sends data whose length equals window size of server to server. + 3. Server sends back ACK with window size 0. + 4. Client sends probe to server. + 5. Server sends back ACK with window size 0. + 6. Server receives data and window size is back to original. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#define DEMO_STACK_SIZE 2048 + +extern void test_control_return(UINT status); + +#if !defined(__PRODUCT_NETXDUO__) || defined(NX_DISABLE_IPV4) +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_16_22_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Spec 16.22 Test.......................................N/A\n"); + test_control_return(3); +} +#else + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG server_window; +static ULONG ack_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_16_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_16_22_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 16.22 Test......................................."); + + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Modify the timeout_shift transmit parameter of the client aocket. */ + status = nx_tcp_socket_transmit_configure(&client_socket, client_socket.nx_tcp_socket_transmit_queue_maximum, + client_socket.nx_tcp_socket_timeout_rate, client_socket.nx_tcp_socket_timeout_max_retries, 1); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Setup function pointer to deal with ACK packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_16_22; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, server_window, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a packet to send one byte. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 1, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_NO_WAIT); + + /* Send should fail since window is zero. */ + if(!status) + error_counter++; + + /* Sleep 3 seconds ticks to wait for the successive zero window probes.*/ + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + tx_thread_resume(&ntest_1); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (ack_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 20, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + server_window = server_socket.nx_tcp_socket_rx_window_current; + + /* Wait until both ACK received. */ + tx_thread_suspend(&ntest_1); + + /* Receive a TCP message from the socket. */ + if(server_socket.nx_tcp_socket_receive_queue_head) + { + status = nx_tcp_socket_receive(&server_socket,&packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, (void*)MSG, packet_ptr -> nx_packet_length) || (packet_ptr -> nx_packet_length != 20)) + error_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_16_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check if it is an ACK packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_LOWER_16_MASK)) + { + if(ack_counter == 0) + ack_counter++; + else + { + /* Check if TCP increase exponentially the interval between successive zero window probes. */ + if(client_socket.nx_tcp_socket_timeout == + client_socket.nx_tcp_socket_timeout_rate << (ack_counter * client_socket.nx_tcp_socket_timeout_shift)) + ack_counter++; + + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass current packet to default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#endif diff --git a/test/regression/netxduo_test/netx_17_17_test.c b/test/regression/netxduo_test/netx_17_17_test.c new file mode 100644 index 00000000..263fe7ca --- /dev/null +++ b/test/regression/netxduo_test/netx_17_17_test.c @@ -0,0 +1,378 @@ +/* 17.17 The TTL value used to send TCP segments MUST be configurable. */ + +/* Procedure + 1. Client connects to server. + 2. Modify TTL of client. + 3. Client sends a new packet to server using modified TTL. + 4. Server receives packets successfully. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG client_TTL; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT my_packet_process_17_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_17_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + client_TTL = 10; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 17.17 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_17_17; + + /* Modify the client socket's TTL. */ + client_socket.nx_tcp_socket_time_to_live = client_TTL; + + /* Create a packet to send. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Send packet to server. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check status... */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check status... */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + else + { + if((packet_ptr -> nx_packet_length == 0) || (memcmp(packet_ptr -> nx_packet_prepend_ptr, (void*)MSG, packet_ptr -> nx_packet_length))) + error_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_17_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + +#if defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header_ptr; +#elif defined(__PRODUCT_NETX__) +NX_IP_HEADER *ip_header_ptr; +#endif + +ULONG TTL; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + +#if defined(__PRODUCT_NETXDUO__) + ip_header_ptr = (NX_IPV4_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); +#elif defined(__PRODUCT_NETX__) + ip_header_ptr = (NX_IP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); +#endif + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (packet_ptr -> nx_packet_length - 40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 40, MSG, 20))) + { + /* Check the TTL value of the packet. */ + TTL = ip_header_ptr -> nx_ip_header_word_2; + TTL = TTL >> 24; + if(TTL == client_TTL) + { + data_packet_counter++; + advanced_packet_process_callback = NULL; + } + + } + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_17_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 17.17 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_18_21_test.c b/test/regression/netxduo_test/netx_18_21_test.c new file mode 100644 index 00000000..0c91493a --- /dev/null +++ b/test/regression/netxduo_test/netx_18_21_test.c @@ -0,0 +1,371 @@ +/* 18.21 TCP MAY aggregate data requested by an application for + sending until accumulated data exceeds effective send MSS. */ + +/* Procedure + 1. Client connect with Server. + 2. Client send packet to Server. + 3. Server receives the packet. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG is_aggregated; +static ULONG mss_option_18_21; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_18_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_18_21_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + is_aggregated = NX_FALSE; + mss_option_18_21 = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 18.21 Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send a SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Get the MSS value of the connected socket. */ + mss_option_18_21 = client_socket.nx_tcp_socket_connect_mss; + + /* Create one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet1, MSG, 40, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Send the first packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet2, MSG, mss_option_18_21 - 40, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Send the first packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check status... */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check status... */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter == 0) && (is_aggregated == NX_TRUE)) + { + printf("SUCCESS!\n"); + test_control_return(0); + } + else if((error_counter == 0) && (is_aggregated == NX_FALSE) && (data_packet_counter == 2)) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("ERROR!\n"); + test_control_return(1); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_18_21; + + while(!(status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE))) + { + + if(((packet_ptr -> nx_packet_length == 40) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr, (void*)MSG, 40))) || + ((packet_ptr -> nx_packet_length == mss_option_18_21 - 40) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr, (void*)MSG, mss_option_18_21 - 40)))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_18_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If the packets are aggregated. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_PSH_BIT) && (packet_ptr -> nx_packet_length - 20 == mss_option_18_21) && + (!memcmp((packet_ptr -> nx_packet_prepend_ptr + 20), (void*)MSG, 40)) && (!memcmp((packet_ptr -> nx_packet_prepend_ptr + 60), (void*)MSG, (mss_option_18_21 - 40)))) + is_aggregated = NX_TRUE; + + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_18_21_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 18.21 Test.......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_01_test.c b/test/regression/netxduo_test/netx_1_01_test.c new file mode 100644 index 00000000..e7ee4e85 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_01_test.c @@ -0,0 +1,347 @@ +/* 1.01 TCP MUST send a SYN,ACK in response to a SYN in LISTEN state. */ + +/* Procedure + 1. Check the state of server is LISTEN. + 2. Client sends a SYN packet. + 3. Check the packet is a SYN one. + 4. Server replies a packet. + 5. Check the packet is a SYN + ACK one. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG syn_ack_counter; +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_1_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_01_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + syn_counter = 0; + syn_ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + UINT status; + ULONG actual_status; + + printf("NetX Test: TCP Spec 1.01 Test........................................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check the state of server is LISTEN. */ + if (server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* Let client checks the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_01; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + /* Check for error. */ + if (status) + error_counter++; + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ + UINT status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client checks the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_01_2; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter||syn_counter!=1||syn_ack_counter!=1) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void my_tcp_packet_receive_1_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a SYN one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT ) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + syn_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + /* If receives other packet, it is error. */ + else + error_counter++; + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +void my_tcp_packet_receive_1_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check whether the packet is a SYN+ACK packet which responsing the SYN one. */ + if(syn_counter == 1) + { + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + syn_ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + } + /* If receives other packet, it is error. */ + else + error_counter++; + + /* Let client receives the SYN + ACK packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.01 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_02_test.c b/test/regression/netxduo_test/netx_1_02_test.c new file mode 100644 index 00000000..16729120 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_02_test.c @@ -0,0 +1,325 @@ +/* 1.02 TCP MUST move on to ESTABLISHED state after receiving ACK in SYN-RCVD state. */ + +/* Procedure + 1. Client sends a SYN packet. + 2. Server receives the SYN packet and replies a SYN + ACK packet. + 3. Client receives the SYN + ACK packet and replies an ACK packet. + 4. Check the state of server is SYN_RCVD. + 5. Check the packet is a ACK one. + 6. Let server deal with the ACK packet and checks the state of server is ESTABLISHED. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ack_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 128, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + printf("NetX Test: TCP Spec 1.02 Test........................................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let server checks the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_02; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check whether received an ACK packet. */ + if(ack_counter != 1) + error_counter++; + + /* Check the state of server is ESTABLISHED. */ + if (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +void my_tcp_packet_receive_1_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check whether the state of server is SYN_RCVD. */ + if (server_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a ACK one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + ack_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.02 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_03_test.c b/test/regression/netxduo_test/netx_1_03_test.c new file mode 100644 index 00000000..a30274ca --- /dev/null +++ b/test/regression/netxduo_test/netx_1_03_test.c @@ -0,0 +1,346 @@ +/* 1.03 TCP MUST send an ACK in response to a FIN received in ESTABLISHED state. */ + +/* Procedure + 1. Check the state of client is ESTABLISHED. + 2. Server sends a FIN packet. + 3. Check the packet is a FIN one. + 4. Client replies a packet. + 5. Check the packet is an ACK one. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG ack_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_1_03_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_03_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + error_counter = 0; + fin_counter = 0; + ack_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client check the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_03; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 1) || (ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 1.03 Test........................................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let server checks the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_03_2; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +void my_tcp_packet_receive_1_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check the state of client is ESTABLISHED. */ + if (client_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + fin_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let client receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +void my_tcp_packet_receive_1_03_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check whether the packet is a ACK packet which responsing the FIN one. */ + if(fin_counter == 1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + ack_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_03_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.03 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_04_ipv6_test.c b/test/regression/netxduo_test/netx_1_04_ipv6_test.c new file mode 100644 index 00000000..83597dd3 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_04_ipv6_test.c @@ -0,0 +1,327 @@ +/* 1.04 TCP, in CLOSED state, must send a RST segment with zero SEQ number +in response to an incoming segment not containing RST and ACK flags. */ + +/* This case is based on IPv6. */ + +/* Procedure +1. Create server and client sockets. +2. Let the client socket connect to the server socket in order to send a segment not containing RST and ACK flags. +3. Check if the server socket is in CLOSED state. +4. Check if the packet is a segment not containing RST and ACK flags. +5. Let the server socket receive the segment and send a RST segment. +6. Check if the packet is the RST segment with zero SEQ number. +7. Let the client socket receive the RST segment. +8. Check the error_counter and rst_counter. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#ifdef FEATURE_NX_IPV6 +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; +static UINT seg_counter; + +static NXD_ADDRESS ipv6_address_0; +static NXD_ADDRESS ipv6_address_1; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_1_04_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_04_ipv6_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + seg_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + if(status) + error_counter++; + + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + if(status) + error_counter++; + + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_1, 64, NX_NULL); + + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.04 IPv6 Test..................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client checks the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_04; + + tx_thread_suspend(&ntest_0); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* DAD */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client checks the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_04_2; + + /* Call connect to establish a TCP connection*/ + status = nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_0, 12, NX_IP_PERIODIC_RATE/2); + + tx_thread_resume(&ntest_0); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (seg_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_1_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *tcp_header_ptr; + + if(server_socket.nx_tcp_socket_state == NX_TCP_CLOSED) + { + + /* Point to the TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Determined if it set the ACK BIT and RST BIT. */ + if((!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) && (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT))) + { + /* The incoming segment is not containing RST and ACK flags. */ + seg_counter = 1; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_1_04_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if (seg_counter == 1) + { + /* Point to the TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Determined the RST BIT,ACK BIT,SEQ. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (tcp_header_ptr -> nx_tcp_sequence_number == 0)) + { + + /* ACK_BIT and RST_BIT has been set and SEQ is zero. */ + rst_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + else + error_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let client receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_04_ipv6_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Spec 1.04 IPv6 Test...................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_1_04_test.c b/test/regression/netxduo_test/netx_1_04_test.c new file mode 100644 index 00000000..4c8051c9 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_04_test.c @@ -0,0 +1,309 @@ +/* 1.04 TCP, in CLOSED state, must send a RST segment with zero SEQ number +in response to an incoming segment not containing RST and ACK flags. */ + +/* Procedure +1. Create server and client sockets. +2. Let the client socket connect to the server socket in order to send a segment not containing RST and ACK flags. +3. Check if the server socket is in CLOSED state. +4. Check if the packet is a segment not containing RST and ACK flags. +5. Let the server socket receive the segment and send a RST segment. +6. Check if the packet is the RST segment with zero SEQ number. +7. Let the client socket receive the RST segment. +8. Check the error_counter and rst_counter. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; +static UINT seg_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_1_04_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_04_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + seg_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.04 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client checks the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_04; + + tx_thread_suspend(&ntest_0); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client checks the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_04_2; + + /* Call connect to establish a TCP connection*/ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 50); + + tx_thread_resume(&ntest_0); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (seg_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_1_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *tcp_header_ptr; + + if(server_socket.nx_tcp_socket_state == NX_TCP_CLOSED) + { + + /* Point to the TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Determined if it set the ACK BIT and RST BIT. */ + if((!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) && (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT))) + { + /* The incoming segment is not containing RST and ACK flags. */ + seg_counter = 1; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_1_04_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if (seg_counter == 1) + { + /* Point to the TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Determined the RST BIT,ACK BIT,SEQ. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (tcp_header_ptr -> nx_tcp_sequence_number == 0)) + { + + /* ACK_BIT and RST_BIT has been set and SEQ is zero. */ + rst_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + else + error_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let client receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_04_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.04 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_05_test.c b/test/regression/netxduo_test/netx_1_05_test.c new file mode 100644 index 00000000..7169fc05 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_05_test.c @@ -0,0 +1,362 @@ +/* 1.05 TCP, in CLOSED state, must send a RST in response to an incoming segment containing ACK and not containing RST and SEQ number is taken from SEG.ACK. */ + +/* Procedure +1. Create server and client sockets. +2. Let the client socket connect to the server socket. +3. Unbind the client socket. +4. Let the server socket send an ACK segment. +5. Check if the client socket is in CLOSED state. +6. Check if the segment is containing ACK and not containing RST. +7. Let the client socket receive the segment and send a RST segment. +8. Check if the segment is the RST one and its SEQ number is taken from SEG.ACK. +9. Check the error_counter and rst_counter. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; +static ULONG ack_counter; +static ULONG ack_number; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_05(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_1_05_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_05_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + ack_counter = 0; + ack_number = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.05 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client check the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_05; + + /* Set the client socket to CLOSE state. */ + client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + + /* Unbind the client socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_1); + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (ack_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Let client check the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_05_2; + + /* Send out an ACK segment. */ + _nx_tcp_packet_send_ack(&server_socket, server_socket.nx_tcp_socket_tx_sequence); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +void my_tcp_packet_receive_1_05(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if(client_socket.nx_tcp_socket_state == NX_TCP_CLOSED) + { + + /* Point to the TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + /* Determined if it set the ACK BIT and not set RST BIT. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT))) + { + /* The incoming segment is containing ACK and not containing RST. */ + ack_counter = 1; + ack_number = tcp_header_ptr -> nx_tcp_acknowledgment_number; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + } + + /* Let client receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +void my_tcp_packet_receive_1_05_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if (ack_counter == 1) + { + /* Point to the TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Determined the RST BIT,ACK BIT,SEQ. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) && (tcp_header_ptr -> nx_tcp_sequence_number == ack_number)) + { + + /* RST_BIT have been set and SEQ number is taken from SEG.ACK. */ + rst_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + else + error_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_05_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.05 Test........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_1_17_test.c b/test/regression/netxduo_test/netx_1_17_test.c new file mode 100644 index 00000000..a4601b8e --- /dev/null +++ b/test/regression/netxduo_test/netx_1_17_test.c @@ -0,0 +1,313 @@ +/* 1.17 TCP, in CLOSED state, MUST send a SYN on an active OPEN call. */ + +/* Procedure + 1. Create a client socket. + 2. Check the state of client is CLOSED and call connect command. + 3. Check the packet is a SYN one. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG syn_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check the state of client is CLOSED. */ + if (client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter)||(syn_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + printf("NetX Test: TCP Spec 1.17 Test........................................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let server checks the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_17; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +void my_tcp_packet_receive_1_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a SYN one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + syn_counter++; + + /* Deal the packet with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the SYN packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.17 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_18_test.c b/test/regression/netxduo_test/netx_1_18_test.c new file mode 100644 index 00000000..7db7f53f --- /dev/null +++ b/test/regression/netxduo_test/netx_1_18_test.c @@ -0,0 +1,325 @@ +/* 1.18 TCP MUST be capable of progressing to ESTABLISHED state after receiving SYN,ACK in SYN-SENT state. */ + +/* Procedure + 1. Client sends a SYN packet and becomes SYN_SENT state. + 2. Server receives the SYN packet and replies a SYN + ACK packet. + 3. Check the state of client is SYN_SENT. + 4. Let client deal with the SYN + ACK packet and checks the state of client is ESTABLISHED. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_18_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client checks the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_18; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(syn_ack_counter == 1) + { + /* Check the state of client is ESTABLISHED. */ + if (client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + } + else + error_counter++; + + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (syn_ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + printf("NetX Test: TCP Spec 1.18 Test........................................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +void my_tcp_packet_receive_1_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check the state of client is SYN_SENT. */ + if(client_socket.nx_tcp_socket_state == NX_TCP_SYN_SENT) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a SYN + ACK one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + syn_ack_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + /* Let client receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_18_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.18 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_19_01_test.c b/test/regression/netxduo_test/netx_1_19_01_test.c new file mode 100644 index 00000000..dce5f0f2 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_19_01_test.c @@ -0,0 +1,321 @@ +/* 1.19.01:TCP MUST send a FIN on a CLOSE call in ESTAB-LISHED state. */ + +/* Procedure + 1.Let the client connect server socket. + 2.Check the state of server socket is Established. + 3.Server send a FIN on a CLOSE call. + 4.Check the FIN packet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG flag_1_19_01; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_19_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_19_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + flag_1_19_01 = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.19.01 Test....................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check the state of server is ESTABLISHED. */ + if(server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + /* Disconnect the server socket to send a CLOSE call. */ + if(flag_1_19_01 == 0) + flag_1_19_01 = 1; + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client check the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_19_01; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void my_tcp_packet_receive_1_19_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + if(flag_1_19_01 == 1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + fin_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + flag_1_19_01 = 0; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let client receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_19_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.19.01 Test.....................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_19_02_test.c b/test/regression/netxduo_test/netx_1_19_02_test.c new file mode 100644 index 00000000..c88d7103 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_19_02_test.c @@ -0,0 +1,338 @@ +/* 1.19.02:TCP MUST send a FIN on a CLOSE call in SYN-RCVD state. */ + +/* Procedure + 1.Client sends a SYN packet and becomes SYN_SENT state. + 2.Server receives the SYN packet and becomes SYN_RECEIVED state. + 3.Server calls the CLOSE command. + 4.Server socket sends a FIN packet on a CLOSE call. + 5.Check the packet is a FIN one */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG flag_1_19_02; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_1_19_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_1_19_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_19_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + flag_1_19_02 = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.19.02 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver drop the SYN+ACK packet. */ + advanced_packet_process_callback = my_packet_process_1_19_02; + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_0); + + /* Check the state of server socket is SYN_RECEIVED. */ + if (server_socket.nx_tcp_socket_state != NX_TCP_SYN_RECEIVED) + error_counter++; + + /* Disconnect the server socket on a CLOSE call. */ + if(flag_1_19_02 == 0) + flag_1_19_02 = 1; + status = nx_tcp_socket_disconnect(&server_socket,50); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client check the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_19_02; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_1_19_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a SYN+ACK packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* SYN+ACK packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + + tx_thread_resume(&ntest_0); + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_1_19_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + if(flag_1_19_02 == 1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + fin_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + flag_1_19_02 = 0; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let client receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_19_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.19.02 Test.....................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_19_03_test.c b/test/regression/netxduo_test/netx_1_19_03_test.c new file mode 100644 index 00000000..a73df0b7 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_19_03_test.c @@ -0,0 +1,321 @@ +/* 1.19.03:TCP MUST send a FIN on a CLOSE call in CLOSE_WAIT state. */ + +/* Procedure + 1.Client socket connects to server socket. + 2.Server socket disconnects to client socket. + 3.Check the state of client socket is CLOSE_WAIT. + 4.Client sends a FIN packet in order to call CLOSE command. + 5.Check the packet is a FIN one. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG flag_1_19_03; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_19_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_19_03_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + flag_1_19_03 = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.19.03 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check the state of client is CLOSE_WAIT. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSE_WAIT) + error_counter++; + + /* Disconnect the client socket to send a CLOSE call. */ + if(flag_1_19_03 == 0) + flag_1_19_03 = 1; + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a connection from client socket. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Point to my function */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_19_03; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_1_19_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + if(flag_1_19_03 == 1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check whether it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + fin_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + flag_1_19_03 = 0; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_19_03_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.19.03 Test.....................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_20_test.c b/test/regression/netxduo_test/netx_1_20_test.c new file mode 100644 index 00000000..455c4656 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_20_test.c @@ -0,0 +1,359 @@ +/* 1.20 TCP MUST move on to CLOSED state after receiving an ACK of the sent FIN in LAST_ACK state. */ + +/* Procedure +1. Establish a connection by the "three-way handshake" procedure. +2. Client sends a FIN packet and becomes LAST_ACK state. +3. Check the packet is FIN one. +4. Server receives the FIN packet and replies an ACK packet. +5. Check the state of client is LAST_ACK. +6. Check the packet is an ACK one. +7. Client receives the ACK packet. +8. Check the state of client is CLOSED. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG ack_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_1_20_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_20_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + fin_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status = nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.20 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client checks the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_20; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* To test if client_socket is on the CLOSED state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (ack_counter!=1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + UINT status; + ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let server checks the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_20_2; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +void my_tcp_packet_receive_1_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *tcp_header_ptr; + + /* Check whether the state of server is LAST_ACK. */ + if (client_socket.nx_tcp_socket_state == NX_TCP_LAST_ACK) + { + /* Check whether the packet is a ACK packet which responsing the FIN one. */ + if(fin_counter == 1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + ack_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + } + + /* Let client receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +void my_tcp_packet_receive_1_20_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a fin one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + fin_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let client receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_20_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.20 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_21_01_test.c b/test/regression/netxduo_test/netx_1_21_01_test.c new file mode 100644 index 00000000..16efb004 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_21_01_test.c @@ -0,0 +1,377 @@ +/* 1.21 TCP MUST send an ACK after receiving a FIN in FIN_WAIT_1 state. */ + +/* Procedure +1. Establish a connection by the "three-way handshake" procedure. +2. Server sends a FIN packet and becomes FIN_WAIT_1 state. +3. Delay the FIN packet and keep the server state to FIN_WAIT_1. +4. Client sends a FIN packet. +5. Check the packet is a FIN one. +6. Server replies an ACK packet. +7. Check the packet is an ACK one. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG ack_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_1_21_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_1_21_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_1_21_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_21_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.21.01 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let the driver delay the FIN packet. */ + advanced_packet_process_callback = my_packet_process_1_21_01; + + /*Let the server socket check the FIN packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_21_01; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client check the ACK packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_21_01_2; + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 1) || (ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_1_21_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +void my_tcp_packet_receive_1_21_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check whether the state of server is in FIN_WAIT_1. */ + if (server_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + fin_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +void my_tcp_packet_receive_1_21_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check whether the packet is a ACK packet which responsing the FIN one. */ + if(fin_counter == 1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + ack_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let client receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_21_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.21.01 Test.....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_1_21_02_test.c b/test/regression/netxduo_test/netx_1_21_02_test.c new file mode 100644 index 00000000..c1ca17e5 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_21_02_test.c @@ -0,0 +1,346 @@ +/* 1.21 TCP MUST send an ACK after receiving a FIN in FIN_WAIT_2 state. */ + +/* Procedure +1. Establish a connection by the "three-way handshake" procedure. +2. Server sends a FIN packet. +3. Server receives an ACK packet which responsing the FIN one and becomes FIN_WAIT_2 state. +4. Client sends a FIN packet. +5. Check the packet is a FIN one. +6. Server replies an ACK packet. +7. Check the packet is an ACK one. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG ack_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_21_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_1_21_02_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_21_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.21.02 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let server check the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_21_02; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client check the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_21_02_2; + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 1) || (ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +void my_tcp_packet_receive_1_21_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check the state of server is FIN_WAIT_2. */ + if (server_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_2) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + fin_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +void my_tcp_packet_receive_1_21_02_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check whether the packet is a ACK packet which responsing the FIN one. */ + if(fin_counter == 1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + ack_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let client receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_21_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.21.02 Test.....................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_26_01_test.c b/test/regression/netxduo_test/netx_1_26_01_test.c new file mode 100644 index 00000000..f9eca41c --- /dev/null +++ b/test/regression/netxduo_test/netx_1_26_01_test.c @@ -0,0 +1,396 @@ +/* 1.26 TCP MAY send an ACK after receiving a data segment in FINWAIT_1 state. */ + +/* Procedure +1. Establish a connection by the "three-way handshake" procedure. +2. Server sends a FIN packet and becomes FIN_WAIT_1 state. +3. Delay the FIN packet and keep the server state to FIN_WAIT_1. +4. Client sends a data segment. +5. Check whether the server receives the data segment. +6. Server replies an ACK packet. +7. Check the packet is an ACK one. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ack_counter; +static ULONG data_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_1_26_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_1_26_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_26_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + data_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; + + printf("NetX Test: TCP Spec 1.26.01 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay the FIN packet. */ + advanced_packet_process_callback = my_packet_process_1_26_01; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_0); + + /* Check the server socket state. */ + if(server_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_1) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr,NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the data segment. */ + if(!memcmp(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + data_counter++; + } + + else + error_counter++; + + tx_thread_suspend(&ntest_0); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client check the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_26_01; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Write ABCs into the packet payload. */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + tx_thread_sleep(NX_IP_PERIODIC_RATE/2); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (data_counter !=1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(ack_counter != 1) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_1_26_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +void my_tcp_packet_receive_1_26_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check whether the packet is a ACK packet which responsing the data segment. */ + if(data_counter == 1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + ack_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let client receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_26_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.26.01 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_26_02_test.c b/test/regression/netxduo_test/netx_1_26_02_test.c new file mode 100644 index 00000000..eccb330d --- /dev/null +++ b/test/regression/netxduo_test/netx_1_26_02_test.c @@ -0,0 +1,362 @@ +/* 1.26 TCP MAY send an ACK after receiving a data segment in FINWAIT_2 state. */ + +/* Procedure + 1. Establish a connection by the "three-way handshake" procedure. + 2. Server disconnects to client and becomes FIN_WAIT_2 state. + 3. Client sends a data segment. + 4. Check whether the server socket is in FIN_WAIT_2 state. + 5. Check whether the server receives the data segment. + 6. Server replies an ACK packet. + 7. Check the packet is an ACK one. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ack_counter; +static ULONG data_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_26_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_26_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + data_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; + + printf("NetX Test: TCP Spec 1.26.02 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_0); + + /* Check the server socket state. */ + if(server_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_2) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr,NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the data segment. */ + if(!memcmp(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + data_counter++; + } + else + error_counter++; + + tx_thread_suspend(&ntest_0); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client check the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_26_02; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Write ABCs into the packet payload. */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + tx_thread_sleep(NX_IP_PERIODIC_RATE/2); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (data_counter !=1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(ack_counter != 1) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +void my_tcp_packet_receive_1_26_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check whether the packet is a ACK packet which responsing the data segment. */ + if(data_counter == 1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + ack_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let client receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_26_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.26.02 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_27_01_test.c b/test/regression/netxduo_test/netx_1_27_01_test.c new file mode 100644 index 00000000..a7224d95 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_27_01_test.c @@ -0,0 +1,380 @@ +/* 1.27.01 TCP must ignore a data segment in SYN_SENT state. */ + +/* Procedure +1. Establish a connection by the "three-way handshake" procedure. +2. Set client socket to CLOSED state. +3. Let client socket connect to the server socket. +4. Let the driver drop the SYN packet. +5. Let the server socket send out a data segment. +6. Check if the client socket is in SYN_SENT state. +7. Let the client socket receive the data segment +8. Check the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static UINT is_ignored; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_1_27_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_1_27_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_27_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + is_ignored = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + printf("NetX Test: TCP Spec 1.27.01 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Set client state to CLOSED. */ + client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + + /* Let driver drop the SYN packet. */ + advanced_packet_process_callback = my_packet_process_1_27_01; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Setup function pointer. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_27_01; + + tx_thread_resume(&ntest_1); + + /* Check the client socket state. */ + if(client_socket.nx_tcp_socket_state == NX_TCP_SYN_SENT) + { + status = nx_tcp_socket_receive(&client_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for valid status. */ + if(status) + is_ignored = NX_TRUE; + } + else + error_counter++; + + tx_thread_resume(&ntest_1); + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(is_ignored != NX_TRUE) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Write ABCs into the packet payload. */ + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + } + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_1_27_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a SYN one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + /* Drop the SYN packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + return NX_TRUE; +} + +static void my_tcp_packet_receive_1_27_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + if(client_socket.nx_tcp_socket_state == NX_TCP_SYN_SENT) + { + if((packet_ptr->nx_packet_length == 40) && !(memcmp(packet_ptr->nx_packet_prepend_ptr + 20, MSG, 20))) + { + data_packet_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_27_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.27.01 Test.....................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_1_27_02_test.c b/test/regression/netxduo_test/netx_1_27_02_test.c new file mode 100644 index 00000000..479fd431 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_27_02_test.c @@ -0,0 +1,352 @@ +/* 1.27.02 TCP must ignore a data segment in CLOSE_WAIT state. */ + +/* Procedure +1. Establish a connection by the "three-way handshake" procedure. +2. Let the server socket disconnect to client socket. +3. Set the server socket to ESTABLISHED state. +4. Let the server socket send out a data segment. +5. Check if the client socket is in CLOSE_WAIT state. +6. Let the client socket receive the data segment. +7. Check the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static UINT is_ignored; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_1_27_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_27_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + is_ignored = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + printf("NetX Test: TCP Spec 1.27.02 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup function pointer. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_27_02; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check the client socket state. */ + if(client_socket.nx_tcp_socket_state == NX_TCP_CLOSE_WAIT) + { + status = nx_tcp_socket_receive(&client_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for valid status. */ + if(status) + is_ignored = NX_TRUE; + } + else + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + tx_thread_resume(&ntest_1); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(is_ignored != NX_TRUE) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Set the server socket to ESTABLISHED state. */ + server_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Write ABCs into the packet payload. */ + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_1_27_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + if(client_socket.nx_tcp_socket_state == NX_TCP_CLOSE_WAIT) + { + if((packet_ptr->nx_packet_length == 40) && !(memcmp(packet_ptr->nx_packet_prepend_ptr + 20, MSG, 20))) + { + data_packet_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_27_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.27.02 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_1_27_03_test.c b/test/regression/netxduo_test/netx_1_27_03_test.c new file mode 100644 index 00000000..44a68823 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_27_03_test.c @@ -0,0 +1,385 @@ +/* 1.27.03 TCP must ignore a data segment in CLOSING state. */ + +/* Procedure +1. Establish a connection by the "three-way handshake" procedure. +2. Let the server socket disconnect to the client socket. +3. Let the driver delay the FIN packet. +4. Let the client socket disconnect to the server socket. +5. Let the client socket send out a data segment. +6. Check if the server socket is in CLOSING state. +7. Let the server socket receive the data segment +8. Check the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static UINT is_ignored; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_1_27_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_1_27_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_27_03_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + is_ignored = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; + + printf("NetX Test: TCP Spec 1.27.03 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay the FIN packet. */ + advanced_packet_process_callback = my_packet_process_1_27_03; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Setup function pointer. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_27_03; + + tx_thread_suspend(&ntest_0); + + /* Check the client socket state. */ + if(server_socket.nx_tcp_socket_state == NX_TCP_CLOSING) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for valid status. */ + if(status) + is_ignored = NX_TRUE; + } + else + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Set client state to CLOSED. */ + client_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Write ABCs into the packet payload. */ + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 50); + + /* Determine if the status is valid. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(is_ignored != NX_TRUE) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_1_27_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + + /* Delay the FIN packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = 200; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_1_27_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + if(server_socket.nx_tcp_socket_state == NX_TCP_CLOSING) + { + if((packet_ptr->nx_packet_length == 40) && !(memcmp(packet_ptr->nx_packet_prepend_ptr + 20, MSG, 20))) + { + data_packet_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_27_03_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.27.03 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_1_27_04_test.c b/test/regression/netxduo_test/netx_1_27_04_test.c new file mode 100644 index 00000000..33557c19 --- /dev/null +++ b/test/regression/netxduo_test/netx_1_27_04_test.c @@ -0,0 +1,368 @@ +/* 1.27.04 TCP must ignore a data segment in LAST_ACK state. */ + +/* Procedure +1. Establish a connection by the "three-way handshake" procedure. +2. Let the server socket disconnect to the client socket. +3. Let the client socket disconnect to the server socket. +4. Let the driver delay the FIN packet. +5. Let the server socket send out a data segment. +6. Check if the client socket is in LAST_ACK state. +7. Let the client socket receive the data segment. +8. Check the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static UINT is_ignored; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_1_27_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_1_27_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_27_04_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + is_ignored = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + printf("NetX Test: TCP Spec 1.27.04 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay the FIN packet. */ + advanced_packet_process_callback = my_packet_process_1_27_04; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Setup function pointer. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_1_27_04; + + tx_thread_resume(&ntest_1); + + /* Check the client socket state. */ + if(client_socket.nx_tcp_socket_state == NX_TCP_LAST_ACK) + { + status = nx_tcp_socket_receive(&client_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for valid status. */ + if(status) + is_ignored = NX_TRUE; + } + else + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(is_ignored != NX_TRUE) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_1); + + /* Set the server socket to ESTABLISHED state. */ + server_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Write ABCs into the packet payload. */ + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out. */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_1_27_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + + /* Delay the FIN packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = 200; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_1_27_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + if(client_socket.nx_tcp_socket_state == NX_TCP_LAST_ACK) + { + if((packet_ptr->nx_packet_length == 40) && !(memcmp(packet_ptr->nx_packet_prepend_ptr + 20, MSG, 20))) + { + data_packet_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_1_27_04_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 1.27.04 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_23_02_01_test.c b/test/regression/netxduo_test/netx_23_02_01_test.c new file mode 100644 index 00000000..edfa6993 --- /dev/null +++ b/test/regression/netxduo_test/netx_23_02_01_test.c @@ -0,0 +1,410 @@ +/* 23.02.1 TCP in LISTEN state, MUST reject an incoming SYN with broadcast address(255.255.255.255) as source IP address. */ + + +/* Procedure + 1. Client send a SYN to Server. + 2. Use packet_process function to receive and deal with the SYN packet,change the IP address. + 3. Check whether the SYN packet is rejected. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); +#if (defined(__PRODUCT_NETXDUO__) || defined(NX_ENABLE_SOURCE_ADDRESS_CHECK)) && !defined(NX_DISABLE_IPV4) + +#ifndef __PRODUCT_NETXDUO__ +#define NX_IPV4_HEADER NX_IP_HEADER +#endif + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG is_rejected; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_23_02_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_23_02_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /*Initial the variable. */ + error_counter = 0; + is_rejected = NX_TRUE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 23.02.01 Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(!status) + is_rejected = NX_FALSE; + + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_23_02_01; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 50); + + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (is_rejected != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_23_02_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +NX_IPV4_HEADER *ip_header_ptr; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +ULONG val; +#else +ULONG source_ip, dest_ip; +ULONG temp; +#endif +ULONG checksum; + + + if(packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + + /* Point to the TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check whether the segment is a SYN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT))) + { + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Point to the IP HEADER. */ + ip_header_ptr = (NX_IPV4_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + + + /* Change the source IP address in the IP header. */ + ip_header_ptr -> nx_ip_header_source_ip = 0xFFFFFFFF; + + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 & 0x0000FFFF; + +#ifdef __PRODUCT_NETXDUO__ + /* Calculate the IP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, + /* Length is the size of IP header, including options */ + 20, + /* IPv4 header checksum doesn't care src/dest addresses */ + NULL, NULL); + + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + +#else + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + + /* Build the IP header checksum. */ + temp = ip_header_ptr -> nx_ip_header_word_0; + checksum = (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_word_1; + checksum += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_word_2; + checksum += (temp >> NX_SHIFT_BY_16); + temp = ip_header_ptr -> nx_ip_header_source_ip; + checksum += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_destination_ip; + checksum += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + + /* Add in the carry bits into the checksum. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Do it again in case previous operation generates an overflow. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | (NX_LOWER_16_MASK & (~checksum)); + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); +#endif + + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); + + + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + + +#ifdef __PRODUCT_NETXDUO__ + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &ip_header_ptr -> nx_ip_header_source_ip; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#else + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_header_ptr -> nx_ip_header_source_ip; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); + + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + advanced_packet_process_callback = NX_NULL; + return NX_TRUE; +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_23_02_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 23.02.01 Test....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_23_02_02_test.c b/test/regression/netxduo_test/netx_23_02_02_test.c new file mode 100644 index 00000000..8f378a38 --- /dev/null +++ b/test/regression/netxduo_test/netx_23_02_02_test.c @@ -0,0 +1,415 @@ +/* 23.02.2 TCP in LISTEN state, MUST reject an incoming SYN with +multicast addresses as source IP address. */ + +/* Update + 1. nx_tcp_packet_process.c between line 340 and line 355. */ + +/* Procedure + 1. Client send a SYN to Server. + 2. Use packet_process function to receive and deal with the SYN packet,change the IP address. + 3. Judge the packet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); +#if (defined(__PRODUCT_NETXDUO__) || defined(NX_ENABLE_SOURCE_ADDRESS_CHECK)) && !defined(NX_DISABLE_IPV4) + +#ifndef __PRODUCT_NETXDUO__ +#define NX_IPV4_HEADER NX_IP_HEADER +#endif + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG is_rejected; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_23_02_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_23_02_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /*Initial the variable. */ + error_counter = 0; + is_rejected = NX_TRUE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 23.02.02 Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(!status) + is_rejected = NX_FALSE; + + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_23_02_02; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 50); + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (is_rejected != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_23_02_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +NX_IPV4_HEADER *ip_header_ptr; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +ULONG val; +#else +ULONG source_ip, dest_ip; +ULONG temp; +#endif +ULONG checksum; + + + if(packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + + /* Point to the TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check whether the segment is a SYN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT))) + { + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Point to the IP HEADER. */ + + ip_header_ptr = (NX_IPV4_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + + + /* Change the source IP address in the IP header. */ + ip_header_ptr -> nx_ip_header_source_ip = 0x010000E0; + + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 & 0x0000FFFF; + +#ifdef __PRODUCT_NETXDUO__ + /* Calculate the IP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, + /* Length is the size of IP header, including options */ + 20, + /* IPv4 header checksum doesn't care src/dest addresses */ + NULL, NULL); + + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + +#else + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + + /* Build the IP header checksum. */ + temp = ip_header_ptr -> nx_ip_header_word_0; + checksum = (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_word_1; + checksum += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_word_2; + checksum += (temp >> NX_SHIFT_BY_16); + temp = ip_header_ptr -> nx_ip_header_source_ip; + checksum += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_destination_ip; + checksum += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + + /* Add in the carry bits into the checksum. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Do it again in case previous operation generates an overflow. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | (NX_LOWER_16_MASK & (~checksum)); + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); +#endif + + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); + + + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + + +#ifdef __PRODUCT_NETXDUO__ + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &ip_header_ptr -> nx_ip_header_source_ip; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#else + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_header_ptr -> nx_ip_header_source_ip; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); + + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + advanced_packet_process_callback = NX_NULL; + return NX_TRUE; +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_23_02_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 23.02.02 Test....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_23_02_03_test.c b/test/regression/netxduo_test/netx_23_02_03_test.c new file mode 100644 index 00000000..d79b36cd --- /dev/null +++ b/test/regression/netxduo_test/netx_23_02_03_test.c @@ -0,0 +1,273 @@ +/* 23.02.03 TCP in LISTEN state, MUST reject an incoming SYN with + broadcast address(subnet-directed broadcast--128.1.2.255) as source IP address. */ + +/* Update + 1. nx_tcp_packet_process.c between line 346 and line 347. */ + +/* Procedure + 1. Client send a SYN to Server. + 2. Use packet_process function to receive and deal with the SYN packet. + 3. Use packet_process function to receive and deal with the SYN packet,Judge the packet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); +#if (defined(__PRODUCT_NETXDUO__) || defined(NX_ENABLE_SOURCE_ADDRESS_CHECK)) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG is_rejected; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_23_02_03_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /*Initial the variable. */ + error_counter = 0; + is_rejected = NX_TRUE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(256, 1, 2, 2), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(256, 1, 2, 255), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 23.02.03 Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(!status) + is_rejected = NX_FALSE; + + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(256, 1, 2, 2), 12, 50); + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (is_rejected != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_23_02_03_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 23.02.03 Test....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_23_02_04_test.c b/test/regression/netxduo_test/netx_23_02_04_test.c new file mode 100644 index 00000000..b88cc5f5 --- /dev/null +++ b/test/regression/netxduo_test/netx_23_02_04_test.c @@ -0,0 +1,273 @@ +/* 23.02.04 TCP in LISTEN state, MUST reject an incoming SYN with + local subnet address (128.1.2.0) as source IP address. */ + +/* Update + 1. nx_tcp_packet_process.c between line 348 and line 349. */ + +/* Procedure + 1. Client send a SYN to Server. + 2. Use packet_process function to receive and deal with the SYN packet. + 3. Use packet_process function to receive and deal with the SYN packet,Judge the packet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); +#if (defined(__PRODUCT_NETXDUO__) || defined(NX_ENABLE_SOURCE_ADDRESS_CHECK)) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG is_rejected; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_23_02_04_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /*Initial the variable. */ + error_counter = 0; + is_rejected = NX_TRUE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(128, 1, 2, 2), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(128, 1, 2, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 23.02.04 Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(!status) + is_rejected = NX_FALSE; + + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(128, 1, 2, 2), 12, 50); + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (is_rejected != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_23_02_04_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 23.02.04 Test....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_2_01_test.c b/test/regression/netxduo_test/netx_2_01_test.c new file mode 100644 index 00000000..b7bde59c --- /dev/null +++ b/test/regression/netxduo_test/netx_2_01_test.c @@ -0,0 +1,390 @@ +/* 2.02 Receiver TCP must check the checksum in any incoming segment, and must not acknowledge in case of an error. */ + +/* Procedure +1. Let the client socket and server socket finish "three-way handshake" process. +2. Let the server socket allocate a data segment and send it out . +3. Change the TCP checksum of the data segment. +4. Check if the receiver TCP reply an ACK pakcet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); +#if !defined(NX_ENABLE_INTERFACE_CAPABILITY) && !defined(NX_DISABLE_TCP_TX_CHECKSUM) && !defined(NX_DISABLE_TCP_RX_CHECKSUM) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ack_counter; +static UINT data_counter; +static ULONG ack_number; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_2_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_2_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_2_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + data_counter = 0; + ack_number = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let my function change the checksum. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_2_01; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (ack_counter) || (data_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 2.01 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let my function change the checksum. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_2_01_2; + + /* Create a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, "01234567890123456789", 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Record the tx_sequence. */ + ack_number = server_socket.nx_tcp_socket_tx_sequence; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Avoid server resend the packet. */ + server_socket.nx_tcp_socket_tx_sequence = server_socket.nx_tcp_socket_tx_sequence - 20; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + /* Get nothing the peer socket info. */ + if (nxd_tcp_socket_peer_info_get(&server_socket, NX_NULL, NX_NULL) == NX_SUCCESS) + error_counter++; +#endif /* __PRODUCT_NETXDUO__ */ +} + +void my_tcp_packet_receive_2_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; + + + /* Change the checksum. */ + if((packet_ptr -> nx_packet_length - 20 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, "01234567890123456789", 20))) + { + + data_counter++; + + /* Point to TCP header */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr->nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + checksum = tcp_header_ptr ->nx_tcp_header_word_4 >> NX_SHIFT_BY_16; + checksum += 1; + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + /* Use the default routine. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + /* Let the client socket receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +void my_tcp_packet_receive_2_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check whether the client socket reply an ACK packet to the data segment. */ + if(data_counter == 1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT))&& (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT))&& (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT))) + { + /* Get the ack_number. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(tcp_header_ptr -> nx_tcp_acknowledgment_number == (ack_number + 20)) + ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + } + else if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT)) + { + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let the server socket receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_2_01_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Spec 2.01 Test........................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_2_02_test.c b/test/regression/netxduo_test/netx_2_02_test.c new file mode 100644 index 00000000..df811293 --- /dev/null +++ b/test/regression/netxduo_test/netx_2_02_test.c @@ -0,0 +1,370 @@ +/* 2.02 Receiver TCP must check the checksum in any incoming segment, and must acknowledge in case of no error. */ + +/* Procedure +1. Let the client socket and server socket finish "three-way handshake" process. +2. Let the server socket allocate a data segment and send it out . +3. Change the TCP checksum of the data segment. +4. Check if the receiver TCP reply an ACK pakcet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ack_counter; +static ULONG ack_number; +static UINT data_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_2_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_2_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + ack_number = 0; + data_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + + printf("NetX Test: TCP Spec 2.02 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_receive(&server_socket, &my_packet,2 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if(status) + error_counter++; + else + { + /* Check whether the server socket received an packet with correct checksum. */ + if((my_packet -> nx_packet_length == 20) && (!memcmp(my_packet -> nx_packet_prepend_ptr, "01234567890123456789", 20))) + data_counter++; + + nx_packet_release(my_packet); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE/2); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_2_02; + + /* Create a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, "01234567890123456789", 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Record the tx_sequence. */ + ack_number = client_socket.nx_tcp_socket_tx_sequence; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE/2); + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (ack_counter !=1)|| (data_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + +void my_tcp_packet_receive_2_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check whether the client socket receives a data segment. */ + if(data_counter == 1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check whether the client socket reply an ACK packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT))&& (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT))&& (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT))) + { + + /* Get the ack_number. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + /* Check if the ACK packet responses to the data segment. */ + if(tcp_header_ptr -> nx_tcp_acknowledgment_number == ack_number + 20) + ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let the server socket receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_2_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 2.02 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_2_17_test.c b/test/regression/netxduo_test/netx_2_17_test.c new file mode 100644 index 00000000..e3ce57d7 --- /dev/null +++ b/test/regression/netxduo_test/netx_2_17_test.c @@ -0,0 +1,360 @@ +/* 2.17 Sender TCP MUST generate checksum. */ + +/* Procedure + 1. Let the client socket send a SYN packet . + 2. Check if the checksum is generated. + 3. Check if the checksum is correct. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks. */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application. */ + +static ULONG error_counter; +static ULONG syn_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern ULONG _nx_ip_checksum_compute(NX_PACKET *, int, UINT, ULONG *, ULONG *); +static void my_tcp_packet_receive_2_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_2_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + printf("NetX Test: TCP Spec 2.17 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (syn_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let the server socket check the checksum. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_2_17; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +void my_tcp_packet_receive_2_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; +ULONG checksum; +ULONG checksum_2_17; +#if defined(__PRODUCT_NETXDUO__) + ULONG *source_ip, *dest_ip; + +#elif defined(__PRODUCT_NETX__) + ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is a SYN one. */ + if(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) + { + syn_counter++; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_4); + + /* Record the value of checksum. */ + checksum_2_17 = header_ptr -> nx_tcp_header_word_4 >> NX_SHIFT_BY_16; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_4); + + /* Clean the checksum in the packet. */ + header_ptr -> nx_tcp_header_word_4 = 0; +#if defined(__PRODUCT_NETXDUO__) + /* Calculate the TCP checksum. */ + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_0.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + +#ifndef NX_DISABLE_TCP_TX_CHECKSUM + /* Check if the checksum is correct. */ + if(checksum_2_17 != checksum) + error_counter++; +#endif /* NX_DISABLE_TCP_TX_CHECKSUM */ + + checksum = ~checksum & NX_LOWER_16_MASK; + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_4); + header_ptr -> nx_tcp_header_word_4 = (checksum_2_17 << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_4); + + /* Use the default routine. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + else + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Let the server socket receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_2_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 2.17 Test........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_2_20_test.c b/test/regression/netxduo_test/netx_2_20_test.c new file mode 100644 index 00000000..a0676464 --- /dev/null +++ b/test/regression/netxduo_test/netx_2_20_test.c @@ -0,0 +1,451 @@ +/* 2.20 When congestion occurs, one-half of the current window size is saved in ssthresh. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG ack_counter; +static ULONG seq_number; +static ULONG ack_counter; +static ULONG duplicate_ack_counter; +static ULONG is_set; +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_2_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_2_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_2_20_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + ack_counter = 0; + seq_number = 0; + duplicate_ack_counter = 0; + is_set = NX_FALSE; + + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +NX_PACKET *my_packet4; + + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 2.20 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_2_20; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_2_20; + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet2, MSG+20, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet3, MSG+40, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Create a tcp packet. */ + status = nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet4, MSG+60, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet4, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + + while(!(status = nx_tcp_socket_receive(&client_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE))) + { + + if((packet_ptr -> nx_packet_length == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr, (MSG + data_packet_counter * 20), 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 4) || (duplicate_ack_counter != 3) || (is_set != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_2_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + + if((packet_ptr -> nx_packet_length-40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr+40, MSG, 20))) + { + if(server_socket.nx_tcp_socket_timeout_retries == 0) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + seq_number = tcp_header_ptr -> nx_tcp_sequence_number; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + else if(server_socket.nx_tcp_socket_timeout_retries == 1) + { + if((server_socket.nx_tcp_socket_tx_slow_start_threshold == server_socket.nx_tcp_socket_tx_outstanding_bytes / 2) || (server_socket.nx_tcp_socket_tx_slow_start_threshold == server_socket.nx_tcp_socket_connect_mss * 2)) + is_set = NX_TRUE; + + advanced_packet_process_callback = NX_NULL; + } + } + return NX_TRUE; +} + +static void my_tcp_packet_receive_2_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(tcp_header_ptr ->nx_tcp_acknowledgment_number == seq_number) + duplicate_ack_counter++; + + if(duplicate_ack_counter == 3) + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_2_20_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 2.20 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_3_01_test.c b/test/regression/netxduo_test/netx_3_01_test.c new file mode 100644 index 00000000..26fb04df --- /dev/null +++ b/test/regression/netxduo_test/netx_3_01_test.c @@ -0,0 +1,329 @@ +/* 3.01 TCP MUST return to LISTEN state, on receiving an acceptable RST, in SYN-RCVD state */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.01 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_3_01; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /*Check the TCP state.*/ + if(server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisted on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_TCP_HEADER header_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_NO_WAIT); + + /* Send RST packet. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + header_ptr.nx_tcp_acknowledgment_number = server_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = server_socket.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + + /* Call disconnect to send a FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error*/ + if(status) + error_counter++; + + /* Delete the socket*/ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error*/ + if (status) + error_counter++; + + /* Check for error. */ + if(error_counter || (syn_ack_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a SYN+ACK packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + syn_ack_counter ++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* SYN+ACK packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_01; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_3_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + if((server_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) && (syn_ack_counter == 1)) + { + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check if TCP sends an RST packet */ + if(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + rst_counter ++; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.01 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_3_02_test.c b/test/regression/netxduo_test/netx_3_02_test.c new file mode 100644 index 00000000..29c78413 --- /dev/null +++ b/test/regression/netxduo_test/netx_3_02_test.c @@ -0,0 +1,356 @@ +/* 3.2 TCP MUST NOT change state, on receiving an unacceptable RST, in SYN-RCVD state. */ + +/* Procedure +1.Client connect with server. +2.Server receives the SYN packet and becomes SYN_RCVD state. +3.Client sends an unacceptable RST packet to server. +4.Server will remain the same state. +5.Check the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; +static ULONG syn_ack_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + syn_ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.02 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + advanced_packet_process_callback = my_packet_process_3_02; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_02; + + tx_thread_suspend(&ntest_0); + + /* The server socket should remain the SYN_RVED state. */ + if((server_socket.nx_tcp_socket_state != NX_TCP_SYN_RECEIVED) || (rst_counter != 1)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_TCP_HEADER header_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_NO_WAIT); + + /* Send an unacceptable packet. */ + header_ptr.nx_tcp_acknowledgment_number = server_socket.nx_tcp_socket_rx_sequence- 10; + + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + + tx_thread_resume(&ntest_0); + + /* Call disconnect to send a FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (rst_counter != 1) || (syn_ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if(packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a AYN+ACK packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + syn_ack_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* AYN+ACK packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_3_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* The server socket should be in SYN_RVED state. */ + if(server_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) + { + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a RST one. */ + if(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + } + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.02 Test........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_3_03_test.c b/test/regression/netxduo_test/netx_3_03_test.c new file mode 100644 index 00000000..17ad7ba5 --- /dev/null +++ b/test/regression/netxduo_test/netx_3_03_test.c @@ -0,0 +1,385 @@ +/* 3.03:TCP MUST send a RST after receiving an unacceptable ACK in SYN-RCVD state. */ + +/* Procedure +1.Client connect with server. +2.Server receives the SYN packet and becomes SYN_RCVD state. +3.Client sends an unacceptable ACK to server. +4.Server should send a RST packet. +5.Check the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; +static ULONG syn_ack_counter; +static ULONG ack_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_3_03_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_03_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + syn_ack_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.03 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_3_03; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_03; + + tx_thread_suspend(&ntest_0); + + /* Call disconnect to send a FIN. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisted on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_NO_WAIT); + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_03_02; + + client_socket.nx_tcp_socket_rx_sequence -= 10; + + /* Send an unacceptable ACK */ + _nx_tcp_packet_send_ack(&client_socket, client_socket.nx_tcp_socket_tx_sequence); + + tx_thread_resume(&ntest_0); + + /* Call disconnect to send a FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error*/ + if(status) + error_counter++; + + /* Delete the socket*/ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error*/ + if (status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (rst_counter != 1) || (syn_ack_counter != 1) || (ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if(packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + syn_ack_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* SYN+ACK packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_3_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* The server socket should be in SYN_RCVD state. */ + if(server_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) + { + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + /* Check if client sends an unacceptable ACK packet */ + if(!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + if(header_ptr -> nx_tcp_acknowledgment_number != server_socket.nx_tcp_socket_rx_sequence) + ack_counter ++; + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + } + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +static void my_tcp_packet_receive_3_03_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* The server socket have received the unacceptable ACK. */ + if(ack_counter == 1) + { + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + if(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter ++; + + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + } + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_03_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.03 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_3_04_test.c b/test/regression/netxduo_test/netx_3_04_test.c new file mode 100644 index 00000000..58ac78e1 --- /dev/null +++ b/test/regression/netxduo_test/netx_3_04_test.c @@ -0,0 +1,525 @@ +/* 3.04:TCP, in ESTABLISHED state, + MUST return ACK with proper SEQ and ACK numbers after recv a seg with OTW SEQ or unacc ACK number, + and remain in same state If the connection is in a synchronized state, + any unacceptable segment (out of window sequence number or unacceptable acknowledgment number) + must elicit only an empty acknowledgment segment containing the current send-sequence number + and an acknowledgment indicating the next sequence number expected to be received, + and the connection remains in the same state. */ + +/* Procedure + 1.Connect + 2.Client sends a packet with OTW SEQ and acceptable ACK number to server + 3.Client should receive an ACK with proper SEQ and ACK numbers + 4.Client sends a packet with proper OTW SEQ and unacceptable ACK number to server + 5.Client should receive an ACK with proper SEQ and ACK numbers */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#endif +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG ack_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_3_04_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_04_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.04 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_04; + + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_3_04; + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_04_2; + + /* Allocate packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the first packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet2, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the second packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + client_socket.nx_tcp_socket_tx_sequence -= 40; + + /* Call disconnect to send a FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 2) || (ack_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + /* Pointer to TCP header. */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + /* Check if it is a DATA packet. */ + if((packet_ptr -> nx_packet_length - 40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 40, MSG, 20))) + { + if (data_packet_counter == 0) + { + /* OTW SEQ. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + tcp_header_ptr-> nx_tcp_sequence_number -= 100; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + } + else + { + /* Unacceptable ACK number. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + tcp_header_ptr-> nx_tcp_acknowledgment_number += 100; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + advanced_packet_process_callback = NX_NULL; + } + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + } + return NX_TRUE; +} + +static void my_tcp_packet_receive_3_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + /* Check if it is a segment. */ + if((packet_ptr -> nx_packet_length - 20 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, 20))) + { + + /* Check if client sends a packet with OTW SEQ and proper ACK number. */ + if(((header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current))&& + (header_ptr ->nx_tcp_acknowledgment_number == server_socket.nx_tcp_socket_tx_sequence) ) + data_packet_counter ++; + + /* Check if client sends a packet with proper SEQ and unacceptable ACK number. */ + else if(((header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence) && + (header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current))&& + (header_ptr ->nx_tcp_acknowledgment_number != server_socket.nx_tcp_socket_tx_sequence)) + data_packet_counter ++; + + if (data_packet_counter == 2) + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +static void my_tcp_packet_receive_3_04_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + if(!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + if ((header_ptr -> nx_tcp_sequence_number == server_socket.nx_tcp_socket_tx_sequence)&& + (header_ptr -> nx_tcp_acknowledgment_number == server_socket.nx_tcp_socket_rx_sequence)) + { + ack_counter++; + + /* ACK packet has been processed. */ + if (ack_counter == 2) + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_04_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.04 Test........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_3_06_test.c b/test/regression/netxduo_test/netx_3_06_test.c new file mode 100644 index 00000000..e05dca97 --- /dev/null +++ b/test/regression/netxduo_test/netx_3_06_test.c @@ -0,0 +1,449 @@ +/* 3.6 TCP, in LISTEN state MUST send a RST after receiving a segment that is carrying an unacceptable ACK and remain in the same state. */ + +/* Procedure + 1. Connection. + 2. Server calls disconnect command. + 3. Client sends a segment that is carrying an unacceptable ACK. + 4. Server checks whether the packet contains ACK or not. + 5. Server checks whether a RST packet is send. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *, ULONG, UINT, ULONG *, ULONG *); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_06(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_06(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_3_06_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_06_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_3_06; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Relisten on the server port. */ + status = nx_tcp_server_socket_relisten(&ip_0, 12, &server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + if(server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_06; + + tx_thread_suspend(&ntest_0); + + if (server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 3.06 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_06_2; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 10, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (data_packet_counter != 1) || (rst_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_3_06(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + if((packet_ptr -> nx_packet_length == 30) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, 10))) + data_packet_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_3_06_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT my_packet_process_3_06(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#else +ULONG source_ip, dest_ip; +#endif + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Modify the acknowledgment number of the packet to an unacceptable data and recalculate the checksum */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_acknowledgment_number); + + /* Modify the acknowledgment number */ + tcp_header_ptr ->nx_tcp_acknowledgment_number += 10; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + } + else if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_06_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.06 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_3_07_test.c b/test/regression/netxduo_test/netx_3_07_test.c new file mode 100644 index 00000000..9b84f20f --- /dev/null +++ b/test/regression/netxduo_test/netx_3_07_test.c @@ -0,0 +1,426 @@ +/* 3.7 TCP, in ESTABLISHED state, MUST send an ACK indicating the correct SEQ number it expects, after receiving a SYN with a SEQ number that is OTW. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; +static ULONG syn_counter; +static ULONG ack_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *, ULONG, UINT, ULONG *, ULONG *); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_07(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_07(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_3_07_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_07_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + syn_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + if(server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + /* Let server checks the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_07; + + tx_thread_suspend(&ntest_0); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.07 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_3_07; + + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Let client checks the packet. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_07_2; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_NO_WAIT); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + tx_thread_resume(&ntest_0); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (rst_counter != 1) || (syn_counter != 1) || (ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_07(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; + +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#else +ULONG source_ip, dest_ip; +#endif + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + else if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + /* Modify the sequence number of the packet to be OTW and recalculate the checksum. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + tcp_header_ptr ->nx_tcp_sequence_number += server_socket.nx_tcp_socket_rx_window_current; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_sequence_number); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_3_07(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a SYN one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + if ((tcp_header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (tcp_header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) + syn_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_3_07_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(tcp_header_ptr -> nx_tcp_acknowledgment_number == server_socket.nx_tcp_socket_rx_sequence) + ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let client receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_07_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.07 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_3_08_test.c b/test/regression/netxduo_test/netx_3_08_test.c new file mode 100644 index 00000000..5ff3c11d --- /dev/null +++ b/test/regression/netxduo_test/netx_3_08_test.c @@ -0,0 +1,397 @@ +/* 3.8 TCP, in LISTEN state, MUST send a RST after receiving a spurious SYN,ACK that potentially corresponds to an old SYN. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#include "nx_ipv6.h" +#else +#include "nx_ip.h" +#endif +#include "nx_packet.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *, int, UINT, ULONG *, ULONG *); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_08(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_08(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_08_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_IP *ip_ptr; +NX_PACKET *packet_ptr; +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG *option_word_2; +#if defined(__PRODUCT_NETXDUO__) + NX_IPV4_HEADER *ip_header_ptr; +ULONG val; +#else + NX_IP_HEADER *ip_header_ptr; +#endif +ULONG checksum; +ULONG source; +ULONG dest; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#else +ULONG source_ip, dest_ip; +ULONG temp; +#endif + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 3.08 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a static ARP entry. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x00112233, 0x4456); + + if(status) + error_counter++; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + if(server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + ip_ptr = server_socket.nx_tcp_socket_ip_ptr; + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + NX_TCP_SYN_SIZE; + packet_ptr -> nx_packet_length = NX_TCP_SYN_SIZE; +#else + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_SYN); + packet_ptr -> nx_packet_length = sizeof(NX_TCP_SYN); +#endif + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + option_word_2 = option_word_1 + 1; + + /*Build TCP header. */ + tcp_header_ptr -> nx_tcp_header_word_0 = (ULONG) server_socket.nx_tcp_socket_port; + tcp_header_ptr -> nx_tcp_sequence_number = 1000; + tcp_header_ptr -> nx_tcp_acknowledgment_number = 0; + tcp_header_ptr -> nx_tcp_header_word_3 = NX_TCP_SYN_HEADER | NX_TCP_SYN_BIT | NX_TCP_ACK_BIT | (server_socket.nx_tcp_socket_rx_window_current); + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + *option_word_1 = NX_TCP_MSS_OPTION; + *option_word_2 = NX_TCP_OPTION_END; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + NX_CHANGE_ULONG_ENDIAN(*option_word_2); + + source = 0x01020305; + dest = 0x01020304; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &dest; + source_ip = &source; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = dest; + source_ip = source; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length + sizeof(NX_IPV4_HEADER); +#elif defined(__PRODUCT_NETX__) + packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length + sizeof(NX_IP_HEADER); +#endif + +#if defined(__PRODUCT_NETXDUO__) + ip_header_ptr = (NX_IPV4_HEADER *) packet_ptr -> nx_packet_prepend_ptr; +#elif defined(__PRODUCT_NETX__) + ip_header_ptr = (NX_IP_HEADER *) packet_ptr -> nx_packet_prepend_ptr; +#endif + + /*Build IP header. */ + ip_header_ptr -> nx_ip_header_word_0 = (NX_IP_VERSION | (0xFFFF & packet_ptr -> nx_packet_length)); +#ifdef NX_ENABLE_IP_ID_RANDOMIZATION + ip_header_ptr -> nx_ip_header_word_1 = (((ULONG)NX_RAND()) << NX_SHIFT_BY_16); +#else + ip_header_ptr -> nx_ip_header_word_1 = (ip_ptr -> nx_ip_packet_id++ << NX_SHIFT_BY_16); +#endif /* NX_ENABLE_IP_ID_RANDOMIZATION */ + ip_header_ptr -> nx_ip_header_word_2 = ((server_socket.nx_tcp_socket_time_to_live << NX_IP_TIME_TO_LIVE_SHIFT) | NX_IP_TCP); + ip_header_ptr -> nx_ip_header_source_ip = 0x01020305; + ip_header_ptr -> nx_ip_header_destination_ip = 0x01020304; + +#ifdef __PRODUCT_NETX__ + + /* Build the IP header checksum. */ + temp = ip_header_ptr -> nx_ip_header_word_0; + checksum = (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_word_1; + checksum += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_word_2; + checksum += (temp >> NX_SHIFT_BY_16); + temp = ip_header_ptr -> nx_ip_header_source_ip; + checksum += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + temp = ip_header_ptr -> nx_ip_header_destination_ip; + checksum += (temp >> NX_SHIFT_BY_16) + (temp & NX_LOWER_16_MASK); + + /* Add in the carry bits into the checksum. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Do it again in case previous operation generates an overflow. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | (NX_LOWER_16_MASK & (~checksum)); +#endif + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + +#ifdef __PRODUCT_NETXDUO__ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, 20, NULL, NULL); + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; +#endif + + advanced_packet_process_callback = my_packet_process_3_08; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_08; + + _nx_ip_packet_deferred_receive(ip_ptr, packet_ptr); + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (syn_ack_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_08(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* RST packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + return NX_TRUE; +} + +static void my_tcp_packet_receive_3_08(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + syn_ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_08_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.08 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_3_17_test.c b/test/regression/netxduo_test/netx_3_17_test.c new file mode 100644 index 00000000..9fe1a117 --- /dev/null +++ b/test/regression/netxduo_test/netx_3_17_test.c @@ -0,0 +1,469 @@ +/* 3.17 TCP in SYN-SENT state MUST send RST after receiving a segment carrying + an unacceptable ACK and send the SYN again, SEQ number is taken from SEG.ACK. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG data_packet_counter; +static ULONG rst_counter; +static ULONG ack_number; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *, ULONG, UINT, ULONG *, ULONG *); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_3_17_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + data_packet_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_3_17; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + if(client_socket.nx_tcp_socket_state != NX_TCP_SYN_SENT) + error_counter++; + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_17; + + tx_thread_resume(&ntest_1); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + tx_thread_resume(&ntest_1); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check for error. */ + if((error_counter) || (data_packet_counter != 1) || (rst_counter != 2) || (syn_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 3.17 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_17_2; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 10, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + tx_thread_suspend(&ntest_1); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; + +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#else +ULONG source_ip, dest_ip; +#endif + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + else if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) + { + syn_counter++; + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + else if((packet_ptr -> nx_packet_length == 50) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 40, MSG, 10))) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_acknowledgment_number); + + tcp_header_ptr ->nx_tcp_acknowledgment_number += 10; + ack_number = tcp_header_ptr ->nx_tcp_acknowledgment_number; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &server_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &server_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = server_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_3_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if((packet_ptr -> nx_packet_length == 30) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, 10))) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_acknowledgment_number); + + if(tcp_header_ptr ->nx_tcp_acknowledgment_number != client_socket.nx_tcp_socket_tx_sequence) + data_packet_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + } + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_3_17_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + syn_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + else if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + if(tcp_header_ptr -> nx_tcp_sequence_number != ack_number) + error_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.17 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_3_18_test.c b/test/regression/netxduo_test/netx_3_18_test.c new file mode 100644 index 00000000..0e6be36c --- /dev/null +++ b/test/regression/netxduo_test/netx_3_18_test.c @@ -0,0 +1,536 @@ +/* 3.18:TCP, in FINWAIT-1 state, + MUST return an ACK with proper SEQ and ACK numbers after recv a seg with OTW SEQ or unacc ACK number, + and remain in same state If the connection is in a synchronized state, + any unacceptable segment (out of window sequence number or unacceptible acknowledgment number) + must elicit only an empty acknowledgment segment containing the current send-sequence number + and an acknowledgment indicating the next sequence number expected to be received, + and the connection remains in the same state. */ + +/* Procedure + 1.Connect + 2.Server disconnect, then server state is FINWAIT1. + 3.Client sends a packet with OTW SEQ and acceptable ACK number to server. + 4.Client should receive an ACK with proper SEQ and ACK numbers + 5.Client sends a packet with proper OTW SEQ and unacceptable ACK number to server + 6.Client should receive an ACK with proper SEQ and ACK numbers */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#endif +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG ack_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_3_18_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_18_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + ack_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.18 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay FIN packet. */ + advanced_packet_process_callback = my_packet_process_3_18; + + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + if(server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_1) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_18; + + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_1) + error_counter++; + + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_1) + error_counter++; + + tx_thread_sleep(1); + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (fin_counter != 1) || (data_packet_counter != 2) || (ack_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_18_2; + + /* Allocate packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the first packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet2, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the second packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + client_socket.nx_tcp_socket_tx_sequence -= 41; + + /* Call disconnect to send a FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + + /* Pointer to TCP header. */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + if ((packet_ptr -> nx_packet_length - 40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 40, MSG, 20))) + { + if(data_packet_counter == 0) + { + /* OTW SEQ. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + tcp_header_ptr-> nx_tcp_sequence_number -= 100; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + } + else + { + /* Unacceptable ACK number. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + tcp_header_ptr-> nx_tcp_acknowledgment_number += 100; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + advanced_packet_process_callback = NX_NULL; + } + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + } + else + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT)) + { + fin_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + return NX_TRUE; +} + +static void my_tcp_packet_receive_3_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + if((packet_ptr -> nx_packet_length - 20 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, 20))) + { + /* Check whether client sends a packet with OTW SEQ and proper ACK number. */ + if (((header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) && + (header_ptr -> nx_tcp_acknowledgment_number + 1 == server_socket.nx_tcp_socket_tx_sequence)) + data_packet_counter++; + + /* Check whether client sends a packet with proper SEQ and unacceptable ACK number. */ + else if(((header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence) && + (header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) && + (header_ptr -> nx_tcp_acknowledgment_number + 1 != server_socket.nx_tcp_socket_tx_sequence)) + data_packet_counter ++; + + if (data_packet_counter == 2) + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +static void my_tcp_packet_receive_3_18_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + if(!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) &&(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)&&!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + if ((header_ptr -> nx_tcp_sequence_number == server_socket.nx_tcp_socket_tx_sequence) && + (header_ptr -> nx_tcp_acknowledgment_number == server_socket.nx_tcp_socket_rx_sequence)) + { + ack_counter++; + + if(ack_counter == 2) + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_18_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.18 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_3_19_test.c b/test/regression/netxduo_test/netx_3_19_test.c new file mode 100644 index 00000000..a269dd46 --- /dev/null +++ b/test/regression/netxduo_test/netx_3_19_test.c @@ -0,0 +1,514 @@ +/* 3.19:TCP, in FINWAIT-2 state, + MUST return an ACK with proper SEQ and ACK numbers after recv a seg with OTW SEQ or unacc ACK number, + and remain in same state If the connection is in a synchronized state, + any unacceptable segment (out of window sequence number or unacceptible acknowledgment number) + must elicit only an empty acknowledgment segment containing the current send-sequence number + and an acknowledgment indicating the next sequence number expected to be received, + and the connection remains in the same state. */ + +/* Procedure + 1.connect + 2.Server disconnect, then server state is FINWAIT2. + 3.Client sends a packet with OTW SEQ and acceptable ACK number to server. + 4.Client should receive an ACK with proper SEQ and ACK numbers + 5.Client sends a packet with proper OTW SEQ and unacceptable ACK number to server + 6.Client should receive an ACK with proper SEQ and ACK numbers */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#endif +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG ack_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_3_19_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_19_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.19 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + if(server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_2) + error_counter++; + + advanced_packet_process_callback = my_packet_process_3_19; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_19; + + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_2) + error_counter++; + + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_2) + error_counter++; + + tx_thread_sleep(1); + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (data_packet_counter != 2) || (ack_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_19_2; + + /* Allocate packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the first packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet2, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the second packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + client_socket.nx_tcp_socket_tx_sequence -= 41; + + /* Call disconnect to send a FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + /* Pointer to TCP header. */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + if ((packet_ptr -> nx_packet_length - 40 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 40, MSG, 20))) + { + if(data_packet_counter == 0) + { + /* OTW SEQ. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + tcp_header_ptr-> nx_tcp_sequence_number -= 100; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + } + else + { + /* Unacceptable ACK number. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + tcp_header_ptr-> nx_tcp_acknowledgment_number += 100; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + advanced_packet_process_callback = NX_NULL; + } + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + } + + return NX_TRUE; +} + +static void my_tcp_packet_receive_3_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + /* Check if client sends a packet with OTW SEQ and proper ACK number. */ + if((packet_ptr -> nx_packet_length - 20 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, 20))) + { + /* Check whether client sends a packet with OTW SEQ and proper ACK number. */ + if (((header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) && + (header_ptr -> nx_tcp_acknowledgment_number == server_socket.nx_tcp_socket_tx_sequence)) + data_packet_counter++; + + /* Check whether client sends a packet with proper SEQ and unacceptable ACK number. */ + else if(((header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence) && + (header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) && + (header_ptr -> nx_tcp_acknowledgment_number != server_socket.nx_tcp_socket_tx_sequence)) + data_packet_counter ++; + + if (data_packet_counter == 2) + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +static void my_tcp_packet_receive_3_19_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + if(!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + if ((header_ptr -> nx_tcp_sequence_number == server_socket.nx_tcp_socket_tx_sequence) && + (header_ptr -> nx_tcp_acknowledgment_number == server_socket.nx_tcp_socket_rx_sequence)) + { + ack_counter++; + + /* ACK packet has been processed. */ + if(ack_counter == 2) + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number) + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_19_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.19 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_3_20_test.c b/test/regression/netxduo_test/netx_3_20_test.c new file mode 100644 index 00000000..65132844 --- /dev/null +++ b/test/regression/netxduo_test/netx_3_20_test.c @@ -0,0 +1,486 @@ +/* 3.20:TCP, in CLOSING state, + MUST return an ACK with proper SEQ and ACK numbers after recv a seg with OTW SEQ or unacc ACK number, + and remain in same state If the connection is in a synchronized state, + any unacceptable segment (out of window sequence number or unacceptible acknowledgment number) + must elicit only an empty acknowledgment segment containing the current send-sequence number + and an acknowledgment indicating the next sequence number expected to be received, + and the connection remains in the same state. */ + +/* Procedure + 1.Connect + 2.Set server to CLOSING state + 3.Client sends a packet with OTW SEQ to server + 4.Client should receive an ACK with proper SEQ and ACK numbers + 5.Client sends a packet with unacceptable acknowledge number to server + 6.Client should receive an ACK with proper SEQ and ACK numbers */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); +#if defined(NX_DISABLE_RESET_DISCONNECT) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG ack_counter; +static ULONG otw_seq_counter; +static ULONG unaccept_ack_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_3_20_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_20_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + ack_counter =0; + otw_seq_counter = 0; + unaccept_ack_counter = 0; + + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.20 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_3_20; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_20; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_CLOSING) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_20_2; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + client_socket.nx_tcp_socket_tx_sequence++; + + _nx_tcp_packet_send_ack(&client_socket, (client_socket.nx_tcp_socket_tx_sequence - 1)); + + client_socket.nx_tcp_socket_tx_sequence++; + + _nx_tcp_packet_send_ack(&client_socket, (client_socket.nx_tcp_socket_tx_sequence - 1)); + + tx_thread_resume(&ntest_0); + + /* Determine if the test was successful. */ + if(error_counter || (ack_counter != 3) || fin_counter != 2 || otw_seq_counter != 1 || unaccept_ack_counter != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (fin_counter == 0)) + { + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + fin_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + else if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT)) + { + if(ack_counter == 1 && otw_seq_counter == 0) + { + /* OTW SEQ. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + tcp_header_ptr-> nx_tcp_sequence_number -= 100; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + } + else if(ack_counter == 2 && unaccept_ack_counter == 0) + { + /* Unacceptable ACK number. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + tcp_header_ptr-> nx_tcp_acknowledgment_number += 100; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; + +} + +static void my_tcp_packet_receive_3_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a FIN one. */ + if ((header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && ((header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT))) + { + fin_counter++; + } + else if (!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) &&(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + &&!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + if(server_socket.nx_tcp_socket_state == NX_TCP_CLOSING) + { + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + /* Check whether client sends a packet with OTW SEQ and proper ACK number. */ + if (((header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) && + (header_ptr -> nx_tcp_acknowledgment_number + 1 == server_socket.nx_tcp_socket_tx_sequence)) + otw_seq_counter++; + + /* Check whether client sends a packet with proper SEQ and unacceptable ACK number. */ + else if(((header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence) && + (header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) && + (header_ptr -> nx_tcp_acknowledgment_number + 1 != server_socket.nx_tcp_socket_tx_sequence)) + { + unaccept_ack_counter++; + + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + } + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +static void my_tcp_packet_receive_3_20_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (ack_counter == 0)) + { + ack_counter++; + } + else if(!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) &&(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)&&!(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + + if ((header_ptr -> nx_tcp_sequence_number == server_socket.nx_tcp_socket_tx_sequence) && + (header_ptr -> nx_tcp_acknowledgment_number == server_socket.nx_tcp_socket_rx_sequence)) + { + ack_counter++; + + if(ack_counter == 3) + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_20_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.20 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_3_21_test.c b/test/regression/netxduo_test/netx_3_21_test.c new file mode 100644 index 00000000..5f3bfb59 --- /dev/null +++ b/test/regression/netxduo_test/netx_3_21_test.c @@ -0,0 +1,550 @@ +/* 3.21:TCP, in LAST-ACK state, + MUST return an ACK with proper SEQ and ACK numbers after recv a seg with OTW SEQ or unacc ACK number, + and remain in same state If the connection is in a synchronized state, + any unacceptable segment (out of window sequence number or unacceptible acknowledgment number) + must elicit only an empty acknowledgment segment containing the current send-sequence number + and an acknowledgment indicating the next sequence number expected to be received, + and the connection remains in the same state. */ + +/* Procedure + 1.Connect. + 2.Set server socket to LAST_ACK state. + 3.Client sends a packet to server. + 4.Set the packet to an OTW packet in the callback function. + 5.Client should receive an ACK with proper SEQ and ACK numbers, and server socket should remain in LAST_ACK state. + 6.Client sends a packet to server. + 7.Set the packet to an unacceptable packet in the callback function. + 8.Client should receive an ACK with proper SEQ and ACK numbers, and server socket should remain in LAST_ACK state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#endif +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG ack_counter; +static ULONG fin_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_3_21_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_21_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + fin_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.21 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Suspend the thread ntest_0. */ + tx_thread_suspend(&ntest_0); + + if (server_socket.nx_tcp_socket_state != NX_TCP_CLOSE_WAIT) + error_counter++; + + /* Set the callback function. */ + advanced_packet_process_callback = my_packet_process_3_21; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + if(server_socket.nx_tcp_socket_state != NX_TCP_LAST_ACK) + error_counter++; + + /* Set the receive function to my_tcp_packet_receive_3_21. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_21; + + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_LAST_ACK) + error_counter++; + + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_LAST_ACK) + error_counter++; + + /* Set the port to NULL. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet1, *my_packet2; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Set client transmit number */ + client_socket.nx_tcp_socket_tx_sequence++; + + /* Send FIN */ + _nx_tcp_packet_send_fin(&client_socket,client_socket.nx_tcp_socket_tx_sequence - 1); + + /* Resume the thread ntest_0. */ + tx_thread_resume(&ntest_0); + + /* Replace the TCP receive function with my_tcp_packet_receive_3_21 for ip_1. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_21_2; + + /* Create 2 packet */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send packet1 */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /*Resume the thread ntest_0. */ + tx_thread_resume(&ntest_0); + + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet2, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send packet2 */ + status = nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter == 0) && (fin_counter == 1) && (ack_counter == 2) && (data_packet_counter == 2)) + { + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +ULONG checksum = 0; +NX_TCP_HEADER *tcp_header_ptr; + +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + /* Point to TCP header */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr+20); + + /* The data segment process. */ + if(packet_ptr -> nx_packet_length - 40 == 20) + { + if (data_packet_counter == 0) + { + /* Chang the sequence number. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + tcp_header_ptr -> nx_tcp_sequence_number -= 100; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + } + else if (data_packet_counter == 1) + { + /* Change the ACK number. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + tcp_header_ptr -> nx_tcp_acknowledgment_number += 100; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + advanced_packet_process_callback = NULL; + } + + client_socket.nx_tcp_socket_tx_sequence -= 20; + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + } + /* The flag packet process. */ + else + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + client_socket.nx_tcp_socket_rx_sequence++; + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + fin_counter++; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + } + + return NX_TRUE; +} + +static void my_tcp_packet_receive_3_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr->nx_packet_prepend_ptr; + + /* Check if it is a segment. */ + if((packet_ptr -> nx_packet_length - 20 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, 20))) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + /* Check if client sends a packet with OTW SEQ and proper ACK number. */ + if(((tcp_header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (tcp_header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current))&& + (tcp_header_ptr ->nx_tcp_acknowledgment_number == server_socket.nx_tcp_socket_tx_sequence) ) + data_packet_counter ++; + + /* Check if client sends a packet with proper SEQ and unacceptable ACK number. */ + else if(((tcp_header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence) && + (tcp_header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current))&& + (tcp_header_ptr ->nx_tcp_acknowledgment_number != server_socket.nx_tcp_socket_tx_sequence)) + data_packet_counter ++; + + if (data_packet_counter == 2) + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_3_21_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)packet_ptr->nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + if ((tcp_header_ptr -> nx_tcp_acknowledgment_number == server_socket.nx_tcp_socket_rx_sequence) && + (tcp_header_ptr -> nx_tcp_sequence_number == server_socket.nx_tcp_socket_tx_sequence)) + { + ack_counter++; + + if (ack_counter == 2) + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_21_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.21 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_3_23_test.c b/test/regression/netxduo_test/netx_3_23_test.c new file mode 100644 index 00000000..2655abfe --- /dev/null +++ b/test/regression/netxduo_test/netx_3_23_test.c @@ -0,0 +1,535 @@ +/* 3.23:TCP, in CLOSE-WAIT state, + MUST return an ACK with proper SEQ and ACK numbers after recv a seg with OTW SEQ or unacc ACK number, + and remain in same state If the connection is in a synchronized state, + any unacceptable segment (out of window sequence number or unacceptible acknowledgment number) + must elicit only an empty acknowledgment segment containing the current send-sequence number + and an acknowledgment indicating the next sequence number expected to be received, + and the connection remains in the same state. */ + +/* Procedure + 1.Connect + 2.Set server socket to CLOSE_WAIT state + 3.Client sends a packet with OTW SEQ to server + 4.Client should receive an ACK with proper SEQ and ACK numbers, and server socket should remain in CLOSE_WAIT state + 5.Client sends a packet with unacceptable acknowledge numbers + 6.Client should receive an ACK with proper SEQ and ACK numbers, and server socket should remain in CLOSE_WAIT state */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_ipv4.h" +#endif +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG ack_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_3_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_3_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_3_23_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_23_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.23 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + /* Suspend the thread ntest_0. */ + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_CLOSE_WAIT) + error_counter++; + + /* Set the receive function to my_tcp_packet_receive_3_23. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_23; + + /* Suspend the thread ntest_0. */ + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_CLOSE_WAIT) + error_counter++; + + /* Suspend the thread ntest_0. */ + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_CLOSE_WAIT) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + + /* Set the port to NULL. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet1, *my_packet2; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status != NX_SUCCESS) + error_counter++; + + /* Set client transmit number */ + client_socket.nx_tcp_socket_tx_sequence++; + + /* Send FIN */ + _nx_tcp_packet_send_fin(&client_socket,client_socket.nx_tcp_socket_tx_sequence - 1); + + tx_thread_resume(&ntest_0); + + /* Set the callback function. */ + advanced_packet_process_callback = my_packet_process_3_23; + + /* Replace the TCP receive function with my_tcp_packet_receive_3_23 for ip_1. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_3_23_2; + + /* Create packet1 */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send packet1 */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Resume the thread ntest_0. */ + tx_thread_resume(&ntest_0); + + /* Create packet2. */ + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet2, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send packet2 */ + status = nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Resume the thread ntest_0. */ + tx_thread_resume(&ntest_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter == 0) && (ack_counter == 2) && (data_packet_counter == 2)) + { + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_3_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +ULONG checksum = 0; +NX_TCP_HEADER *tcp_header_ptr; + +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +#else +#error "NetX Product undefined." +#endif + + /* Point to TCP header */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + + /* The data segment process. */ + if(packet_ptr -> nx_packet_length - 40 == 20) + { + if (data_packet_counter == 0) + { + /* Chang the sequence number. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + tcp_header_ptr -> nx_tcp_sequence_number -= 100; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + } + else if (data_packet_counter == 1) + { + /* Change the ACK number. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + tcp_header_ptr -> nx_tcp_acknowledgment_number += 100; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + advanced_packet_process_callback = NULL; + + } + client_socket.nx_tcp_socket_tx_sequence -= 20; + + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + } + + return NX_TRUE; +} + +static void my_tcp_packet_receive_3_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr->nx_packet_prepend_ptr; + + + /* Check if it is a segment. */ + if((packet_ptr -> nx_packet_length - 20 == 20) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, 20))) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + /* Check if client sends a packet with OTW SEQ and proper ACK number. */ + if(((tcp_header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (tcp_header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) && + (tcp_header_ptr ->nx_tcp_acknowledgment_number == server_socket.nx_tcp_socket_tx_sequence) ) + data_packet_counter ++; + + /* Check if client sends a packet with proper SEQ and unacceptable ACK number. */ + else if(((tcp_header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence) && + (tcp_header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) && + (tcp_header_ptr ->nx_tcp_acknowledgment_number != server_socket.nx_tcp_socket_tx_sequence)) + data_packet_counter ++; + + if (data_packet_counter == 2) + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_3_23_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)packet_ptr->nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + if ((tcp_header_ptr -> nx_tcp_acknowledgment_number == server_socket.nx_tcp_socket_rx_sequence) && + (tcp_header_ptr -> nx_tcp_sequence_number == server_socket.nx_tcp_socket_tx_sequence)) + { + ack_counter++; + + if (ack_counter == 2) + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_3_23_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 3.23 Test........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_4_01_test.c b/test/regression/netxduo_test/netx_4_01_test.c new file mode 100644 index 00000000..617c8d59 --- /dev/null +++ b/test/regression/netxduo_test/netx_4_01_test.c @@ -0,0 +1,376 @@ +/* 4.01 TCP in a CLOSED state, MUST ignore a RST control message. */ +/* An incoming segment containing a RST is discarded. */ + +/* Procedure +1.Client connect with server. +2.Client becomes CLOSED state. +3.Server sends a RST packet to Client. +4.Client should ignore the incoming RST packet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_4_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_4_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Let thread 1 run. */ + tx_thread_relinquish(); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send a SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error*/ + if(status) + error_counter++; + + /* The client state should be in ESTABLISHED state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + /* Modify the Client state to NX_TCP_CLOSED. */ + client_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + + /* Monitor the RST message from Server. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_4_01; + + /* Monitor the TCP message from Client. */ + advanced_packet_process_callback = my_packet_process_4_01; + + /* Let Server socket send RST message to Client Socket. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* The client state should be in CLOSED state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error*/ + if(status) + error_counter++; + + /* Delete the socket*/ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error*/ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_TCP_HEADER header_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.01 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* The client state should be in ESTABLISHED state. */ + if(server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + /* Let thread 0 run. */ + tx_thread_relinquish(); + + /* Fake one TCP header to send RST packet. */ + header_ptr.nx_tcp_header_word_3 = NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + header_ptr.nx_tcp_acknowledgment_number = 1; + header_ptr.nx_tcp_sequence_number = 1; + + /* Send the RST packet to Client. */ + _nx_tcp_packet_send_rst(&server_socket, &header_ptr); + + /* Call disconnect to send a SYN. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisted on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_4_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Set the TCP header. */ + header_ptr = (NX_TCP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a RST packet. */ + if ((header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + /* Increase the RST counter. */ + rst_counter++; + + /* Cover the tcp receive function. */ + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Let Client socket receive the RST packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT my_packet_process_4_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +#ifdef __PRODUCT_NETXDUO__ +NX_IPV4_HEADER *ip_header_ptr; +#else +NX_IP_HEADER *ip_header_ptr; +#endif + + /* Set the IP header. */ +#ifdef __PRODUCT_NETXDUO__ + ip_header_ptr = (NX_IPV4_HEADER *) packet_ptr -> nx_packet_prepend_ptr; +#else + ip_header_ptr = (NX_IP_HEADER *) packet_ptr -> nx_packet_prepend_ptr; +#endif + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Check if the source address is 1.2.3.4. */ + if (ip_header_ptr -> nx_ip_header_source_ip == IP_ADDRESS(1, 2, 3, 4)) + { + + /* Client socket shouldn't send any packet in response. */ + error_counter ++; + } + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.01 Test........................................N/A\n"); + test_control_return(3); +} + +#endif diff --git a/test/regression/netxduo_test/netx_4_17_test.c b/test/regression/netxduo_test/netx_4_17_test.c new file mode 100644 index 00000000..a1f1ce71 --- /dev/null +++ b/test/regression/netxduo_test/netx_4_17_test.c @@ -0,0 +1,191 @@ +/* 4.17 For an active OPEN call with unspecified foreign socket, +TCP MUST return error: foreign socket unspecified. */ + +/* Procedure +1. Client connect with foreign socket. +2. Judge the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_17_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status = nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.17 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.17 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_4_21_test.c b/test/regression/netxduo_test/netx_4_21_test.c new file mode 100644 index 00000000..a70baeda --- /dev/null +++ b/test/regression/netxduo_test/netx_4_21_test.c @@ -0,0 +1,328 @@ +/* 4.21 If an OPEN call arrives on state SYN-SENT, TCP MUST return error: connection already exists. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_4_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_21_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.21 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay SYN packet. */ + advanced_packet_process_callback = my_packet_process_4_21; + + /* Call connect to send an SYN. */ + nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Check state. */ + if (client_socket.nx_tcp_socket_state == NX_TCP_SYN_SENT) + { + /* Try to connect to the server. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* NX_NOT_CLOSED is equal to the message of "error: connection already exists". */ + if(status != NX_NOT_CLOSED) + error_counter++; + } + else + error_counter++; + + /* Let the server to disconnect. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (syn_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_4_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* Check if it is a SYN packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + syn_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* SYN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_21_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.21 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_4_23_test.c b/test/regression/netxduo_test/netx_4_23_test.c new file mode 100644 index 00000000..bf0a43ec --- /dev/null +++ b/test/regression/netxduo_test/netx_4_23_test.c @@ -0,0 +1,331 @@ +/* 4.23 If an OPEN call arrives on state SYN-RCVD, TCP MUST return error: connection already exists. */ + +/* Procedure +1. Client sends a SYN packet and becomes SYN_SENT state. +2. Server receives the SYN packet and becomes SYN_RCVD state. +3. Server calls the OPEN call. +4. Judge the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_4_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_23_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_0); + + /* Send packet in SYN_RECEIVED status. */ + if(server_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) + { + + status = nx_tcp_client_socket_connect(&server_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* NX_NOT_CLOSED is equal to the message of "error: connection already exists". */ + if(status != NX_NOT_CLOSED) + error_counter++; + } + + status = nx_tcp_socket_state_wait(&server_socket, NX_TCP_ESTABLISHED, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.23 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the timeout error occurred. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_4_23; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /*syn_ack_counter =1.error_counter=0. */ + if(error_counter == 0) + { + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_4_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Point to the TCP HEADER */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Intercept the SYN+ACK message */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* SYN+ACK packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + + tx_thread_resume(&ntest_0); + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_23_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.23 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_4_24_test.c b/test/regression/netxduo_test/netx_4_24_test.c new file mode 100644 index 00000000..4892d9a1 --- /dev/null +++ b/test/regression/netxduo_test/netx_4_24_test.c @@ -0,0 +1,293 @@ +/* 4.24 If an OPEN call arrives on state ESTABLISHED, TCP MUST return error: connection already exists. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#define DEMO_STACK_SIZE 2048 +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_24_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status = nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.24 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + /* Check for error. */ + if(status) + error_counter++; + + /* Try to connect to the server again. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 0); + + /* NX_NOT_CLOSED is equal to the message of "error: connection already exists". */ + if(status != NX_NOT_CLOSED) + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check the error. */ + if( !error_counter ) + { + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_24_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.24 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_4_25_test.c b/test/regression/netxduo_test/netx_4_25_test.c new file mode 100644 index 00000000..518daa36 --- /dev/null +++ b/test/regression/netxduo_test/netx_4_25_test.c @@ -0,0 +1,315 @@ +/* 4.25 If an OPEN call arrives on state FINWAIT-1, TCP MUST return error: connection already exists. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 +#include "nx_ram_network_driver_test_1500.h" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +extern ULONG packet_gather; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_4_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_25_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 1", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 0", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status = nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.25 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let the driver drop the FIN packet. */ + advanced_packet_process_callback = my_packet_process_4_25; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Determine if the status is valid. */ + if(status) + error_counter++; + + /* An OPEN call arrives at the state NX_TCP_FIN_WAIT_1. */ + if (client_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_1) + { + status = nx_tcp_client_socket_connect(&server_socket, IP_ADDRESS(1, 2, 3, 5), 12, 0); + + if (status != NX_NOT_CLOSED) + error_counter++; + } + else + error_counter++; + + /* Resume the thread. */ + tx_thread_resume(&ntest_1); + + /* Determine if the test was successful. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Suspend the thread. */ + tx_thread_suspend(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_4_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* SYN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_25_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.25 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_4_26_test.c b/test/regression/netxduo_test/netx_4_26_test.c new file mode 100644 index 00000000..7de695a6 --- /dev/null +++ b/test/regression/netxduo_test/netx_4_26_test.c @@ -0,0 +1,293 @@ +/* 4.26 If an OPEN call arrives on state FINWAIT-2, TCP MUST return error: connection already exists. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_26_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Connect to the server socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Determine if the status is valid. */ + if(status) + error_counter++; + + /* An OPEN call arrives when the client socket is in FIN_WAIT_2 state. */ + if(client_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_2) + { + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* NX_NOT_CLOSED is equal to the message of "error: connection already exists". */ + if( status != NX_NOT_CLOSED ) + { + error_counter++; + } + } + else + error_counter++; + + /* Resume the ntest_1 thread. */ + tx_thread_resume(&ntest_1); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.26 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Suspend the ntest_1 thread. */ + tx_thread_suspend(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the server socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_26_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.26 Test........................................N/A\n"); + test_control_return(3); + +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_4_27_test.c b/test/regression/netxduo_test/netx_4_27_test.c new file mode 100644 index 00000000..769be0ae --- /dev/null +++ b/test/regression/netxduo_test/netx_4_27_test.c @@ -0,0 +1,297 @@ +/* 4.27 If an OPEN call arrives on state CLOSE-WAIT, TCP MUST return error: connection already exists. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_27_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status = nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.27 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the timeout error occurred. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check the state */ + if(client_socket.nx_tcp_socket_state == NX_TCP_CLOSE_WAIT) + { + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 0); + + /* NX_NOT_CLOSED is equal to the message of "error: connection already exists". */ + if( status != NX_NOT_CLOSED ) + error_counter++; + } + else + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_27_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.27 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_4_28_test.c b/test/regression/netxduo_test/netx_4_28_test.c new file mode 100644 index 00000000..98f8d4e0 --- /dev/null +++ b/test/regression/netxduo_test/netx_4_28_test.c @@ -0,0 +1,341 @@ +/* 4.28 If an OPEN call arrives on state CLOSING, TCP MUST return error: connection already exists. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ +static ULONG error_counter; +static ULONG fin_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_4_28(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_4_28(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_28_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status += nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.28 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver drop the FIN packet. */ + advanced_packet_process_callback = my_packet_process_4_28; + + /*Let the client socket to check the FIN segment*/ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_4_28; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Resume the thread. */ + tx_thread_resume(&ntest_1); + + if (client_socket.nx_tcp_socket_state == NX_TCP_CLOSING) + { + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 0); + + if (status != NX_NOT_CLOSED) + error_counter++; + } + else + error_counter++; + + /* Let the server thread finish first. */ + tx_thread_suspend(&ntest_0); + + /* Determine if the test was successful. */ + if ((error_counter) || (fin_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_4_28(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + fin_counter++; + + /* Delay the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +static void my_tcp_packet_receive_4_28(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a FIN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + + /* It is a FIN packet. */ + fin_counter++; + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_28_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.28 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_4_29_test.c b/test/regression/netxduo_test/netx_4_29_test.c new file mode 100644 index 00000000..620bc8e9 --- /dev/null +++ b/test/regression/netxduo_test/netx_4_29_test.c @@ -0,0 +1,301 @@ +/* 4.29 If an OPEN call arrives on state LAST-ACK, TCP MUST return error: connection already exists. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_4_29(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_29_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status += nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.29 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay SYN packet. */ + advanced_packet_process_callback = my_packet_process_4_29; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + if(client_socket.nx_tcp_socket_state == NX_TCP_LAST_ACK) + { + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 0); + + /* NX_NOT_CLOSED is equal to the message of "error: connection already exists". */ + if (status != NX_NOT_CLOSED) + error_counter++; + } + else + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_4_29(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* The FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_4_29_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 4.29 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_5_18_test.c b/test/regression/netxduo_test/netx_5_18_test.c new file mode 100644 index 00000000..b76c28d1 --- /dev/null +++ b/test/regression/netxduo_test/netx_5_18_test.c @@ -0,0 +1,195 @@ +/* 5.18 If a SEND call arrives on CLOSED state, and user has got proper access to such conn, TCP MUST return "error: connection does not exist". */ + +/* Procedure + 1. Client bind. + 2. Client allocates a packet and sends the packet. + 3. TCP return "NX_NOT CONNECTED". */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_18_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 5.18 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + +#if defined(__PRODUCT_NETXDUO__) + client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; +#endif + + /*An SEND call arrives when thc client socket is in NX_TCP_CLOSED state. */ + if(client_socket.nx_tcp_socket_state == NX_TCP_CLOSED) + { + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Release the packet. */ + nx_packet_release(my_packet); + } + else + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_18_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 5.18 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_5_19_test.c b/test/regression/netxduo_test/netx_5_19_test.c new file mode 100644 index 00000000..130f27b5 --- /dev/null +++ b/test/regression/netxduo_test/netx_5_19_test.c @@ -0,0 +1,327 @@ +/* 5.19 If SEND call arrives on state FINWAIT-1, TCP MUST return error: connection closing. */ + +/* Procedure + 1. Connection. + 2. Client calls disconnect and sends a FIN packet.. + 3. Client interrupts the FIN packet and calls send command. + 4. Check the state of client is FIN_WAIT_1 and the status is NX_NOT_CONNECTED. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_5_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_19_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 5.19 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay FIN packet. */ + advanced_packet_process_callback = my_packet_process_5_19; + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* A SEND Call arrives when client socket is in NX_TCP_WAIT_1 state.*/ + if(client_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_1) + { + /* Create a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, "01012345678920123456", 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status != NX_NOT_CONNECTED) + error_counter++; + + } + else + error_counter++; + + /* Resume the ntest_1 thread. */ + tx_thread_resume(&ntest_1); +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_5_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_19_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 5.19 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_5_20_test.c b/test/regression/netxduo_test/netx_5_20_test.c new file mode 100644 index 00000000..ef218b13 --- /dev/null +++ b/test/regression/netxduo_test/netx_5_20_test.c @@ -0,0 +1,303 @@ +/* 5.20 If SEND call arrives on state FINWAIT-2, TCP MUST return error: connection closing. */ + +/* Procedure +1. Connection. +2. Client calls disconnect and sends a FIN packet.. +3. Server replies an ACK packet. +4. Client receives the ACK packet and calls send command. +5. Check the state of client is FIN_WAIT_2 and the status is NX_NOT_CONNECTED. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_20_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 5.20 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* A SEND call arrives when the client server is in FIN_WAIT_2 state. */ + if(server_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_2) + { + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, "01012345678920123456", 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status != NX_NOT_CONNECTED) + error_counter++; + } + else + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten the server socket. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the server socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_20_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 5.20 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_5_21_test.c b/test/regression/netxduo_test/netx_5_21_test.c new file mode 100644 index 00000000..bfc6b980 --- /dev/null +++ b/test/regression/netxduo_test/netx_5_21_test.c @@ -0,0 +1,202 @@ +/* 5.21 If a SEND call arrives on LISTEN state, and foreign socket was not specified, TCP MUST return "error: foreign socket unspecified". */ + +/* Procedure +1. Create server socket and listen. +2. Allocates a packet and sends the packet. +3. TCP return "NX_NOT_BOUND". */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_21_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 5.21 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /*An SEND call arrives when the server socket is in NX_TCP_LISTEN_STATE state. */ + if(server_socket.nx_tcp_socket_state == NX_TCP_LISTEN_STATE) + { + /* Create a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, "01012345678920123456", 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + server_socket.nx_tcp_socket_mss = 100; + +#if defined(__PRODUCT_NETXDUO__) + server_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; +#endif + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if(status == NX_SUCCESS) + error_counter++; + } + else + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_21_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 5.21 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_5_22_test.c b/test/regression/netxduo_test/netx_5_22_test.c new file mode 100644 index 00000000..c1365f60 --- /dev/null +++ b/test/regression/netxduo_test/netx_5_22_test.c @@ -0,0 +1,357 @@ +/* 5.22 f SEND call arrives on state CLOSING, TCP MUST return "error: connection closing". */ + +/* Procedure + 1. Connection. + 2. Client calls disconnect and sends a FIN packet.. + 3. Server interrupts the FIN packet and call disconnect command. + 4. Client receives the FIN packet and becomes CLOSING state. + 5. Client calls send command and checks the status is NX_NOT_CONNECTED. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined (NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG fin_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_5_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_5_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_22_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter =0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 5.22 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay the FIN packet. */ + advanced_packet_process_callback = my_packet_process_5_22; + + /*Let the client socket to check the FIN segment*/ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_5_22; + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Resume the thread. */ + tx_thread_resume(&ntest_1); + + if (client_socket.nx_tcp_socket_state == NX_TCP_CLOSING) + { + + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, "01012345678920123456", 20, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status != NX_NOT_CONNECTED) + error_counter++; + } + else + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*n Suspend the ntest_1 thread. */ + tx_thread_suspend(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccept the socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter !=2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_5_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + fin_counter++; + + /* Delay the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* SYN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +static void my_tcp_packet_receive_5_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + + /* It is a SYN packet. */ + fin_counter++; + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_22_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 5.22 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_5_23_test.c b/test/regression/netxduo_test/netx_5_23_test.c new file mode 100644 index 00000000..cd3ef955 --- /dev/null +++ b/test/regression/netxduo_test/netx_5_23_test.c @@ -0,0 +1,318 @@ +/* 5.23 If SEND call arrives on state LAST-ACK, TCP MUST return "error: connection closing". */ + +/* Procedure + 1. Connection. + 2. Client calls disconnect and sends a FIN packet.. + 3. Server replies an ACK packet and calls disconnect command. + 4. Server becomes LSAT_ACK state. + 5. Server calls send command and checks the status is NX_NOT_CONNECTED. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_5_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_23_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 5.23 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay SYN packet. */ + advanced_packet_process_callback = my_packet_process_5_23; + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Check the state of server is LAST_ACK. */ + if (client_socket.nx_tcp_socket_state == NX_TCP_LAST_ACK) + { + /* Create a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, "01012345678920123456", 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status != NX_NOT_CONNECTED) + error_counter++; + } + else + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_5_23(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_23_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 5.23 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_5_24_test.c b/test/regression/netxduo_test/netx_5_24_test.c new file mode 100644 index 00000000..a162dc20 --- /dev/null +++ b/test/regression/netxduo_test/netx_5_24_test.c @@ -0,0 +1,383 @@ +/* 5.24 If a SEND call arrives on SYN-SENT state, TCP MAY queue the request and send it after entering ESTABLISHED state. */ + +/* Procedure + 1. Client sends a SYN packet and becomes SYN_SENT state. + 2. Client calls the send command. + 3. Check the status, test error. + 4. After entering ESTABLISHED state, check if client sends the packet.*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_5_24(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_24_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 5.24 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay SYN packet. */ + advanced_packet_process_callback = my_packet_process_5_24; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Check state. */ + if (client_socket.nx_tcp_socket_state == NX_TCP_SYN_SENT) + { + /* Create a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, "01012345678920123456", 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + } + else + error_counter++; + + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (syn_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(data_packet_counter != 1) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *rcv_packet_ptr; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(client_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED && server_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) + { + status = nx_tcp_socket_receive(&server_socket, &rcv_packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + if(status == NX_SUCCESS) + { + data_packet_counter ++; + + /* Check data length */ + if(rcv_packet_ptr -> nx_packet_length != 20) + error_counter++; + + /* Check received data. */ + if(memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, "01012345678920123456", 20)) + error_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + } + else + error_counter++; + + /* Let client thread disconnect first. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_5_24(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* Check if it is a SYN packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + syn_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* SYN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_24_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 5.24 Test........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_5_25_test.c b/test/regression/netxduo_test/netx_5_25_test.c new file mode 100644 index 00000000..c8f4ba7e --- /dev/null +++ b/test/regression/netxduo_test/netx_5_25_test.c @@ -0,0 +1,380 @@ +/* 5.25 If a SEND call arrives on SYN-RCVD state, TCP MAY queue the request and send it after entering ESTABLISHED state. */ + +/* Procedure +1. Client sends a SYN packet and becomes SYN_SENT state. +2. Server receives the SYN packet and becomes SYN_RCVD state. +3. Server calls the send command. +4. Check the status, test error. +5. After entering ESTABLISHED state, check if server sends the packet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_5_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_25_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 5.25 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay SYN+ACK packet. */ + advanced_packet_process_callback = my_packet_process_5_25; + + /* Accept a client socket connection. */ + nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_0); + + /* Send packet in SYN_RECEIVED status. */ + if (server_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED && + client_socket.nx_tcp_socket_state == NX_TCP_SYN_SENT) + { + /* Create a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, "01012345678920123456", 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + } + + status = nx_tcp_socket_state_wait(&server_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Sleep to let client thread run. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *rcv_packet_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_receive(&client_socket, &rcv_packet_ptr, NX_IP_PERIODIC_RATE); + + if(!status) + { + data_packet_counter ++; + + /* Check data length */ + if(rcv_packet_ptr -> nx_packet_length != 20) + error_counter++; + + /* Check received data. */ + if(memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, "01012345678920123456", 20)) + error_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + /* Let client thread disconnect first. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (syn_ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if (data_packet_counter != 1) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_5_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if(packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a SYN+ACK packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + syn_ack_counter++; + + /* Drop the SYN packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + /* SYN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + + tx_thread_resume(&ntest_0); + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_5_25_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 5.25 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_6_17_test.c b/test/regression/netxduo_test/netx_6_17_test.c new file mode 100644 index 00000000..1f1be647 --- /dev/null +++ b/test/regression/netxduo_test/netx_6_17_test.c @@ -0,0 +1,337 @@ +/* 6.17 If RECEIVE call arrives on state CLOSING, TCP MUST return error: connection closing. */ + +/* Procedure + 1. Client connect with Server. + 2. Server call disconnect, then Server state is FINWAIT1. + 3. CLient call disconnect,then Server state is CLOSING. + 4. Server call receive function. + 5. Judge the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_6_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_6_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.17 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_6_17; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_6_17; + + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state == NX_TCP_CLOSING) + { + /* Server call receive. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 50); + + if(status != NX_NOT_CONNECTED) + error_counter++; + } + else + error_counter++; + + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + tx_thread_resume(&ntest_0); + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_6_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + /* It is a FIN packet. */ + fin_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_6_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + fin_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.17 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_6_18_test.c b/test/regression/netxduo_test/netx_6_18_test.c new file mode 100644 index 00000000..7ac804e5 --- /dev/null +++ b/test/regression/netxduo_test/netx_6_18_test.c @@ -0,0 +1,171 @@ +/* 6.18 If RECEIVE call arrives on CLOSED state, and the user has got access to such conn, TCP MUST return error: connection does not exist. */ + +/* Procedure + 1. Client bind. + 2. Client calls receive command. + 3. TCP return "NX_NOT_CONNECTED". */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_IPV4) + + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_18_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 6.18 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check the state of the TCP client. */ + if ( client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Call receive. */ + status = nx_tcp_socket_receive(&client_socket, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_18_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.18 Test........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_6_20_test.c b/test/regression/netxduo_test/netx_6_20_test.c new file mode 100644 index 00000000..414dcfb0 --- /dev/null +++ b/test/regression/netxduo_test/netx_6_20_test.c @@ -0,0 +1,385 @@ +/* 6.20 If a RECEIVE call arrives on SYN-SENT state, TCP MAY queue the request and for processing after entering ESTABLISHED state. */ + +/* Procedure +1. Client sends a SYN packet and becomes SYN_SENT state. +2. Client calls the receive command. +3. Check the status, test error. +4. After entering ESTABLISHED state, check if client receives the packet.*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG data_packet_counter; +static UINT rcv_status; +static NX_PACKET *my_packet; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_6_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_20_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + data_packet_counter = 0; + rcv_status = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + printf("NetX Test: TCP Spec 6.20 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay SYN packet. */ + advanced_packet_process_callback = my_packet_process_6_20; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + if (client_socket.nx_tcp_socket_state != NX_TCP_SYN_SENT) + error_counter++; + + /* Call a receive function! */ + rcv_status = nx_tcp_socket_receive(&client_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(rcv_status == NX_SUCCESS) + { + /* Check received data and the data length. */ + if((packet_ptr -> nx_packet_length != 20) || (memcmp(packet_ptr -> nx_packet_prepend_ptr, MSG, 20))) + error_counter++; + else + data_packet_counter ++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + tx_thread_resume(&ntest_1); + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (syn_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if((rcv_status != NX_SUCCESS) || (data_packet_counter != 1)) + { + printf("WARNING!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if((client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) || (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + error_counter++; + + /* Create a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Disconnect the client socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_6_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* Check if it is a SYN packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + syn_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* SYN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_20_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.20 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_6_22_01_test.c b/test/regression/netxduo_test/netx_6_22_01_test.c new file mode 100644 index 00000000..5f52dd19 --- /dev/null +++ b/test/regression/netxduo_test/netx_6_22_01_test.c @@ -0,0 +1,387 @@ +/* 6.22.01 If RECEIVE call arrives in ESTABLISHED or FINWAIT-1 state, + TCP MUST reassemble queued incoming segments and return to the application. */ + +/* Procedure + 1. Client connect with Server, then Client state is ESTABLISHED. + 2. Client call receive function, then judge the status. + 3. Client call disconnect, and delay a fin packet, then Client state is FIN-WAIT-1. + 4. Client call receive function, then check the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG_1 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define MSG_2 "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_6_22_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_22_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *rcv_packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.22.01 Test....................................."); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the timeout error occurred. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check client state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + /* Call socket receive. */ + status = nx_tcp_socket_receive(&client_socket, &rcv_packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status != NX_SUCCESS) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == 20) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG_1, 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + /* Let driver delay the FIN packet. */ + advanced_packet_process_callback = my_packet_process_6_22_01; + + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Check client state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_1) + error_counter++; + + /* Call socket receive. */ + status = nx_tcp_socket_receive(&client_socket, &rcv_packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status != NX_SUCCESS) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == 20) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG_2, 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + tx_thread_resume(&ntest_1); +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create three packets. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet1, MSG_1, 20, &pool_0, NX_IP_PERIODIC_RATE); + status += nx_packet_data_append(my_packet2, MSG_2, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet1, NX_IP_PERIODIC_RATE); + status += nx_tcp_socket_send(&server_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if(error_counter || (fin_counter != 1) || (data_packet_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_6_22_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT)) + { + + fin_counter++; + + /* Delay 1 seconds. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_22_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.22.01 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_6_22_02_test.c b/test/regression/netxduo_test/netx_6_22_02_test.c new file mode 100644 index 00000000..406999f3 --- /dev/null +++ b/test/regression/netxduo_test/netx_6_22_02_test.c @@ -0,0 +1,340 @@ +/* 6.22.02 If RECEIVE call arrives in FINWAIT-2 state, + TCP MUST reassemble queued incoming segments and return to the application. */ + +/* Procedure + 1. Client connect with Server, then Client state is ESTABLISHED. + 2. Client call disconnect without waiting, then Client state is FIN-WAIT-2.. + 3. Client call receive function,then judge the status. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_22_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *rcv_packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.22.02 Test....................................."); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the timeout error occurred. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Check client state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_2) + error_counter++; + + /* Call socket receive. */ + status = nx_tcp_socket_receive(&client_socket, &rcv_packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status != NX_SUCCESS) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == 20) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + + tx_thread_resume(&ntest_1); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if(error_counter || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create three packets. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_22_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.22.02 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_6_23_test.c b/test/regression/netxduo_test/netx_6_23_test.c new file mode 100644 index 00000000..d93375a9 --- /dev/null +++ b/test/regression/netxduo_test/netx_6_23_test.c @@ -0,0 +1,325 @@ +/* 6.23 If RECEIVE call arrives on CLOSE-WAIT state and there is data awaiting delivery, TCP MUST return the data to the application. */ + +/* Procedure + 1. Connection. + 2. Server sends a data packet. + 3. Server calls disconnect command and sends a FIN packet. + 4. Client replies the FIN packet and becomes CLOSE_WAIT state. + 5. Client calls receive command and checks the status is SUCCESS. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_23_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *rcv_packet_ptr; + + printf("NetX Test: TCP Spec 6.23 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(client_socket.nx_tcp_socket_state == NX_TCP_CLOSE_WAIT) + { + /* Client call receive. */ + status = nx_tcp_socket_receive(&client_socket, &rcv_packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + if(status != NX_SUCCESS) + error_counter++; + else + { + /* Check data length and payload */ + if((rcv_packet_ptr -> nx_packet_length == 20) && (!memcmp(rcv_packet_ptr -> nx_packet_prepend_ptr, MSG, 20))) + data_packet_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet_ptr); + } + } + else + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (data_packet_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_23_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.23 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_6_24_test.c b/test/regression/netxduo_test/netx_6_24_test.c new file mode 100644 index 00000000..975e13ce --- /dev/null +++ b/test/regression/netxduo_test/netx_6_24_test.c @@ -0,0 +1,292 @@ +/* 6.24 If RECEIVE call arrives on CLOSE-WAIT state and there is no data awaiting delivery, TCP MUST respond error: connection closing to the application. */ + +/* Procedure + 1. Connection. + 2. Server calls disconnect command and sends a FIN packet. + 3. Client replies the FIN packet and becomes CLOSE_WAIT state. + 4. Client calls receive command and checks the status is NX_NOT_CONNECTED. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_24_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 6.24 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + if(client_socket.nx_tcp_socket_state == NX_TCP_CLOSE_WAIT) + { + /* Call receive. */ + status = nx_tcp_socket_receive(&client_socket, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + if(status != NX_NOT_CONNECTED) + error_counter++; + } + else + error_counter++; + + /* Disconnect. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_24_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.24 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_6_25_test.c b/test/regression/netxduo_test/netx_6_25_test.c new file mode 100644 index 00000000..e1b3800a --- /dev/null +++ b/test/regression/netxduo_test/netx_6_25_test.c @@ -0,0 +1,310 @@ +/* 6.25 If RECEIVE call arrives on state LAST-ACK, TCP MUST return "error: connection closing". */ + +/* Procedure + 1. Connection. + 2. Server calls disconnect command and sends a FIN packet. + 3. Client replies an ACK packet and calls disconnect command. + 4. Client calls receive command. + 5. Check the state of client is LAST_ACK and TCP return NX_NOT_CONNECTED. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG fin_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_6_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_25_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + printf("NetX Test: TCP Spec 6.25 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay FIN packet. */ + advanced_packet_process_callback = my_packet_process_6_25; + + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + if(client_socket.nx_tcp_socket_state == NX_TCP_LAST_ACK) + { + /* Client receive the packet. */ + status = nx_tcp_socket_receive(&client_socket, &my_packet, 50); + + if(status != NX_NOT_CONNECTED) + error_counter++; + } + else + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_6_25(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + /* It is a FIN packet. */ + fin_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_25_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.25 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_6_27_test.c b/test/regression/netxduo_test/netx_6_27_test.c new file mode 100644 index 00000000..50cefe2c --- /dev/null +++ b/test/regression/netxduo_test/netx_6_27_test.c @@ -0,0 +1,165 @@ +/* 6.27 For CLOSE call on CLOSED state, if the user has got access to such a connection, + TCP MUST return error: connection does not exist. */ + +/* Procedure +1. Client bind. +2. Client calls close command. +3. TCP return "NX_NOT_CONNECTED". */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_27_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.27 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check the state of the TCP client. */ + if ( client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + if (status != NX_NOT_CONNECTED) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_27_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.27 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_6_28_test.c b/test/regression/netxduo_test/netx_6_28_test.c new file mode 100644 index 00000000..0349e219 --- /dev/null +++ b/test/regression/netxduo_test/netx_6_28_test.c @@ -0,0 +1,347 @@ +/* 6.28 For CLOSE call on state CLOSING, TCP MUST return with error: connection closing. */ + +/* Procedure + 1. Client connect with Server. + 2. Server call disconnect, then Server state is FINWAIT1. + 3. Client call disconnect,then Server state is CLOSING. + 4. Server call disconnect. + 5. Judge the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_6_28(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_6_28(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_28_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status = nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.28 Test........................................"); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay SYN packet. */ + advanced_packet_process_callback = my_packet_process_6_28; + + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + /*Let the server socket to check the FIN segment*/ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_6_28; + + tx_thread_suspend(&ntest_0); + + if (server_socket.nx_tcp_socket_state == NX_TCP_CLOSING) + { + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + if (status != NX_NOT_CONNECTED) + error_counter++; + } + else + error_counter++; + + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_6_28(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + + fin_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* SYN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_6_28(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Client receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + + /* It is a SYN packet. */ + fin_counter++; + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_28_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.28 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_6_29_test.c b/test/regression/netxduo_test/netx_6_29_test.c new file mode 100644 index 00000000..20e5293c --- /dev/null +++ b/test/regression/netxduo_test/netx_6_29_test.c @@ -0,0 +1,325 @@ +/* 6.29 TCP, in FINWAIT-1 state, MUST return error: connection closing for CLOSE call. */ + +/* Procedure + 1. Client connect with Server. + 2. Server disconnect, then server state is FINWAIT1. + 3. Client call disconnect. + 4. Check the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_6_29(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_29_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.29 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let driver delay FIN packet. */ + advanced_packet_process_callback = my_packet_process_6_29; + + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + if (server_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_1) + { + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + if (status != NX_NOT_CONNECTED) + error_counter++; + } + else + error_counter++; + + tx_thread_suspend(&ntest_0); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if(error_counter || (fin_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_6_29(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + + fin_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + /* FIN packet has been processed. */ + advanced_packet_process_callback = NX_NULL; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_29_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.29 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_6_32_test.c b/test/regression/netxduo_test/netx_6_32_test.c new file mode 100644 index 00000000..67d424df --- /dev/null +++ b/test/regression/netxduo_test/netx_6_32_test.c @@ -0,0 +1,298 @@ +/* 6.32 For CLOSE call on state FINWAIT-2, TCP SHOULD return error: connection closing. */ + +/* Procedure + 1. Client connect with Server. + 2. Server disconnect, then Server state is FINWAIT2. + 3. Server call disconnect function. + 4. Check the status. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_32_application_define(void *first_unused_memory) +#endif + { +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status += nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.32 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call disconnect to send a FIN. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT ); + + /* Check if server state is FIN_WAIT_2. */ + if(server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_2) + error_counter++; + + /* Server state is FIN_WAIT_2, Call disconnect to send an FIN. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check the server state. */ + if(status != NX_NOT_CONNECTED) + error_counter++; + + tx_thread_suspend(&ntest_0); + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisted on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call disconnect to send an FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + tx_thread_resume(&ntest_0); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error*/ + if(status) + error_counter++; + + /* Delete the socket*/ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error*/ + if (status) + error_counter++; + + /* Return error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_6_32_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 6.32 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_8_01_test.c b/test/regression/netxduo_test/netx_8_01_test.c new file mode 100644 index 00000000..fcef5239 --- /dev/null +++ b/test/regression/netxduo_test/netx_8_01_test.c @@ -0,0 +1,487 @@ +/* 8.01 TCP MUST ignore an incoming segment with RST flag in LISTEN state. */ + +/* Procedure +1. Connection. +2. Server calls disconnect command. +3. Server calls unaccept and relisten command. +4. Client sends a segment that is carrying an RST flag. +5. Check whether server send a packet in response to incoming segment. +6. Clean up.Print the resuit. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define MSG "ABCDEFGHIJKLMNOPQRSTUVWXYZ " +#include "nx_ip.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG data_packet_counter; +static ULONG rst_counter; + +static ULONG client_tx; + +/* Define thread prototypes. */ + +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT my_packet_process_8_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_8_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_8_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1.need? */ + status = nx_icmp_enable(&ip_0); + status = nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Set the callback function to my_packet_process_8_01. */ + advanced_packet_process_callback = my_packet_process_8_01; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Set the port to NULL. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup server socket state to LISTEN */ + status = nx_tcp_server_socket_relisten(&ip_0, 12, &server_socket); + + if(status) + error_counter++; + + /* Set the receive function to my_tcp_packet_receive_8_01. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_01; + + if(server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* suspend the thread ntest_0. */ + tx_thread_suspend(&ntest_0); + + if(server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.01 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Replace the TCP receive function with my_tcp_packet_receive_8_01 for ip_1. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_01_2; + + /* Check for error. */ + if(status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + client_tx = server_socket.nx_tcp_socket_tx_sequence; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Replace the TCP receive function with _nx_tcp_packet_receive for ip_1. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* resume the thread ntest_0 */ + tx_thread_resume(&ntest_0); + + /* Disconnect the server socket. */ + nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /*Check the status. */ + if((error_counter == 0) && (rst_counter == 1) && (data_packet_counter == 1)) + { + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_8_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +ULONG checksum = 0; +NX_TCP_HEADER *tcp_header_ptr; + +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +NX_IPV4_HEADER *ip_header_ptr; +#else +ULONG source_ip, dest_ip; +NX_IP_HEADER *ip_header_ptr; +#endif + + /* Point to the TCP HEADER */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Drop the FIN packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + else if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (packet_ptr -> nx_packet_length - 40 == 20)) + { + +#if defined(__PRODUCT_NETXDUO__) + + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); + +#else + + ip_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); + +#endif + + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + + tcp_header_ptr -> nx_tcp_header_word_3 &= 0xFFE0FFFF; + tcp_header_ptr -> nx_tcp_header_word_3 |= NX_TCP_ACK_BIT|NX_TCP_RST_BIT; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 &= 0x0000ffff; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + + dest_ip = &ip_header_ptr -> nx_ip_header_destination_ip; + source_ip = &ip_header_ptr -> nx_ip_header_source_ip; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + + dest_ip = ip_header_ptr -> nx_ip_header_destination_ip; + source_ip = ip_header_ptr -> nx_ip_header_source_ip; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); + +#endif + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); + +#else + + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); + +#endif + + advanced_packet_process_callback = NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_8_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)packet_ptr->nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + if((packet_ptr -> nx_packet_length == 40) && (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, 20))) + data_packet_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_8_01_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)packet_ptr->nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(tcp_header_ptr -> nx_tcp_acknowledgment_number == client_tx) + error_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.01 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_8_02_test.c b/test/regression/netxduo_test/netx_8_02_test.c new file mode 100644 index 00000000..a99ac3ec --- /dev/null +++ b/test/regression/netxduo_test/netx_8_02_test.c @@ -0,0 +1,428 @@ +/* 8.2 :TCP in LISTEN state, + TCP MUST send RST in response to incoming segment with ACK and remain in the same state, + SEQ number of RST is taken from SEG.ACK. */ + +/* Procedure +1. Connection. +2. Server calls disconnect command. +3. Server calls unaccept and relisten command. +4. Client sends a segment that is carrying an ACK flag. +5. Server sends a RST segment with SEQ number taken from SEG.ACK. +6. Clean up.Print the resuit. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define MSG "ABCDEFGHIJKLMNOPQRSTUVWXYZ " +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; +static ULONG data_packet_counter; +static ULONG ack_segment; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_8_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_8_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_8_02_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + data_packet_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 8.02 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 100, NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Set the callback function to my_packet_process_8_02. */ + advanced_packet_process_callback = my_packet_process_8_02; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Set the port to NULL. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup server socket state to LISTEN */ + status = nx_tcp_server_socket_relisten(&ip_0, 12, &server_socket); + + if(status) + error_counter++; + + if (server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* Set the receive function to my_tcp_packet_receive_8_02. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_02; + + /* suspend the thread ntest_0 */ + tx_thread_suspend(&ntest_0); + + /* Check whether the server socket is in LISTEN state. */ + if((data_packet_counter == 1) && (rst_counter == 2)) + { + if (server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + } + else + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, + NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Replace the TCP receive function with my_tcp_packet_receive_8_02 for ip_1. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_02_2; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Resume the thread ntest_0. */ + tx_thread_resume(&ntest_0); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /*Check the program status. */ + if((error_counter == 0) && (data_packet_counter == 1) && (rst_counter == 2)) + { + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_8_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if(packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + + /* Point to the TCP header */ + tcp_header_ptr = (NX_TCP_HEADER *)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + *operation_ptr = NX_RAMDRIVER_OP_DROP; + rst_counter++; + + advanced_packet_process_callback = NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_8_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr->nx_packet_prepend_ptr; + + if ((packet_ptr -> nx_packet_length - 20 == 20) && !memcmp(packet_ptr -> nx_packet_prepend_ptr + 20, MSG, 20)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + ack_segment = tcp_header_ptr -> nx_tcp_acknowledgment_number; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + data_packet_counter++; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_8_02_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)packet_ptr->nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + if (tcp_header_ptr -> nx_tcp_sequence_number == ack_segment) + rst_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.02 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_8_17_test.c b/test/regression/netxduo_test/netx_8_17_test.c new file mode 100644 index 00000000..259c2505 --- /dev/null +++ b/test/regression/netxduo_test/netx_8_17_test.c @@ -0,0 +1,366 @@ +/* 8.17 TCP in SYN-SENT state MUST ignore a segment carrying an unacceptable ACK and RST. */ + +/* Procedure +1. Client connects. +2. Drop the SYN+ACK packet in the driver. +3. Server sends a segment that is carrying an ACK and RST flag with unacceptable ACK number. +4. Clean up.Print the resuit. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_8_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_8_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_17_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_8_17; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Check the client socket state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_SYN_SENT) + error_counter++; + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_17; + + /* Resume the thread ntest_1. */ + tx_thread_resume(&ntest_1); + + /* Check the client socket state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_SYN_SENT) + error_counter++; + + /* Resume the thread ntest_1. */ + tx_thread_resume(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check for error. */ + if(error_counter || (syn_ack_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_TCP_HEADER tcp_header_ptr; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 8.17 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_1); + + /* If ACK bit not set, _nx_tcp_packet_send_rst will send one RST and ACK packet. */ + tcp_header_ptr.nx_tcp_header_word_3 = NX_TCP_RST_BIT; + + /* Set the sequence number. */ + tcp_header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence; + tcp_header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence + 30; + + /* Send RST. */ + _nx_tcp_packet_send_rst(&server_socket, &tcp_header_ptr); + + /* Suspend the thread ntest_1. */ + tx_thread_suspend(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Set the port to NULL. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_8_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if(packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + client_socket.nx_tcp_socket_rx_sequence = tcp_header_ptr -> nx_tcp_sequence_number + 1; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + syn_ack_counter++; + + advanced_packet_process_callback = NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_8_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + && (tcp_header_ptr ->nx_tcp_acknowledgment_number != client_socket.nx_tcp_socket_tx_sequence)) + { + rst_counter ++; + + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.17 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_8_18_test.c b/test/regression/netxduo_test/netx_8_18_test.c new file mode 100644 index 00000000..83343534 --- /dev/null +++ b/test/regression/netxduo_test/netx_8_18_test.c @@ -0,0 +1,450 @@ +/* 8.18 TCP, in SYN-SENT state MUST ignore a RST control message. */ + +/* Procedure +1. Client connects. +2. Drop the SYN+ACK packet in the driver. +3. Server sends a segment that is carrying an RST and ACK flag. +4. Modify the packet with RST flag. +5. Client ignores the packet. +6. Clean up.Print the resuit. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_8_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_8_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_18_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_8_18; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Check the client socket state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_SYN_SENT) + error_counter++; + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_18; + + /* Resume the thread ntest_1. */ + tx_thread_resume(&ntest_1); + + /* Check the client socket state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_SYN_SENT) + error_counter++; + + /* Resume the thread ntest_1. */ + tx_thread_resume(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check for error. */ + if(error_counter || (syn_ack_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_TCP_HEADER tcp_header_ptr; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 8.18 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_1); + + + /* Set the RST. */ + tcp_header_ptr.nx_tcp_header_word_3 |= NX_TCP_RST_BIT | NX_TCP_ACK_BIT; + + /* Set the sequence number. */ + tcp_header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence; + tcp_header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence; + + /* Send RST. */ + _nx_tcp_packet_send_rst(&server_socket, &tcp_header_ptr); + + + /* Suspend the thread ntest_1. */ + tx_thread_suspend(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Set the port to NULL. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_8_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum = 0; + +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +NX_IPV4_HEADER *ip_header_ptr; +#elif defined(__PRODUCT_NETX__) +ULONG source_ip, dest_ip; +NX_IP_HEADER *ip_header_ptr; +#endif + + if(packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + client_socket.nx_tcp_socket_rx_sequence = tcp_header_ptr -> nx_tcp_sequence_number + 1; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + syn_ack_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + } + + /* Remove the ACK bit in THE rst packet. */ + else if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { +#if defined(__PRODUCT_NETXDUO__) + + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); + +#elif defined(__PRODUCT_NETX__) + + ip_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); + +#endif + + tcp_header_ptr -> nx_tcp_header_word_3 &= 0xffc0ffff; + tcp_header_ptr -> nx_tcp_header_word_3 |= NX_TCP_RST_BIT; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + tcp_header_ptr -> nx_tcp_header_word_4 &= 0x0000ffff; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + + dest_ip = &ip_header_ptr -> nx_ip_header_destination_ip; + source_ip = &ip_header_ptr -> nx_ip_header_source_ip; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + + checksum = ~checksum & NX_LOWER_16_MASK; + +#elif defined(__PRODUCT_NETX__) + + dest_ip = ip_header_ptr -> nx_ip_header_destination_ip; + source_ip = ip_header_ptr -> nx_ip_header_source_ip; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); + +#endif + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); + +#elif defined(__PRODUCT_NETX__) + + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); + +#endif + + advanced_packet_process_callback = NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_8_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + rst_counter ++; + + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_18_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.18 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_8_19_test.c b/test/regression/netxduo_test/netx_8_19_test.c new file mode 100644 index 00000000..b122876e --- /dev/null +++ b/test/regression/netxduo_test/netx_8_19_test.c @@ -0,0 +1,359 @@ +/* 8.19 TCP, in SYN-SENT state MUST move on to CLOSED state after receiving a segment with ACK and RST and acceptable ACK number. */ + +/* Procedure +1. Connection. +2. Drop the SYN+ACK packet in the driver. +3. Server sends a segment that is carrying an ACK and RST flag with acceptable ACK number. +4. Check the client state. +5. Clean up.Print the resuit. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_8_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_8_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_19_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_8_19; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Check the client socket state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_SYN_SENT) + error_counter++; + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_19; + + /* Resume the thread ntest_1. */ + tx_thread_resume(&ntest_1); + + /* Check the client socket state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Resume the thread ntest_1. */ + tx_thread_resume(&ntest_1); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check for error. */ + if(error_counter || (syn_ack_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_TCP_HEADER tcp_header_ptr; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 8.19 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_1); + + /* Set the RST. */ + tcp_header_ptr.nx_tcp_header_word_3 = NX_TCP_RST_BIT; + + /* Set the sequence number. */ + tcp_header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence ; + tcp_header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence ; + + /* Send RST. */ + _nx_tcp_packet_send_rst(&server_socket, &tcp_header_ptr); + + /* Suspend the thread ntest_1. */ + tx_thread_suspend(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Set the port to NULL. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_8_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + syn_ack_counter++; + + advanced_packet_process_callback = NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + return NX_TRUE; +} + + +static void my_tcp_packet_receive_8_19(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && + (tcp_header_ptr -> nx_tcp_acknowledgment_number == client_socket.nx_tcp_socket_tx_sequence)) + { + rst_counter++; + + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_19_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.19 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_8_20_test.c b/test/regression/netxduo_test/netx_8_20_test.c new file mode 100644 index 00000000..b41d6952 --- /dev/null +++ b/test/regression/netxduo_test/netx_8_20_test.c @@ -0,0 +1,352 @@ +/* 8.20 TCP, in SYN-SENT state MUST remain in the same state after receiving a segment with neither SYN nor RST flag set. */ + + +/* Procedure +1. Connection. +2. Drop syn+ack packet. +3. server sends ack packet. +4. the state of client socket should be the SYN_SENT. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; +static ULONG ack_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_8_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_8_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_20_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_8_20; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Check the client socket state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_SYN_SENT) + error_counter++; + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_20; + + /* Resume the thread ntest_1. */ + tx_thread_resume(&ntest_1); + + /* Check whether the client socket state has changed. */ + if((ack_counter != 1) || (client_socket.nx_tcp_socket_state != NX_TCP_SYN_SENT)) + error_counter++; + + /* Resume the thread ntest_1. */ + tx_thread_resume(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check for error. */ + if(error_counter || (syn_ack_counter != 1) || (ack_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(2); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 8.20 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + /* Suspend the thread ntest_1. */ + tx_thread_suspend(&ntest_1); + + /* Send a ack packet. */ + _nx_tcp_packet_send_ack(&server_socket,server_socket.nx_tcp_socket_tx_sequence); + + /* Suspend the thread ntest_1. */ + tx_thread_suspend(&ntest_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Set the port to NULL. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_8_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + /* Drop the SYN+ACK packet in order to postpone the connection. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + syn_ack_counter++; + + advanced_packet_process_callback = NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + return NX_TRUE; +} + +static void my_tcp_packet_receive_8_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if(!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_acknowledgment_number == client_socket.nx_tcp_socket_tx_sequence)) + { + ack_counter++; + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_20_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.20 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_8_21_test.c b/test/regression/netxduo_test/netx_8_21_test.c new file mode 100644 index 00000000..aed3857a --- /dev/null +++ b/test/regression/netxduo_test/netx_8_21_test.c @@ -0,0 +1,392 @@ +/* 8.21:TCP, in SYN-RCVD state, + MUST send ACK with next expected SEQ num on receiving any segment (without RST) with OTW SEQ number and remain in the same state. */ + +/* Procedure + 1.Connect + 2.Set server socket to SYN_RCVD state + 3.Client sends a packet with OTW SEQ to server + 4.Client should receive an ACK with proper SEQ and ACK numbers, and server socket should remain in SYN_RCVD state */ + +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG ack_counter; +static ULONG seg_counter; +static ULONG expected_ack; +static ULONG expected_seq; +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_8_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_8_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_8_21_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_21_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + seg_counter = 0; + ack_counter = 0; + expected_ack = 0; + expected_seq = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Spec 8.21 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_21; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + /* Suspend the thread ntest_0. */ + tx_thread_suspend(&ntest_0); + + /* Check the server socket state. */ + if((seg_counter != 1) || (server_socket.nx_tcp_socket_state != NX_TCP_SYN_RECEIVED)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Set the port to NULL. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process_8_21; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Deal the packet with my routing. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_21_2; + + expected_ack = client_socket.nx_tcp_socket_tx_sequence; + + /* Send FIN with OTW sequence. */ + _nx_tcp_packet_send_fin(&client_socket,(client_socket.nx_tcp_socket_tx_sequence - 50)); + + /* Resume the thread ntest_1. */ + tx_thread_resume(&ntest_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check for error. */ + if(error_counter || (ack_counter != 1) || (seg_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_8_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Skip packet that is not TCP. */ + if (packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Drop the ACK packet. */ + if(!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + advanced_packet_process_callback = NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + return NX_TRUE; +} + +static void my_tcp_packet_receive_8_21(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Check the server socket state. */ + if(server_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) + { + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + /* Check the FIN packet with OTW sequence. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + if((tcp_header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (tcp_header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) + { + seg_counter++; + + /* Record expected sequence of the server socket. */ + expected_seq = server_socket.nx_tcp_socket_tx_sequence; + + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_8_21_2(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + /* Check the ACK packet. */ + if(!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && + (tcp_header_ptr -> nx_tcp_sequence_number == expected_seq) && (tcp_header_ptr -> nx_tcp_acknowledgment_number == expected_ack)) + { + ack_counter++; + + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_21_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.21 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_8_29_01_test.c b/test/regression/netxduo_test/netx_8_29_01_test.c new file mode 100644 index 00000000..785a0b6f --- /dev/null +++ b/test/regression/netxduo_test/netx_8_29_01_test.c @@ -0,0 +1,385 @@ +/* 8.29.01 TCP, in SYN-RECEIVED or ESTABLISHED state,MUST ignore a RST segment with OTW SEQ number. */ + +/* Procedure + 1.Client sends a SYN to Server. + 2.Server responses SYN+ACK to Client. + 3.Delay the SYN+ACK packet. + 4.When Server is on the SYN_RECEIVED state, Client sends a RST which contains a OTW SEQ to Server. + 5.Check whether the state has been changed. + 6.When Server is on the ESTABLISHED state, Client sends a RST which contains a OTW SEQ to Server. + 7.Check whether the state has been changed.*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_8_29_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_8_29_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_29_01_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.29.01 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_8_29_01; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_0); + + /* Check Server socket's state. */ + if((rst_counter != 1) || (server_socket.nx_tcp_socket_state != NX_TCP_SYN_RECEIVED)) + error_counter++; + + status = nx_tcp_socket_state_wait(&server_socket, NX_TCP_ESTABLISHED, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_0); + + /* Check Server socket's state. */ + if((rst_counter != 2) || (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + error_counter++; + + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_TCP_HEADER header_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_NO_WAIT); + + /* Send RST */ + header_ptr.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + header_ptr.nx_tcp_acknowledgment_number = server_socket.nx_tcp_socket_rx_sequence - 10; + header_ptr.nx_tcp_sequence_number = server_socket.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + + tx_thread_resume(&ntest_0); + + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send RST */ + header_ptr.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + header_ptr.nx_tcp_acknowledgment_number = server_socket.nx_tcp_socket_rx_sequence - 20; + header_ptr.nx_tcp_sequence_number = server_socket.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + + tx_thread_resume(&ntest_0); + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (syn_ack_counter != 1) || (rst_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_8_29_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if(packet_ptr -> nx_packet_length >= 40) + { + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a SYN+ACK packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + syn_ack_counter++; + + /* Delay 500 ticks. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = 200; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_29_01; + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + return NX_TRUE; +} + +static void my_tcp_packet_receive_8_29_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(((server_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) && (rst_counter == 0)) || ((server_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) && (rst_counter == 1))) + { + /* Check if the packet is a RST one with OTW SEQ number. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + if((tcp_header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (tcp_header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) + rst_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + } + } + + if(rst_counter == 2) + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_29_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.29.01 Test.....................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_8_29_02_test.c b/test/regression/netxduo_test/netx_8_29_02_test.c new file mode 100644 index 00000000..c71ed782 --- /dev/null +++ b/test/regression/netxduo_test/netx_8_29_02_test.c @@ -0,0 +1,380 @@ +/* 8.29.02 TCP, in FINWAIT-1 or FINWAIT-2 state,MUST ignore a RST segment with OTW SEQ number. */ + +/* Procedure + 1.Connection. + 2.Server disconnect without waiting. + 3.Delay the FIN packet. + 4.When Server is on the FINWAIT-1 state, Client sends a RST which contains a OTW SEQ to Server. + 5.Check whether the state has been changed. + 6.When Server is on the FINWAIT-2 state, Client sends a RST which contains a OTW SEQ to Server. + 7.Check whether the state has been changed. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_8_29_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_8_29_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_29_02_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.29.02 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_8_29_02; + + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + if(server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_1) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_29_02; + + tx_thread_suspend(&ntest_0); + + if((rst_counter != 1) || (server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_1)) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + if(server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_2) + error_counter++; + + tx_thread_suspend(&ntest_0); + + if((rst_counter != 2) || (server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_2)) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 1) || (rst_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_TCP_HEADER header_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send RST */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_RST_BIT; + header_ptr.nx_tcp_acknowledgment_number = server_socket.nx_tcp_socket_rx_sequence - 10; + header_ptr.nx_tcp_sequence_number = server_socket.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + + tx_thread_resume(&ntest_0); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Send RST */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_RST_BIT; + header_ptr.nx_tcp_acknowledgment_number = server_socket.nx_tcp_socket_rx_sequence - 20; + header_ptr.nx_tcp_sequence_number = server_socket.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + + tx_thread_resume(&ntest_0); + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_8_29_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + fin_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void my_tcp_packet_receive_8_29_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a RST one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + if ((tcp_header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (tcp_header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) + rst_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(rst_counter == 2) + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_29_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.29.02 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_8_29_03_test.c b/test/regression/netxduo_test/netx_8_29_03_test.c new file mode 100644 index 00000000..a3a590fd --- /dev/null +++ b/test/regression/netxduo_test/netx_8_29_03_test.c @@ -0,0 +1,341 @@ +/* 8.29.03 TCP, in CLOSING state,MUST ignore a RST segment with OTW SEQ number. */ + +/* Procedure + 1. Client connect with Server. + 2. Server call disconnect, then Server state is FINWAIT1. + 3. CLient call disconnect,then Server state is CLOSING. + 4. Client send a RST to Server. + 5. Check whether the state has been changed. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_8_29_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_8_29_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_29_03_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_8_29_03; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_29_03; + + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_0); + + if((rst_counter != 1) || (server_socket.nx_tcp_socket_state != NX_TCP_CLOSING)) + error_counter++; + + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_TCP_HEADER header_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.29.03 Test....................................."); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Send RST */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_RST_BIT; + header_ptr.nx_tcp_acknowledgment_number = server_socket.nx_tcp_socket_rx_sequence - 10; + header_ptr.nx_tcp_sequence_number = server_socket.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + + tx_thread_resume(&ntest_0); + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 2) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_8_29_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (fin_counter == 0)) + { + fin_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + advanced_packet_process_callback = NX_NULL; + + return NX_TRUE; +} + +static void my_tcp_packet_receive_8_29_03(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(server_socket.nx_tcp_socket_state == NX_TCP_CLOSING) + { + /* Check the packet is a RST one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + if ((tcp_header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (tcp_header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) + rst_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + else if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + fin_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_29_03_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.29.03 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_8_29_04_test.c b/test/regression/netxduo_test/netx_8_29_04_test.c new file mode 100644 index 00000000..7607917b --- /dev/null +++ b/test/regression/netxduo_test/netx_8_29_04_test.c @@ -0,0 +1,367 @@ +/* 8.29.04 TCP, in CLOSE-WAIT or LAST-ACK state,MUST ignore a RST segment with OTW SEQ number. */ + +/* Procedure + 1.Connection. + 2.Server disconnect without waiting. + 3.When Client is on the CLOSE-WAIT state, Server sends a RST which contains a OTW SEQ to Client. + 4.Check whether the state has been changed. + 5.Client disconnect without waiting. + 6.Delay the FIN packet. + 7.When Client is on the LAST-ACK state, Server sends a RST which contains a OTW SEQ to Client. + 8.Check whether the state has been changed. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_8_29_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_8_29_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_29_04_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the received packet with my routine. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_8_29_04; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check whether the client socket's state changed after receiving a RST packet. */ + if((rst_counter != 1) || (client_socket.nx_tcp_socket_state != NX_TCP_CLOSE_WAIT)) + error_counter++; + + /* Delay the FIN packet in my_packet_process_8_29_04 to keep the socket in LAST_ACK state. */ + advanced_packet_process_callback = my_packet_process_8_29_04; + + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + if(client_socket.nx_tcp_socket_state != NX_TCP_LAST_ACK) + error_counter++; + + tx_thread_resume(&ntest_1); + + /* Check whether the client socket's state changed after receiving a RST packet. */ + if((rst_counter != 2) || (client_socket.nx_tcp_socket_state != NX_TCP_LAST_ACK)) + error_counter++; + + tx_thread_resume(&ntest_1); + + /* Determine if the test was successful. */ + if((error_counter) || (fin_counter != 1) || (rst_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_TCP_HEADER header_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.29.04 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + +#if 0 + tx_thread_suspend(&ntest_1); +#endif + + /* Send RST */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_RST_BIT; + header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence - 10; + header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_rst(&server_socket, &header_ptr); + + tx_thread_suspend(&ntest_1); + + /* Send RST */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_RST_BIT; + header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence - 20; + header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_rst(&server_socket, &header_ptr); + + tx_thread_suspend(&ntest_1); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process_8_29_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + fin_counter++; + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + advanced_packet_process_callback = NX_NULL; + + return NX_TRUE; +} + +static void my_tcp_packet_receive_8_29_04(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + if(((client_socket.nx_tcp_socket_state == NX_TCP_CLOSE_WAIT) && (rst_counter == 0)) || ((client_socket.nx_tcp_socket_state == NX_TCP_LAST_ACK) && (rst_counter == 1))) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check whether the packet is a RST one. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + if ((tcp_header_ptr -> nx_tcp_sequence_number < server_socket.nx_tcp_socket_rx_sequence) || + (tcp_header_ptr -> nx_tcp_sequence_number >= server_socket.nx_tcp_socket_rx_sequence + server_socket.nx_tcp_socket_rx_window_current)) + rst_counter++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + if(rst_counter == 2) + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_8_29_04_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 8.29.04 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_9_17_test.c b/test/regression/netxduo_test/netx_9_17_test.c new file mode 100644 index 00000000..ac871e5d --- /dev/null +++ b/test/regression/netxduo_test/netx_9_17_test.c @@ -0,0 +1,336 @@ +/* 9.17 TCP, in SYN-RCVD state, reached through active OPEN, MUST inform "connection refused" to application on recv a RST. + and socket state MUST go to CLOSED state on RST.*/ + +/* RFC 793, Section 3.9, page 70, Event Processing. +The user need not be informed. If this connection was +initiated with an active OPEN (i.e., came from SYN-SENT state) +then the connection was refused, signalthe user "connection refused". +In either case, all segmentson the retransmission queue should be removed. +And in the active OPEN case, enter the CLOSED state and delete the TCB,and return. */ + +/* Procedure +1. Client_1 sends a SYN to Client_2. +2. Use my_packet_process_9_17 function to drop the SYN packet. +3. Client_2 sends a SYN to Client_1. +4. Client_1 send a SYN+ACK to Client_2. +5. Use my_packet_process_9_17 function to drop the SYN+ACK packet. +6. Client_2 sends a RST to Client_1. +7. Check the connection return status and the Client_1 state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_1_socket; +static NX_TCP_SOCKET client_2_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_3000(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_3000(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_9_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_9_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_17_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the counters. */ + error_counter = 0; + syn_counter = 0; + rst_counter = 0; + + /* Create the client thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_3000, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_3000, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the client thread. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.17 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_1_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_1_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the SYN packet with my routing */ + advanced_packet_process_callback = my_packet_process_9_17; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_9_17; + + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_1_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Judge the Client state. */ + if((rst_counter != 1) || (client_1_socket.nx_tcp_socket_state != NX_TCP_CLOSED) || status != NX_NOT_CONNECTED) + { + error_counter++; + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_1_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_1_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +/* Define the server thread. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_TCP_HEADER header_ptr; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_2_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_bind(&client_2_socket, 12, NX_IP_PERIODIC_RATE); + + + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_2_socket, IP_ADDRESS(1, 2, 3, 4), 12, NX_NO_WAIT); + + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + header_ptr.nx_tcp_acknowledgment_number = client_1_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = client_1_socket.nx_tcp_socket_tx_sequence + 1; + _nx_tcp_packet_send_rst(&client_2_socket, &header_ptr); + + tx_thread_sleep(1); + + /* Return error. */ + if((error_counter) || (syn_counter != 2 ) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process_9_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if (ip_ptr != &ip_0) + return NX_TRUE; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* Check if it is a SYN packet. */ + if (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (syn_counter == 0)) + { + syn_counter++; + + /*Drop the packet*/ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + else if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (syn_counter == 2)) + { + *operation_ptr = NX_RAMDRIVER_OP_DROP; + advanced_packet_process_callback = NX_NULL; + } + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; + +} + +void my_tcp_packet_receive_9_17(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a SYN one. */ + if (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && (syn_counter == 1)) + { + syn_counter++; + } + /* Check the packet is a RST one. */ + else if (client_1_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) + { + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.17 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_9_18_test.c b/test/regression/netxduo_test/netx_9_18_test.c new file mode 100644 index 00000000..19436193 --- /dev/null +++ b/test/regression/netxduo_test/netx_9_18_test.c @@ -0,0 +1,333 @@ +/* 9.18 TCP, in ESTABLISHED state, MUST return to CLOSED state on RESET. */ + +/* RFC 793, Section 3.9, page 70, Event Processing. +ESTABLISHED +If the RST bit is set then, Users should receive an unsolicited general +"connection reset" signal. Enter the CLOSED state, delete the TCB, +and return. */ + +/* Procedure +1. Establish a connection by the "three-way handshake" procedure. +2. Server sends a RST to Client. +3. Check the Client state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if defined NX_DISABLE_RESET_DISCONNECT && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_9_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_18_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the client thread. */ + tx_thread_create(&ntest_0, "ntest 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&ntest_1, "ntest 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the client thread. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.18 Test........................................"); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Let client checks the packet. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_9_18; + + /* Call connect to send an SYN. */ + status =nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + /* Check for error. */ + if(status) + error_counter++; + + /* Check the client state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + tx_thread_resume(&ntest_1); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +/* Define the server thread. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_TCP_HEADER header_ptr; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + /* Send a RST packet */ + header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_rst(&server_socket, &header_ptr); + + tx_thread_suspend(&ntest_1); + + status = nx_tcp_socket_disconnect(&server_socket,NX_NO_WAIT); + + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +void my_tcp_packet_receive_9_18(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if(client_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) + { + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a RST one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_18_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.18 Test........................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_9_19_01_test.c b/test/regression/netxduo_test/netx_9_19_01_test.c new file mode 100644 index 00000000..88351e13 --- /dev/null +++ b/test/regression/netxduo_test/netx_9_19_01_test.c @@ -0,0 +1,372 @@ +/* 9.19.01 TCP, in FINWAIT-1 state, MUST return to CLOSED state on RST. */ + +/* RFC 793, Section 3.9, page 70, Event Processing. + FIN-WAIT-1 + If the RST bit is set then, Users should receive an unsolicited general + "connection reset" signal. Enter the CLOSED state, delete the TCB, + and return. */ + +/* Procedure +1. Establish a connection by the "three-way handshake" procedure. +2. Client disconnect, then Client state is FINWAIT1. +3. Server sends a RST to Client. +4. Judge the Client state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined NX_DISABLE_RESET_DISCONNECT && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fin_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_9_19_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_9_19_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_19_01_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fin_counter = 0; + rst_counter = 0; + + /* Create the client thread. */ + tx_thread_create(&ntest_0, "ntest 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&ntest_1, "ntest 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.19.01 Test....................................."); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_9_19_01; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_9_19_01; + + /* Call disconnect to send an FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + tx_thread_resume(&ntest_1); + + + /* Check the client state. */ + if((rst_counter != 1) || (client_socket.nx_tcp_socket_state != NX_TCP_CLOSED)) + error_counter++; + + tx_thread_resume(&ntest_1); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status += nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (fin_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_TCP_HEADER header_ptr; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + /* Let the ACK number is big enough excluding the OTW situation. */ + header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence + 1; + _nx_tcp_packet_send_rst(&server_socket, &header_ptr); + + tx_thread_suspend(&ntest_1); + + status = nx_tcp_socket_disconnect(&server_socket,NX_NO_WAIT); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + +static UINT my_packet_process_9_19_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER* tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + fin_counter++; + + /*Drop the packet*/ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +void my_tcp_packet_receive_9_19_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if(client_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_1) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a RST one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + else + error_counter++; + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_19_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.19.01 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_9_19_02_test.c b/test/regression/netxduo_test/netx_9_19_02_test.c new file mode 100644 index 00000000..8e97aa17 --- /dev/null +++ b/test/regression/netxduo_test/netx_9_19_02_test.c @@ -0,0 +1,315 @@ +/* 9.19.02 TCP, in FINWAIT-2 state, MUST return to CLOSED state on RST. */ + +/* RFC 793, Section 3.9, page 70, Event Processing. + FIN-WAIT-2 + If the RST bit is set then, Users should receive an unsolicited general + "connection reset" signal. Enter the CLOSED state, delete the TCB, + and return. */ + +/* Procedure + 1. Establish a connection by the "three-way handshake" procedure. + 2. Client disconnect, then Client state is FINWAIT2. + 3. Server sends a RST to Client. + 4. Judge the Client state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if defined NX_DISABLE_RESET_DISCONNECT && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_9_19_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_19_02_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "ntest 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "ntest 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.19.02 Test....................................."); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_9_19_02; + + /* Call disconnect to send an FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + + tx_thread_resume(&ntest_1); + + /* Check the client state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + tx_thread_resume(&ntest_1); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if(error_counter || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_TCP_HEADER header_ptr; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + /* Send a RST packet */ + header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence + 1; + _nx_tcp_packet_send_rst(&server_socket, &header_ptr); + + tx_thread_suspend(&ntest_1); + + status = nx_tcp_socket_disconnect(&server_socket,NX_NO_WAIT); + + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +void my_tcp_packet_receive_9_19_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if(client_socket.nx_tcp_socket_state == NX_TCP_FIN_WAIT_2) + { + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a RST one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_19_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.19.02 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_9_20_test.c b/test/regression/netxduo_test/netx_9_20_test.c new file mode 100644 index 00000000..343d6606 --- /dev/null +++ b/test/regression/netxduo_test/netx_9_20_test.c @@ -0,0 +1,321 @@ +/* 9.20 TCP, in CLOSE-WAIT state, MUST return to CLOSED state on RST. */ + +/* Procedure + 1. Client connect with Server. + 2. Server disconnect, then Client state is CLOSE-WAIT. + 3. Server sends RST to Client. + 4. Judge the Client state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_9_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_20_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 256 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.20 Test........................................"); + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*Let the client socket check the RST packet*/ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_9_20; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check the client state. */ + if((rst_counter != 1) || (client_socket.nx_tcp_socket_state != NX_TCP_CLOSED)) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status += nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_TCP_HEADER header_ptr; + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + /* Set the sequence number. */ + header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence; + + /* Send RST. */ + _nx_tcp_packet_send_rst(&server_socket, &header_ptr); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + + +void my_tcp_packet_receive_9_20(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if(client_socket.nx_tcp_socket_state == NX_TCP_CLOSE_WAIT) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a RST one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_20_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.20 Test........................................N/A\n"); + test_control_return(3); + +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_9_21_01_test.c b/test/regression/netxduo_test/netx_9_21_01_test.c new file mode 100644 index 00000000..30549984 --- /dev/null +++ b/test/regression/netxduo_test/netx_9_21_01_test.c @@ -0,0 +1,365 @@ +/* 9.21 TCP, in CLOSING, LAST-ACK state, MUST return to CLOSED state on receiving a RST. */ + +/*9.21.1 test the TCP in LAST-ACK state*/ +/* Procedure + 1. Client connect with Server. + 2. Server disconnect. + 3. Client disconnect,then Client's state move to LAST-ACK state. + 4. Server sends RST to Client. + 5. Judge the Client state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_9_21_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_9_21_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_21_01_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status = nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.21.01 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the FIN packet with my routing */ + advanced_packet_process_callback = my_packet_process_9_21_01; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_9_21_01; + + /* Call disconnect to send an FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + tx_thread_resume(&ntest_1); + + /* Check the client state. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_TCP_HEADER header_ptr; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if (status) + error_counter++; + + /* Call disconnect to send an FIN. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + tx_thread_suspend(&ntest_1); + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + /* Set the sequence number. */ + header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence + 1; + + /* Send RST. */ + _nx_tcp_packet_send_rst(&server_socket, &header_ptr); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + + +static UINT my_packet_process_9_21_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* drop the fin packet send from client to server */ + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + *operation_ptr = NX_RAMDRIVER_OP_DROP; + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; + +} + +void my_tcp_packet_receive_9_21_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if(client_socket.nx_tcp_socket_state == NX_TCP_LAST_ACK) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a RST one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_21_01_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.21.01 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_9_21_02_test.c b/test/regression/netxduo_test/netx_9_21_02_test.c new file mode 100644 index 00000000..239355b8 --- /dev/null +++ b/test/regression/netxduo_test/netx_9_21_02_test.c @@ -0,0 +1,359 @@ +/* 9.21 TCP, in CLOSING, LAST-ACK state, MUST return to CLOSED state on receiving a RST. */ + +/*9.21.2 test the TCP in CLOSING state*/ +/* Procedure + 1. Client connect with Server. + 2. Server disconnect, delay the FIN packet + 3. Client disconnect, then Server state is CLOSING + 4. Client sends RST to Server. + 5. Check the Server state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_9_21_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_9_21_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_21_02_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536 * 16); + pointer = pointer + 1536 * 16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.21.02 Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process_9_21_02; + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_9_21_02; + + /* Call disconnect to send an FIN. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + +#ifdef __PRODUCT_NETXDUO__ + if(server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) +#else + if(server_socket.nx_tcp_socket_state != NX_TCP_CLOSED) +#endif + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_TCP_HEADER header_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send an SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call disconnect to send an FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + /* Set the sequence number. */ + header_ptr.nx_tcp_acknowledgment_number = server_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = server_socket.nx_tcp_socket_tx_sequence + 1; + + /* Send RST. */ + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + + +} + + +static UINT my_packet_process_9_21_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER* tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + /*Delay the packet*/ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + advanced_packet_process_callback = NX_NULL; + + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +void my_tcp_packet_receive_9_21_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if(server_socket.nx_tcp_socket_state == NX_TCP_CLOSING) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a RST one. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_21_02_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.21.02 Test.....................................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_9_22_test.c b/test/regression/netxduo_test/netx_9_22_test.c new file mode 100644 index 00000000..370f85ef --- /dev/null +++ b/test/regression/netxduo_test/netx_9_22_test.c @@ -0,0 +1,349 @@ +/* 9.22 TCP, in SYN-RCVD state through passive open, MUST return to LISTEN state on RST. */ + + +/* Procedure +1. Client connect to the Server. +2. Drop the ack packet sent from the Client to the Server, then the server state is SYN_RCVD +3. Client sends a RST to Server. +4. Judge the Server state. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#include "nx_ram_network_driver_test_1500.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); + +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process_9_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_9_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_22_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + if(status) + error_counter++; + + status = nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.22 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal the the SYN+ACK packet with my routine. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_9_22; + advanced_packet_process_callback = my_packet_process_9_22; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check the state of the client. */ + if(server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_TCP_HEADER header_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Call connect to send a SYN. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Send RST. */ + header_ptr.nx_tcp_header_word_3 = header_ptr.nx_tcp_header_word_3 | NX_TCP_ACK_BIT | NX_TCP_RST_BIT; + + header_ptr.nx_tcp_acknowledgment_number = server_socket.nx_tcp_socket_rx_sequence; + header_ptr.nx_tcp_sequence_number = server_socket.nx_tcp_socket_tx_sequence + 1; + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if((error_counter) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +static UINT my_packet_process_9_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a SYN+ACK packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT)) + { + /*Drop the packet*/ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + advanced_packet_process_callback = NX_NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; + +} + +void my_tcp_packet_receive_9_22(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Check the packet is a RST one. */ + if (server_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_22_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.22 Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_9_27_test.c b/test/regression/netxduo_test/netx_9_27_test.c new file mode 100644 index 00000000..155994a0 --- /dev/null +++ b/test/regression/netxduo_test/netx_9_27_test.c @@ -0,0 +1,428 @@ +/* 9.27 TCP, in SYN-RCVD state, MUST send a reset and go to CLOSED, on recv a seg with SYN in window. */ + +/* Procedure +1. Client connect to the Server. +2. Change the ACK packet sent from the Client to the Server to a SYN packet. +3. Judge whether the Client received a RST packet. +4. Judge the Server state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG rst_counter; + +static UINT syn_flag; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +extern USHORT _nx_ip_checksum_compute(NX_PACKET *, ULONG, UINT, ULONG *, ULONG *); + +static UINT my_packet_process_9_27(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive_9_27_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void my_tcp_packet_receive_9_27_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_27_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + rst_counter = 0; + syn_flag = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.27 Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive_9_27_01; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + if(server_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Deal rst with my routing. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_9_27_02; + advanced_packet_process_callback = my_packet_process_9_27; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Disconnect the socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Return error. */ + if(error_counter || (syn_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Return success. */ + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process_9_27(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; + +#if defined(__PRODUCT_NETXDUO__) +ULONG *source_ip, *dest_ip; +#else +ULONG source_ip, dest_ip; +#endif + + if (packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + syn_flag = 1; + + /* Clean the ACK bit. */ + tcp_header_ptr -> nx_tcp_header_word_3 = tcp_header_ptr -> nx_tcp_header_word_3 & 0xFFEFFFFF; + + /* Set the SYN bit. */ + tcp_header_ptr -> nx_tcp_header_word_3 = tcp_header_ptr -> nx_tcp_header_word_3 | NX_TCP_SYN_BIT; + + /*SYN occupy a squence number*/ + client_socket.nx_tcp_socket_tx_sequence ++; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); +#endif + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + +#if defined(__PRODUCT_NETXDUO__) + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &ip_1.nx_ip_interface[TEST_INTERFACE].nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#else + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_1.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); +#endif + + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + advanced_packet_process_callback = NX_NULL; + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + + +static void my_tcp_packet_receive_9_27_01(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + if((server_socket.nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) && (syn_flag == 1)) + { + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check the packet is a SYN one. */ + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) + { + syn_counter++; + + /* Deal packets with default routing. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + } + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void my_tcp_packet_receive_9_27_02(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + rst_counter++; + + /* Deal packets with default routing. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_9_27_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Spec 9.27 Test........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_api_compile_test.c b/test/regression/netxduo_test/netx_api_compile_test.c new file mode 100644 index 00000000..f6fa0b08 --- /dev/null +++ b/test/regression/netxduo_test/netx_api_compile_test.c @@ -0,0 +1,332 @@ +/* This NetX test concentrates on compiling all APIs for NetXDuo. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_ERROR_CHECKING) && defined(__PRODUCT_NETXDUO__) +#define DEMO_STACK_SIZE 2048 +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_packet.h" +#include "nx_tcp.h" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static ULONG error_counter = 0; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_api_compile_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +NX_PACKET *pkt_ptr = NX_NULL; + + /* Print out test information banner. */ + printf("NetX Test: API Compile Test.........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* APIs for ARP. */ + nx_arp_dynamic_entries_invalidate(0); + nx_arp_dynamic_entry_set(0, 0, 0, 0); + nx_arp_enable(0, 0 , 0); + nx_arp_entry_delete(0, 0); + nx_arp_gratuitous_send(0, 0); + nx_arp_hardware_address_find(0, 0, 0, 0); + nx_arp_info_get(0, 0, 0, 0, 0, 0, 0, 0, 0); + nx_arp_ip_address_find(0, 0, 0, 0); + nx_arp_static_entries_delete(0); + nx_arp_static_entry_create(0, 0, 0, 0); + nx_arp_static_entry_delete(0, 0, 0, 0); + + /* APIs for ICMP */ + nx_icmp_enable(0); + nx_icmp_info_get(0, 0, 0, 0, 0, 0, 0); + nx_icmp_ping(0, 0, 0, 0, 0, 0); + nxd_icmp_enable(0); + nxd_icmp_ping(0, 0, 0, 0, 0, 0); + nxd_icmp_source_ping(0, 0, 0, 0, 0, 0, 0); + nxd_icmpv6_ra_flag_callback_set(0, 0); + + /* APIs for IGMP */ + nx_igmp_enable(0); + nx_igmp_info_get(0, 0, 0, 0, 0); + nx_igmp_loopback_disable(0); + nx_igmp_loopback_enable(0); + nx_igmp_multicast_interface_join(0, 0, 0); + nx_igmp_multicast_interface_leave(0, 0, 0); + nx_igmp_multicast_join(0, 0); + nx_igmp_multicast_leave(0, 0); + + /* APIs for IP */ + nx_ip_address_change_notify(0, 0, 0); + nx_ip_address_get(0, 0, 0); + nx_ip_address_set(0, 0, 0); + nx_ip_auxiliary_packet_pool_set(0, 0); +#ifndef NX_ENABLE_DUAL_PACKET_POOL + _nx_ip_auxiliary_packet_pool_set(0, 0); +#endif + nx_ip_create(0, 0, 0, 0, 0, 0, 0, 0, 0); + nx_ip_delete(0); + nx_ip_driver_direct_command(0, 0, 0); + nx_ip_driver_interface_direct_command(0, 0, 0, 0); + nx_ip_forwarding_disable(0); + nx_ip_forwarding_enable(0); + nx_ip_fragment_disable(0); + nx_ip_fragment_enable(0); + nx_ip_gateway_address_clear(0); + nx_ip_gateway_address_get(0, 0); + nx_ip_gateway_address_set(0, 0); + nx_ip_info_get(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + nx_ip_interface_address_get(0, 0, 0, 0); + nx_ip_interface_address_mapping_configure(0, 0, 0); + nx_ip_interface_address_set(0, 0, 0, 0); + nx_ip_interface_attach(0, 0, 0, 0, 0); + nx_ip_interface_capability_get(0, 0, 0); + nx_ip_interface_capability_set(0, 0, 0); +#ifndef NX_ENABLE_INTERFACE_CAPABILITY + _nx_ip_interface_capability_get(0, 0, 0); + _nx_ip_interface_capability_set(0, 0, 0); +#endif + nx_ip_interface_detach(0, 0); + nx_ip_interface_info_get(0, 0, 0, 0, 0, 0, 0, 0); + nx_ip_interface_mtu_set(0, 0, 0); + nx_ip_interface_physical_address_get(0, 0, 0, 0); + nx_ip_interface_physical_address_set(0, 0, 0, 0, 0); + nx_ip_interface_status_check(0, 0, 0, 0, 0); + nx_ip_link_status_change_notify_set(0, 0); + nx_ip_max_payload_size_find(0, 0, 0, 0, 0, 0, 0, 0); + nx_ip_status_check(0, 0, 0, 0); + nx_ip_static_route_add(0, 0, 0, 0); + nx_ip_static_route_delete(0, 0, 0); +#ifndef NX_ENABLE_IP_STATIC_ROUTING + _nx_ip_static_route_add(0, 0, 0, 0); + _nx_ip_static_route_delete(0, 0, 0); +#endif + nx_ipv4_multicast_interface_join(0, 0, 0); + nx_ipv4_multicast_interface_leave(0, 0, 0); + nxd_ipv6_address_change_notify(0, 0); +#ifndef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + _nxd_ipv6_address_change_notify(0, 0); +#endif + nxd_ipv6_address_delete(0, 0); + nxd_ipv6_address_get(0, 0, 0, 0, 0); + nxd_ipv6_address_set(0, 0, 0, 0, 0); + nxd_ipv6_default_router_add(0, 0, 0, 0); + nxd_ipv6_default_router_delete(0, 0); + nxd_ipv6_default_router_entry_get(0, 0, 0, 0, 0, 0, 0); + nxd_ipv6_default_router_get(0, 0, 0, 0, 0); + nxd_ipv6_default_router_number_of_entries_get(0, 0, 0); + nxd_ipv6_disable(0); + nxd_ipv6_enable(0); + nxd_ipv6_multicast_interface_join(0, 0, 0); + nxd_ipv6_multicast_interface_leave(0, 0, 0); +#ifndef NX_ENABLE_IPV6_MULTICAST + _nxd_ipv6_multicast_interface_join(0, 0, 0); + _nxd_ipv6_multicast_interface_leave(0, 0, 0); +#endif + nxd_ipv6_stateless_address_autoconfig_disable(0, 0); + nxd_ipv6_stateless_address_autoconfig_enable(0, 0); +#ifndef NX_IPV6_STATELESS_AUTOCONFIG_CONTROL + _nxd_ipv6_stateless_address_autoconfig_disable(0, 0); + _nxd_ipv6_stateless_address_autoconfig_enable(0, 0); +#endif + + /* APIs for RAW service. */ + nx_ip_raw_packet_disable(0); + nx_ip_raw_packet_enable(0); + nx_ip_raw_packet_filter_set(0, 0); +#ifndef NX_ENABLE_IP_RAW_PACKET_FILTER + _nx_ip_raw_packet_filter_set(0, 0); +#endif + nx_ip_raw_packet_receive(0, 0, 0); + nx_ip_raw_packet_send(0, pkt_ptr, 0, 0); + nx_ip_raw_packet_source_send(0, pkt_ptr, 0, 0, 0); + nx_ip_raw_receive_queue_max_set(0, 0); + nxd_ip_raw_packet_send(0, pkt_ptr, 0, 0, 0, 0); + nxd_ip_raw_packet_source_send(0, 0, 0, 0, 0, 0, 0); + + /* APIs for ND cache. */ + nxd_nd_cache_entry_set(0, 0, 0, 0); + nxd_nd_cache_entry_delete(0, 0); + nxd_nd_cache_hardware_address_find(0, 0, 0, 0, 0); + nxd_nd_cache_invalidate(0); + nxd_nd_cache_ip_address_find(0, 0, 0, 0, 0); + + /* APIs for packet pool. */ + nx_packet_allocate(0, 0, 0, 0); + nx_packet_copy(0, 0, 0, 0); + nx_packet_data_append(0, 0, 0, 0, 0); + nx_packet_data_extract_offset(0, 0, 0, 0, 0); + nx_packet_data_retrieve(0, 0, 0); + nx_packet_length_get(0, 0); + nx_packet_pool_create(0, 0, 0, 0, 0); + nx_packet_pool_delete(0); + nx_packet_pool_info_get(0, 0, 0, 0, 0, 0); + nx_packet_pool_low_watermark_set(0, 0); +#ifndef NX_ENABLE_LOW_WATERMARK + _nx_packet_pool_low_watermark_set(0, 0); +#endif + nx_packet_release(pkt_ptr); + nx_packet_transmit_release(pkt_ptr); + + /* APIs for RARP. */ + nx_rarp_disable(0); + nx_rarp_enable(0); + nx_rarp_info_get(0, 0, 0, 0); + + /* APIs for TCP. */ + nx_tcp_client_socket_bind(0, 0, 0); + nx_tcp_client_socket_connect(0, 0, 0, 0); + nx_tcp_client_socket_port_get(0, 0); + nx_tcp_client_socket_unbind(0); + nx_tcp_enable(0); + nx_tcp_free_port_find(0, 0, 0); + nx_tcp_info_get(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + nx_tcp_server_socket_accept(0, 0); + nx_tcp_server_socket_listen(0, 0, 0, 0, 0); + nx_tcp_server_socket_relisten(0, 0, 0); + nx_tcp_server_socket_unaccept(0); + nx_tcp_server_socket_unlisten(0, 0); + nx_tcp_socket_bytes_available(0, 0); + nx_tcp_socket_create(0, 0, 0, 0, 0, 0, 0, 0, 0); + nx_tcp_socket_delete(0); + nx_tcp_socket_disconnect(0, 0); + nx_tcp_socket_disconnect_complete_notify(0, 0); + nx_tcp_socket_establish_notify(0, 0); +#ifdef NX_DISABLE_EXTENDED_NOTIFY_SUPPORT + _nx_tcp_socket_disconnect_complete_notify(0, 0); + _nx_tcp_socket_establish_notify(0, 0); +#endif + nx_tcp_socket_info_get(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + nx_tcp_socket_mss_get(0, 0); + nx_tcp_socket_mss_peer_get(0, 0); + nx_tcp_socket_mss_set(0, 0); + nx_tcp_socket_peer_info_get(0, 0, 0); + nx_tcp_socket_queue_depth_notify_set(0, 0); +#ifndef NX_ENABLE_TCP_QUEUE_DEPTH_UPDATE_NOTIFY + _nx_tcp_socket_queue_depth_notify_set(0, 0); +#endif + nx_tcp_socket_receive(0, 0, 0); + nx_tcp_socket_receive_notify(0, 0); + nx_tcp_socket_receive_queue_max_set(0, 0); +#ifndef NX_ENABLE_LOW_WATERMARK + _nx_tcp_socket_receive_queue_max_set(0, 0); +#endif + nx_tcp_socket_send(0, pkt_ptr, 0); + nx_tcp_socket_state_wait(0, 0, 0); + nx_tcp_socket_timed_wait_callback(0, 0); +#ifdef NX_DISABLE_EXTENDED_NOTIFY_SUPPORT + _nx_tcp_socket_timed_wait_callback(0, 0); +#endif + nx_tcp_socket_transmit_configure(0, 0, 0, 0, 0); + nx_tcp_socket_window_update_notify_set(0, 0); + nxd_tcp_client_socket_connect(0, 0, 0, 0); + nxd_tcp_socket_peer_info_get(0, 0, 0); + + /* APIs for UDP */ + nx_udp_enable(0); + nx_udp_free_port_find(0, 0, 0); + nx_udp_info_get(0, 0, 0, 0, 0, 0, 0, 0); + nx_udp_packet_info_extract(0, 0, 0, 0, 0); + nx_udp_socket_bind(0, 0, 0); + nx_udp_socket_bytes_available(0, 0); + nx_udp_socket_checksum_disable(0); + nx_udp_socket_checksum_enable(0); + nx_udp_socket_create(0, 0, 0, 0, 0, 0, 0); + nx_udp_socket_delete(0); + nx_udp_socket_info_get(0, 0, 0, 0, 0, 0, 0, 0); + nx_udp_socket_port_get(0, 0); + nx_udp_socket_receive(0, 0, 0); + nx_udp_socket_receive_notify(0, 0); + nx_udp_socket_send(0, pkt_ptr, 0, 0); + nx_udp_socket_source_send(0, pkt_ptr, 0, 0, 0); + nx_udp_socket_unbind(0); + nx_udp_source_extract(0, 0, 0); + nxd_udp_packet_info_extract(0, 0, 0, 0, 0); + nxd_udp_socket_send(0, pkt_ptr, 0, 0); + nxd_udp_socket_source_send(0, pkt_ptr, 0, 0, 0); + nxd_udp_source_extract(0, 0, 0); + + /* APIs for others. */ + nx_system_initialize(); +#ifndef NX_DRIVER_DEFERRED_PROCESSING +UINT status; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &pkt_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + _nx_ip_driver_deferred_enable(0, 0); + _nx_ip_driver_deferred_receive(0, pkt_ptr); +#endif + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_api_compile_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: API Compile Test..........................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_arp_auto_entry_test.c b/test/regression/netxduo_test/netx_arp_auto_entry_test.c new file mode 100644 index 00000000..d110c79d --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_auto_entry_test.c @@ -0,0 +1,168 @@ +/* Test ARP entry is created automatically on receiving an ARP packet. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ARP_AUTO_ENTRY) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* ARP packet. + * src MAC: 20:0b:c7:94:45:96 + * src IP: 1.2.3.5. + * dst MAC: 00:00:00:00:00:00 + * dst IP: 1.2.3.4. */ +static char arp_pkt[] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x0b, /* ...... . */ +0xc7, 0x94, 0x45, 0x96, 0x08, 0x06, 0x00, 0x01, /* ..E..... */ +0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x20, 0x0b, /* ...... . */ +0xc7, 0x94, 0x45, 0x96, 0x01, 0x02, 0x03, 0x05, /* ..E..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* ........ */ +0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_auto_entry_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP */ + status = nx_arp_enable(&ip_0, pointer, 1024); + + /* Check ARP enable status. */ + if(status) + error_counter++; + pointer = pointer + 1024; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +ULONG physical_msw, physical_lsw; + + /* Print out test information banner. */ + printf("NetX Test: ARP Auto Entry Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Inject ARP packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &arp_pkt[14], sizeof(arp_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(arp_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ARP packet. */ + _nx_arp_packet_deferred_receive(&ip_0, packet_ptr); + + /* Verify ARP entry is created. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 5), &physical_msw, &physical_lsw); + + /* Check status */ + if(status) + error_counter++; + + /* Verify the MAC. */ + if ((((physical_msw >> 8) & 0xFF) != 0x20) || + (((physical_msw) & 0xFF) != 0x0b) || + (((physical_lsw >> 24) & 0xFF) != 0xc7) || + (((physical_lsw >> 16) & 0xFF) != 0x94) || + (((physical_lsw >> 8) & 0xFF) != 0x45) || + (((physical_lsw) & 0xFF) != 0x96)) + { + error_counter++; + } + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_auto_entry_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Invalid Type Test.....................................N/A\n"); + test_control_return(3); + +} +#endif /* NX_DISABLE_ARP_AUTO_ENTRY */ diff --git a/test/regression/netxduo_test/netx_arp_basic_test.c b/test/regression/netxduo_test/netx_arp_basic_test.c new file mode 100644 index 00000000..d6c1c566 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_basic_test.c @@ -0,0 +1,327 @@ +/* This NetX test concentrates on the basic ARP operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + printf("NetX Test: ARP Basic Processing Test................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Basic Processing Test.................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_arp_branch_test.c b/test/regression/netxduo_test/netx_arp_branch_test.c new file mode 100644 index 00000000..568b9b6d --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_branch_test.c @@ -0,0 +1,846 @@ +/* This NetX test concentrates on the code coverage for ARP functions, + *_nx_arp_static_entry_delete_internal + *_nx_arp_interface_entries_delete + *_nx_arp_packet_receive + *_nx_arp_periodic_update +*/ + +#include "nx_arp.h" +#include "nx_api.h" +#include "tx_thread.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_ASSERT +static TX_THREAD thread_for_assert; +#endif +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; +static UINT arp_entries; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef __PRODUCT_NETXDUO__ +#ifndef NX_DISABLE_ASSERT +static void thread_for_assert_entry(ULONG thread_input); +#endif +static UINT arp_packet_allocate(NX_IP *ip_ptr, NX_PACKET **packet_ptr, UINT arp_type, + ULONG source_ip, ULONG source_physical_msw, ULONG source_physical_lsw, + ULONG target_ip, ULONG target_physical_msw, ULONG target_physical_lsw); +#endif + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_branch_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 2048; + arp_entries = 1024 / sizeof(NX_ARP); + + /* Check ARP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +#ifdef __PRODUCT_NETXDUO__ +UINT i; +ULONG address; +ULONG msw; +ULONG lsw; +NX_PACKET *my_packet; +#endif /* __PRODUCT_NETXDUO__ */ +NX_ARP arp_entry; +NX_ARP arp_entry_next; +NX_ARP *arp_active_list; +ULONG physical_msw, physical_lsw; + + /* Print out some test information banners. */ + printf("NetX Test: ARP Branch Test..........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + + _nx_arp_initialize(); + + /* Hit false condition of if (arp_entry -> nx_arp_active_list_head) in _nx_arp_static_entry_delete_internal(). */ + nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 7), 0x0011, 0x22334457); + ip_0.nx_ip_arp_table[10] -> nx_arp_active_list_head = NX_NULL; + _nx_arp_static_entry_delete_internal(&ip_0, ip_0.nx_ip_arp_table[10]); + + + /* Hit condition of while (next_arp_entry) in _nx_arp_interface_entries_delete(). */ + ip_0.nx_ip_arp_static_list = &arp_entry; + arp_entry.nx_arp_pool_previous = NX_NULL; + arp_entry.nx_arp_pool_next = NX_NULL; + arp_entry.nx_arp_ip_interface = NX_NULL; + _nx_arp_interface_entries_delete(&ip_0, 0); + + /* Recover */ + ip_0.nx_ip_arp_static_list = NX_NULL; + + + + /* Test _nx_arp_packet_receive(). */ + + /* Hit false condition (sender_ip_address == 0). + if ((interface_ptr -> nx_interface_ip_address == 0) && + ((sender_ip_address == interface_ptr -> nx_interface_ip_probe_address) || + ((sender_ip_address == 0) && (target_ip_address == interface_ptr -> nx_interface_ip_probe_address)))) + */ + + /* Clear the interface address. */ + ip_0.nx_ip_interface[0].nx_interface_ip_address = 0; + + /* Set the probe address. */ + ip_0.nx_ip_interface[0].nx_interface_ip_probe_address = IP_ADDRESS(1, 2, 3, 4); + + /* Allocate the packet. */ + status = arp_packet_allocate(&ip_0, &my_packet, NX_ARP_OPTION_REQUEST, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334456, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the packet interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Call _nx_arp_packet_receive. */ + _nx_arp_packet_receive(&ip_0, my_packet); + + + /* Hit false condition. + if ((sender_physical_msw != interface_ptr -> nx_interface_physical_address_msw) || + (sender_physical_lsw != interface_ptr -> nx_interface_physical_address_lsw)) + + if (interface_ptr -> nx_interface_ip_conflict_notify_handler) + */ + + /* Allocate ARP packet, */ + status = arp_packet_allocate(&ip_0, &my_packet, NX_ARP_OPTION_REQUEST, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the packet interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Call _nx_arp_packet_receive. */ + _nx_arp_packet_receive(&ip_0, my_packet); + + /* Allocate ARP packet, */ + status = arp_packet_allocate(&ip_0, &my_packet, NX_ARP_OPTION_REQUEST, IP_ADDRESS(1, 2, 3, 4), 0x0022, 0x22334456, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the packet interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Call _nx_arp_packet_receive. */ + _nx_arp_packet_receive(&ip_0, my_packet); + + + /* Hit false condition. + if ((sender_physical_msw != interface_ptr -> nx_interface_physical_address_msw) || + (sender_physical_lsw != interface_ptr -> nx_interface_physical_address_lsw)) + */ + + /* Set the interface address. */ + ip_0.nx_ip_interface[0].nx_interface_ip_address = IP_ADDRESS(1, 2, 3, 4); + + /* Clear the probe address. */ + ip_0.nx_ip_interface[0].nx_interface_ip_probe_address = IP_ADDRESS(0, 0, 0, 0); + + /* Allocate ARP packet, */ + status = arp_packet_allocate(&ip_0, &my_packet, NX_ARP_OPTION_REQUEST, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the packet interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Call _nx_arp_packet_receive. */ + _nx_arp_packet_receive(&ip_0, my_packet); + + /* Allocate ARP packet, */ + status = arp_packet_allocate(&ip_0, &my_packet, NX_ARP_OPTION_REQUEST, IP_ADDRESS(1, 2, 3, 4), 0x0022, 0x22334456, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the packet interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Call _nx_arp_packet_receive. */ + _nx_arp_packet_receive(&ip_0, my_packet); + + /* Hit false condition. + if (((ip_ptr -> nx_ip_arp_allocate)(ip_ptr, &(ip_ptr -> nx_ip_arp_table[index]), NX_FALSE)) == NX_SUCCESS) + */ + + /* Set the IP address. */ + address = 20; + + /* Set the physical address. */ + msw = 0x0033; + lsw = 0x22334457; + + /* Loop to added the static entries to fill the arp entries. */ + for (i = 0; i < arp_entries; i++) + { + + /* Set a static ARP entry. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, address), msw, lsw); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address ++; + + /* Update the physical address. */ + lsw ++; + } + } + + /* Allocate ARP packet, */ + status = arp_packet_allocate(&ip_0, &my_packet, NX_ARP_OPTION_REQUEST, IP_ADDRESS(1, 2, 3, 10), 0x0011, 0x22334458, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the packet interface. */ + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + + /* Call _nx_arp_packet_receive. */ + _nx_arp_packet_receive(&ip_0, my_packet); + + /* Test packet_ptr -> nx_packet_length < NX_ARP_MESSAGE_SIZE. */ + /* Allocate ARP packet, */ + status = arp_packet_allocate(&ip_0, &my_packet, NX_ARP_OPTION_REQUEST, IP_ADDRESS(1, 2, 3, 10), 0x0011, 0x22334458, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the packet length. */ + my_packet -> nx_packet_length -= 1; + + /* Call _nx_arp_packet_receive. */ + _nx_arp_packet_receive(&ip_0, my_packet); + + /* Update the address. */ + address --; + lsw --; + + /* Loop to delete the static entries. */ + for (i = 0; i < arp_entries; i++) + { + + /* Set a static ARP entry. */ + status = nx_arp_static_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, address), msw, lsw); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address --; + + /* Update the physical address. */ + lsw --; + } + } + + + +#ifndef NX_DISABLE_ASSERT + /* Test _nx_arp_packet_send(). */ + /* Hit NX_ASSERT(nx_interface != NX_NULL); */ + + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); +#endif /* NX_DISABLE_ASSERT */ +#endif /* __PRODUCT_NETXDUO__ */ + + + + /* Test _nx_arp_periodic_update(). */ + +#if 0 + /* Hit flase condition. + if ((arp_entry -> nx_arp_physical_address_msw) || (arp_entry -> nx_arp_physical_address_lsw)) + */ + ip_0.nx_ip_arp_dynamic_active_count ++; + ip_0.nx_ip_arp_dynamic_list = &arp_entry; + arp_entry.nx_arp_entry_next_update = 1; + arp_entry.nx_arp_physical_address_msw = 0x0000; + arp_entry.nx_arp_physical_address_lsw = 0x22334456; + arp_entry.nx_arp_retries = 0; + arp_entry.nx_arp_active_list_head = NX_NULL; + arp_entry.nx_arp_pool_next = &arp_entry; + arp_entry.nx_arp_pool_previous = &arp_entry; + arp_entry.nx_arp_packets_waiting = NX_NULL; + _nx_arp_periodic_update(&ip_0); + + /* Hit flase condition. + if ((arp_entry -> nx_arp_physical_address_msw) || (arp_entry -> nx_arp_physical_address_lsw)) + */ + ip_0.nx_ip_arp_dynamic_active_count ++; + ip_0.nx_ip_arp_dynamic_list = &arp_entry; + arp_entry.nx_arp_entry_next_update = 1; + arp_entry.nx_arp_physical_address_msw = 0x0011; + arp_entry.nx_arp_physical_address_lsw = 0x00000000; + arp_entry.nx_arp_retries = 0; + arp_entry.nx_arp_active_list_head = NX_NULL; + arp_entry.nx_arp_pool_next = &arp_entry; + arp_entry.nx_arp_pool_previous = &arp_entry; + arp_entry.nx_arp_packets_waiting = NX_NULL; + _nx_arp_periodic_update(&ip_0); + + /* Hit flase condition. + if ((arp_entry -> nx_arp_physical_address_msw) || (arp_entry -> nx_arp_physical_address_lsw)) + */ + ip_0.nx_ip_arp_dynamic_active_count ++; + ip_0.nx_ip_arp_dynamic_list = &arp_entry; + arp_entry.nx_arp_entry_next_update = 1; + arp_entry.nx_arp_physical_address_msw = 0x0000; + arp_entry.nx_arp_physical_address_lsw = 0x00000000; + arp_entry.nx_arp_retries = 0; + arp_entry.nx_arp_active_list_head = NX_NULL; + arp_entry.nx_arp_pool_next = &arp_entry; + arp_entry.nx_arp_pool_previous = &arp_entry; + arp_entry.nx_arp_packets_waiting = NX_NULL; + arp_entry.nx_arp_ip_address = IP_ADDRESS(1, 2, 3, 10); + arp_entry.nx_arp_ip_interface = &ip_0.nx_ip_interface[0]; + _nx_arp_periodic_update(&ip_0); +#endif + + /* Hit flase condition. + if ((arp_entry -> nx_arp_physical_address_msw) || (arp_entry -> nx_arp_physical_address_lsw)) + + if (arp_entry -> nx_arp_active_list_head) + + if (arp_entry != arp_entry -> nx_arp_pool_next) + */ + ip_0.nx_ip_arp_dynamic_active_count ++; + ip_0.nx_ip_arp_dynamic_list = &arp_entry; + arp_entry.nx_arp_entry_next_update = 1; + arp_entry.nx_arp_physical_address_msw = 0; + arp_entry.nx_arp_physical_address_lsw = 0; + arp_entry.nx_arp_retries = NX_ARP_MAXIMUM_RETRIES; + arp_entry.nx_arp_active_list_head = NX_NULL; + arp_entry.nx_arp_pool_next = &arp_entry; + arp_entry.nx_arp_pool_previous = &arp_entry; + arp_entry.nx_arp_packets_waiting = NX_NULL; + _nx_arp_periodic_update(&ip_0); + + + /* Hit flase condition. + if (*(arp_entry -> nx_arp_active_list_head) == arp_entry) + */ + arp_active_list = &arp_entry_next; + ip_0.nx_ip_arp_dynamic_active_count ++; + ip_0.nx_ip_arp_dynamic_list = &arp_entry; + arp_entry.nx_arp_entry_next_update = 1; + arp_entry.nx_arp_physical_address_msw = 0; + arp_entry.nx_arp_physical_address_lsw = 0; + arp_entry.nx_arp_retries = NX_ARP_MAXIMUM_RETRIES; + arp_entry.nx_arp_active_list_head = &arp_active_list; + arp_entry.nx_arp_active_next = arp_active_list; + arp_entry.nx_arp_active_previous = &arp_entry; + arp_entry.nx_arp_packets_waiting = NX_NULL; + arp_active_list -> nx_arp_active_next = &arp_entry; + _nx_arp_periodic_update(&ip_0); + + + +#ifdef __PRODUCT_NETXDUO__ + /* Test _nx_arp_static_entry_create */ + /* Hit false condition if (ip_ptr -> nx_ip_arp_dynamic_list == arp_ptr) */ + _nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer += 1024; + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 29), 0x0011, 0x22334478); /* arp index: 0 */ + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 61), 0x0011, 0x22334488); /* arp index: 0 */ + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 62), 0x0011, 0x22334499); /* arp index: 1 */ + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + _nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 61), 0x0011, 0x22334488); + + /* Recover, delete the arp entry. */ + status = nx_arp_dynamic_entries_invalidate(&ip_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_arp_static_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, 61), 0x0011, 0x22334488); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + + /* Test _nx_arp_hardware_address_find */ + /* Hit false condition (arp_entry -> nx_arp_physical_address_msw | arp_entry -> nx_arp_physical_address_lsw)) for static arp list */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 61), 0x0011, 0x22334488); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 61), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0011) || (physical_lsw != 0x22334488)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the MAC address. */ + ip_0.nx_ip_arp_static_list -> nx_arp_physical_address_msw = 0x0000; + ip_0.nx_ip_arp_static_list -> nx_arp_physical_address_lsw = 0x22334488; + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 61), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0000) || (physical_lsw != 0x22334488)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the MAC address. */ + ip_0.nx_ip_arp_static_list -> nx_arp_physical_address_msw = 0x0011; + ip_0.nx_ip_arp_static_list -> nx_arp_physical_address_lsw = 0x00000000; + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 61), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0011) || (physical_lsw != 0x00000000)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the MAC address. */ + ip_0.nx_ip_arp_static_list -> nx_arp_physical_address_msw = 0x0000; + ip_0.nx_ip_arp_static_list -> nx_arp_physical_address_lsw = 0x22334488; + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 61), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0000) || (physical_lsw != 0x22334488)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the MAC address. */ + ip_0.nx_ip_arp_static_list -> nx_arp_physical_address_msw = 0x0000; + ip_0.nx_ip_arp_static_list -> nx_arp_physical_address_lsw = 0x00000000; + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 61), &physical_msw, &physical_lsw); + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Recover the MAC address. */ + ip_0.nx_ip_arp_static_list -> nx_arp_physical_address_msw = 0x0011; + ip_0.nx_ip_arp_static_list -> nx_arp_physical_address_lsw = 0x22334488; + + status = nx_arp_static_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, 61), 0x0011, 0x22334488); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Hit false condition (arp_entry -> nx_arp_physical_address_msw | arp_entry -> nx_arp_physical_address_lsw)) for dynamic arp list */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 61), 0x0011, 0x22334488); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 61), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0011) || (physical_lsw != 0x22334488)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the MAC address. */ + ip_0.nx_ip_arp_dynamic_list -> nx_arp_physical_address_msw = 0x0000; + ip_0.nx_ip_arp_dynamic_list -> nx_arp_physical_address_lsw = 0x22334488; + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 61), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0000) || (physical_lsw != 0x22334488)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the MAC address. */ + ip_0.nx_ip_arp_dynamic_list -> nx_arp_physical_address_msw = 0x0011; + ip_0.nx_ip_arp_dynamic_list -> nx_arp_physical_address_lsw = 0x00000000; + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 61), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0011) || (physical_lsw != 0x00000000)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the MAC address. */ + ip_0.nx_ip_arp_dynamic_list -> nx_arp_physical_address_msw = 0x0000; + ip_0.nx_ip_arp_dynamic_list -> nx_arp_physical_address_lsw = 0x22334488; + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 61), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0000) || (physical_lsw != 0x22334488)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the MAC address. */ + ip_0.nx_ip_arp_dynamic_list -> nx_arp_physical_address_msw = 0x0000; + ip_0.nx_ip_arp_dynamic_list -> nx_arp_physical_address_lsw = 0x00000000; + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 61), &physical_msw, &physical_lsw); + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Recover the MAC address. */ + ip_0.nx_ip_arp_dynamic_list -> nx_arp_physical_address_msw = 0x0011; + ip_0.nx_ip_arp_dynamic_list -> nx_arp_physical_address_lsw = 0x22334488; + + status = nx_arp_dynamic_entries_invalidate(&ip_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + +#ifdef __PRODUCT_NETXDUO__ + /* Test _nx_arp_static_entry_create() */ + /* Hit condition of if (arp_ptr -> nx_arp_route_static == NX_FALSE) */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 61), 0x0011, 0x22334488); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create static entry. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 61), 0x0011, 0x22334488); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create static entry. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 61), 0x0011, 0x22334488); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Recover, delete the ARP entry. */ + status = nx_arp_static_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, 61), 0x0011, 0x22334488); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +#ifdef __PRODUCT_NETXDUO__ +UINT arp_packet_allocate(NX_IP *ip_ptr, NX_PACKET **packet_ptr, UINT arp_type, + ULONG source_ip, ULONG source_physical_msw, ULONG source_physical_lsw, + ULONG target_ip, ULONG target_physical_msw, ULONG target_physical_lsw) +{ + +NX_PACKET *request_ptr; +ULONG *message_ptr; + + + /* Allocate a packet to build the ARP message in. */ + if (nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &request_ptr, NX_PHYSICAL_HEADER, NX_NO_WAIT)) + { + + /* Error getting packet, so just get out! */ + return (NX_FALSE); + } + + /* Build the ARP request packet. */ + + /* Setup the size of the ARP message. */ + request_ptr -> nx_packet_length = NX_ARP_MESSAGE_SIZE; + + /* Setup the append pointer to the end of the message. */ + request_ptr -> nx_packet_append_ptr = request_ptr -> nx_packet_prepend_ptr + NX_ARP_MESSAGE_SIZE; + + /* Setup the pointer to the message area. */ + message_ptr = (ULONG *) request_ptr -> nx_packet_prepend_ptr; + + /* Write the Hardware type into the message. */ + *message_ptr = (ULONG) (NX_ARP_HARDWARE_TYPE << 16) | (NX_ARP_PROTOCOL_TYPE); + *(message_ptr+1) = (ULONG) (NX_ARP_HARDWARE_SIZE << 24) | (NX_ARP_PROTOCOL_SIZE << 16) | arp_type; + *(message_ptr+2) = (ULONG) (source_physical_msw << 16) | (source_physical_lsw >> 16); + *(message_ptr+3) = (ULONG) (source_physical_lsw << 16) | (source_ip >> 16); + *(message_ptr+4) = (ULONG) (source_ip << 16) | (target_physical_msw & 0xFFFF); + *(message_ptr+5) = (ULONG) target_physical_lsw; + *(message_ptr+6) = (ULONG) target_ip; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Return packet. */ + *packet_ptr = request_ptr; + + return (NX_TRUE); +} + +#ifndef NX_DISABLE_ASSERT +/* Define the test threads. */ + +static void thread_for_assert_entry(ULONG thread_input) +{ + + /* Call function with NULL interface. */ + _nx_arp_packet_send(&ip_0, IP_ADDRESS(1, 2, 3, 5), NX_NULL); +} +#endif /* NX_DISABLE_ASSERT */ + +#endif /* __PRODUCT_NETXDUO__ */ +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_branch_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Branch Test...........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_arp_conflict_test.c b/test/regression/netxduo_test/netx_arp_conflict_test.c new file mode 100644 index 00000000..40a14911 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_conflict_test.c @@ -0,0 +1,183 @@ +/* This NetX test concentrates on the ARP conflict operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_arp.h" + +#define DEMO_STACK_SIZE 2048 + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_ARP_DEFEND_BY_REPLY) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG arp_packet_received; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern VOID _nx_arp_packet_send(NX_IP *ip_ptr, ULONG destination_ip, NX_INTERFACE *nx_interface); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_conflict_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + arp_packet_received = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + + printf("NetX Test: ARP Conflict Test........................................."); + + /* Setup callback function. */ + advanced_packet_process_callback = my_packet_process; + + /* Send conflict ARP packet. */ + _nx_arp_packet_send(&ip_0, IP_ADDRESS(1, 2, 3, 4), &ip_0.nx_ip_interface[0]); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Three packets: one sent by this thread, one sent by ip_1 and one sent by ip_0. */ + if(arp_packet_received != 3) + error_counter++; + + /* Send conflict ARP packet in 10 seconds. */ + _nx_arp_packet_send(&ip_0, IP_ADDRESS(1, 2, 3, 4), &ip_0.nx_ip_interface[0]); + + /* Only more packet sent by this thread. */ + if(arp_packet_received != 4) + error_counter++; + + tx_thread_sleep(10 * NX_IP_PERIODIC_RATE); + + /* Send conflict ARP packet after 10 seconds. */ + _nx_arp_packet_send(&ip_0, IP_ADDRESS(1, 2, 3, 4), &ip_0.nx_ip_interface[0]); + + /* Three more packets: one sent by this thread, one sent by ip_1 and one sent by ip_0. */ + if(arp_packet_received != 7) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +ULONG *message; + + /* Counter ARP packet only. */ + if (packet_ptr -> nx_packet_length == NX_ARP_MESSAGE_SIZE) + { + message = (ULONG *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(*message); + if(*message == (ULONG)((NX_ARP_HARDWARE_TYPE << 16) | NX_ARP_PROTOCOL_TYPE)) + arp_packet_received++; + NX_CHANGE_ULONG_ENDIAN(*message); + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_conflict_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Conflict Test.........................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_arp_dual_pool_test.c b/test/regression/netxduo_test/netx_arp_dual_pool_test.c new file mode 100644 index 00000000..f6e8cf53 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_dual_pool_test.c @@ -0,0 +1,217 @@ +/* This NetX test concentrates on the ARP packets from dual pool. */ + +#include "nx_api.h" +#include "nx_arp.h" + +extern void test_control_return(UINT status); + +#if defined(NX_ENABLE_DUAL_PACKET_POOL) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG arp_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dual_pool_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + arp_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 512 + sizeof(NX_PACKET)); + pointer = pointer + 512 + sizeof(NX_PACKET); + + if (status) + error_counter++; + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 256, pointer, 256 + sizeof(NX_PACKET)); + pointer = pointer + 256 + sizeof(NX_PACKET); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; + + /* Print out some test information banners. */ + printf("NetX Test: ARP Dual Pool Test........................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process; + + /* Send a gratuitous ARP message. */ + nx_arp_gratuitous_send(&ip_0, NX_NULL); + + /* Check the arp_counter. */ + if (arp_counter != 1) + { + error_counter++; + } + + /* Allocate the only one packet from default packet pool. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT); + if (status) + { + error_counter++; + } + + /* Send a gratuitous ARP message. */ + nx_arp_gratuitous_send(&ip_0, NX_NULL); + + /* Check the arp_counter. */ + if (arp_counter != 1) + { + error_counter++; + } + + /* Now set dual packet pool. */ + status = nx_ip_auxiliary_packet_pool_set(&ip_0, &pool_1); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Send a gratuitous ARP message. */ + nx_arp_gratuitous_send(&ip_0, NX_NULL); + + /* Check the arp_counter. */ + if (arp_counter != 2) + { + error_counter++; + } + + /* Allocate the only one packet from default packet pool. */ + status = nx_packet_allocate(&pool_1, &packet_ptr, 0, NX_NO_WAIT); + if (status) + { + error_counter++; + } + + /* Send a gratuitous ARP message. */ + nx_arp_gratuitous_send(&ip_0, NX_NULL); + + /* Check the arp_counter. */ + if (arp_counter != 2) + { + error_counter++; + } + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Check the packet length. */ + if (packet_ptr ->nx_packet_length == NX_ARP_MESSAGE_SIZE) + { + + /* Update the arp_counter. */ + arp_counter++; + } + + /* Return to caller. */ + return NX_TRUE; +} +#else /* NX_ENABLE_DUAL_PACKET_POOL */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dual_pool_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Dual Pool Test........................................N/A\n"); + + test_control_return(3); + +} +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ diff --git a/test/regression/netxduo_test/netx_arp_dynamic_entry_fail_test.c b/test/regression/netxduo_test/netx_arp_dynamic_entry_fail_test.c new file mode 100644 index 00000000..01e739af --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_dynamic_entry_fail_test.c @@ -0,0 +1,176 @@ +/* This NetX test concentrates on the ARP dynamic entry retries has been exceeded. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_system.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_fail_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: ARP Dynamic Entry Fail Test..............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the packet count. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an IP address that does not exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping another IP address that does not exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 37), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the packet count, one ping packet should be exi. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total - 2) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep to test the _nx_arp_periodic_update. */ + tx_thread_sleep((NX_ARP_MAXIMUM_RETRIES + 1) * NX_ARP_UPDATE_RATE * NX_IP_PERIODIC_RATE); + + /* Check the packet count. */ + if ((pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_fail_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Dynamic Entry Fail Test...............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_arp_dynamic_entry_set_test.c b/test/regression/netxduo_test/netx_arp_dynamic_entry_set_test.c new file mode 100644 index 00000000..b725317d --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_dynamic_entry_set_test.c @@ -0,0 +1,202 @@ +/* This NetX test concentrates on the ARP dynamic entry operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_set_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_address; +ULONG physical_msw; +ULONG physical_lsw; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP Dynamic Entry Set Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry that can be reached. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 5), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0011) || (physical_lsw != 0x22334457)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the IP address for existence entry. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334457); + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 5))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry that cannot be reached. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 4, 5), 0x0011, 0x22334458); + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the gateway. */ + status = nx_ip_gateway_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 1)); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry that cannot be reached again. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 4, 5), 0x0011, 0x22334458); + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry that cannot be reached again. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 15), 0x00, 0x22334459); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0000, 0x22334459); + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 15))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 15), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x00) || (physical_lsw != 0x22334459)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* The test was successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_set_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Dynamic Entry Set Test................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_arp_dynamic_entry_test.c b/test/regression/netxduo_test/netx_arp_dynamic_entry_test.c new file mode 100644 index 00000000..35116055 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_dynamic_entry_test.c @@ -0,0 +1,423 @@ +/* This NetX test concentrates on the ARP dynamic entry operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG ip_address; +ULONG physical_msw; +ULONG physical_lsw; +ULONG requests_sent; +ULONG requests_received; +ULONG responses_sent; +ULONG responses_received; +ULONG dynamic_entries; +ULONG static_entries; +ULONG aged_entries; +ULONG invalid_messages; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP Dynamic Entry Processing Test........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334457); + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 5))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 5), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0011) || (physical_lsw != 0x22334457)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a invalid dynamic ARP entry, the destination address isnot directly accessible . */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0x0011, 0x22334458); + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the IP address for inexistence entry. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334458); + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address for inexistence entry. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(2, 2, 3, 5), &physical_msw, &physical_lsw); + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get nothing from ARP information. */ + status = nx_arp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get ARP information. */ + status = nx_arp_info_get(&ip_0, &requests_sent, &requests_received, &responses_sent, &responses_received, &dynamic_entries, &static_entries, &aged_entries, &invalid_messages); + + /* Check for error conditions. */ + if ((status) || (requests_received) || (requests_sent) || (responses_sent) || (responses_received) || (dynamic_entries != 1) || (static_entries) || (aged_entries) || (invalid_messages)) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + /* Test the API arp entry delete. */ + status = nx_arp_entry_delete(&ip_0, IP_ADDRESS(1,2,3,5)); + if(status != NX_SUCCESS) + error_counter++; +#endif /* __PRODUCT_NETXDUO__ */ + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_1, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Dynamic Entry Processing Test.........................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_arp_dynamic_entry_test2.c b/test/regression/netxduo_test/netx_arp_dynamic_entry_test2.c new file mode 100644 index 00000000..e49f72b7 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_dynamic_entry_test2.c @@ -0,0 +1,260 @@ +/* This NetX test concentrates on the ARP dynamic entry operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_system.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; +static CHAR set_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_test2_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + /* Print out some test information banners. */ + printf("NetX Test: ARP Dynamic Entry Processing Test2........................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the packet count. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an IP address that does exist, but the peer IP instance disable the ARP feature. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the packet count, one ping packet should be exi. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total - 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the all dynamic entries. */ + status = nx_arp_dynamic_entries_invalidate(&ip_0); + + /* Check the status and packet count. */ + if ((status) || (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set packet process to detect the ARP message and set the dynamic entry, the ping operation should be correct. */ + advanced_packet_process_callback = my_packet_process; + + /* Update the counter. */ + set_counter = 0; + + /* Now ping an IP address that does exist. */ + /* The reply packet contains checksum 0. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 1) || (pings_sent != 2) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28 /* data only */) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; + + /* Update the counter. */ + set_counter ++; + + /* Check the arp counter. */ + if (set_counter == 1) + { + + /* Set a dynamic ARP entry for IP instance0, the ping will be sent. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + { + error_counter++; + } + + /* Set a dynamic ARP entry for IP instance0, the ping will be response. */ + status = nx_arp_dynamic_entry_set(&ip_1, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + if (status) + { + error_counter++; + } + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Dynamic Entry Processing Test2........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_arp_dynamic_entry_test3.c b/test/regression/netxduo_test/netx_arp_dynamic_entry_test3.c new file mode 100644 index 00000000..fb2639f5 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_dynamic_entry_test3.c @@ -0,0 +1,174 @@ +/* This NetX test concentrates on sending packet when ARP entry is not completed. */ + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_test3_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: ARP Dynamic Entry Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delay the first ARP request by 1 second. */ + advanced_packet_process_callback = packet_process; + + /* Create a dynamic entry with zero MAC. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0, 0); + + /* Check the status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now send ping with fragment disabled. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "Test", 4, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + advanced_packet_process_callback = NX_NULL; + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_test3_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Dynamic Entry Test....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_arp_dynamic_entry_timeout_test.c b/test/regression/netxduo_test/netx_arp_dynamic_entry_timeout_test.c new file mode 100644 index 00000000..8a283de7 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_dynamic_entry_timeout_test.c @@ -0,0 +1,160 @@ +/* This NetX test concentrates on the ARP dynamic entry timeouts on NX_ARP_MAXIMUM_RETRIES * NX_ARP_UPDATE_RATE operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_timeout_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_address; +UINT i; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP Dynamic Entry Timeout Test............................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#if (NX_ARP_EXPIRATION_RATE != NX_ARP_UPDATE_RATE) + ip_0.nx_ip_arp_dynamic_list -> nx_arp_entry_next_update = NX_ARP_UPDATE_RATE; +#endif /* (NX_ARP_EXPIRATION_RATE == 0) */ + + for (i = 0; i < NX_ARP_MAXIMUM_RETRIES + 1; i++) + { + tx_thread_sleep((NX_ARP_UPDATE_RATE - 1) * NX_IP_PERIODIC_RATE); + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334457); + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 5))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334457); + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_entry_timeout_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Dynamic Entry Timeout Test............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_arp_dynamic_invalidate_test.c b/test/regression/netxduo_test/netx_arp_dynamic_invalidate_test.c new file mode 100644 index 00000000..9d6ff9b1 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_dynamic_invalidate_test.c @@ -0,0 +1,405 @@ +/* This NetX test concentrates on the ARP dynamic entry invalidate operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_invalidate_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG ip_address; +ULONG physical_msw; +ULONG physical_lsw; +ULONG requests_sent; +ULONG requests_received; +ULONG responses_sent; +ULONG responses_received; +ULONG dynamic_entries; +ULONG static_entries; +ULONG aged_entries; +ULONG invalid_messages; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP Dynamic Invalidate Processing Test...................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup multiple dynamic ARP entries. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + status += nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 6), 0x0011, 0x22334458); + status += nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 7), 0x0011, 0x22334459); + status += nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 39), 0x0011, 0x2233445a); + status += nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 37), 0x0011, 0x2233445b); + status += nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 69), 0x0011, 0x2233445c); + + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334457); + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 5))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 5), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0011) || (physical_lsw != 0x22334457)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send a gratuitous ARP message. */ + status = nx_arp_gratuitous_send(&ip_0, NX_NULL); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Invalidate all ARP dynamic entries. */ + status = nx_arp_dynamic_entries_invalidate(&ip_0); + + /* Get ARP information. */ + status = nx_arp_info_get(&ip_0, &requests_sent, &requests_received, &responses_sent, &responses_received, &dynamic_entries, &static_entries, &aged_entries, &invalid_messages); + + /* Check for error conditions - and look for the ARP message being sent! */ + if ((status) || (requests_received)|| (responses_sent) || (responses_received) || (dynamic_entries) || (static_entries) || (aged_entries) || (invalid_messages)) + error_counter++; + +#ifndef NX_DISABLE_ARP_INFO + if(requests_sent != 1) + error_counter++; +#endif + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_1, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_dynamic_invalidate_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Dynamic Invalidate Processing Test....................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_arp_entry_abnormal_operation_test.c b/test/regression/netxduo_test/netx_arp_entry_abnormal_operation_test.c new file mode 100644 index 00000000..5df330b0 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_entry_abnormal_operation_test.c @@ -0,0 +1,570 @@ +/* This NetX test concentrates on the ARP dynamic/static entry abnormal operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if defined (__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define NX_ETHERNET_IP 0x0800 +#define NX_ETHERNET_ARP 0x0806 +#define NX_ETHERNET_RARP 0x8035 +#define NX_ETHERNET_IPV6 0x86DD + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static UINT arp_receive; +static UINT icmp_receive; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_entry_abnormal_operation_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Attach new interface. */ + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_256); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing. */ + status = nx_icmp_enable(&ip_0); + + /* Check ICMP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG ip_address; +ULONG physical_msw; +ULONG physical_lsw; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP Entry Abnormal Operation Test........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to detect the packet. */ + advanced_packet_process_callback = my_packet_process; + + /* Clear the arp receive and icmp receive falg. */ + arp_receive = NX_FALSE; + icmp_receive = NX_FALSE; + + /* Ping an IP address that does exist, but the peer IP instance disable the ARP feature. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the arp receive and icmp receive flag. */ + if ((arp_receive != NX_TRUE) || (icmp_receive != NX_FALSE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_dynamic_active_count != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_static_entries != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Clear the arp receive and icmp receive falg. */ + arp_receive = NX_FALSE; + icmp_receive = NX_FALSE; + + /* Set a dynamic ARP entry with the same IP address. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0x0011, 0x22334467); + + /* Determine if the timeout error occurred. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the arp receive and icmp receive flag. */ + if ((arp_receive != NX_FALSE) || (icmp_receive != NX_TRUE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_dynamic_active_count != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_static_entries != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Clear the arp receive and icmp receive falg. */ + arp_receive = NX_FALSE; + icmp_receive = NX_FALSE; + + /* Ping an IP address that does exist, but the peer IP instance disable the ARP feature. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 50); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the arp receive and icmp receive flag. */ + if ((arp_receive != NX_FALSE) || (icmp_receive != NX_TRUE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_dynamic_active_count != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_static_entries != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Clear the arp receive and icmp receive falg. */ + arp_receive = NX_FALSE; + icmp_receive = NX_FALSE; + + /* Setup multiple static ARP entries. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0x0011, 0x22334467); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the arp receive and icmp receive flag. */ + if ((arp_receive != NX_FALSE) || (icmp_receive != NX_FALSE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_dynamic_active_count != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_static_entries != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334467); + if ((status) || (ip_address != IP_ADDRESS(2, 2, 3, 5))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(2, 2, 3, 5), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0011) || (physical_lsw != 0x22334467)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Clear the arp receive and icmp receive falg. */ + arp_receive = NX_FALSE; + icmp_receive = NX_FALSE; + + /* Ping an IP address that does exist, but the peer IP instance disable the ARP feature. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the arp receive and icmp receive flag. */ + if ((arp_receive != NX_FALSE) || (icmp_receive != NX_TRUE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_dynamic_active_count != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_static_entries != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0x0011, 0x22334467); + +#ifdef __PRODUCT_NETXDUO__ + /* Determine if the timeout error occurred. */ + if (status == NX_SUCCESS) +#else + if (status) +#endif + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_dynamic_active_count != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_static_entries != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Detach the second interface. */ + status = nx_ip_interface_detach(&ip_0, 1); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_dynamic_active_count != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_static_entries != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Attach interface again. */ + status = nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_256); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to detect the packet. */ + advanced_packet_process_callback = my_packet_process; + + /* Clear the arp receive and icmp receive falg. */ + arp_receive = NX_FALSE; + icmp_receive = NX_FALSE; + + /* Ping an IP address that does exist, but the peer IP instance disable the ARP feature. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the arp receive and icmp receive flag. */ + if ((arp_receive != NX_TRUE) || (icmp_receive != NX_FALSE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_dynamic_active_count != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_static_entries != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Clear the arp receive and icmp receive falg. */ + arp_receive = NX_FALSE; + icmp_receive = NX_FALSE; + + /* Setup multiple static ARP entries. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0x0011, 0x22334467); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the arp receive and icmp receive flag. */ + if ((arp_receive != NX_FALSE) || (icmp_receive != NX_TRUE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_dynamic_active_count != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the dynamic entry count. */ + if (ip_0.nx_ip_arp_static_entries != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + printf("SUCCESS!\n"); + test_control_return(0); +} +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +#ifdef __PRODUCT_NETXDUO__ +NX_IPV4_HEADER *ip_header_ptr; +#else +NX_IP_HEADER *ip_header_ptr; +#endif +ULONG protocol; + + /* For this test case, only ARP and ICMP packet will be send. */ + + /* Check the packet length. */ + if (packet_ptr -> nx_packet_length >= 28) + { + +#if defined(__PRODUCT_NETXDUO__) + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + +#else + ip_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#endif + + /* Get IP header. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + protocol = (ip_header_ptr -> nx_ip_header_word_2 >> 16) & 0xFF; + + /* Is ICMP packet? */ + if(protocol == 1) + { + + /* Set the flag. */ + icmp_receive = NX_TRUE; + } + else + { + + /* Set the flag. */ + arp_receive = NX_TRUE; + } + } + + /* Release the packet. */ + nx_packet_release(packet_ptr); + + return NX_FALSE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_entry_abnormal_operation_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: ARP Entry Abnormal Operation Test.........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_arp_entry_cache_test.c b/test/regression/netxduo_test/netx_arp_entry_cache_test.c new file mode 100644 index 00000000..89bc57f5 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_entry_cache_test.c @@ -0,0 +1,383 @@ +/* This NetX test concentrates on the ARP dynamic entry operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define ARP_ENTRY_COUNT 35 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_entry_cache_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0, the ARP cache can store five entries. */ + status = nx_arp_enable(&ip_0, (void *) pointer, ARP_ENTRY_COUNT * sizeof(NX_ARP)); + pointer = pointer + ARP_ENTRY_COUNT * sizeof(NX_ARP); + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +INT i; +UINT status; +ULONG physical_msw; +ULONG physical_lsw; +ULONG address; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP Entry CACHE Processing Test..........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address. */ + address = 5; + + /* Set the physical address. */ + physical_msw = 0x0011; + physical_lsw = 0x22334457; + + /* Loop to added the dynamic entries, the dynamic entry can be replaced. . */ + for (i = 0; i < 3 * ARP_ENTRY_COUNT; i++) + { + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, address), physical_msw, physical_lsw); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address ++; + + /* Update the physical address. */ + physical_lsw ++; + } + } + + /* Delete the entry that does not exist. */ + status = nx_arp_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, address)); + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address --; + + /* Update the physical address. */ + physical_lsw --; + + /* Update the idex. */ + i --; + } + + /* Loop to delete the dynamic entries, the dynamic entry can be replaced. . */ + for (; i >= 2 * ARP_ENTRY_COUNT; i--) + { + + /* Delete a dynamic ARP entry. */ + status = nx_arp_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, address)); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address --; + + /* Update the physical address. */ + physical_lsw --; + } + } + + /* Loop to delete the replaced dynamic entries. */ + for (; i >= 0; i--) + { + + /* Delete a dynamic ARP entry. */ + status = nx_arp_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, address)); + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address --; + + /* Update the physical address. */ + physical_lsw --; + } + } + + /* Set the IP address. */ + address = 5; + + /* Set the physical address. */ + physical_msw = 0x0011; + physical_lsw = 0x22334457; + + /* Loop to added the dynamic entries, 35. */ + for (i = 0; i < ARP_ENTRY_COUNT; i++) + { + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, address), physical_msw, physical_lsw); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address ++; + + /* Update the physical address. */ + physical_lsw ++; + } + } + + /* Loop to added the static entries, 35. */ + for (; i < 2 * ARP_ENTRY_COUNT; i++) + { + + /* Set a static ARP entry. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, address), physical_msw, physical_lsw); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address ++; + + /* Update the physical address. */ + physical_lsw ++; + } + } + + /* Set a static ARP entry, should be fail. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, address), physical_msw, physical_lsw); + if (status != NX_NO_MORE_ENTRIES) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry, should be fail. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, address), physical_msw, physical_lsw); + if (status != NX_NO_MORE_ENTRIES) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Update the IP address. */ + address --; + + /* Update the physical address. */ + physical_lsw --; + + /* Update the idex. */ + i --; + + /* Loop to delete the static entries. */ + for (; i >= ARP_ENTRY_COUNT; i--) + { + + /* Delete a static ARP entry. */ + status = nx_arp_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, address)); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address --; + + /* Update the physical address. */ + physical_lsw --; + } + } + + /* Loop to delete the replaced dynamic entries. */ + for (; i >= 0; i--) + { + + /* Delete a dynamic ARP entry. */ + status = nx_arp_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, address)); + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address --; + + /* Update the physical address. */ + physical_lsw --; + } + } + + /* Set the IP address. */ + address = 5; + + /* Set the physical address. */ + physical_msw = 0x0011; + physical_lsw = 0x22334457; + + /* Loop to added the dynamic entries, 35. */ + for (i = 0; i < ARP_ENTRY_COUNT; i++) + { + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, address), physical_msw, physical_lsw); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address ++; + + /* Update the physical address. */ + physical_lsw ++; + } + } + + /* Invalidate all dynamic entries. */ + status = nx_arp_dynamic_entries_invalidate(&ip_0); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_entry_cache_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Entry CACHE Processing Test...........................N/A\n"); + + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ + diff --git a/test/regression/netxduo_test/netx_arp_gratuitous_test.c b/test/regression/netxduo_test/netx_arp_gratuitous_test.c new file mode 100644 index 00000000..a5c49150 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_gratuitous_test.c @@ -0,0 +1,489 @@ +/* This NetX test concentrates on the ARP Gratuitous operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_arp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG announce_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_gratuitous_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + announce_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG ip_address; +ULONG physical_msw; +ULONG physical_lsw; +ULONG requests_sent; +ULONG requests_received; +ULONG responses_sent; +ULONG responses_received; +ULONG dynamic_entries; +ULONG static_entries; +ULONG aged_entries; +ULONG invalid_messages; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP Gratuitous Entry Processing Test......................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334457); + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 5))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 5), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0011) || (physical_lsw != 0x22334457)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the ARP packet. */ + advanced_packet_process_callback = my_packet_process; + + /* Send a gratuitous ARP message. */ + status = nx_arp_gratuitous_send(&ip_0, NX_NULL); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the ARP packet. */ + advanced_packet_process_callback = NX_NULL; + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get ARP information. */ + status = nx_arp_info_get(&ip_0, &requests_sent, &requests_received, &responses_sent, &responses_received, &dynamic_entries, &static_entries, &aged_entries, &invalid_messages); + + /* Check for error conditions - and look for the ARP message being sent! */ + if ((status) || (requests_received)|| (responses_sent) || (responses_received) || (dynamic_entries != 1) || (static_entries) || (aged_entries) || (invalid_messages)) + error_counter++; +#ifndef NX_DISABLE_ARP_INFO + if(requests_sent != 1) + error_counter++; +#endif + + /* Check announce_counter. */ + if (announce_counter == 0) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_1, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 200 /* 100 */); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +ULONG *message_ptr; +ULONG sender_physical_msw; +ULONG sender_physical_lsw; +ULONG sender_ip_address; +ULONG target_physical_msw; +ULONG target_physical_lsw; +ULONG target_ip_address; +ULONG message_type; + + /* Check the packet length. */ + if (packet_ptr ->nx_packet_length != NX_ARP_MESSAGE_SIZE) + { + + /* Update the error_counter. */ + error_counter++; + + /* Release the packet */ + nx_packet_release(packet_ptr); + + /* Return to caller. */ + return NX_FALSE; + } + + /* Setup a pointer to the ARP message. */ + message_ptr = (ULONG *) packet_ptr -> nx_packet_prepend_ptr; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Pickup the ARP message type. */ + message_type = (ULONG) (*(message_ptr+1) & 0xFFFF); + + /* Determine if the ARP message type is valid. */ + if (message_type != NX_ARP_OPTION_REQUEST) + { + + /* Update the error_counter. */ + error_counter++; + + /* Release the packet */ + nx_packet_release(packet_ptr); + + /* Return to caller. */ + return NX_FALSE; + } + + + /* Pick up the sender's physical address from the message. */ + sender_physical_msw = (*(message_ptr+2) >> 16); + sender_physical_lsw = (*(message_ptr+2) << 16) | (*(message_ptr+3) >> 16); + sender_ip_address = (*(message_ptr+3) << 16) | (*(message_ptr+4) >> 16); + target_physical_msw = (*(message_ptr+4) & 0x0000FFFF); + target_physical_lsw = *(message_ptr+5); + target_ip_address = *(message_ptr+6); + + /* Check the sender and target information. */ + if (((sender_physical_msw | sender_physical_lsw) != 0) && (sender_ip_address != 0) && + ((target_physical_msw | target_physical_lsw) == 0) && (target_ip_address != 0)) + announce_counter ++; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Return to caller. */ + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_gratuitous_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Gratuitous Entry Processing Test......................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_arp_invalid_type_test.c b/test/regression/netxduo_test/netx_arp_invalid_type_test.c new file mode 100644 index 00000000..cd7f4817 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_invalid_type_test.c @@ -0,0 +1,149 @@ +/* Test processing of ARP packet with invalid type. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ARP_INFO) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* ARP packet. + * Type: 0003. */ +static char ra_pkt[] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x0b, /* ...... . */ +0xc7, 0x94, 0x45, 0x96, 0x08, 0x06, 0x00, 0x01, /* ..E..... */ +0x08, 0x00, 0x06, 0x04, 0x00, 0x03, 0x20, 0x0b, /* ...... . */ +0xc7, 0x94, 0x45, 0x96, 0xc0, 0xa8, 0x64, 0x01, /* ..E...d. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xa8, /* ........ */ +0x64, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_invalid_type_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP */ + status = nx_arp_enable(&ip_0, pointer, 1024); + + /* Check ARP enable status. */ + if(status) + error_counter++; + pointer = pointer + 1024; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ARP Invalid Type Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Inject ARP packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ARP packet. */ + _nx_arp_packet_deferred_receive(&ip_0, packet_ptr); + + if (ip_0.nx_ip_arp_invalid_messages != 1) + error_counter++; + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_invalid_type_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Invalid Type Test.....................................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_arp_no_duplicate_entry_test.c b/test/regression/netxduo_test/netx_arp_no_duplicate_entry_test.c new file mode 100644 index 00000000..5b5186a5 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_no_duplicate_entry_test.c @@ -0,0 +1,425 @@ +/* Send ARP packets using the deferred receive service. This test checks that duplicate ARP entries are + not created, that existing matching ARP entries will be updated regardless of message type, and ARP probe + packets (zero sender IP address) are not entered into the ARP cache. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined (NX_DISABLE_ARP_AUTO_ENTRY) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#ifdef __PRODUCT_NETX__ +#define NX_ARP_TABLE_MASK NX_ROUTE_TABLE_MASK +#endif + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* ARP request packet. This test checks that request packets are checked for adding to/updating the ARP cache. + * src MAC: 20:0b:c7:94:45:96 + * src IP: 1.2.3.5. + * target MAC: 00:00:00:00:00:00 + * target IP: 1.2.3.4. */ +static char arp_request_pkt[] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x0b, /* ...... . */ +0xc7, 0x94, 0x45, 0x96, 0x08, 0x06, 0x00, 0x01, /* ..E..... */ +0x08, 0x00, 0x06, 0x04, 0x00, 0x01, + 0x20, 0x0b, /* ...... . */ +0xc7, 0x94, 0x45, 0x96, 0x01, 0x02, 0x03, 0x05, /* ..E..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* ........ */ +0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + + +/* Second ARP request packet + * src MAC: 20:0b:c7:94:45:97 The test is to check if the 20:0b:c7:94:45:96 entry is updated to 20:0b:c7:94:45:97 + there should not be duplicate entries for 1.2.3.5. + * src IP: 1.2.3.5. + * target MAC: 00:00:00:00:00:00 + * target IP: 1.2.3.4. */ +static char arp_request_pkt2[] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x0b, /* ...... . */ +0xc7, 0x94, 0x45, 0x97, 0x08, 0x06, 0x00, 0x01, /* ..E..... */ +0x08, 0x00, 0x06, 0x04, 0x00, 0x01, + 0x20, 0x0b, /* ...... . */ +0xc7, 0x94, 0x45, 0x97, 0x01, 0x02, 0x03, 0x05, /* ..E..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* ........ */ +0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + +/* An ARP reply packet; This tests that NetX checks responses for updating its ARP Cache + * src MAC: 30:1b:d7:a4:55:a6 + * src IP: 1.2.3.44. + * target MAC: 22:0b:c7:94:45:98 + * target IP: 1.2.3.6. */ +static char arp_reply_pkt[] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x30, 0x1b, /* ...... . */ +0xd7, 0xa4, 0x55, 0xa6, 0x08, 0x06, 0x00, 0x01, /* ..E..... */ +0x08, 0x00, 0x06, 0x04, 0x00, 0x02, + 0x30, 0x1b, /* ...... . */ +0xd7, 0xa4, 0x55, 0xa6, 0x01, 0x02, 0x03, 0x2c, /* ..E..... */ +0x22, 0x0b, 0xc7, 0x94, 0x45, 0x98, 0x01, 0x02, /* ........ */ +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + +/* An ARP probe packet - This test is to check that NetX does not create an entry for probe (sender address is zero) packets. + * src MAC: 00:b1:7d:4a:55:6a + * src IP: 0.0.0.0 + * target MAC: 00:00:00:00:00:00 + * target IP: 1.2.3.85. */ +static char arp_probe_pkt[] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xb1, /* ...... . */ +0x7d, 0x4a, 0x55, 0x6a, 0x08, 0x06, 0x00, 0x01, /* ..E..... */ +0x08, 0x00, 0x06, 0x04, 0x00, 0x01, + + 0x00, 0xb1, /* ...... . */ +0x7d, 0x4a, 0x55, 0x6a, 0x00, 0x00, 0x00, 0x00, /* ..E..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* ........ */ +0x03, 0x055, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + + +/* Third ARP request packet -- The test is to check that NetX does not create a duplicate entry for 1.2.3.5. + * src MAC: 20:0b:c7:94:45:97 + * src IP: 1.2.3.5. + * target MAC: 00:00:00:00:00:00 + * target IP: 1.2.3.4. */ +static char arp_request_pkt3[] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x0b, /* ...... . */ +0xc7, 0x94, 0x45, 0x97, 0x08, 0x06, 0x00, 0x01, /* ..E..... */ +0x08, 0x00, 0x06, 0x04, 0x00, 0x01, + 0x20, 0x0b, /* ...... . */ +0xc7, 0x94, 0x45, 0x97, 0x01, 0x02, 0x03, 0x05, /* ..E..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* ........ */ +0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_no_duplicate_entry_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP */ + status = nx_arp_enable(&ip_0, pointer, 1024); + + /* Check ARP enable status. */ + if(status) + error_counter++; + pointer = pointer + 1024; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +ULONG physical_msw, physical_lsw; +ULONG test_ip_address; +UINT index; +UINT match_count = 0; +NX_ARP *arp_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: ARP No Duplicate Entry Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Inject ARP packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /******************************* First ARP packet ******************************** + This will be a request. Fill in the packet with data. Skip the MAC header. */ + + memcpy(packet_ptr -> nx_packet_prepend_ptr, &arp_request_pkt[14], sizeof(arp_request_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(arp_request_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ARP packet. */ + _nx_arp_packet_deferred_receive(&ip_0, packet_ptr); + + /* Verify ARP entry is added to the ARP table. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 5), &physical_msw, &physical_lsw); + + /* Check status */ + if(status) + error_counter++; + + /* Verify the MAC. */ + if ((((physical_msw >> 8) & 0xFF) != 0x20) || + (((physical_msw) & 0xFF) != 0x0b) || + (((physical_lsw >> 24) & 0xFF) != 0xc7) || + (((physical_lsw >> 16) & 0xFF) != 0x94) || + (((physical_lsw >> 8) & 0xFF) != 0x45) || + (((physical_lsw) & 0xFF) != 0x96)) + { + error_counter++; + } + + /******************************* Second ARP packet ******************************** + Inject a second ARP packet from same host but different MAC. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* This will be a request. Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &arp_request_pkt2[14], sizeof(arp_request_pkt2) - 14); + packet_ptr -> nx_packet_length = sizeof(arp_request_pkt2) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ARP packet. */ + _nx_arp_packet_deferred_receive(&ip_0, packet_ptr); + + /* Verify ARP entry is added to the ARP table. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 5), &physical_msw, &physical_lsw); + + /* Check status */ + if(status) + error_counter++; + + /* Verify the MAC. */ + if ((((physical_msw >> 8) & 0xFF) != 0x20) || + (((physical_msw) & 0xFF) != 0x0b) || + (((physical_lsw >> 24) & 0xFF) != 0xc7) || + (((physical_lsw >> 16) & 0xFF) != 0x94) || + (((physical_lsw >> 8) & 0xFF) != 0x45) || + (((physical_lsw) & 0xFF) != 0x97)) + { + error_counter++; + } + + /* Verify this MAC is not an entry in the table. */ + physical_msw = 0x200b; + physical_lsw = 0xc7944596; + + /* The MAC address above should not be in the table. */ + status = nx_arp_ip_address_find(&ip_0, &test_ip_address, physical_msw, physical_lsw); + + /* Check status */ + if(status != NX_ENTRY_NOT_FOUND) + error_counter++; + + /******************************* Third ARP packet ******************************** + Inject a third ARP packet. This is a response packet */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* This will be a request. Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &arp_reply_pkt[14], sizeof(arp_reply_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(arp_reply_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ARP packet. */ + _nx_arp_packet_deferred_receive(&ip_0, packet_ptr); + + /* Verify ARP entry is created. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 44), &physical_msw, &physical_lsw); + + /* Check status */ + if(status) + error_counter++; + + /* Verify the MAC. */ + else if ((((physical_msw >> 8) & 0xFF) != 0x30) || + (((physical_msw) & 0xFF) != 0x1b) || + (((physical_lsw >> 24) & 0xFF) != 0xd7) || + (((physical_lsw >> 16) & 0xFF) != 0xa4) || + (((physical_lsw >> 8) & 0xFF) != 0x55) || + (((physical_lsw) & 0xFF) != 0xa6)) + { + error_counter++; + } + + + /* Verify ARP entry is created for the target of this reply packet (1.2.3.6). */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 6), &physical_msw, &physical_lsw); + + /* Check status */ + if(status != NX_ENTRY_NOT_FOUND) + error_counter++; + + + /******************************* Fourth ARP packet ******************************** + Inject a fourth ARP packet. This is a probe packet */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* This will be a request. Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &arp_probe_pkt[14], sizeof(arp_probe_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(arp_probe_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ARP packet. */ + _nx_arp_packet_deferred_receive(&ip_0, packet_ptr); + + /* Verify ARP entry is NOT created. ARP probes should not be added to the ARP cache. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 85), &physical_msw, &physical_lsw); + + /* Check status */ + if(status != NX_ENTRY_NOT_FOUND) + error_counter++; + + /* This is the MAC of the sender of the ARP probe. */ + physical_msw = 0x00b1; + physical_lsw = 0x7d4a556a; + + /* The IP address should not be in the ARP cache because it is an ARP probe. */ + status = nx_arp_ip_address_find(&ip_0, &test_ip_address, physical_msw, physical_lsw); + + /* Check status */ + if(status != NX_ENTRY_NOT_FOUND) + error_counter++; + + + + /******************************* Fifth ARP packet ******************************** + Inject a fifth ARP packet. This is a duplicate request packet */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* This will be a request. Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &arp_request_pkt3[14], sizeof(arp_request_pkt3) - 14); + packet_ptr -> nx_packet_length = sizeof(arp_request_pkt3) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ARP packet. */ + _nx_arp_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Calculate the hash index for the sender IP address. */ + index = (UINT) ((IP_ADDRESS(0x01, 0x02, 0x03, 0x05) + (IP_ADDRESS(0x01, 0x02, 0x03, 0x05) >> 8)) & NX_ARP_TABLE_MASK); + + /* Pickup the first ARP entry. */ + arp_ptr = ip_0.nx_ip_arp_table[index]; + + /* Loop to look for an ARP match. There should be only one. */ + do + { + match_count++; + + /* Determine if we are at the end of the ARP list. */ + if (arp_ptr == ip_0.nx_ip_arp_table[index]) + { + + /* Clear the ARP pointer. */ + arp_ptr = NX_NULL; + break; + } + + /* Move to the next active ARP entry. */ + arp_ptr = arp_ptr -> nx_arp_active_next; + + } while (arp_ptr); + + /* Check out match count. */ + if (match_count != 1) + { + error_counter++; + } + + /* Check for any error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_no_duplicate_entry_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP No Duplicate Entry Test...............................N/A\n"); + test_control_return(3); + +} +#endif /* NX_DISABLE_ARP_AUTO_ENTRY */ diff --git a/test/regression/netxduo_test/netx_arp_nxe_api_test.c b/test/regression/netxduo_test/netx_arp_nxe_api_test.c new file mode 100644 index 00000000..755f2d25 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_nxe_api_test.c @@ -0,0 +1,789 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP invalid_ip; +static UCHAR cache_memory[1024]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void responder_handler(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_address; +ULONG physical_msw; +ULONG physical_lsw; +ULONG arp_requests_sent; +ULONG arp_requests_received; +ULONG arp_responses_sent; +ULONG arp_responses_received; +ULONG arp_dynamic_entries; +ULONG arp_static_entries; +ULONG arp_aged_entries; +ULONG arp_invalid_messages; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP NXE API Test.........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_arp_enable api */ + /************************************************/ + + /* Enable the ARP feature for NULL IP instance. */ + status = nx_arp_enable(NX_NULL, cache_memory, 1024); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the ARP feature for invalid IP instance. */ + status = nx_arp_enable(&invalid_ip, cache_memory, 1024); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the ARP feature for IP instance with invalid cache. */ + status = nx_arp_enable(&ip_0, NX_NULL, 1024); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the ARP feature for IP instance with invalid cache size. */ + status = nx_arp_enable(&ip_0, cache_memory, 2); + + /* Check for error. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the ARP feature for valid IP instance. */ + status = nx_arp_enable(&ip_0, cache_memory, 1024); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the ARP feature again. */ + status = nx_arp_enable(&ip_0, cache_memory, 1024); + + /* Check for error. */ + if (status != NX_ALREADY_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_arp_entry_delete api */ + /************************************************/ + + /* Delete the entry for NULL IP instance. */ + status = nx_arp_entry_delete(NX_NULL, IP_ADDRESS(1, 2, 3, 4)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the entry for invalid IP instance. */ + status = nx_arp_entry_delete(&invalid_ip, IP_ADDRESS(1, 2, 3, 4)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the entry with invalid IP address. */ + status = nx_arp_entry_delete(&ip_0, NX_NULL); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_arp_gratuitous_send api */ + /************************************************/ + + /* Call the gratuitous send for NULL IP instance. */ + status = nx_arp_gratuitous_send(NX_NULL, responder_handler); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call the gratuitous send for invalid IP instance. */ + status = nx_arp_gratuitous_send(&invalid_ip, responder_handler); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_IP_ID; + + /* Call the gratuitous send for invalid IP instance. */ + status = nx_arp_gratuitous_send(&invalid_ip, responder_handler); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ARP feature. */ + ip_0.nx_ip_arp_allocate = NX_NULL; + + /* Call the gratuitous send for valid IP instance without ARP feature. */ + status = nx_arp_gratuitous_send(&ip_0, responder_handler); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_arp_hardware_address_find api */ + /************************************************/ + + /* Find the hardware address for NULL IP instance. */ + status = nx_arp_hardware_address_find(NX_NULL, IP_ADDRESS(1, 2, 3, 4), &physical_msw, &physical_lsw); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Find the hardware address for invalid IP instance. */ + status = nx_arp_hardware_address_find(&invalid_ip, IP_ADDRESS(1, 2, 3, 4), &physical_msw, &physical_lsw); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address for valid IP instance with invalid physical_msw pointer. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 4), NX_NULL, &physical_lsw); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address for valid IP instance with invalid physical_msw pointer. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 4), &physical_msw, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address for valid IP instance with NULL IP address. */ + status = nx_arp_hardware_address_find(&ip_0, NX_NULL, &physical_msw, &physical_lsw); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ARP feature. */ + ip_0.nx_ip_arp_allocate = NX_NULL; + + /* Find the hardware address for valid IP instance without ARP feature. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 4), &physical_msw, &physical_lsw); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_arp_info_get api */ + /************************************************/ + + /* Get the ARP information for NULL IP instance. */ + status = nx_arp_info_get(NX_NULL, &arp_requests_sent, &arp_requests_received, &arp_responses_sent, &arp_responses_received, &arp_dynamic_entries, &arp_static_entries, &arp_aged_entries, &arp_invalid_messages); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the ARP information for invalid IP instance. */ + status = nx_arp_info_get(&invalid_ip, &arp_requests_sent, &arp_requests_received, &arp_responses_sent, &arp_responses_received, &arp_dynamic_entries, &arp_static_entries, &arp_aged_entries, &arp_invalid_messages); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ARP feature. */ + ip_0.nx_ip_arp_allocate = NX_NULL; + + /* Get the ARP information for invalid IP instance. */ + status = nx_arp_info_get(&ip_0, &arp_requests_sent, &arp_requests_received, &arp_responses_sent, &arp_responses_received, &arp_dynamic_entries, &arp_static_entries, &arp_aged_entries, &arp_invalid_messages); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_arp_ip_address_find api */ + /************************************************/ + + /* Find the ip address for NULL IP instance. */ + status = nx_arp_ip_address_find(NX_NULL, &ip_address, 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Find the ip address for invalid IP instance. */ + status = nx_arp_ip_address_find(&invalid_ip, &ip_address, 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the ip address for valid IP instance with invalid ip address pointer. */ + status = nx_arp_ip_address_find(&ip_0, NX_NULL, 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the ip address for valid IP instance with NULL physical address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0, 0); + + /* Check for error. */ + if (status != NX_INVALID_PARAMETERS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ARP feature. */ + ip_0.nx_ip_arp_allocate = NX_NULL; + + /* Find the ip address for valid IP instance without ARP feature. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /*****************************************************/ + /* Tested the nxe_arp_dynamic_entries_invalidate api */ + /*****************************************************/ + + /* Delete the dynamic entries for NULL IP instance. */ + status = nx_arp_dynamic_entries_invalidate(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Delete the dynamic entries for invalid IP instance. */ + status = nx_arp_dynamic_entries_invalidate(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ARP feature. */ + ip_0.nx_ip_arp_allocate = NX_NULL; + + /* Delete the dynamic entries for valid IP instance without ARP feature. */ + status = nx_arp_dynamic_entries_invalidate(&ip_0); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_arp_dynamic_entry_set api */ + /************************************************/ + + /* Create the dynamic entry for NULL IP instance. */ + status = nx_arp_dynamic_entry_set(NX_NULL, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Create the dynamic entry for invalid IP instance. */ + status = nx_arp_dynamic_entry_set(&invalid_ip, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the dynamic entry with invalid IP address. */ + status = nx_arp_dynamic_entry_set(&ip_0, NX_NULL, 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the dynamic entry with multicast IP address. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(224,0,0,251), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the dynamic entry with directed broadcast IP address. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(255, 255, 255, 255), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ARP feature. */ + ip_0.nx_ip_arp_allocate = NX_NULL; + + /* Create the dynamic entry for valid IP instance without ARP feature. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_arp_static_entries_delete api */ + /************************************************/ + + /* Delete the static entries for NULL IP instance. */ + status = nx_arp_static_entries_delete(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Delete the static entries for invalid IP instance. */ + status = nx_arp_static_entries_delete(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ARP feature. */ + ip_0.nx_ip_arp_allocate = NX_NULL; + + /* Delete the static entries for valid IP instance without ARP feature. */ + status = nx_arp_static_entries_delete(&ip_0); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_arp_static_entry_create api */ + /************************************************/ + + /* Create the static entry for NULL IP instance. */ + status = nx_arp_static_entry_create(NX_NULL, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Create the static entry for invalid IP instance. */ + status = nx_arp_static_entry_create(&invalid_ip, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the static entry with invalid IP address. */ + status = nx_arp_static_entry_create(&ip_0, NX_NULL, 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the static entry with multicast IP address. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(224,0,0,251), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the static entry with directed broadcast IP address. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(255, 255, 255, 255), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the static entry with invalid IP address. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 4), 0, 0); + + /* Check for error. */ + if (status != NX_INVALID_PARAMETERS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ARP feature. */ + ip_0.nx_ip_arp_allocate = NX_NULL; + + /* Create the static entry for valid IP instance without ARP feature. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_arp_static_entry_delete api */ + /************************************************/ + + /* Delete the static entry for NULL IP instance. */ + status = nx_arp_static_entry_delete(NX_NULL, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Delete the static entry for invalid IP instance. */ + status = nx_arp_static_entry_delete(&invalid_ip, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the static entry for valid IP address. */ + status = nx_arp_static_entry_delete(&ip_0, NX_NULL, 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the static entry for valid physical address. */ + status = nx_arp_static_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, 4), 0, 0); + + /* Check for error. */ + if (status != NX_INVALID_PARAMETERS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ARP feature. */ + ip_0.nx_ip_arp_allocate = NX_NULL; + + /* Delete the static entry for valid IP instance without ARP feature. */ + status = nx_arp_static_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void responder_handler(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP NXE API Test..........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_arp_packet_allocate_test.c b/test/regression/netxduo_test/netx_arp_packet_allocate_test.c new file mode 100644 index 00000000..3a83a4c8 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_packet_allocate_test.c @@ -0,0 +1,232 @@ +/* This NetX test concentrates on the ARP conflict operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_arp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG arp_packet_received; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_packet_allocate_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + arp_packet_received = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT i; +UINT status; +UINT packet_counter; +NX_PACKET *my_packet[10]; + + printf("NetX Test: ARP Packet Allocate Test.................................."); + + /* Setup callback function. */ + advanced_packet_process_callback = my_packet_process; + + /* Loop to allocate the all packets to let _nx_packet_data_append failure in nx_ip_forward_packet_process.c */ + packet_counter = pool_0.nx_packet_pool_available; + for (i = 0; i < packet_counter; i++) + { + status = nx_packet_allocate(&pool_0, &my_packet[i], 0, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Check the available counter. */ + if (pool_0.nx_packet_pool_available != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0, 0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the arp_packet_received counter. */ + if (arp_packet_received != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Loop to release all packet. */ + for (i = 0; i < packet_counter; i++) + { + + /* Release the packet. */ + status = nx_packet_release(my_packet[i]); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + + /* Check the available counter. */ + if (pool_0.nx_packet_pool_available != packet_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 6), 0, 0); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the arp_packet_received counter. */ + if (arp_packet_received != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +ULONG *message; + + /* Counter ARP packet only. */ + if (packet_ptr -> nx_packet_length == NX_ARP_MESSAGE_SIZE) + { + message = (ULONG *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(*message); + if(*message == (ULONG)((NX_ARP_HARDWARE_TYPE << 16) | NX_ARP_PROTOCOL_TYPE)) + arp_packet_received++; + NX_CHANGE_ULONG_ENDIAN(*message); + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_packet_allocate_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Packet Allocate Test..................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_arp_queue_depth_test.c b/test/regression/netxduo_test/netx_arp_queue_depth_test.c new file mode 100644 index 00000000..b38a693b --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_queue_depth_test.c @@ -0,0 +1,172 @@ +/* This NetX test concentrates on the ARP dynamic entry operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_queue_depth_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +CHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: ARP Queue Depth Test......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the packet count. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Loop to send the ICMP ping to test the ARP queue depth. */ + for (i = 0; i < NX_ARP_MAX_QUEUE_DEPTH + 3; i ++) + { + + /* Ping an IP address that does exist, but the peer IP instance disable the ARP feature. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 10); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the count. */ + if (i < NX_ARP_MAX_QUEUE_DEPTH) + { + + /* Check the packet count, one ping packet should be exi. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total - i - 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + else + { + + /* Check the packet count, one ping packet should be exi. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total - NX_ARP_MAX_QUEUE_DEPTH) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + } + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_queue_depth_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Queue Depth Test......................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_arp_static_entries_delete_test.c b/test/regression/netxduo_test/netx_arp_static_entries_delete_test.c new file mode 100644 index 00000000..07bdf841 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_static_entries_delete_test.c @@ -0,0 +1,423 @@ +/* This NetX test concentrates on the ARP static delete all entries operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_static_entries_delete_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG ip_address; +ULONG physical_msw; +ULONG physical_lsw; +ULONG requests_sent; +ULONG requests_received; +ULONG responses_sent; +ULONG responses_received; +ULONG dynamic_entries; +ULONG static_entries; +ULONG aged_entries; +ULONG invalid_messages; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP Static Delete All Entries Processing Test............."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup multiple static ARP entries. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + status += nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 6), 0x0011, 0x22334458); + status += nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 7), 0x0011, 0x22334459); + status += nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 39), 0x0011, 0x2233445a); + status += nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 37), 0x0011, 0x2233445b); + status += nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 69), 0x0000, 0x2233445c); + + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334457); + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 5))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 5), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0011) || (physical_lsw != 0x22334457)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0000, 0x2233445c); + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 69))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 69), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0000) || (physical_lsw != 0x2233445c)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send a gratuitous ARP message. */ + status = nx_arp_gratuitous_send(&ip_0, NX_NULL); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Delete all ARP static entries. */ + status = nx_arp_static_entries_delete(&ip_0); + + /* Get ARP information. */ + status = nx_arp_info_get(&ip_0, &requests_sent, &requests_received, &responses_sent, &responses_received, &dynamic_entries, &static_entries, &aged_entries, &invalid_messages); + + /* Check for error conditions - and look for the ARP message being sent! */ + if ((status) || (requests_received)|| (responses_sent) || (responses_received) || (dynamic_entries) || (static_entries) || (aged_entries) || (invalid_messages)) + error_counter++; + +#ifndef NX_DISABLE_ARP_INFO + if(requests_sent != 1) + error_counter++; +#endif + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a static ARP entry. */ + status = nx_arp_static_entry_create(&ip_1, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_static_entries_delete_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Static Delete All Entries Processing Test.............N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_arp_static_entry_create_test.c b/test/regression/netxduo_test/netx_arp_static_entry_create_test.c new file mode 100644 index 00000000..0189bac9 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_static_entry_create_test.c @@ -0,0 +1,316 @@ +/* This NetX test concentrates on the ARP static entry create operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define ARP_ENTRY_COUNT 35 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_static_entry_create_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0, the ARP cache can store thirty-five entries. */ + status = nx_arp_enable(&ip_0, (void *) pointer, ARP_ENTRY_COUNT * sizeof(NX_ARP)); + pointer = pointer + ARP_ENTRY_COUNT * sizeof(NX_ARP); + if (status) + error_counter++; + + /* Enable TCP processing for IP instance 0. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +ULONG address; +ULONG msw; +ULONG lsw; +ULONG ip_address; +ULONG physical_msw; +ULONG physical_lsw; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP Static Entry Create Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the gateway. */ + status = nx_ip_gateway_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 1)); + + /* Check the status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the static entries. */ + if (ip_0.nx_ip_arp_static_entries != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Set a static ARP entry, the destination address is not directly accessible. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0x0022, 0x22334457); + + /* Check the status. */ + if (status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the static entries. */ + if (ip_0.nx_ip_arp_static_entries != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Set the IP address. */ + address = 5; + + /* Set the physical address. */ + msw = 0x0011; + lsw = 0x22334457; + + /* Loop to added the static entries to fill the arp entries, only remain one ARP entry for dynamic. */ + for (i = 0; i < ARP_ENTRY_COUNT - 1; i++) + { + + /* Set a static ARP entry. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, address), msw, lsw); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the IP address. */ + address ++; + + /* Update the physical address. */ + lsw ++; + } + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the static entries. */ + if (ip_0.nx_ip_arp_static_entries != ARP_ENTRY_COUNT - 1) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Set a valid dynamic ARP entry. */ + status = nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, address), msw, lsw); + + /* Check the status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the static entries. */ + if (ip_0.nx_ip_arp_static_entries != ARP_ENTRY_COUNT - 1) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, msw, lsw); + + /* Check the result. */ + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, address))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, address), &physical_msw, &physical_lsw); + + /* Check the result. */ + if ((status) || (physical_msw != msw) || (physical_lsw != lsw)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Update the physical address. */ + lsw ++; + + /* Set a valid static ARP entry again to instead the dynamic ARP entry, same IP address, different physical address. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, address), msw, lsw); + + /* Check the status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + /* Check the static entries. */ + if (ip_0.nx_ip_arp_static_entries != ARP_ENTRY_COUNT) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, msw, lsw); + + /* Check the result. */ + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, address))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, address), &physical_msw, &physical_lsw); + + /* Check the result. */ + if ((status) || (physical_msw != msw) || (physical_lsw != lsw)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0000, 0xaabbccdd); + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 200), &physical_msw, &physical_lsw); + + /* Check the result. */ + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test was successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_static_entry_create_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Static Entry Create Test..............................N/A\n"); + + test_control_return(3); +} +#endif + \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_arp_static_entry_pollute_test.c b/test/regression/netxduo_test/netx_arp_static_entry_pollute_test.c new file mode 100644 index 00000000..9b70281a --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_static_entry_pollute_test.c @@ -0,0 +1,210 @@ +/* This NetX test concentrates on the ARP static entry may be updated by ARP packet. + * JIRA: https://expresslogic.atlassian.net/projects/NETXDUO/issues/NETXDUO-222. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_static_entry_pollute_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG ip_address; +ULONG physical_msw; +ULONG physical_lsw; +ULONG requests_sent; +ULONG requests_received; +ULONG responses_sent; +ULONG responses_received; +ULONG dynamic_entries; +ULONG static_entries; +ULONG aged_entries; +ULONG invalid_messages; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP Static Entry Pollute Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set an incorrect static ARP entry of IP1 in IP0. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x00FF, 0x22334457); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 5), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x00FF) || (physical_lsw != 0x22334457)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_icmp_ping(&ip_1, IP_ADDRESS(1, 2, 3, 4), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + { + nx_packet_release(my_packet); + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 5), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x00FF) || (physical_lsw != 0x22334457)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_static_entry_pollute_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Static Entry Pollute Test.............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_arp_static_entry_test.c b/test/regression/netxduo_test/netx_arp_static_entry_test.c new file mode 100644 index 00000000..82355b83 --- /dev/null +++ b/test/regression/netxduo_test/netx_arp_static_entry_test.c @@ -0,0 +1,473 @@ +/* This NetX test concentrates on the ARP static entry operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_static_entry_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG ip_address; +ULONG physical_msw; +ULONG physical_lsw; +ULONG requests_sent; +ULONG requests_received; +ULONG responses_sent; +ULONG responses_received; +ULONG dynamic_entries; +ULONG static_entries; +ULONG aged_entries; +ULONG invalid_messages; + + + /* Print out some test information banners. */ + printf("NetX Test: ARP Static Entry Processing Test.........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete an not existing static entry. */ + status = nx_arp_static_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + + /* Check for error. */ + if (status == NX_SUCCESS) + error_counter++; + + /* Set a static ARP entry. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the IP address. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334457); + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 5))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(1, 2, 3, 5), &physical_msw, &physical_lsw); + if ((status) || (physical_msw != 0x0011) || (physical_lsw != 0x22334457)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a invalid static ARP entry, the destination address isnot directly accessible . */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0x0011, 0x22334458); + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the IP address for inexistence entry. */ + status = nx_arp_ip_address_find(&ip_0, &ip_address, 0x0011, 0x22334458); + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address for inexistence entry. */ + status = nx_arp_hardware_address_find(&ip_0, IP_ADDRESS(2, 2, 3, 5), &physical_msw, &physical_lsw); + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get ARP information. */ + status = nx_arp_info_get(&ip_0, &requests_sent, &requests_received, &responses_sent, &responses_received, &dynamic_entries, &static_entries, &aged_entries, &invalid_messages); + +#ifndef NX_DISABLE_ARP_INFO + if ((requests_sent) || (requests_received) || (responses_sent) || (responses_received) || (static_entries != 1) || (aged_entries) || (invalid_messages)) + { + error_counter++; + } +#endif + + /* Check for error conditions. */ + if ((status) || (dynamic_entries)) + error_counter++; + + /* Delete the static entry with wrong MAC. */ + status = nx_arp_static_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0, 0x22334457); + + /* Check for error. */ + if (status == NX_SUCCESS) + error_counter++; + + /* Delete the static entry. */ + status = nx_arp_static_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get ARP information again. */ + status = nx_arp_info_get(&ip_0, &requests_sent, &requests_received, &responses_sent, &responses_received, &dynamic_entries, &static_entries, &aged_entries, &invalid_messages); + +#ifndef NX_DISABLE_ARP_INFO + if ((requests_sent) || (requests_received) || (responses_sent) || (responses_received) || (static_entries) || (aged_entries) || (invalid_messages)) + { + error_counter++; + } +#endif + + /* Check for other error conditions. */ + if ((status) || (dynamic_entries)) + error_counter++; + + /* Set a static ARP entry with lsw 0 . */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 15), 0x0011, 0x00000000); + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the static entry with wrong MAC. */ + status = nx_arp_static_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, 15), 0x0011, 0x00000001); + + /* Check for error. */ + if (status != NX_ENTRY_NOT_FOUND) + error_counter++; + + /* Delete the static entry with correct MAC. */ + status = nx_arp_static_entry_delete(&ip_0, IP_ADDRESS(1, 2, 3, 15), 0x0011, 0x00000000); + + /* Check for error. */ + if (status) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set a static ARP entry. */ + status = nx_arp_static_entry_create(&ip_1, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_arp_static_entry_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ARP Static Entry Processing Test..........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_caller_check_test.c b/test/regression/netxduo_test/netx_caller_check_test.c new file mode 100644 index 00000000..b863fd5c --- /dev/null +++ b/test/regression/netxduo_test/netx_caller_check_test.c @@ -0,0 +1,1105 @@ +/* This NetX test concentrates on caller check for error checking functions. */ + +#include "nx_api.h" +#include "tx_thread.h" +#include "tx_timer.h" +#include "nx_udp.h" +#include "nx_tcp.h" +#include "nx_rarp.h" +#include "nx_ip.h" +#include "nx_icmp.h" +#include "nx_igmp.h" +#include "nx_arp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && defined(__PRODUCT_NETXDUO__) && defined(__linux__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP test_ip; +static NX_TCP_SOCKET tcp_socket; +static NX_UDP_SOCKET udp_socket; +static NXD_ADDRESS address = {NX_IP_VERSION_V6, }; +static TX_TIMER timer_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static ULONG expected_system_state; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void link_status_change_notify(NX_IP *ip_ptr, UINT interface_index, UINT link_up); +static void tcp_receive_notify(NX_TCP_SOCKET *socket_ptr); +static VOID tcp_socket_window_update_notify(NX_TCP_SOCKET *socket_ptr); +VOID test_process(ULONG id); +VOID test_process_1(ULONG id); +VOID test_process_2(ULONG id); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_caller_check_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable UDP processing for IP instance. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for IP instance. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Enable IGMP for IP instance. */ + status = nx_igmp_enable(&ip_0); + + /* Check IGMP enable status. */ + if (status) + error_counter++; + + /* Enable ICMP processing for IP instance. */ + status = nxd_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + +VOID test_process(ULONG id) +{ +UINT uint_value; +ULONG ulong_value; +NX_PACKET_POOL + test_pool; +ULONG ipv6_addr[4]; +UINT old_state = _tx_thread_system_state; + + + _tx_thread_system_state = expected_system_state; + + if (nx_ip_raw_packet_enable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_raw_packet_disable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_raw_receive_queue_max_set(&ip_0, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_fragment_disable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_rarp_enable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_gateway_address_clear(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, + NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_link_status_change_notify_set(&ip_0, link_status_change_notify) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_address_change_notify(&ip_0, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_rarp_disable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_fragment_enable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_rarp_queue_process = _nx_rarp_queue_process; + if (nx_rarp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_arp_static_entries_delete(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_icmp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_igmp_loopback_enable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_igmp_loopback_disable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_driver_direct_command(&ip_0, 0xFFFFFFFF, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_driver_interface_direct_command(&ip_0, 0xFFFFFFFF, 0, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_interface_physical_address_set(&ip_0, 0, 0, 0, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, + NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_igmp_info_get(&ip_0, 0, 0, 0, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_interface_mtu_set(&ip_0, 0, 1500) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_gateway_address_set(&ip_0, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_arp_entry_delete(&ip_0, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_arp_allocate = NX_NULL; + if (nx_arp_enable(&ip_0, (VOID *)0x20000000, 1024) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_arp_allocate = _nx_arp_entry_allocate; + if (nx_tcp_socket_mss_set(&tcp_socket, 1460) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_mss_get(&tcp_socket, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_window_update_notify_set(&tcp_socket, tcp_socket_window_update_notify) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_gateway_address_get(&ip_0, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_icmp_packet_receive = NX_NULL; + if (nx_icmp_enable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_icmp_packet_receive = _nx_icmp_packet_receive; + if (nx_tcp_socket_info_get(&tcp_socket, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, + NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_igmp_packet_receive = NX_NULL; + if (nx_igmp_enable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_igmp_packet_receive = _nx_igmp_packet_receive; + if (nx_ip_interface_address_mapping_configure(&ip_0, 0, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_interface_info_get(&ip_0, 0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_address_set(&ip_0, 1, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_address_get(&ip_0, &ulong_value, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_interface_address_set(&ip_0, 0, 1, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_interface_physical_address_get(&ip_0, 0, &ulong_value, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_transmit_configure(&tcp_socket, 1, 1, 1, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_receive_notify(&tcp_socket, tcp_receive_notify) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_packet_pool_create(&test_pool, "Invalid pool", 256, (VOID *)0x20000000, 1024) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_interface_address_get(&ip_0, 0, &ulong_value, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_create(&test_ip, "test ip", 0, 0, &pool_0, _nx_ram_network_driver_256, + (VOID *)0x20000000, 1024, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_arp_static_entry_create(&ip_0, 1, 1, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + address.nxd_ip_version = NX_IP_VERSION_V6; + if (nx_ip_max_payload_size_find(&ip_0, &address, 0, 1, 1, NX_PROTOCOL_TCP, &ulong_value, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_create(&ip_0, &udp_socket, "UDP socket", 0, 0, 0, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_create(&ip_0, &tcp_socket, "TCP socket", 0, 0, 0, 0, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } +#if (NX_MAX_PHYSICAL_INTERFACES>1) + if (nx_ip_interface_detach(&ip_0, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_interface_attach(&ip_0, "Second interface", 1, 0, _nx_ram_network_driver_256) != NX_CALLER_ERROR) + { + error_counter++; + } +#endif /* (NX_MAX_PHYSICAL_INTERFACES>1) */ +#ifdef FEATURE_NX_IPV6 + if (nxd_ipv6_enable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_ipv6_disable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_ipv6_default_router_delete(&ip_0, &address) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_ipv6_default_router_entry_get(&ip_0, 0, 0, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_ipv6_default_router_number_of_entries_get(&ip_0, 0, &uint_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_icmpv6_ra_flag_callback_set(&ip_0, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_icmp_enable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_ipv6_address_delete(&ip_0, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_nd_cache_entry_delete(&ip_0, ipv6_addr) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_nd_cache_entry_set(&ip_0, ipv6_addr, 0, "") != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_ipv6_address_get(&ip_0, 0, &address, &ulong_value, &uint_value) != NX_CALLER_ERROR) + { + error_counter++; + } + address.nxd_ip_version = NX_IP_VERSION_V6; + if (nxd_ipv6_default_router_add(&ip_0, &address, 1, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } +#endif /* FEATURE_NX_IPV6 */ + + _tx_thread_system_state = old_state; + + /* Deactivate current timer. */ + tx_timer_deactivate(&timer_0); +} + +VOID test_process_1(ULONG id) +{ +NX_PACKET *packet_ptr; +ULONG ulong_value; +UINT uint_value; +ULONG ipv6_addr[4]; +UINT old_state = _tx_thread_system_state; +TX_THREAD *old_thread = _tx_thread_current_ptr; + + + nx_packet_allocate(&pool_0, &packet_ptr, 0, 0); + packet_ptr -> nx_packet_ip_version = 0; + + _tx_thread_system_state = expected_system_state; + + if (id == 1) + _tx_thread_current_ptr = TX_NULL; + + if (nxd_udp_packet_info_extract(packet_ptr, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_packet_info_extract(packet_ptr, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_bytes_available(&udp_socket, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_port_get(&udp_socket, &uint_value) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_raw_ip_processing = _nx_ip_raw_packet_processing; + if (nx_ip_raw_packet_receive(&ip_0, &packet_ptr, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_receive(&udp_socket, &packet_ptr, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (id == 1) + _tx_thread_current_ptr = old_thread; + + nx_packet_allocate(&pool_0, &packet_ptr, 0, 0); + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr; + + if (id == 1) + _tx_thread_current_ptr = TX_NULL; + + if (nxd_udp_source_extract(packet_ptr, &address, &uint_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_delete(&udp_socket) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_unbind(&udp_socket) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_free_port_find(&ip_0, 1, &uint_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_delete(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ipv4_multicast_interface_leave(&ip_0, IP_ADDRESS(224, 0, 0, 1), 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_packet_pool_delete(&pool_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_arp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_arp_dynamic_entries_invalidate(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_disconnect(&tcp_socket, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_client_socket_unbind(&tcp_socket) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_delete(&tcp_socket) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_server_socket_accept(&tcp_socket, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_server_socket_unaccept(&tcp_socket) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_state_wait(&tcp_socket, NX_TCP_CLOSED, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ipv4_multicast_interface_join(&ip_0, IP_ADDRESS(224, 0, 0, 1), 0) != NX_CALLER_ERROR) + { + error_counter++; + } + + if (id == 1) + _tx_thread_current_ptr = old_thread; + + nx_packet_allocate(&pool_0, &packet_ptr, sizeof(NX_IPV4_HEADER), 0); + address.nxd_ip_version = NX_IP_VERSION_V4; + address.nxd_ip_address.v4 = 1; + + if (id == 1) + _tx_thread_current_ptr = TX_NULL; + + if (nxd_ip_raw_packet_send(&ip_0, packet_ptr, &address, 0, 0, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_raw_packet_source_send(&ip_0, packet_ptr, 1, 0, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_raw_packet_send(&ip_0, packet_ptr, 1, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + + if (id == 1) + _tx_thread_current_ptr = old_thread; + + nx_packet_release(packet_ptr); + + if (id == 1) + _tx_thread_current_ptr = TX_NULL; + + if (nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224, 0, 0, 1), 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224, 0, 0, 1), 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &ulong_value, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_bind(&udp_socket, 10, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_mss_peer_get(&tcp_socket, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_client_socket_bind(&tcp_socket, 1, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_bytes_available(&tcp_socket, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_receive(&tcp_socket, &packet_ptr, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_client_socket_port_get(&tcp_socket, &uint_value) != NX_CALLER_ERROR) + { + error_counter++; + } + + if (id == 1) + _tx_thread_current_ptr = old_thread; + + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, 0); + + if (id == 1) + _tx_thread_current_ptr = TX_NULL; + + if (nx_udp_socket_send(&udp_socket, packet_ptr, 1, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + + if (id == 1) + _tx_thread_current_ptr = old_thread; + + nx_packet_release(packet_ptr); + + if (id == 1) + _tx_thread_current_ptr = TX_NULL; + + if (nx_arp_ip_address_find(&ip_0, ipv6_addr, 1, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_free_port_find(&ip_0, 1, &uint_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224, 0, 0, 1)) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224, 0, 0, 1)) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_icmp_ping(&ip_0, 1, "", 0, &packet_ptr, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_socket_peer_info_get(&tcp_socket, &ulong_value, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_arp_static_entry_delete(&ip_0, 1, 1, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_server_socket_unlisten(&ip_0, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_tcp_socket_peer_info_get(&tcp_socket, &address, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_tcp_client_socket_connect(&tcp_socket, &address, 1, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_client_socket_connect(&tcp_socket, 1, 1, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + + if (id == 1) + _tx_thread_current_ptr = old_thread; + + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, 0); + + if (id == 1) + _tx_thread_current_ptr = TX_NULL; + + if (nx_udp_socket_source_send(&udp_socket, packet_ptr, 1, 1, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + + if (id == 1) + _tx_thread_current_ptr = old_thread; + + nx_packet_release(packet_ptr); + + if (id == 1) + _tx_thread_current_ptr = TX_NULL; + + if (nx_ip_interface_status_check(&ip_0, 0, NX_IP_INITIALIZE_DONE, &ulong_value, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_arp_hardware_address_find(&ip_0, 1, &ulong_value, &ulong_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_arp_dynamic_entry_set(&ip_0, 1, 1, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_arp_gratuitous_send(&ip_0, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + + if (id == 1) + _tx_thread_current_ptr = old_thread; + + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + + if (id == 1) + _tx_thread_current_ptr = TX_NULL; + + if (nx_tcp_socket_send(&tcp_socket, packet_ptr, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_udp_socket_source_send(&udp_socket, packet_ptr, &address, 1, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_udp_socket_send(&udp_socket, packet_ptr, &address, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_ip_raw_packet_source_send(&ip_0, packet_ptr, &address, 0, 0, 0, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + + if (id == 1) + _tx_thread_current_ptr = old_thread; + + nx_packet_release(packet_ptr); + + if (id == 1) + _tx_thread_current_ptr = TX_NULL; + + if (nx_tcp_server_socket_relisten(&ip_0, 1, &tcp_socket) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_tcp_server_socket_listen(&ip_0, 1, &tcp_socket, 1, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_icmp_ping(&ip_0, &address, "", 0, &packet_ptr, 0) != NX_CALLER_ERROR) + { + error_counter++; + } +#ifdef FEATURE_NX_IPV6 + if (nxd_nd_cache_invalidate(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_nd_cache_ip_address_find(&ip_0, &address, 1, 1, &uint_value) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nxd_icmp_source_ping(&ip_0, &address, 0, "", 0, &packet_ptr, 0) != NX_CALLER_ERROR) + { + error_counter++; + } + address.nxd_ip_version = NX_IP_VERSION_V6; + if (nxd_nd_cache_hardware_address_find(&ip_0, &address, &ulong_value, &ulong_value, &uint_value) != NX_CALLER_ERROR) + { + error_counter++; + } +#endif /* FEATURE_NX_IPV6 */ + + _tx_thread_system_state = old_state; + + if (id == 1) + _tx_thread_current_ptr = old_thread; + + /* Deactivate current timer. */ + tx_timer_deactivate(&timer_0); +} + +VOID test_process_2(ULONG id) +{ +NX_PACKET *packet_ptr; +NX_PACKET *test_packet_ptr; +ULONG ulong_value; +UINT old_state = _tx_thread_system_state; +TX_THREAD *old_thread = _tx_thread_current_ptr; + + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + + _tx_thread_system_state = expected_system_state; + + if (id == 1) + _tx_thread_current_ptr = TX_NULL; + + if (nx_packet_allocate(&pool_0, &test_packet_ptr, 0, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_packet_copy(packet_ptr, &packet_ptr, &pool_0, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_packet_data_append(packet_ptr, "", 1, &pool_0, 1) != NX_CALLER_ERROR) + { + error_counter++; + } + + _tx_thread_system_state = old_state; + + if (id == 1) + _tx_thread_current_ptr = old_thread; + + nx_packet_release(packet_ptr); +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +TX_INTERRUPT_SAVE_AREA +UINT i; +UINT old_state; +TX_THREAD *old_thread; +NX_PACKET *packet_ptr; +ULONG ulong_value; +UINT uint_value; +ULONG ipv6_addr[4]; +struct sched_param sp; + + /* Print out some test information banners. */ + printf("NetX Test: Caller Check Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Modify the thread priority so it will pass the check as not a user thread. */ + sp.sched_priority = 1; + pthread_setschedparam(_tx_thread_current_ptr -> tx_thread_linux_thread_id, SCHED_FIFO, &sp); + + /* Create a UDP socket. */ + nx_udp_socket_create(&ip_0, &udp_socket, "UDP Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Create a TCP socket. */ + nx_tcp_socket_create(&ip_0, &tcp_socket, "TCP Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + TX_DISABLE + old_state = _tx_thread_system_state; + old_thread = _tx_thread_current_ptr; + + /* 1. NX_INIT_AND_THREADS_CALLER_CHECKING checking. */ + + /* 1.1 _tx_thread_system_state = 1, _tx_thread_current_ptr != _tx_timer_thread */ + expected_system_state = 1; + test_process(0); + +#ifndef TX_TIMER_PROCESS_IN_ISR + /* Restore. */ + _tx_thread_current_ptr = old_thread; + _tx_thread_system_state = old_state; + + /* 1.2 _tx_thread_system_state = 0xF0F0F0F0UL, _tx_thread_current_ptr = _tx_timer_thread */ + expected_system_state = 0xF0F0F0F0UL; + tx_timer_create(&timer_0, "TIMER 0", test_process, 0, 1, 1, TX_AUTO_ACTIVATE); + /* Invoke functions in timer thread. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + tx_timer_delete(&timer_0); +#endif /* TX_TIMER_PROCESS_IN_ISR */ + + /* Restore. */ + _tx_thread_current_ptr = old_thread; + _tx_thread_system_state = old_state; + + /* 1.3 _tx_thread_current_ptr = &_tx_timer_thread, _tx_thread_system_state = 0. */ + expected_system_state = 0; + tx_timer_create(&timer_0, "TIMER 1", test_process, 0, 1, 1, TX_AUTO_ACTIVATE); + /* Invoke functions in timer thread. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + tx_timer_delete(&timer_0); + + /* Restore. */ + _tx_thread_current_ptr = old_thread; + _tx_thread_system_state = old_state; + + + /* 2. NX_NOT_ISR_CALLER_CHECKING checking. */ + /* 2.1 _tx_thread_system_state = 0 */ + _tx_thread_system_state = 0; + if (nx_udp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) == NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_info_get(&udp_socket, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) == NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_udp_packet_receive = NX_NULL; + if (nx_udp_enable(&ip_0) == NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + if (nx_udp_socket_checksum_disable(&udp_socket) == NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_checksum_enable(&udp_socket) == NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_packet_pool_info_get(&pool_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) == NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_forwarding_enable(&ip_0) == NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_forwarding_disable(&ip_0) == NX_CALLER_ERROR) + { + error_counter++; + } + + /* 2.2 _tx_thread_system_state = 1 */ + _tx_thread_system_state = 1; + if (nx_udp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_info_get(&udp_socket, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_udp_packet_receive = NX_NULL; + if (nx_udp_enable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + if (nx_udp_socket_checksum_disable(&udp_socket) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_checksum_enable(&udp_socket) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_packet_pool_info_get(&pool_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_forwarding_enable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_forwarding_disable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_tcp_packet_receive = NX_NULL; + if (nx_tcp_enable(&ip_0) != NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* 2.3 _tx_thread_system_state = 0xF0F0F0F0UL */ + _tx_thread_system_state = 0xF0F0F0F0UL; + if (nx_udp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) == NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_info_get(&udp_socket, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) == NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_udp_packet_receive = NX_NULL; + if (nx_udp_enable(&ip_0) == NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + if (nx_udp_socket_checksum_disable(&udp_socket) == NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_udp_socket_checksum_enable(&udp_socket) == NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_packet_pool_info_get(&pool_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL) == NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_forwarding_enable(&ip_0) == NX_CALLER_ERROR) + { + error_counter++; + } + if (nx_ip_forwarding_disable(&ip_0) == NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_tcp_packet_receive = NX_NULL; + if (nx_tcp_enable(&ip_0) == NX_CALLER_ERROR) + { + error_counter++; + } + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Restore. */ + _tx_thread_current_ptr = old_thread; + _tx_thread_system_state = old_state; + + + /* 3. NX_THREADS_ONLY_CALLER_CHECKING checking. */ + /* 3.1 _tx_thread_system_state = 1 */ + expected_system_state = 1; + test_process_1(0); + + /* Restore. */ + _tx_thread_current_ptr = old_thread; + _tx_thread_system_state = old_state; + + /* 3.2 _tx_thread_current_ptr = &_tx_timer_thread, _tx_thread_system_state = 0. */ + expected_system_state = 0; + tx_timer_create(&timer_0, "TIMER 2", test_process_1, 0, 1, 1, TX_AUTO_ACTIVATE); + /* Invoke functions in timer thread. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + tx_timer_delete(&timer_0); + + /* Restore. */ + _tx_thread_current_ptr = old_thread; + _tx_thread_system_state = old_state; + + /* 3.3 _tx_thread_current_ptr = TX_NULL, _tx_thread_system_state = 0. */ + expected_system_state = 0; + test_process_1(1); + + /* Restore. */ + _tx_thread_current_ptr = old_thread; + _tx_thread_system_state = old_state; + + /* 4. NX_THREAD_WAIT_CALLER_CHECKING checking. */ + /* 4.1 _tx_thread_system_state = 1. */ + expected_system_state = 1; + test_process_2(0); + + /* 4.2 _tx_thread_current_ptr = TX_NULL, _tx_thread_system_state = 0. */ + expected_system_state = 0; + test_process_2(1); + + /* 4.3 _tx_thread_current_ptr = &_tx_timer_thread, _tx_thread_system_state = 0. */ + expected_system_state = 0; + tx_timer_create(&timer_0, "TIMER 3", test_process_2, 0, 1, 1, TX_AUTO_ACTIVATE); + /* Invoke functions in timer thread. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + tx_timer_delete(&timer_0); + + /* Restore. */ + _tx_thread_current_ptr = old_thread; + _tx_thread_system_state = old_state; + TX_RESTORE + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void link_status_change_notify(NX_IP *ip_ptr, UINT interface_index, UINT link_up) +{ +} + +static void tcp_receive_notify(NX_TCP_SOCKET *socket_ptr) +{ +} + +static VOID tcp_socket_window_update_notify(NX_TCP_SOCKET *socket_ptr) +{ +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_caller_check_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Caller Check Test.........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_checksum_test.c b/test/regression/netxduo_test/netx_checksum_test.c new file mode 100644 index 00000000..453b58e0 --- /dev/null +++ b/test/regression/netxduo_test/netx_checksum_test.c @@ -0,0 +1,323 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_tcp.h" +#include "nx_icmp.h" +#ifdef FEATURE_NX_IPV6 +#include "nx_ipv6.h" +#endif /* FEATURE_NX_IPV6 */ + +#if defined(__PRODUCT_NETX__) +#define NX_PROTOCOL_TCP 6 +#define NX_PROTOCOL_UDP 17 +#define NX_PROTOCOL_ICMPV6 58 +#define NX_PROTOCOL_ICMP 1 +#define NX_IP_VERSION_V4 4 /* IP-in-IP encapsulation */ +#endif + +#define DEMO_STACK_SIZE 2048 +#define PHYSICAL_OFFSET 14 + +/* Define raw packet data. */ +static char pkt_tcp_32[] = { +0x00, 0x50, 0x56, 0xc0, 0x00, 0x08, 0x00, 0x0c, +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x10, +0x00, 0x34, 0xf2, 0x4b, 0x40, 0x00, 0x40, 0x06, +0xea, 0x94, 0xc0, 0xa8, 0xee, 0x80, 0xc0, 0xa8, +0xee, 0x01, 0x00, 0x16, 0xe2, 0xb1, 0xcb, 0xe8, +0x2a, 0xb4, 0x0a, 0x4e, 0x4c, 0x16, 0x80, 0x10, +0x03, 0xea, 0x36, 0xba, 0x00, 0x00, 0x01, 0x01, +0x05, 0x0a, 0x0a, 0x4e, 0x4e, 0x16, 0x0a, 0x4e, +0x4e, 0xca }; + +static char pkt_tcp_37[] = { +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, +0x00, 0x39, 0x77, 0xd7, 0x40, 0x00, 0x40, 0x06, +0xc4, 0xe5, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, +0x00, 0x01, 0x00, 0x0d, 0x9d, 0x48, 0x52, 0x32, +0xec, 0x47, 0x52, 0x2b, 0x98, 0x93, 0x80, 0x18, +0x02, 0x00, 0x4f, 0x22, 0x00, 0x00, 0x01, 0x01, +0x08, 0x0a, 0x03, 0x05, 0x9b, 0x90, 0x03, 0x05, +0x9b, 0x90, 0x48, 0x65, 0x6c, 0x6c, 0x6f }; + +static char pkt_udp_53[] = { +0x00, 0x50, 0x56, 0xfb, 0x32, 0x2d, 0x00, 0x0c, +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, +0x00, 0x49, 0x43, 0x73, 0x40, 0x00, 0x40, 0x11, +0x99, 0x5c, 0xc0, 0xa8, 0xee, 0x80, 0xc0, 0xa8, +0xee, 0x02, 0xe1, 0xee, 0x00, 0x35, 0x00, 0x35, +0x61, 0x91, 0x7c, 0x8c, 0x01, 0x00, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x68, +0x65, 0x6c, 0x70, 0x06, 0x75, 0x62, 0x75, 0x6e, +0x74, 0x75, 0x03, 0x63, 0x6f, 0x6d, 0x0b, 0x6c, +0x6f, 0x63, 0x61, 0x6c, 0x64, 0x6f, 0x6d, 0x61, +0x69, 0x6e, 0x00, 0x00, 0x1c, 0x00, 0x01 }; + +static char pkt_udp_40[] = { +0x00, 0x50, 0x56, 0xfb, 0x32, 0x2d, 0x00, 0x0c, +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, +0x00, 0x3c, 0x43, 0x5a, 0x40, 0x00, 0x40, 0x11, +0x99, 0x82, 0xc0, 0xa8, 0xee, 0x80, 0xc0, 0xa8, +0xee, 0x02, 0xd7, 0x98, 0x00, 0x35, 0x00, 0x28, +0x06, 0x9c, 0x34, 0xb8, 0x01, 0x00, 0x00, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, +0x77, 0x77, 0x06, 0x67, 0x6f, 0x6f, 0x67, 0x6c, +0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, +0x00, 0x01 }; + +static char pkt_icmp_18[] = { +0x00, 0x50, 0x56, 0xfb, 0x32, 0x2d, 0x00, 0x0c, +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, +0x00, 0x26, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, +0xcb, 0x04, 0xc0, 0xa8, 0xee, 0x80, 0xc0, 0xa8, +0x00, 0x01, 0x08, 0x00, 0x26, 0x76, 0x15, 0xa0, +0x00, 0x01, 0x71, 0x94, 0xd1, 0x50, 0x65, 0xfa, +0x0b, 0x00, 0x08, 0x09 }; + +static char pkt_icmp_23[] = { +0x00, 0x50, 0x56, 0xfb, 0x32, 0x2d, 0x00, 0x0c, +0x29, 0x01, 0xd4, 0x79, 0x08, 0x00, 0x45, 0x00, +0x00, 0x2b, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01, +0xca, 0xff, 0xc0, 0xa8, 0xee, 0x80, 0xc0, 0xa8, +0x00, 0x01, 0x08, 0x00, 0x55, 0x9b, 0x15, 0xa4, +0x00, 0x02, 0x91, 0x94, 0xd1, 0x50, 0xf2, 0xb7, +0x0b, 0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, +0x0e }; + +static char pkt_icmpv6_32[] = { +0x33, 0x33, 0xff, 0x89, 0x7e, 0xba, 0x00, 0x0c, +0x29, 0x01, 0xd4, 0x79, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, +0x29, 0xff, 0xfe, 0x01, 0xd4, 0x79, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0xff, 0x89, 0x7e, 0xba, 0x87, 0x00, +0x42, 0x58, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x70, +0x49, 0x3f, 0x59, 0x89, 0x7e, 0xba, 0x01, 0x01, +0x00, 0x0c, 0x29, 0x01, 0xd4, 0x79 }; + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void verify_checksum(UINT index); +extern void test_control_return(UINT status); + +typedef struct CHECKSUM_TEST_SEQ_STRUCT +{ + char *pkt_data; + int pkt_size; + + ULONG protocol; + ULONG offset; +}CHECKSUM_TEST_SEQ; + +static CHECKSUM_TEST_SEQ checksum_test_seq[] = +{ + + /* ICMPv6 checksum with payload size 32. */ + {pkt_icmpv6_32, sizeof(pkt_icmpv6_32), NX_PROTOCOL_ICMPV6, 54}, + + /* Following packets are IPv4. */ + /* IPv4 checksum with payload size 43. */ + {pkt_icmp_23, sizeof(pkt_icmp_23), NX_IP_VERSION_V4, 14}, + + /* ICMPv4 checksum with payload size 23. */ + {pkt_icmp_23, sizeof(pkt_icmp_23), NX_PROTOCOL_ICMP, 34}, + + /* IPv4 checksum with payload size 38. */ + {pkt_icmp_18, sizeof(pkt_icmp_18), NX_IP_VERSION_V4, 14}, + + /* ICMPv4 checksum with payload size 18. */ + {pkt_icmp_18, sizeof(pkt_icmp_18), NX_PROTOCOL_ICMP, 34}, + + /* IPv4 checksum with payload size 60. */ + {pkt_udp_40, sizeof(pkt_udp_40), NX_IP_VERSION_V4, 14}, + + /* UDP checksum with payload size 40. */ + {pkt_udp_40, sizeof(pkt_udp_40), NX_PROTOCOL_UDP, 34}, + + /* IPv4 checksum with payload size 73. */ + {pkt_udp_53, sizeof(pkt_udp_53), NX_IP_VERSION_V4, 14}, + + /* UDP checksum with payload size 53. */ + {pkt_udp_53, sizeof(pkt_udp_53), NX_PROTOCOL_UDP, 34}, + + /* IPv4 checksum with payload size 57. */ + {pkt_tcp_37, sizeof(pkt_tcp_37), NX_IP_VERSION_V4, 14}, + + /* TCP checksum with payload size 37. */ + {pkt_tcp_37, sizeof(pkt_tcp_37), NX_PROTOCOL_TCP, 34}, + + /* IPv4 checksum with payload size 52. */ + {pkt_tcp_32, sizeof(pkt_tcp_32), NX_IP_VERSION_V4, 14}, + + /* TCP checksum with payload size 32. */ + {pkt_tcp_32, sizeof(pkt_tcp_32), NX_PROTOCOL_TCP, 34} +}; + +static UINT seq_size = sizeof(checksum_test_seq)/sizeof(CHECKSUM_TEST_SEQ); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_checksum_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: Checksum Test............................................."); + + for(i = 0; i < seq_size; i++) + verify_checksum(i); + + /* Check status. */ + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the verify checksum function. */ +static void verify_checksum(UINT index) +{ +NX_PACKET *pkt_ptr; +ULONG source_ip[4]; +ULONG dest_ip[4]; +ULONG checksum; + + + /* Allocate a packet and fill data into the packet. */ + if(nx_packet_allocate(&pool_0, &pkt_ptr, NX_RECEIVE_PACKET, TX_NO_WAIT)) + { + error_counter++; + return; + } + if(nx_packet_data_append(pkt_ptr, checksum_test_seq[index].pkt_data + checksum_test_seq[index].offset, + checksum_test_seq[index].pkt_size - checksum_test_seq[index].offset, + &pool_0, TX_NO_WAIT)) + { + error_counter++; + nx_packet_release(pkt_ptr); + return; + } + +#if defined(__PRODUCT_NETXDUO__) + /* Get IP address. */ + if((*(checksum_test_seq[index].pkt_data + PHYSICAL_OFFSET) >> 4) == NX_IP_VERSION_V4) + { +#ifndef NX_DISABLE_IPV4 + NX_IPV4_HEADER *ip_header_ptr; + ip_header_ptr = (NX_IPV4_HEADER*)(checksum_test_seq[index].pkt_data + PHYSICAL_OFFSET); + source_ip[0] = ip_header_ptr -> nx_ip_header_source_ip; + dest_ip[0] = ip_header_ptr -> nx_ip_header_destination_ip; + NX_CHANGE_ULONG_ENDIAN(source_ip[0]); + NX_CHANGE_ULONG_ENDIAN(dest_ip[0]); + + pkt_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4; +#else + nx_packet_release(pkt_ptr); + return; +#endif /* NX_DISABLE_IPV4 */ + } +#ifdef FEATURE_NX_IPV6 + else if((*(checksum_test_seq[index].pkt_data + PHYSICAL_OFFSET) >> 4) == NX_IP_VERSION_V6) + { + NX_IPV6_HEADER *ipv6_header; + ipv6_header = (NX_IPV6_HEADER*)(checksum_test_seq[index].pkt_data + PHYSICAL_OFFSET); + COPY_IPV6_ADDRESS(ipv6_header -> nx_ip_header_source_ip, source_ip); + COPY_IPV6_ADDRESS(ipv6_header -> nx_ip_header_destination_ip, dest_ip); + _nx_ipv6_address_change_endian(source_ip); + _nx_ipv6_address_change_endian(dest_ip); + + pkt_ptr -> nx_packet_ip_version = NX_IP_VERSION_V6; + } +#endif /* FEATURE_NX_IPV6 */ + else + { + + /* Release packet. */ + nx_packet_release(pkt_ptr); + return; + } + + if(checksum_test_seq[index].protocol == NX_IP_VERSION_V4) + pkt_ptr -> nx_packet_length = 20; + + /* Calculate checksum. */ + checksum = _nx_ip_checksum_compute(pkt_ptr, checksum_test_seq[index].protocol, + pkt_ptr -> nx_packet_length, + source_ip, dest_ip); + + checksum = ~checksum & NX_LOWER_16_MASK; +#elif defined(__PRODUCT_NETX__) + checksum = 0; + if(checksum_test_seq[index].protocol == NX_PROTOCOL_TCP) + { + NX_IP_HEADER *ip_header_ptr; + ip_header_ptr = (NX_IP_HEADER*)(checksum_test_seq[index].pkt_data + PHYSICAL_OFFSET); + source_ip[0] = ip_header_ptr -> nx_ip_header_source_ip; + dest_ip[0] = ip_header_ptr -> nx_ip_header_destination_ip; + NX_CHANGE_ULONG_ENDIAN(source_ip[0]); + NX_CHANGE_ULONG_ENDIAN(dest_ip[0]); + checksum = _nx_tcp_checksum(pkt_ptr, source_ip[0], dest_ip[0]); + } + else if(checksum_test_seq[index].protocol == NX_PROTOCOL_ICMP) + { + checksum = _nx_icmp_checksum_compute(pkt_ptr); + checksum = ~checksum & NX_LOWER_16_MASK; + } +#endif + if(checksum) + error_counter++; + + /* Release packet. */ + nx_packet_release(pkt_ptr); +} diff --git a/test/regression/netxduo_test/netx_dest_table_add_fail_test.c b/test/regression/netxduo_test/netx_dest_table_add_fail_test.c new file mode 100644 index 00000000..5d82470b --- /dev/null +++ b/test/regression/netxduo_test/netx_dest_table_add_fail_test.c @@ -0,0 +1,235 @@ +/* This NetX test concentrates on the failure of adding destination table. */ + +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); +#ifdef FEATURE_NX_IPV6 +#include "nx_icmpv6.h" +#include "nx_nd_cache.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NXD_ADDRESS global_address_0; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dest_table_add_fail_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check status. */ + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + + /* Check ICMPv6 enable status. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +ND_CACHE_ENTRY *nd_cache_entry; +NX_IPV6_DESTINATION_ENTRY + *dest_entry; +NXD_ADDRESS dest_ip; +CHAR mac_address[6]; +ULONG next_hop; + + + /* Print out test information banner. */ + printf("NetX Test: Dest Table Add Fail Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Added ND Cache entry until full. */ + for (i = 0; i < NX_IPV6_NEIGHBOR_CACHE_SIZE; i++) + { + + /* Set unique MAC address. */ + mac_address[0] = 0x00; + mac_address[1] = 0x11; + mac_address[2] = 0x22; + mac_address[3] = 0x33; + mac_address[4] = 0x44; + mac_address[5] = i + 1; + + /* Set unique ipv6 address. */ + dest_ip.nxd_ip_version = NX_IP_VERSION_V6; + dest_ip.nxd_ip_address.v6[0] = 0x20010000; + dest_ip.nxd_ip_address.v6[1] = 0x00000000; + dest_ip.nxd_ip_address.v6[2] = 0x00000000; + dest_ip.nxd_ip_address.v6[3] = i + 1; + + /* Call the function to added nd cache entry. */ + status = _nx_nd_cache_add(&ip_0, dest_ip.nxd_ip_address.v6, &ip_0.nx_ip_interface[0], mac_address, + NX_FALSE, ND_CACHE_STATE_CREATED, &(ip_0.nx_ipv6_address[0]), &nd_cache_entry); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Set unique MAC address. */ + mac_address[0] = 0x00; + mac_address[1] = 0x11; + mac_address[2] = 0x22; + mac_address[3] = 0x33; + mac_address[4] = 0x44; + mac_address[5] = i + 1; + + /* Set unique ipv6 address. */ + dest_ip.nxd_ip_version = NX_IP_VERSION_V6; + dest_ip.nxd_ip_address.v6[0] = 0x20010000; + dest_ip.nxd_ip_address.v6[1] = 0x00000000; + dest_ip.nxd_ip_address.v6[2] = 0x00000000; + dest_ip.nxd_ip_address.v6[3] = i + 1; + + /* Call the function to added nd cache entry. */ + status = _nx_nd_cache_add(&ip_0, dest_ip.nxd_ip_address.v6, &ip_0.nx_ip_interface[0], mac_address, + NX_FALSE, ND_CACHE_STATE_CREATED, &(ip_0.nx_ipv6_address[0]), &nd_cache_entry); + + /* Check status. */ + if (status != NX_NOT_SUCCESSFUL) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Add destination table entry. */ + status = _nx_icmpv6_dest_table_add(&ip_0, dest_ip.nxd_ip_address.v6, &dest_entry, + &next_hop, 0, 0, &(ip_0.nx_ipv6_address[0])); + + /* Check status. */ + if (status != NX_NOT_SUCCESSFUL) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now delete one nd cache entry. */ + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_nd_status = ND_CACHE_STATE_INVALID; + + /* Add destination table entry. */ + status = _nx_icmpv6_dest_table_add(&ip_0, dest_ip.nxd_ip_address.v6, &dest_entry, + &next_hop, 0, 0, &(ip_0.nx_ipv6_address[0])); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_dest_table_add_fail_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Dest Table Add Fail Test..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_icmp_small_header_test.c b/test/regression/netxduo_test/netx_forward_icmp_small_header_test.c new file mode 100644 index 00000000..0592f9a2 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_icmp_small_header_test.c @@ -0,0 +1,222 @@ +/* This NetX test concentrates on the forwarding operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_icmp_small_header_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 0. */ + status = nx_icmp_enable(&ip_0); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 1. */ + status = nx_icmp_enable(&ip_1); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 2. */ + status = nx_icmp_enable(&ip_2); + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: Forward ICMP Small Header Processing Test................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to get the IPv4 packet. */ + ip_0.nx_ipv4_packet_receive = my_packet_process; + + /* Now ip_1 ping ip_2. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_1, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 1) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +ULONG shift_size; + + /* Calculate the shift data size. */ + shift_size = (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr); + + /* Move the data to the start location, so the forward packet should remove the packet data to added the physical header. */ + memmove(packet_ptr -> nx_packet_data_start, packet_ptr -> nx_packet_prepend_ptr, shift_size); + + /* Update the prepend and append pointer. */ + packet_ptr -> nx_packet_prepend_ptr = packet_ptr -> nx_packet_data_start; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + shift_size; + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(ip_ptr, packet_ptr); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_icmp_small_header_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward ICMP Small Header Processing Test.................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_icmp_small_header_test2.c b/test/regression/netxduo_test/netx_forward_icmp_small_header_test2.c new file mode 100644 index 00000000..db832643 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_icmp_small_header_test2.c @@ -0,0 +1,299 @@ +/* This NetX test concentrates on the Forward ICMP ping with small header operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter = 0; +static ULONG shift_size = 0; +static ULONG callback_0_counter = 0; +static ULONG callback_1_counter = 0; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static VOID ip_0_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_icmp_small_header_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 3); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 0. */ + status = nx_icmp_enable(&ip_0); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 1. */ + status = nx_icmp_enable(&ip_1); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 2. */ + status = nx_icmp_enable(&ip_2); + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; +UINT size; +CHAR data[256]; + + + /* Print out test information banner. */ + printf("NetX Test: Forward ICMP Small Header Processing Test2................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup static ARP entries. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334458); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup static ARP entries. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0x0011, 0x22334459); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup static ARP entries. */ + status = nx_arp_static_entry_create(&ip_1, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup static ARP entries. */ + status = nx_arp_static_entry_create(&ip_2, IP_ADDRESS(2, 2, 3, 4), 0x0011, 0x22334457); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to get the IPv4 packet. */ + ip_0.nx_ipv4_packet_receive = ip_0_packet_process; + + /* Set the max size for ICMP. */ + size = 256 - NX_IPv4_ICMP_PACKET - NX_ICMP_HEADER_SIZE; + + /* Set the data. */ + for (i = 0; i < size; i++) + data[i] = 'a'; + + /* Now ip_1 ping ip_2 again, this packet will be modified by callback function. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(2, 2, 3, 5), data, size, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status . */ + if ((status != NX_SUCCESS) || (my_packet -> nx_packet_length != size)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the counter. */ + if ((callback_0_counter != 1) || (callback_1_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +static VOID ip_0_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + /* Update the counter. */ + callback_0_counter ++; + + /* Calculate the shift data size. */ + shift_size = (ULONG)(packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start); + + /* Update the data start pointer. */ + packet_ptr -> nx_packet_data_start += shift_size; + + /* Set the callback function to get the IPv4 packet. */ + advanced_packet_process_callback = driver_packet_process; + + /* Reset the IP callback function. */ + ip_0.nx_ipv4_packet_receive = _nx_ipv4_packet_receive; + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(ip_ptr, packet_ptr); +} +static UINT driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Update the counter. */ + callback_1_counter ++; + + /* Check the packet pointer for forwarding packet. */ + if ((packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start) != NX_PHYSICAL_HEADER) + error_counter ++; + + /* Update the packet start pointer.*/ + packet_ptr -> nx_packet_data_start -= shift_size; + + /* Clear the callback function. */ + advanced_packet_process_callback = NX_NULL; + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_icmp_small_header_test2_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward ICMP Small Header Processing Test2................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_icmp_small_header_test3.c b/test/regression/netxduo_test/netx_forward_icmp_small_header_test3.c new file mode 100644 index 00000000..80ed1a82 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_icmp_small_header_test3.c @@ -0,0 +1,314 @@ +/* This NetX test concentrates on the Forward ICMP ping with small header operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter = 0; +static ULONG shift_size = 0; +static ULONG callback_0_counter = 0; +static ULONG callback_1_counter = 0; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static VOID ip_0_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_icmp_small_header_test3_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 3); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 0. */ + status = nx_icmp_enable(&ip_0); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 1. */ + status = nx_icmp_enable(&ip_1); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 2. */ + status = nx_icmp_enable(&ip_2); + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; +UINT size; +CHAR data[256]; + + + /* Print out test information banner. */ + printf("NetX Test: Forward ICMP Small Header Processing Test3................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup static ARP entries. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334458); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup static ARP entries. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0x0011, 0x22334459); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup static ARP entries. */ + status = nx_arp_static_entry_create(&ip_1, IP_ADDRESS(1, 2, 3, 4), 0x0011, 0x22334456); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup static ARP entries. */ + status = nx_arp_static_entry_create(&ip_2, IP_ADDRESS(2, 2, 3, 4), 0x0011, 0x22334457); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to get the IPv4 packet. */ + ip_0.nx_ipv4_packet_receive = ip_0_packet_process; + + /* Set the max size for ICMP. */ + size = 256 - NX_IPv4_ICMP_PACKET - NX_ICMP_HEADER_SIZE; + + /* Set the data. */ + for (i = 0; i < size; i++) + data[i] = 'a'; + + /* Now ip_1 ping ip_2 again, this packet will be modified by callback function. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(2, 2, 3, 5), data, size, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status . */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the counter. */ + if ((callback_0_counter != 1) || (callback_1_counter != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +static VOID ip_0_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +UINT packet_counter; +UINT i; +UINT status; +NX_PACKET *my_packet[10]; + + /* Update the counter. */ + callback_0_counter ++; + + /* Calculate the shift data size. */ + shift_size = (ULONG)(packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start); + + /* Update the data start pointer. */ + packet_ptr -> nx_packet_data_start += shift_size; + + /* Set the callback function to get the IPv4 packet. */ + advanced_packet_process_callback = driver_packet_process; + + /* Reset the IP callback function. */ + ip_0.nx_ipv4_packet_receive = _nx_ipv4_packet_receive; + + /* Loop to allocate the all packets to let _nx_packet_data_append failure in nx_ip_forward_packet_process.c */ + packet_counter = pool_0.nx_packet_pool_available; + for (i = 0; i < packet_counter; i++) + { + status = nx_packet_allocate(&pool_0, &my_packet[i], 0, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter ++; + } + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(ip_ptr, packet_ptr); +} +static UINT driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Update the counter. */ + callback_1_counter ++; + + /* Check the packet pointer for forwarding packet. */ + if ((packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_data_start) != NX_PHYSICAL_HEADER) + error_counter ++; + + /* Update the packet start pointer.*/ + packet_ptr -> nx_packet_data_start -= shift_size; + + /* Clear the callback function. */ + advanced_packet_process_callback = NX_NULL; + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_icmp_small_header_test3_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward ICMP Small Header Processing Test3................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_icmp_test.c b/test/regression/netxduo_test/netx_forward_icmp_test.c new file mode 100644 index 00000000..79c51d1c --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_icmp_test.c @@ -0,0 +1,377 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_icmp_ping_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 0. */ + status = nx_icmp_enable(&ip_0); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 1. */ + status = nx_icmp_enable(&ip_1); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 2. */ + status = nx_icmp_enable(&ip_2); + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; + +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: Forward ICMP Processing Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ip_0 ping ip_1. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 1) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Now ip_0 ping ip_2. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 2) || (ping_responses_received != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + /* Enable all TX checksum capability. */ + nx_ip_interface_capability_set(&ip_0, 0, NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM); +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + /* Now ip_1 ping an one address of ip_0. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(1, 2, 3, 4), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_1, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 1) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Now ip_1 ping an other address of ip_0. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(2, 2, 3, 4), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_1, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 2) || (ping_responses_received != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Now ip_1 ping ip_2. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_1, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 3) || (ping_responses_received != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + /* Disable all interface capability. */ + nx_ip_interface_capability_set(&ip_0, 0, 0); +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + /* Now ip_2 ping an one address of ip_0. */ + status = nx_icmp_ping(&ip_2, IP_ADDRESS(2, 2, 3, 4), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_2, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 1) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Now ip_2 ping an other address of ip_0. */ + status = nx_icmp_ping(&ip_2, IP_ADDRESS(1, 2, 3, 4), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_2, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 2) || (ping_responses_received != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Now ip_2 ping ip_1. */ + status = nx_icmp_ping(&ip_2, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_2, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 3) || (ping_responses_received != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Now ip_1 ping the address that does not exist. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(3, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the timeout error occurred. */ + if ((ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_icmp_ping_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward ICMP Processing Test..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_icmp_ttl_test.c b/test/regression/netxduo_test/netx_forward_icmp_ttl_test.c new file mode 100644 index 00000000..1a5f8c68 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_icmp_ttl_test.c @@ -0,0 +1,303 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter = 0; +static ULONG icmp_counter = 0; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_icmp_ttl_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 0. */ + status = nx_icmp_enable(&ip_0); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 1. */ + status = nx_icmp_enable(&ip_1); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 2. */ + status = nx_icmp_enable(&ip_2); + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; + +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: Forward ICMP TTL Processing Test.........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function. */ + packet_process_callback = my_packet_process; + + /* Now ip_1 ping ip_2. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_1, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 1) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Now ip_1 ping ip_2 again, modified the TTL as 1, this packet should be dropped by forward function. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status . */ + if ((status == NX_SUCCESS) || (ip_0.nx_ip_receive_packets_dropped != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the ICMP counter for IP instance 1. */ + if (icmp_counter != 2) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +#if defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header_ptr; +#else +NX_IP_HEADER *ip_header_ptr; +#endif +ULONG protocol; +ULONG checksum; +ULONG old_m; +ULONG new_m; + + /* Only detect the IP instance 1. */ + if (ip_ptr != &ip_1) + return NX_TRUE; + + /* Ignore packet that is not ICMP. */ + if(packet_ptr -> nx_packet_length < 28) + return NX_TRUE; + +#if defined(__PRODUCT_NETXDUO__) + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + +#else + ip_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#endif + + /* Get IP header. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Get the next protocol. */ + protocol = (ip_header_ptr -> nx_ip_header_word_2 >> 16) & 0xFF; + + /* Is ICMP packet? */ + if(protocol == 1) + { + + /* Yes it is. */ + + /* Only modify the second ICMP packet. */ + if (icmp_counter == 1) + { + + /* Get the old checksum (HC) in header. */ + checksum = ip_header_ptr -> nx_ip_header_word_2 & NX_LOWER_16_MASK; + + /* Get the old TTL(m). */ + old_m = (ip_header_ptr -> nx_ip_header_word_2 & 0xFFFF0000) >> 16;; + + /* Set the new TTL as 1. */ + new_m = ((old_m & 0x00FF) | (0x0100)); + + /* Update the checksum, get the new checksum(HC'), + The new_m is ULONG value, so need get the lower value after invert. */ + checksum = ((~checksum) & 0xFFFF) + ((~old_m) & 0xFFFF) + new_m; + + /* Fold a 4-byte value into a two byte value */ + checksum = (checksum >> 16) + (checksum & 0xFFFF); + + /* Do it again in case previous operation generates an overflow */ + checksum = (checksum >> 16) + (checksum & 0xFFFF); + + /* Set the ttl as 1. */ + ip_header_ptr -> nx_ip_header_word_2 = (ip_header_ptr -> nx_ip_header_word_2 & 0x00FFFFFF) | 0x01000000; + + /* Now store the new checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ((ip_header_ptr -> nx_ip_header_word_2 & 0xFFFF0000) | ((~checksum) & NX_LOWER_16_MASK)); + } + + /* Update the ICMP counter. */ + icmp_counter ++; + } + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_icmp_ttl_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward ICMP TTL Processing Test..........................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_link_local_address_test.c b/test/regression/netxduo_test/netx_forward_link_local_address_test.c new file mode 100644 index 00000000..088545e2 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_link_local_address_test.c @@ -0,0 +1,187 @@ +/* This NetX test concentrates on the Link Local address check operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_link_local_address_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0, link local address. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(169, 254, 0, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2, link local address. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(169, 254, 0, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(169, 254, 0, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 0. */ + status = nx_icmp_enable(&ip_0); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 1. */ + status = nx_icmp_enable(&ip_1); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 2. */ + status = nx_icmp_enable(&ip_2); + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; + +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: Forward Link Local Address Test..........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ip_1 ping ip_2, ip_0 should not forward the packet with link-local address. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(169, 254, 0, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successfully. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_link_local_address_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward Link Local Address Test...........................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_multicast_test.c b/test/regression/netxduo_test/netx_forward_multicast_test.c new file mode 100644 index 00000000..a95b517d --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_multicast_test.c @@ -0,0 +1,224 @@ +/* This NetX test concentrates on the multicast forward. + * Multicast packet must not be forward. */ + +#include "tx_api.h" +#include "nx_api.h" + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_ICMP_INFO) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_multicast_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 0. */ + status = nx_icmp_enable(&ip_0); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 1. */ + status = nx_icmp_enable(&ip_1); + if (status) + error_counter++; + + /* Enable ICMP processing for both IP Instance 2. */ + status = nx_icmp_enable(&ip_2); + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; +NX_IP_DRIVER driver_request; + + + /* Print out test information banner. */ + printf("NetX Test: Forward multicast Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register the new multicast group with the underlying driver to + ensure that there is room for the new group at the hardware level. */ + driver_request.nx_ip_driver_ptr = &ip_0; + driver_request.nx_ip_driver_command = NX_LINK_MULTICAST_JOIN; + driver_request.nx_ip_driver_physical_address_msw = NX_IP_MULTICAST_UPPER; + driver_request.nx_ip_driver_physical_address_lsw = NX_IP_MULTICAST_LOWER | (IP_ADDRESS(224, 0, 0, 2) & NX_IP_MULTICAST_MASK); + driver_request.nx_ip_driver_interface = &ip_0.nx_ip_interface[0]; + (ip_0.nx_ip_interface[0].nx_interface_link_driver_entry)(&driver_request); + + /* Now ip_1 ping multicast address. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(224, 0, 0, 2), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* No response is expected. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + if ((status != NX_SUCCESS) || (ping_timeouts != 0) || (pings_sent != 0) || (ping_responses_received != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_icmp_info_get(&ip_1, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + if ((status != NX_SUCCESS) || (ping_timeouts != 1) || (pings_sent != 1) || (ping_responses_received != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_icmp_info_get(&ip_2, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + if ((status != NX_SUCCESS) || (ping_timeouts != 0) || (pings_sent != 0) || (ping_responses_received != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_multicast_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward multicast Test....................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_tcp_test_1.c b/test/regression/netxduo_test/netx_forward_tcp_test_1.c new file mode 100644 index 00000000..97f59c95 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_tcp_test_1.c @@ -0,0 +1,479 @@ +/* This NetX test concentrates on the basic TCP operation with forward. */ + +/* Test tcp function between IP_1 and Interface0 of IP_0. */ + + /*************/ + /* */ + /* IP_1 */ + /****************/ /* 1.2.3.5 */ + /* 1.2.3.4 */ /*************/ + /* Interface0 */ + /* */ + /* IP_0 */ + /* */ + /* Interface1 */ + /* 2.2.3.4 */ /*************/ + /****************/ /* */ + /* IP_2 */ + /* 2.2.3.5 */ + /*************/ + + + +#include "tx_api.h" +#include "nx_api.h" + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; +static NX_TCP_SOCKET socket_0; +static NX_TCP_SOCKET socket_1; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_tcp_test_1_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + status += nx_tcp_enable(&ip_2); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + /* Print out some test information banners. */ + printf("NetX Test: Forward TCP Processing Test1.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &socket_1, "Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_1, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&socket_1, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the port for the client socket. */ + status = nx_tcp_client_socket_port_get(&socket_1, &free_port); + + /* Check for error. */ + if ((status) || (free_port != 0x88)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&socket_1, IP_ADDRESS(1, 2, 3, 4), 0x89, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&socket_1, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&socket_1, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + nx_packet_release(my_packet); + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&socket_1, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&socket_1); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&socket_1, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + + if((packets_sent != 1) || (bytes_sent != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check for errors. */ + if ((error_counter) || (status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&socket_1); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &socket_0, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 0x89, &socket_0, 5, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&socket_0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&socket_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&socket_0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&socket_0); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 0x89); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&socket_0); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_tcp_test_1_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward TCP Processing Test1..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_tcp_test_2.c b/test/regression/netxduo_test/netx_forward_tcp_test_2.c new file mode 100644 index 00000000..40ea6902 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_tcp_test_2.c @@ -0,0 +1,476 @@ +/* This NetX test concentrates on the basic TCP operation with forward. */ + +/* Test tcp function between IP_1 and Interface1 of IP_0. */ + + /*************/ + /* */ + /* IP_1 */ + /****************/ /* 1.2.3.5 */ + /* 1.2.3.4 */ /*************/ + /* Interface0 */ + /* */ + /* IP_0 */ + /* */ + /* Interface1 */ + /* 2.2.3.4 */ /*************/ + /****************/ /* */ + /* IP_2 */ + /* 2.2.3.5 */ + /*************/ + + +#include "tx_api.h" +#include "nx_api.h" + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; +static NX_TCP_SOCKET socket_0; +static NX_TCP_SOCKET socket_1; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_tcp_test_2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + status += nx_tcp_enable(&ip_2); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + /* Print out some test information banners. */ + printf("NetX Test: Forward TCP Processing Test2.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &socket_1, "Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_1, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&socket_1, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the port for the client socket. */ + status = nx_tcp_client_socket_port_get(&socket_1, &free_port); + + /* Check for error. */ + if ((status) || (free_port != 0x88)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&socket_1, IP_ADDRESS(2, 2, 3, 4), 0x89, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&socket_1, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&socket_1, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + nx_packet_release(my_packet); + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&socket_1, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&socket_1); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&socket_1, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + + if((packets_sent != 1) || (bytes_sent != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check for errors. */ + if ((error_counter) || (status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&socket_1); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &socket_0, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 0x89, &socket_0, 5, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&socket_0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&socket_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&socket_0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&socket_0); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 0x89); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&socket_0); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_tcp_test_2_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward TCP Processing Test2..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_tcp_test_3.c b/test/regression/netxduo_test/netx_forward_tcp_test_3.c new file mode 100644 index 00000000..defc829f --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_tcp_test_3.c @@ -0,0 +1,480 @@ +/* This NetX test concentrates on the basic TCP operation with forward. */ + +/* Test tcp function between IP_2 and Interface0 of IP_0. */ + + /*************/ + /* */ + /* IP_1 */ + /****************/ /* 1.2.3.5 */ + /* 1.2.3.4 */ /*************/ + /* Interface0 */ + /* */ + /* IP_0 */ + /* */ + /* Interface1 */ + /* 2.2.3.4 */ /*************/ + /****************/ /* */ + /* IP_2 */ + /* 2.2.3.5 */ + /*************/ + + +#include "tx_api.h" +#include "nx_api.h" + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; +static NX_TCP_SOCKET socket_0; +static NX_TCP_SOCKET socket_2; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_tcp_test_3_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + status += nx_tcp_enable(&ip_2); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + /* Print out some test information banners. */ + printf("NetX Test: Forward TCP Processing Test3.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_2, &socket_2, "Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_2, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&socket_2, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the port for the client socket. */ + status = nx_tcp_client_socket_port_get(&socket_2, &free_port); + + /* Check for error. */ + if ((status) || (free_port != 0x88)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&socket_2, IP_ADDRESS(1, 2, 3, 4), 0x89, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&socket_2, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&socket_2, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + nx_packet_release(my_packet); + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&socket_2, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&socket_2); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&socket_2, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + + if((packets_sent != 1) || (bytes_sent != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check for errors. */ + if ((error_counter) || (status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&socket_2); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &socket_0, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 0x89, &socket_0, 5, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&socket_0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&socket_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&socket_0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&socket_0); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 0x89); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&socket_0); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_tcp_test_3_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward TCP Processing Test3..............................N/A\n"); + test_control_return(3); +} +#endif + + diff --git a/test/regression/netxduo_test/netx_forward_tcp_test_4.c b/test/regression/netxduo_test/netx_forward_tcp_test_4.c new file mode 100644 index 00000000..f9fe12d1 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_tcp_test_4.c @@ -0,0 +1,476 @@ +/* This NetX test concentrates on the basic TCP operation with forward. */ + +/* Test tcp function between IP_2 and Interface1 of IP_0. */ + + /*************/ + /* */ + /* IP_1 */ + /****************/ /* 1.2.3.5 */ + /* 1.2.3.4 */ /*************/ + /* Interface0 */ + /* */ + /* IP_0 */ + /* */ + /* Interface1 */ + /* 2.2.3.4 */ /*************/ + /****************/ /* */ + /* IP_2 */ + /* 2.2.3.5 */ + /*************/ + + +#include "tx_api.h" +#include "nx_api.h" + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; +static NX_TCP_SOCKET socket_0; +static NX_TCP_SOCKET socket_2; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_tcp_test_4_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + status += nx_tcp_enable(&ip_2); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + /* Print out some test information banners. */ + printf("NetX Test: Forward TCP Processing Test4.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_2, &socket_2, "Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_2, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&socket_2, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the port for the client socket. */ + status = nx_tcp_client_socket_port_get(&socket_2, &free_port); + + /* Check for error. */ + if ((status) || (free_port != 0x88)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&socket_2, IP_ADDRESS(2, 2, 3, 4), 0x89, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&socket_2, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&socket_2, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + nx_packet_release(my_packet); + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&socket_2, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&socket_2); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&socket_2, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + + if((packets_sent != 1) || (bytes_sent != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check for errors. */ + if ((error_counter) || (status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&socket_2); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &socket_0, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 0x89, &socket_0, 5, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&socket_0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&socket_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&socket_0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&socket_0); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 0x89); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&socket_0); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_tcp_test_4_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward TCP Processing Test4..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_tcp_test_5.c b/test/regression/netxduo_test/netx_forward_tcp_test_5.c new file mode 100644 index 00000000..94ba66c4 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_tcp_test_5.c @@ -0,0 +1,476 @@ +/* This NetX test concentrates on the basic TCP operation with forward. */ + +/* Test tcp function between IP_1 and IP_2. */ + + /*************/ + /* */ + /* IP_1 */ + /****************/ /* 1.2.3.5 */ + /* 1.2.3.4 */ /*************/ + /* Interface0 */ + /* */ + /* IP_0 */ + /* */ + /* Interface1 */ + /* 2.2.3.4 */ /*************/ + /****************/ /* */ + /* IP_2 */ + /* 2.2.3.5 */ + /*************/ + + +#include "tx_api.h" +#include "nx_api.h" + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; +static NX_TCP_SOCKET socket_1; +static NX_TCP_SOCKET socket_2; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_tcp_test_5_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + status += nx_tcp_enable(&ip_2); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + /* Print out some test information banners. */ + printf("NetX Test: Forward TCP Processing Test5.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &socket_1, "Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_1, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&socket_1, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the port for the client socket. */ + status = nx_tcp_client_socket_port_get(&socket_1, &free_port); + + /* Check for error. */ + if ((status) || (free_port != 0x88)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&socket_1, IP_ADDRESS(2, 2, 3, 5), 0x89, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&socket_1, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&socket_1, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + nx_packet_release(my_packet); + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&socket_1, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&socket_1); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&socket_1, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + + if((packets_sent != 1) || (bytes_sent != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check for errors. */ + if ((error_counter) || (status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&socket_1); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_2, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_2, &socket_2, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_2, 0x89, &socket_2, 5, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&socket_2, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&socket_2, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&socket_2, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&socket_2); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_2, 0x89); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&socket_2); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_tcp_test_5_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward TCP Processing Test5..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_udp_fragment_test.c b/test/regression/netxduo_test/netx_forward_udp_fragment_test.c new file mode 100644 index 00000000..e9d67e6c --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_udp_fragment_test.c @@ -0,0 +1,497 @@ +/* This NetX test concentrates on forward fragment operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined (NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +static NX_UDP_SOCKET socket_1; +static NX_UDP_SOCKET socket_2; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; +static ULONG notify_calls = 0; + +static UCHAR message[1024]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_udp_fragment_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + notify_calls = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 1500 * 10); + pointer = pointer + 1500 * 10; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_256); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + status += nx_udp_enable(&ip_2); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; + + /* Enable the fragment function. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + status += nx_ip_fragment_enable(&ip_2); + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Print out some test information banners. */ + printf("NetX Test: Forward UDP Fragment Test................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket 1. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x89. */ + status = nx_udp_free_port_find(&ip_1, 0x89, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x89)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_1, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x89)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket 2. */ + status = nx_udp_socket_create(&ip_2, &socket_2, "Socket 2", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x8a. */ + status = nx_udp_free_port_find(&ip_2, 0x8a, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x8a)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_2, 0x8a, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_2, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x8a)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket1 sends udp packet to Socket2 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Clear the message. */ + memset(&message[0], 1, 1024); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &message[0], 400); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 400; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 400; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(2, 2, 3, 5), 0x8a); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP socket2 information. */ + status = nx_udp_socket_info_get(&socket_2, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != 0) || (bytes_sent != 0) || (packets_received != 1) || (bytes_received != 400)) + { + error_counter++; + } +#endif + /* Check status. */ + if ((error_counter) || (receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /***********************************************************************/ + /* Socket1 sends udp packet to Socket2 */ + /***********************************************************************/ + + /* Clear the message. */ + memset(&message[0], 1, 1024); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &message[0], 1024); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 1024; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 1024; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(2, 2, 3, 5), 0x8a); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Get UDP socket2 information. */ + status = nx_udp_socket_info_get(&socket_2, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != 0) || (bytes_sent != 0) || (packets_received != 2) || (bytes_received != 1424)) + { + error_counter++; + } +#endif + /* Check status. */ + if ((error_counter) || (receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_2); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_2); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /***********************************************************************/ + /* Socket2 receives the udp packet from Socket1 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_2, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_2, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_udp_fragment_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward UDP Fragment Test.................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_udp_fragment_test2.c b/test/regression/netxduo_test/netx_forward_udp_fragment_test2.c new file mode 100644 index 00000000..bf990e23 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_udp_fragment_test2.c @@ -0,0 +1,457 @@ +/* This NetX test concentrates on the forward fragment operation(fragment failure:_nx_packet_allocate failure in nx_ip_fragment_forward_packet). */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined (NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +static NX_UDP_SOCKET socket_1; +static NX_UDP_SOCKET socket_2; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; +static ULONG packet_received = NX_FALSE; +static ULONG notify_calls = 0; + +static UCHAR message[1024]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_udp_fragment_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + notify_calls = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 1500 * 10); + pointer = pointer + 1500 * 10; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + status += nx_udp_enable(&ip_2); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; + + /* Enable the fragment function. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + status += nx_ip_fragment_enable(&ip_2); + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; + + + /* Print out some test information banners. */ + printf("NetX Test: Forward UDP Fragment Test2................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket 1. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x89. */ + status = nx_udp_free_port_find(&ip_1, 0x89, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x89)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_1, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x89)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to get the IPv4 packet. */ + ip_0.nx_ipv4_packet_receive = my_packet_process; + + /***********************************************************************/ + /* Socket1 sends udp packet to Socket2 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Clear the message. */ + memset(&message[0], 1, 1024); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_data_append(my_packet, &message[0], 800, &pool_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(2, 2, 3, 5), 0x8a); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((error_counter) || (packet_received != NX_TRUE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Create a UDP socket 2. */ + status = nx_udp_socket_create(&ip_2, &socket_2, "Socket 2", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x8a. */ + status = nx_udp_free_port_find(&ip_2, 0x8a, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x8a)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_2, 0x8a, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_2, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x8a)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket2 receives the udp packet from Socket1 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_2, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP socket2 information. */ + status = nx_udp_socket_info_get(&socket_2, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != 0) || (bytes_sent != 0) || (packets_received != 1) || (bytes_received != 800)) + { + error_counter++; + } +#endif + + /* Check status. */ + if ((error_counter) || (receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +UINT i; +UINT avalibale_count; +NX_PACKET *my_packet; +NX_PACKET *tmp_packet[10]; + + + /* Update the flag. */ + packet_received = NX_TRUE; + + /* Store the packet. */ + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, &my_packet, &pool_0, NX_NO_WAIT); + + /* Check the status. */ + if (status) + error_counter++; + + /* Get the available count. */ + avalibale_count = pool_0.nx_packet_pool_available; + + /* Allocate the all packets. */ + for (i = 0; i < avalibale_count; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &tmp_packet[i], NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check the status. */ + if (status) + error_counter++; + } + + /* Call the _nx_ipv4_packet_receive function directly receive this packet(forward module). */ + _nx_ipv4_packet_receive(&ip_0, packet_ptr); + + /* Check the forward fragment operation(_nx_ip_fragment_forward_packet function). */ +#ifndef NX_DISABLE_IP_INFO + if ((ip_0.nx_ip_fragment_failures != 1) || (ip_0.nx_ip_send_packets_dropped != 1) || (ip_0.nx_ip_transmit_resource_errors != 1)) + error_counter++; +#endif + + /* Check the packet available count(fragment failure, the source packet should be release). */ + if (pool_0.nx_packet_pool_available != 1) + error_counter++; + + /* Allocate the all packets. */ + for (i = 0; i < avalibale_count; i++) + { + + /* Release the packets. */ + nx_packet_release(tmp_packet[i]); + } + + /* Call the _nx_ipv4_packet_receive function directly receive the copy packet(forward module). */ + _nx_ipv4_packet_receive(&ip_0, my_packet); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_udp_fragment_test2_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward UDP Fragment Test2................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_udp_fragment_test3.c b/test/regression/netxduo_test/netx_forward_udp_fragment_test3.c new file mode 100644 index 00000000..ec2836b1 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_udp_fragment_test3.c @@ -0,0 +1,445 @@ +/* This NetX test concentrates on the forward fragment operation(fragment failure:_nx_packet_data_append failure in nx_ip_fragment_forward_packet). */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined (NX_DISABLE_FRAGMENTATION) && !defined (NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_PACKET_POOL pool_2; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +static NX_UDP_SOCKET socket_1; +static NX_UDP_SOCKET socket_2; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; +static ULONG packet_received = NX_FALSE; +static ULONG notify_calls = 0; + +static UCHAR message[1024]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_udp_fragment_test3_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + notify_calls = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 256 * 10); + pointer = pointer + 256 * 10; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 1500, pointer, 1500 * 10); + pointer = pointer + 1500 * 10; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_2, "NetX Main Packet Pool", 1500, pointer, 1500 * 10); + pointer = pointer + 1500 * 10; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_2, _nx_ram_network_driver_512, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + status += nx_udp_enable(&ip_2); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; + + /* Enable the fragment function. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + status += nx_ip_fragment_enable(&ip_2); + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; + + + /* Print out some test information banners. */ + printf("NetX Test: Forward UDP Fragment Test3................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket 1. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x89. */ + status = nx_udp_free_port_find(&ip_1, 0x89, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x89)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_1, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x89)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to get the IPv4 packet. */ + ip_0.nx_ipv4_packet_receive = my_packet_process; + + /***********************************************************************/ + /* Socket1 sends udp packet to Socket2 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Clear the message. */ + memset(&message[0], 1, 1024); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_1, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_data_append(my_packet, &message[0], 800, &pool_1, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(2, 2, 3, 5), 0x8a); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((error_counter) || (packet_received != NX_TRUE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Create a UDP socket 2. */ + status = nx_udp_socket_create(&ip_2, &socket_2, "Socket 2", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x8a. */ + status = nx_udp_free_port_find(&ip_2, 0x8a, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x8a)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_2, 0x8a, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_2, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x8a)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket2 receives the udp packet from Socket1 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_2, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP socket2 information. */ + status = nx_udp_socket_info_get(&socket_2, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != 0) || (bytes_sent != 0) || (packets_received != 0) || (bytes_received != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check status. */ + if ((receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +UINT i; +UINT avalibale_count; +NX_PACKET *tmp_packet[10]; + + + /* Update the flag. */ + packet_received = NX_TRUE; + + /* Get the available count. */ + avalibale_count = pool_0.nx_packet_pool_available; + + /* Fragment packet_ptr need four packets. */ + + /* Remain two packets for fragment, one packet for nx_packet allocate, one packet for nx_packet_data_append in nx_ip_fragment_forward_packet. */ + for (i = 0; i < avalibale_count - 2; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &tmp_packet[i], 0, TX_WAIT_FOREVER); + + /* Check the status. */ + if (status) + error_counter++; + } + + /* Call the _nx_ipv4_packet_receive function directly receive the copy packet(forward module). */ + _nx_ipv4_packet_receive(&ip_0, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_udp_fragment_test3_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward UDP Fragment Test3................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_udp_fragment_test4.c b/test/regression/netxduo_test/netx_forward_udp_fragment_test4.c new file mode 100644 index 00000000..200d6e19 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_udp_fragment_test4.c @@ -0,0 +1,446 @@ +/* This NetX test concentrates on the forward fragment operation. + (fragment failure: source_packet -> nx_packet_next is null and the remaining_bytes is non zero in nx_ip_fragment_forward_packet). */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined (NX_DISABLE_FRAGMENTATION) && !defined (NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_PACKET_POOL pool_2; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +static NX_UDP_SOCKET socket_1; +static NX_UDP_SOCKET socket_2; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; +static ULONG packet_received = NX_FALSE; +static UCHAR message[1024]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_udp_fragment_test4_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 256 * 10); + pointer = pointer + 256 * 10; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 1500, pointer, 1500 * 10); + pointer = pointer + 1500 * 10; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_2, "NetX Main Packet Pool", 1500, pointer, 1500 * 10); + pointer = pointer + 1500 * 10; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_2, _nx_ram_network_driver_512, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + status += nx_udp_enable(&ip_2); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; + + /* Enable the fragment function. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + status += nx_ip_fragment_enable(&ip_2); + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; + + + /* Print out some test information banners. */ + printf("NetX Test: Forward UDP Fragment Test4................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket 1. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x89. */ + status = nx_udp_free_port_find(&ip_1, 0x89, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x89)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_1, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x89)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to get the IPv4 packet. */ + ip_0.nx_ipv4_packet_receive = my_packet_process; + + /***********************************************************************/ + /* Socket1 sends udp packet to Socket2 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Clear the message. */ + memset(&message[0], 1, 1024); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_1, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_data_append(my_packet, &message[0], 800, &pool_1, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(2, 2, 3, 5), 0x8a); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((error_counter) || (packet_received != NX_TRUE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Create a UDP socket 2. */ + status = nx_udp_socket_create(&ip_2, &socket_2, "Socket 2", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x8a. */ + status = nx_udp_free_port_find(&ip_2, 0x8a, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x8a)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_2, 0x8a, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_2, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x8a)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket2 receives the udp packet from Socket1 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_2, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP socket2 information. */ + status = nx_udp_socket_info_get(&socket_2, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != 0) || (bytes_sent != 0) || (packets_received != 0) || (bytes_received != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check status. */ + if ((receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_IPV4_HEADER *ip_header_ptr; +ULONG checksum; +ULONG val; + + /* Update the flag. */ + packet_received = NX_TRUE; + + /* Discard the chain packet. */ + packet_ptr -> nx_packet_next = NX_NULL; + packet_ptr -> nx_packet_last = NX_NULL; + + /* Set the IP header. */ + ip_header_ptr = (NX_IPV4_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + + /* Clear the checksum. */ + ip_header_ptr -> nx_ip_header_word_2 &= 0x0000FFFF; + + /* Calcuate the checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, 20, NULL, NULL); + + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + + /* Call the _nx_ipv4_packet_receive function directly receive the copy packet(forward module). */ + _nx_ipv4_packet_receive(&ip_0, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_udp_fragment_test4_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward UDP Fragment Test3................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_forward_udp_test.c b/test/regression/netxduo_test/netx_forward_udp_test.c new file mode 100644 index 00000000..25b17598 --- /dev/null +++ b/test/regression/netxduo_test/netx_forward_udp_test.c @@ -0,0 +1,954 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; +static NX_UDP_SOCKET socket_2; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_udp_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + notify_calls = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an forward IP Instance 0. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface for forward IP Instance 0. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if (status) + error_counter++; + + /* Create an IP Instance 1. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 1. */ + status = nx_ip_gateway_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 4)); + if (status) + error_counter++; + + /* Create another IP Instance 2. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the gateway for IP Instance 2. */ + status = nx_ip_gateway_address_set(&ip_2, IP_ADDRESS(2, 2, 3, 4)); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + status += nx_udp_enable(&ip_2); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable the forwarding function for IP Instance 0. */ + status = nx_ip_forwarding_enable(&ip_0); + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Print out some test information banners. */ + printf("NetX Test: Forward UDP Processing Test..............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket 0. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x88. */ + status = nx_udp_free_port_find(&ip_0, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket 1. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x89. */ + status = nx_udp_free_port_find(&ip_1, 0x89, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x89)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_1, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x89)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket 2. */ + status = nx_udp_socket_create(&ip_2, &socket_2, "Socket 2", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x8a. */ + status = nx_udp_free_port_find(&ip_2, 0x8a, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x8a)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_2, 0x8a, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_2, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x8a)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket0 sends udp packet to unknow address */ + /***********************************************************************/ + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(3, 2, 3, 5), 0x89, 0); + + /* Check status. */ + if (status) + { + nx_packet_release(my_packet); + } + + /***********************************************************************/ + /* Socket0 sends udp packet to Socket1 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket0 sends udp packet to Socket2 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(2, 2, 3, 5), 0x8a); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket1 sends udp packet to Socket0 by interface0 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(1, 2, 3, 4), 0x88); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket1 sends udp packet to Socket0 by interface1 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(2, 2, 3, 4), 0x88); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket1 sends udp packet to Socket2 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(2, 2, 3, 5), 0x8a); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket2 sends udp packet to Socket0 by interface0 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_2, my_packet, IP_ADDRESS(1, 2, 3, 4), 0x88); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket2 sends udp packet to Socket0 by interface1 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_2, my_packet, IP_ADDRESS(2, 2, 3, 4), 0x88); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket2 sends udp packet to Socket1 */ + /***********************************************************************/ + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_2, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Get UDP socket0 information. */ + status = nx_udp_socket_info_get(&socket_0, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != 3) || (bytes_sent != 3 * 28) || (packets_received != 4) || (bytes_received != 4 * 28)) + { + error_counter++; + } +#endif + /* Check status. */ + if ((error_counter) || (receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP socket1 information. */ + status = nx_udp_socket_info_get(&socket_1, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != 3) || (bytes_sent != 3 * 28) || (packets_received != 2) || (bytes_received != 2 * 28)) + { + error_counter++; + } +#endif + /* Check status. */ + if ((error_counter) || (receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP socket2 information. */ + status = nx_udp_socket_info_get(&socket_2, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != 3) || (bytes_sent != 3 * 28) || (packets_received != 2) || (bytes_received != 2 * 28)) + { + error_counter++; + } +#endif + /* Check status. */ + if ((error_counter) || (receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_2); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_2); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + + /***********************************************************************/ + /* Socket1 receives the udp packet from Socket0 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket2 receives the udp packet from Socket0 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_2, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket0 receives the udp packet from Socket1 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket0 receives the udp packet from Socket1 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket2 receives the udp packet from Socket1 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_2, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket0 receives the udp packet from Socket2 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket0 receives the udp packet from Socket2 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************************************/ + /* Socket1 receives the udp packet from Socket2 */ + /***********************************************************************/ + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_forward_udp_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Forward UDP Processing Test...............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_http_proxy_basic_test.c b/test/regression/netxduo_test/netx_http_proxy_basic_test.c new file mode 100644 index 00000000..d9aacbf3 --- /dev/null +++ b/test/regression/netxduo_test/netx_http_proxy_basic_test.c @@ -0,0 +1,481 @@ +/* This case tests basic HTTP Proxy connection. */ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_ENABLE_HTTP_PROXY) && defined(__PRODUCT_NETXDUO__) +#include "nx_http_proxy_client.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 +#define TOTAL_SIZE DEMO_STACK_SIZE + (PACKET_SIZE * 8) + 2048 + 1024 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_TCP_SOCKET test_client; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET test_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +static UINT test_server_start = 0; +static UINT test_client_stop = 0; + +/* Set up the HTTP proxy server global variables */ +static TX_THREAD proxy_thread; +static NX_PACKET_POOL proxy_pool; +static NX_IP proxy_ip; +static NX_TCP_SOCKET agent_server, agent_client; + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static void thread_proxy_entry(ULONG thread_input); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define HTTP_PROXY_ADDRESS IP_ADDRESS(1,2,3,6) +#define HTTP_PROXY_PORT 8888 +#define TEST_SERVER_PORT 8080 + +static UCHAR connect_200[] = +{ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x43, 0x6f, 0x6e, +0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, +0x68, 0x65, 0x64, 0x0d, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, +0x3a, 0x20, 0x74, 0x69, 0x6e, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x31, 0x2e, 0x38, 0x2e, +0x34, 0x0d, 0x0a, 0x0d, 0x0a, +}; + +static UCHAR connect_req[] = +{ +0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x3a, /* CONNECT 1.2.3.4: */ +0x38, 0x30, 0x38, 0x30, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, /* 8080 HTTP/1.1..H */ +0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x0d, 0x0a, 0x50, 0x72, /* ost: 1.2.3.4..Pr */ +0x6f, 0x78, 0x79, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, /* oxy-authorizatio */ +0x6e, 0x3a, 0x20, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, 0x64, 0x58, 0x4e, 0x6c, 0x63, 0x6a, 0x70, /* n: Basic dXNlcjp */ +0x77, 0x59, 0x58, 0x4e, 0x7a, 0x64, 0x32, 0x39, 0x79, 0x5a, 0x41, 0x3d, 0x3d, 0x0d, 0x0a, 0x0d, /* wYXNzd29yZA==... */ +0x0a +}; + +static UCHAR test_data[] = "HTTP Proxy Basic Test!"; + +#define TEST_LOOP 3 + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_basic_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + /* Create the HTTP Proxy thread. */ + status = tx_thread_create(&proxy_thread, "HTTP Proxy", thread_proxy_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&proxy_pool, "HTTP Proxy Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&proxy_ip, "HTTP Proxy IP", HTTP_PROXY_ADDRESS, + 0xFFFFFF00UL, &proxy_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&proxy_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&proxy_ip); + if (status) + error_counter++; +} + +void thread_client_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS proxy_server_address; +NXD_ADDRESS server_ip_address; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + proxy_server_address.nxd_ip_version = NX_IP_VERSION_V4; + proxy_server_address.nxd_ip_address.v4 = HTTP_PROXY_ADDRESS; + + status = nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, NX_NULL, 1, "password", sizeof("password") - 1); + if (status != NX_PTR_ERROR) + error_counter++; + + status = nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", sizeof("user") - 1, NX_NULL, 1); + if (status != NX_PTR_ERROR) + error_counter++; + + status = nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", NX_HTTP_PROXY_MAX_USERNAME + 1, "password", sizeof("password") - 1); + if (status != NX_SIZE_ERROR) + error_counter++; + + status = nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", sizeof("user") - 1, "password", NX_HTTP_PROXY_MAX_PASSWORD + 1); + if (status != NX_SIZE_ERROR) + error_counter++; + + status = nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", sizeof("user") - 1, "password", sizeof("password") - 1); + if(status) + error_counter++; + + status = nx_tcp_socket_create(&client_ip, &test_client, "Test Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&test_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + for ( i = 0 ; i < TEST_LOOP; i++) + { + + /* Wait test server started. */ + while(!test_server_start) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send data. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_packet_data_append(packet_ptr, test_data, sizeof(test_data) - 1, &client_pool, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_tcp_socket_send(&test_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive the echo data from server. */ + status = nx_tcp_socket_receive(&test_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + + /* Check the received data. */ + if ((packet_ptr -> nx_packet_length != (sizeof(test_data) - 1)) || + (memcmp(packet_ptr -> nx_packet_prepend_ptr, test_data, packet_ptr -> nx_packet_length) != 0)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Set the flag. */ + test_client_stop = 1; + nx_tcp_socket_disconnect(&test_client, NX_IP_PERIODIC_RATE); + } + + nx_tcp_client_socket_unbind(&test_client); + nx_tcp_socket_delete(&test_client); +} + +void thread_proxy_entry(ULONG thread_input) +{ +UINT i, status; +ULONG actual_status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&proxy_ip, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&proxy_ip, &agent_server, "Agent Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + status += nx_tcp_socket_create(&proxy_ip, &agent_client, "Agent Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&proxy_ip, HTTP_PROXY_PORT, &agent_server, 5, NX_NULL); + if(status) + error_counter++; + + for (i = 0; i < TEST_LOOP; i++) + { + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&agent_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive CONNECT request. */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Check the received CONNECT request. */ + if (memcmp(packet_ptr -> nx_packet_prepend_ptr, connect_req, sizeof(connect_req)) != 0) + error_counter++; + + /* Connect to the test server. */ + status = nx_tcp_client_socket_bind(&agent_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + status += nxd_tcp_client_socket_connect(&agent_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send response to test client. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_length = 0; + nx_packet_data_append(packet_ptr, connect_200, sizeof(connect_200), &proxy_pool, NX_IP_PERIODIC_RATE); + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Tunneling... */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_receive(&agent_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnet. */ + nx_tcp_socket_disconnect(&agent_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&agent_server); + nx_tcp_server_socket_relisten(&proxy_ip, HTTP_PROXY_PORT, &agent_server); + nx_tcp_socket_disconnect(&agent_client, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&agent_client); + } + + nx_tcp_socket_delete(&agent_server); + nx_tcp_socket_delete(&agent_client); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Basic Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_create(&server_ip, &test_server, "Test Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + status = nx_tcp_server_socket_listen(&server_ip, TEST_SERVER_PORT, &test_server, 5, NX_NULL); + if(status) + error_counter++; + + for (i = 0; i < TEST_LOOP; i++) + { + + /* Set the flag. */ + test_server_start = 1; + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&test_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive client data. */ + status = nx_tcp_socket_receive(&test_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Echo data. */ + status = nx_tcp_socket_send(&test_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + while(!test_client_stop) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + test_server_start = 0; + test_client_stop = 0; + + nx_tcp_socket_disconnect(&test_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&test_server); + nx_tcp_server_socket_relisten(&server_ip, TEST_SERVER_PORT, &test_server); + } + nx_tcp_server_socket_unlisten(&server_ip, TEST_SERVER_PORT); + nx_tcp_socket_delete(&test_server); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Basic Test.....................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_http_proxy_data_fin_test.c b/test/regression/netxduo_test/netx_http_proxy_data_fin_test.c new file mode 100644 index 00000000..6a418666 --- /dev/null +++ b/test/regression/netxduo_test/netx_http_proxy_data_fin_test.c @@ -0,0 +1,589 @@ +/* This case tests: +1. TCP connection failed with HTTP Proxy server. +2. Processing CONNECT response with FIN set. */ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_ENABLE_HTTP_PROXY) && !defined(NX_DISABLE_EXTENDED_NOTIFY_SUPPORT) && defined(__PRODUCT_NETXDUO__) +#include "nx_http_proxy_client.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 +#define TOTAL_SIZE DEMO_STACK_SIZE + (PACKET_SIZE * 8) + 2048 + 1024 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_TCP_SOCKET test_client; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET test_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +static UINT test_server_start = 0; +static UINT test_client_stop = 0; + +/* Set up the HTTP proxy server global variables */ +static TX_THREAD proxy_thread; +static NX_PACKET_POOL proxy_pool; +static NX_IP proxy_ip; +static NX_TCP_SOCKET agent_server, agent_client; + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static void thread_proxy_entry(ULONG thread_input); +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define HTTP_PROXY_ADDRESS IP_ADDRESS(1,2,3,6) +#define HTTP_PROXY_PORT 8888 +#define TEST_SERVER_PORT 8080 + +static UCHAR connect_200[] = +{ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x43, 0x6f, 0x6e, /* HTTP/1.0 200 Con */ +0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, /* nection establis */ +0x68, 0x65, 0x64, 0x0d, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, /* hed..Proxy-agent */ +0x3a, 0x20, 0x74, 0x69, 0x6e, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x31, 0x2e, 0x38, 0x2e, /* : tinyproxy/1.8. */ +0x34, 0x0d, 0x0a, 0x0d, 0x0a, /* 4.... */ +}; + +static UCHAR connect_req[] = +{ +0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x3a, /* CONNECT 1.2.3.4: */ +0x38, 0x30, 0x38, 0x30, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, /* 8080 HTTP/1.1..H */ +0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x0d, 0x0a, 0x50, 0x72, /* ost: 1.2.3.4..Pr */ +0x6f, 0x78, 0x79, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, /* oxy-authorizatio */ +0x6e, 0x3a, 0x20, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, 0x64, 0x58, 0x4e, 0x6c, 0x63, 0x6a, 0x70, /* n: Basic dXNlcjp */ +0x77, 0x59, 0x58, 0x4e, 0x7a, 0x64, 0x32, 0x39, 0x79, 0x5a, 0x41, 0x3d, 0x3d, 0x0d, 0x0a, 0x0d, /* wYXNzd29yZA==... */ +0x0a +}; + +static UCHAR connect_403[] = +{ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x33, 0x20, 0x41, 0x63, 0x63, /* HTTP/1.0 403 Acc */ +0x65, 0x73, 0x73, 0x20, 0x76, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0d, 0x0a, 0x53, /* ess violation..S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x74, 0x69, 0x6e, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, /* erver: tinyproxy */ +0x2f, 0x31, 0x2e, 0x38, 0x2e, 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, /* /1.8.4..Content- */ +0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, /* Type: text/html. */ +0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, /* .Connection: clo */ +0x73, 0x65, 0x0d, 0x0a, 0x0d, 0x0a, /* se.... */ +}; + +static UCHAR test_data[] = "HTTP Proxy Basic Test!"; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_data_fin_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + /* Create the HTTP Proxy thread. */ + status = tx_thread_create(&proxy_thread, "HTTP Proxy", thread_proxy_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&proxy_pool, "HTTP Proxy Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&proxy_ip, "HTTP Proxy IP", HTTP_PROXY_ADDRESS, + 0xFFFFFF00UL, &proxy_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&proxy_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&proxy_ip); + if (status) + error_counter++; +} + +static UINT connected = NX_FALSE; +static UINT disconnected = NX_FALSE; +static void test_establish_notify(NX_TCP_SOCKET *socekt_ptr) +{ + connected = NX_TRUE; +} + +static void test_disconnect_callback(NX_TCP_SOCKET *socekt_ptr) +{ + disconnected = NX_TRUE; +} + +void thread_client_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +NXD_ADDRESS proxy_server_address; +NXD_ADDRESS server_ip_address; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + proxy_server_address.nxd_ip_version = NX_IP_VERSION_V4; + proxy_server_address.nxd_ip_address.v4 = HTTP_PROXY_ADDRESS; + nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", sizeof("user") - 1, "password", sizeof("password") - 1); + + status = nx_tcp_socket_create(&client_ip, &test_client, "Test Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, test_disconnect_callback); + if(status) + error_counter++; + + nx_tcp_socket_establish_notify(&test_client, test_establish_notify); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&test_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait test server started. */ + while(!test_server_start) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + connected = NX_FALSE; + disconnected = NX_FALSE; + + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + + /* Server not started. */ + if (!status || (connected == NX_TRUE) || (disconnected == NX_TRUE)) + { + error_counter++; + test_client_stop = 1; + return; + } + + /* Resume the HTTP Proxy server. */ + tx_thread_resume(&proxy_thread); + + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + + /* Error response with FIN set. */ + if (!status || (connected == NX_TRUE) || (disconnected == NX_TRUE)) + { + error_counter++; + test_client_stop = 1; + return; + } + + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + + if (status || (connected != NX_TRUE)) + { + error_counter++; + test_client_stop = 1; + return; + } + + /* Send data. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_packet_data_append(packet_ptr, test_data, sizeof(test_data) - 1, &client_pool, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_tcp_socket_send(&test_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive the echo data from server. */ + status = nx_tcp_socket_receive(&test_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + + /* Check the received data. */ + if ((packet_ptr -> nx_packet_length != (sizeof(test_data) - 1)) || + (memcmp(packet_ptr -> nx_packet_prepend_ptr, test_data, packet_ptr -> nx_packet_length) != 0)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Set the flag. */ + test_client_stop = 1; + nx_tcp_socket_disconnect(&test_client, NX_IP_PERIODIC_RATE); + + nx_tcp_client_socket_unbind(&test_client); + nx_tcp_socket_delete(&test_client); +} + +void thread_proxy_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&proxy_ip, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&proxy_ip, &agent_server, "Agent Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + status += nx_tcp_socket_create(&proxy_ip, &agent_client, "Agent Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Suspend the thread to make client connection timeout. */ + tx_thread_suspend(&proxy_thread); + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&proxy_ip, HTTP_PROXY_PORT, &agent_server, 5, NX_NULL); + if(status) + error_counter++; + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&agent_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive CONNECT request. */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + { + error_counter++; + return; + } + + /* Check the received CONNECT request. */ + if (memcmp(packet_ptr -> nx_packet_prepend_ptr, connect_req, sizeof(connect_req)) != 0) + error_counter++; + + /* Set the TCP receive function. */ + client_ip.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + + /* Send error response to test client and with FIN set. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_length = 0; + nx_packet_data_append(packet_ptr, connect_403, sizeof(connect_403), &proxy_pool, NX_IP_PERIODIC_RATE); + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Disconnet. */ + nx_tcp_socket_disconnect(&agent_server, NX_NO_WAIT); + nx_tcp_server_socket_unaccept(&agent_server); + nx_tcp_server_socket_relisten(&proxy_ip, HTTP_PROXY_PORT, &agent_server); + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&agent_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive CONNECT request. */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + { + error_counter++; + return; + } + + /* Check the received CONNECT request. */ + if (memcmp(packet_ptr -> nx_packet_prepend_ptr, connect_req, sizeof(connect_req)) != 0) + error_counter++; + + /* Connect to the test server. */ + status = nx_tcp_client_socket_bind(&agent_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + status += nxd_tcp_client_socket_connect(&agent_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send response to test client. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_length = 0; + nx_packet_data_append(packet_ptr, connect_200, sizeof(connect_200), &proxy_pool, NX_IP_PERIODIC_RATE); + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Tunneling... */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_receive(&agent_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnet. */ + nx_tcp_socket_disconnect(&agent_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&agent_server); + nx_tcp_server_socket_relisten(&proxy_ip, HTTP_PROXY_PORT, &agent_server); + nx_tcp_socket_disconnect(&agent_client, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&agent_client); + + nx_tcp_socket_delete(&agent_server); + nx_tcp_socket_delete(&agent_client); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Data Fin Test.................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_create(&server_ip, &test_server, "Test Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + status = nx_tcp_server_socket_listen(&server_ip, TEST_SERVER_PORT, &test_server, 5, NX_NULL); + if(status) + error_counter++; + + /* Set the flag. */ + test_server_start = 1; + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&test_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive client data. */ + status = nx_tcp_socket_receive(&test_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Echo data. */ + status = nx_tcp_socket_send(&test_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + while(!test_client_stop) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + test_server_start = 0; + test_client_stop = 0; + + nx_tcp_socket_disconnect(&test_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&test_server); + nx_tcp_server_socket_relisten(&server_ip, TEST_SERVER_PORT, &test_server); + + nx_tcp_server_socket_unlisten(&server_ip, TEST_SERVER_PORT); + nx_tcp_socket_delete(&test_server); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; +ULONG *source_ip, *dest_ip; + + /* Set the tcp header pointer. */ + tcp_header_ptr = (NX_TCP_HEADER *) packet_ptr ->nx_packet_prepend_ptr; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Set FIN bit. */ + tcp_header_ptr -> nx_tcp_header_word_3 = tcp_header_ptr -> nx_tcp_header_word_3 | NX_TCP_FIN_BIT; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Clear the checksum field. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + /* Calculate the checksum . */ + dest_ip = &test_client.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &test_client.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + /* Clear the callback function. */ + client_ip.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_data_fin_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Data Fin Test..................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_http_proxy_disconnect_test.c b/test/regression/netxduo_test/netx_http_proxy_disconnect_test.c new file mode 100644 index 00000000..c6fefa9f --- /dev/null +++ b/test/regression/netxduo_test/netx_http_proxy_disconnect_test.c @@ -0,0 +1,531 @@ +/* This case tests TCP disconnect before HTTP Proxy connected. */ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_ENABLE_HTTP_PROXY) && !defined(NX_DISABLE_EXTENDED_NOTIFY_SUPPORT) && defined(__PRODUCT_NETXDUO__) +#include "nx_http_proxy_client.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 +#define TOTAL_SIZE DEMO_STACK_SIZE + (PACKET_SIZE * 8) + 2048 + 1024 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_TCP_SOCKET test_client; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET test_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +static UINT test_server_start = 0; +static UINT test_client_stop = 0; + +/* Set up the HTTP proxy server global variables */ +static TX_THREAD proxy_thread; +static NX_PACKET_POOL proxy_pool; +static NX_IP proxy_ip; +static NX_TCP_SOCKET agent_server, agent_client; + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static void thread_proxy_entry(ULONG thread_input); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define HTTP_PROXY_ADDRESS IP_ADDRESS(1,2,3,6) +#define HTTP_PROXY_PORT 8888 +#define TEST_SERVER_PORT 8080 + +static UCHAR connect_200[] = +{ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x43, 0x6f, 0x6e, /* HTTP/1.0 200 Con */ +0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, /* nection establis */ +0x68, 0x65, 0x64, 0x0d, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, /* hed..Proxy-agent */ +0x3a, 0x20, 0x74, 0x69, 0x6e, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x31, 0x2e, 0x38, 0x2e, /* : tinyproxy/1.8. */ +0x34, 0x0d, 0x0a, 0x0d, 0x0a, /* 4.... */ +}; + +static UCHAR connect_req[] = +{ +0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x3a, /* CONNECT 1.2.3.4: */ +0x38, 0x30, 0x38, 0x30, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, /* 8080 HTTP/1.1..H */ +0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x0d, 0x0a, 0x50, 0x72, /* ost: 1.2.3.4..Pr */ +0x6f, 0x78, 0x79, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, /* oxy-authorizatio */ +0x6e, 0x3a, 0x20, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, 0x64, 0x58, 0x4e, 0x6c, 0x63, 0x6a, 0x70, /* n: Basic dXNlcjp */ +0x77, 0x59, 0x58, 0x4e, 0x7a, 0x64, 0x32, 0x39, 0x79, 0x5a, 0x41, 0x3d, 0x3d, 0x0d, 0x0a, 0x0d, /* wYXNzd29yZA==... */ +0x0a +}; + +static UCHAR test_data[] = "HTTP Proxy Basic Test!"; + +#define TEST_LOOP 2 + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_disconnect_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + /* Create the HTTP Proxy thread. */ + status = tx_thread_create(&proxy_thread, "HTTP Proxy", thread_proxy_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&proxy_pool, "HTTP Proxy Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&proxy_ip, "HTTP Proxy IP", HTTP_PROXY_ADDRESS, + 0xFFFFFF00UL, &proxy_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&proxy_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&proxy_ip); + if (status) + error_counter++; +} + +static UINT connected = NX_FALSE; +static UINT disconnected = NX_FALSE; +static void test_establish_notify(NX_TCP_SOCKET *socekt_ptr) +{ + connected = NX_TRUE; +} + +static void test_disconnect_callback(NX_TCP_SOCKET *socekt_ptr) +{ + disconnected = NX_TRUE; +} + +void thread_client_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS proxy_server_address; +NXD_ADDRESS server_ip_address; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + proxy_server_address.nxd_ip_version = NX_IP_VERSION_V4; + proxy_server_address.nxd_ip_address.v4 = HTTP_PROXY_ADDRESS; + nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", sizeof("user") - 1, "password", sizeof("password") - 1); + + status = nx_tcp_socket_create(&client_ip, &test_client, "Test Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, test_disconnect_callback); + if(status) + error_counter++; + + nx_tcp_socket_establish_notify(&test_client, test_establish_notify); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&test_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + for ( i = 0; i < TEST_LOOP; i++) + { + + /* Wait test server started. */ + while(!test_server_start) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + connected = NX_FALSE; + disconnected = NX_FALSE; + + if (i % 2 == 0) + { + + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_NO_WAIT); + if(status != NX_IN_PROGRESS) + error_counter++; + + status = nx_tcp_socket_state_wait(&test_client, NX_TCP_ESTABLISHED, NX_IP_PERIODIC_RATE); + } + else + { + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + } + + /* Server disconnected. */ + if (!status || (connected == NX_TRUE) || (disconnected == NX_TRUE)) + { + error_counter++; + test_client_stop = 1; + return; + } + + if (i % 2 == 0) + { + + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_NO_WAIT); + if(status != NX_IN_PROGRESS) + error_counter++; + + status = nx_tcp_socket_state_wait(&test_client, NX_TCP_ESTABLISHED, NX_IP_PERIODIC_RATE); + } + else + { + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + } + + if (status || (connected != NX_TRUE)) + { + error_counter++; + test_client_stop = 1; + return; + } + + /* Send data. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_packet_data_append(packet_ptr, test_data, sizeof(test_data) - 1, &client_pool, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_tcp_socket_send(&test_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive the echo data from server. */ + status = nx_tcp_socket_receive(&test_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + + /* Check the received data. */ + if ((packet_ptr -> nx_packet_length != (sizeof(test_data) - 1)) || + (memcmp(packet_ptr -> nx_packet_prepend_ptr, test_data, packet_ptr -> nx_packet_length) != 0)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Set the flag. */ + test_client_stop = 1; + nx_tcp_socket_disconnect(&test_client, NX_IP_PERIODIC_RATE); + } + + nx_tcp_client_socket_unbind(&test_client); + nx_tcp_socket_delete(&test_client); +} + +void thread_proxy_entry(ULONG thread_input) +{ +UINT i, status; +ULONG actual_status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&proxy_ip, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&proxy_ip, &agent_server, "Agent Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + status += nx_tcp_socket_create(&proxy_ip, &agent_client, "Agent Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&proxy_ip, HTTP_PROXY_PORT, &agent_server, 5, NX_NULL); + if(status) + error_counter++; + + for (i = 0; i < TEST_LOOP; i++) + { + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&agent_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Disconnet. */ + nx_tcp_socket_disconnect(&agent_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&agent_server); + nx_tcp_server_socket_relisten(&proxy_ip, HTTP_PROXY_PORT, &agent_server); + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&agent_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive CONNECT request. */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + { + error_counter++; + return; + } + + /* Check the received CONNECT request. */ + if (memcmp(packet_ptr -> nx_packet_prepend_ptr, connect_req, sizeof(connect_req)) != 0) + error_counter++; + + /* Connect to the test server. */ + status = nx_tcp_client_socket_bind(&agent_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + status += nxd_tcp_client_socket_connect(&agent_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send response to test client. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_length = 0; + nx_packet_data_append(packet_ptr, connect_200, sizeof(connect_200), &proxy_pool, NX_IP_PERIODIC_RATE); + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Tunneling... */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_receive(&agent_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnet. */ + nx_tcp_socket_disconnect(&agent_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&agent_server); + nx_tcp_server_socket_relisten(&proxy_ip, HTTP_PROXY_PORT, &agent_server); + nx_tcp_socket_disconnect(&agent_client, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&agent_client); + } + + nx_tcp_socket_delete(&agent_server); + nx_tcp_socket_delete(&agent_client); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Disconnect Test................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_create(&server_ip, &test_server, "Test Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + status = nx_tcp_server_socket_listen(&server_ip, TEST_SERVER_PORT, &test_server, 5, NX_NULL); + if(status) + error_counter++; + + for (i = 0; i < TEST_LOOP; i++) + { + + /* Set the flag. */ + test_server_start = 1; + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&test_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive client data. */ + status = nx_tcp_socket_receive(&test_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Echo data. */ + status = nx_tcp_socket_send(&test_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + while(!test_client_stop) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + test_server_start = 0; + test_client_stop = 0; + + nx_tcp_socket_disconnect(&test_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&test_server); + nx_tcp_server_socket_relisten(&server_ip, TEST_SERVER_PORT, &test_server); + } + nx_tcp_server_socket_unlisten(&server_ip, TEST_SERVER_PORT); + nx_tcp_socket_delete(&test_server); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_disconnect_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Disconnect Test................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_http_proxy_error_response_test.c b/test/regression/netxduo_test/netx_http_proxy_error_response_test.c new file mode 100644 index 00000000..991a84ae --- /dev/null +++ b/test/regression/netxduo_test/netx_http_proxy_error_response_test.c @@ -0,0 +1,545 @@ +/* This case tests HTTP Proxy error response. */ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_ENABLE_HTTP_PROXY) && !defined(NX_DISABLE_EXTENDED_NOTIFY_SUPPORT) && defined(__PRODUCT_NETXDUO__) +#include "nx_http_proxy_client.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 +#define TOTAL_SIZE DEMO_STACK_SIZE + (PACKET_SIZE * 8) + 2048 + 1024 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_TCP_SOCKET test_client; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET test_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +static UINT test_server_start = 0; +static UINT test_client_stop = 0; + +/* Set up the HTTP proxy server global variables */ +static TX_THREAD proxy_thread; +static NX_PACKET_POOL proxy_pool; +static NX_IP proxy_ip; +static NX_TCP_SOCKET agent_server, agent_client; + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static void thread_proxy_entry(ULONG thread_input); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define HTTP_PROXY_ADDRESS IP_ADDRESS(1,2,3,6) +#define HTTP_PROXY_PORT 8888 +#define TEST_SERVER_PORT 8080 + +static UCHAR connect_200[] = +{ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x43, 0x6f, 0x6e, /* HTTP/1.0 200 Con */ +0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, /* nection establis */ +0x68, 0x65, 0x64, 0x0d, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, /* hed..Proxy-agent */ +0x3a, 0x20, 0x74, 0x69, 0x6e, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x31, 0x2e, 0x38, 0x2e, /* : tinyproxy/1.8. */ +0x34, 0x0d, 0x0a, 0x0d, 0x0a, /* 4.... */ +}; + +static UCHAR connect_req[] = +{ +0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x3a, /* CONNECT 1.2.3.4: */ +0x38, 0x30, 0x38, 0x30, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, /* 8080 HTTP/1.1..H */ +0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x0d, 0x0a, 0x50, 0x72, /* ost: 1.2.3.4..Pr */ +0x6f, 0x78, 0x79, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, /* oxy-authorizatio */ +0x6e, 0x3a, 0x20, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, 0x64, 0x58, 0x4e, 0x6c, 0x63, 0x6a, 0x70, /* n: Basic dXNlcjp */ +0x77, 0x59, 0x58, 0x4e, 0x7a, 0x64, 0x32, 0x39, 0x79, 0x5a, 0x41, 0x3d, 0x3d, 0x0d, 0x0a, 0x0d, /* wYXNzd29yZA==... */ +0x0a +}; + +static UCHAR connect_403[] = +{ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x33, 0x20, 0x41, 0x63, 0x63, /* HTTP/1.0 403 Acc */ +0x65, 0x73, 0x73, 0x20, 0x76, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0d, 0x0a, 0x53, /* ess violation..S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x74, 0x69, 0x6e, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, /* erver: tinyproxy */ +0x2f, 0x31, 0x2e, 0x38, 0x2e, 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, /* /1.8.4..Content- */ +0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, /* Type: text/html. */ +0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, /* .Connection: clo */ +0x73, 0x65, 0x0d, 0x0a, 0x0d, 0x0a, /* se.... */ +}; + +static UCHAR test_data[] = "HTTP Proxy Basic Test!"; + +#define TEST_LOOP 2 + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_error_response_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + /* Create the HTTP Proxy thread. */ + status = tx_thread_create(&proxy_thread, "HTTP Proxy", thread_proxy_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&proxy_pool, "HTTP Proxy Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&proxy_ip, "HTTP Proxy IP", HTTP_PROXY_ADDRESS, + 0xFFFFFF00UL, &proxy_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&proxy_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&proxy_ip); + if (status) + error_counter++; +} + +static UINT connected = NX_FALSE; +static void test_establish_notify(NX_TCP_SOCKET *socekt_ptr) +{ + connected = NX_TRUE; +} + +void thread_client_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS proxy_server_address; +NXD_ADDRESS server_ip_address; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + proxy_server_address.nxd_ip_version = NX_IP_VERSION_V4; + proxy_server_address.nxd_ip_address.v4 = HTTP_PROXY_ADDRESS; + nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", sizeof("user") - 1, "password", sizeof("password") - 1); + + status = nx_tcp_socket_create(&client_ip, &test_client, "Test Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + nx_tcp_socket_establish_notify(&test_client, test_establish_notify); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&test_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + for ( i = 0; i < TEST_LOOP; i++) + { + + /* Wait test server started. */ + while(!test_server_start) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + connected = NX_FALSE; + + if (i % 2 == 0) + { + + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_NO_WAIT); + if(status != NX_IN_PROGRESS) + error_counter++; + + status = nx_tcp_socket_state_wait(&test_client, NX_TCP_ESTABLISHED, NX_IP_PERIODIC_RATE); + } + else + { + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + } + + /* Received error response. */ + if (!status || (connected == NX_TRUE)) + { + error_counter++; + test_client_stop = 1; + return; + } + + if (i % 2 == 0) + { + + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_NO_WAIT); + if(status != NX_IN_PROGRESS) + error_counter++; + + status = nx_tcp_socket_state_wait(&test_client, NX_TCP_ESTABLISHED, NX_IP_PERIODIC_RATE); + } + else + { + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + } + + if (status || (connected != NX_TRUE)) + { + error_counter++; + test_client_stop = 1; + return; + } + + /* Send data. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_packet_data_append(packet_ptr, test_data, sizeof(test_data) - 1, &client_pool, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_tcp_socket_send(&test_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive the echo data from server. */ + status = nx_tcp_socket_receive(&test_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + + /* Check the received data. */ + if ((packet_ptr -> nx_packet_length != (sizeof(test_data) - 1)) || + (memcmp(packet_ptr -> nx_packet_prepend_ptr, test_data, packet_ptr -> nx_packet_length) != 0)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Set the flag. */ + test_client_stop = 1; + nx_tcp_socket_disconnect(&test_client, NX_IP_PERIODIC_RATE); + } + + nx_tcp_client_socket_unbind(&test_client); + nx_tcp_socket_delete(&test_client); +} + +void thread_proxy_entry(ULONG thread_input) +{ +UINT i, status; +ULONG actual_status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&proxy_ip, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&proxy_ip, &agent_server, "Agent Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + status += nx_tcp_socket_create(&proxy_ip, &agent_client, "Agent Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&proxy_ip, HTTP_PROXY_PORT, &agent_server, 5, NX_NULL); + if(status) + error_counter++; + + for (i = 0; i < TEST_LOOP; i++) + { + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&agent_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive CONNECT request. */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send error response to test client. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_length = 0; + nx_packet_data_append(packet_ptr, connect_403, sizeof(connect_403), &proxy_pool, NX_IP_PERIODIC_RATE); + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Disconnet. */ + nx_tcp_socket_disconnect(&agent_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&agent_server); + nx_tcp_server_socket_relisten(&proxy_ip, HTTP_PROXY_PORT, &agent_server); + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&agent_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive CONNECT request. */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Check the received CONNECT request. */ + if (memcmp(packet_ptr -> nx_packet_prepend_ptr, connect_req, sizeof(connect_req)) != 0) + error_counter++; + + /* Connect to the test server. */ + status = nx_tcp_client_socket_bind(&agent_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + status += nxd_tcp_client_socket_connect(&agent_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send response to test client. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_length = 0; + nx_packet_data_append(packet_ptr, connect_200, sizeof(connect_200), &proxy_pool, NX_IP_PERIODIC_RATE); + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Tunneling... */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_receive(&agent_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnet. */ + nx_tcp_socket_disconnect(&agent_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&agent_server); + nx_tcp_server_socket_relisten(&proxy_ip, HTTP_PROXY_PORT, &agent_server); + nx_tcp_socket_disconnect(&agent_client, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&agent_client); + } + + nx_tcp_socket_delete(&agent_server); + nx_tcp_socket_delete(&agent_client); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Error Response Test............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_create(&server_ip, &test_server, "Test Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + status = nx_tcp_server_socket_listen(&server_ip, TEST_SERVER_PORT, &test_server, 5, NX_NULL); + if(status) + error_counter++; + + for (i = 0; i < TEST_LOOP; i++) + { + + /* Set the flag. */ + test_server_start = 1; + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&test_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive client data. */ + status = nx_tcp_socket_receive(&test_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Echo data. */ + status = nx_tcp_socket_send(&test_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + while(!test_client_stop) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + test_server_start = 0; + test_client_stop = 0; + + nx_tcp_socket_disconnect(&test_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&test_server); + nx_tcp_server_socket_relisten(&server_ip, TEST_SERVER_PORT, &test_server); + } + nx_tcp_server_socket_unlisten(&server_ip, TEST_SERVER_PORT); + nx_tcp_socket_delete(&test_server); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_error_response_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Error Response Test............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_http_proxy_multiple_response_test.c b/test/regression/netxduo_test/netx_http_proxy_multiple_response_test.c new file mode 100644 index 00000000..6113afb3 --- /dev/null +++ b/test/regression/netxduo_test/netx_http_proxy_multiple_response_test.c @@ -0,0 +1,504 @@ +/* This case tests HTTP Proxy response in multiple packets. */ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_ENABLE_HTTP_PROXY) && !defined(NX_DISABLE_EXTENDED_NOTIFY_SUPPORT) && defined(__PRODUCT_NETXDUO__) +#include "nx_http_proxy_client.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 +#define TOTAL_SIZE DEMO_STACK_SIZE + (PACKET_SIZE * 8) + 2048 + 1024 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_TCP_SOCKET test_client; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET test_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +static UINT test_server_start = 0; +static UINT test_client_stop = 0; + +/* Set up the HTTP proxy server global variables */ +static TX_THREAD proxy_thread; +static NX_PACKET_POOL proxy_pool; +static NX_IP proxy_ip; +static NX_TCP_SOCKET agent_server, agent_client; + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static void thread_proxy_entry(ULONG thread_input); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define HTTP_PROXY_ADDRESS IP_ADDRESS(1,2,3,6) +#define HTTP_PROXY_PORT 8888 +#define TEST_SERVER_PORT 8080 + +static UCHAR connect_200[] = +{ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x43, 0x6f, 0x6e, +0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, +0x68, 0x65, 0x64, 0x0d, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, +0x3a, 0x20, 0x74, 0x69, 0x6e, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x31, 0x2e, 0x38, 0x2e, +0x34, 0x0d, 0x0a, 0x0d, 0x0a, +}; + +static UCHAR connect_req[] = +{ +0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x3a, /* CONNECT 1.2.3.4: */ +0x38, 0x30, 0x38, 0x30, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, /* 8080 HTTP/1.1..H */ +0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x0d, 0x0a, 0x50, 0x72, /* ost: 1.2.3.4..Pr */ +0x6f, 0x78, 0x79, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, /* oxy-authorizatio */ +0x6e, 0x3a, 0x20, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, 0x64, 0x58, 0x4e, 0x6c, 0x63, 0x6a, 0x70, /* n: Basic dXNlcjp */ +0x77, 0x59, 0x58, 0x4e, 0x7a, 0x64, 0x32, 0x39, 0x79, 0x5a, 0x41, 0x3d, 0x3d, 0x0d, 0x0a, 0x0d, /* wYXNzd29yZA==... */ +0x0a +}; + +static UCHAR test_data[] = "HTTP Proxy Basic Test!"; + +#define TEST_LOOP 4 + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_multiple_response_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + /* Create the HTTP Proxy thread. */ + status = tx_thread_create(&proxy_thread, "HTTP Proxy", thread_proxy_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&proxy_pool, "HTTP Proxy Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&proxy_ip, "HTTP Proxy IP", HTTP_PROXY_ADDRESS, + 0xFFFFFF00UL, &proxy_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&proxy_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&proxy_ip); + if (status) + error_counter++; +} + +static UINT connected = NX_FALSE; +static void test_establish_notify(NX_TCP_SOCKET *socekt_ptr) +{ + connected = NX_TRUE; +} + +void thread_client_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS proxy_server_address; +NXD_ADDRESS server_ip_address; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + proxy_server_address.nxd_ip_version = NX_IP_VERSION_V4; + proxy_server_address.nxd_ip_address.v4 = HTTP_PROXY_ADDRESS; + nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", sizeof("user") - 1, "password", sizeof("password") - 1); + + status = nx_tcp_socket_create(&client_ip, &test_client, "Test Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + nx_tcp_socket_establish_notify(&test_client, test_establish_notify); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&test_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + for ( i = 0 ; i < TEST_LOOP; i++) + { + + /* Wait test server started. */ + while(!test_server_start) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + connected = NX_FALSE; + if (i % 2 == 0) + { + + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_NO_WAIT); + if(status != NX_IN_PROGRESS) + error_counter++; + + status = nx_tcp_socket_state_wait(&test_client, NX_TCP_ESTABLISHED, NX_IP_PERIODIC_RATE); + } + else + { + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + } + + if (status || (connected != NX_TRUE)) + { + error_counter++; + test_client_stop = 1; + return; + } + + /* Send data. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_packet_data_append(packet_ptr, test_data, sizeof(test_data) - 1, &client_pool, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_tcp_socket_send(&test_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive the echo data from server. */ + status = nx_tcp_socket_receive(&test_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + + /* Check the received data. */ + if ((packet_ptr -> nx_packet_length != (sizeof(test_data) - 1)) || + (memcmp(packet_ptr -> nx_packet_prepend_ptr, test_data, packet_ptr -> nx_packet_length) != 0)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Set the flag. */ + test_client_stop = 1; + nx_tcp_socket_disconnect(&test_client, NX_IP_PERIODIC_RATE); + } + + nx_tcp_client_socket_unbind(&test_client); + nx_tcp_socket_delete(&test_client); +} + +void thread_proxy_entry(ULONG thread_input) +{ +UINT i, status; +ULONG actual_status; +NX_PACKET *packet_ptr, *packet_ptr_1, *packet_ptr_2; +NXD_ADDRESS server_ip_address; + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&proxy_ip, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&proxy_ip, &agent_server, "Agent Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + status += nx_tcp_socket_create(&proxy_ip, &agent_client, "Agent Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&proxy_ip, HTTP_PROXY_PORT, &agent_server, 5, NX_NULL); + if(status) + error_counter++; + + for (i = 0; i < TEST_LOOP; i++) + { + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&agent_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive CONNECT request. */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Check the received CONNECT request. */ + if (memcmp(packet_ptr -> nx_packet_prepend_ptr, connect_req, sizeof(connect_req)) != 0) + error_counter++; + + /* Connect to the test server. */ + status = nx_tcp_client_socket_bind(&agent_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + status += nxd_tcp_client_socket_connect(&agent_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send response to test client. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_length = 0; + nx_packet_data_append(packet_ptr, connect_200, 5, &proxy_pool, NX_IP_PERIODIC_RATE); + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_packet_allocate(&client_pool, &packet_ptr_1, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + nx_packet_data_append(packet_ptr_1, connect_200 + 5, 15, &proxy_pool, NX_IP_PERIODIC_RATE); + status = nx_tcp_socket_send(&agent_server, packet_ptr_1, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_packet_allocate(&client_pool, &packet_ptr_2, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + nx_packet_data_append(packet_ptr_2, connect_200 + 20, sizeof(connect_200) - 20, &proxy_pool, NX_IP_PERIODIC_RATE); + status = nx_tcp_socket_send(&agent_server, packet_ptr_2, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Tunneling... */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_receive(&agent_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnet. */ + nx_tcp_socket_disconnect(&agent_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&agent_server); + nx_tcp_server_socket_relisten(&proxy_ip, HTTP_PROXY_PORT, &agent_server); + nx_tcp_socket_disconnect(&agent_client, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&agent_client); + } + + nx_tcp_socket_delete(&agent_server); + nx_tcp_socket_delete(&agent_client); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Multiple Response Test........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_create(&server_ip, &test_server, "Test Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + status = nx_tcp_server_socket_listen(&server_ip, TEST_SERVER_PORT, &test_server, 5, NX_NULL); + if(status) + error_counter++; + + for (i = 0; i < TEST_LOOP; i++) + { + + /* Set the flag. */ + test_server_start = 1; + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&test_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive client data. */ + status = nx_tcp_socket_receive(&test_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Echo data. */ + status = nx_tcp_socket_send(&test_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + while(!test_client_stop) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + test_server_start = 0; + test_client_stop = 0; + + nx_tcp_socket_disconnect(&test_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&test_server); + nx_tcp_server_socket_relisten(&server_ip, TEST_SERVER_PORT, &test_server); + } + nx_tcp_server_socket_unlisten(&server_ip, TEST_SERVER_PORT); + nx_tcp_socket_delete(&test_server); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_multiple_response_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Multiple Response Test.........................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_http_proxy_non_block_test.c b/test/regression/netxduo_test/netx_http_proxy_non_block_test.c new file mode 100644 index 00000000..0b27f3a5 --- /dev/null +++ b/test/regression/netxduo_test/netx_http_proxy_non_block_test.c @@ -0,0 +1,479 @@ +/* This case tests HTTP Proxy non-blocking connection. */ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_ENABLE_HTTP_PROXY) && !defined(NX_DISABLE_EXTENDED_NOTIFY_SUPPORT) && defined(__PRODUCT_NETXDUO__) +#include "nx_http_proxy_client.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 +#define TOTAL_SIZE DEMO_STACK_SIZE + (PACKET_SIZE * 8) + 2048 + 1024 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_TCP_SOCKET test_client; +static NX_IP client_ip; +static UINT error_counter; + +static NX_TCP_SOCKET test_server; +static NX_PACKET_POOL server_pool; +static TX_THREAD server_thread; +static NX_IP server_ip; +static UINT test_server_start = 0; +static UINT test_client_stop = 0; + +/* Set up the HTTP proxy server global variables */ +static TX_THREAD proxy_thread; +static NX_PACKET_POOL proxy_pool; +static NX_IP proxy_ip; +static NX_TCP_SOCKET agent_server, agent_client; + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static void thread_proxy_entry(ULONG thread_input); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define HTTP_PROXY_ADDRESS IP_ADDRESS(1,2,3,6) +#define HTTP_PROXY_PORT 8888 +#define TEST_SERVER_PORT 8080 + +static UCHAR connect_200[] = +{ +0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x43, 0x6f, 0x6e, +0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x73, 0x74, 0x61, 0x62, 0x6c, 0x69, 0x73, +0x68, 0x65, 0x64, 0x0d, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74, +0x3a, 0x20, 0x74, 0x69, 0x6e, 0x79, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2f, 0x31, 0x2e, 0x38, 0x2e, +0x34, 0x0d, 0x0a, 0x0d, 0x0a, +}; + +static UCHAR connect_req[] = +{ +0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x3a, /* CONNECT 1.2.3.4: */ +0x38, 0x30, 0x38, 0x30, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x48, /* 8080 HTTP/1.1..H */ +0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x0d, 0x0a, 0x50, 0x72, /* ost: 1.2.3.4..Pr */ +0x6f, 0x78, 0x79, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, /* oxy-authorizatio */ +0x6e, 0x3a, 0x20, 0x42, 0x61, 0x73, 0x69, 0x63, 0x20, 0x64, 0x58, 0x4e, 0x6c, 0x63, 0x6a, 0x70, /* n: Basic dXNlcjp */ +0x77, 0x59, 0x58, 0x4e, 0x7a, 0x64, 0x32, 0x39, 0x79, 0x5a, 0x41, 0x3d, 0x3d, 0x0d, 0x0a, 0x0d, /* wYXNzd29yZA==... */ +0x0a +}; + +static UCHAR test_data[] = "HTTP Proxy Basic Test!"; + +#define TEST_LOOP 3 + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_non_block_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + if (status) + error_counter++; + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + if (status) + error_counter++; + + /* Create the HTTP Proxy thread. */ + status = tx_thread_create(&proxy_thread, "HTTP Proxy", thread_proxy_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + if (status) + error_counter++; + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&proxy_pool, "HTTP Proxy Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&proxy_ip, "HTTP Proxy IP", HTTP_PROXY_ADDRESS, + 0xFFFFFF00UL, &proxy_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + status = nx_arp_enable(&proxy_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&proxy_ip); + if (status) + error_counter++; +} + +static UINT connected = NX_FALSE; +static void test_establish_notify(NX_TCP_SOCKET *socekt_ptr) +{ + connected = NX_TRUE; +} + +void thread_client_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS proxy_server_address; +NXD_ADDRESS server_ip_address; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + proxy_server_address.nxd_ip_version = NX_IP_VERSION_V4; + proxy_server_address.nxd_ip_address.v4 = HTTP_PROXY_ADDRESS; + nx_http_proxy_client_enable(&client_ip, &proxy_server_address, HTTP_PROXY_PORT, "user", sizeof("user") - 1, "password", sizeof("password") - 1); + + status = nx_tcp_socket_create(&client_ip, &test_client, "Test Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + nx_tcp_socket_establish_notify(&test_client, test_establish_notify); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&test_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + for ( i = 0 ; i < TEST_LOOP; i++) + { + + /* Wait test server started. */ + while(!test_server_start) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + status = nxd_tcp_client_socket_connect(&test_client, &server_ip_address, TEST_SERVER_PORT, NX_NO_WAIT); + if(status != NX_IN_PROGRESS) + error_counter++; + + status = nx_tcp_socket_state_wait(&test_client, NX_TCP_ESTABLISHED, NX_IP_PERIODIC_RATE); + + if (status || (connected != NX_TRUE)) + { + error_counter++; + test_client_stop = 1; + return; + } + + /* Send data. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_packet_data_append(packet_ptr, test_data, sizeof(test_data) - 1, &client_pool, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_tcp_socket_send(&test_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive the echo data from server. */ + status = nx_tcp_socket_receive(&test_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + { + + /* Check the received data. */ + if ((packet_ptr -> nx_packet_length != (sizeof(test_data) - 1)) || + (memcmp(packet_ptr -> nx_packet_prepend_ptr, test_data, packet_ptr -> nx_packet_length) != 0)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Set the flag. */ + test_client_stop = 1; + nx_tcp_socket_disconnect(&test_client, NX_IP_PERIODIC_RATE); + } + + nx_tcp_client_socket_unbind(&test_client); + nx_tcp_socket_delete(&test_client); +} + +void thread_proxy_entry(ULONG thread_input) +{ +UINT i, status; +ULONG actual_status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&proxy_ip, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&proxy_ip, &agent_server, "Agent Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + status += nx_tcp_socket_create(&proxy_ip, &agent_client, "Agent Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&proxy_ip, HTTP_PROXY_PORT, &agent_server, 5, NX_NULL); + if(status) + error_counter++; + + for (i = 0; i < TEST_LOOP; i++) + { + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&agent_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive CONNECT request. */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Check the received CONNECT request. */ + if (memcmp(packet_ptr -> nx_packet_prepend_ptr, connect_req, sizeof(connect_req)) != 0) + error_counter++; + + /* Connect to the test server. */ + status = nx_tcp_client_socket_bind(&agent_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + status += nxd_tcp_client_socket_connect(&agent_client, &server_ip_address, TEST_SERVER_PORT, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send response to test client. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_length = 0; + nx_packet_data_append(packet_ptr, connect_200, sizeof(connect_200), &proxy_pool, NX_IP_PERIODIC_RATE); + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Tunneling... */ + status = nx_tcp_socket_receive(&agent_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_client, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_receive(&agent_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + status = nx_tcp_socket_send(&agent_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnet. */ + nx_tcp_socket_disconnect(&agent_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&agent_server); + nx_tcp_server_socket_relisten(&proxy_ip, HTTP_PROXY_PORT, &agent_server); + nx_tcp_socket_disconnect(&agent_client, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&agent_client); + } + + nx_tcp_socket_delete(&agent_server); + nx_tcp_socket_delete(&agent_client); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Non Block Test................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_create(&server_ip, &test_server, "Test Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + + status = nx_tcp_server_socket_listen(&server_ip, TEST_SERVER_PORT, &test_server, 5, NX_NULL); + if(status) + error_counter++; + + for (i = 0; i < TEST_LOOP; i++) + { + + /* Set the flag. */ + test_server_start = 1; + + /* Accept a connection from test client. */ + status = nx_tcp_server_socket_accept(&test_server, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Receive client data. */ + status = nx_tcp_socket_receive(&test_server, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Echo data. */ + status = nx_tcp_socket_send(&test_server, packet_ptr, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Wait client test finished. */ + while(!test_client_stop) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + test_server_start = 0; + test_client_stop = 0; + + nx_tcp_socket_disconnect(&test_server, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&test_server); + nx_tcp_server_socket_relisten(&server_ip, TEST_SERVER_PORT, &test_server); + } + nx_tcp_server_socket_unlisten(&server_ip, TEST_SERVER_PORT); + nx_tcp_socket_delete(&test_server); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_http_proxy_non_block_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: HTTP Proxy Non Block Test.................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_icmp_branch_test.c b/test/regression/netxduo_test/netx_icmp_branch_test.c new file mode 100644 index 00000000..f1ec06b3 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_branch_test.c @@ -0,0 +1,242 @@ +/* This NetX test concentrates on the code coverage for ICMP functions, + * _nx_icmp_packet_receive.c + * _nx_icmp_cleanup.c + */ + +#include "nx_icmp.h" +#include "nx_api.h" +#include "tx_thread.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID suspend_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_branch_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable UDP processing for IP instance. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for IP instance. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Enable ICMP processing for IP instance. */ + status = nx_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +#ifndef NX_ENABLE_ICMP_ADDRESS_CHECK +ULONG system_state; +#endif /* NX_ENABLE_ICMP_ADDRESS_CHECK */ +#if !defined(NX_ENABLE_ICMP_ADDRESS_CHECK) || defined(__PRODUCT_NETXDUO__) +NX_PACKET *my_packet[2]; +#endif /* !defined(NX_ENABLE_ICMP_ADDRESS_CHECK) || defined(__PRODUCT_NETXDUO__) */ +#ifdef __PRODUCT_NETXDUO__ +NX_IPV4_HEADER *ip_header_ptr; +#endif /* __PRODUCT_NETXDUO__ */ + + /* Print out some test information banners. */ + printf("NetX Test: ICMP Branch Test.........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + +#ifndef NX_ENABLE_ICMP_ADDRESS_CHECK + /* Hit condition of if ((_tx_thread_system_state) || (&(ip_ptr -> nx_ip_thread) != _tx_thread_current_ptr)) in _nx_icmp_packet_receive(). */ + tx_mutex_get(&(ip_0.nx_ip_protection), TX_WAIT_FOREVER); + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + nx_packet_data_append(my_packet[0], "abcdefghijklmnopqrstuvwxyz", 26, &pool_0, NX_NO_WAIT); + + system_state = _tx_thread_system_state; + _tx_thread_system_state = 0; + + _nx_icmp_packet_receive(&ip_0, my_packet[0]); + ip_0.nx_ip_icmp_queue_head = NX_NULL; + + _tx_thread_system_state = system_state; + nx_packet_release(my_packet[0]); + + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + nx_packet_data_append(my_packet[0], "abcdefghijklmnopqrstuvwxyz", 26, &pool_0, NX_NO_WAIT); + system_state = _tx_thread_system_state; + _tx_thread_system_state = 1; + + _nx_icmp_packet_receive(&ip_0, my_packet[0]); + ip_0.nx_ip_icmp_queue_head = NX_NULL; + + _tx_thread_system_state = system_state; + nx_packet_release(my_packet[0]); + tx_mutex_put(&(ip_0.nx_ip_protection)); +#endif /* NX_ENABLE_ICMP_ADDRESS_CHECK */ + + + /* Test _nx_icmp_cleanup(). */ + /* tx_thread_suspend_control_block is set to NULL. */ + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + _nx_icmp_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* tx_thread_suspend_control_block is set to IP but tx_thread_suspend_cleanup is set to NULL. */ + tx_thread_identify() -> tx_thread_suspend_control_block = &ip_0; + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + _nx_icmp_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* tx_thread_suspend_control_block is set to IP and tx_thread_suspend_cleanup is set to suspend_cleanup, but clear the IP ID. */ + tx_thread_identify() -> tx_thread_suspend_control_block = &ip_0; + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + ip_0.nx_ip_id = 0; + _nx_icmp_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + ip_0.nx_ip_id = NX_IP_ID; + + +#ifdef __PRODUCT_NETXDUO__ + /* Test _nx_icmpv4_send_error_message(). */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_ip_header = my_packet[0] -> nx_packet_prepend_ptr; + ip_header_ptr = (NX_IPV4_HEADER *)(my_packet[0] -> nx_packet_prepend_ptr); + ip_header_ptr -> nx_ip_header_destination_ip = IP_ADDRESS(224, 0, 0, 1); + _nx_icmpv4_send_error_message(&ip_0, my_packet[0], 0, 0); + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &(ip_0.nx_ip_interface[0]); + ip_header_ptr -> nx_ip_header_word_1 = NX_IP_OFFSET_MASK; + ip_header_ptr -> nx_ip_header_destination_ip = IP_ADDRESS(2, 2, 3, 0); + _nx_icmpv4_send_error_message(&ip_0, my_packet[0], 0, 0); + ip_header_ptr -> nx_ip_header_word_1 = 0; + ip_header_ptr -> nx_ip_header_destination_ip = IP_ADDRESS(1, 2, 3, 6); + ip_header_ptr -> nx_ip_header_source_ip = IP_ADDRESS(0, 0, 0, 0); + _nx_icmpv4_send_error_message(&ip_0, my_packet[0], 0, 0); + ip_header_ptr -> nx_ip_header_source_ip = IP_ADDRESS(0, 0, 0, 0); + _nx_icmpv4_send_error_message(&ip_0, my_packet[0], 0, 0); + ip_header_ptr -> nx_ip_header_source_ip = NX_IP_LOOPBACK_LAST; + _nx_icmpv4_send_error_message(&ip_0, my_packet[0], 0, 0); + ip_header_ptr -> nx_ip_header_source_ip = NX_IP_LIMITED_BROADCAST; + _nx_icmpv4_send_error_message(&ip_0, my_packet[0], 0, 0); + nx_packet_release(my_packet[0]); +#endif /* __PRODUCT_NETXDUO__ */ + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static VOID suspend_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER) +{ +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_branch_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Branch Test..........................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_icmp_broadcast_ping_test.c b/test/regression/netxduo_test/netx_icmp_broadcast_ping_test.c new file mode 100644 index 00000000..b2845e8f --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_broadcast_ping_test.c @@ -0,0 +1,230 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_broadcast_ping_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Broadcast Ping Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an subnet-directed broadcast. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 255), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + +#ifdef NX_ENABLE_ICMP_ADDRESS_CHECK + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#else + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Ping an limited broadcast. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(255, 255, 255, 255), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + +#ifdef NX_ENABLE_ICMP_ADDRESS_CHECK + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#else + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Enable IGMP feature. */ + status = nx_igmp_enable(&ip_0); + status += nx_igmp_enable(&ip_1); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Join in multicast group. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224, 0, 0, 251)); + status += nx_igmp_multicast_join(&ip_1, IP_ADDRESS(224, 0, 0, 251)); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an multicast. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(224, 0, 0, 251), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + +#ifdef NX_ENABLE_ICMP_ADDRESS_CHECK + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#else + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_broadcast_ping_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Broadcast Ping Test..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_cleanup_test.c b/test/regression/netxduo_test/netx_icmp_cleanup_test.c new file mode 100644 index 00000000..31a66e72 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_cleanup_test.c @@ -0,0 +1,422 @@ +/* This NetX test concentrates on the ICMP Clean up operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" +#ifdef FEATURE_NX_IPV6 +#include "nx_icmpv6.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static TX_THREAD ntest_2; +static TX_THREAD ntest_3; +#ifdef FEATURE_NX_IPV6 +static TX_THREAD ntest_4; +#endif +static TX_THREAD ntest_5; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_2_entry(ULONG thread_input); +static void ntest_3_entry(ULONG thread_input); +#ifdef FEATURE_NX_IPV6 +static void ntest_4_entry(ULONG thread_input); +#endif +static void ntest_5_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_cleanup_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; +#ifdef FEATURE_NX_IPV6 +NXD_ADDRESS global_address; +#endif + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_2, "thread 2", ntest_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_3, "thread 3", ntest_3_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + +#ifdef FEATURE_NX_IPV6 + /* Create the main thread. */ + tx_thread_create(&ntest_4, "thread 4", ntest_4_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; +#endif + + /* Create the main thread. */ + tx_thread_create(&ntest_5, "thread 5", ntest_5_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for IP instances. */ + status = nx_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address.nxd_ip_version = NX_IP_VERSION_V6; + global_address.nxd_ip_address.v6[0] = 0x20010000; + global_address.nxd_ip_address.v6[1] = 0x00000000; + global_address.nxd_ip_address.v6[2] = 0x00000000; + global_address.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; +#endif + + /* Resume the test thread. */ + tx_thread_resume(&ntest_0); +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Cleanup Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif + + tx_thread_resume(&ntest_1); + tx_thread_resume(&ntest_2); + tx_thread_resume(&ntest_3); +#ifdef FEATURE_NX_IPV6 + tx_thread_resume(&ntest_4); +#endif + tx_thread_resume(&ntest_5); + + /* Check the ICMP ping suspended count. */ + if (ip_0.nx_ip_icmp_ping_suspended_count != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an unknown IP address. This will timeout after 1 second. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 7), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Check the ICMP ping suspended count. */ + if (ip_0.nx_ip_icmp_ping_suspended_count != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an unknown IP address. This will timeout after 5 seconds. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 7), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_WAIT_ABORTED) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the ICMP ping suspended count. */ + if (ip_0.nx_ip_icmp_ping_suspended_count != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the test threads. */ + +static void ntest_2_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Check the ICMP ping suspended count. */ + if (ip_0.nx_ip_icmp_ping_suspended_count != 2) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an unknown IP address. This will timeout after 4 seconds. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 7), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 4 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the ICMP ping suspended count. */ + if (ip_0.nx_ip_icmp_ping_suspended_count != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Abort thread 1. */ + tx_thread_wait_abort(&ntest_1); +} + +/* Define the test threads. */ + +static void ntest_3_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Check the ICMP ping suspended count. */ + if (ip_0.nx_ip_icmp_ping_suspended_count != 3) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an unknown IP address. This will timeout after 3 seconds. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 7), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 3 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the ICMP ping suspended count. */ + if (ip_0.nx_ip_icmp_ping_suspended_count != 2) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + +#ifdef FEATURE_NX_IPV6 +/* Define the test threads. */ + +static void ntest_4_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +NXD_ADDRESS dest_address; + + /* Check the ICMP ping suspended count. */ + if (ip_0.nx_ip_icmp_ping_suspended_count != 4) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set destination address. */ + dest_address.nxd_ip_version = NX_IP_VERSION_V6; + dest_address.nxd_ip_address.v6[0] = 0x20010000; + dest_address.nxd_ip_address.v6[1] = 0x00000000; + dest_address.nxd_ip_address.v6[2] = 0x00000000; + dest_address.nxd_ip_address.v6[3] = 0x10000002; + + /* Ping an unknown IP address. This will timeout after 2 seconds. */ + status = nxd_icmp_ping(&ip_0, &dest_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the ICMP ping suspended count. */ + if (ip_0.nx_ip_icmp_ping_suspended_count != 3) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} +#endif + +/* Define the test threads. */ + +static void ntest_5_entry(ULONG thread_input) +{ + +#ifdef FEATURE_NX_IPV6 + /* Check the ICMP ping suspended count. */ + if (ip_0.nx_ip_icmp_ping_suspended_count != 5) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#else + /* Check the ICMP ping suspended count. */ + if (ip_0.nx_ip_icmp_ping_suspended_count != 4) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_cleanup_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Cleanup Test.........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_icmp_interface2_ping6_test.c b/test/regression/netxduo_test/netx_icmp_interface2_ping6_test.c new file mode 100644 index 00000000..e47d0d9e --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_interface2_ping6_test.c @@ -0,0 +1,623 @@ +/* This NetX test concentrates on the ICMP ping6 operation use second interface. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES > 1) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_nd_cache.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +static NXD_ADDRESS ipv6_address_3; +static NXD_ADDRESS ipv6_address_4; +static NXD_ADDRESS ipv6_address_5; +static NXD_ADDRESS ip0_lla_1; +static NXD_ADDRESS ip0_lla_2; +static NXD_ADDRESS ip1_lla_1; +static NXD_ADDRESS ip1_lla_2; +#ifndef NX_DISABLE_LOOPBACK_INTERFACE +static NXD_ADDRESS loopback_addr; +#endif /* NX_DISABLE_LOOPBACK_INTERFACE */ +#ifdef NX_DISABLE_FRAGMENTATION +static char long_msg[700] = ""; +#endif + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +#if !defined(NX_DISABLE_IPV6_DAD) || defined(NX_DISABLE_FRAGMENTATION) +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +#endif +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT check_checksum(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +#if (NX_IPV6_NEIGHBOR_CACHE_SIZE==8) && defined(NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES) +static UINT packet_process_filter(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +#endif + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_interface2_ping6_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface. */ + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + status += nx_ip_interface_attach(&ip_1, "Second Interface", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, _nx_ram_network_driver_512); + if (status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + ipv6_address_5.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_5.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_5.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_5.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_5.nxd_ip_address.v6[3] = 0x10000005; + + ip0_lla_1.nxd_ip_version = NX_IP_VERSION_V6; + ip0_lla_1.nxd_ip_address.v6[0] = 0xfe800000; + ip0_lla_1.nxd_ip_address.v6[1] = 0x0; + ip0_lla_1.nxd_ip_address.v6[2] = 0x0; + ip0_lla_1.nxd_ip_address.v6[3] = 0x1; + + ip0_lla_2.nxd_ip_version = NX_IP_VERSION_V6; + ip0_lla_2.nxd_ip_address.v6[0] = 0xfe800000; + ip0_lla_2.nxd_ip_address.v6[1] = 0x0; + ip0_lla_2.nxd_ip_address.v6[2] = 0x0; + ip0_lla_2.nxd_ip_address.v6[3] = 0x2; + + ip1_lla_1.nxd_ip_version = NX_IP_VERSION_V6; + ip1_lla_1.nxd_ip_address.v6[0] = 0xfe800000; + ip1_lla_1.nxd_ip_address.v6[1] = 0x1; + ip1_lla_1.nxd_ip_address.v6[2] = 0x0; + ip1_lla_1.nxd_ip_address.v6[3] = 0x1; + + ip1_lla_2.nxd_ip_version = NX_IP_VERSION_V6; + ip1_lla_2.nxd_ip_address.v6[0] = 0xfe800000; + ip1_lla_2.nxd_ip_address.v6[1] = 0x1; + ip1_lla_2.nxd_ip_address.v6[2] = 0x0; + ip1_lla_2.nxd_ip_address.v6[3] = 0x2; + +#ifndef NX_DISABLE_LOOPBACK_INTERFACE + loopback_addr.nxd_ip_version = NX_IP_VERSION_V6; + loopback_addr.nxd_ip_address.v6[0] = 0x0; + loopback_addr.nxd_ip_address.v6[1] = 0x0; + loopback_addr.nxd_ip_address.v6[2] = 0x0; + loopback_addr.nxd_ip_address.v6[3] = 0x1; +#endif /* NX_DISABLE_LOOPBACK_INTERFACE */ + + /* Check ipv6 address set status. */ + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ICMP processing for both IP instances. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +#if !defined(NX_DISABLE_IPV6_DAD) || defined(NX_DISABLE_FRAGMENTATION) +TX_INTERRUPT_SAVE_AREA +#endif +UINT status = 0; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; +NX_IPV6_HEADER *ipv6_header; +UINT addr_index_1; +UINT addr_index_2; +ULONG return_value; + + /* Print out test information banner. */ + printf("NetX Test: ICMP Interface2 Ping6 Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_LOOPBACK_INTERFACE + /* Now ping loopback address. */ + status = nxd_icmp_ping(&ip_0, &loopback_addr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); +#endif /* NX_DISABLE_LOOPBACK_INTERFACE */ + + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Configure mapping needed and test again. */ + nx_ip_interface_address_mapping_configure(&ip_0, 0, NX_FALSE); + nx_ip_interface_address_mapping_configure(&ip_1, 0, NX_FALSE); + + /* Now ping local address. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Now ping an IP address that does exist. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + nx_ip_interface_address_mapping_configure(&ip_0, 0, NX_TRUE); + nx_ip_interface_address_mapping_configure(&ip_1, 0, NX_TRUE); + + /* Delete the global addresses and assign link local addresses. */ + status = nxd_ipv6_address_delete(&ip_0, 0); + status += nxd_ipv6_address_delete(&ip_1, 0); + if(status) + error_counter++; + + /* Set interfaces' address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + if(status) + error_counter++; + + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_5, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now setup address 5. */ + status = nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_5, 64, NX_NULL); + if(status) + error_counter++; + + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Ping address 5. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_5, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Now ping local address. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Now ping peer's address. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Now ping an IP address that does exist. */ + /* The checksum of echo reply should not be 0xFFFF. */ + packet_process_callback = check_checksum; + status = nxd_icmp_ping(&ip_0, &ipv6_address_4, "zzzNzFzHbJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + packet_process_callback = NX_NULL; + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO +#ifndef NX_DISABLE_LOOPBACK_INTERFACE + if ((ping_timeouts != 1) || (pings_sent != 8) || (ping_responses_received != 7)) +#else + if ((ping_timeouts != 1) || (pings_sent != 7) || (ping_responses_received != 6)) +#endif /* NX_DISABLE_LOOPBACK_INTERFACE */ + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages) || error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Make sure the packet is received via the 2nd address on IP 0. */ + ipv6_header = (NX_IPV6_HEADER*)(my_packet -> nx_packet_ip_header); + + if(!CHECK_IPV6_ADDRESSES_SAME(ipv6_header -> nx_ip_header_destination_ip, ipv6_address_3.nxd_ip_address.v6)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + + + /* Set interfaces' address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &ip0_lla_1, 10, &addr_index_1); + status += nxd_ipv6_address_set(&ip_1, 0, &ip1_lla_1, 10, NX_NULL); + status += nxd_ipv6_address_set(&ip_0, 1, &ip0_lla_2, 10, &addr_index_2); + status += nxd_ipv6_address_set(&ip_1, 1, &ip1_lla_2, 10, NX_NULL); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_IPV6_DAD + /* Disable interrupts. */ + TX_DISABLE + + /* Hook link driver to check packets. */ + packet_process_callback = packet_process; + + /* Send ICMPv6 packet before address is valid. */ + nxd_icmp_interface_ping(&ip_0, &ip1_lla_2, addr_index_2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_NO_WAIT); + + packet_process_callback = NX_NULL; + + /* Restore previous interrupt posture. */ + TX_RESTORE + + /* Check whether ICMPv6 echo request is sent out. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Send a ping to ip1_lla_2, via ip0_lla_2.*/ + status = nxd_icmp_interface_ping(&ip_0, &ip1_lla_2, addr_index_2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, TX_TIMER_TICKS_PER_SECOND); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Verify that we receive the ping response via addr_3 */ + ipv6_header = (NX_IPV6_HEADER*)(my_packet -> nx_packet_ip_header); + if(!CHECK_IPV6_ADDRESSES_SAME(ipv6_header -> nx_ip_header_destination_ip, ip0_lla_2.nxd_ip_address.v6)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Set link status from up to down. */ + nx_ip_driver_interface_direct_command(&ip_0, NX_LINK_DISABLE, 0, &return_value); + nx_ip_driver_interface_direct_command(&ip_0, NX_LINK_DISABLE, 1, &return_value); + + /* Send a ping to ip1_lla_2.*/ + status = nxd_icmp_ping(&ip_0, &ip1_lla_2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, TX_TIMER_TICKS_PER_SECOND); + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set link status from down to up. */ + nx_ip_driver_interface_direct_command(&ip_0, NX_LINK_ENABLE, 0, &return_value); + nx_ip_driver_interface_direct_command(&ip_0, NX_LINK_ENABLE, 1, &return_value); + +#ifdef NX_DISABLE_FRAGMENTATION + + /* Disable interrupts. */ + TX_DISABLE + + /* Hook link driver to check packets. */ + packet_process_callback = packet_process; + + /* Send ICMPv6 packet larger than MTU. */ + nxd_icmp_interface_ping(&ip_0, &ip1_lla_2, addr_index_2, long_msg, 600, &my_packet, NX_NO_WAIT); + + packet_process_callback = NX_NULL; + + /* Restore previous interrupt posture. */ + TX_RESTORE + + /* Check whether ICMPv6 echo request is sent out. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_FRAGMENTATION */ + +#if 0 +#if (NX_IPV6_DESTINATION_TABLE_SIZE==8) + /* Seven destination tables are used. Ping needs two more destination tables. Ping should not success. */ + status = nxd_icmp_interface_ping(&ip_0, &ip1_lla_1, addr_index_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#if (NX_IPV6_NEIGHBOR_CACHE_SIZE==8) && defined(NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES) && (NX_IPV6_DESTINATION_TABLE_SIZE>8) + /* Seven nd caches are used. nd cache of ip0_lla_2 is poluted. Ping needs two more destination tables. Ping should not success. */ + packet_process_callback = packet_process_filter; + status = nxd_icmp_interface_ping(&ip_0, &ip1_lla_1, addr_index_2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif +#endif + + printf("SUCCESS!\n"); + test_control_return(0); + + +} + + +static UINT check_checksum(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_IPV6_HEADER *ip_header_ptr; +ULONG protocol; +NX_ICMPV6_HEADER *icmp_header_ptr; + + /* Ignore packet that is not ICMP. */ + if(packet_ptr -> nx_packet_length < (sizeof(NX_IPV6_HEADER) + sizeof(NX_ICMPV6_HEADER))) + return NX_TRUE; + + ip_header_ptr = (NX_IPV6_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + + /* Get IP header. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + protocol = (ip_header_ptr -> nx_ip_header_word_1 >> 8) & 0xFF; + if(protocol == NX_PROTOCOL_ICMPV6) + { + + /* Get ICMP header. */ + icmp_header_ptr = (NX_ICMPV6_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV6_HEADER)); + if((icmp_header_ptr -> nx_icmpv6_header_checksum) == 0xFFFF) + error_counter++; + } + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); +} + + +#if !defined(NX_DISABLE_IPV6_DAD) || defined(NX_DISABLE_FRAGMENTATION) +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + /* In this case, ICMPv6 echo request is sent out. */ + error_counter++; + return NX_TRUE; +} +#endif + +#if (NX_IPV6_NEIGHBOR_CACHE_SIZE==8) && defined(NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES) +static UINT packet_process_filter(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +UINT i; + + /* Continue process only when echo request is received. */ + if (packet_ptr -> nx_packet_length != 76) + return NX_TRUE; + + /* Modify ND CACHE for lla_0. */ + for (i = 0; i < NX_IPV6_NEIGHBOR_CACHE_SIZE; i++) + { + if (CHECK_IPV6_ADDRESSES_SAME(ip_0.nx_ipv6_nd_cache[i].nx_nd_cache_dest_ip, ip0_lla_2.nxd_ip_address.v6)) + { + ip_0.nx_ipv6_nd_cache[i].nx_nd_cache_dest_ip[3] = 9; + break; + } + } + + /* Modify destination table for lla_0. */ + for (i = 0; i < NX_IPV6_DESTINATION_TABLE_SIZE; i++) + { + + /* Skip invalid entries. */ + if (!ip_0.nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid) + continue; + + if(CHECK_IPV6_ADDRESSES_SAME(ip_0.nx_ipv6_destination_table[i].nx_ipv6_destination_entry_destination_address, ip0_lla_2.nxd_ip_address.v6)) + { + ip_0.nx_ipv6_destination_table[i].nx_ipv6_destination_entry_destination_address[3] = 9; + break; + } + } + + packet_process_callback = NX_NULL; + return NX_TRUE; +} +#endif + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_interface2_ping6_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Interface2 Ping6 Test................................N/A\n"); + + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmp_interface2_ping_test.c b/test/regression/netxduo_test/netx_icmp_interface2_ping_test.c new file mode 100644 index 00000000..0f1f2e3b --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_interface2_ping_test.c @@ -0,0 +1,206 @@ +/* This NetX test concentrates on the ICMP ping operation use second interface. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_interface2_ping_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface. */ + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + status += nx_ip_interface_attach(&ip_1, "Second Interface", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, _nx_ram_network_driver_512); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS ip_address; +#endif /* __PRODUCT_NETXDUO__ */ + + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Interface2 Ping Test................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 7), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Set the address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(2, 2, 3, 5); + + /* Now ping an IP address that does exist using unreachable interface. */ + status = nxd_icmp_source_ping(&ip_0, &ip_address, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status == NX_SUCCESS) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO +#ifdef __PRODUCT_NETXDUO__ + if ((ping_timeouts != 2) || (pings_sent != 3) || (ping_responses_received != 1)) +#else + if ((ping_timeouts != 1) || (pings_sent != 2) || (ping_responses_received != 1)) +#endif /* __PRODUCT_NETXDUO__ */ + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28 /* data only */) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_interface2_ping_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: ICMP Interface2 Ping Test.................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_invalid_echo_reply_test.c b/test/regression/netxduo_test/netx_icmp_invalid_echo_reply_test.c new file mode 100644 index 00000000..2776be08 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_invalid_echo_reply_test.c @@ -0,0 +1,159 @@ +/* This NetX test concentrates on processing an echo reply without sequence match. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_ICMP_INFO) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* ICMP packet. + * src: 1.2.3.5 + * dst: 1.2.3.4 */ +static char icmp_pkt[] = { +0x18, 0x03, 0x73, 0x29, 0x5f, 0x66, 0x20, 0x0b, /* ..s)_f . */ +0xc7, 0x94, 0x45, 0x96, 0x08, 0x00, 0x45, 0x00, /* ..E...E. */ +0x00, 0x3c, 0x2b, 0x25, 0x00, 0x00, 0xff, 0x01, /* .<+%.... */ +0x88, 0x8f, 0x01, 0x02, 0x03, 0x05, 0x01, 0x02, /* ........ */ +0x03, 0x04, 0x00, 0x00, 0x55, 0x5a, 0x00, 0x01, /* ....UZ.. */ +0x00, 0x01, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* ..abcdef */ +0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, /* ghijklmn */ +0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, /* opqrstuv */ +0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* wabcdefg */ +0x68, 0x69 /* hi */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_invalid_echo_reply_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing. */ + status = nx_icmp_enable(&ip_0); + + /* Check ICMP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Invalid Echo Reply Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Inject Echo Reply packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &icmp_pkt[14], sizeof(icmp_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(icmp_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the Echo Reply packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + if ((ip_0.nx_ip_ping_responses_received != 1) || + (ip_0.nx_ip_icmp_invalid_packets != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_invalid_echo_reply_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: ICMP Invalid Echo Reply Test..............................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_ICMP_INFO */ diff --git a/test/regression/netxduo_test/netx_icmp_invalid_source_test.c b/test/regression/netxduo_test/netx_icmp_invalid_source_test.c new file mode 100644 index 00000000..bf6abab2 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_invalid_source_test.c @@ -0,0 +1,160 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(NX_ENABLE_SOURCE_ADDRESS_CHECK) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_invalid_source_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192, 168, 0, 1), 0xFFFFFFFCUL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(192, 168, 0, 3), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Invalid Source Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping from IP_0 to IP_1. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(192, 168, 0, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if (status == NX_SUCCESS) + { + nx_packet_release(my_packet); + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping from IP_1 to IP_0. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(192, 168, 0, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if (status == NX_SUCCESS) + { + nx_packet_release(my_packet); + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_invalid_source_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: ICMP Invalid Source Test..................................N/A\n"); + test_control_return(3); +} +#endif /* NX_ENABLE_SOURCE_ADDRESS_CHECK */ diff --git a/test/regression/netxduo_test/netx_icmp_loopback_fail_test.c b/test/regression/netxduo_test/netx_icmp_loopback_fail_test.c new file mode 100644 index 00000000..6558b216 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_loopback_fail_test.c @@ -0,0 +1,158 @@ +/* This NetX test concentrates on the ICMP ping through loopback interface. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_LOOPBACK_INTERFACE) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_loopback_fail_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for IP_0. */ + status = nx_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *first_packet; +NX_PACKET *second_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Loopback Fail Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Make sure only two packets are available in the pool. */ + if (pool_0.nx_packet_pool_available != 2) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping IPv4 loopback address. */ + status = nx_icmp_ping(&ip_0, NX_IP_LOOPBACK_FIRST + 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &first_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (first_packet == NX_NULL) || (first_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Make sure only one packet is available in the pool since first_packet is not released. */ + /* Now ping IPv4 loopback address. */ + status = nx_icmp_ping(&ip_0, NX_IP_LOOPBACK_FIRST + 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &second_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_IP_INFO + if (ip_0.nx_ip_send_packets_dropped != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_IP_INFO */ + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_loopback_fail_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: ICMP Loopback Fail Test...................................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_LOOPBACK_INTERFACE */ diff --git a/test/regression/netxduo_test/netx_icmp_loopback_test.c b/test/regression/netxduo_test/netx_icmp_loopback_test.c new file mode 100644 index 00000000..8a9a770f --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_loopback_test.c @@ -0,0 +1,171 @@ +/* This NetX test concentrates on the ICMP ping through loopback interface. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_LOOPBACK_INTERFACE) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static NXD_ADDRESS address_lo; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_0; +#endif /* FEATURE_NX_IPV6 */ + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_loopback_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nxd_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status = nxd_ipv6_enable(&ip_0); + + /* Set global address. */ + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0x20010DB8; + address_0.nxd_ip_address.v6[1] = 0x00010001; + address_0.nxd_ip_address.v6[2] = 0x021122FF; + address_0.nxd_ip_address.v6[3] = 0xFE334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &address_0, 64, NX_NULL); + + /* Check for errors. */ + if (status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ + + /* Set loopback address. */ + address_lo.nxd_ip_version = NX_IP_VERSION_V4; + address_lo.nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Loopback Test........................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping IPv4 loopback address. */ + status = nxd_icmp_source_ping(&ip_0, &address_lo, NX_LOOPBACK_INTERFACE, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Wait for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Now ping IPv6 address through loopback interface. */ + status = nxd_icmp_source_ping(&ip_0, &address_0, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#endif + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_loopback_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: ICMP Loopback Test........................................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_LOOPBACK_INTERFACE */ diff --git a/test/regression/netxduo_test/netx_icmp_loopback_test2.c b/test/regression/netxduo_test/netx_icmp_loopback_test2.c new file mode 100644 index 00000000..93441e08 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_loopback_test2.c @@ -0,0 +1,178 @@ +/* This NetX test concentrates on the ICMP ping through all kinds of IPv4 loopback addresses. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_LOOPBACK_INTERFACE) && defined(__PRODUCT_NETXDUO__) && !defined(NX_ENABLE_ICMP_ADDRESS_CHECK) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_loopback_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for IP_0. */ + status = nx_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG addr; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Loopback Test 2......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test loopback address between 127.0.0.1 and 127.255.255.255. The step is a random value less than 0x1000. */ + for (addr = NX_IP_LOOPBACK_FIRST; addr <= NX_IP_LOOPBACK_LAST; addr += (NX_RAND() & 0xFFF) + 1) + { + + /* Now ping IPv4 loopback address. */ + status = nx_icmp_ping(&ip_0, addr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + + /* Now ping IPv4 interface address with address mapping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 4), "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + + /* Disable address mapping. */ + status = nx_ip_interface_address_mapping_configure(&ip_0, 0, NX_FALSE); + + /* Check error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping IPv4 interface address without address mapping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 4), "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_loopback_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: ICMP Loopback Test 2......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_multiple_ping6_test1.c b/test/regression/netxduo_test/netx_icmp_multiple_ping6_test1.c new file mode 100644 index 00000000..81c17300 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_multiple_ping6_test1.c @@ -0,0 +1,289 @@ +/* This NetX test concentrates on the ICMPv6 ping operation. */ +/* + thread 0 send ICMPv6 Echo Request to the existent IP address IP_ADDRESS(1, 2, 3, 5), + thread 1 send ICMPv6 Echo Request to the nonexistent IP address IP_ADDRESS(1, 2, 3, 7), + Delay the ICMPv6 Echo Reply in driver, let thread 0 receive the ICMPv6 Echo Reply after thread 1 send ICMPv6 Echo Request. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#ifdef FEATURE_NX_IPV6 + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; +static NXD_ADDRESS destination_address; +static UINT icmpv6_request_counter; +static UINT icmpv6_reply_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_multiple_ping6_test1_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + icmpv6_request_counter = 0; + icmpv6_reply_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Resume test thread. */ + tx_thread_resume(&ntest_0); +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Multiple Ping6 Test1................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + tx_thread_resume(&ntest_1); + + /* Let driver delay the echo reply for 1 second. */ + advanced_packet_process_callback = packet_process; + + /* Set ipv6 destination address. */ + destination_address.nxd_ip_version = NX_IP_VERSION_V6; + destination_address.nxd_ip_address.v6[0] = 0x20010000; + destination_address.nxd_ip_address.v6[1] = 0x00000000; + destination_address.nxd_ip_address.v6[2] = 0x00000000; + destination_address.nxd_ip_address.v6[3] = 0x10000002; + + /* Now ping an IP address that does exist. */ + /* The reply packet contains checksum 0. */ + status = nxd_icmp_ping(&ip_0, &destination_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 3 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status) || (my_packet -> nx_packet_length != 28) || + (memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let thread 1 run. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Check the error counter. */ + if ((error_counter) || (icmpv6_request_counter != 1) || (icmpv6_reply_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Set ipv6 destination address. */ + destination_address.nxd_ip_version = NX_IP_VERSION_V6; + destination_address.nxd_ip_address.v6[0] = 0x20010000; + destination_address.nxd_ip_address.v6[1] = 0x00000000; + destination_address.nxd_ip_address.v6[2] = 0x00000000; + destination_address.nxd_ip_address.v6[3] = 0x10000003; + + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nxd_icmp_ping(&ip_0, &destination_address, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if (status == NX_SUCCESS) + { + error_counter++; + } +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Packet length: 40(IPv6) + 8(ICMPv6) + 28(data). */ + if ((ip_ptr == &ip_0) && + (packet_ptr -> nx_packet_length == 76) && + (*(packet_ptr -> nx_packet_prepend_ptr + 40) == NX_ICMPV6_ECHO_REQUEST_TYPE)) + { + + /* Updated the icmpv6_request_counter. */ + icmpv6_request_counter ++; + } + + /* Packet length: 40(IPv6) + 8(ICMPv6) + 28(data). */ + if ((ip_ptr == &ip_1) && + (packet_ptr -> nx_packet_length == 76) && + (*(packet_ptr -> nx_packet_prepend_ptr + 40) == NX_ICMPV6_ECHO_REPLY_TYPE)) + { + + /* Updated the icmpv6_request_counter. */ + icmpv6_reply_counter ++; + + /* Delay the first ICMPv6 Echo Reply. */ + if (icmpv6_reply_counter == 1) + { + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + } + } + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_multiple_ping6_test1_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Multiple Ping6 Test1.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_multiple_ping6_test2.c b/test/regression/netxduo_test/netx_icmp_multiple_ping6_test2.c new file mode 100644 index 00000000..bc6b7703 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_multiple_ping6_test2.c @@ -0,0 +1,277 @@ +/* This NetX test concentrates on the ICMPv6 ping operation. */ +/* + thread 0 send ICMPv6 Echo Request to the existent IP address IP_ADDRESS(1, 2, 3, 5), + thread 1 send ICMPv6 Echo Request to the existent IP address IP_ADDRESS(1, 2, 3, 5), + Delay the first ICMPv6 Echo Reply in driver, let thread 1 first receive the ICMPv6 Echo Reply before thread 0 receive the ICMPv6 Echo Reply. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#ifdef FEATURE_NX_IPV6 + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; +static UINT icmpv6_request_counter; +static UINT icmpv6_reply_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_multiple_ping6_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + icmpv6_request_counter = 0; + icmpv6_reply_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Resume test thread. */ + tx_thread_resume(&ntest_0); +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Multiple Ping6 Test2................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + tx_thread_resume(&ntest_1); + + /* Let driver delay the echo reply for 1 second. */ + advanced_packet_process_callback = packet_process; + + /* Now ping an IP address that does exist. */ + /* The reply packet contains checksum 0. */ + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 3 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status) || (my_packet -> nx_packet_length != 28) || + (memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let thread 1 run. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Check the error counter. */ + if ((error_counter) || (icmpv6_request_counter != 2) || (icmpv6_reply_counter != 2)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Ping an exist IP address. */ + status = nxd_icmp_ping(&ip_0, &global_address_1, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status) || (my_packet -> nx_packet_length != 28) || + (memcmp(my_packet -> nx_packet_prepend_ptr, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28))) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Packet length: 40(IPv6) + 8(ICMPv6) + 28(data). */ + if ((ip_ptr == &ip_0) && + (packet_ptr -> nx_packet_length == 76) && + (*(packet_ptr -> nx_packet_prepend_ptr + 40) == NX_ICMPV6_ECHO_REQUEST_TYPE)) + { + + /* Updated the icmpv6_request_counter. */ + icmpv6_request_counter ++; + } + + /* Packet length: 40(IPv6) + 8(ICMPv6) + 28(data). */ + if ((ip_ptr == &ip_1) && + (packet_ptr -> nx_packet_length == 76) && + (*(packet_ptr -> nx_packet_prepend_ptr + 40) == NX_ICMPV6_ECHO_REPLY_TYPE)) + { + + /* Updated the icmpv6_request_counter. */ + icmpv6_reply_counter ++; + + /* Delay the first ICMPv6 Echo Reply. */ + if (icmpv6_reply_counter == 1) + { + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + } + } + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_multiple_ping6_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Multiple Ping6 Test2.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_multiple_ping_test1.c b/test/regression/netxduo_test/netx_icmp_multiple_ping_test1.c new file mode 100644 index 00000000..d89eebfa --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_multiple_ping_test1.c @@ -0,0 +1,244 @@ +/* This NetX test concentrates on the ICMP ping operation. */ +/* + thread 0 send ICMP Echo Request to the existent IP address IP_ADDRESS(1, 2, 3, 5), + thread 1 send ICMP Echo Request to the nonexistent IP address IP_ADDRESS(1, 2, 3, 7), + Delay the ICMP Echo Reply in driver, let thread 0 receive the ICMP Echo Reply after thread 1 send ICMP Echo Request. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static UINT icmp_request_counter; +static UINT icmp_reply_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_multiple_ping_test1_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + icmp_request_counter = 0; + icmp_reply_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Multiple Ping Test1.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver delay the echo reply for 1 second. */ + advanced_packet_process_callback = packet_process; + + /* Ping an IP address. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 3 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status) || (my_packet -> nx_packet_length != 28) || + (memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let thread 1 run. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Check the error counter. */ + if ((error_counter) || (icmp_request_counter != 1) || (icmp_reply_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 7), "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if (status == NX_SUCCESS) + { + error_counter++; + } +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Packet length: 20(IP) + 8(ICMP) + 28(data). */ + if ((ip_ptr == &ip_0) && + (packet_ptr -> nx_packet_length == 56) && + (*(packet_ptr -> nx_packet_prepend_ptr + 20) == NX_ICMP_ECHO_REQUEST_TYPE)) + { + + /* Updated the icmp_request_counter. */ + icmp_request_counter ++; + } + + /* Packet length: 20(IP) + 8(ICMP) + 28(data). */ + if ((ip_ptr == &ip_1) && + (packet_ptr -> nx_packet_length == 56) && + (*(packet_ptr -> nx_packet_prepend_ptr + 20) == NX_ICMP_ECHO_REPLY_TYPE)) + { + + /* Updated the icmp_request_counter. */ + icmp_reply_counter ++; + + /* Delay the first ICMP Echo Reply. */ + if (icmp_reply_counter == 1) + { + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + } + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_multiple_ping_test1_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Multiple Ping Test1..................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_icmp_multiple_ping_test2.c b/test/regression/netxduo_test/netx_icmp_multiple_ping_test2.c new file mode 100644 index 00000000..6e555b6c --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_multiple_ping_test2.c @@ -0,0 +1,244 @@ +/* This NetX test concentrates on the ICMP ping operation. */ +/* + thread 0 send ICMP Echo Request to the existent IP address IP_ADDRESS(1, 2, 3, 5), + thread 1 send ICMP Echo Request to the existent IP address IP_ADDRESS(1, 2, 3, 5), + Delay the first ICMP Echo Reply in driver, let thread 1 first receive the ICMP Echo Reply before thread 0 receive the ICMP Echo Reply. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static UINT icmp_request_counter; +static UINT icmp_reply_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_multiple_ping_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + icmp_request_counter = 0; + icmp_reply_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Multiple Ping Test2.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver delay the echo reply for 1 second. */ + advanced_packet_process_callback = packet_process; + + /* Ping an IP address. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 3 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status) || (my_packet -> nx_packet_length != 28) || + (memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the error counter. */ + if ((error_counter) || (icmp_request_counter != 2) || (icmp_reply_counter != 2)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status) || (my_packet -> nx_packet_length != 28) || + (memcmp(my_packet -> nx_packet_prepend_ptr, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28))) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Packet length: 20(IP) + 8(ICMP) + 28(data). */ + if ((ip_ptr == &ip_0) && + (packet_ptr -> nx_packet_length == 56) && + (*(packet_ptr -> nx_packet_prepend_ptr + 20) == NX_ICMP_ECHO_REQUEST_TYPE)) + { + + /* Updated the icmp_request_counter. */ + icmp_request_counter ++; + } + + /* Packet length: 20(IP) + 8(ICMP) + 28(data). */ + if ((ip_ptr == &ip_1) && + (packet_ptr -> nx_packet_length == 56) && + (*(packet_ptr -> nx_packet_prepend_ptr + 20) == NX_ICMP_ECHO_REPLY_TYPE)) + { + + /* Updated the icmp_request_counter. */ + icmp_reply_counter ++; + + /* Delay the first ICMP Echo Reply. */ + if (icmp_reply_counter == 1) + { + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + } + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_multiple_ping_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Multiple Ping Test2..................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_icmp_nxe_api_test.c b/test/regression/netxduo_test/netx_icmp_nxe_api_test.c new file mode 100644 index 00000000..7b61c340 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_nxe_api_test.c @@ -0,0 +1,670 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#ifdef FEATURE_NX_IPV6 +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#endif /* FEATURE_NX_IPV6 */ + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP invalid_ip; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef FEATURE_NX_IPV6 +static void icmpv6_ra_flag_callback(NX_IP *ip_ptr, UINT ra_flag); +#endif + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; +#ifdef FEATURE_NX_IPV6 +NXD_ADDRESS ipv6_address; +#endif + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Set ipv6 version and address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x10000001; + + /* Set interfaces' address */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 64, NX_NULL); + + /* Check for IP create errors. */ + if (status) + error_counter++; +#endif +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet = NX_NULL; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; +#ifdef FEATURE_NX_IPV6 +NXD_ADDRESS ip_address; +#endif + + /* Print out some test information banners. */ + printf("NetX Test: ICMP NXE API Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_icmp_enable api */ + /************************************************/ + + /* Enable the ICMP feature for NULL IP instance. */ + status = nx_icmp_enable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Enable the ICMP feature for invalid IP instance. */ + status = nx_icmp_enable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the ICMP feature for valid IP instance. */ + status = nx_icmp_enable(&ip_0); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the ICMP feature again for valid IP instance . */ + status = nx_icmp_enable(&ip_0); + + /* Check for error. */ + if (status != NX_ALREADY_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_icmp_info_get api */ + /************************************************/ + + /* Get the ICMP information for NULL IP instance. */ + status = nx_icmp_info_get(NX_NULL, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the ICMP information for invalid IP instance. */ + status = nx_icmp_info_get(&invalid_ip, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ICMP feature. */ + ip_0.nx_ip_icmp_packet_receive = NX_NULL; + + /* Get the ICMP information for invalid IP instance. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_icmp_ping api */ + /************************************************/ + + /* Send the ping information for NULL IP instance. */ + status = nx_icmp_ping(NX_NULL, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Send the ping information for invalid IP instance. */ + status = nx_icmp_ping(&invalid_ip, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the ping information for valid IP instance with NULL packet pointer. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, NX_NULL, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Send the ping information for valid IP instance with invalid address. */ + status = nx_icmp_ping(&ip_0, NX_NULL, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ICMP feature. */ + ip_0.nx_ip_icmp_packet_receive = NX_NULL; + + /* Send the ping information for valid IP instance with disable ICMP feature. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + + /************************************************/ + /* Tested the nxde_icmp_enable api */ + /************************************************/ + + /* Enable the ICMPv6 feature for NULL IP instance. */ + status = nxd_icmp_enable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Enable the ICMPv6 feature for invalid IP instance. */ + status = nxd_icmp_enable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxde_icmp_ping api */ + /************************************************/ + + /* Set the address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Send the ping information for NULL IP instance. */ + status = nxd_icmp_ping(NX_NULL, &ip_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Send the ping information for invalid IP instance. */ + status = nxd_icmp_ping(&invalid_ip, &ip_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the ping information for valid IP instance with NULL packet pointer. */ + status = nxd_icmp_ping(&ip_0, &ip_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, NX_NULL, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the ping information for valid IP instance with invalid address. */ + status = nxd_icmp_ping(&ip_0, NX_NULL, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the wrong address version. */ + ip_address.nxd_ip_version = 0x80; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Send the ping information for valid IP instance with invalid address. */ + status = nxd_icmp_ping(&ip_0, &ip_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the address . */ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Disable the ICMPv4 feature. */ + ip_0.nx_ip_icmpv4_packet_process = NX_NULL; + + /* Send the ping information, valid IP instance, valid address and disable ICMPv4 feature. */ + status = nxd_icmp_ping(&ip_0, &ip_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the address . */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x20010000; + ip_address.nxd_ip_address.v6[1] = 0x00000000; + ip_address.nxd_ip_address.v6[2] = 0x00000000; + ip_address.nxd_ip_address.v6[3] = 0x00000001; + + /* Disable the ICMPv6 feature. */ + ip_0.nx_ip_icmpv6_packet_process = NX_NULL; + + /* Send the ping information, valid IP instance, valid address and disable ICMPv6 feature. */ + status = nxd_icmp_ping(&ip_0, &ip_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ip_icmpv6_packet_process = _nx_icmpv6_packet_process; + + /* Disable the IPv6 feature. */ + ip_0.nx_ipv6_packet_receive = NX_NULL; + + /* Send the ping information, valid IP instance, valid address and disable ICMPv6 feature. */ + status = nxd_icmp_ping(&ip_0, &ip_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ipv6_packet_receive = _nx_ipv6_packet_receive; + + /************************************************/ + /* Tested the nxde_icmp_source_ping api */ + /************************************************/ + + /* Set the address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Send the ping information for NULL IP instance. */ + status = nxd_icmp_source_ping(NX_NULL, &ip_address, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Send the ping information for invalid IP instance. */ + status = nxd_icmp_source_ping(&invalid_ip, &ip_address, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the ping information for valid IP instance with NULL packet pointer. */ + status = nxd_icmp_source_ping(&ip_0, &ip_address, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, NX_NULL, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the ping information for valid IP instance with invalid address. */ + status = nxd_icmp_source_ping(&ip_0, NX_NULL, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the wrong address version. */ + ip_address.nxd_ip_version = 0x80; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Send the ping information for valid IP instance with invalid address. */ + status = nxd_icmp_source_ping(&ip_0, &ip_address, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the address . */ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Send the ping information, valid IP instance, valid address and valid interface index. */ + status = nxd_icmp_source_ping(&ip_0, &ip_address, NX_MAX_IP_INTERFACES, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the ICMPv4 feature. */ + ip_0.nx_ip_icmpv4_packet_process = NX_NULL; + + /* Send the ping information, valid IP instance, valid address and disable ICMPv4 feature. */ + status = nxd_icmp_source_ping(&ip_0, &ip_address, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the address . */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x20010000; + ip_address.nxd_ip_address.v6[1] = 0x00000000; + ip_address.nxd_ip_address.v6[2] = 0x00000000; + ip_address.nxd_ip_address.v6[3] = 0x00000001; + + /* Send the ping information, valid IP instance, valid address and invalid address index. */ + status = nxd_icmp_source_ping(&ip_0, &ip_address, NX_MAX_IPV6_ADDRESSES + NX_LOOPBACK_IPV6_ENABLED, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the ping information, valid IP instance, valid address and invalid address attached interface. */ + ip_0.nx_ipv6_address[0].nxd_ipv6_address_attached = NX_NULL; + status = nxd_icmp_source_ping(&ip_0, &ip_address, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ipv6_address[0].nxd_ipv6_address_attached = &ip_0.nx_ip_interface[0]; + + /* Send the ping information, valid IP instance, valid address and invalid address state. */ + ip_0.nx_ipv6_address[0].nxd_ipv6_address_valid = NX_FALSE; + status = nxd_icmp_source_ping(&ip_0, &ip_address, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ipv6_address[0].nxd_ipv6_address_valid = NX_TRUE; + + /* Disable the ICMPv6 feature. */ + ip_0.nx_ip_icmpv6_packet_process = NX_NULL; + + /* Send the ping information, valid IP instance, valid address and disable ICMPv6 feature. */ + status = nxd_icmp_source_ping(&ip_0, &ip_address, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ip_icmpv6_packet_process = _nx_icmpv6_packet_process; + + /* Disable the IPv6 feature. */ + ip_0.nx_ipv6_packet_receive = NX_NULL; + + /* Send the ping information, valid IP instance, valid address and disable ICMPv6 feature. */ + status = nxd_icmp_source_ping(&ip_0, &ip_address, 0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ipv6_packet_receive = _nx_ipv6_packet_receive; + + /***************************************************/ + /* Tested the nxde_icmpv6_ra_flag_callback_set api */ + /***************************************************/ + + /* Send the ra callback function for NULL IP instance. */ + status = nxd_icmpv6_ra_flag_callback_set(NX_NULL, icmpv6_ra_flag_callback); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the ra callback function for invalid IP instance. */ + status = nxd_icmpv6_ra_flag_callback_set(&invalid_ip, icmpv6_ra_flag_callback); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#ifdef FEATURE_NX_IPV6 +static void icmpv6_ra_flag_callback(NX_IP *ip_ptr, UINT ra_flag) +{ +} +#endif +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP NXE API Test.........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_packet_receive_function_test.c b/test/regression/netxduo_test/netx_icmp_packet_receive_function_test.c new file mode 100644 index 00000000..5eb7ca86 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_packet_receive_function_test.c @@ -0,0 +1,424 @@ +/* This NetX test case test _nx_icmp_packet_receive and _nx_icmp_queue_process function with non standard operation . */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ICMPV4_RX_CHECKSUM) && !defined(NX_ENABLE_ICMP_ADDRESS_CHECK) && !defined(NX_DISABLE_IPV4) +#include "nx_icmp.h" +#include "nx_ip.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UCHAR icmp_packet_received = NX_FALSE; +static NX_PACKET *copy_packet_0; +static NX_PACKET *copy_packet_1; +static NX_PACKET *copy_packet_2; +static NX_PACKET *copy_packet_3; +static NX_PACKET *copy_packet_4; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +static void packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_packet_receive_function_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += _nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + /* Print out test information banner. */ + printf("NetX Test: ICMP Packet Receive Function Test........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Point to new receive function */ + ip_1.nx_ip_icmp_packet_receive = packet_receive; + + /* Now ping an IP address that does exist. */ + /* The reply packet contains checksum 0. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information for IP instance0. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 1) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28 /* data only */) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages) || error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ICMP_INFO +#ifdef __PRODUCT_NETXDUO__ + + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + if ((copy_packet_2 -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_ICMPV4_RX_CHECKSUM) == 0) + { +#endif /* NX_DISABLE_ICMP_INFO */ + + /* Check the ICMP information for IP instance1. */ + if ((ip_1.nx_ip_icmp_total_messages_received != 5) || (ip_1.nx_ip_icmp_invalid_packets != 3) || (ip_1.nx_ip_pings_received != 1) || (ip_1.nx_ip_pings_responded_to != 1) || (ip_1.nx_ip_icmp_checksum_errors != 1) || (ip_1.nx_ip_icmp_unhandled_messages != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + } + else + { + + /* Check the ICMP information for IP instance1. */ + if ((ip_1.nx_ip_icmp_total_messages_received != 4) || (ip_1.nx_ip_icmp_invalid_packets != 2) || (ip_1.nx_ip_pings_received != 1) || (ip_1.nx_ip_pings_responded_to != 1) || (ip_1.nx_ip_icmp_checksum_errors != 0) || (ip_1.nx_ip_icmp_unhandled_messages != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + } +#endif /* NX_DISABLE_ICMP_INFO */ +#else + + /* Check the ICMP information for IP instance1. */ + if ((ip_1.nx_ip_icmp_total_messages_received != 4) || (ip_1.nx_ip_icmp_invalid_packets != 2) || (ip_1.nx_ip_pings_received != 1) || (ip_1.nx_ip_pings_responded_to != 1) || (ip_1.nx_ip_icmp_checksum_errors != 1) || (ip_1.nx_ip_icmp_unhandled_messages != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ +#endif /* NX_DISABLE_ICMP_INFO */ + + /* Determine if the test was successful. */ + if ((error_counter) || (icmp_packet_received != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status != NX_SUCCESS) + { + error_counter++; + } + + /* Wait for receive the ICMP packet. */ + while(icmp_packet_received == NX_FALSE) + { + tx_thread_sleep(1); + } + + /* Call _nx_icmp_packet_receive to directly receive the invalid packet. */ + _nx_icmp_packet_receive(&ip_1, copy_packet_0); + + /* Let IP thread to diretcly process the ICMP packet. */ + tx_thread_sleep(1); + +#ifdef __PRODUCT_NETXDUO__ + + /* Disable ICMP feature. */ + ip_1.nx_ip_icmpv4_packet_process = NX_NULL; + + /* Call _nx_icmp_packet_receive to directly receive the valid packet . */ + _nx_icmp_packet_receive(&ip_1, copy_packet_1); + + /* Let IP thread to diretcly process the ICMP packet. */ + tx_thread_sleep(1); + + /* Reenable ICMP feature. */ + ip_1.nx_ip_icmpv4_packet_process = _nx_icmpv4_packet_process; +#endif + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + if ((copy_packet_2 -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_ICMPV4_RX_CHECKSUM) == 0) + { +#endif + /* Call _nx_icmp_packet_receive to directly receive the packet with incorrect checksum, and queue the packet to the ICMP message queue. */ + _nx_icmp_packet_receive(&ip_1, copy_packet_2); +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + } +#endif + + /* Call _nx_icmp_packet_receive to receive the packet with incorrect code, and queue the packet to the ICMP message queue. */ + _nx_icmp_packet_receive(&ip_1, copy_packet_3); + + /* Call _nx_icmp_packet_receive to receive the valid packet, and queue the packet to the ICMP message queue. */ + _nx_icmp_packet_receive(&ip_1, copy_packet_4); +} + +static void packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +NX_ICMP_HEADER *header_ptr; +ULONG checksum; +ULONG old_m; +ULONG new_m; + + /* Store the ICMP ping packet. */ + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, ©_packet_0, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check for error. */ + if((status != NX_SUCCESS)) + { + error_counter++; + } + + /* Set the packet length with invalid value. */ + memcpy(copy_packet_0 -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ12", 28); + copy_packet_0 -> nx_packet_length = sizeof(NX_ICMP_HEADER) - 1; + copy_packet_0 -> nx_packet_append_ptr = copy_packet_0 -> nx_packet_prepend_ptr + copy_packet_0 -> nx_packet_length; + + /* Update the packet prepend and length to include the IP header. */ + packet_ptr -> nx_packet_prepend_ptr -= 20; + packet_ptr -> nx_packet_length += 20; + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_1, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet prepend and length. */ + copy_packet_1 -> nx_packet_prepend_ptr += 20; + copy_packet_1 -> nx_packet_length -= 20; + } + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_2, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet prepend and length. */ + copy_packet_2 -> nx_packet_prepend_ptr += 20; + copy_packet_2 -> nx_packet_length -= 20; + + /* Point to the ICMP message header. */ + header_ptr = (NX_ICMP_HEADER *) copy_packet_2 -> nx_packet_prepend_ptr; + + /* Set the incorrect checksum. */ + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_0); + header_ptr -> nx_icmp_header_word_0 -= 1; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_0); + } + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_3, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet prepend and length. */ + copy_packet_3 -> nx_packet_prepend_ptr += 20; + copy_packet_3 -> nx_packet_length -= 20; + + /* Point to the ICMP message header. */ + header_ptr = (NX_ICMP_HEADER *) copy_packet_3 -> nx_packet_prepend_ptr; + + /* Set the incorrect ICMP code. */ + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_0); + + /* Set the new ICMP code. */ + header_ptr -> nx_icmp_header_word_0 += 0x01000000; + + /* Get the old checksum (HC) in header. */ + checksum = header_ptr -> nx_icmp_header_word_0 & NX_LOWER_16_MASK; + + /* Get the new ICMP code in the header. */ + new_m = (header_ptr -> nx_icmp_header_word_0 & 0xFFFF0000) >> 16; + + /* Get the OLD ICMP code. */ + old_m = new_m - 0x0100; + + /* Update the checksum, get the new checksum(HC'), + The new_m is ULONG value, so need get the lower value after invert. */ + checksum = ((~checksum) & 0xFFFF) + ((~old_m) & 0xFFFF) + new_m; + + /* Fold a 4-byte value into a two byte value */ + checksum = (checksum >> 16) + (checksum & 0xFFFF); + + /* Do it again in case previous operation generates an overflow */ + checksum = (checksum >> 16) + (checksum & 0xFFFF); + + /* Now store the new checksum in the IP header. */ + header_ptr -> nx_icmp_header_word_0 = ((header_ptr -> nx_icmp_header_word_0 & 0xFFFF0000) | ((~checksum) & NX_LOWER_16_MASK)); + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_icmp_header_word_0); + } + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_4, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet prepend and length. */ + copy_packet_4 -> nx_packet_prepend_ptr += 20; + copy_packet_4 -> nx_packet_length -= 20; + } + + /* Release the ICMP ping packet. */ + nx_packet_release(packet_ptr); + + /* Update the flag. */ + icmp_packet_received = NX_TRUE; + + /* Stop the process. */ + return; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_packet_receive_function_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: ICMP Packet Receive Function Test.........................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_ping6_data_append_test.c b/test/regression/netxduo_test/netx_icmp_ping6_data_append_test.c new file mode 100644 index 00000000..27aec9bf --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_ping6_data_append_test.c @@ -0,0 +1,194 @@ +/* This NetX test concentrates on the ICMP Interface Ping6 data append operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_FRAGMENTATION) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; +static CHAR data[4096]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping6_data_append_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool, packet payload size is 256, packet counts is 10. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, ((sizeof(NX_PACKET) + 256) * 10)); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Ping6 Data Append Test..............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Initialize the data. */ + for (i = 0; i < 4096; i ++) + data[i] = 'A'; + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Ping an IP address that does exist. One packet size is 256, use 2 packets. */ + status = nxd_icmp_ping(&ip_0, &global_address_1, data, 400, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an IP address that does exist. One packet size is 256, use 20 packets, data append failure. */ + status = nxd_icmp_ping(&ip_0, &global_address_1, data, 4096, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_OVERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping6_data_append_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Ping6 Data Append Test...............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_ping6_fragment_test.c b/test/regression/netxduo_test/netx_icmp_ping6_fragment_test.c new file mode 100644 index 00000000..0e5a2ff8 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_ping6_fragment_test.c @@ -0,0 +1,225 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_FRAGMENTATION) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; + +/* Define the ping message. */ +static CHAR ping_message[259]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping6_fragment_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 10240); + pointer = pointer + 10240; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable fragment. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i, index; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Ping6 Fragment Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Random genearte the write data. */ + for (i = 0; i < sizeof(ping_message); i ++) + { + ping_message[i] = (UCHAR)rand(); + } + + /* Now ping an IP address that does exist. */ + /* The reply packet contains checksum 0. */ + status = nxd_icmp_ping(&ip_0, &global_address_1, ping_message, sizeof(ping_message), &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 1) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != sizeof(ping_message) /* data only */) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages) || error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Compute a simple hash based on the dest_ip */ + index = (UINT)((global_address_1.nxd_ip_address.v6[0] + global_address_1.nxd_ip_address.v6[1] + global_address_1.nxd_ip_address.v6[2] + global_address_1.nxd_ip_address.v6[3]) % (NX_IPV6_NEIGHBOR_CACHE_SIZE)); + + /* Check the queued packet for ND CACHE. */ + if (ip_0.nx_ipv6_nd_cache[index].nx_nd_cache_packet_waiting_head) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping6_fragment_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Ping6 Fragment Test..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_ping6_test.c b/test/regression/netxduo_test/netx_icmp_ping6_test.c new file mode 100644 index 00000000..4463d52f --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_ping6_test.c @@ -0,0 +1,509 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +extern void test_control_return(UINT status); +#ifdef FEATURE_NX_IPV6 + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; +static NXD_ADDRESS destination_address; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping6_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 again. */ + status = nxd_ipv6_enable(&ip_0); + + /* Check status. */ + if (status != NX_ALREADY_ENABLED) + error_counter++; + + /* Disable IPv6. */ + status = nxd_ipv6_disable(&ip_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Disable IPv6 again. */ + status = nxd_ipv6_disable(&ip_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Enable IPv6 again. */ + status = nxd_ipv6_enable(&ip_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(__PRODUCT_NETXDUO__) + /* Enable IP fragment for both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check IP fragment enable status. */ + if (status) + error_counter++; +#endif +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +NX_PACKET *packet_ptr[20]; +UINT i; +ULONG pings_sent; +ULONG pings_sent_expected = 0; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG ping_responses_received_expected = 0; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Ping6 Test..........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Loop to allocate the all packets. */ + for (i = 0; i < pool_0.nx_packet_pool_total; i++) + { + + /* Allocate the packets. */ + status = nx_packet_allocate(&pool_0, &packet_ptr[i], NX_ICMP_PACKET, 1); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Set ipv6 destination address. */ + destination_address.nxd_ip_version = NX_IP_VERSION_V6; + destination_address.nxd_ip_address.v6[0] = 0x20010000; + destination_address.nxd_ip_address.v6[1] = 0x00000000; + destination_address.nxd_ip_address.v6[2] = 0x00000000; + destination_address.nxd_ip_address.v6[3] = 0x10000002; + + /* Ping an IP address that does exist. */ + status = nxd_icmp_ping(&ip_0, &destination_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_NO_PACKET) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != pings_sent_expected) || (ping_responses_received != ping_responses_received_expected)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Loop to release the all packets. */ + for (i = 0; i < pool_0.nx_packet_pool_total; i++) + { + + /* Release the packets. */ + status = nx_packet_release(packet_ptr[i]); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Set ipv6 destination address. */ + destination_address.nxd_ip_version = NX_IP_VERSION_V6; + destination_address.nxd_ip_address.v6[0] = 0x20010000; + destination_address.nxd_ip_address.v6[1] = 0x00000000; + destination_address.nxd_ip_address.v6[2] = 0x00000000; + destination_address.nxd_ip_address.v6[3] = 0x10000002; + +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(__PRODUCT_NETXDUO__) + /* Ping an IP address with big data. */ + status = nxd_icmp_ping(&ip_0, &destination_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 257, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + pings_sent_expected++; + ping_responses_received_expected++; + nx_packet_release(my_packet); +#endif + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != pings_sent_expected) || (ping_responses_received != ping_responses_received_expected)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Set ipv6 destination address. */ + destination_address.nxd_ip_version = NX_IP_VERSION_V6; + destination_address.nxd_ip_address.v6[0] = 0x30010000; + destination_address.nxd_ip_address.v6[1] = 0x00000000; + destination_address.nxd_ip_address.v6[2] = 0x00000000; + destination_address.nxd_ip_address.v6[3] = 0x10000003; + + /* Ping an unreachable IP address (Different network) with no wait. */ + status = nxd_icmp_ping(&ip_0, &destination_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status . */ + if ((status != NX_NO_INTERFACE_ADDRESS) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != pings_sent_expected) || (ping_responses_received != ping_responses_received_expected)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Set ipv6 destination address. */ + destination_address.nxd_ip_version = NX_IP_VERSION_V6; + destination_address.nxd_ip_address.v6[0] = 0x20010000; + destination_address.nxd_ip_address.v6[1] = 0x00000000; + destination_address.nxd_ip_address.v6[2] = 0x00000000; + destination_address.nxd_ip_address.v6[3] = 0x10000003; + + /* Ping an unknown IP address with no wait. */ + status = nxd_icmp_ping(&ip_0, &destination_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_NO_WAIT); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + pings_sent_expected++; + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != pings_sent_expected) || (ping_responses_received != ping_responses_received_expected)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + + /* Set ipv6 destination address. */ + destination_address.nxd_ip_version = NX_IP_VERSION_V6; + destination_address.nxd_ip_address.v6[0] = 0x20010000; + destination_address.nxd_ip_address.v6[1] = 0x00000000; + destination_address.nxd_ip_address.v6[2] = 0x00000000; + destination_address.nxd_ip_address.v6[3] = 0x10000003; + + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nxd_icmp_ping(&ip_0, &destination_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + pings_sent_expected++; + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 1) || (pings_sent != pings_sent_expected) || (ping_responses_received != ping_responses_received_expected)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Set ipv6 destination address. */ + destination_address.nxd_ip_version = NX_IP_VERSION_V6; + destination_address.nxd_ip_address.v6[0] = 0x20010000; + destination_address.nxd_ip_address.v6[1] = 0x00000000; + destination_address.nxd_ip_address.v6[2] = 0x00000000; + destination_address.nxd_ip_address.v6[3] = 0x10000001; + + /* Now ping loopback address. */ + status = nxd_icmp_ping(&ip_0, &destination_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + pings_sent_expected++; + ping_responses_received_expected++; + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 1) || (pings_sent != pings_sent_expected) || (ping_responses_received != ping_responses_received_expected)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Release the packet. */ + nx_packet_release(my_packet); + + /* Set ipv6 destination address. */ + destination_address.nxd_ip_version = NX_IP_VERSION_V6; + destination_address.nxd_ip_address.v6[0] = 0x20010000; + destination_address.nxd_ip_address.v6[1] = 0x00000000; + destination_address.nxd_ip_address.v6[2] = 0x00000000; + destination_address.nxd_ip_address.v6[3] = 0x10000002; + + /* Now ping an IP address that does exist. */ + /* The reply packet contains checksum 0. */ + status = nxd_icmp_ping(&ip_0, &destination_address, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + pings_sent_expected++; + ping_responses_received_expected++; + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 1) || (pings_sent != pings_sent_expected) || (ping_responses_received != ping_responses_received_expected)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28 /* data only */) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages) || error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Invalidate all nd caches. */ + status = nxd_nd_cache_invalidate(&ip_0); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist again. */ + status = nxd_icmp_ping(&ip_0, &destination_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Invalidate all nd caches. */ + status = nxd_nd_cache_invalidate(&ip_0); + + /* Disable and enable IPv6. */ + status = nxd_ipv6_disable(&ip_0); + status += nxd_ipv6_enable(&ip_0); + + /* Set the IPv6 address. */ + status += nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist with icmp disabled. Skip error checking. */ + status = _nxd_icmp_ping(&ip_0, &destination_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping6_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Ping6 Test...........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_ping_fragment_test.c b/test/regression/netxduo_test/netx_icmp_ping_fragment_test.c new file mode 100644 index 00000000..9b34904d --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_ping_fragment_test.c @@ -0,0 +1,203 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR msg[256]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping_fragment_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: ICMP Ping Fragment Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now send ping with fragment disabled. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), msg, sizeof(msg), &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_NO_RESPONSE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable IP fragment for both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check IP fragment enable status. */ + if (status) + error_counter++; + + + /* Now send ping with fragment enabled. The fragment will be disabled while ARP is sent. */ + advanced_packet_process_callback = packet_process; + nx_arp_dynamic_entries_invalidate(&ip_0); + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), msg, sizeof(msg), &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_NO_RESPONSE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Enable IP fragment for both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check IP fragment enable status. */ + if (status) + error_counter++; + + + /* Now send ping with fragment enabled. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), msg, sizeof(msg), &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Disable fragment. */ + nx_ip_fragment_disable(&ip_0); + nx_ip_fragment_disable(&ip_1); + + advanced_packet_process_callback = NX_NULL; + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping_fragment_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: ICMP Ping Fragment Test...................................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_icmp_ping_multicast_test.c b/test/regression/netxduo_test/netx_icmp_ping_multicast_test.c new file mode 100644 index 00000000..75533d11 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_ping_multicast_test.c @@ -0,0 +1,188 @@ +/* This NetX test concentrates on the ICMP ping multicast operation. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_ENABLE_ICMP_ADDRESS_CHECK) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +#ifndef NX_DISABLE_FRAGMENTATION +static CHAR msg[300]; +#endif /* NX_DISABLE_FRAGMENTATION */ + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping_multicast_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 10240); + pointer = pointer + 10240; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: ICMP Ping Multicast Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Now send a ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 255), "Test", 4, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); + + +#ifndef NX_DISABLE_FRAGMENTATION + /* Now send a large ping with fragment disabled. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 255), msg, sizeof(msg), &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_NO_RESPONSE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Enable IP fragment for both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check IP fragment enable status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now send a large ping with fragment enabled. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 255), msg, sizeof(msg), &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet); +#endif /* NX_DISABLE_FRAGMENTATION */ + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping_multicast_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: ICMP Ping Fragment Test...................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_ping_test.c b/test/regression/netxduo_test/netx_icmp_ping_test.c new file mode 100644 index 00000000..9a15bb60 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_ping_test.c @@ -0,0 +1,531 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR msg[5000]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(__PRODUCT_NETXDUO__) + /* Enable IP fragment for both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check IP fragment enable status. */ + if (status) + error_counter++; +#endif +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +NX_PACKET *packet_ptr[20]; +UINT i; +ULONG pings_sent; +ULONG pings_sent_expected = 0; +ULONG ping_timeouts; +ULONG ping_timeouts_expected = 0; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG ping_responses_received_expected = 0; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS ip_address; +#endif + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Ping Test............................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Bring down the primary interface. And ping limited broadcast address. */ + ip_0.nx_ip_interface[0].nx_interface_link_up = NX_FALSE; + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(255, 255, 255, 255), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* No interface to send ping packet. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bring up the primary interface. And ping limited broadcast address. */ + ip_0.nx_ip_interface[0].nx_interface_link_up = NX_TRUE; + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(255, 255, 255, 255), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + +#ifdef NX_ENABLE_ICMP_ADDRESS_CHECK + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + ping_timeouts_expected++; +#else + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + ping_responses_received_expected++; +#endif + + pings_sent_expected++; + nx_packet_release(my_packet); +#endif + + packet_process_callback = my_packet_process; + + /* Loop to allocate the all packets. */ + for (i = 0; i < pool_0.nx_packet_pool_total; i++) + { + + /* Allocate the packets. */ + status = nx_packet_allocate(&pool_0, &packet_ptr[i], NX_ICMP_PACKET, 10); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_NO_PACKET) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Loop to release the all packets. */ + for (i = 0; i < pool_0.nx_packet_pool_total; i++) + { + + /* Release the packets. */ + status = nx_packet_release(packet_ptr[i]); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Ping an IP address that does exist but the packet is not enough to fill all the data. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), msg, sizeof(msg), &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(__PRODUCT_NETXDUO__) + /* Ping an IP address with big data. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 257, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + nx_packet_release(my_packet); + pings_sent_expected++; + ping_responses_received_expected++; +#endif + + /* Ping an unreachable IP address with no wait. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 7), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status . */ + if ((status != NX_IP_ADDRESS_ERROR) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an unknown IP address with no wait. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 7), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_NO_WAIT); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + pings_sent_expected++; + + /* Get no ICMP information. */ + status = nx_icmp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL); + + /* Check the status . */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != ping_timeouts_expected) || (pings_sent != pings_sent_expected) || (ping_responses_received != ping_responses_received_expected)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 7), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + pings_sent_expected++; + ping_timeouts_expected++; + + /* Now ping loopback address. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 4), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + pings_sent_expected++; + ping_responses_received_expected++; + + /* Release the packet. */ + nx_packet_release(my_packet); + +#ifndef NX_DISABLE_LOOPBACK_INTERFACE + + /* Now ping loopback address. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + pings_sent_expected++; + ping_responses_received_expected++; + + /* Release the packet. */ + nx_packet_release(my_packet); +#endif /* NX_DISABLE_LOOPBACK_INTERFACE */ + + /* Now ping an IP address that does exist. */ + /* The reply packet contains checksum 0. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + pings_sent_expected++; + ping_responses_received_expected++; + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != ping_timeouts_expected) || (pings_sent != pings_sent_expected) || (ping_responses_received != ping_responses_received_expected)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28 /* data only */) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages) || error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + + /* Set the address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Now ping an IP address that does exist using nxd_icmp_ping API. */ + /* The reply packet contains checksum 0. */ + status = nxd_icmp_ping(&ip_0, &ip_address, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + pings_sent_expected++; + ping_responses_received_expected++; + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != ping_timeouts_expected) || (pings_sent != pings_sent_expected) || (ping_responses_received != ping_responses_received_expected)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28 /* data only */) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages) || error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist using nxd_icmp_source_ping API. */ + /* The reply packet contains checksum 0. */ + status = nxd_icmp_source_ping(&ip_0, &ip_address, 0, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + pings_sent_expected++; + ping_responses_received_expected++; + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != ping_timeouts_expected) || (pings_sent != pings_sent_expected) || (ping_responses_received != ping_responses_received_expected)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28 /* data only */) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages) || error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef FEATURE_NX_IPV6 + /* Set the address version. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + + /* Now ping an IPv6 address when disable the IPv6 feature. */ + status = nxd_icmp_ping(&ip_0, &ip_address, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if (status != NX_NOT_SUPPORTED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IPv6 address when disable the IPv6 feature. */ + status = nxd_icmp_source_ping(&ip_0, &ip_address, 0, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if (status != NX_NOT_SUPPORTED) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif +#endif + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +#if defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header_ptr; +#else +NX_IP_HEADER *ip_header_ptr; +#endif +ULONG protocol; +NX_ICMP_HEADER *icmp_header_ptr; + + /* Ignore packet that is not ICMP. */ + if(packet_ptr -> nx_packet_length < 28) + return NX_TRUE; + +#if defined(__PRODUCT_NETXDUO__) + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + +#else + ip_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#endif + + /* Get IP header. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + protocol = (ip_header_ptr -> nx_ip_header_word_2 >> 16) & 0xFF; + + /* Is ICMP packet? */ + if(protocol == 1) + { + + /* Yes it is. */ + /* Get ICMP header. */ + icmp_header_ptr = (NX_ICMP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(icmp_header_ptr -> nx_icmp_header_word_0); + + if((icmp_header_ptr -> nx_icmp_header_word_0 & NX_LOWER_16_MASK) == 0xFFFF) + error_counter++; + + NX_CHANGE_ULONG_ENDIAN(icmp_header_ptr -> nx_icmp_header_word_0); + } + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMP Ping Test............................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_icmp_send_error_message_test.c b/test/regression/netxduo_test/netx_icmp_send_error_message_test.c new file mode 100644 index 00000000..8cc1c483 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_send_error_message_test.c @@ -0,0 +1,470 @@ +/* This NetX test concentrates on the ICMPv4 Error Message. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +#if defined (__PRODUCT_NETXDUO__) && !defined (NX_DISABLE_ICMPV4_ERROR_MESSAGE) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ip_0_icmp_counter; +static ULONG ip_1_icmp_counter; +static ULONG ip_1_icmp_error_message_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static VOID my_ipv4_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_send_error_message_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + ip_0_icmp_counter = 0; + ip_1_icmp_counter = 0; + ip_1_icmp_error_message_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for IP 0 instances. */ + status = nx_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Send Error Message Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + packet_process_callback = my_packet_process; + + /* Test illegal length of NX_IP_OPTION_INTERNET_TIMESTAMP option by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the value. */ + if ((ip_0_icmp_counter != 1) && (ip_1_icmp_counter != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable ICMP processing for IP 1 instances. */ + status = nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Test illegal length of NX_IP_OPTION_INTERNET_TIMESTAMP option and destination address (255, 255, 255, 255) by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the value. */ + if ((ip_0_icmp_counter != 2) && (ip_1_icmp_counter != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test illegal length of NX_IP_OPTION_INTERNET_TIMESTAMP option and non-initial fragment by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the value. */ + if ((ip_0_icmp_counter != 3) && (ip_1_icmp_counter != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set my function. */ + ip_1.nx_ipv4_packet_receive = my_ipv4_packet_receive; + + /* Test illegal length of NX_IP_OPTION_INTERNET_TIMESTAMP option by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the value. */ + if ((ip_0_icmp_counter != 4) && (ip_1_icmp_counter != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_ENABLE_SOURCE_ADDRESS_CHECK + /* Test illegal length of NX_IP_OPTION_INTERNET_TIMESTAMP option and multicast address by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the value. */ + if ((ip_0_icmp_counter != 5) && (ip_1_icmp_counter != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Test unknown protocol. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_ENABLE_SOURCE_ADDRESS_CHECK + /* Check the value. */ + if ((ip_0_icmp_counter != 6) && (ip_1_icmp_counter != 1)) +#else + /* Check the value. */ + if ((ip_0_icmp_counter != 5) && (ip_1_icmp_counter != 1)) +#endif + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_IPV4_HEADER *ip_header_ptr; +NX_ICMP_HEADER *icmp_header_ptr; +ULONG ip_header_length; +ULONG protocol; +ULONG checksum; +ULONG val; +ULONG offset = 0; +ULONG shift; +ULONG message_word; + + /* Get the IP header pointer. */ + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + + /* Get IP header. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + protocol = (ip_header_ptr -> nx_ip_header_word_2 >> 16) & 0xFF; + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Only process ICMP message. */ + if (protocol != NX_PROTOCOL_ICMP) + return (NX_TRUE); + + /* Modify the ICMP packet from ip_0 instance. */ + if(ip_ptr == &ip_0) + { + + /* Update the icmp_counter. */ + ip_0_icmp_counter++; + + /* Get the IP header pointer. */ + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + + /* Calculate the IPv4 option length. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + ip_header_length = ((ip_header_ptr -> nx_ip_header_word_0 & NX_IP_LENGTH_MASK) >> 24) * sizeof(ULONG); + + /* Get ICMP header. */ + icmp_header_ptr = (NX_ICMP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + ip_header_length); + + /* Add the illegal length 7 for NX_IP_OPTION_INTERNET_TIMESTAMP option. */ + if ((ip_0_icmp_counter == 1) || (ip_0_icmp_counter == 2) || +#ifndef NX_ENABLE_SOURCE_ADDRESS_CHECK + (ip_0_icmp_counter == 3) || (ip_0_icmp_counter == 4) || (ip_0_icmp_counter == 5)) +#else + (ip_0_icmp_counter == 3) || (ip_0_icmp_counter == 4)) +#endif + { + + /* Move the data to add the option. */ + offset = 12; + shift = packet_ptr -> nx_packet_length - ip_header_length; + memmove(((UCHAR *)(icmp_header_ptr)) + offset, icmp_header_ptr, shift); + + /* Clear memory. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add type, length, offset, overflw and flags. */ + message_word = (ULONG)((NX_IP_OPTION_INTERNET_TIMESTAMP << 24) | (7 << 16) | (5 << 8) ); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Add type, length, offset, overflw and flags. */ + memcpy(icmp_header_ptr, &message_word, sizeof(ULONG)); + + /* Clear the time stamp value. */ + memset(((UCHAR *)(icmp_header_ptr)) + sizeof(ULONG), 0 , offset - sizeof(ULONG)); + } + + /* Modified the destination address to 255.255.255.255. */ + if (ip_0_icmp_counter == 2) + { + + /* Modified the destination address to 255.255.255.255. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + ip_header_ptr -> nx_ip_header_destination_ip = IP_ADDRESS(255, 255, 255, 255); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + } + + /* Modified the fragment offset. */ + if (ip_0_icmp_counter == 3) + { + + /* Modified the destination address to 255.255.255.255. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + ip_header_ptr -> nx_ip_header_word_1 |= 10; + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + } + +#ifndef NX_ENABLE_SOURCE_ADDRESS_CHECK + /* Modified the destination address to 255.255.255.255. */ + if (ip_0_icmp_counter == 5) + { + + /* Modified the source address to 224.0.0.251. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + ip_header_ptr -> nx_ip_header_source_ip = IP_ADDRESS(224,0,0,251); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip); + } +#endif + + /* Modified the protocol as unknown. */ +#ifndef NX_ENABLE_SOURCE_ADDRESS_CHECK + if (ip_0_icmp_counter == 6) +#else + if (ip_0_icmp_counter == 5) +#endif + { + + /* Set the protocol as unkown protocol, ip_1 should send the icmp unreachable meesage. */; + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + ip_header_ptr -> nx_ip_header_word_2 |= 0x00FF0000; + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + } + + /* Update the header IP length and total length. */ + ip_header_length += offset; + packet_ptr -> nx_packet_append_ptr += offset; + packet_ptr -> nx_packet_length += offset; + + /* Rebuild the first 32-bit word of the IP header. */ + ip_header_ptr -> nx_ip_header_word_0 = (ULONG)((NX_IP_VERSION_V4 << 28) | + ((ip_header_length/sizeof(ULONG)) << 24) | + NX_IP_NORMAL | + (0xFFFF & packet_ptr -> nx_packet_length)); + + /* Endian swapping logic. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Clear the checksum . */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 & 0x0000FFFF; + + /* Calculate the checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, + /* Length is the size of IP header, including options */ + (UINT)(ip_header_length), + /* IPv4 header checksum does not use src/dest addresses */ + NULL, NULL); + + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + } + + /* Check the ICMP packet from ip_1 instance. */ + if(ip_ptr == &ip_1) + { + + /* Update the icmp_counter. */ + ip_1_icmp_counter++; + } + + return NX_TRUE; +} + +VOID my_ipv4_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_PACKET *my_packet[20]; +UINT packet_counter; +UINT i; + + /* Record the counter. */ + packet_counter = ip_ptr -> nx_ip_default_packet_pool -> nx_packet_pool_available; + + /* Loop to allocate the packet. */ + for (i = 0; i < packet_counter; i ++) + nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet[i], 0, NX_NO_WAIT); + + /* Receive the packet. */ + _nx_ipv4_packet_receive(ip_ptr, packet_ptr); + + /* Loop to release the packet. */ + for (i = packet_counter; i > 0; i --) + nx_packet_release(my_packet[i - 1]); + + /* Reset the function. */ + ip_1.nx_ipv4_packet_receive = _nx_ipv4_packet_receive; +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_send_error_message_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: ICMP Send Error Message Test..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_send_error_message_test_1.c b/test/regression/netxduo_test/netx_icmp_send_error_message_test_1.c new file mode 100644 index 00000000..d537e302 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_send_error_message_test_1.c @@ -0,0 +1,284 @@ +/* This NetX test concentrates on sending the ICMP error message. + * The destination of incoming packet is link-layer broadcast address. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +#if defined (__PRODUCT_NETXDUO__) && !defined (NX_DISABLE_ICMPV4_ERROR_MESSAGE) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ip_0_icmp_counter; +static ULONG ip_1_icmp_counter; +static ULONG ip_1_icmp_error_message_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_send_error_message_test_1_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + ip_0_icmp_counter = 0; + ip_1_icmp_counter = 0; + ip_1_icmp_error_message_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status = nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMP Send Error Message Test 1............................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + packet_process_callback = my_packet_process; + + /* Test illegal length of NX_IP_OPTION_INTERNET_TIMESTAMP option and destination address (1, 2, 3, 255) by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the value. */ + if ((ip_0_icmp_counter != 1) && (ip_1_icmp_counter != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_IPV4_HEADER *ip_header_ptr; +NX_ICMP_HEADER *icmp_header_ptr; +ULONG ip_header_length; +ULONG protocol; +ULONG checksum; +ULONG val; +ULONG offset = 0; +ULONG shift; +ULONG message_word; + + /* Get the IP header pointer. */ + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + + /* Get IP header. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + protocol = (ip_header_ptr -> nx_ip_header_word_2 >> 16) & 0xFF; + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Only process ICMP message. */ + if (protocol != NX_PROTOCOL_ICMP) + return (NX_TRUE); + + /* Modify the ICMP packet from ip_0 instance. */ + if(ip_ptr == &ip_0) + { + + /* Update the icmp_counter. */ + ip_0_icmp_counter++; + + /* Get the IP header pointer. */ + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + + /* Calculate the IPv4 option length. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + ip_header_length = ((ip_header_ptr -> nx_ip_header_word_0 & NX_IP_LENGTH_MASK) >> 24) * sizeof(ULONG); + + /* Get ICMP header. */ + icmp_header_ptr = (NX_ICMP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + ip_header_length); + + /* Add the illegal length 7 for NX_IP_OPTION_INTERNET_TIMESTAMP option. */ + /* Move the data to add the option. */ + offset = 12; + shift = packet_ptr -> nx_packet_length - ip_header_length; + memmove(((UCHAR *)(icmp_header_ptr)) + offset, icmp_header_ptr, shift); + + /* Clear memory. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add type, length, offset, overflw and flags. */ + message_word = (ULONG)((NX_IP_OPTION_INTERNET_TIMESTAMP << 24) | (7 << 16) | (5 << 8) ); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Add type, length, offset, overflw and flags. */ + memcpy(icmp_header_ptr, &message_word, sizeof(ULONG)); + + /* Clear the time stamp value. */ + memset(((UCHAR *)(icmp_header_ptr)) + sizeof(ULONG), 0 , offset - sizeof(ULONG)); + + /* Modified the destination address to 1.2.3.255. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + ip_header_ptr -> nx_ip_header_destination_ip = IP_ADDRESS(1, 2, 3, 255); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + + /* Update the header IP length and total length. */ + ip_header_length += offset; + packet_ptr -> nx_packet_append_ptr += offset; + packet_ptr -> nx_packet_length += offset; + + /* Rebuild the first 32-bit word of the IP header. */ + ip_header_ptr -> nx_ip_header_word_0 = (ULONG)((NX_IP_VERSION_V4 << 28) | + ((ip_header_length/sizeof(ULONG)) << 24) | + NX_IP_NORMAL | + (0xFFFF & packet_ptr -> nx_packet_length)); + + /* Endian swapping logic. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Clear the checksum . */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 & 0x0000FFFF; + + /* Calculate the checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, + /* Length is the size of IP header, including options */ + (UINT)(ip_header_length), + /* IPv4 header checksum does not use src/dest addresses */ + NULL, NULL); + + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + } + + /* Check the ICMP packet from ip_1 instance. */ + else if(ip_ptr == &ip_1) + { + + /* Update the icmp_counter. */ + ip_1_icmp_counter++; + } + + return NX_TRUE; +} +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_send_error_message_test_1_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: ICMP Send Error Message Test 1............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmp_tunnel_ipv4_ipv4_ping_test.c b/test/regression/netxduo_test/netx_icmp_tunnel_ipv4_ipv4_ping_test.c new file mode 100644 index 00000000..f2edfc9f --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_tunnel_ipv4_ipv4_ping_test.c @@ -0,0 +1,240 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_tunnel.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping_tunnel_ipv4_ipv4_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_256); + + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; + + /* Create ip0 TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020304; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020305; + + /* Set up TUNNEL */ + status = _nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V4,address_selector_0); + + + /* Create ip1 TUNNEL . */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020305; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020304; + + /* Set up TUNNEL */ + status = _nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V4,address_selector_1); +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: TUNNEL ICMP IPV4_4 Ping Test.................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 7), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 1) || (pings_sent != 2) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28 /* data only */) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping_tunnel_ipv4_ipv4_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TUNNEL ICMP IPV4_4 Ping Test..............................N/A\n"); + + test_control_return(3); + +} + +#endif /* NX_TUNNEL_ENABLE */ \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_icmp_tunnel_ipv4_ipv6_ping_test.c b/test/regression/netxduo_test/netx_icmp_tunnel_ipv4_ipv6_ping_test.c new file mode 100644 index 00000000..18740150 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_tunnel_ipv4_ipv6_ping_test.c @@ -0,0 +1,280 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_ipv6.h" +#include "nx_tunnel.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping_tunnel_ipv4_ipv6_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; + + /* Create ip0 TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address = ipv6_address_3; + address_selector_0.nx_selector_dst_tunnel_address = ipv6_address_4; + + /* Set up TUNNEL */ + status = _nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V6,address_selector_0); + + + /* Create ip1 TUNNEL . */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address = ipv6_address_4; + address_selector_1.nx_selector_dst_tunnel_address = ipv6_address_3; + + /* Set up TUNNEL */ + status = _nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V6,address_selector_1); +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: TUNNEL ICMP IPV4_6 Ping Test.................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 7), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 1) || (pings_sent != 2) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28 /* data only */) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping_tunnel_ipv4_ipv6_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TUNNEL ICMP IPV4_6 Ping Test..............................N/A\n"); + + test_control_return(3); + +} + +#endif /* NX_TUNNEL_ENABLE */ \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_icmp_tunnel_ipv6_ipv4_ping_test.c b/test/regression/netxduo_test/netx_icmp_tunnel_ipv6_ipv4_ping_test.c new file mode 100644 index 00000000..f7efe16e --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_tunnel_ipv6_ipv4_ping_test.c @@ -0,0 +1,311 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_tunnel.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping6_tunnel_ipv6_ipv4_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; + + /* Create ip0 TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020304; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020305; + + /* Set up TUNNEL */ + status = _nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V4,address_selector_0); + + if (status) + error_counter++; + + /* Create ip1 TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020305; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020304; + + /* Set up TUNNEL */ + status = _nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V4,address_selector_1); + + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: TUNNEL ICMP IPV6_4 Ping Test.................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = _nx_icmp_ping6(&ip_0, &ipv6_address_3, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = _nx_icmp_ping6(&ip_0, &ipv6_address_2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 1) || (pings_sent != 2) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping6_tunnel_ipv6_ipv4_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TUNNEL ICMP IPV6_4 Ping Test..............................N/A\n"); + + test_control_return(3); + +} +#endif /* NX_TUNNEL_ENABLE */ \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_icmp_tunnel_ipv6_ipv6_ping_test.c b/test/regression/netxduo_test/netx_icmp_tunnel_ipv6_ipv6_ping_test.c new file mode 100644 index 00000000..4ffbe154 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmp_tunnel_ipv6_ipv6_ping_test.c @@ -0,0 +1,308 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_tunnel.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; +NXD_ADDRESS ipv6_address_5; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping6_tunnel_ipv6_ipv6_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + ipv6_address_5.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_5.nxd_ip_address.v6[0] = 0x20000001; + ipv6_address_5.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_5.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_5.nxd_ip_address.v6[3] = 0x50000004; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address = ipv6_address_3; + address_selector_0.nx_selector_dst_tunnel_address = ipv6_address_4; + + /* Set up TUNNEL */ + status = _nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V6,address_selector_0); + + if (status) + error_counter++; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address = ipv6_address_4; + address_selector_1.nx_selector_dst_tunnel_address = ipv6_address_3; + + /* Set up TUNNEL */ + status = _nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V6,address_selector_1); + + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: TUNNEL ICMP IPV6_6 Ping Test.................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = _nx_icmp_ping6(&ip_0, &ipv6_address_5, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = _nx_icmp_ping6(&ip_0, &ipv6_address_2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 1) || (pings_sent != 2) || (ping_responses_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmp_ping6_tunnel_ipv6_ipv6_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TUNNEL ICMP IPV6_6 Ping Test..............................N/A\n"); + + test_control_return(3); + +} +#endif /* NX_TUNNEL_ENABLE */ \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_icmpv6_DAD_test.c b/test/regression/netxduo_test/netx_icmpv6_DAD_test.c new file mode 100644 index 00000000..44339f43 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_DAD_test.c @@ -0,0 +1,426 @@ +/* This NetX test concentrates on the ICMP ping6 operation use second interface. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_IPV6_DAD) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +/* Define the counters used in the test application... */ +static ULONG error_counter; +static ULONG NS_counter; +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +static ULONG Address_manual_config_counter; +static ULONG DAD_success_counter; +static ULONG DAD_failure_counter; +#endif + +static NXD_ADDRESS link_address_0; +static NXD_ADDRESS link_address_1; +static NXD_ADDRESS global_address; +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +static VOID ipv6_address_DAD_notify(NX_IP *ip_ptr, UINT status, UINT interface_index, UINT ipv6_addr_index, ULONG *ipv6_address); +#endif + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_DAD_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Check IP create status. */ + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ICMP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status = 0; +ULONG prefix_length; +UINT interface_index; +UINT valid_address_count; +UINT packet_counter; +UINT i; +UINT address_index; +NX_PACKET *my_packet[30]; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 DAD Test .........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + /* Set the callback function. */ + nxd_ipv6_address_change_notify(&ip_0, ipv6_address_DAD_notify); + + /* Set the callback function. */ + nxd_ipv6_address_change_notify(&ip_1, ipv6_address_DAD_notify); +#endif + + /* Hook link driver to check packets. */ + packet_process_callback = packet_process; + + /* Allocate all packet from packet pool. */ + packet_counter = pool_0.nx_packet_pool_available; + for(i =0; i < packet_counter; i ++) + { + + /* Allocate the packet. */ + status = nx_packet_allocate(&pool_0, &my_packet[i], NX_TCP_PACKET, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Set the IPv6 linklocal address for IP instance 0. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check the NS counter. */ + if(NS_counter != 0) + error_counter ++; + + /* Release all allocated packet. */ + for(i =0; i < packet_counter; i ++) + { + + /* Allocate the packet. */ + status = nx_packet_release(my_packet[i]); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Delete the IPv6 linklocal address for IP instance 0. */ + status = nxd_ipv6_address_delete(&ip_0, address_index); + + /* Check the status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 linklocal address for IP instance 0 again. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check the NS counter. */ + if(NS_counter != 3) + error_counter ++; + + /* Get the IPv6 link local address for IP instance 0. */ + status = nxd_ipv6_address_get(&ip_0, 0, &link_address_0, &prefix_length, &interface_index); + + /* Check the status. */ + if(status) + error_counter ++; + + /* Reset the NS_counter. */ + NS_counter = 0; + + /* Set the IPv6 linklocal address for IP instance 1. */ + status = nxd_ipv6_address_set(&ip_1, 0, NX_NULL, 10, NX_NULL); + + /* Check the status. */ + if(status) + error_counter ++; + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check the NS counter. */ + if(NS_counter != 3) + error_counter ++; + + /* Get the IPv6 link local address for IP instance 0. */ + status = nxd_ipv6_address_get(&ip_1, 0, &link_address_1, &prefix_length, &interface_index); + + /* Check the status. */ + if(status) + error_counter ++; + + /* Reset the NS_counter. */ + NS_counter = 0; + + /* Set ipv6 global address for IP instance 0. */ + global_address.nxd_ip_version = NX_IP_VERSION_V6; + global_address.nxd_ip_address.v6[0] = 0x20010000; + global_address.nxd_ip_address.v6[1] = 0x00000000; + global_address.nxd_ip_address.v6[2] = 0x00000000; + global_address.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address, 64, NX_NULL); + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check the NS counter. */ + if(NS_counter != 3) + error_counter ++; + + /* Get the IPv6 global address for IP instance 0. */ + status = nxd_ipv6_address_get(&ip_0, 1, &global_address_0, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || + (!CHECK_IPV6_ADDRESSES_SAME(&global_address.nxd_ip_address.v6[0], &global_address_0.nxd_ip_address.v6[0]))) + error_counter ++; + + /* Reset the NS_counter. */ + NS_counter = 0; + + /* Get count of valid addresses. */ + valid_address_count = 0; + for (i = 0; i < NX_MAX_IPV6_ADDRESSES; i++) + { + if (ip_1.nx_ipv6_address[i].nxd_ipv6_address_valid) + { + valid_address_count++; + } + } + + /* Set the same IPv6 global address for instance 1. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address, 64, NX_NULL); + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check the NS counter. */ + if(NS_counter != 1) + error_counter ++; + + /* Get the IPv6 global address for IP instance 1. */ + status = nxd_ipv6_address_get(&ip_1, 1, &global_address_1, &prefix_length, &interface_index); + + /* Check the status. */ + if(!status) + error_counter ++; + + /* Is there only one address in the list of interface? */ + if (ip_1.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address_next != NX_NULL) + error_counter++; + + /* Check count of valid addresses. */ + for (i = 0; i < NX_MAX_IPV6_ADDRESSES; i++) + { + if (ip_1.nx_ipv6_address[i].nxd_ipv6_address_valid) + { + valid_address_count--; + } + } + if (valid_address_count) + error_counter++; + + /* Clear link driver to check packets. */ + packet_process_callback = NX_NULL; + +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + /* Check the counter. */ + if((Address_manual_config_counter != 5) || (DAD_success_counter != 4) || (DAD_failure_counter != 1)) + { + error_counter ++; + } +#endif + + /* Check the error counter. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_ICMPV6_HEADER *header_ptr; + + /* Points to the ICMP message header. */ + header_ptr = (NX_ICMPV6_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV6_HEADER)); + + /* Determine the message type and call the appropriate handler. */ + if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_NEIGHBOR_SOLICITATION_TYPE) + { + + /* Update the NS counter. */ + NS_counter ++; + } + + return NX_TRUE; +} + +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +static VOID ipv6_address_DAD_notify(NX_IP *ip_ptr, UINT status, UINT interface_index, UINT ipv6_addr_index, ULONG *ipv6_address) +{ + + /* Check thte status. */ + switch(status) + { + case NX_IPV6_ADDRESS_MANUAL_CONFIG: + { + + /* Update the counter. */ + Address_manual_config_counter ++; + break; + } + + case NX_IPV6_ADDRESS_DAD_SUCCESSFUL: + { + + /* Check the IPv6 address index. */ + if((ipv6_addr_index == 1) && (ip_ptr == &ip_1)) + error_counter ++; + + /* Update the counter. */ + DAD_success_counter ++; + break; + } + case NX_IPV6_ADDRESS_DAD_FAILURE: + { + + /* Check the IPv6 address index. */ + if((ipv6_addr_index == 1) && (ip_ptr != &ip_1)) + error_counter ++; + + /* Update the counter. */ + DAD_failure_counter ++; + break; + } + } +} +#endif +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_DAD_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 DAD Test...........................................N/A\n"); + + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_abnormal_mtu_in_ra_test.c b/test/regression/netxduo_test/netx_icmpv6_abnormal_mtu_in_ra_test.c new file mode 100644 index 00000000..a5718077 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_abnormal_mtu_in_ra_test.c @@ -0,0 +1,201 @@ +/* Test processing of RA with MTU option whose value is larger than link MTU. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* RA packet. + * src: 0xFE80::0x0200:0x00FF:0xFE00:0xA0A0 + * mtu option: MTU size is 3000 */ +static char ra_pkt[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x18, 0x3a, 0xff, 0xfe, 0x80, /* ....:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x82, 0xc6, 0x40, 0x00, 0x07, 0x08, 0x00, 0x00, /* ..@..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x0b, 0xb8 /* ...... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_abnormal_mtu_in_ra_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; +NX_IPV6_DESTINATION_ENTRY *dest_entry_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Abnormal MTU in RA Test............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Get destination entry. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x020000FF; + ipv6_address.nxd_ip_address.v6[3] = 0xFE00A0A0; + status = _nx_icmpv6_dest_table_find(&ip_0, ipv6_address.nxd_ip_address.v6, &dest_entry_ptr, 0, 0); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + + /* Verify the MTU size. */ + if (dest_entry_ptr -> nx_ipv6_destination_entry_path_mtu != 1500) + { + error_counter++; + } + } + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_abnormal_mtu_in_ra_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Abnormal MTU in RA Test............................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_branch_test.c b/test/regression/netxduo_test/netx_icmpv6_branch_test.c new file mode 100644 index 00000000..e30a6cc4 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_branch_test.c @@ -0,0 +1,578 @@ +/* This NetX test concentrates on the code coverage for ICMPv6 functions, + * _nx_icmpv6_DAD_failure.c + * _nx_icmpv6_dest_table_find.c + */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_ENABLE_INTERFACE_CAPABILITY) +#include "tx_thread.h" +#include "nx_icmp.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 + +#define ASSERT_THREAD_COUNT 10 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +#ifndef NX_DISABLE_ASSERT +static TX_THREAD thread_for_assert[ASSERT_THREAD_COUNT]; +static UCHAR stack_for_assert[ASSERT_THREAD_COUNT][DEMO_STACK_SIZE]; +#endif + +/* NS packet with invalid option type 0. */ +static unsigned char pkt1[86] = { +0x33, 0x33, 0xff, 0x00, 0x01, 0x00, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, /* "3DV..`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, /* ... :... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x87, 0x00, /* ........ */ +0xae, 0x68, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, /* .h...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x00, 0x01, /* "..3DV.. */ +0x00, 0x11, 0x22, 0x33, 0x44, 0x56 /* .."3DV */ +}; + +/* NS packet with different SLLA. */ +static unsigned char pkt2[86] = { +0x33, 0x33, 0xff, 0x33, 0x44, 0x56, 0x00, 0x00, /* 33.3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, /* ... :... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0xff, 0x33, 0x44, 0x56, 0x87, 0x00, /* ...3DV.. */ +0x2d, 0xd9, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, /* -....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x01, 0x01, /* "..3DV.. */ +0x00, 0x00, 0x00, 0x00, 0xa0, 0xa0 /* ...... */ +}; +static unsigned char pkt3[86] = { +0x33, 0x33, 0xff, 0x33, 0x44, 0x56, 0x00, 0x00, /* 33.3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, /* ... :... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0xff, 0x33, 0x44, 0x56, 0x87, 0x00, /* ...3DV.. */ +0x2d, 0x39, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, /* -9...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x01, 0x01, /* "..3DV.. */ +0x00, 0xa0, 0x00, 0x00, 0xa0, 0xa0 /* ...... */ +}; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifndef NX_DISABLE_ASSERT +static VOID thread_for_assert_entry_0(ULONG thread_input); +static VOID thread_for_assert_entry_1(ULONG thread_input); +static VOID thread_for_assert_entry_2(ULONG thread_input); +static VOID thread_for_assert_entry_3(ULONG thread_input); +static VOID thread_for_assert_entry_4(ULONG thread_input); +static VOID thread_for_assert_entry_5(ULONG thread_input); +static VOID thread_for_assert_entry_6(ULONG thread_input); +static VOID thread_for_assert_entry_7(ULONG thread_input); +static VOID thread_for_assert_entry_8(ULONG thread_input); +static VOID thread_for_assert_entry_9(ULONG thread_input); +static VOID (*thread_for_assert_entry[])(ULONG) = +{ + thread_for_assert_entry_0, + thread_for_assert_entry_1, + thread_for_assert_entry_2, + thread_for_assert_entry_3, + thread_for_assert_entry_4, + thread_for_assert_entry_5, + thread_for_assert_entry_6, + thread_for_assert_entry_7, + thread_for_assert_entry_8, + thread_for_assert_entry_9, +}; +#endif + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_branch_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ICMP processing for IP instance. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ICMP enable status. */ + if (status) + error_counter++; + + /* Enable IPv6 processing for IP instance. */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG destination_address[4]; +ULONG next_hop[4]; +NX_IPV6_DESTINATION_ENTRY + *dest_entry_ptr; +#ifndef NX_DISABLE_IPV6_DAD +NXD_ADDRESS ipv6_address; +#endif +NX_PACKET *packet_ptr; +NX_IPV6_HEADER + *ip_header_ptr; +ND_CACHE_ENTRY + nd_entry; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: ICMPv6 Branch Test........................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + +#ifndef NX_DISABLE_IPV6_DAD + /* Hit condition of if (address_ptr -> nxd_ipv6_address_next == ipv6_address) in _nx_icmpv6_DAD_failure(). */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000009; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x00010003; + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 64, NX_NULL); + + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000009; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x00010004; + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 64, NX_NULL); + + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000009; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x00010005; + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 64, NX_NULL); + + _nx_icmpv6_DAD_failure(&ip_0, &ip_0.nx_ipv6_address[2]); + _nx_icmpv6_DAD_failure(&ip_0, &ip_0.nx_ipv6_address[1]); + + nxd_ipv6_address_delete(&ip_0, 0); + nxd_ipv6_address_delete(&ip_0, 1); + nxd_ipv6_address_delete(&ip_0, 2); +#endif + + + + /* Test _nx_icmpv6_dest_table_find. */ + /* Hit false condition of (i < NX_IPV6_DESTINATION_TABLE_SIZE). */ + ip_0.nx_ipv6_destination_table_size = 1; + if (_nx_icmpv6_dest_table_find(&ip_0, destination_address, &dest_entry_ptr, 0, 0) == NX_SUCCESS) + { + error_counter++; + } + + /* Recover*/ + ip_0.nx_ipv6_destination_table_size = 0; + +#ifndef NX_DISABLE_ASSERT + for (i = 0; i < ASSERT_THREAD_COUNT; i++) + { + + /* Create the assert thread. */ + tx_thread_create(&thread_for_assert[i], "Assert Test thread", thread_for_assert_entry[i], 0, + stack_for_assert[i], DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert[i]); + tx_thread_delete(&thread_for_assert[i]); + } +#endif + for (i = 0; i < NX_IPV6_DESTINATION_TABLE_SIZE; i++) + { + ip_0.nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid = NX_FALSE; + } + + /* Test _nx_icmpv6_send_queued_packets(). */ + /* Cover the false branch of 'if (status == NX_SUCCESS)'. */ + destination_address[0] = 0xfe800000; + destination_address[1] = 0; + destination_address[2] = 0; + destination_address[3] = 1; + next_hop[0] = 0; + next_hop[1] = 0; + next_hop[2] = 0; + next_hop[3] = 0; + nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if (nx_packet_allocate(&pool_0, &packet_ptr, NX_IPv6_PACKET, 0)) + { + error_counter++; + } + ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_append_ptr += sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV6_HEADER); + COPY_IPV6_ADDRESS(destination_address, ip_header_ptr -> nx_ip_header_destination_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + nd_entry.nx_nd_cache_packet_waiting_head = packet_ptr; + nd_entry.nx_nd_cache_interface_ptr = &(ip_0.nx_ip_interface[0]); + packet_ptr -> nx_packet_queue_next = NX_NULL; + packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr = &(ip_0.nx_ipv6_address[0]); + _nx_icmpv6_send_queued_packets(&ip_0, &nd_entry); + + /* Test _nx_icmpv6_send_queued_packets(). */ + /* Cover the false branch of 'if (!CHECK_UNSPECIFIED_ADDRESS(&(next_hop_address[0])))'. */ + destination_address[0] = 0xfe800000; + destination_address[1] = 0; + destination_address[2] = 0; + destination_address[3] = 1; + next_hop[0] = 0; + next_hop[1] = 0; + next_hop[2] = 0; + next_hop[3] = 0; + nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + _nx_icmpv6_dest_table_add(&ip_0, destination_address, &dest_entry_ptr, next_hop, 0, 0, &ip_0.nx_ipv6_address[0]); + if (nx_packet_allocate(&pool_0, &packet_ptr, NX_IPv6_PACKET, 0)) + { + error_counter++; + } + ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_append_ptr += sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV6_HEADER); + COPY_IPV6_ADDRESS(destination_address, ip_header_ptr -> nx_ip_header_destination_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + nd_entry.nx_nd_cache_packet_waiting_head = packet_ptr; + nd_entry.nx_nd_cache_interface_ptr = &(ip_0.nx_ip_interface[0]); + packet_ptr -> nx_packet_queue_next = NX_NULL; + packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr = &(ip_0.nx_ipv6_address[0]); + _nx_icmpv6_send_queued_packets(&ip_0, &nd_entry); + + /* Cover the false branch of 'if ((next_hop_dest_entry_ptr -> nx_ipv6_destination_entry_path_mtu > 0) &&'. */ + destination_address[0] = 0xfe800000; + destination_address[1] = 0; + destination_address[2] = 0; + destination_address[3] = 3; + ip_0.nx_ip_interface[0].nx_interface_ip_mtu_size = 0; + _nx_icmpv6_dest_table_add(&ip_0, destination_address, &dest_entry_ptr, next_hop, 0, 0, &ip_0.nx_ipv6_address[0]); + ip_0.nx_ip_interface[0].nx_interface_ip_mtu_size = 256; + destination_address[0] = 0xfe800000; + destination_address[1] = 0; + destination_address[2] = 0; + destination_address[3] = 2; + next_hop[0] = 0xfe800000; + next_hop[1] = 0; + next_hop[2] = 0; + next_hop[3] = 3; + _nx_icmpv6_dest_table_add(&ip_0, destination_address, &dest_entry_ptr, next_hop, 256, 0, &ip_0.nx_ipv6_address[0]); + if (nx_packet_allocate(&pool_0, &packet_ptr, NX_IPv6_PACKET, 0)) + { + error_counter++; + } + ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_append_ptr += sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV6_HEADER); + COPY_IPV6_ADDRESS(destination_address, ip_header_ptr -> nx_ip_header_destination_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + nd_entry.nx_nd_cache_packet_waiting_head = packet_ptr; + nd_entry.nx_nd_cache_interface_ptr = &(ip_0.nx_ip_interface[0]); + packet_ptr -> nx_packet_queue_next = NX_NULL; + packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr = &(ip_0.nx_ipv6_address[0]); + _nx_icmpv6_send_queued_packets(&ip_0, &nd_entry); + + /* Cover the false branch of 'if (status == NX_SUCCESS)'. */ + destination_address[0] = 0xfe800000; + destination_address[1] = 0; + destination_address[2] = 0; + destination_address[3] = 5; + next_hop[0] = 0xfe800000; + next_hop[1] = 0; + next_hop[2] = 0; + next_hop[3] = 6; + _nx_icmpv6_dest_table_add(&ip_0, destination_address, &dest_entry_ptr, next_hop, 256, 0, &ip_0.nx_ipv6_address[0]); + if (nx_packet_allocate(&pool_0, &packet_ptr, NX_IPv6_PACKET, 0)) + { + error_counter++; + } + ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_append_ptr += sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV6_HEADER); + COPY_IPV6_ADDRESS(destination_address, ip_header_ptr -> nx_ip_header_destination_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip); + nd_entry.nx_nd_cache_packet_waiting_head = packet_ptr; + nd_entry.nx_nd_cache_interface_ptr = &(ip_0.nx_ip_interface[0]); + packet_ptr -> nx_packet_queue_next = NX_NULL; + packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr = &(ip_0.nx_ipv6_address[0]); + _nx_icmpv6_send_queued_packets(&ip_0, &nd_entry); + + + +#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE + /* Test _nx_icmpv6_send_error_message(). */ + /* Cover the true banch of 'if ((pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr == NX_NULL) ||' */ + destination_address[0] = 0xfe800000; + destination_address[1] = 0; + destination_address[2] = 0; + destination_address[3] = 1; + if (nx_packet_allocate(&pool_0, &packet_ptr, NX_IPv6_PACKET, 0)) + { + error_counter++; + } + ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_append_ptr += sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr = NX_NULL; + COPY_IPV6_ADDRESS(destination_address, ip_header_ptr -> nx_ip_header_destination_ip); + COPY_IPV6_ADDRESS(destination_address, ip_header_ptr -> nx_ip_header_source_ip); + _nx_icmpv6_send_error_message(&ip_0, packet_ptr, 0, 0); +#endif + + + /* Test _nx_icmpv6_process_ns(). */ + /* Cover the false branch of '(option_ptr -> nx_icmpv6_option_type == ICMPV6_OPTION_TYPE_SRC_LINK_ADDR)'. */ + /* Inject NS packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the NS packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Test _nx_icmpv6_process_ns(). */ + /* Cover the false branch of '(mac_msw != new_msw)'. */ + /* Inject NS packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt2) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Set address state to valid. */ + ip_0.nx_ipv6_address[0].nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_VALID; + + /* Directly receive the NS packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Inject NS packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt3[14], sizeof(pkt3) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt3) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Set address state to valid. */ + ip_0.nx_ipv6_address[0].nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_VALID; + + /* Directly receive the NS packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#ifndef NX_DISABLE_ASSERT +static VOID thread_for_assert_entry_0(ULONG thread_input) +{ + + /* Test _nx_icmpv6_dest_table_add(). */ + /* Hit NX_ASSERT((destination_address != NX_NULL) && (dest_entry_ptr != NX_NULL) && (next_hop != NX_NULL)); */ + _nx_icmpv6_dest_table_add(&ip_0, NX_NULL, NX_NULL, NX_NULL, 0, 0, NX_NULL); +} + +static VOID thread_for_assert_entry_1(ULONG thread_input) +{ +ULONG destination_address[4] = {0}; + + /* Test _nx_icmpv6_dest_table_add(). */ + /* Hit NX_ASSERT((destination_address != NX_NULL) && (dest_entry_ptr != NX_NULL) && (next_hop != NX_NULL)); */ + _nx_icmpv6_dest_table_add(&ip_0, destination_address, NX_NULL, NX_NULL, 0, 0, NX_NULL); +} + +static VOID thread_for_assert_entry_2(ULONG thread_input) +{ +ULONG destination_address[4] = {0}; +NX_IPV6_DESTINATION_ENTRY *dest_entry; + + /* Test _nx_icmpv6_dest_table_add(). */ + /* Hit NX_ASSERT((destination_address != NX_NULL) && (dest_entry_ptr != NX_NULL) && (next_hop != NX_NULL)); */ + _nx_icmpv6_dest_table_add(&ip_0, destination_address, &dest_entry, NX_NULL, 0, 0, NX_NULL); +} + +static VOID thread_for_assert_entry_3(ULONG thread_input) +{ +ULONG destination_address[4] = {0}; +NX_IPV6_DESTINATION_ENTRY *dest_entry; +ULONG next_hop; +UINT i; + + /* Test _nx_icmpv6_dest_table_add(). */ + /* Hit NX_ASSERT(i < NX_IPV6_DESTINATION_TABLE_SIZE); */ + for (i = 0; i < NX_IPV6_DESTINATION_TABLE_SIZE; i++) + { + ip_0.nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid = NX_TRUE; + } + _nx_icmpv6_dest_table_add(&ip_0, destination_address, &dest_entry, &next_hop, 0, 0, NX_NULL); +} + +static VOID thread_for_assert_entry_4(ULONG thread_input) +{ + + /* Test _nx_icmpv6_dest_table_find(). */ + /* Hit NX_ASSERT((destination_address != NX_NULL) && (dest_entry_ptr != NULL)); */ + _nx_icmpv6_dest_table_find(&ip_0, NX_NULL, NX_NULL, 0, 0); +} + +static VOID thread_for_assert_entry_5(ULONG thread_input) +{ +ULONG destination_address[4]; + + /* Test _nx_icmpv6_dest_table_find(). */ + /* Hit NX_ASSERT((destination_address != NX_NULL) && (dest_entry_ptr != NULL)); */ + _nx_icmpv6_dest_table_find(&ip_0, destination_address, NX_NULL, 0, 0); +} + +static VOID thread_for_assert_entry_6(ULONG thread_input) +{ +ULONG destination_address[4]; +NXD_IPV6_ADDRESS ipv6_address; + + /* Test _nx_icmpv6_send_ns(). */ + /* Hit NX_ASSERT(driver_request.nx_ip_driver_interface != NX_NULL); */ + ipv6_address.nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_TENTATIVE; + ipv6_address.nxd_ipv6_address_attached = NX_NULL; + _nx_icmpv6_send_ns(&ip_0, destination_address, NX_FALSE, &ipv6_address, NX_FALSE, NX_NULL); +} + +static VOID thread_for_assert_entry_7(ULONG thread_input) +{ +ULONG destination_address[4]; +NXD_IPV6_ADDRESS ipv6_address; +NX_INTERFACE nx_interface; + + /* Test _nx_icmpv6_send_ns(). */ + /* Hit NX_ASSERT(outgoing_address -> nxd_ipv6_address_attached -> nx_interface_link_driver_entry != NX_NULL); */ + ipv6_address.nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_TENTATIVE; + ipv6_address.nxd_ipv6_address_attached = &nx_interface; + nx_interface.nx_interface_link_driver_entry = NX_NULL; + _nx_icmpv6_send_ns(&ip_0, destination_address, NX_FALSE, &ipv6_address, NX_FALSE, NX_NULL); +} + +static VOID thread_for_assert_entry_8(ULONG thread_input) +{ + + /* Test _nx_icmpv6_send_queued_packets(). */ + /* Hit NX_ASSERT(nd_entry != NX_NULL); */ + _nx_icmpv6_send_queued_packets(&ip_0, NX_NULL); +} + +static VOID thread_for_assert_entry_9(ULONG thread_input) +{ +ND_CACHE_ENTRY nd_entry; + + /* Test _nx_icmpv6_send_queued_packets(). */ + /* Hit NX_ASSERT(nd_entry -> nx_nd_cache_packet_waiting_head != NX_NULL); */ + nd_entry.nx_nd_cache_packet_waiting_head = NX_NULL; + _nx_icmpv6_send_queued_packets(&ip_0, &nd_entry); +} +#endif + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_branch_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Branch Test........................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_icmpv6_destination_table_periodic_test.c b/test/regression/netxduo_test/netx_icmpv6_destination_table_periodic_test.c new file mode 100644 index 00000000..600ee12c --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_destination_table_periodic_test.c @@ -0,0 +1,985 @@ +/* This NetX test to test the ICMPv6 Echo request process. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) + +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_ram_network_driver_test_1500.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +static ULONG echo_request_sent; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Frame (118 bytes): RA */ +static const unsigned char pkt1[118] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x40, 0x3a, 0xff, 0xfe, 0x80, /* ...@:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x9f, 0x75, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, /* .u... .. */ +0x75, 0x30, 0x00, 0x00, 0x03, 0xe8, 0x01, 0x01, /* u0...... */ +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x05, 0xdc, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* :.....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (70 bytes): Echo Request 3ffe:501:ffff:100:200:ff:fe00:100 */ +static const unsigned char pkt2[70] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x10, 0x3a, 0xff, 0x3f, 0xfe, /* ....:.?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x80, 0x00, /* "..3DV.. */ +0x7a, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* z....... */ +0x03, 0x04, 0x05, 0x06, 0x07, 0x08 /* ...... */ +}; + +/* Frame (86 bytes): NS */ +static const unsigned char pkt3[86] = { +0x33, 0x33, 0xff, 0x00, 0x01, 0x00, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, /* "3DV..`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0x3f, 0xfe, /* ... :.?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0xff, 0x02, /* "..3DV.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0xff, 0x00, 0x01, 0x00, 0x87, 0x00, /* ........ */ +0x1c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* .l....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x01, 0x01, /* ........ */ +0x00, 0x11, 0x22, 0x33, 0x44, 0x56 /* .."3DV */ +}; + +/* Frame (86 bytes): NA */ +static const unsigned char pkt4[86] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0x3f, 0xfe, /* ... :.?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x88, 0x00, /* "..3DV.. */ +0x57, 0x0b, 0xe0, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* W.....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x01, 0x00 /* ...... */ +}; + +/* Frame (70 bytes): Echo Reply 3ffe:501:ffff:100:200:ff:fe00:100 */ +static const unsigned char pkt5[70] = { +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, /* "3DV..`. */ +0x00, 0x00, 0x00, 0x10, 0x3a, 0xff, 0x3f, 0xfe, /* ....:.?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x3f, 0xfe, /* "..3DV?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x81, 0x00, /* ........ */ +0x79, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* y....... */ +0x03, 0x04, 0x05, 0x06, 0x07, 0x08 /* ...... */ +}; + +/* Frame (1294 bytes): Echo Request 3ffe:501:ffff:102:200:ff:fe00:a2a2 */ +static const unsigned char pkt6[1294] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x04, 0xd8, 0x3a, 0xff, 0x3f, 0xfe, /* ....:.?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x02, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa2, 0xa2, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x80, 0x00, /* "..3DV.. */ +0xd4, 0x9f, 0xff, 0xff, 0x00, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05 /* ...... */ +}; + +/* Frame (1294 bytes): Echo Reply, 3ffe:501:ffff:102:200:ff:fe00:a2a2 */ +static const unsigned char pkt7[1294] = { +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, /* "3DV..`. */ +0x00, 0x00, 0x04, 0xd8, 0x3a, 0xff, 0x3f, 0xfe, /* ....:.?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x3f, 0xfe, /* "..3DV?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x02, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa2, 0xa2, 0x81, 0x00, /* ........ */ +0xd3, 0x9f, 0xff, 0xff, 0x00, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05 /* ...... */ +}; + +/* Frame (1294 bytes): Packet Too Big, MTU 56, 3ffe:501:ffff:100:200:ff:fe00:100 */ +static const unsigned char pkt8[1294] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x04, 0xd8, 0x3a, 0x40, 0x3f, 0xfe, /* ....:@?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x02, 0x00, /* "..3DV.. */ +0xe1, 0x8e, 0x00, 0x00, 0x00, 0x38, 0x60, 0x00, /* .....8`. */ +0x00, 0x00, 0x04, 0xd8, 0x3a, 0x40, 0x3f, 0xfe, /* ....:@?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x3f, 0xfe, /* "..3DV?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x02, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa2, 0xa2, 0x81, 0x00, /* ........ */ +0xd3, 0x9f, 0xff, 0xff, 0x00, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* ........ */ +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, /* ........ */ +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, /* ........ */ +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* ........ */ +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* ........ */ +0x05, 0x05, 0x05, 0x05, 0x05, 0x05 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_destination_table_periodic_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + packet_counter = 0; + echo_request_sent = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*4); + pointer = pointer + 1536*4; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check IP create status. */ + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ICMP enable status. */ + if(status) + error_counter++; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +NXD_ADDRESS dest_ip; +CHAR mac[6]; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Destination Table Periodic Test...................."); + + /* Set the linklocal address*/ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Setup filter function to check whether the packet is sent from ip_0. */ + advanced_packet_process_callback = my_packet_process; + + /* Set the destination address and mac address. */ + dest_ip.nxd_ip_version = NX_IP_VERSION_V6; + dest_ip.nxd_ip_address.v6[0] = 0xfe800000; + dest_ip.nxd_ip_address.v6[1] = 0x00000000; + dest_ip.nxd_ip_address.v6[2] = 0x020000ff; + dest_ip.nxd_ip_address.v6[3] = 0xfe000100; + mac[0] = 0; + mac[1] = 0; + mac[2] = 0; + mac[3] = 0; + mac[4] = 1; + mac[5] = 0; + + /* Added ND Cache Entry. */ + status = nxd_nd_cache_entry_set(&ip_0, dest_ip.nxd_ip_address.v6, 0, mac); + + /* Check status */ + if(status) + error_counter ++; + + /* Send ICMPv6 RA to ip_0. */ + /* The source address is fe80::200:ff:fe00:100. */ + /* The destination address is ff02::1. */ + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMPv6 RA packet. */ + _nx_ip_packet_receive(&ip_0, packet_ptr); + + /* Waiting for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check the destination table. the destination address is fe80::200:ff:fe00:100. */ + if ((ip_0.nx_ipv6_destination_table_size != 1) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[0] != 0xfe800000) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[1] != 0x00000000) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[3] != 0xfe000100) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_path_mtu != 1500) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_MTU_timer_tick != NX_WAIT_FOREVER)) + error_counter ++; + + /* Send ICMPv6 Echo Request to ip_0. */ + /* The source address is 3ffe:501:ffff:100:200:ff:fe00:100. */ + /* The destination address is 3ffe:501:ffff:100:211:22ff:fe33:4456. */ + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt2) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMPv6 Echo Request packet. */ + _nx_ip_packet_receive(&ip_0, packet_ptr); + + /* Sleep 1 second to check NS, inject NA and check Echo Reply. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the destination table. */ + if ((ip_0.nx_ipv6_destination_table_size != 2) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[0] != 0xfe800000) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[1] != 0x00000000) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[3] != 0xfe000100) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_path_mtu != 1500) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_MTU_timer_tick != NX_WAIT_FOREVER) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[0] != 0x3ffe0501) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[1] != 0xffff0100) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[3] != 0xfe000100) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_path_mtu != 1500) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_MTU_timer_tick != NX_WAIT_FOREVER)) + error_counter ++; + + /* Send ICMPv6 Echo Request to ip_0. */ + /* The source address is 3ffe:501:ffff:102:200:ff:fe00:a2a2. */ + /* The destination address is 3ffe:501:ffff:100:211:22ff:fe33:4456. */ + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt6[14], sizeof(pkt6) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt6) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMPv6 Echo Request packet. */ + _nx_ip_packet_receive(&ip_0, packet_ptr); + + /* Sleep 1 second to check Echo Reply. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the destination table. */ + if ((ip_0.nx_ipv6_destination_table_size != 3) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[0] != 0xfe800000) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[1] != 0x00000000) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[3] != 0xfe000100) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_path_mtu != 1500) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_MTU_timer_tick != NX_WAIT_FOREVER) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[0] != 0x3ffe0501) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[1] != 0xffff0100) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[3] != 0xfe000100) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_path_mtu != 1500) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_MTU_timer_tick != NX_WAIT_FOREVER) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[0] != 0x3ffe0501) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[1] != 0xffff0102) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[3] != 0xfe00a2a2) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_path_mtu != 1500) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_MTU_timer_tick != NX_WAIT_FOREVER)) + error_counter ++; + + /* Send ICMPv6 Packet too big packet with MTU 56 to ip_0. */ + /* The source address is 0x3ffe:501:ffff:100:200:ff:fe00:100. */ + /* The destination address is 0x3ffe:501:ffff:100:211:22ff:fe33:4456. */ + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt8[14], sizeof(pkt8) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt8) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMPv6 Packet too big packet. */ + _nx_ip_packet_receive(&ip_0, packet_ptr); + + /* Check the destination table. */ + if ((ip_0.nx_ipv6_destination_table_size != 3) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[0] != 0xfe800000) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[1] != 0x00000000) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[3] != 0xfe000100) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_path_mtu != 1500) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_MTU_timer_tick != NX_WAIT_FOREVER) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[0] != 0x3ffe0501) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[1] != 0xffff0100) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[3] != 0xfe000100) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_path_mtu != 1500) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_MTU_timer_tick != NX_WAIT_FOREVER) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[0] != 0x3ffe0501) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[1] != 0xffff0102) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[3] != 0xfe00a2a2) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_path_mtu != 56) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_MTU_timer_tick != NX_PATH_MTU_INCREASE_WAIT_INTERVAL_TICKS)) + error_counter ++; + + /* Sleep NX_PATH_MTU_INCREASE_WAIT_INTERVAL_TICKS to check destination table. */ +#if (NX_IP_PERIODIC_RATE == 1000) + /* Plus 10 ticks to for the deviation when defined NX_IP_PERIODIC_RATE as 1000. */ + tx_thread_sleep(NX_PATH_MTU_INCREASE_WAIT_INTERVAL_TICKS + NX_IP_PERIODIC_RATE / 100); +#else + tx_thread_sleep(NX_PATH_MTU_INCREASE_WAIT_INTERVAL_TICKS); +#endif + + /* Check the destination table. */ + if ((ip_0.nx_ipv6_destination_table_size != 3) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[0] != 0xfe800000) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[1] != 0x00000000) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_destination_address[3] != 0xfe000100) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_path_mtu != 1500) || + (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_MTU_timer_tick != NX_WAIT_FOREVER) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[0] != 0x3ffe0501) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[1] != 0xffff0100) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_destination_address[3] != 0xfe000100) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_path_mtu != 1500) || + (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_MTU_timer_tick != NX_WAIT_FOREVER) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[0] != 0x3ffe0501) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[1] != 0xffff0102) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[2] != 0x020000ff) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_destination_address[3] != 0xfe00a2a2) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_path_mtu != 1500) || + (ip_0.nx_ipv6_destination_table[2].nx_ipv6_destination_entry_MTU_timer_tick != NX_WAIT_FOREVER)) + error_counter ++; + + /* Check error_counter and packet_counter. */ + if ((error_counter) || (packet_counter != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Out successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Check whether it is an NS packet. */ + if ((packet_counter == 0) && (packet_ptr -> nx_packet_length == (sizeof(pkt3) - 14))) + { + + /* Updated the packet counter. */ + packet_counter ++; + + /* Send NA packet to ip_0. */ + /* The source address is 0x3ffe:501:ffff:100:200:ff:fe00:100. */ + /* The destination address is 0x3ffe:501:ffff:100:211:22ff:fe33:4456. */ + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt4[14], sizeof(pkt4) - 14); + my_packet -> nx_packet_length = sizeof(pkt4) - 14; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMP redirect packet. */ + _nx_ip_packet_receive(&ip_0, my_packet); + } + + /* Check whether it is an Echo Reply packet. */ + if ((packet_counter == 1) && (packet_ptr -> nx_packet_length == (sizeof(pkt5) - 14))) + { + + /* Updated the packet counter. */ + packet_counter ++; + } + + /* Check whether it is an Echo Reply packet. */ + if ((packet_counter == 2) && (packet_ptr -> nx_packet_length == (sizeof(pkt7) - 14))) + { + + /* Updated the packet counter. */ + packet_counter ++; + } + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_destination_table_periodic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Destination Table Periodic Test....................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmpv6_echo_reply_test.c b/test/regression/netxduo_test/netx_icmpv6_echo_reply_test.c new file mode 100644 index 00000000..b8fa7c08 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_echo_reply_test.c @@ -0,0 +1,287 @@ +/* This NetX test to test the ICMPv6 Echo Reply process. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMP_INFO) && !defined(NX_DISABLE_IPV6_DAD) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_ram_network_driver_test_1500.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void icmp_checksum_compute(NX_PACKET *packet_ptr); + +/* Frame (68 bytes) */ +static const unsigned char pkt1[68] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x0e, 0x3a, 0x40, 0xfe, 0x80, /* ....:@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x81, 0x00, /* "..3DV.. */ +0x19, 0x1b, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff /* .... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_echo_reply_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*4); + pointer = pointer + 1536*4; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check IP create status. */ + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +NX_IPV6_HEADER *ip_header_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Echo Reply Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address*/ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Before DAD complete. */ + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Write data into the packet payload, ignore the physical header! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], 54); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 54; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 54; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Calculate the ICMP checksum. */ + icmp_checksum_compute(my_packet); + + /* Call the _nx_ip_packet_receive function directly receive the ICMPv6 Echo Reply. */ + _nx_ip_packet_receive(&ip_0, my_packet); + + /* Check the value. */ + if ((ip_0.nx_ip_ping_responses_received != 1) || (ip_0.nx_ip_icmp_invalid_packets != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Write data into the packet payload, ignore the physical header! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], 54); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 54; + + /* Set the error append pointer. */ + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 54; + + /* Points to the base of IPv6 header. */ + ip_header_ptr = (NX_IPV6_HEADER*)my_packet -> nx_packet_prepend_ptr; + + /* Modified the source address as invalid. */ + ip_header_ptr -> nx_ip_header_source_ip[0] = 0; + ip_header_ptr -> nx_ip_header_source_ip[1] = 0; + ip_header_ptr -> nx_ip_header_source_ip[2] = 0; + ip_header_ptr -> nx_ip_header_source_ip[3] = 0; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Calculate the ICMP checksum. */ + icmp_checksum_compute(my_packet); + + /* Call the _nx_ip_packet_receive function directly receive the ICMPv6 Echo Reply with error source address. */ + _nx_ip_packet_receive(&ip_0, my_packet); + + /* Check the value. */ + if ((ip_0.nx_ip_ping_responses_received != 2) || (ip_0.nx_ip_icmp_invalid_packets != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Write data into the packet payload, ignore the physical header! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], 54); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 54; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 54; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Calculate the ICMP checksum. */ + icmp_checksum_compute(my_packet); + + /* Call the _nx_ip_packet_receive function directly receive the valid ICMPv6 Echo Reply. */ + _nx_ip_packet_receive(&ip_0, my_packet); + + /* Check the value. */ + if ((ip_0.nx_ip_ping_responses_received != 3) || (ip_0.nx_ip_icmp_invalid_packets != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Out successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void icmp_checksum_compute(NX_PACKET *packet_ptr) +{ +NX_ICMPV6_HEADER *header_ptr; +ULONG *source_ip, *dest_ip; +ULONG checksum; + + /* Set packet version. */ + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V6; + + /* Skip IPv6 header. */ + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV6_HEADER); + + /* Get IPv6 addresses. */ + source_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 32); + dest_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 16); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(dest_ip); + + header_ptr = (NX_ICMPV6_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + /* Calculate the ICMP checksum. */ + header_ptr -> nx_icmpv6_header_checksum = 0; + + /* Calculate the checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_ICMPV6, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + header_ptr -> nx_icmpv6_header_checksum = checksum; + NX_CHANGE_USHORT_ENDIAN(header_ptr -> nx_icmpv6_header_checksum); + + /* Recover IPv6 header. */ + NX_IPV6_ADDRESS_CHANGE_ENDIAN(source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(dest_ip); + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV6_HEADER); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_echo_reply_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Echo Reply Test....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmpv6_echo_request_test.c b/test/regression/netxduo_test/netx_icmpv6_echo_request_test.c new file mode 100644 index 00000000..20a8cfb0 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_echo_request_test.c @@ -0,0 +1,288 @@ +/* This NetX test to test the ICMPv6 Echo request process. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMP_INFO) && !defined(NX_DISABLE_IPV6_DAD) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_ram_network_driver_test_1500.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void icmp_checksum_compute(NX_PACKET *packet_ptr); + +/* Frame (68 bytes) */ +static const unsigned char pkt1[68] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x0e, 0x3a, 0x40, 0xfe, 0x80, /* ....:@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x80, 0x00, /* "..3DV.. */ +0x19, 0x1b, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff /* .... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_echo_request_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*4); + pointer = pointer + 1536*4; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check icmp enable status. */ + if(status) + error_counter++; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +NX_IPV6_HEADER *ip_header_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Echo Request Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address*/ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Before DAD complete. */ + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Write data into the packet payload, ignore the physical header! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], 54); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 54; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 54; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Calculate the ICMP checksum. */ + icmp_checksum_compute(my_packet); + + /* Call the _nx_ip_packet_receive function directly receive the ICMPv6 Echo Request. */ + _nx_ip_packet_receive(&ip_0, my_packet); + + /* Check the value. */ + if ((ip_0.nx_ip_pings_received != 0) || (ip_0.nx_ip_pings_responded_to != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Write data into the packet payload, ignore the physical header! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], 54); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 54; + + /* Set the error append pointer. */ + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 54; + + /* Points to the base of IPv6 header. */ + ip_header_ptr = (NX_IPV6_HEADER*)my_packet -> nx_packet_prepend_ptr; + + /* Modified the source address as invalid. */ + ip_header_ptr -> nx_ip_header_source_ip[0] = 0; + ip_header_ptr -> nx_ip_header_source_ip[1] = 0; + ip_header_ptr -> nx_ip_header_source_ip[2] = 0; + ip_header_ptr -> nx_ip_header_source_ip[3] = 0; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Calculate the ICMP checksum. */ + icmp_checksum_compute(my_packet); + + /* Call the _nx_ip_packet_receive function directly receive the ICMPv6 Echo Request with error source address. */ + _nx_ip_packet_receive(&ip_0, my_packet); + + /* Check the value. */ + if ((ip_0.nx_ip_pings_received != 0) || (ip_0.nx_ip_pings_responded_to != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Write data into the packet payload, ignore the physical header! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], 54); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 54; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 54; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Calculate the ICMP checksum. */ + icmp_checksum_compute(my_packet); + + /* Call the _nx_ip_packet_receive function directly receive the valid ICMPv6 Echo Request. */ + _nx_ip_packet_receive(&ip_0, my_packet); + + /* Check the value. */ + if ((ip_0.nx_ip_pings_received != 1) || (ip_0.nx_ip_pings_responded_to != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Out successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void icmp_checksum_compute(NX_PACKET *packet_ptr) +{ +NX_ICMPV6_HEADER *header_ptr; +ULONG *source_ip, *dest_ip; +ULONG checksum; + + /* Set packet version. */ + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V6; + + /* Skip IPv6 header. */ + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV6_HEADER); + + /* Get IPv6 addresses. */ + source_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 32); + dest_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 16); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(dest_ip); + + header_ptr = (NX_ICMPV6_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + /* Calculate the ICMP checksum. */ + header_ptr -> nx_icmpv6_header_checksum = 0; + + /* Calculate the checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_ICMPV6, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + header_ptr -> nx_icmpv6_header_checksum = checksum; + NX_CHANGE_USHORT_ENDIAN(header_ptr -> nx_icmpv6_header_checksum); + + /* Recover IPv6 header. */ + NX_IPV6_ADDRESS_CHANGE_ENDIAN(source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(dest_ip); + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV6_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV6_HEADER); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_echo_request_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Echo Request Test..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmpv6_error_small_packet_test.c b/test/regression/netxduo_test/netx_icmpv6_error_small_packet_test.c new file mode 100644 index 00000000..c282d8fc --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_error_small_packet_test.c @@ -0,0 +1,305 @@ +/* This NetX test concentrates on icmpv6 error function. */ +/* + * 1. IP 0 sends a UDP packet to IP 1. + * 2. Since IP 1 has no UDP socket binding, it will reply ICMPv6 error. + * 3. No ICMPv6 error message is sent out since IP 1 payload is too small. + * + */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined (NX_DISABLE_ICMPV6_ERROR_MESSAGE) && !defined(NX_DISABLE_PACKET_CHAIN) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; + +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +static NXD_ADDRESS multicast_addr; +static NXD_ADDRESS lla_1; +static NXD_ADDRESS lla_2; + +static UCHAR pool_area_0[40960]; +static UCHAR pool_area_1[2048]; +static UCHAR test_data[128]; +static CHAR mac[2][6] = {{0x00, 0x11, 0x22, 0x33, 0x44, 0x56}, {0x00, 0x11, 0x22, 0x33, 0x44, 0x57}}; +static ULONG icmpv6_error_count; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT _nx_ram_network_driver_set_pool(NX_PACKET_POOL *pool_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_error_small_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + icmpv6_error_count = 0; + memset(test_data, 255, sizeof(test_data)); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create two packet pools. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pool_area_0, sizeof(pool_area_0)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create two packet pools. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", NX_IPv6_ICMP_PACKET, pool_area_1, sizeof(pool_area_1)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + multicast_addr.nxd_ip_version = NX_IP_VERSION_V6; + multicast_addr.nxd_ip_address.v6[0] = 0xFF020000; + multicast_addr.nxd_ip_address.v6[1] = 0x00000000; + multicast_addr.nxd_ip_address.v6[2] = 0x00000000; + multicast_addr.nxd_ip_address.v6[3] = 0x00000001; + + lla_1.nxd_ip_version = NX_IP_VERSION_V6; + lla_1.nxd_ip_address.v6[0] = 0xfe800000; + lla_1.nxd_ip_address.v6[1] = 0x00000000; + lla_1.nxd_ip_address.v6[2] = 0x00000000; + lla_1.nxd_ip_address.v6[3] = 0x10000001; + + lla_2.nxd_ip_version = NX_IP_VERSION_V6; + lla_2.nxd_ip_address.v6[0] = 0xfe800000; + lla_2.nxd_ip_address.v6[1] = 0x00000000; + lla_2.nxd_ip_address.v6[2] = 0x00000000; + lla_2.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + /* Check for IPv6 address set errors. */ + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check for IPv6 enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check for ICMP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status += nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out some test information banners. */ + printf("NetX Test: ICMPv6 Error Small Packet Test............................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait until DAD finishes. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + advanced_packet_process_callback = my_packet_process; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver use large pool. */ + _nx_ram_network_driver_set_pool(&pool_0); + + /* Test error message with icmp disabled. */ + /* Set nd cache so no NS or NA is needed. */ + nxd_nd_cache_entry_set(&ip_0, ipv6_address_2.nxd_ip_address.v6, 0, mac[1]); + nxd_nd_cache_entry_set(&ip_1, ipv6_address_1.nxd_ip_address.v6, 0, mac[0]); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Write data into the packet payload! */ + status += nx_packet_data_append(my_packet, test_data, sizeof(test_data), &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the UDP packet to unbinded peer. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &ipv6_address_2, 0x89); + + /* Check status. */ + if ((status) || (icmpv6_error_count != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +UCHAR *data = packet_ptr -> nx_packet_prepend_ptr; + + /* Check whether it is an icmpv6 packet. */ + if (packet_ptr -> nx_packet_length >= 48) + { + + /* Is it ICMPv6 packet? */ + if (data[6] == 0x3A) + { + + /* ICMPv6 error message. */ + if (data[40] == 0x01) + { + + /* Yes it is. */ + icmpv6_error_count++; + } + } + } + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_error_small_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: ICMPv6 Error Small Packet Test............................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_icmpv6_error_test.c b/test/regression/netxduo_test/netx_icmpv6_error_test.c new file mode 100644 index 00000000..46f68999 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_error_test.c @@ -0,0 +1,548 @@ +/* This NetX test concentrates on icmpv6 error function. */ +/* + * 1. IP 0 sends a UDP packet to IP 1. + * 2. Since IP 1 has no UDP socket binding, it will reply ICMPv6 error. + * 3. During sending ICMPv6 error packet, original data are copied. + * 4. Since IP 1 has smaller payload pool than IP 0, there was a bug causes memory leak. + * + */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined (NX_DISABLE_ICMPV6_ERROR_MESSAGE) && !defined(NX_DISABLE_PACKET_CHAIN) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; + +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +static NXD_ADDRESS multicast_addr; +static NXD_ADDRESS lla_1; +static NXD_ADDRESS lla_2; + +static UCHAR pool_area_0[40960]; +static UCHAR pool_area_1[2048]; +static UCHAR clean_buffer[1024]; +static UCHAR test_data[1024]; +static CHAR mac[2][6] = {{0x00, 0x11, 0x22, 0x33, 0x44, 0x56}, {0x00, 0x11, 0x22, 0x33, 0x44, 0x57}}; +static ULONG dest_unreachable_count; +static ULONG parameter_problem_count; +static NX_PACKET *test_packet[10]; + +/* Packet to trigger parameter problem message. + * src: 2001::1000:1 + * dst: ff02::1 */ +static const unsigned char pkt1[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, /* "3DV..`. */ +0x00, 0x00, 0x00, 0x25, 0x00, 0xff, 0x20, 0x01, /* ...%.. . */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x00, /* ......<. */ +0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, /* ......,. */ +0x87, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, /* ......:. */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x80, 0x00, /* .....e.. */ +0x10, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* ........ */ +0x03, 0x04, 0x05 /* ... */ +}; + +/* Packet to trigger parameter problem message. + * src: fe80::1000:1 + * dst: ff02::1 */ +static const unsigned char pkt2[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, /* "3DV..`. */ +0x00, 0x00, 0x00, 0x25, 0x00, 0xff, 0xfe, 0x80, /* ...%.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x00, /* ......<. */ +0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, /* ......,. */ +0x87, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, /* ......:. */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x80, 0x00, /* .....e.. */ +0x10, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* ........ */ +0x03, 0x04, 0x05 /* ... */ +}; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT _nx_ram_network_driver_set_pool(NX_PACKET_POOL *pool_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_error_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + dest_unreachable_count = 0; + parameter_problem_count = 0; + memset(clean_buffer, 0, sizeof(clean_buffer)); + memset(test_data, 255, sizeof(test_data)); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create two packet pools. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pool_area_0, sizeof(pool_area_0)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create two packet pools. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 544, pool_area_1, sizeof(pool_area_1)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + multicast_addr.nxd_ip_version = NX_IP_VERSION_V6; + multicast_addr.nxd_ip_address.v6[0] = 0xFF020000; + multicast_addr.nxd_ip_address.v6[1] = 0x00000000; + multicast_addr.nxd_ip_address.v6[2] = 0x00000000; + multicast_addr.nxd_ip_address.v6[3] = 0x00000001; + + lla_1.nxd_ip_version = NX_IP_VERSION_V6; + lla_1.nxd_ip_address.v6[0] = 0xfe800000; + lla_1.nxd_ip_address.v6[1] = 0x00000000; + lla_1.nxd_ip_address.v6[2] = 0x00000000; + lla_1.nxd_ip_address.v6[3] = 0x10000001; + + lla_2.nxd_ip_version = NX_IP_VERSION_V6; + lla_2.nxd_ip_address.v6[0] = 0xfe800000; + lla_2.nxd_ip_address.v6[1] = 0x00000000; + lla_2.nxd_ip_address.v6[2] = 0x00000000; + lla_2.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + /* Check for IPv6 address set errors. */ + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check for IPv6 enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check for ICMP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status += nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + + /* Print out some test information banners. */ + printf("NetX Test: ICMPv6 Error Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait until DAD finishes. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + advanced_packet_process_callback = my_packet_process; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver use large pool. */ + _nx_ram_network_driver_set_pool(&pool_0); + + /* Test error message with icmp disabled. */ + /* Set nd cache so no NS or NA is needed. */ + nxd_nd_cache_entry_set(&ip_0, ipv6_address_2.nxd_ip_address.v6, 0, mac[1]); + nxd_nd_cache_entry_set(&ip_1, ipv6_address_1.nxd_ip_address.v6, 0, mac[0]); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Write data into the packet payload! */ + status += nx_packet_data_append(my_packet, test_data, sizeof(test_data), &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the UDP packet to unbinded peer. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &ipv6_address_2, 0x89); + + /* Check status. */ + if ((status) || (dest_unreachable_count != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test error message with icmp enabled. */ + nxd_icmp_enable(&ip_1); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Write data into the packet payload! */ + status += nx_packet_data_append(my_packet, test_data, sizeof(test_data), &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate all packets of IP1's default pool. */ + for (i = 0; i < sizeof(test_packet) / sizeof(NX_PACKET *); i++) + { + if (nx_packet_allocate(&pool_1, &test_packet[i], 0, NX_NO_WAIT)) + break; + } + + /* Whether array reaches the bound. */ + if (i == sizeof(test_packet) / sizeof(NX_PACKET *)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the UDP packet to unbinded peer. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &ipv6_address_2, 0x89); + + /* No destination unrechable message should received since pool of IP1 is empty. */ + /* Check status. */ + if ((status) || (dest_unreachable_count != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release all packets. */ + while (i != 0) + { + i--; + nx_packet_release(test_packet[i]); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Write data into the packet payload! */ + status += nx_packet_data_append(my_packet, test_data, sizeof(test_data), &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the UDP packet to unbinded peer. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &ipv6_address_2, 0x89); + + /* Check status. */ + if ((status) || (dest_unreachable_count != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Verify all packets are normal. */ + for (i = 0; i < sizeof(test_packet) / sizeof(NX_PACKET *); i++) + { + if (nx_packet_allocate(&pool_1, &test_packet[i], 0, NX_NO_WAIT)) + break; + nx_packet_data_append(test_packet[i], test_data, pool_1.nx_packet_pool_payload_size, &pool_1, NX_NO_WAIT); + } + + /* Whether array reaches the bound. */ + if (i == sizeof(test_packet) / sizeof(NX_PACKET *)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release all packets. */ + while (i != 0) + { + i--; + nx_packet_release(test_packet[i]); + } + + /* Verify the clean buffer is not polluted. */ + for (i = 0; i < sizeof(clean_buffer); i++) + { + if (clean_buffer[i] != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + my_packet -> nx_packet_length = sizeof(pkt1) - 14; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + /* Directly receive the packet to let IP 1 send parameter problem packet. */ + _nx_ip_packet_deferred_receive(&ip_1, my_packet); + + /* Since IP 1 doesn't have link local address, the ICMPV6 error message can't be sent. */ + if (parameter_problem_count != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Set link local address. */ + nxd_ipv6_address_set(&ip_0, 0, &lla_1, 10, NX_NULL); + nxd_ipv6_address_set(&ip_1, 0, &lla_2, 10, NX_NULL); + +#ifndef NX_DISABLE_IPV6_DAD + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) - 14); + my_packet -> nx_packet_length = sizeof(pkt2) - 14; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + /* Directly receive the packet to let IP 1 send parameter problem packet. + * Since lla_2 is not ready, no ICMPV6 message could be sent from link local address. */ + _nx_ip_packet_deferred_receive(&ip_1, my_packet); + + if (parameter_problem_count != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* NX_DISABLE_IPV6_DAD */ + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) - 14); + my_packet -> nx_packet_length = sizeof(pkt2) - 14; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + /* Directly receive the packet to let IP 1 send parameter problem packet. */ + _nx_ip_packet_deferred_receive(&ip_1, my_packet); + + if (parameter_problem_count != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +UCHAR *data = packet_ptr -> nx_packet_prepend_ptr; + + /* Check whether it is an icmpv6 packet. */ + if (packet_ptr -> nx_packet_length >= 48) + { + + /* Is it ICMPv6 packet? */ + if (data[6] == 0x3A) + { + + /* Is it destination unreachable packet? */ + if (data[40] == 0x01) + { + + /* Yes it is. */ + dest_unreachable_count++; + } + + /* Is it parameter problem packet? */ + if (data[40] == 0x04) + { + + /* Yes it is. */ + parameter_problem_count++; + } + } + + /* Is it a framgent packet? */ + else if (data[6] == 0x2C) + { + + /* Is the offset non-zero? */ + if ((data[42] != 0) || ((data[32] & 0xF8) != 0)) + { + + /* Drop the fragment that is not header. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + } + } + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_error_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: ICMPv6 Error Test.........................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_icmpv6_invalid_length_test.c b/test/regression/netxduo_test/netx_icmpv6_invalid_length_test.c new file mode 100644 index 00000000..eb907ce1 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_invalid_length_test.c @@ -0,0 +1,183 @@ +/* Test processing of RA with invalid option type and length. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* RA packet. + * ICMPv6 option type: 0. + * ICMPv6 option length: 8. + * Actual ICMPv6 option length: 4. */ +static char ra_pkt[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x18, 0x3a, 0xff, 0xfe, 0x80, /* ....:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x93, 0x7d, 0x40, 0x00, 0x07, 0x08, 0x00, 0x00, /* .~@..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_length_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid Length Test................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + +#ifndef NX_DISABLE_ICMP_INFO + if (ip_0.nx_ip_icmp_invalid_packets != 1) + error_counter++; +#endif /* NX_DISABLE_ICMP_INFO */ + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_length_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid Length Test................................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_invalid_length_test2.c b/test/regression/netxduo_test/netx_icmpv6_invalid_length_test2.c new file mode 100644 index 00000000..f7d684cf --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_invalid_length_test2.c @@ -0,0 +1,177 @@ +/* Test processing of NS with invalid ICMPv6 payload length. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMP_INFO) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* NS packet. + * ICMPv6 type: 135. + * ICMPv6 code: 0. + * The length of ICMPv6 payload is 8. */ +static char ns_pkt[62] = { +0x33, 0x33, 0xff, 0x00, 0x01, 0x00, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, /* "3DV..`. */ +0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, 0xfe, 0x80, /* ....:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x87, 0x00, /* "..3DV.. */ +0x14, 0x20, 0x00, 0x00, 0x00, 0x00 /* c..... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_length_test2_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid Length Test 2.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ns_pkt[14], sizeof(ns_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ns_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the NS packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + if (ip_0.nx_ip_icmp_invalid_packets != 1) + error_counter++; + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_length_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid Length Test 2..............................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_invalid_message_test.c b/test/regression/netxduo_test/netx_icmpv6_invalid_message_test.c new file mode 100644 index 00000000..3f1780a4 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_invalid_message_test.c @@ -0,0 +1,230 @@ +/* Test processing of too big message with invalid length. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_RX_SIZE_CHECKING) +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Invalid too big message. */ +static char too_big_pkt[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x08, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x02, 0x00, +0xf2, 0x80, 0x00, 0x00, 0x05, 0x00 +}; + +static char echo_request_pkt[] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x07, 0x3a, 0x40, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x80, 0x00, +0x19, 0x22, 0x00, 0x00, 0x00 +}; + +static char echo_reply_pkt[] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x07, 0x3a, 0x40, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x81, 0x00, +0x18, 0x22, 0x00, 0x00, 0x00 +}; + +typedef struct TEST_PACKET_STRUCT +{ + CHAR *test_packet_ptr; + UINT test_packet_length; + +}TEST_PACKET; + +static TEST_PACKET test_packet[] = +{ +#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY + { + too_big_pkt, + sizeof(too_big_pkt), + }, +#endif + { + echo_request_pkt, + sizeof(echo_request_pkt), + }, + { + echo_reply_pkt, + sizeof(echo_reply_pkt), + }, +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_message_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; +INT i; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid Message Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + /* Inject the test packets. */ + for (i = 0; i < (sizeof(test_packet) / sizeof(TEST_PACKET)); i++) + { + + /* Allocate packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if (status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr->nx_packet_prepend_ptr, test_packet[i].test_packet_ptr + 14, test_packet[i].test_packet_length - 14); + packet_ptr->nx_packet_length = test_packet[i].test_packet_length - 14; + packet_ptr->nx_packet_append_ptr = packet_ptr->nx_packet_prepend_ptr + packet_ptr->nx_packet_length; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + } + +#ifndef NX_DISABLE_ICMP_INFO + if (ip_0.nx_ip_icmp_invalid_packets != (sizeof(test_packet) / sizeof(TEST_PACKET))) + error_counter++; +#endif /* NX_DISABLE_ICMP_INFO */ + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_message_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid Message Test...............................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_invalid_na.c b/test/regression/netxduo_test/netx_icmpv6_invalid_na.c new file mode 100644 index 00000000..c848d36d --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_invalid_na.c @@ -0,0 +1,178 @@ +/* Test processing of NA with same target address after DAD. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMP_INFO) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* NA packet. + * target Address: FE80::211:22FF:FE33:4456 */ +static char na_pkt[86] = { +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, /* "3DV..`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, /* ... :... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0xfe, 0x80, /* "..3DV.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x88, 0x00, /* "..3DV.. */ +0x7c, 0xb7, 0x60, 0x00, 0x00, 0x00, 0xfe, 0x80, /* |.`..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x02, 0x01, /* "..3DV.. */ +0x00, 0x11, 0x22, 0x33, 0x44, 0x56 /* .."3DV */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_na_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid NA Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &na_pkt[14], sizeof(na_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(na_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the NA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + if (ip_0.nx_ip_icmp_invalid_packets != 1) + error_counter++; + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_na_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid NA Test....................................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_invalid_ra_dest_test.c b/test/regression/netxduo_test/netx_icmpv6_invalid_ra_dest_test.c new file mode 100644 index 00000000..d3ea2ba9 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_invalid_ra_dest_test.c @@ -0,0 +1,189 @@ +/* Test processing of RA with destination multicast address but not ff02::1. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMP_INFO) && !defined(NX_DISABLE_IP_INFO) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* RA packet. + * destination: 0xff02::1:ff33:4456. */ +static char ra_pkt[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0xff, 0x33, 0x44, 0x56, 0x86, 0x00, /* ...3DV.. */ +0xea, 0x6b, 0x40, 0x00, 0x07, 0x0d, 0x00, 0x00, /* .k@..... */ +0x75, 0x35, 0x00, 0x00, 0x03, 0xed, 0x01, 0x01, /* u5...... */ +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, /* @....... */ +0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_ra_dest_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid RA Dest Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x021122FF; + ipv6_address.nxd_ip_address.v6[3] = 0xFE334456; + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Verify the packet is received by IP but dropped by ICMP layer. */ + if ((ip_0.nx_ip_total_packets_delivered != 1) || (ip_0.nx_ip_icmp_invalid_packets != 1)) + error_counter++; + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_ra_dest_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid RA Dest Test...............................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_icmpv6_invalid_ra_option_test.c b/test/regression/netxduo_test/netx_icmpv6_invalid_ra_option_test.c new file mode 100644 index 00000000..3e8c11e3 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_invalid_ra_option_test.c @@ -0,0 +1,183 @@ +/* Test processing of RA with invalid option. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMP_INFO) && !defined(NX_DISABLE_IP_INFO) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* RA packet. + * Invalid option length for option type ICMPV6_OPTION_TYPE_PREFIX_INFO. */ +static char ra_pkt[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x40, 0x3a, 0xff, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, 0xa0, 0x1d, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, +0x75, 0x30, 0x00, 0x00, 0x03, 0xe8, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x01, +0x00, 0x00, 0x00, 0x00, 0x05, 0xdc, 0x03, 0x04, 0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_ra_option_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid RA Option Test............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x021122FF; + ipv6_address.nxd_ip_address.v6[3] = 0xFE334456; + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Verify the packet is received by IP but dropped by ICMP layer. */ + if ((ip_0.nx_ip_total_packets_delivered != 1) || (ip_0.nx_ip_icmp_invalid_packets != 1)) + error_counter++; + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_invalid_ra_option_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Invalid RA Option Test.............................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_icmpv6_mtu_option_test.c b/test/regression/netxduo_test/netx_icmpv6_mtu_option_test.c new file mode 100644 index 00000000..f367a479 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_mtu_option_test.c @@ -0,0 +1,190 @@ +/* This NetX test concentrates on the IPv6 process ICMPv6 Option for MTU 0. + change last two bytes from 0x05, 0x00 to 0x00, 0x00 */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); +#if defined FEATURE_NX_IPV6 && defined NX_ENABLE_IPV6_PATH_MTU_DISCOVERY + +#include "nx_icmpv6.h" +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static char mtu_option[78] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x18, 0x3a, 0xff, 0xfe, 0x80, /* ....:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x45, 0x1b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, /* E....... */ +0x27, 0x10, 0x00, 0x00, 0x03, 0xe8, 0x05, 0x01, /* '....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_mtu_option_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check IP create status. */ + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + + /* Check ICMP enable status. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 MTU Option Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address*/ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check status */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &mtu_option[0], sizeof(mtu_option)); + my_packet -> nx_packet_length = sizeof(mtu_option); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + /* Directly pointer to ICMPv6 MTU option. */ + my_packet -> nx_packet_prepend_ptr += 70; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_ipv6_address_ptr = &ip_0.nx_ipv6_address[0]; + + /* Call function to process the MTU option. */ + status = _nx_icmpv6_process_packet_too_big(&ip_0, my_packet); + + /* Check the error counter. */ + if (status != NX_INVALID_MTU_DATA) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_mtu_option_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 MTU Option Test....................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_icmpv6_na_buffer_overwrite_test.c b/test/regression/netxduo_test/netx_icmpv6_na_buffer_overwrite_test.c new file mode 100644 index 00000000..a746301c --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_na_buffer_overwrite_test.c @@ -0,0 +1,367 @@ +/* Test processing of NA with chained packet. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_RX_SIZE_CHECKING) + +#define DEMO_STACK_SIZE 2048 + +#define PACKET_PAYLOAD_SIZE 1508 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* NA packet. */ +static char na_pkt[] = { +0xc8, 0xd9, 0xd2, 0x23, 0xe4, 0x9a, 0xc8, 0xd9, /* ...#.... */ +0xd2, 0x24, 0x23, 0x53, 0x86, 0xdd, 0x60, 0x00, /* .$#S..`. */ +0x00, 0x00, 0x05, 0xb0, 0x00, 0xff, 0x11, 0x11, /* ........ */ +0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x66, 0x66, 0x66, 0x67, 0x11, 0x11, /* ..fffg.. */ +0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3a, 0xb4, /* ..ffff:. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, /* ........ */ +0x99, 0xde, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_na_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_PAYLOAD_SIZE, pointer, (sizeof(NX_PACKET) + PACKET_PAYLOAD_SIZE)*16); + pointer = pointer + ((sizeof(NX_PACKET) + PACKET_PAYLOAD_SIZE)*16); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 NA Buffer Overwrite Test..........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0x11111111; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x66666666; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 64, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Inject NA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(packet_ptr, &na_pkt[14], sizeof(na_pkt) - 14, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter++; + + /* Directly receive the NA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Wait 1s to process this NA packet. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if (nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_na_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 NA Buffer Overwrite Test...........................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_na_test.c b/test/regression/netxduo_test/netx_icmpv6_na_test.c new file mode 100644 index 00000000..4ebef5c2 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_na_test.c @@ -0,0 +1,262 @@ +/* Test the process of NA packet. Section 7.2.5, RFC 4861 + * 1. Inject RA packet with TLLA. + * 2. Inject NA packet with different LLA. All flags are not set. + * 3. Router should not be modified since overwrite bit is not set and TLLA is different. + * 4. Inject NA packet with no TLLA. All flags are not set. + * 5. Router should be deleted since no TLLA. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static char ra_pkt[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x1c, 0xb4, 0x40, 0x00, 0x00, 0x14, 0x00, 0x01, /* ..@..... */ +0x86, 0xa0, 0x00, 0x00, 0x03, 0xe8, 0x01, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0xa0, 0xa0, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* :.....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static char na_pkt1[86] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xc0, 0xc0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, /* ... :... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x00, /* ........ */ +0x75, 0x9c, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, /* u....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0 /* ...... */ +}; + +static char na_pkt2[78] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x18, 0x3a, 0xff, 0xfe, 0x80, /* ....:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x88, 0x00, /* "..3DV.. */ +0xd1, 0x4e, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, /* .N...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_na_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +UINT num_entries; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 NA Test............................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check whether one router is added. */ + status = nxd_ipv6_default_router_number_of_entries_get(&ip_0, 0, &num_entries); + + /* Check status */ + if(status) + error_counter++; + + if (num_entries != 1) + error_counter++; + + + /* Inject the first NA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &na_pkt1[14], sizeof(na_pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(na_pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the NA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check whether one router is still available. */ + status = nxd_ipv6_default_router_number_of_entries_get(&ip_0, 0, &num_entries); + + /* Check status */ + if(status) + error_counter++; + + if (num_entries != 1) + error_counter++; + + + /* Inject the second NA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &na_pkt2[14], sizeof(na_pkt2) - 14); + packet_ptr -> nx_packet_length = sizeof(na_pkt2) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the NA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check whether no router is available. */ + status = nxd_ipv6_default_router_number_of_entries_get(&ip_0, 0, &num_entries); + + /* Check status */ + if(status) + error_counter++; + + if (num_entries != 0) + error_counter++; + + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_na_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 NA Test............................................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_na_tlla_changed_test.c b/test/regression/netxduo_test/netx_icmpv6_na_tlla_changed_test.c new file mode 100644 index 00000000..3fead71e --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_na_tlla_changed_test.c @@ -0,0 +1,346 @@ +/* Test processing of solicitated RA. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#ifdef FEATURE_NX_IPV6 +#include "nx_nd_cache.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Packet trace from 73 of section 2, TAHI test. */ +/* Frame (70 bytes) */ +static unsigned char pkt1[70] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x10, 0x3a, 0x40, 0xfe, 0x80, /* ....:@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x80, 0x00, /* "..3DV.. */ +0x7a, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, /* z......# */ +0x45, 0x67, 0x89, 0xab, 0xcd, 0xef /* Eg.... */ +}; + +/* Frame (86 bytes) */ +static unsigned char pkt3[86] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, /* ... :... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x88, 0x00, /* "..3DV.. */ +0xad, 0x86, 0x60, 0x00, 0x00, 0x00, 0xfe, 0x80, /* ..`..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x01, 0x00 /* ...... */ +}; + +/* Frame (86 bytes) */ +static unsigned char pkt5[86] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, /* ... :... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x88, 0x00, /* "..3DV.. */ +0xad, 0xe5, 0x20, 0x00, 0x00, 0x00, 0xfe, 0x80, /* .. ..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0xa0, 0x00, 0xa0, 0xa0 /* ...... */ +}; + +/* Packet trace from 125 of section 2, TAHI test. */ +/* Frame (110 bytes) */ +static unsigned char ra_pkt[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0xa0, 0x49, 0x40, 0x00, 0x07, 0x08, 0x00, 0x00, /* .I@..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0xa0, 0xa0, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* :.....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (86 bytes) */ +static unsigned char pkt8[86] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, /* ... :... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x88, 0x00, /* "..3DV.. */ +0x0e, 0x05, 0x20, 0x00, 0x00, 0x00, 0xfe, 0x80, /* .. ..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0xa0, 0xa0, 0xa0 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_na_tlla_changed_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +NXD_ADDRESS router_address; +NX_PACKET *packet_ptr; +UINT interface_index; +ULONG physical_msw; +ULONG physical_lsw; +ND_CACHE_ENTRY + *nd_entry; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 NA TLLA Changed Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x021122FF; + ipv6_address.nxd_ip_address.v6[3] = 0xFE334456; + router_address.nxd_ip_version = NX_IP_VERSION_V6; + router_address.nxd_ip_address.v6[0] = 0xFE800000; + router_address.nxd_ip_address.v6[1] = 0x00000000; + router_address.nxd_ip_address.v6[2] = 0x020000FF; + router_address.nxd_ip_address.v6[3] = 0xFE000100; + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + + /* Inject echo request packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the echo request packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Inject NA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt3[14], sizeof(pkt3) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt3) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the NA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + if (nxd_nd_cache_hardware_address_find(&ip_0, &router_address, &physical_msw, &physical_lsw, &interface_index)) + error_counter++; + else if ((physical_msw != 0x0) || (physical_lsw != 0x100)) + error_counter++; + + + /* Inject NA packet with different TLLA. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt5[14], sizeof(pkt5) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt5) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the NA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + if (nxd_nd_cache_hardware_address_find(&ip_0, &router_address, &physical_msw, &physical_lsw, &interface_index)) + error_counter++; + else if ((physical_msw != 0x00) || (physical_lsw != 0xa000a0a0)) + error_counter++; + + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Find the ND cache and set te status to created. */ + if (_nx_nd_cache_find_entry(&ip_0, router_address.nxd_ip_address.v6, &nd_entry)) + { + printf("ERROR!\n"); + test_control_return(1); + } + nd_entry -> nx_nd_cache_nd_status = ND_CACHE_STATE_CREATED; + + /* Inject NA packet with different TLLA. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt5[14], sizeof(pkt5) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt5) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the NA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Inject NA packet with r bit changed from TRUE to FALSE. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt8[14], sizeof(pkt8) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt8) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the NA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_na_tlla_changed_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 NA TLLA Changed Test...............................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_ns_buffer_overwrite_test.c b/test/regression/netxduo_test/netx_icmpv6_ns_buffer_overwrite_test.c new file mode 100644 index 00000000..d044354b --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_ns_buffer_overwrite_test.c @@ -0,0 +1,367 @@ +/* Test processing of NS with chained packet. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_RX_SIZE_CHECKING) + +#define DEMO_STACK_SIZE 2048 + +#define PACKET_PAYLOAD_SIZE 1508 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* NS packet. */ +static char ns_pkt[] = { +0xc8, 0xd9, 0xd2, 0x23, 0xe4, 0x9a, 0xc8, 0xd9, /* ...#.... */ +0xd2, 0x24, 0x23, 0x53, 0x86, 0xdd, 0x60, 0x00, /* .$#S..`. */ +0x00, 0x00, 0x05, 0xb0, 0x00, 0xff, 0x11, 0x11, /* ........ */ +0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x66, 0x66, 0x66, 0x67, 0x11, 0x11, /* ..fffg.. */ +0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3a, 0xb4, /* ..ffff:. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, /* ........ */ +0x9a, 0xde, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ns_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_PAYLOAD_SIZE, pointer, (sizeof(NX_PACKET) + PACKET_PAYLOAD_SIZE)*16); + pointer = pointer + ((sizeof(NX_PACKET) + PACKET_PAYLOAD_SIZE)*16); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 NS Buffer Overwrite Test..........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0x11111111; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x66666666; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 64, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Inject NS packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(packet_ptr, &ns_pkt[14], sizeof(ns_pkt) - 14, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter++; + + /* Directly receive the NS packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Wait 1s to process this NS packet. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if (nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ns_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 NS Buffer Overwrite Test...........................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_ns_with_small_packet_test.c b/test/regression/netxduo_test/netx_icmpv6_ns_with_small_packet_test.c new file mode 100644 index 00000000..0e2315b1 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_ns_with_small_packet_test.c @@ -0,0 +1,166 @@ +/* This NetX test concentrates on the ICMPV6 NS operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_IPV6_DAD) +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ +static ULONG error_counter; +static ULONG NS_counter; + +/* Define thread prototypes. */ +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ns_with_small_packet_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_IPv6_ICMP_PACKET, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check IP create status. */ + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ICMP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status = 0; +UINT address_index; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 NS With Small Packet Test.........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Hook link driver to check packets. */ + packet_process_callback = packet_process; + + /* Set the IPv6 linklocal address for IP instance 0. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check the NS counter. */ + if(NS_counter != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_ICMPV6_HEADER *header_ptr; + + + /* Points to the ICMP message header. */ + header_ptr = (NX_ICMPV6_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV6_HEADER)); + + /* Determine the message type and call the appropriate handler. */ + if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_NEIGHBOR_SOLICITATION_TYPE) + { + + /* Update the NS counter. */ + NS_counter ++; + } + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ns_with_small_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 NS With Small Packet Test..........................N/A\n"); + + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_ra_address_full_test.c b/test/regression/netxduo_test/netx_icmpv6_ra_address_full_test.c new file mode 100644 index 00000000..60d6d4a5 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_ra_address_full_test.c @@ -0,0 +1,198 @@ +/* Test processing of solicitated RA. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* RA packet. + * destination: 0xfe80::1. + * reachable time: 1ms. + * retrans timer: 1ms. */ +static char ra_pkt[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, 0xfe, 0x80, /* ...0:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x42, 0x73, 0x40, 0x00, 0x07, 0x08, 0x00, 0x00, /* Bs@..... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* :.....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_address_full_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Address Full Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x00000001; + + /* Loop to set the linklocal address. All address entries are used. */ + while (nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 10, &address_index) == NX_SUCCESS) + { + ipv6_address.nxd_ip_address.v6[3]++; + } + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Sleep 5 seconds for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + for (address_index = 0; address_index < NX_MAX_IPV6_ADDRESSES; address_index++) + { + if (nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index)) + { + + /* No more addresses. */ + break; + } + + /* Check the prefix. */ + if (prefix_length == 64) + { + + /* Global address is set though address entries are all used. Error. */ + error_counter++; + break; + } + } + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_address_full_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Address Full Test...............................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_ra_buffer_overwrite_test.c b/test/regression/netxduo_test/netx_icmpv6_ra_buffer_overwrite_test.c new file mode 100644 index 00000000..a81cb1d6 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_ra_buffer_overwrite_test.c @@ -0,0 +1,371 @@ +/* Test processing of too big with chained packet. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) && !defined(NX_DISABLE_RX_SIZE_CHECKING) && !defined(NX_DISABLE_PACKET_CHAIN) + +#define DEMO_STACK_SIZE 2048 + +#define PACKET_PAYLOAD_SIZE 1536 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Packet. */ +static char pkt[] = { +0xc8, 0xd9, 0xd2, 0x23, 0xe4, 0x9a, 0xc8, 0xd9, /* ...#.... */ +0xd2, 0x24, 0x23, 0x53, 0x86, 0xdd, 0x60, 0x00, /* .$#S..`. */ +0x00, 0x00, 0x05, 0xd0, 0x00, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x66, 0x66, 0x66, 0x67, 0xfe, 0x80, /* ..fffg.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3a, 0xb3, /* ..ffff,. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, /* ........ */ +0x4a, 0x7a, 0x40, 0x00, 0x07, 0x08, 0x00, 0x00, /* Bs@..... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* :.....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_PAYLOAD_SIZE, pointer, (sizeof(NX_PACKET) + PACKET_PAYLOAD_SIZE)*16); + pointer = pointer + ((sizeof(NX_PACKET) + PACKET_PAYLOAD_SIZE)*16); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Buffer Overwrite Test..........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x66666666; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 64, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Inject NS packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(packet_ptr, &pkt[14], sizeof(pkt) - 14, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter++; + + /* Directly receive the NS packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Wait 1s to process this NS packet. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if (nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Buffer Overwrite Test...........................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_ra_flag_callback_test.c b/test/regression/netxduo_test/netx_icmpv6_ra_flag_callback_test.c new file mode 100644 index 00000000..55abcd8b --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_ra_flag_callback_test.c @@ -0,0 +1,192 @@ +/* Test ICMPv6 RA flag callback function. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UINT ra_flag_notified; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID icmpv6_ra_flag_callback(NX_IP *ip_ptr, UINT ra_flag); + +/* RA packet with prefix length 128. */ +static char pkt_prefix_128[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, +0xed, 0xeb, 0x40, 0x00, 0x07, 0x0d, 0x00, 0x00, +0x75, 0x35, 0x00, 0x00, 0x03, 0xed, 0x01, 0x01, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x04, +0x80, 0xc0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_flag_callback_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + ra_flag_notified = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Flag Callback Test.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set callback function. */ + nxd_icmpv6_ra_flag_callback_set(&ip_0, icmpv6_ra_flag_callback); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + /* Inject RA with prefix length 128. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_prefix_128[14], sizeof(pkt_prefix_128) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt_prefix_128) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check whether icmpv6_ra_flag_callback is called. */ + if (ra_flag_notified != NX_TRUE) + error_counter++; + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static VOID icmpv6_ra_flag_callback(NX_IP *ip_ptr, UINT ra_flag) +{ + ra_flag_notified = NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_flag_callback_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Flag Callback Test..............................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_ra_invalid_length_test.c b/test/regression/netxduo_test/netx_icmpv6_ra_invalid_length_test.c new file mode 100644 index 00000000..842b74be --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_ra_invalid_length_test.c @@ -0,0 +1,176 @@ +/* Test processing of RA with invalid length. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMP_INFO) && !defined(NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* RA packet. + Invalid length. */ +static char ra_pkt[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x0f, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x02, 0x00, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, +0xf9, 0xf8, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, +0x75, 0x30, 0x00, 0x00, 0x03 +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_invalid_length_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Invalid Length Test............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + if (ip_0.nx_ip_icmp_invalid_packets != 1) + error_counter++; + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_invalid_length_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Invalid Length Test.............................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_ra_lifetime_test.c b/test/regression/netxduo_test/netx_icmpv6_ra_lifetime_test.c new file mode 100644 index 00000000..4aeeddc4 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_ra_lifetime_test.c @@ -0,0 +1,231 @@ +/* Test the lifetime of RA. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* RA packet. + * router lifetime: 5s. + * prefix: 0x2001::/64. */ +static char ra_pkt1[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0xd4, 0x71, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, /* .q...... */ +0x75, 0x30, 0x00, 0x00, 0x03, 0xe8, 0x01, 0x01, /* u0...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, /* :..... . */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* RA packet. + * router lifetime: 6s. + * prefix: 0x2002::/64. */ +static char ra_pkt2[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x02, 0x00, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0xd3, 0x6f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, /* .o...... */ +0x75, 0x30, 0x00, 0x00, 0x03, 0xe8, 0x01, 0x01, /* u0...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, /* :..... . */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_lifetime_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +UINT num_entries; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Lifetime Test..................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt1[14], sizeof(ra_pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt2[14], sizeof(ra_pkt2) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt2) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Check whether two routers are added. */ + status = nxd_ipv6_default_router_number_of_entries_get(&ip_0, 0, &num_entries); + + /* Check status */ + if(status) + error_counter++; + + if (num_entries != 2) + error_counter++; + + + /* Wait until router timeouts. */ + tx_thread_sleep(10 * NX_IP_PERIODIC_RATE); + + + /* Check whether no routers are available. */ + status = nxd_ipv6_default_router_number_of_entries_get(&ip_0, 0, &num_entries); + + /* Check status */ + if(status) + error_counter++; + + if (num_entries != 0) + error_counter++; + + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_lifetime_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Lifetime Test...................................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_ra_router_full_test.c b/test/regression/netxduo_test/netx_icmpv6_ra_router_full_test.c new file mode 100644 index 00000000..dc5b59f0 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_ra_router_full_test.c @@ -0,0 +1,186 @@ +/* Test processing of solicitated RA. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* RA packet. + * destination: 0xfe80::1. + * reachable time: 1ms. + * retrans timer: 1ms. */ +static char ra_pkt[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, 0xfe, 0x80, /* ...0:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x42, 0x73, 0x40, 0x00, 0x07, 0x08, 0x00, 0x00, /* Bs@..... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* :.....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_router_full_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +NXD_ADDRESS router_address; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Address Full Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x00000001; + router_address.nxd_ip_version = NX_IP_VERSION_V6; + router_address.nxd_ip_address.v6[0] = 0xFE800000; + router_address.nxd_ip_address.v6[1] = 0x00000000; + router_address.nxd_ip_address.v6[2] = 0x00000000; + router_address.nxd_ip_address.v6[3] = 0x00000002; + + /* Set the linklocal address. */ + if (nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 10, &address_index)) + error_counter++; + + /* Sleep 5 seconds for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Loop to add router until full. */ + while (nxd_ipv6_default_router_add(&ip_0, &router_address, 3600, 0) == NX_SUCCESS) + { + router_address.nxd_ip_address.v6[3]++; + } + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_router_full_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA Address Full Test...............................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_ra_slla_changed_test.c b/test/regression/netxduo_test/netx_icmpv6_ra_slla_changed_test.c new file mode 100644 index 00000000..d456f368 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_ra_slla_changed_test.c @@ -0,0 +1,253 @@ +/* Test processing of solicitated RA. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Packet trace from 154 of section 2, TAHI test. */ +/* Frame (70 bytes) */ +static unsigned char pkt1[70] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x10, 0x3a, 0x40, 0xfe, 0x80, /* ....:@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x80, 0x00, /* "..3DV.. */ +0xdb, 0x52, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, /* .R.....# */ +0x45, 0x67, 0x89, 0xab, 0xcd, 0xef /* Eg.... */ +}; + +/* Frame (86 bytes) */ +static unsigned char pkt3[86] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, /* ... :... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x88, 0x00, /* "..3DV.. */ +0x4e, 0xa4, 0xe0, 0x00, 0x00, 0x00, 0xfe, 0x80, /* N....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0xa0, 0xa0 /* ...... */ +}; + +/* The MAC address in SLLA is changed to 00:c0:00:00:c0:c0. */ +/* Frame (78 bytes) */ +static unsigned char pkt5[78] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xc0, 0xc0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x18, 0x3a, 0xff, 0xfe, 0x80, /* ....:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0xad, 0x0d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, /* ..@..... */ +0x27, 0x10, 0x00, 0x00, 0x03, 0xe8, 0x01, 0x01, /* '....... */ +0x00, 0xc0, 0x00, 0x00, 0xc0, 0xc0 /* ...... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_slla_changed_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +NXD_ADDRESS router_address; +NX_PACKET *packet_ptr; +UINT interface_index; +ULONG physical_msw; +ULONG physical_lsw; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA SLLA Changed Test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x021122FF; + ipv6_address.nxd_ip_address.v6[3] = 0xFE334456; + router_address.nxd_ip_version = NX_IP_VERSION_V6; + router_address.nxd_ip_address.v6[0] = 0xFE800000; + router_address.nxd_ip_address.v6[1] = 0x00000000; + router_address.nxd_ip_address.v6[2] = 0x020000FF; + router_address.nxd_ip_address.v6[3] = 0xFE00A0A0; + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + + /* Inject echo request packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the echo request packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Inject NA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt3[14], sizeof(pkt3) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt3) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the NA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + if (nxd_nd_cache_hardware_address_find(&ip_0, &router_address, &physical_msw, &physical_lsw, &interface_index)) + error_counter++; + else if ((physical_msw != 0x0) || (physical_lsw != 0xa0a0)) + error_counter++; + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt5[14], sizeof(pkt5) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt5) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + if (nxd_nd_cache_hardware_address_find(&ip_0, &router_address, &physical_msw, &physical_lsw, &interface_index)) + error_counter++; + else if ((physical_msw != 0xc0) || (physical_lsw != 0xc0c0)) + error_counter++; + + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_ra_slla_changed_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 RA SLLA Changed Test...............................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_redirect_buffer_overwrite_test.c b/test/regression/netxduo_test/netx_icmpv6_redirect_buffer_overwrite_test.c new file mode 100644 index 00000000..9fe1a5d6 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_redirect_buffer_overwrite_test.c @@ -0,0 +1,370 @@ +/* Test processing of too big with chained packet. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_REDIRECT_PROCESS) && !defined(NX_DISABLE_RX_SIZE_CHECKING) && !defined(NX_DISABLE_PACKET_CHAIN) + +#define DEMO_STACK_SIZE 2048 + +#define PACKET_PAYLOAD_SIZE 1516 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Packet. */ +static char pkt[] = { +0xc8, 0xd9, 0xd2, 0x23, 0xe4, 0x9a, 0xc8, 0xd9, /* ...#.... */ +0xd2, 0x24, 0x23, 0x53, 0x86, 0xdd, 0x60, 0x00, /* .$#S..`. */ +0x00, 0x00, 0x05, 0xc8, 0x00, 0xff, 0x11, 0x11, /* ........ */ +0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x66, 0x66, 0x66, 0x67, 0x11, 0x11, /* ..fffg.. */ +0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3a, 0xb3, /* ..ffff,. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, /* ........ */ +0x98, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_redirect_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_PAYLOAD_SIZE, pointer, (sizeof(NX_PACKET) + PACKET_PAYLOAD_SIZE)*16); + pointer = pointer + ((sizeof(NX_PACKET) + PACKET_PAYLOAD_SIZE)*16); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Redirect Buffer Overwrite Test....................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0x11111111; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x66666666; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 64, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Inject NS packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(packet_ptr, &pkt[14], sizeof(pkt) - 14, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter++; + + /* Directly receive the NS packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Wait 1s to process this NS packet. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if (nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_redirect_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Redirect Buffer Overwrite Test.....................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_redirect_nd_full_test.c b/test/regression/netxduo_test/netx_icmpv6_redirect_nd_full_test.c new file mode 100644 index 00000000..53ce9e44 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_redirect_nd_full_test.c @@ -0,0 +1,283 @@ +/* Test processing of REDIRECT message when ND cache is full. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMP_INFO) && !defined(NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* RA packet with SLLA and PREFIX options. */ +static char ra_pkt[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0xa0, 0x49, 0x40, 0x00, 0x07, 0x08, 0x00, 0x00, /* .I@..... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0xa0, 0xa0, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* :.....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Redirect packet */ +static char redirect_pkt[94] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x28, 0x3a, 0xff, 0xfe, 0x80, /* ...(:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x89, 0x00, /* "..3DV.. */ +0x9a, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00 /* ...... */ +}; + +/* Redirect packet */ +static char redirect_tlla_pkt[102] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, 0xfe, 0x80, /* ...0:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x89, 0x00, /* "..3DV.. */ +0x9d, 0x15, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa1, 0xa1, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 /* ...... */ +}; + +/* Redirect packet with TLLA changed */ +static char redirect_tlla_changed_pkt[102] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, 0xfe, 0x80, /* ...0:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x89, 0x00, /* "..3DV.. */ +0x9e, 0x15, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x02, 0x01, /* ........ */ +0x00, 0x01, 0x00, 0x00, 0xa1, 0xa1 /* ...... */ +}; + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_redirect_nd_full_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +ULONG address[4] = {0xfe800000, 0, 0, 1}; +CHAR mac[6] = {0, 0, 0, 0, 0, 1}; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Redirect ND Full Test.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Sleep 5 seconds for global address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + + /* Inject REDIRECT packet with TLLA changed. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &redirect_tlla_changed_pkt[14], sizeof(redirect_tlla_changed_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(redirect_tlla_changed_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the REDIRECT packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Occupy all ND caches. */ + while (nxd_nd_cache_entry_set(&ip_0, address, 0, mac) == NX_SUCCESS) + { + address[3]++; + mac[5]++; + } + + /* Inject REDIRECT packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &redirect_pkt[14], sizeof(redirect_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(redirect_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the REDIRECT packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Inject REDIRECT packet with TLLA option. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &redirect_tlla_pkt[14], sizeof(redirect_tlla_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(redirect_tlla_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the REDIRECT packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Verify the redirect message is dropped. */ + if (ip_0.nx_ip_icmp_invalid_packets != 2) + error_counter++; + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_redirect_nd_full_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Redirect ND Full Test..............................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_redirect_test.c b/test/regression/netxduo_test/netx_icmpv6_redirect_test.c new file mode 100644 index 00000000..73c45294 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_redirect_test.c @@ -0,0 +1,540 @@ +/* This NetX test to test the ICMPv6 Echo request process. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_REDIRECT_PROCESS) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_ram_network_driver_test_1500.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG echo_request_sent; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* ICMPv6 redirect to 3ffe:501:ffff::200:ff:fe00:100. */ +static const unsigned char pkt1[] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x89, 0x00, +0x97, 0xda, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x02, 0x01, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00 }; + + +/* ICMPv6 redirect to 3ffe:501:ffff::300:ff:fe00:100. */ +static const unsigned char pkt2[102] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, 0xfe, 0x80, /* ...0:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x89, 0x00, /* "..3DV.. */ +0x95, 0xda, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x00, 0x00, 0x03, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x00, 0x00, 0x03, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x01, 0x00 /* ...... */ +}; + + +/* ICMPv6 redirect to 3ffe:501:ffff::200:ff:fe00:100. + * MTU in MTU option is 1484 */ +static const unsigned char pkt3[110] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x89, 0x00, /* "..3DV.. */ +0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, /* .0...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa1, 0xa1, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x05, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x05, 0xcc, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 /* ...... */ +}; + + +/* ICMPv6 redirect to 3ffe:501:ffff::200:ff:fe00:100. + * MTU in MTU option is 1244 */ +static const unsigned char pkt4[110] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x89, 0x00, /* "..3DV.. */ +0x92, 0x32, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, /* .0...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa1, 0xa1, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x05, 0xff, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 /* ...... */ +}; + +/* ICMPv6 redirect to 3ffe:501:ffff::200:ff:fe00:100. + * MTU in MTU option is 1200, less than NX_MINIMUM_IPV6_PATH_MTU */ +static const unsigned char pkt5[110] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x89, 0x00, /* "..3DV.. */ +0x93, 0x5c, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, /* .0...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa1, 0xa1, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x05, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x04, 0xb0, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0xa1, 0xa1 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_redirect_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + echo_request_sent = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*4); + pointer = pointer + 1536*4; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check IP create status. */ + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ICMP enable status. */ + if(status) + error_counter++; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +NXD_ADDRESS src, dst, dst_2, router; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Redirect Test......................................"); + + /* Setup address. */ + src.nxd_ip_version = NX_IP_VERSION_V6; + src.nxd_ip_address.v6[0] = 0x3ffe0501; + src.nxd_ip_address.v6[1] = 0xffff0100; + src.nxd_ip_address.v6[2] = 0x021122ff; + src.nxd_ip_address.v6[3] = 0xfe334456; + + dst.nxd_ip_version = NX_IP_VERSION_V6; + dst.nxd_ip_address.v6[0] = 0x3ffe0501; + dst.nxd_ip_address.v6[1] = 0xffff0000; + dst.nxd_ip_address.v6[2] = 0x020000ff; + dst.nxd_ip_address.v6[3] = 0xfe000100; + + dst_2.nxd_ip_version = NX_IP_VERSION_V6; + dst_2.nxd_ip_address.v6[0] = 0x3ffe0501; + dst_2.nxd_ip_address.v6[1] = 0xffff0000; + dst_2.nxd_ip_address.v6[2] = 0x030000ff; + dst_2.nxd_ip_address.v6[3] = 0xfe000100; + + router.nxd_ip_version = NX_IP_VERSION_V6; + router.nxd_ip_address.v6[0] = 0xfe800000; + router.nxd_ip_address.v6[1] = 0x00000000; + router.nxd_ip_address.v6[2] = 0x020000ff; + router.nxd_ip_address.v6[3] = 0xfe00a0a0; + + /* Set the linklocal address*/ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + status += nxd_ipv6_address_set(&ip_0, 0, &src, 64, NX_NULL); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Send ICMP redirect packet to ip_0. */ + /* The redirect destination is 0x3ffe:501:ffff:0:200:ff:fe00:100. */ + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMP redirect packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Since this message is not sent from router(no router yet). It should not be added into destination table. */ + if (ip_0.nx_ipv6_destination_table_size != 0) + { + error_counter++; + } + + /* Set router. */ + nxd_ipv6_default_router_add(&ip_0, &router, 60, 0); + + /* Send ICMP redirect packet to ip_0. */ + /* The redirect destination is 0x3ffe:501:ffff:0:200:ff:fe00:100. */ + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMP redirect packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check the destination table. */ + if ((ip_0.nx_ipv6_destination_table_size != 1) || (ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_valid != NX_TRUE)) + { + error_counter++; + } + + + /* Now move this desitnation table entry from the first one to the second one. */ + memcpy(&ip_0.nx_ipv6_destination_table[1], &ip_0.nx_ipv6_destination_table[0], sizeof(ip_0.nx_ipv6_destination_table[0])); + ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_valid = NX_FALSE; + + + /* Send ICMP redirect packet to ip_0. */ + /* The redirect destination is 0x3ffe:501:ffff:0:200:ff:fe00:100. */ + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMP redirect packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check the destination table. */ + if ((ip_0.nx_ipv6_destination_table_size != 1) || (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_valid != NX_TRUE)) + { + error_counter++; + } + + /* Setup filter function to check whether echo request is sent. */ + advanced_packet_process_callback = my_packet_process; + status = nxd_icmp_ping(&ip_0, &dst, "", 0, &packet_ptr, NX_NO_WAIT); + + if ((status == NX_SUCCESS) || (echo_request_sent != 1)) + { + error_counter++; + } + + + /* Occupy all destination tables. */ + for (i = 0; i < NX_IPV6_DESTINATION_TABLE_SIZE; i++) + { + if (i != 1) + { + memcpy(&ip_0.nx_ipv6_destination_table[i], &ip_0.nx_ipv6_destination_table[1], sizeof(ip_0.nx_ipv6_destination_table[i])); + ip_0.nx_ipv6_destination_table_size++; + } + } + + /* The redirect destination is 0x3ffe:501:ffff:0:300:ff:fe00:100. */ + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt2) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMP redirect packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Release destination tables occpied before. */ + for (i = 0; i < NX_IPV6_DESTINATION_TABLE_SIZE; i++) + { + if (i != 1) + { + ip_0.nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid = NX_FALSE; + ip_0.nx_ipv6_destination_table_size--; + } + } + + + /* Send ICMP redirect packet to ip_0. */ + /* The redirect destination is 0x3ffe:501:ffff:0:300:ff:fe00:100. */ + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt2) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMP redirect packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check the destination table. */ + if (ip_0.nx_ipv6_destination_table_size != 2) + { + error_counter++; + } + + /* Setup filter function to check whether echo request is sent. */ + advanced_packet_process_callback = my_packet_process; + status = nxd_icmp_ping(&ip_0, &dst_2, "", 0, &packet_ptr, NX_NO_WAIT); + + if ((status == NX_SUCCESS) || (echo_request_sent != 2)) + { + error_counter++; + } + + + /* Remove destination entry for 0x3ffe:501:ffff:0:200:ff:fe00:100*/ + ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_valid = NX_FALSE; + ip_0.nx_ipv6_destination_table_size--; + + /* The redirect destination is 0x3ffe:501:ffff:0:200:ff:fe00:100. */ + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt3[14], sizeof(pkt3) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt3) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMP redirect packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check the destination table. */ + if (ip_0.nx_ipv6_destination_table_size != 2) + { + error_counter++; + } + +#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY + if (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_path_mtu != 1484) + { + error_counter++; + } +#endif /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */ + + + /* Remove destination entry for 0x3ffe:501:ffff:0:200:ff:fe00:100*/ + ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_valid = NX_FALSE; + ip_0.nx_ipv6_destination_table_size--; + + /* The redirect destination is 0x3ffe:501:ffff:0:200:ff:fe00:100. */ + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt4[14], sizeof(pkt4) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt4) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMP redirect packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check the destination table. The option length is invalid, so the destination table is not updated. */ + if (ip_0.nx_ipv6_destination_table_size != 1) + { + error_counter++; + } + + /* The redirect destination is 0x3ffe:501:ffff:0:200:ff:fe00:100. */ + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_RECEIVE_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt5[14], sizeof(pkt5) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt5) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the ICMP redirect packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check the destination table. */ + if (ip_0.nx_ipv6_destination_table_size != 2) + { + error_counter++; + } + +#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY + if (ip_0.nx_ipv6_destination_table[1].nx_ipv6_destination_entry_path_mtu != 1200) + { + error_counter++; + } +#endif /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */ + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Out successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +UCHAR *data = packet_ptr -> nx_packet_prepend_ptr; + + /* Check whether it is an echo request packet. */ + if (packet_ptr -> nx_packet_length == 48) + { + + /* Is it ICMPv6 packet? */ + if (data[6] == 0x3A) + { + /* Is the ICMPv6 type echo request? */ + if (data[40] == 0x80) + { + + /* It is echo request packet. */ + echo_request_sent++; + advanced_packet_process_callback = NX_NULL; + } + } + } + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_redirect_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Redirect Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_icmpv6_router_solicitation_test.c b/test/regression/netxduo_test/netx_icmpv6_router_solicitation_test.c new file mode 100644 index 00000000..922fe31d --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_router_solicitation_test.c @@ -0,0 +1,211 @@ +/* Test ICMPv6 Router Solicitation for _nx_packet_allocate failure in _nx_icmpv6_send.rs. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_SOLICITATION) + +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rs_counter; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_router_solicitation_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + rs_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Router Solicitation Test..........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to process the RS packet. */ + advanced_packet_process_callback = my_packet_process; + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the Router */ + if (ip_0.nx_ip_interface[0].nx_ipv6_rtr_solicitation_count != 3) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for linklocal address DAD and (NX_ICMPV6_RTR_SOLICITATION_INTERVAL*3) for Router Solicitation. */ + tx_thread_sleep((5 + (NX_ICMPV6_RTR_SOLICITATION_INTERVAL * 3)) * NX_IP_PERIODIC_RATE); + + /* Check the Router Solicitation count. */ + if (ip_0.nx_ip_interface[0].nx_ipv6_rtr_solicitation_count != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the error. */ + if((error_counter) ||(rs_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +UINT i; +UINT packet_counter; +NX_ICMPV6_HEADER *header_ptr; +NX_PACKET *tmp_packet[16]; + + + /* Points to the ICMP message header. */ + header_ptr = (NX_ICMPV6_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV6_HEADER)); + + /* Determine the message type and call the appropriate handler. */ + if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_ROUTER_SOLICITATION_TYPE) + { + + /* Update the RS counter. */ + rs_counter ++; + } + + /* Check the rs_counter, allocate all packets to let ip_0 send RS failure. */ + if (rs_counter == 1) + { + + /* Release the RS packet. */ + nx_packet_release(packet_ptr); + + /* Get the available packet. */ + packet_counter = pool_0.nx_packet_pool_available; + + /* Loop to allocate the all packets from pool_0. */ + for (i = 0; i < packet_counter; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &tmp_packet[i], NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check the status. */ + if (status) + error_counter++; + } + } + + return NX_FALSE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_router_solicitation_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Router Solicitation Test...........................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_solicitated_ra_test.c b/test/regression/netxduo_test/netx_icmpv6_solicitated_ra_test.c new file mode 100644 index 00000000..def43b1d --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_solicitated_ra_test.c @@ -0,0 +1,196 @@ +/* Test processing of solicitated RA. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* RA packet. + * destination: 0xfe80::1. + * reachable time: 1ms. + * retrans timer: 1ms. */ +static char ra_pkt[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x30, 0x3a, 0xff, 0xfe, 0x80, /* ...0:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x42, 0x73, 0x40, 0x00, 0x07, 0x08, 0x00, 0x00, /* Bs@..... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* :.....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_solicitated_ra_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Solicitated RA Test................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x00000001; + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Sleep 5 seconds for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index + 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 64) || (interface_index != 0)) + error_counter++; + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_solicitated_ra_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Solicitated RA Test................................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_icmpv6_too_big_buffer_overwrite_test.c b/test/regression/netxduo_test/netx_icmpv6_too_big_buffer_overwrite_test.c new file mode 100644 index 00000000..7a5cc0d4 --- /dev/null +++ b/test/regression/netxduo_test/netx_icmpv6_too_big_buffer_overwrite_test.c @@ -0,0 +1,367 @@ +/* Test processing of too big with chained packet. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) && !defined(NX_DISABLE_RX_SIZE_CHECKING) + +#define DEMO_STACK_SIZE 2048 + +#define PACKET_PAYLOAD_SIZE 1536 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Packet. */ +static char pkt[] = { +0xc8, 0xd9, 0xd2, 0x23, 0xe4, 0x9a, 0xc8, 0xd9, /* ...#.... */ +0xd2, 0x24, 0x23, 0x53, 0x86, 0xdd, 0x60, 0x00, /* .$#S..`. */ +0x00, 0x00, 0x05, 0xb0, 0x00, 0xff, 0x11, 0x11, /* ........ */ +0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x66, 0x66, 0x66, 0x67, 0x11, 0x11, /* ..fffg.. */ +0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3a, 0xb3, /* ..ffff:. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x1f, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_too_big_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_PAYLOAD_SIZE, pointer, (sizeof(NX_PACKET) + PACKET_PAYLOAD_SIZE)*16); + pointer = pointer + ((sizeof(NX_PACKET) + PACKET_PAYLOAD_SIZE)*16); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Too Big Buffer Overwrite Test......................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0x11111111; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x66666666; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 64, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Inject NS packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(packet_ptr, &pkt[14], sizeof(pkt) - 14, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter++; + + /* Directly receive the NS packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Wait 1s to process this NS packet. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if (nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_icmpv6_too_big_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ICMPv6 Too Big Buffer Overwrite Test......................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_igmp_basic_test.c b/test/regression/netxduo_test/netx_igmp_basic_test.c new file mode 100644 index 00000000..a948df93 --- /dev/null +++ b/test/regression/netxduo_test/netx_igmp_basic_test.c @@ -0,0 +1,219 @@ +/* This NetX test concentrates on the basic IGMP operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IGMP_INFO) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable IGMP processing for both this IP instance. */ + status = nx_igmp_enable(&ip_0); + + /* Check enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG igmp_reports_sent; +ULONG igmp_queries_received; +ULONG igmp_checksum_errors; +ULONG current_groups_joined; + + + /* Print out test information banner. */ + printf("NetX Test: IGMP Basic Operation Test................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Perform 7 IGMP join operations. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,1)); + status += nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,2)); + status += nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,3)); + status += nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,5)); + status += nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,6)); + status += nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,7)); + + /* Join one group another 4 times to test the counting operation. */ + status += nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,4)); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call the IGMP information get routine to see if all the groups are there. */ + status = nx_igmp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL); + + /* Check for status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + /* Check for status. */ + if ((status) || (igmp_reports_sent) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 7)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the periodic event to test igmp_periodic_processing. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Attempt to join a new group. This should result in an error. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,8)); + + /* Determine if an error has occurred. */ + if (status != NX_NO_MORE_ENTRIES) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now leave all the groups to make sure that processing works properly. */ + status = nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,1)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,2)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,3)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,5)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,6)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,7)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call the IGMP information get routine to see if all the groups are there. */ + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + /* Check for status. */ + if ((status) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_basic_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IGMP Basic Operation Test.................................N/A\n"); + test_control_return(3); + +} +#endif /* NX_DISABLE_IGMP_INFO */ diff --git a/test/regression/netxduo_test/netx_igmp_branch_test.c b/test/regression/netxduo_test/netx_igmp_branch_test.c new file mode 100644 index 00000000..6b930e5b --- /dev/null +++ b/test/regression/netxduo_test/netx_igmp_branch_test.c @@ -0,0 +1,516 @@ +/* This NetX test concentrates on the code coverage for IGMP functions, + * _nx_igmp_packet_receive + *_nx_igmp_multicast_check + *_nx_igmp_multicast_interface_join_internal + *_nx_igmp_multicast_interface_leave_internal + *_nx_igmp_periodic_processing + *_nx_igmp_packet_process + */ + +#include "nx_api.h" +#include "tx_thread.h" +#include "tx_timer.h" +#include "nx_igmp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_branch_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable IGMP processing for IP instance. */ + status = nx_igmp_enable(&ip_0); + + /* Check IGMP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG system_state; +NX_PACKET *my_packet[2]; +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_ENABLE_INTERFACE_CAPABILITY) +UINT packet_available; +#endif + + + /* Print out some test information banners. */ + printf("NetX Test: IGMP Branch Test.........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Hit condition of if ((_tx_thread_system_state) || (&(ip_ptr -> nx_ip_thread) != _tx_thread_current_ptr)) in _nx_igmp_packet_receive(). */ + tx_mutex_get(&(ip_0.nx_ip_protection), TX_WAIT_FOREVER); + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + nx_packet_data_append(my_packet[0], "abcdefghijklmnopqrstuvwxyz", 26, &pool_0, NX_NO_WAIT); + + system_state = _tx_thread_system_state; + _tx_thread_system_state = 0; + + _nx_igmp_packet_receive(&ip_0, my_packet[0]); + ip_0.nx_ip_igmp_queue_head = NX_NULL; + + _tx_thread_system_state = system_state; + nx_packet_release(my_packet[0]); + + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + nx_packet_data_append(my_packet[0], "abcdefghijklmnopqrstuvwxyz", 26, &pool_0, NX_NO_WAIT); + system_state = _tx_thread_system_state; + _tx_thread_system_state = 1; + + _nx_igmp_packet_receive(&ip_0, my_packet[0]); + ip_0.nx_ip_igmp_queue_head = NX_NULL; + + _tx_thread_system_state = system_state; + nx_packet_release(my_packet[0]); + tx_mutex_put(&(ip_0.nx_ip_protection)); + + + + /* Hit condition of if ((ip_ptr -> nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_list == group) && (nx_interface == ip_ptr -> nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_interface_list)) in _nx_igmp_multicast_check(). */ + nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224, 0, 0, 2)); + _nx_igmp_multicast_check(&ip_0, IP_ADDRESS(224, 0, 0, 2), &ip_0.nx_ip_interface[0]); + _nx_igmp_multicast_check(&ip_0, IP_ADDRESS(224, 0, 0, 2), NX_NULL); + nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224, 0, 0, 2)); + + + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_ENABLE_INTERFACE_CAPABILITY) + /* Hit condition of if ((ip_ptr -> nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_list == group) && (nx_interface == ip_ptr -> nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_interface_list)) in _nx_igmp_multicast_interface_join_internal(). */ + /* Attach the 2nd interface to IP instance0 */ + nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver_256); + nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224, 0, 0, 2), 0); + _nx_igmp_multicast_interface_join_internal(&ip_0, IP_ADDRESS(224, 0, 0, 2), 0, NX_FALSE); + _nx_igmp_multicast_interface_join_internal(&ip_0, IP_ADDRESS(224, 0, 0, 2), 1, NX_FALSE); + _nx_igmp_multicast_interface_join_internal(&ip_0, IP_ADDRESS(224, 0, 0, 3), 1, NX_FALSE); + _nx_igmp_multicast_interface_join_internal(&ip_0, IP_ADDRESS(224, 0, 0, 3), 0, NX_FALSE); + nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224, 0, 0, 2)); + nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224, 0, 0, 3)); + nx_ip_interface_detach(&ip_0, 1); + + + + /* Test _nx_igmp_multicast_interface_leave_internal */ + /* Hit false condition of if (status == NX_SUCCESS) for _nx_packet_allocate.*/ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 2); + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list = &ip_0.nx_ip_interface[0]; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_count = 1; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_update_time = 1; + + /* Record the packet available count. */ + packet_available = pool_0.nx_packet_pool_available; + + /* Set the packet available count as 0. */ + pool_0.nx_packet_pool_available = 0; + + /* Call function. */ + _nx_igmp_multicast_interface_leave_internal(&ip_0, IP_ADDRESS(224, 0, 0, 2), 0); + + /* Recover the packet available count. */ + pool_0.nx_packet_pool_available = packet_available; + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + + + + /* Test _nx_igmp_multicast_interface_leave_internal + 173 [ - + ]: 42 : if (ip_ptr -> nx_ip_igmp_router_version == NX_IGMP_HOST_VERSION_1) + 174 : : { + 177 : 0 : tx_mutex_put(&(ip_ptr -> nx_ip_protection)); + 180 : 0 : return(NX_SUCCESS); + 181 : : } + */ + ip_0.nx_ip_igmp_router_version = NX_IGMP_HOST_VERSION_1; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 2); + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list = &ip_0.nx_ip_interface[0]; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_count = 1; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_update_time = 1; + + /* Call function. */ + _nx_igmp_multicast_interface_leave_internal(&ip_0, IP_ADDRESS(224, 0, 0, 2), 0); + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + + /* Revert the IGMP version */ + ip_0.nx_ip_igmp_router_version = NX_IGMP_HOST_VERSION_2; + + + + /* Test _nx_igmp_periodic_processing(). */ + + /* Hit false condition of (ip_ptr -> nx_ipv4_multicast_entry[i].nx_ipv4_multicast_update_time != NX_WAIT_FOREVER). */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 2); + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_update_time = NX_WAIT_FOREVER; + _nx_igmp_periodic_processing(&ip_0); + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + + + /* Hit false condition of if ((sent_count > 0) && (ip_ptr -> nx_ipv4_multicast_entry[i].nx_ipv4_multicast_update_time == 0)). */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list = &ip_0.nx_ip_interface[0]; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 2); + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_update_time = 1; + ip_0.nx_ipv4_multicast_entry[1].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 3); + ip_0.nx_ipv4_multicast_entry[1].nx_ipv4_multicast_update_time = 2; + _nx_igmp_periodic_processing(&ip_0); + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + ip_0.nx_ipv4_multicast_entry[1].nx_ipv4_multicast_join_list = 0; + + + /* Hit false condition of if ((ip_ptr -> nx_ipv4_multicast_entry[i].nx_ipv4_multicast_update_time == 0) && (sent_count == 0)). */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 2); + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_update_time = 1; + ip_0.nx_ipv4_multicast_entry[1].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 3); + ip_0.nx_ipv4_multicast_entry[1].nx_ipv4_multicast_update_time = 1; + _nx_igmp_periodic_processing(&ip_0); + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + ip_0.nx_ipv4_multicast_entry[1].nx_ipv4_multicast_join_list = 0; + + + /* Hit false condition of if (status == NX_SUCCESS) for _nx_packet_allocate. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 2); + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list = &ip_0.nx_ip_interface[0]; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_update_time = 1; + + /* Record the packet available count. */ + packet_available = pool_0.nx_packet_pool_available; + + /* Set the packet available count as 0. */ + pool_0.nx_packet_pool_available = 0; + + /* Call function. */ + _nx_igmp_periodic_processing(&ip_0); + + /* Recover the packet available count. */ + pool_0.nx_packet_pool_available = packet_available; + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + + + + /* Test _nx_igmp_packet_process(). */ + + /* Hit false condition of if (packet_ptr -> nx_packet_last) and if (checksum & NX_CARRY_BIT). */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_prepend_ptr[0] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[1] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[2] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[3] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[4] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[5] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[6] = 0xFF; + my_packet[0] -> nx_packet_prepend_ptr[7] = 0xFF; + my_packet[0] -> nx_packet_prepend_ptr[8] = 0x2; + my_packet[0] -> nx_packet_length = 9; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + my_packet[0] -> nx_packet_length; + _nx_igmp_packet_process(&ip_0, my_packet[0]); + +#ifndef NX_DISABLE_PACKET_CHAIN + /* Hit true condition + * 172 [ - + ]: 6 : if (packet_ptr -> nx_packet_last) */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_prepend_ptr[0] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[1] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[2] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[3] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[4] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[5] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[6] = 0xFF; + my_packet[0] -> nx_packet_prepend_ptr[7] = 0xFF; + my_packet[0] -> nx_packet_prepend_ptr[8] = 0x2; + my_packet[0] -> nx_packet_length = 9; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + my_packet[0] -> nx_packet_length; + my_packet[0] -> nx_packet_last = my_packet[0]; + _nx_igmp_packet_process(&ip_0, my_packet[0]); +#endif /* NX_DISABLE_PACKET_CHAIN */ + + /* Hit false condition of if ((update_time > max_update_time) || (update_time == 0)). */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_prepend_ptr[0] = 0x01; + my_packet[0] -> nx_packet_prepend_ptr[1] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[2] = 0x1E; + my_packet[0] -> nx_packet_prepend_ptr[3] = 0x04; + my_packet[0] -> nx_packet_prepend_ptr[4] = 0xE0; + my_packet[0] -> nx_packet_prepend_ptr[5] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[6] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[7] = 0xFB; + my_packet[0] -> nx_packet_length = 8; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + my_packet[0] -> nx_packet_length; + _tx_timer_system_clock = 1; + _nx_igmp_packet_process(&ip_0, my_packet[0]); + + /* Hit false condition of if ((update_time > max_update_time) || (update_time == 0)). */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_prepend_ptr[0] = 0x01; + my_packet[0] -> nx_packet_prepend_ptr[1] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[2] = 0x1E; + my_packet[0] -> nx_packet_prepend_ptr[3] = 0x04; + my_packet[0] -> nx_packet_prepend_ptr[4] = 0xE0; + my_packet[0] -> nx_packet_prepend_ptr[5] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[6] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[7] = 0xFB; + my_packet[0] -> nx_packet_length = 8; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + my_packet[0] -> nx_packet_length; + _tx_timer_system_clock = 0; + _nx_igmp_packet_process(&ip_0, my_packet[0]); + + /* Hit false condition of (header_ptr -> nx_igmp_header_word_1 != NX_NULL)) and (ip_ptr -> nx_ipv4_multicast_entry[i].nx_ipv4_multicast_update_time == NX_WAIT_FOREVER). */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_prepend_ptr[0] = 0x01; + my_packet[0] -> nx_packet_prepend_ptr[1] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[2] = 0xFE; + my_packet[0] -> nx_packet_prepend_ptr[3] = 0xFF; + my_packet[0] -> nx_packet_prepend_ptr[4] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[5] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[6] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[7] = 0x00; + my_packet[0] -> nx_packet_length = 8; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + my_packet[0] -> nx_packet_length; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 251); + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list = &ip_0.nx_ip_interface[0]; + _nx_igmp_packet_process(&ip_0, my_packet[0]); + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + + /* Hit true condition of (header_ptr -> nx_igmp_header_word_1 != NX_NULL)) and (ip_ptr -> nx_ipv4_multicast_entry[i].nx_ipv4_multicast_update_time == NX_WAIT_FOREVER). */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_prepend_ptr[0] = 0x01; + my_packet[0] -> nx_packet_prepend_ptr[1] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[2] = 0xFE; + my_packet[0] -> nx_packet_prepend_ptr[3] = 0xFF; + my_packet[0] -> nx_packet_prepend_ptr[4] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[5] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[6] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[7] = 0x00; + my_packet[0] -> nx_packet_length = 8; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + my_packet[0] -> nx_packet_length; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 251); + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_update_time = NX_WAIT_FOREVER; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list = &ip_0.nx_ip_interface[0]; + _nx_igmp_packet_process(&ip_0, my_packet[0]); + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + + /* Hit false condition of (header_ptr -> nx_igmp_header_word_0 & NX_IGMP_TYPE_MASK) == NX_IGMP_HOST_RESPONSE_TYPE). */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_prepend_ptr[0] = 0x17; + my_packet[0] -> nx_packet_prepend_ptr[1] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[2] = 0x08; + my_packet[0] -> nx_packet_prepend_ptr[3] = 0x04; + my_packet[0] -> nx_packet_prepend_ptr[4] = 0xE0; + my_packet[0] -> nx_packet_prepend_ptr[5] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[6] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[7] = 0xFB; + my_packet[0] -> nx_packet_length = 8; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + my_packet[0] -> nx_packet_length; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 251); + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list = &ip_0.nx_ip_interface[0]; + _nx_igmp_packet_process(&ip_0, my_packet[0]); + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + + + /* Hit false condition of for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++) */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_prepend_ptr[0] = 0x16; + my_packet[0] -> nx_packet_prepend_ptr[1] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[2] = 0x09; + my_packet[0] -> nx_packet_prepend_ptr[3] = 0x04; + my_packet[0] -> nx_packet_prepend_ptr[4] = 0xE0; + my_packet[0] -> nx_packet_prepend_ptr[5] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[6] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[7] = 0xFB; + my_packet[0] -> nx_packet_length = 8; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + my_packet[0] -> nx_packet_length; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list = &ip_0.nx_ip_interface[0]; + _nx_igmp_packet_process(&ip_0, my_packet[0]); + + /* Hit false condition of for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++) */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_prepend_ptr[0] = 0x16; + my_packet[0] -> nx_packet_prepend_ptr[1] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[2] = 0x09; + my_packet[0] -> nx_packet_prepend_ptr[3] = 0x04; + my_packet[0] -> nx_packet_prepend_ptr[4] = 0xE0; + my_packet[0] -> nx_packet_prepend_ptr[5] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[6] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[7] = 0xFB; + my_packet[0] -> nx_packet_length = 8; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + my_packet[0] -> nx_packet_length; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 251);; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list = &ip_0.nx_ip_interface[0]; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_update_time = NX_WAIT_FOREVER; + _nx_igmp_packet_process(&ip_0, my_packet[0]); + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + + /* Hit false condition : + else if (((header_ptr -> nx_igmp_header_word_0 & NX_IGMP_TYPE_MASK) == NX_IGMP_HOST_RESPONSE_TYPE) + */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_prepend_ptr[0] = 0x14; + my_packet[0] -> nx_packet_prepend_ptr[1] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[2] = 0x0b; + my_packet[0] -> nx_packet_prepend_ptr[3] = 0x04; + my_packet[0] -> nx_packet_prepend_ptr[4] = 0xE0; + my_packet[0] -> nx_packet_prepend_ptr[5] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[6] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[7] = 0xFB; + my_packet[0] -> nx_packet_length = 8; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + my_packet[0] -> nx_packet_length; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 251);; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list = &ip_0.nx_ip_interface[0]; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_update_time = NX_WAIT_FOREVER; + _nx_igmp_packet_process(&ip_0, my_packet[0]); + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; + + /* Hit false condition : + else if (((header_ptr -> nx_igmp_header_word_0 & NX_IGMP_TYPE_MASK) == NX_IGMP_HOST_RESPONSE_TYPE) + */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_prepend_ptr[0] = 0x12; + my_packet[0] -> nx_packet_prepend_ptr[1] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[2] = 0x0d; + my_packet[0] -> nx_packet_prepend_ptr[3] = 0x04; + my_packet[0] -> nx_packet_prepend_ptr[4] = 0xE0; + my_packet[0] -> nx_packet_prepend_ptr[5] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[6] = 0x00; + my_packet[0] -> nx_packet_prepend_ptr[7] = 0xFB; + my_packet[0] -> nx_packet_length = 8; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + my_packet[0] -> nx_packet_length; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = IP_ADDRESS(224, 0, 0, 251);; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list = &ip_0.nx_ip_interface[0]; + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_update_time = NX_WAIT_FOREVER; + _nx_igmp_packet_process(&ip_0, my_packet[0]); + + /* Recover the multicast. */ + ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list = 0; +#endif /* __PRODUCT_NETXDUO__ */ + + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_branch_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IGMP Branch Test..........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_igmp_checksum_computation_test.c b/test/regression/netxduo_test/netx_igmp_checksum_computation_test.c new file mode 100644 index 00000000..63752cc3 --- /dev/null +++ b/test/regression/netxduo_test/netx_igmp_checksum_computation_test.c @@ -0,0 +1,373 @@ +/* This NetX test case verifies that the IGMP packet data is included in the checksum, not just the header, + and that it handles 2 byte data when there is zero length left. Also it must handled chained + packets. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_igmp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +#define DATA_SIZE 762 +#define PACKET_PAYLOAD 600 + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void igmp_checksum_compute(NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_checksum_computation_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_PAYLOAD, pointer, PACKET_PAYLOAD*6); + pointer = pointer + PACKET_PAYLOAD*6; + + if(status) + error_counter++; + + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable IGMP processing for both IP instances. */ + status = nx_igmp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: IGMP Checksum Computation Test............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Point to new receive function */ + advanced_packet_process_callback = my_packet_process; + + /* Perform IGMP join operations for IP instance0. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,1)); + + /* Determine if there is an error. */ + if (status) + { + error_counter++; + } + + return; +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_IGMP_HEADER *header_ptr; +NX_PACKET *my_packet; +UINT status; +UCHAR buffer[DATA_SIZE]; + + +#ifndef NX_DISABLE_IGMPV2 + /* Check the version. */ + if (ip_ptr -> nx_ip_igmp_router_version == NX_IGMP_HOST_VERSION_2) + { + /* Setup a pointer to the IGMP packet header. */ + header_ptr = (NX_IGMP_HEADER *) (packet_ptr -> nx_packet_prepend_ptr + 24); + } + else + { + + /* Setup a pointer to the IGMP packet header. */ + header_ptr = (NX_IGMP_HEADER *) (packet_ptr -> nx_packet_prepend_ptr + 20); + } +#else + header_ptr = (NX_IGMP_HEADER *) (packet_ptr -> nx_packet_prepend_ptr + 20); +#endif + + /* Do byte swapping for little endian processors before parsing + IGMP header data. */ + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); + +#ifndef NX_DISABLE_IGMPV2 + /* Is this IGMPv1 host's join request? */ + if (((header_ptr -> nx_igmp_header_word_0 & NX_IGMP_TYPE_MASK) == NX_IGMP_HOST_RESPONSE_TYPE) || + /* ...Or an IGMPv2 host's join request? */ + ((header_ptr -> nx_igmp_header_word_0 & NX_IGMPV2_TYPE_MASK) == NX_IGMP_HOST_V2_JOIN_TYPE)) +#else + + /* Is this another IGMPv1 host's join request? */ + if ((header_ptr -> nx_igmp_header_word_0 & NX_IGMP_TYPE_MASK) == NX_IGMP_HOST_RESPONSE_TYPE) +#endif + { + + /* Fill the buffer with 0x58. */ + memset(&buffer[0],0x58, DATA_SIZE); + + /* Ensure that the data is not symmetrical with respect to endianness or our test is meaningless. */ + if (DATA_SIZE > 8) + { + buffer[0] = 48; + buffer[1] = 47; + buffer[2] = 46; + buffer[3] = 45; + buffer[4] = 44; + buffer[5] = 43; + buffer[6] = 42; + buffer[7] = 41; + } + + /* Allocate a packet to place the IGMP Router query message in, IGMP version1. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IGMP_PACKET , TX_NO_WAIT); + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + + /* Setup the pointer to the message area. */ + header_ptr = (NX_IGMP_HEADER *) my_packet -> nx_packet_prepend_ptr; + + /* Build the IGMPv1 Router query message. */ + header_ptr -> nx_igmp_header_word_0 = (ULONG) (NX_IGMP_VERSION | NX_IGMP_ROUTER_QUERY_TYPE); + header_ptr -> nx_igmp_header_word_1 = ip_ptr -> nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list; + + /* Stamp the outgoing interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = ip_ptr -> nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list; + + /* set the append pointer past the IGMP header including the 2 extra bytes. */ + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + NX_IGMP_HEADER_SIZE; + my_packet -> nx_packet_length = NX_IGMP_HEADER_SIZE; + + /* Add the IGMP 'data'. */ + nx_packet_data_append(my_packet, &buffer[0], DATA_SIZE, &pool_0, 200); + + /* Calculate the IGMP checksum. */ + igmp_checksum_compute(my_packet); + + /* Call _nx_igmp_packet_receive to directly receive the valid packet. */ + _nx_igmp_packet_receive(&ip_0, my_packet); + + } + else + error_counter++; + + + } + + /* Determine if the test was successful. */ + if ((error_counter) || (ip_0.nx_ip_igmp_checksum_errors != 0) || (ip_0.nx_ip_igmp_invalid_packets != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return NX_TRUE; +} + +static void igmp_checksum_compute(NX_PACKET *packet_ptr) +{ + +NX_IGMP_HEADER *header_ptr; +UCHAR *word_ptr; +NX_PACKET *current_packet; +ULONG checksum; +ULONG long_temp; +USHORT short_temp; +ULONG length; + + + /* Setup a pointer to the IGMP packet header. */ + header_ptr = (NX_IGMP_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + + /* Clear the IGMP checksum. */ + header_ptr -> nx_igmp_header_word_0 &= 0xFFFF0000; + + /* First verify the checksum is correct. */ + checksum = 0; + + /* Setup the length of the packet checksum. */ + length = packet_ptr -> nx_packet_length; + + /* Check for an odd numbered (invalid) length packet payload. */ + if (((length/sizeof(USHORT))*sizeof(USHORT)) != length) + { + + /* Discard the packet. */ + nx_packet_release(packet_ptr); + + return; + } + + + /* Swap back to host byte order to insert the checksum if little endian is specified. */ + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_1); + + /* Setup the pointer to the start of the packet. */ + word_ptr = (UCHAR *) packet_ptr -> nx_packet_prepend_ptr; + + /* Initialize the current packet to the input packet pointer. */ + current_packet = packet_ptr; + + checksum = 0; + + /* Loop to calculate the packet's checksum. */ + while (length) + { + /* Determine if there is at least one ULONG left. */ + if ((UINT)(current_packet -> nx_packet_append_ptr - word_ptr) >= sizeof(ULONG)) + { + + /* Pickup a whole ULONG. */ + long_temp = *((ULONG *) word_ptr); + + /* Add upper 16-bits into checksum. */ + checksum = checksum + (long_temp >> NX_SHIFT_BY_16); + + /* Check for carry bits. */ + if (checksum & NX_CARRY_BIT) + checksum = (checksum & NX_LOWER_16_MASK) + 1; + + /* Add lower 16-bits into checksum. */ + checksum = checksum + (long_temp & NX_LOWER_16_MASK); + + /* Check for carry bits. */ + + if (checksum & NX_CARRY_BIT) + checksum = (checksum & NX_LOWER_16_MASK) + 1; + + /* Move the word pointer and decrease the length. */ + word_ptr = word_ptr + sizeof(ULONG); + length = length - sizeof(ULONG); + + } + else + { + + /* Pickup the 16-bit word. */ + short_temp = *((USHORT *) word_ptr); + + /* Add next 16-bit word into checksum. */ + checksum = checksum + short_temp; + + /* Check for carry bits. */ + if (checksum & NX_CARRY_BIT) + checksum = (checksum & NX_LOWER_16_MASK) + 1; + + /* Move the word pointer and decrease the length. */ + word_ptr = word_ptr + sizeof(USHORT); + length = length - sizeof(USHORT); + } + + /* Determine if we are at the end of the current packet. */ + if ((word_ptr >= (UCHAR *) current_packet -> nx_packet_append_ptr) && + (current_packet -> nx_packet_next)) + { + + /* We have crossed the packet boundary. Move to the next packet + structure. */ + current_packet = current_packet -> nx_packet_next; + + /* Setup the new word pointer. */ + word_ptr = (UCHAR *) current_packet -> nx_packet_prepend_ptr; + } + } + + /* Swap back to host byte order to insert the checksum if little endian is specified. */ + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); + + /* If little endian is specified, we need to byte swap the checksum instead of computing the + data in network byte order. */ + NX_CHANGE_ULONG_ENDIAN(checksum); + + /* Place the checksum 1s complement into the first header word. */ + header_ptr -> nx_igmp_header_word_0 |= (~(checksum >> NX_SHIFT_BY_16) & NX_LOWER_16_MASK); + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_checksum_computation_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IGMP Checksum Computation Test............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_igmp_interface_indirect_report_send_test.c b/test/regression/netxduo_test/netx_igmp_interface_indirect_report_send_test.c new file mode 100644 index 00000000..fac3d854 --- /dev/null +++ b/test/regression/netxduo_test/netx_igmp_interface_indirect_report_send_test.c @@ -0,0 +1,307 @@ +/* This NetX test tests the IGMP report send IGMP operation. The application + registers (joins) a group address with the IP instance long enough to send + out an initial report. Then the application wishes to resend the same IGMP + report (because it detects a new router. The timeout in the multicast entry for that + group address is reset to one so that an IGMP report is sent out on the next + periodic. For 5.9, this service is an internal function and only supports + sending join IGMP reports. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_igmp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IGMP_INFO) && (NX_MAX_PHYSICAL_INTERFACES > 1) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_interface_indirect_report_send_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + status = nx_ip_interface_attach(&ip_0, "Secondary IP", IP_ADDRESS(1,2,4,4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable IGMP processing for both this IP instance. */ + status = nx_igmp_enable(&ip_0); + + /* Check enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + + UINT status; + ULONG igmp_reports_sent; + ULONG igmp_queries_received; + ULONG igmp_checksum_errors; + ULONG current_groups_joined; + + + /* Let the IP task initialize the driver. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE / 5); + + /* Print out test information banner. */ + printf("NetX Test: IGMP Multicast Indirect Report Send Test.................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Perform an IGMP join operation on the primary interface. */ + status = nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,7), 0); + + /* Determine if there is an error. */ + if (status) + { + error_counter++ ; + } + + /* Perform another IGMP join operation on the primary interface. */ + status = nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,1), 0); + + /* Determine if there is an error. */ + if (status) + { + error_counter++ ; + } + + /* Perform an IGMP join operation on the secondary interface. */ + status = nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,3), 1); + + /* Determine if there is an error. */ + if (status) + { + error_counter++ ; + } + + /* Should be long enough for three IP periodic cycles to send a report. */ + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + /* Call the IGMP information get routine to see if all the groups are there. */ + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + /* Check for status and if NetX sent off any IGMP reports. */ + if ((status) || (igmp_reports_sent != 3) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 3)) + { + error_counter++; + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE / 10); + +#ifdef __PRODUCT_NETXDUO__ + /* Perform IGMP leave operation and test if we need to send a leave report. */ + status = nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,3), 1); +#else + status = nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,3)); +#endif + + /* Determine if there is an error. */ + if (status) + { + error_counter++ ; + } + + /* Call the IGMP information get routine to see if all the groups are there. */ + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + +#ifndef NX_DISABLE_IGMPV2 + /* Check for status and if NetX sent off any IGMP reports. */ + if ((igmp_reports_sent != 3) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 2)) +#else + /* IGMPv1 protocol does not call for sending leave reports. */ + if ((igmp_reports_sent != 3) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 2)) +#endif + { + error_counter++; + } + + /* Attempt to rejoin the group after we cleared the multicast entry for it. */ + status = _nx_igmp_interface_report_send(&ip_0, IP_ADDRESS(224,0,0,1), 0, NX_TRUE); + + /* Determine if there is an error. */ + if (status != NX_SUCCESS) + { + error_counter++ ; + } + + /* Wait a second, only one IGMP report goes out per IP thread task periodic. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Call the IGMP information get routine to see if NetX sent out another report message. */ + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + if (status) + { + error_counter++; + } + + /* Check IGMP statistics. */ + +#ifndef NX_DISABLE_IGMPV2 + if ((status) || (igmp_reports_sent != 4) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 2)) +#else + /* IGMPv1 protocol does not call for sending leave reports. */ + if ((status) || (igmp_reports_sent != 4) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 2)) +#endif + { + error_counter++; + } + + /* Send a join report for a group that we left the membership of. */ + status = _nx_igmp_interface_report_send(&ip_0, IP_ADDRESS(224,0,0,7), 0, NX_TRUE); + + /* Determine if there is an error. This call should succeed because nx_igmp_interface_report_send does not check + the membership of the group address. It is assumed the caller does. */ + if (status != NX_SUCCESS) + { + error_counter++ ; + } + + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + if (status) + { + error_counter++; + } + +#ifndef NX_DISABLE_IGMPV2 + if ((status) || (igmp_reports_sent != 5) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 2)) +#else + /* IGMPv1 protocol does not call for sending leave reports. */ + if ((status) || (igmp_reports_sent != 5) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 2)) +#endif + { + error_counter++; + } + + /* Perform an IGMP leave operation on the primary interface. */ +#ifdef __PRODUCT_NETXDUO__ + status = nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,5), 0); +#else + status = nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,5)); +#endif + + /* We never joined this group so this call should return an error. */ + if (status == NX_SUCCESS) + { + error_counter++; + } + + /* Call the IGMP information get routine to see if NetX sent out another report message. */ + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + if (status) + { + error_counter++; + } + + /* Check for status. There should be no change here. */ +#ifndef NX_DISABLE_IGMPV2 + if ((status) || (igmp_reports_sent != 5) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 2)) +#else + /* IGMPv1 protocol does not call for sending leave reports. */ + if ((status) || (igmp_reports_sent != 5) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 2)) +#endif + { + error_counter++; + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_interface_indirect_report_send_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IGMP Multicast Indirect Report Send Test...................N/A\n"); + test_control_return(3); + +} +#endif /* NX_DISABLE_IGMP_INFO */ diff --git a/test/regression/netxduo_test/netx_igmp_join_fail_test.c b/test/regression/netxduo_test/netx_igmp_join_fail_test.c new file mode 100644 index 00000000..e0bb83d5 --- /dev/null +++ b/test/regression/netxduo_test/netx_igmp_join_fail_test.c @@ -0,0 +1,183 @@ +/* This NetX test concentrates on the IGMP join fails when driver returns error. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static UINT available; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void test_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_join_fail_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + available = NX_TRUE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, test_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable IGMP processing for both this IP instance. */ + status = nx_igmp_enable(&ip_0); + + /* Check enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: IGMP Join Fail Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set available to false. */ + available = NX_FALSE; + + /* Perform IGMP join operations. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,1)); + + /* Determine if there is an error. */ + if (status != NX_NO_MORE_ENTRIES) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set available to true. */ + available = NX_TRUE; + + /* Perform IGMP join operations. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,1)); + + /* Determine if there is an error. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now leave the group to make sure that processing works properly. */ + status = nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,1)); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void test_driver(struct NX_IP_DRIVER_STRUCT *driver_req) +{ + if ((driver_req -> nx_ip_driver_command == NX_LINK_MULTICAST_JOIN) && + (available == NX_FALSE)) + { + + /* Return not supported. */ + driver_req -> nx_ip_driver_status = NX_UNHANDLED_COMMAND; + } + else + { + + /* Pass the request to ram driver. */ + _nx_ram_network_driver_256(driver_req); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_join_fail_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IGMP Join Fail Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_igmp_leave_test.c b/test/regression/netxduo_test/netx_igmp_leave_test.c new file mode 100644 index 00000000..63dec5e1 --- /dev/null +++ b/test/regression/netxduo_test/netx_igmp_leave_test.c @@ -0,0 +1,158 @@ +/* This NetX test concentrates on the IGMP leave. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_leave_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable IGMP processing for both this IP instance. */ + status = nx_igmp_enable(&ip_0); + + /* Check enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: IGMP Leave Test..........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Perform IGMP join operations. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,1)); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now leave the group to make sure that processing works properly. */ + status = nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,1)); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now leave the group again. */ + status = nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,1)); + + /* Determine if no entry is found. */ + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_leave_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IGMP Leave Test...........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_igmp_loopback_test.c b/test/regression/netxduo_test/netx_igmp_loopback_test.c new file mode 100644 index 00000000..0809c53f --- /dev/null +++ b/test/regression/netxduo_test/netx_igmp_loopback_test.c @@ -0,0 +1,312 @@ +/* This NetX test concentrates on the IGMP loopback operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IGMP_INFO) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define TEST_INTERFACE 1 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_loopback_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable IGMP processing for both this IP instance. */ + status = nx_igmp_enable(&ip_0); + + /* Check enable status. */ + if (status) + error_counter++; + + /* Enable UDP processing for this IP instance. */ + status = nx_udp_enable(&ip_0); + + /* Check enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG igmp_reports_sent; +ULONG igmp_queries_received; +ULONG igmp_checksum_errors; +ULONG current_groups_joined; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS dest_address; +#endif + + + /* Print out test information banner. */ + printf("NetX Test: IGMP Loopback Operation Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + /* Enable all TX checksum capability. */ + nx_ip_interface_capability_set(&ip_0, TEST_INTERFACE, NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM); + +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + /* Enable IGMP loopback. */ + status = nx_igmp_loopback_enable(&ip_0); + + /* Perform 7 IGMP join operations. */ + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,1),TEST_INTERFACE); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,2),TEST_INTERFACE); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,3),TEST_INTERFACE); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4),TEST_INTERFACE); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,5),TEST_INTERFACE); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,6),TEST_INTERFACE); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,7),TEST_INTERFACE); + + /* Join one group another 4 times to test the counting operation. */ + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4),TEST_INTERFACE); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4),TEST_INTERFACE); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4),TEST_INTERFACE); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4),TEST_INTERFACE); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 2 seconds to let IGMP packets be sent. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Call the IGMP information get routine to see if all the groups are there. */ + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + /* Check for status. */ + if ((status) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 7)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create and bind two UDP sockets. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Sending Socket", NX_IP_NORMAL, NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 5); + status += nx_udp_socket_create(&ip_0, &socket_1, "Receiving Socket", NX_IP_NORMAL, NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 5); + status += nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + status += nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + +#ifdef __PRODUCT_NETXDUO__ + dest_address.nxd_ip_address.v4 =IP_ADDRESS(224, 0, 0, 4); + dest_address.nxd_ip_version = 4; + + /* Send the UDP packet. */ + status = nxd_udp_socket_interface_send(&socket_0, my_packet, &dest_address, 0x89, TEST_INTERFACE); +#else + + /* Send the UDP packet. */ + status = nx_udp_socket_interface_send(&socket_0, my_packet, IP_ADDRESS(224, 0, 0, 4), 0x89, TEST_INTERFACE); +#endif + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive the UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the IGMP loopback. */ + status = nx_igmp_loopback_disable(&ip_0); + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + /* Disable all interface capability. */ + nx_ip_interface_capability_set(&ip_0, TEST_INTERFACE, 0); +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + /* Now leave all the groups to make sure that processing works properly. */ +#ifdef __PRODUCT_NETXDUO__ + status = nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,1), TEST_INTERFACE); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,2), TEST_INTERFACE); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,3), TEST_INTERFACE); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), TEST_INTERFACE); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,5), TEST_INTERFACE); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,6), TEST_INTERFACE); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,7), TEST_INTERFACE); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), TEST_INTERFACE); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), TEST_INTERFACE); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), TEST_INTERFACE); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), TEST_INTERFACE); +#else + + status = nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,1)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,2)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,3)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,5)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,6)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,7)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); +#endif + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call the IGMP information get routine to see if all the groups are there. */ + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + /* Check for status. */ + if ((status) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_loopback_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IGMP Loopback Operation Test..............................N/A\n"); + test_control_return(3); + +} +#endif /* NX_DISABLE_IGMP_INFO */ diff --git a/test/regression/netxduo_test/netx_igmp_multicast_basic_test.c b/test/regression/netxduo_test/netx_igmp_multicast_basic_test.c new file mode 100644 index 00000000..e89f80e1 --- /dev/null +++ b/test/regression/netxduo_test/netx_igmp_multicast_basic_test.c @@ -0,0 +1,302 @@ +/* This NetX test concentrates on the basic multicast IGMP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IGMP_INFO) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_multicast_basic_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Set the second interface. */ + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable IGMP processing for both this IP instance. */ + status = nx_igmp_enable(&ip_0); + + /* Check enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + + UINT status; + ULONG igmp_reports_sent; + ULONG igmp_queries_received; + ULONG igmp_checksum_errors; + ULONG current_groups_joined; + + + /* Print out test information banner. */ + printf("NetX Test: IGMP Multicast Basic Operation Test......................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test the first interface. */ + /* Perform 7 IGMP join operations. */ + status = nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,1), 0); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,2), 0); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,3), 0); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 0); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,5), 0); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,7), 0); + +#ifdef __PRODUCT_NETXDUO__ + /* Test the nxe_igmp_multicast_interface_join_internal.c */ + status += nx_ipv4_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,6), 0); +#else + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,6), 0); +#endif /* __PRODUCT_NETXDUO__ */ + + /* Join one group another 4 times to test the counting operation. */ + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 0); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 0); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 0); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 0); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call the IGMP information get routine to see if all the groups are there. */ + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + /* Check for status. */ + if ((status) || (igmp_reports_sent) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 7)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to join a new group. This should result in an error. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,8)); + + /* Determine if an error has occurred. */ + if (status != NX_NO_MORE_ENTRIES) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,1)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,2)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,3)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,5)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,7)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); +#ifdef __PRODUCT_NETXDUO__ + status += nx_ipv4_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,6), 0); +#else + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,6)); +#endif /* __PRODUCT_NETXDUO__ */ + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + if(NX_MAX_PHYSICAL_INTERFACES > 1) + { + + /* Test the second interface. */ + /* Perform 7 IGMP join operations. */ + status = nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,1), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,2), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,3), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,5), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,6), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,7), 1); + + /* Join one group another 4 times to test the counting operation. */ + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 1); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call the IGMP information get routine to see if all the groups are there. */ + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + /* Check for status. */ + if ((status) || (igmp_reports_sent) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined != 7)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to join a new group. This should result in an error. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,8)); + + /* Determine if an error has occurred. */ + if (status != NX_NO_MORE_ENTRIES) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now leave all the groups to make sure that processing works properly. */ +#ifdef __PRODUCT_NETXDUO__ + status = nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,1), 1); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,2), 1); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,3), 1); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,5), 1); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,6), 1); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,7), 1); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,4), 1); +#else + status = nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,1)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,2)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,3)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,5)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,6)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,7)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); + status += nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,4)); +#endif + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Call the IGMP information get routine to see if all the groups are there. */ + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + /* Check for status. */ + if ((status) || (igmp_reports_sent) || (igmp_queries_received) || (igmp_checksum_errors) || (current_groups_joined)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_multicast_basic_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IGMP Multicast Basic Operation Test.......................N/A\n"); + test_control_return(3); + +} +#endif /* NX_DISABLE_IGMP_INFO */ diff --git a/test/regression/netxduo_test/netx_igmp_nxe_api_test.c b/test/regression/netxduo_test/netx_igmp_nxe_api_test.c new file mode 100644 index 00000000..fb92ee45 --- /dev/null +++ b/test/regression/netxduo_test/netx_igmp_nxe_api_test.c @@ -0,0 +1,744 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "nx_igmp.h" +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined NX_DISABLE_ERROR_CHECKING && defined __PRODUCT_NETXDUO__ && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP invalid_ip; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG igmp_reports_sent; +ULONG igmp_queries_received; +ULONG igmp_checksum_errors; +ULONG current_groups_joined; + + + /* Print out some test information banners. */ + printf("NetX Test: IGMP NXE API Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_igmp_enable api */ + /************************************************/ + + /* Enable the IGMP feature for NULL IP instance. */ + status = nx_icmp_enable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Enable the IGMP feature for invalid IP instance. */ + status = nx_igmp_enable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the IGMP feature for valid IP instance. */ + status = nx_igmp_enable(&ip_0); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the IGMP feature again for valid IP instance . */ + status = nx_igmp_enable(&ip_0); + + /* Check for error. */ + if (status != NX_ALREADY_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_igmp_info_get api */ + /************************************************/ + + /* Get the IGMP information for NULL IP instance. */ + status = nx_igmp_info_get(NX_NULL, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the IGMP information for invalid IP instance. */ + status = nx_igmp_info_get(&invalid_ip, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the IGMP feature. */ + ip_0.nx_ip_igmp_packet_receive = NX_NULL; + + /* Get the IGMP information for invalid IP instance. */ + status = nx_igmp_info_get(&ip_0, &igmp_reports_sent, &igmp_queries_received, &igmp_checksum_errors, ¤t_groups_joined); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_igmp_loopback_disable api */ + /************************************************/ + + /* Disable the IGMP loopback for NULL IP instance. */ + status = nx_igmp_loopback_disable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Disable the IGMP loopback for invalid IP instance. */ + status = nx_igmp_loopback_disable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the IGMP feature. */ + ip_0.nx_ip_igmp_packet_receive = NX_NULL; + + /* Disable the IGMP loopback for invalid IP instance. */ + status = nx_igmp_loopback_disable(&ip_0); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_igmp_loopback_enable api */ + /************************************************/ + + /* Enable the IGMP loopback for NULL IP instance. */ + status = nx_igmp_loopback_enable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Enable the IGMP loopback for invalid IP instance. */ + status = nx_igmp_loopback_enable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the IGMP feature. */ + ip_0.nx_ip_igmp_packet_receive = NX_NULL; + + /* Enable the IGMP loopback for invalid IP instance. */ + status = nx_igmp_loopback_enable(&ip_0); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***************************************************/ + /* Tested the nxe_igmp_multicast_interface_join api */ + /***************************************************/ + + /* Reset the igmp packet receive function. */ + ip_0.nx_ip_igmp_packet_receive = _nx_igmp_packet_receive; + + /* Join the ICMP group for NULL IP instance. */ + status = nx_igmp_multicast_interface_join(NX_NULL, IP_ADDRESS(224,0,0,251), 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Join the ICMP group for invalid IP instance. */ + status = nx_igmp_multicast_interface_join(&invalid_ip, IP_ADDRESS(224,0,0,251), 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Join the ICMP group with invalid IP address. */ + status = nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(1, 2, 3, 4), NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the IGMP feature. */ + ip_0.nx_ip_igmp_packet_receive = NX_NULL; + + /* Join the ICMP group with IGMP feature disable. */ + status = nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,251), 0); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the igmp packet receive function. */ + ip_0.nx_ip_igmp_packet_receive = _nx_igmp_packet_receive; + + /* Join the ICMP group with MAX interface index. */ + status = nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,251), NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Join the ICMP group with invalid interface. */ + ip_0.nx_ip_interface[0].nx_interface_valid = NX_FALSE; + status = nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,251), 0); + ip_0.nx_ip_interface[0].nx_interface_valid = NX_TRUE; + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /*************************************************************/ + /* Tested the nxe_igmp_multicast_interface_join_internal api */ + /* by nxe_ipv4_multicast_interface_join api */ + /*************************************************************/ + + /* Reset the igmp packet receive function. */ + ip_0.nx_ip_igmp_packet_receive = _nx_igmp_packet_receive; + + /* Join the ICMP group for NULL IP instance. */ + status = nx_ipv4_multicast_interface_join(NX_NULL, IP_ADDRESS(224,0,0,251), 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Join the ICMP group with invalid interface. */ + ip_0.nx_ip_interface[0].nx_interface_valid = NX_FALSE; + status = nx_ipv4_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,251), 0); + ip_0.nx_ip_interface[0].nx_interface_valid = NX_TRUE; + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Join the ICMP group for invalid IP instance. */ + status = nx_ipv4_multicast_interface_join(&invalid_ip, IP_ADDRESS(224,0,0,251), 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Join the ICMP group with invalid IP address. */ + status = nx_ipv4_multicast_interface_join(&ip_0, IP_ADDRESS(1, 2, 3, 4), NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Join the ICMP group with MAX interface index. */ + status = nx_ipv4_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,251), NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /*****************************************************/ + /* Tested the nxe_igmp_multicast_interface_leave api */ + /*****************************************************/ + + /* Reset the igmp packet receive function. */ + ip_0.nx_ip_igmp_packet_receive = _nx_igmp_packet_receive; + + /* Leave the ICMP group for NULL IP instance. */ + status = nx_igmp_multicast_interface_leave(NX_NULL, IP_ADDRESS(224,0,0,251), 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Leave the ICMP group for invalid IP instance. */ + status = nx_igmp_multicast_interface_leave(&invalid_ip, IP_ADDRESS(224,0,0,251), 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Leave the ICMP group with invalid IP address. */ + status = nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(1, 2, 3, 4), NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the IGMP feature. */ + ip_0.nx_ip_igmp_packet_receive = NX_NULL; + + /* Join the ICMP group with IGMP feature disable. */ + status = nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,251), 0); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the igmp packet receive function. */ + ip_0.nx_ip_igmp_packet_receive = _nx_igmp_packet_receive; + + /* Leave the ICMP group with MAX interface index. */ + status = nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,251), NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Leave the IGMP group with invalid interface. */ + ip_0.nx_ip_interface[0].nx_interface_valid = NX_FALSE; + status = nx_igmp_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,251), 0); + ip_0.nx_ip_interface[0].nx_interface_valid = NX_TRUE; + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /**************************************************************/ + /* Tested the nxe_igmp_multicast_interface_leave_internal api */ + /* by nxe_ipv4_multicast_interface_leave api */ + /**************************************************************/ + + /* Reset the igmp packet receive function. */ + ip_0.nx_ip_igmp_packet_receive = _nx_igmp_packet_receive; + + /* Leave the multicast for NULL IP instance. */ + status = nx_ipv4_multicast_interface_leave(NX_NULL, IP_ADDRESS(224,0,0,251), 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Leave the multicast for invalid IP instance. */ + status = nx_ipv4_multicast_interface_leave(&invalid_ip, IP_ADDRESS(224,0,0,251), 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Leave the multicast with invalid IP address. */ + status = nx_ipv4_multicast_interface_leave(&ip_0, IP_ADDRESS(1, 2, 3, 4), NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Leave the multicast group with MAX interface index. */ + status = nx_ipv4_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,251), NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Leave the IGMP group with invalid interface. */ + ip_0.nx_ip_interface[0].nx_interface_valid = NX_FALSE; + status = nx_ipv4_multicast_interface_leave(&ip_0, IP_ADDRESS(224,0,0,251), 0); + ip_0.nx_ip_interface[0].nx_interface_valid = NX_TRUE; + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***************************************************/ + /* Tested the nxe_igmp_multicast_join api */ + /***************************************************/ + + /* Reset the igmp packet receive function. */ + ip_0.nx_ip_igmp_packet_receive = _nx_igmp_packet_receive; + + /* Join the ICMP group for NULL IP instance. */ + status = nx_igmp_multicast_join(NX_NULL, IP_ADDRESS(224,0,0,251)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Join the ICMP group for invalid IP instance. */ + status = nx_igmp_multicast_join(&invalid_ip, IP_ADDRESS(224,0,0,251)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Join the ICMP group with invalid IP address. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(1, 2, 3, 4)); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the IGMP feature. */ + ip_0.nx_ip_igmp_packet_receive = NX_NULL; + + /* Join the ICMP group with IGMP feature disable. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,251)); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP instance ID and igmp packet receive function. */ + invalid_ip.nx_ip_id = NX_IP_ID; + invalid_ip.nx_ip_igmp_packet_receive = _nx_igmp_packet_receive; + + /* Join the ICMP group with invalid interface index. */ + status = nx_igmp_multicast_join(&invalid_ip, IP_ADDRESS(224,0,0,251)); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***************************************************/ + /* Tested the nxe_igmp_multicast_leave api */ + /***************************************************/ + + /* Reset the igmp packet receive function. */ + ip_0.nx_ip_igmp_packet_receive = _nx_igmp_packet_receive; + + /* Join the ICMP group for NULL IP instance. */ + status = nx_igmp_multicast_leave(NX_NULL, IP_ADDRESS(224,0,0,251)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Join the ICMP group for invalid IP instance. */ + status = nx_igmp_multicast_leave(&invalid_ip, IP_ADDRESS(224,0,0,251)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Join the ICMP group with invalid IP address. */ + status = nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(1, 2, 3, 4)); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the IGMP feature. */ + ip_0.nx_ip_igmp_packet_receive = NX_NULL; + + /* Join the ICMP group with IGMP feature disable. */ + status = nx_igmp_multicast_leave(&ip_0, IP_ADDRESS(224,0,0,251)); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP instance ID and igmp packet receive function. */ + invalid_ip.nx_ip_id = NX_IP_ID; + invalid_ip.nx_ip_igmp_packet_receive = _nx_igmp_packet_receive; + + /* Join the ICMP group with invalid interface index. */ + status = nx_igmp_multicast_leave(&invalid_ip, IP_ADDRESS(224,0,0,251)); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IGMP NXE API Test.........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_igmp_packet_receive_function_test.c b/test/regression/netxduo_test/netx_igmp_packet_receive_function_test.c new file mode 100644 index 00000000..6a570e27 --- /dev/null +++ b/test/regression/netxduo_test/netx_igmp_packet_receive_function_test.c @@ -0,0 +1,412 @@ +/* This NetX test case test _nx_igmp_packet_receive and _nx_igmp_queue_process function with non standard operation . */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_igmp.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UCHAR igmp_packet_received = NX_FALSE; +static NX_PACKET *copy_packet_0; +static NX_PACKET *copy_packet_1; +static NX_PACKET *copy_packet_2; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +static void packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void igmp_checksum_compute(NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_packet_receive_function_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += _nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable IGMP processing for both IP instances. */ + status = nx_igmp_enable(&ip_0); + status += nx_igmp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: IGMP Packet Receive Function Test........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Point to new receive function */ + ip_1.nx_ip_igmp_packet_receive = packet_receive; + + /* Perform IGMP join operations for IP instance1. */ + status = nx_igmp_multicast_join(&ip_1, IP_ADDRESS(224,0,0,1)); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Perform IGMP join operations for IP instance0. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,1)); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 500 ticks to trigger the NX_IP_PERIODIC_EVENT event. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check the IGMP information for IP instance1. */ +#ifndef NX_DISABLE_IGMP_INFO + if (ip_1.nx_ip_igmp_invalid_packets != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Create and bind two UDP sockets. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Sending Socket", NX_IP_NORMAL, NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 5); + status += nx_udp_socket_create(&ip_1, &socket_1, "Receiving Socket", NX_IP_NORMAL, NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 5); + status += nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + status += nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(224, 0, 0, 1), 0x89); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive the UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if ((error_counter) || (igmp_packet_received != NX_TRUE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status != NX_SUCCESS) + { + error_counter++; + } + + /* Wait for receive the IGMP packet. */ + while(igmp_packet_received == NX_FALSE) + { + tx_thread_sleep(1); + } + + /* Call _nx_igmp_packet_receive to directly receive the invalid packet. */ + _nx_igmp_packet_receive(&ip_1, copy_packet_0); + + /* Calculate the IGMP checksum. */ + igmp_checksum_compute(copy_packet_1); + igmp_checksum_compute(copy_packet_2); + + /* Call _nx_icmp_packet_receive to receive the packet with incorrect checksum. */ + _nx_igmp_packet_receive(&ip_1, copy_packet_1); + + /* Call _nx_icmp_packet_receive to receive the valid packet. */ + _nx_igmp_packet_receive(&ip_1, copy_packet_2); +} + +static void packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +NX_IGMP_HEADER *header_ptr; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, ©_packet_0, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check for error. */ + if((status != NX_SUCCESS)) + { + error_counter++; + } + + /* Set the packet length with invalid value. */ + memcpy(copy_packet_0 -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ12", 28); + copy_packet_0 -> nx_packet_length = sizeof(NX_IGMP_HEADER) - 1; + copy_packet_0 -> nx_packet_append_ptr = copy_packet_0 -> nx_packet_prepend_ptr + copy_packet_0 -> nx_packet_length; + + /* Update the packet prepend and length to include the IP header. */ + packet_ptr -> nx_packet_prepend_ptr -= 20; + packet_ptr -> nx_packet_length += 20; + + /* Store the packet with incorrect checksum. */ + status = nx_packet_copy(packet_ptr, ©_packet_1, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet prepend and length. */ + copy_packet_1 -> nx_packet_prepend_ptr += 20; + copy_packet_1 -> nx_packet_length -= 20; + + /* Point to the ICMP message header. */ + header_ptr = (NX_IGMP_HEADER *) copy_packet_1 -> nx_packet_prepend_ptr; + + /* Set the incorrect checksum. */ + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); + header_ptr -> nx_igmp_header_word_0 -= 1; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); + +#ifdef __PRODUCT_NETXDUO__ + /* Set interface of packet. */ + copy_packet_1 -> nx_packet_address.nx_packet_interface_ptr = &ip_1.nx_ip_interface[0]; +#endif /* __PRODUCT_NETXDUO__ */ + } + + /* Store the packet with valid message. */ + status = nx_packet_copy(packet_ptr, ©_packet_2, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet prepend and length. */ + copy_packet_2 -> nx_packet_prepend_ptr += 20; + copy_packet_2 -> nx_packet_length -= 20; + +#ifdef __PRODUCT_NETXDUO__ + /* Set interface of packet. */ + copy_packet_2 -> nx_packet_address.nx_packet_interface_ptr = &ip_1.nx_ip_interface[0]; +#endif /* __PRODUCT_NETXDUO__ */ + } + + /* Release the IGMP packet. */ + nx_packet_release(packet_ptr); + + /* Update the flag. */ + igmp_packet_received = NX_TRUE; + + /* Stop the process. */ + return; +} + + +static void igmp_checksum_compute(NX_PACKET *packet_ptr) +{ +ULONG checksum; +ULONG temp; +NX_IGMP_HEADER *header_ptr; + + /* Setup the pointer to the message area. */ + header_ptr = (NX_IGMP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_1); + + /* Clear the IGMP checksum. */ + header_ptr -> nx_igmp_header_word_0 &= 0xFFFF0000; + + + /* Calculate the checksum. */ + temp = header_ptr -> nx_igmp_header_word_0; + checksum = (temp >> NX_SHIFT_BY_16); + checksum += (temp & NX_LOWER_16_MASK); + temp = header_ptr -> nx_igmp_header_word_1; + checksum += (temp >> NX_SHIFT_BY_16); + checksum += (temp & NX_LOWER_16_MASK); + + /* Add in the carry bits into the checksum. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Do it again in case previous operation generates an overflow. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Place the checksum into the first header word. */ + header_ptr -> nx_igmp_header_word_0 |= (~checksum & NX_LOWER_16_MASK); + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_1); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_packet_receive_function_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IGMP Packet Receive Function Test.........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_igmp_router_query_test.c b/test/regression/netxduo_test/netx_igmp_router_query_test.c new file mode 100644 index 00000000..4136e2cb --- /dev/null +++ b/test/regression/netxduo_test/netx_igmp_router_query_test.c @@ -0,0 +1,471 @@ +/* This NetX test case test router query type . */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_igmp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UCHAR igmp_host_response = 0; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void igmp_checksum_compute(NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_router_query_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable IGMP processing for both IP instances. */ + status = nx_igmp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: IGMP Router Qeury Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Point to new receive function */ + advanced_packet_process_callback = my_packet_process; + + /* Perform IGMP join operations for IP instance0. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,1)); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 2000 ticks to trigger the NX_IP_PERIODIC_EVENT event + 1. Receive the IGMP Host response message, + 2. Send the IGMP Router query message with invalid checksum, + 3. Send the IGMP Router query message, + 4. Send the IGMP Router query message with not joined group address, + 5. Receive the IGMP Host repsonse message. */ + tx_thread_sleep(20 * NX_IP_PERIODIC_RATE); + +#ifndef NX_DISABLE_IGMP_INFO + /* Check the count. */ + if ((ip_0.nx_ip_igmp_reports_sent != 2) || (ip_0.nx_ip_igmp_queries_received != 4) || (ip_0.nx_ip_igmp_invalid_packets != 1) || (ip_0.nx_ip_igmp_checksum_errors != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_IGMP_INFO */ + + /* Determine if the test was successful. */ + if ((error_counter) || (igmp_host_response != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_IGMP_HEADER *header_ptr; +NX_PACKET *my_packet; +ULONG checksum; +ULONG temp; +UINT status; +UINT router_alert = 0; +UINT i; + + +#ifndef NX_DISABLE_IGMPV2 + if (ip_ptr -> nx_ip_igmp_router_version == NX_IGMP_HOST_VERSION_2) + router_alert = 4; +#endif + +#ifndef NX_DISABLE_IGMPV2 + /* Check the version. */ + if (ip_ptr -> nx_ip_igmp_router_version == NX_IGMP_HOST_VERSION_2) + { + /* Setup a pointer to the IGMP packet header. */ + header_ptr = (NX_IGMP_HEADER *) (packet_ptr -> nx_packet_prepend_ptr + 24); + } + else + { + + /* Setup a pointer to the IGMP packet header. */ + header_ptr = (NX_IGMP_HEADER *) (packet_ptr -> nx_packet_prepend_ptr + 20); + } +#else + header_ptr = (NX_IGMP_HEADER *) (packet_ptr -> nx_packet_prepend_ptr + 20); +#endif + + /* Do byte swapping for little endian processors before parsing + IGMP header data. */ + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); + +#ifndef NX_DISABLE_IGMPV2 + /* Is this IGMPv1 host's join request? */ + if (((header_ptr -> nx_igmp_header_word_0 & NX_IGMP_TYPE_MASK) == NX_IGMP_HOST_RESPONSE_TYPE) || + /* ...Or an IGMPv2 host's join request? */ + ((header_ptr -> nx_igmp_header_word_0 & NX_IGMPV2_TYPE_MASK) == NX_IGMP_HOST_V2_JOIN_TYPE)) +#else + + /* Is this another IGMPv1 host's join request? */ + if ((header_ptr -> nx_igmp_header_word_0 & NX_IGMP_TYPE_MASK) == NX_IGMP_HOST_RESPONSE_TYPE) +#endif + { + + /* Do byte swapping for little endian processors before parsing + IGMP header data. */ + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); + + /* Update the counter. */ + igmp_host_response ++; + + /* Check the igmp host repsone counter. */ + if (igmp_host_response != 1) + return NX_TRUE; + + /* Allocate a packet to place the IGMP Router query message in, IGMP version1. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet, NX_IGMP_PACKET + router_alert, TX_NO_WAIT); + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + /* Prepare a IGMP Router Query and send on the "all hosts" multicast + address. */ + + /* Calculate the IGMP response message size and store it in the + packet header. */ + my_packet -> nx_packet_length = NX_IGMP_HEADER_SIZE; + + /* Setup the append pointer to the end of the message. */ + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + NX_IGMP_HEADER_SIZE; + + /* Stamp the outgoing interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = ip_ptr -> nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list; + + /* Build the IGMP host response packet. */ + + /* Setup the pointer to the message area. */ + header_ptr = (NX_IGMP_HEADER *) my_packet -> nx_packet_prepend_ptr; + + /* Build the IGMPv1 Router query message. */ + header_ptr -> nx_igmp_header_word_0 = (ULONG) (NX_IGMP_VERSION | NX_IGMP_ROUTER_QUERY_TYPE); + header_ptr -> nx_igmp_header_word_1 = ip_ptr -> nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list; + + /* Calculate the checksum. */ + temp = header_ptr -> nx_igmp_header_word_0; + checksum = (temp >> NX_SHIFT_BY_16); + checksum += (temp & NX_LOWER_16_MASK); + temp = header_ptr -> nx_igmp_header_word_1; + checksum += (temp >> NX_SHIFT_BY_16); + checksum += (temp & NX_LOWER_16_MASK); + + /* Add in the carry bits into the checksum. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Do it again in case previous operation generates an overflow. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Modify checksum to invalid one. */ + checksum++; + + /* Place the checksum into the first header word. */ + header_ptr -> nx_igmp_header_word_0 = header_ptr -> nx_igmp_header_word_0 | (~checksum & NX_LOWER_16_MASK); + + /* IGMPv2 packets must be IPv4 packets. */ + my_packet -> nx_packet_ip_version = NX_IP_VERSION_V4; + + /* If NX_LITTLE_ENDIAN is defined, the headers need to be swapped. */ + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_1); + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + /* Clear the capability of calculating the IGMP checksum. */ + ip_0.nx_ip_interface[0].nx_interface_capability_flag &= ~NX_INTERFACE_CAPABILITY_IGMP_RX_CHECKSUM; +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + /* Call _nx_icmp_packet_receive to directly receive the IGMP packet with invalid checksum. */ + _nx_igmp_packet_receive(&ip_0, my_packet); + } + else + { + + /* Update the error counter. */ + error_counter ++; + } + + for (i = 0; i < 2; i++) + { + + /* Allocate a packet to place the IGMP Router query message in, IGMP version1. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet, NX_IGMP_PACKET + router_alert, TX_NO_WAIT); + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + /* Prepare a IGMP Router Query and send on the "all hosts" multicast + address. */ + + /* Calculate the IGMP response message size and store it in the + packet header. */ + my_packet -> nx_packet_length = NX_IGMP_HEADER_SIZE; + + /* Setup the append pointer to the end of the message. */ + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + NX_IGMP_HEADER_SIZE; + + /* Stamp the outgoing interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = ip_ptr -> nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list; + + /* Build the IGMP host response packet. */ + + /* Setup the pointer to the message area. */ + header_ptr = (NX_IGMP_HEADER *) my_packet -> nx_packet_prepend_ptr; + + /* Build the IGMPv1 Router query message. */ + header_ptr -> nx_igmp_header_word_0 = (ULONG) (NX_IGMP_VERSION | NX_IGMP_ROUTER_QUERY_TYPE | 0x00010000); + header_ptr -> nx_igmp_header_word_1 = ip_ptr -> nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list; + + /* IGMPv2 packets must be IPv4 packets. */ + my_packet -> nx_packet_ip_version = NX_IP_VERSION_V4; + + /* Calculate the IGMP checksum. */ + igmp_checksum_compute(my_packet); + + /* Call _nx_igmp_packet_receive to directly receive the valid packet. */ + _nx_igmp_packet_receive(&ip_0, my_packet); + } + else + { + + /* Update the error counter. */ + error_counter ++; + } + } + + /* Allocate a packet to place the IGMP Router query message in, IGMP version1. The group address is not joined. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet, NX_IGMP_PACKET + router_alert, TX_NO_WAIT); + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + /* Prepare a IGMP Router Query and send on the "all hosts" multicast + address. */ + + /* Calculate the IGMP response message size and store it in the + packet header. */ + my_packet -> nx_packet_length = NX_IGMP_HEADER_SIZE; + + /* Setup the append pointer to the end of the message. */ + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + NX_IGMP_HEADER_SIZE; + + /* Stamp the outgoing interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = ip_ptr -> nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list; + + /* Build the IGMP host response packet. */ + + /* Setup the pointer to the message area. */ + header_ptr = (NX_IGMP_HEADER *) my_packet -> nx_packet_prepend_ptr; + + /* Build the IGMPv1 Router query message. */ + header_ptr -> nx_igmp_header_word_0 = (ULONG) (NX_IGMP_VERSION | NX_IGMP_ROUTER_QUERY_TYPE); + header_ptr -> nx_igmp_header_word_1 = ip_ptr -> nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list + 1; + + /* IGMPv2 packets must be IPv4 packets. */ + my_packet -> nx_packet_ip_version = NX_IP_VERSION_V4; + + /* Calculate the IGMP checksum. */ + igmp_checksum_compute(my_packet); + + /* Call _nx_icmp_packet_receive to directly receive the IGMP packet with group address not joined. */ + _nx_igmp_packet_receive(&ip_0, my_packet); + } + else + { + + /* Update the error counter. */ + error_counter ++; + } + + /* Allocate a packet to place the IGMP Router query message in, IGMP version1. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet, NX_IGMP_PACKET + router_alert, TX_NO_WAIT); + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + /* Prepare a IGMP Router Query and send on the "all hosts" multicast + address. */ + + /* Calculate the IGMP response message size and store it in the + packet header. */ + my_packet -> nx_packet_length = NX_IGMP_HEADER_SIZE; + + /* Setup the append pointer to the end of the message. */ + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + NX_IGMP_HEADER_SIZE; + + /* Stamp the outgoing interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = ip_ptr -> nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_interface_list; + + /* Build the IGMP host response packet. */ + + /* Setup the pointer to the message area. */ + header_ptr = (NX_IGMP_HEADER *) my_packet -> nx_packet_prepend_ptr; + + /* Build the IGMPv1 Router query message. */ + header_ptr -> nx_igmp_header_word_0 = (ULONG) (NX_IGMP_VERSION | NX_IGMP_ROUTER_QUERY_TYPE); + header_ptr -> nx_igmp_header_word_1 = ip_ptr -> nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_list; + + /* Calculate the IGMP checksum. */ + igmp_checksum_compute(my_packet); + + /* Modify thread time so the random value get from tx_time_get will be in control. */ + tx_time_set((tx_time_get() & 0xFFFFFFF0) + 2); + + /* Call _nx_icmp_packet_receive to directly receive the valid packet. */ + _nx_igmp_packet_receive(&ip_0, my_packet); + } + else + { + + /* Update the error counter. */ + error_counter ++; + } + } + + return NX_TRUE; +} + +static void igmp_checksum_compute(NX_PACKET *packet_ptr) +{ +ULONG checksum; +ULONG temp; +NX_IGMP_HEADER *header_ptr; + + /* Setup the pointer to the message area. */ + header_ptr = (NX_IGMP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + /* Clear the IGMP checksum. */ + header_ptr -> nx_igmp_header_word_0 &= 0xFFFF0000; + + + /* Calculate the checksum. */ + temp = header_ptr -> nx_igmp_header_word_0; + checksum = (temp >> NX_SHIFT_BY_16); + checksum += (temp & NX_LOWER_16_MASK); + temp = header_ptr -> nx_igmp_header_word_1; + checksum += (temp >> NX_SHIFT_BY_16); + checksum += (temp & NX_LOWER_16_MASK); + + /* Add in the carry bits into the checksum. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Do it again in case previous operation generates an overflow. */ + checksum = (checksum >> NX_SHIFT_BY_16) + (checksum & NX_LOWER_16_MASK); + + /* Place the checksum into the first header word. */ + header_ptr -> nx_igmp_header_word_0 |= (~checksum & NX_LOWER_16_MASK); + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_igmp_header_word_1); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_igmp_router_query_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IGMP Router Qeury Test....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_abnormal_packet_test.c b/test/regression/netxduo_test/netx_ip_abnormal_packet_test.c new file mode 100644 index 00000000..29f4d8a2 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_abnormal_packet_test.c @@ -0,0 +1,762 @@ +/* Test IPv6 prefix with length not equal 64. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_LOOPBACK_INTERFACE) && !defined(NX_DISABLE_IPV4) + +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmp.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Frame (74 bytes) */ +/* IPv4 pakcet with next protocol 60(DESTINATION). */ +static char pkt1[74] = { +0x20, 0x0b, 0xc7, 0x94, 0x45, 0x96, 0x18, 0x03, /* ...E... */ +0x73, 0x29, 0x5f, 0x66, 0x08, 0x00, 0x45, 0x00, /* s)_f..E. */ +0x00, 0x3c, 0x6c, 0x31, 0x00, 0x00, 0x40, 0x3c, /* . nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Set invalid value to test destination protocol. */ + packet_ptr -> nx_packet_destination_header = 1; + packet_ptr -> nx_packet_option_state = 0; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "", 0, &ping_resp, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + nx_packet_release(ping_resp); + } + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt2; + pkt_len = sizeof(pkt2); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Set invalid value to test destination protocol. */ + packet_ptr -> nx_packet_destination_header = 0; + packet_ptr -> nx_packet_option_state = ROUTING_HEADER; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "", 0, &ping_resp, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + nx_packet_release(ping_resp); + } + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt3; + pkt_len = sizeof(pkt3); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Set invalid value to test destination protocol. */ + packet_ptr -> nx_packet_destination_header = 0; + packet_ptr -> nx_packet_option_state = FRAGMENT_HEADER; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "", 0, &ping_resp, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + nx_packet_release(ping_resp); + } + + +#ifndef NX_IPSEC_ENABLE + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt4; + pkt_len = sizeof(pkt4); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "", 0, &ping_resp, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + nx_packet_release(ping_resp); + } + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt5; + pkt_len = sizeof(pkt5); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "", 0, &ping_resp, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + nx_packet_release(ping_resp); + } +#endif /* NX_IPSEC_ENABLE */ + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt6; + pkt_len = sizeof(pkt6); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Disable ICMP. */ + ip_0.nx_ip_icmpv6_packet_process = NX_NULL; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Disable ICMP. */ + ip_0.nx_ip_icmpv6_packet_process = _nx_icmpv6_packet_process; + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "", 0, &ping_resp, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + nx_packet_release(ping_resp); + } + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt7; + pkt_len = sizeof(pkt7); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Disable ICMP. */ + ip_0.nx_ip_icmp_packet_receive = NX_NULL; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Disable ICMP. */ + ip_0.nx_ip_icmp_packet_receive = _nx_icmp_packet_receive; + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "", 0, &ping_resp, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + nx_packet_release(ping_resp); + } + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt8; + pkt_len = sizeof(pkt8); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "", 0, &ping_resp, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + nx_packet_release(ping_resp); + } + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt9; + pkt_len = sizeof(pkt9); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "", 0, &ping_resp, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + nx_packet_release(ping_resp); + } + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt10; + pkt_len = sizeof(pkt10); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "", 0, &ping_resp, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + nx_packet_release(ping_resp); + } + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt11; + pkt_len = sizeof(pkt11); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(127, 0, 0, 1), "", 0, &ping_resp, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + error_counter++; + } + else + { + nx_packet_release(ping_resp); + } + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt12; + pkt_len = sizeof(pkt12); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt13; + pkt_len = sizeof(pkt13); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + pkt_data_ptr = pkt14; + pkt_len = sizeof(pkt14); + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data_ptr[14], pkt_len - 14); + packet_ptr -> nx_packet_length = pkt_len - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Abnormal Packet Test...................................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_ip_address_change_notify_test.c b/test/regression/netxduo_test/netx_ip_address_change_notify_test.c new file mode 100644 index 00000000..0d334d27 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_address_change_notify_test.c @@ -0,0 +1,223 @@ +/* This NetX test concentrates on the IP Address Change Notify operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ip_0_address_change_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void ip_0_address_change_notify(NX_IP *ip_ptr, VOID *additional_info); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_address_change_notify_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Initialize the value. */ + error_counter = 0; + ip_0_address_change_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: IP Address Change Notify Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register IP address change callback. */ + status = nx_ip_address_change_notify(&ip_0, ip_0_address_change_notify, NX_NULL); + + /* Check for error */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address change counter. */ + if (ip_0_address_change_counter != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test nx_ip_address_set function. */ + + /* Set the same address and network mask again. */ + status = nx_ip_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address change counter. */ + if (ip_0_address_change_counter != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the different address and same network mask again. */ + status = nx_ip_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address change counter. */ + if (ip_0_address_change_counter != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the same address and different network mask again. */ + status = nx_ip_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0xFFFF0000); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address change counter. */ + if (ip_0_address_change_counter != 2) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test nx_ip_interface_address_set function. */ + + /* Set the different address and same network mask again. */ + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(1, 2, 3, 6), 0xFFFF0000); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address change counter. */ + if (ip_0_address_change_counter != 3) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the same address and different network mask again. */ + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(1, 2, 3, 6), 0xFF000000); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address change counter. */ + if (ip_0_address_change_counter != 4) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); + +} +static VOID ip_0_address_change_notify(NX_IP *ip_ptr, VOID *additional_info) +{ + + /* Update the address change counter. */ + ip_0_address_change_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_address_change_notify_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Address Change Notify Test.............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_ip_address_conflict_callback_test.c b/test/regression/netxduo_test/netx_ip_address_conflict_callback_test.c new file mode 100644 index 00000000..a81bf733 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_address_conflict_callback_test.c @@ -0,0 +1,212 @@ +/* This NetX test concentrates on the IPv4 Address Conflict Detection. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_arp.h" + +extern void test_control_return(UINT status); +#ifndef NX_DISABLE_IPV4 +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG conflict_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void ip_address_conflict_detection(NX_IP *ip_ptr, UINT interface_index, ULONG ip_address, ULONG msw, ULONG lsw); +static void reject_arp_packet(NX_IP *ip_ptr, UINT interface_index, + ULONG source_ip, ULONG source_physical_msw, ULONG source_physical_lsw, + ULONG target_ip, ULONG target_physical_msw, ULONG target_physical_lsw); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_address_conflict_callback_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + conflict_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + + + /* Print out some test information banners. */ + printf("NetX Test: IP Address Conflict Callback Test........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address conflict callback function. */ + ip_0.nx_ip_interface[0].nx_interface_ip_conflict_notify_handler = ip_address_conflict_detection; + + /* Reject the ARP packet without conflict. */ + reject_arp_packet(&ip_0, 0, IP_ADDRESS(1, 2, 3, 5), 0x00000011, 0x22334457, IP_ADDRESS(1, 2, 3, 4), 0x00000011, 0x22334456); + + /* Check the announce counter. */ + if (conflict_counter != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reject the ARP packet with conflict. */ + reject_arp_packet(&ip_0, 0, IP_ADDRESS(1, 2, 3, 4), 0x00000011, 0x22334457, IP_ADDRESS(1, 2, 3, 4), 0x00000011, 0x22334456); + + /* Check the announce counter. */ + if (conflict_counter != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +VOID reject_arp_packet(NX_IP *ip_ptr, UINT interface_index, + ULONG source_ip, ULONG source_physical_msw, ULONG source_physical_lsw, + ULONG target_ip, ULONG target_physical_msw, ULONG target_physical_lsw) +{ + +NX_PACKET *request_ptr; +ULONG *message_ptr; + + + /* Allocate a packet to build the ARP message in. */ + if (nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &request_ptr, NX_PHYSICAL_HEADER, NX_NO_WAIT)) + { + + /* Increment error counter. */ + error_counter ++; + + /* Error getting packet, so just get out! */ + return; + } + + /* Build the ARP request packet. */ + + /* Setup the size of the ARP message. */ + request_ptr -> nx_packet_length = NX_ARP_MESSAGE_SIZE; + + /* Setup the append pointer to the end of the message. */ + request_ptr -> nx_packet_append_ptr = request_ptr -> nx_packet_prepend_ptr + NX_ARP_MESSAGE_SIZE; + + /* Setup the pointer to the message area. */ + message_ptr = (ULONG *) request_ptr -> nx_packet_prepend_ptr; + + /* Write the Hardware type into the message. */ + *message_ptr = (ULONG) (NX_ARP_HARDWARE_TYPE << 16) | (NX_ARP_PROTOCOL_TYPE); + *(message_ptr+1) = (ULONG) (NX_ARP_HARDWARE_SIZE << 24) | (NX_ARP_PROTOCOL_SIZE << 16) | + NX_ARP_OPTION_REQUEST; + *(message_ptr+2) = (ULONG) (source_physical_msw << 16) | (source_physical_lsw >> 16); + *(message_ptr+3) = (ULONG) (source_physical_lsw << 16) | (source_ip >> 16); + *(message_ptr+4) = (ULONG) (source_ip << 16) | (target_physical_msw & 0xFFFF); + *(message_ptr+5) = (ULONG) target_physical_lsw; + *(message_ptr+6) = (ULONG) target_ip; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Set the interface. */ + request_ptr -> nx_packet_ip_interface = &ip_ptr -> nx_ip_interface[interface_index]; + + /* Directly receive this packet as conflict packet. */ + _nx_arp_packet_deferred_receive(ip_ptr, request_ptr); +} + +static void ip_address_conflict_detection(NX_IP *ip_ptr, UINT interface_index, ULONG ip_address, ULONG msw, ULONG lsw) +{ + + /* Update the conflict counter. */ + conflict_counter ++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_address_conflict_callback_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Address Conflict Callback Test.........................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_address_conflict_detection_test.c b/test/regression/netxduo_test/netx_ip_address_conflict_detection_test.c new file mode 100644 index 00000000..d1849e17 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_address_conflict_detection_test.c @@ -0,0 +1,497 @@ +/* This NetX test concentrates on the IPv4 Address Conflict Detection. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_arp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the timing and retry constants for ARP probe and announce. */ + +#define NX_ARP_PROBE_WAIT 1 +#define NX_ARP_PROBE_NUM 3 +#define NX_ARP_PROBE_MIN 1 +#define NX_ARP_PROBE_MAX 2 +#define NX_ARP_ANNOUNCE_WAIT 2 +#define NX_ARP_ANNOUNCE_NUM 2 +#define NX_ARP_ANNOUNCE_INTERVAL 2 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG probe_counter; +static ULONG announce_counter; +static ULONG conflict_counter; +static ULONG gratuitous_responder_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void ip_address_conflict_detection(NX_IP *ip_ptr, UINT interface_index, ULONG ip_address, ULONG msw, ULONG lsw); +static void gratuitous_responder_handler(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_address_conflict_detection_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + probe_counter = 0; + announce_counter = 0; + conflict_counter = 0; + gratuitous_responder_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +UINT packet_counter; +UINT i; +ULONG delay; +NX_PACKET *my_packet[30]; + + + /* Print out some test information banners. */ + printf("NetX Test: IP Address Conflict Detection Test........................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process; + + /* Set the IP address conflict callback function for probing. */ + ip_0.nx_ip_interface[0].nx_interface_ip_conflict_notify_handler = ip_address_conflict_detection; + + /* Allocate all packet from packet pool. */ + packet_counter = pool_0.nx_packet_pool_available; + for(i =0; i < packet_counter; i ++) + { + + /* Allocate the packet. */ + status = nx_packet_allocate(&pool_0, &my_packet[i], NX_TCP_PACKET, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Call to send ARP Probe. */ + status = _nx_arp_probe_send(&ip_0, 0, IP_ADDRESS(1, 2, 3, 4)); + + /* Check status. */ + if (status != NX_NO_PACKET) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release all allocated packet. */ + for(i =0; i < packet_counter; i ++) + { + + /* Allocate the packet. */ + status = nx_packet_release(my_packet[i]); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Delay before probing. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE * NX_ARP_PROBE_WAIT); + + /* Loop to probe for the specified local IP address according to RFC5227. */ + for (i = 0; i < NX_ARP_PROBE_NUM; i++) + { + + /* Send the ARP probe. */ + _nx_arp_probe_send(&ip_0, 0, IP_ADDRESS(1, 2, 3, 4)); + + /* Calculate the delay time. */ + delay = ((ULONG) NX_RAND()) % (NX_IP_PERIODIC_RATE * NX_ARP_PROBE_MAX); + + /* Determine if this is less than the minimum. */ + if (delay < (NX_IP_PERIODIC_RATE * NX_ARP_PROBE_MIN)) + { + + /* Set the delay to the minimum. */ + delay = (NX_IP_PERIODIC_RATE * NX_ARP_PROBE_MIN); + } + + /* Sleep for a small period of time. */ + tx_thread_sleep(delay); + } + + /* Check the probe counter. */ + if ((probe_counter != 3) || (conflict_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Change new address and start probing. */ + + /* Delay before probing. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE * NX_ARP_PROBE_WAIT); + + /* Loop to probe for the specified local IP address according to RFC5227. */ + for (i = 0; i < NX_ARP_PROBE_NUM; i++) + { + + /* Send the ARP probe. */ + _nx_arp_probe_send(&ip_0, 0, IP_ADDRESS(1, 2, 3, 5)); + + /* Calculate the delay time. */ + delay = ((ULONG) NX_RAND()) % (NX_IP_PERIODIC_RATE * NX_ARP_PROBE_MAX); + + /* Determine if this is less than the minimum. */ + if (delay < (NX_IP_PERIODIC_RATE * NX_ARP_PROBE_MIN)) + { + + /* Set the delay to the minimum. */ + delay = (NX_IP_PERIODIC_RATE * NX_ARP_PROBE_MIN); + } + + /* Sleep for a small period of time. */ + tx_thread_sleep(delay); + } + + /* Check the probe counter. */ + if ((probe_counter != 6) || (conflict_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the NetX IP address. */ + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(1, 2, 3, 5), 0xFFFF0000); + + /* Check for status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate all packet from packet pool. */ + packet_counter = pool_0.nx_packet_pool_available; + for(i =0; i < packet_counter; i ++) + { + + /* Allocate the packet. */ + status = nx_packet_allocate(&pool_0, &my_packet[i], NX_TCP_PACKET, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Send the ARP announcement. */ + status = _nx_arp_announce_send(&ip_0, 0); + + /* Check status. */ + if (status != NX_NO_PACKET) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release all allocated packet. */ + for(i =0; i < packet_counter; i ++) + { + + /* Allocate the packet. */ + status = nx_packet_release(my_packet[i]); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Delay before announcing. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE * NX_ARP_ANNOUNCE_WAIT); + + /* It is now time to go into an announce phase to indicate local IP address is ours! + Note:NetX do not give up its address during announce pahse. */ + for (i = 0; i < NX_ARP_ANNOUNCE_NUM; i++) + { + + /* Send the ARP announcement. */ + _nx_arp_announce_send(&ip_0, 0); + + /* Calculate the delay time. */ + delay = (NX_IP_PERIODIC_RATE * NX_ARP_ANNOUNCE_INTERVAL); + + /* Sleep for announce interval. */ + tx_thread_sleep(delay); + } + + /* Check the announce counter. */ + if (announce_counter != 2) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send a gratuitous ARP message. */ + status = nx_arp_gratuitous_send(&ip_0, gratuitous_responder_handler); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep for IP conflict. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the announce counter. */ + if ((announce_counter != 4) || (conflict_counter != 2) || (gratuitous_responder_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +ULONG *message_ptr; +ULONG sender_physical_msw; +ULONG sender_physical_lsw; +ULONG sender_ip_address; +ULONG target_physical_msw; +ULONG target_physical_lsw; +ULONG target_ip_address; +ULONG message_type; + + /* Check the packet length. */ + if (packet_ptr ->nx_packet_length != NX_ARP_MESSAGE_SIZE) + { + + /* Update the error_counter. */ + error_counter++; + + /* Release the packet */ + nx_packet_release(packet_ptr); + + /* Return to caller. */ + return NX_FALSE; + } + + /* Setup a pointer to the ARP message. */ + message_ptr = (ULONG *) packet_ptr -> nx_packet_prepend_ptr; + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Pickup the ARP message type. */ + message_type = (ULONG) (*(message_ptr+1) & 0xFFFF); + + /* Determine if the ARP message type is valid. */ + if (message_type != NX_ARP_OPTION_REQUEST) + { + + /* Update the error_counter. */ + error_counter++; + + /* Release the packet */ + nx_packet_release(packet_ptr); + + /* Return to caller. */ + return NX_FALSE; + } + + + /* Pick up the sender's physical address from the message. */ + sender_physical_msw = (*(message_ptr+2) >> 16); + sender_physical_lsw = (*(message_ptr+2) << 16) | (*(message_ptr+3) >> 16); + sender_ip_address = (*(message_ptr+3) << 16) | (*(message_ptr+4) >> 16); + target_physical_msw = (*(message_ptr+4) & 0x0000FFFF); + target_physical_lsw = *(message_ptr+5); + target_ip_address = *(message_ptr+6); + + /* Check the sender and target information. */ + if (((sender_physical_msw | sender_physical_lsw) != 0) && (sender_ip_address == 0) && + ((target_physical_msw | target_physical_lsw) == 0) && (target_ip_address != 0)) + probe_counter ++; + + else if (((sender_physical_msw | sender_physical_lsw) != 0) && (sender_ip_address != 0) && + ((target_physical_msw | target_physical_lsw) == 0) && (target_ip_address != 0)) + announce_counter ++; + + /* Let IP conflict. */ + if ((probe_counter == 3) || (announce_counter == 3)) + { + + /* Modify the sender MAC address let IP address conflict. */ + *(message_ptr+2) += 0x10; + } + + /* Endian swapping logic. If NX_LITTLE_ENDIAN is specified, these macros will + swap the endian of the ARP message. */ + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+3)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+4)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+5)); + NX_CHANGE_ULONG_ENDIAN(*(message_ptr+6)); + + /* Let IP conflict. */ + if ((probe_counter == 3) || (announce_counter == 3)) + { + + /* Directly receive this packet as conflict packet. */ + _nx_arp_packet_deferred_receive(ip_ptr, packet_ptr); + + return NX_FALSE; + } + + /* Release the packet */ + nx_packet_release(packet_ptr); + + /* Return to caller. */ + return NX_FALSE; +} + +static void ip_address_conflict_detection(NX_IP *ip_ptr, UINT interface_index, ULONG ip_address, ULONG msw, ULONG lsw) +{ + + /* Update the conflict counter. */ + conflict_counter ++; +} + +static void gratuitous_responder_handler(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + /* Update the gratuitous_responder_counter. */ + gratuitous_responder_counter ++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_address_conflict_detection_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Address Conflict Detection Test........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_address_get_test.c b/test/regression/netxduo_test/netx_ip_address_get_test.c new file mode 100644 index 00000000..677e8f19 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_address_get_test.c @@ -0,0 +1,204 @@ +/* This NetX test concentrates on the IP Address Get operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_address_get_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG address; +ULONG mask; + + /* Print out test information banner. */ + printf("NetX Test: IP Address Get Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_address_get(&ip_0, &address, &mask); + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(1,2,3,4)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_address_get(&ip_0, 1, &address, &mask); + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(4, 3, 2, 10)) || (mask != 0xFF000000)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_get(&ip_0, 2, &address, &mask); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + status = nx_ip_address_get(&ip_1, &address, &mask); + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(1,2,3,5)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_address_get(&ip_1, 1, &address, &mask); + + + if((status != NX_SUCCESS ) || (address != IP_ADDRESS(4,3,2,11)) || (mask != 0xFF000000)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_get(&ip_1, 2, &address, &mask); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + printf("SUCCESS!\n"); + test_control_return(0); + +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_address_get_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Address Get Test.......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_address_set_test.c b/test/regression/netxduo_test/netx_ip_address_set_test.c new file mode 100644 index 00000000..faf1d33e --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_address_set_test.c @@ -0,0 +1,462 @@ +/* This NetX test concentrates on the IP Address Set operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_address_set_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 14), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 15), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG address; +ULONG mask; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; +ULONG my_packet_length; + + + /* Print out test information banner. */ + printf("NetX Test: IP Address Set Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 110), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 111), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Make sure we can ping using the current IP address. */ + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(4, 3, 2, 91), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(4, 3, 2, 110), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + status += nx_packet_length_get(my_packet, &my_packet_length); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* It should also be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(1, 2, 3, 14), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping via the other direction. */ + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 9), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 111), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* It should also be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 15), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((pings_sent != 3) || (ping_timeouts != 1) || (ping_responses_received != 2) || (icmp_checksum_errors) || + (icmp_unhandled_messages)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (ping_threads_suspended)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_1, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((pings_sent != 3) || (ping_timeouts != 1) || (ping_responses_received != 2) || (icmp_checksum_errors) || + (icmp_unhandled_messages)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (ping_threads_suspended)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reconfigure the interface IP addresses. */ + status = nx_ip_interface_address_set(&ip_0, 1, IP_ADDRESS(4, 3, 2, 10), 0xFFFFFF00); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_set(&ip_0, 2, IP_ADDRESS(4, 3, 2, 15), 0xFFFFF000); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + status = nx_ip_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_address_set(&ip_1, 1, IP_ADDRESS(4, 3, 2, 11), 0xFFFFFF00); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_set(&ip_1, 2, IP_ADDRESS(4, 3, 2, 15), 0xFFFFF000); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + status = nx_ip_address_set(&ip_1, IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Make sure we can ping via the new interface IP address. */ + /* Make sure we can ping using the current IP address. */ + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(4, 3, 2, 91), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(4, 3, 2, 10), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* It should also be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(1, 2, 3, 4), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping via the other direction. */ + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 9), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 11), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* It should also be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + + if ((pings_sent != 6) || (ping_timeouts != 2) || (ping_responses_received != 4) ||(icmp_checksum_errors) || (icmp_unhandled_messages)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (ping_threads_suspended)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_1, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + + if ((pings_sent != 6) || (ping_timeouts != 2) || (ping_responses_received != 4) ||(icmp_checksum_errors) || (icmp_unhandled_messages)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (ping_threads_suspended)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + status = nx_ip_interface_address_get(&ip_0, 0, &address, &mask); + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(1, 2, 3, 4)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + status = nx_ip_interface_address_get(&ip_0, 1, &address, &mask); + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(4, 3, 2, 10)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_get(&ip_0, 2, &address, &mask); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + status = nx_ip_interface_address_get(&ip_1, 0, &address, &mask); + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(1, 2, 3, 5)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_address_get(&ip_1, 1, &address, &mask); + + if((status != NX_SUCCESS ) || (address != IP_ADDRESS(4, 3, 2, 11)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_get(&ip_1, 2, &address, &mask); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + printf("SUCCESS!\n"); + test_control_return(0); + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_address_set_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Address Set Test.......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_auxiliary_packet_pool_set_test.c b/test/regression/netxduo_test/netx_ip_auxiliary_packet_pool_set_test.c new file mode 100644 index 00000000..1e8183ae --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_auxiliary_packet_pool_set_test.c @@ -0,0 +1,167 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +#if defined __PRODUCT_NETXDUO__ && defined NX_ENABLE_DUAL_PACKET_POOL + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL auxiliary_pool_0; +static NX_PACKET_POOL auxiliary_pool_1; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_auxiliary_packet_pool_set_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. 256 * 10= 2560 */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2560); + pointer = pointer + 2560; + + if (status) + error_counter++; + + /* Create a auxiliary packet pool 0. 128*10 = 1280 */ + status = nx_packet_pool_create(&auxiliary_pool_0, "NetX Auxiliary Packet Pool 0", 128, pointer, 1280); + pointer = pointer + 1280; + + if (status) + error_counter++; + + /* Create a auxiliary packet pool 1. 512*10 = 5120 */ + status = nx_packet_pool_create(&auxiliary_pool_1, "NetX Auxiliary Packet Pool 1", 512, pointer, 5120); + pointer = pointer + 5120; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: IP Auxiliary Packet Pool Set Test........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the auxiliary packet pool 0 for IP instance 0. */ + status = nx_ip_auxiliary_packet_pool_set(&ip_0, &auxiliary_pool_0); + + /* Check the status. */ + if(status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the default packet pool and auxiliary packet pool. */ + if ((ip_0.nx_ip_default_packet_pool != &pool_0) || + (ip_0.nx_ip_auxiliary_packet_pool != &auxiliary_pool_0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the auxiliary packet pool 1 for IP instance 1. */ + status = nx_ip_auxiliary_packet_pool_set(&ip_0, &auxiliary_pool_1); + + /* Check the status. */ + if(status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the default packet pool and auxiliary packet pool. */ + if ((ip_0.nx_ip_default_packet_pool != &auxiliary_pool_1) || + (ip_0.nx_ip_auxiliary_packet_pool != &auxiliary_pool_0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_auxiliary_packet_pool_set_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Auxiliary Packet Pool Set Test.........................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_basic_test.c b/test/regression/netxduo_test/netx_ip_basic_test.c new file mode 100644 index 00000000..7783be60 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_basic_test.c @@ -0,0 +1,386 @@ +/* This NetX test concentrates on the basic IP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *ip_0_memory_ptr; +static CHAR *ip_1_memory_ptr; +static CHAR *arp_0_memory_ptr; +static CHAR *arp_1_memory_ptr; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern ULONG simulated_address_msw; +extern ULONG simulated_address_lsw; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create IP instances. */ + ip_0_memory_ptr = pointer; + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + ip_1_memory_ptr = pointer; + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 10), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + arp_0_memory_ptr = pointer; + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + arp_1_memory_ptr = pointer; + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_address; +ULONG mask; +ULONG value; +ULONG ip_total_packets_sent; +ULONG ip_total_bytes_sent; +ULONG ip_total_packets_received; +ULONG ip_total_bytes_received; +ULONG ip_invalid_packets; +ULONG ip_receive_packets_dropped; +ULONG ip_receive_checksum_errors; +ULONG ip_send_packets_dropped; +ULONG ip_total_fragments_sent; +ULONG ip_total_fragments_received; +#ifdef __PRODUCT_NETXDUO__ +ULONG physical_msw; +ULONG physical_lsw; +ULONG gateway_addr_getted; +#endif /* __PRODUCT_NETXDUO__ */ +#ifdef NX_ENABLE_IP_STATIC_ROUTING +NX_INTERFACE + *if_ptr = NX_NULL; +ULONG next_hop_address; + + + /* Test static routing. */ + /* Add static route. */ + nx_ip_static_route_add(&ip_0, IP_ADDRESS(1, 2, 3, 0), 0xFFFFFF00UL, IP_ADDRESS(1, 2, 3, 2)); + + nx_ip_static_route_add(&ip_0, IP_ADDRESS(1, 2, 3, 0), 0xFFFFFF00UL, IP_ADDRESS(1, 2, 3, 1)); + + nx_ip_static_route_add(&ip_0, IP_ADDRESS(1, 2, 4, 0), 0xFFFFFF00UL, IP_ADDRESS(1, 2, 3, 1)); + + /* Find route. */ + _nx_ip_route_find(&ip_0, IP_ADDRESS(1, 2, 3, 2), &if_ptr, &next_hop_address); + + /* Check interface and next hop address. */ + if((if_ptr != &ip_0.nx_ip_interface[0]) || + (next_hop_address != IP_ADDRESS(1, 2, 3, 1))) + error_counter++; +#endif /* NX_ENABLE_IP_STATIC_ROUTING */ + + + /* Print out test information banner. */ + printf("NetX Test: IP Basic Operation Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the IP address. */ + status = nx_ip_address_get(&ip_0, &ip_address, &mask); + + /* Check for an error. */ + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 9))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address. */ + status = nx_ip_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 13), 0xFFFFFF00UL); + status += nx_ip_address_get(&ip_0, &ip_address, &mask); + + /* Check for an error. */ + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 13))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_IP_STATIC_ROUTING + /* Delete a static route. */ + status = nx_ip_static_route_delete(&ip_0, IP_ADDRESS(1,2,4,0), 0xFFFFFF00UL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + + /* Delete both IP instances. */ + status = nx_ip_delete(&ip_0); + status += nx_ip_delete(&ip_1); + + /* Check for an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_0_memory_ptr, 2048, 1); + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_1_memory_ptr, 2048, 1); + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_0, (void *) arp_0_memory_ptr, 1024); + status += nx_arp_enable(&ip_1, (void *) arp_1_memory_ptr, 1024); + + /* Check the status of the IP instances. */ + status += nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_INITIALIZE_DONE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call driver directly. */ + status = nx_ip_driver_direct_command(&ip_0, NX_LINK_GET_STATUS, &value); + + /* Check for an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call driver directly specifying the interface. */ + status = nx_ip_driver_interface_direct_command(&ip_0, NX_LINK_GET_STATUS, 0, &value); + + /* Check for an error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable and disable forwarding. */ + status = nx_ip_forwarding_enable(&ip_0); + status += nx_ip_forwarding_disable(&ip_0); + + /* Check for an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Enable fragment feature. */ + status = nx_ip_fragment_enable(&ip_0); + +#ifndef NX_DISABLE_FRAGMENTATION + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#else + /* Check the status. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Disable fragment feature. */ + status = nx_ip_fragment_disable(&ip_0); + +#ifndef NX_DISABLE_FRAGMENTATION + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#else + /* Check the status. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif +#endif + + /* Set the gateway address. */ + status = nx_ip_gateway_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 87)); + + /* Check for an error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + status = nx_ip_gateway_address_get(&ip_0, &gateway_addr_getted); + if((status != NX_SUCCESS) || gateway_addr_getted != IP_ADDRESS(1,2,3,87)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ + +#ifdef __PRODUCT_NETXDUO__ + /* Get Mac address. */ + status = nx_ip_interface_physical_address_get(&ip_0, 0, &physical_msw, &physical_lsw); + if((status != NX_SUCCESS) || + (physical_msw != simulated_address_msw) || + (physical_lsw != simulated_address_lsw)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_gateway_address_clear(&ip_0); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ + + /* Get nothing from IP info. */ + status = nx_ip_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get IP info. */ + status = nx_ip_info_get(&ip_0, &ip_total_packets_sent, + &ip_total_bytes_sent, + &ip_total_packets_received, + &ip_total_bytes_received, + &ip_invalid_packets, + &ip_receive_packets_dropped, + &ip_receive_checksum_errors, + &ip_send_packets_dropped, + &ip_total_fragments_sent, + &ip_total_fragments_received); + + /* Check status. */ + if ((status) || (ip_total_packets_sent) || (ip_total_bytes_sent) || (ip_total_packets_received) || + (ip_total_bytes_received) || (ip_invalid_packets) || (ip_receive_packets_dropped) || (ip_receive_checksum_errors) || + (ip_send_packets_dropped) || (ip_total_fragments_sent) || (ip_total_fragments_received)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Basic Operation Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_branch_test.c b/test/regression/netxduo_test/netx_ip_branch_test.c new file mode 100644 index 00000000..fc4df347 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_branch_test.c @@ -0,0 +1,1143 @@ +/* This NetX test concentrates on the code coverage for IP functions, + * _nx_ip_deferred_link_status_process.c + * _nx_ip_interface_detach.c + * _nx_ip_max_payload_size_find.c + * _nx_ip_packet_receive.c + */ + +#include "nx_ip.h" +#include "nx_api.h" +#include "tx_thread.h" +#include "nx_icmp.h" +#include "nx_arp.h" +#include "nx_rarp.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nx_udp.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_test1; +static TX_THREAD thread_test2; +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_ASSERT +static TX_THREAD thread_for_assert; +static UINT assert_count = 0; +#endif +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static CHAR *pointer; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID suspend_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER); +static VOID link_status_change_callback(NX_IP *ip_ptr, UINT interface_index, UINT link_status); +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_ASSERT +static void thread_for_assert_entry(ULONG thread_input); +#endif +#ifdef FEATURE_NX_IPV6 +static UINT my_raw_packet_processing(NX_IP *ip_ptr, ULONG protocol, NX_PACKET *packet_ptr); +#endif + +#ifdef __PRODUCT_NETXDUO__ +static char pkt1[590] = { +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x08, 0x00, 0x45, 0x00, /* "3DX..E. */ +0x02, 0x40, 0x00, 0x01, 0x40, 0x00, 0x80, 0x11, /* .@..@... */ +0xf8, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x44, 0x00, 0x43, 0x02, 0x2c, /* ...D.C., */ +0xd7, 0x45, 0x01, 0x01, 0x06, 0x00, 0x22, 0x33, /* .E...."3 */ +0x44, 0x60, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, /* D`...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* "3DX.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x01, 0x33, 0x04, 0xff, /* Sc5..3.. */ +0xff, 0xff, 0xff, 0x0c, 0x0b, 0x64, 0x68, 0x63, /* .....dhc */ +0x70, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, /* p_client */ +0x37, 0x03, 0x01, 0x03, 0x06, 0xff, 0x00, 0x00, /* 7....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Frame (342 bytes) */ +static char pkt2[342] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x58, 0x00, 0x50, /* .."3DX.P */ +0x56, 0x39, 0xf6, 0x3d, 0x08, 0x00, 0x45, 0x10, /* V9.=..E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x25, 0x7d, 0x0a, 0x00, 0x00, 0x01, 0x0a, 0x00, /* %}...... */ +0x00, 0x18, 0x00, 0x3c, 0x00, 0x44, 0x01, 0x34, /* ...<.D.4 */ +0xdb, 0x3c, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .<...."3 */ +0x44, 0x60, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, /* D`...... */ +0x00, 0x00, 0x0a, 0x00, 0x00, 0x18, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* "3DX.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x02, 0x36, 0x04, 0x0a, /* Sc5..6.. */ +0x00, 0x00, 0x01, 0x33, 0x04, 0x00, 0x00, 0x01, /* ...3.... */ +0x2c, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ,....... */ +0x04, 0x0a, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Frame (342 bytes) */ +static char pkt3[342] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x58, 0x00, 0x50, /* .."3DX.P */ +0x56, 0x39, 0xf6, 0x3d, 0x08, 0x00, 0x45, 0x10, /* V9.=..E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x25, 0x7d, 0x0a, 0x00, 0x00, 0x01, 0x0a, 0x00, /* %}...... */ +0x00, 0x18, 0x00, 0x43, 0x00, 0x46, 0x01, 0x34, /* ...C.F.4 */ +0xd8, 0x32, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .2...."3 */ +0x44, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, /* D`...... */ +0x00, 0x00, 0x0a, 0x00, 0x00, 0x18, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* "3DX.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x36, 0x04, 0x0a, /* Sc5..6.. */ +0x00, 0x00, 0x01, 0x33, 0x04, 0x00, 0x00, 0x01, /* ...3.... */ +0x2c, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ,....... */ +0x04, 0x0a, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +/* Frame (342 bytes) */ +static const unsigned char pkt4[342] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x58, 0x00, 0x50, /* .."3DX.P */ +0x56, 0x39, 0xf6, 0x3d, 0x08, 0x00, 0x45, 0x10, /* V9.=..E. */ +0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, /* .H...... */ +0x25, 0x7d, 0x0a, 0x00, 0x00, 0x01, 0x0a, 0x00, /* %}...... */ +0x00, 0x18, 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, /* ...C.D.4 */ +0xd8, 0x34, 0x02, 0x01, 0x06, 0x00, 0x22, 0x33, /* .4...."3 */ +0x44, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, /* D`...... */ +0x00, 0x00, 0x0a, 0x00, 0x00, 0x18, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, /* ........ */ +0x22, 0x33, 0x44, 0x58, 0x00, 0x00, 0x00, 0x00, /* "3DX.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, /* ......c. */ +0x53, 0x63, 0x35, 0x01, 0x05, 0x36, 0x04, 0x0a, /* Sc5..6.. */ +0x00, 0x00, 0x01, 0x33, 0x04, 0x00, 0x00, 0x01, /* ...3.... */ +0x2c, 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, 0x03, /* ,....... */ +0x04, 0x0a, 0x00, 0x00, 0x01, 0xff, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + + +#ifdef FEATURE_NX_IPV6 +static const unsigned char pkt5[78] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x18, 0x00, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x3a, 0x00, /* "..3DV:. */ +0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* ........ */ +0x09, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* ........ */ +0x03, 0x04, 0x05, 0x06, 0x07, 0x08 /* ...... */ +}; +#endif /* FEATURE_NX_IPV6 */ +#endif + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_branch_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 800, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 processing for IP instance. */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if (status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG thread_state; +NX_PACKET *my_packet[2]; + +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS dest_address; +ULONG src_ip_addr = 0x01020304; +ULONG dest_ip_addr = 0x01020305; +NX_IPV4_HEADER *ip_header_ptr; +NX_ARP *temp_arp; +#endif /* __PRODUCT_NETXDUO__ */ +NX_INTERFACE + *if_ptr = NX_NULL; +ULONG next_hop_address; +#ifndef NX_DISABLE_LOOPBACK_INTERFACE +UINT i; +#endif +#ifdef FEATURE_NX_IPV6 +NX_IPV6_HEADER *ipv6_header_ptr; +#endif /* FEATURE_NX_IPV6 */ + + + /* Print out some test information banners. */ + printf("NetX Test: IP Branch Test............................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Hit false condition of ip_ptr -> nx_ip_interface[i].nx_interface_link_status_change in _nx_ip_deferred_link_status_process(). */ + ip_0.nx_ip_link_status_change_callback = link_status_change_callback; + ip_0.nx_ip_interface[0].nx_interface_link_status_change = NX_FALSE; + _nx_ip_deferred_link_status_process(&ip_0); + ip_0.nx_ip_interface[0].nx_interface_link_status_change = NX_TRUE; + _nx_ip_deferred_link_status_process(&ip_0); + + /* Recover. */ + ip_0.nx_ip_link_status_change_callback = NX_NULL; + + +#ifdef __PRODUCT_NETXDUO__ + /* Hit condition of if (interface_ptr -> nx_interface_valid == NX_FALSE) in _nx_ip_max_payload_size_find(). */ + dest_address.nxd_ip_version = NX_IP_VERSION_V4; + _nx_ip_max_payload_size_find(&ip_0, &dest_address, 0, 0, 0, NX_PROTOCOL_TCP, NX_NULL, NX_NULL); + _nx_ip_max_payload_size_find(&ip_0, &dest_address, NX_MAX_PHYSICAL_INTERFACES, 0, 0, NX_PROTOCOL_TCP, NX_NULL, NX_NULL); + _nx_ip_max_payload_size_find(&ip_0, &dest_address, 0, 0, 0, NX_PROTOCOL_ICMP, NX_NULL, NX_NULL); + + +#if (NX_MAX_PHYSICAL_INTERFACES >= 2) + /* Hit condition of if (interface_ptr -> nx_interface_valid == NX_FALSE) in _nx_ip_interface_detach(). */ + _nx_ip_interface_detach(&ip_0, 1); + nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver_256); + _nx_ip_interface_detach(&ip_0, 1); +#endif + +#endif /* __PRODUCT_NETXDUO__ */ + + + + /* Test _nx_ip_raw_packet_cleanup(). */ + /* tx_thread_suspend_control_block is set to NULL. */ + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + _nx_ip_raw_packet_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* tx_thread_suspend_control_block is set to IP but tx_thread_suspend_cleanup is set to NULL. */ + tx_thread_identify() -> tx_thread_suspend_control_block = &ip_0; + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + _nx_ip_raw_packet_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* tx_thread_suspend_control_block is set to IP and tx_thread_suspend_cleanup is set to suspend_cleanup, but clear the IP ID. */ + tx_thread_identify() -> tx_thread_suspend_control_block = &ip_0; + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + ip_0.nx_ip_id = 0; + _nx_ip_raw_packet_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + ip_0.nx_ip_id = NX_IP_ID; + + ip_0.nx_ip_raw_packet_suspended_count ++; + tx_thread_identify() -> tx_thread_suspended_next = tx_thread_identify(); + thread_state = tx_thread_identify() -> tx_thread_state; + tx_thread_identify() -> tx_thread_state = 0; + _nx_ip_raw_packet_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + tx_thread_identify() -> tx_thread_state = thread_state; + + + /* Setup tx_thread_suspend_cleanup, control block. */ + ip_0.nx_ip_raw_packet_suspended_count ++; + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = &ip_0; + tx_thread_identify() -> tx_thread_suspended_next = &thread_test1; + tx_thread_identify() -> tx_thread_suspended_previous = &thread_test2; + thread_state = tx_thread_identify() -> tx_thread_state; + tx_thread_identify() -> tx_thread_state = 0; + _nx_ip_raw_packet_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + tx_thread_identify() -> tx_thread_state = thread_state; + + +#ifdef FEATURE_NX_IPV6 + /* Hit condition of if (ip_version == NX_IP_VERSION_V4 && ip_ptr -> nx_ipv4_packet_receive) and if (ip_version == NX_IP_VERSION_V6 && ip_ptr -> nx_ipv6_packet_receive) in _nx_ip_packet_receive(). */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + *(my_packet[0] -> nx_packet_prepend_ptr) = NX_IP_VERSION_V4 << 4; + ip_0.nx_ipv4_packet_receive = NX_NULL; + _nx_ip_packet_receive(&ip_0, my_packet[0]); + *(my_packet[0] -> nx_packet_prepend_ptr) = NX_IP_VERSION_V6 << 4; + ip_0.nx_ipv6_packet_receive = NX_NULL; + _nx_ip_packet_receive(&ip_0, my_packet[0]); + ip_0.nx_ipv4_packet_receive = _nx_ipv4_packet_receive; + ip_0.nx_ipv6_packet_receive = _nx_ipv6_packet_receive; + nx_packet_release(my_packet[0]); +#endif /* FEATURE_NX_IPV6 */ + + /* Test nx_ip_route_find with a down interface for multicast address. */ + ip_0.nx_ip_interface[0].nx_interface_link_up = NX_FALSE; + if_ptr = &ip_0.nx_ip_interface[0]; + _nx_ip_route_find(&ip_0, IP_ADDRESS(224, 2, 3, 2), &if_ptr, &next_hop_address); + ip_0.nx_ip_interface[0].nx_interface_link_up = NX_TRUE; + + /* Hit the condition that (*ip_interface_ptr != interface_ptr). */ + if_ptr = &ip_0.nx_ip_interface[4]; + _nx_ip_route_find(&ip_0, IP_ADDRESS(1, 2, 3, 4), &if_ptr, &next_hop_address); + + /* Test nx_ip_route_find with a down interface for link local address. */ + ip_0.nx_ip_interface[0].nx_interface_link_up = NX_FALSE; + if_ptr = &ip_0.nx_ip_interface[0]; + _nx_ip_route_find(&ip_0, IP_ADDRESS(169, 254, 3, 2), &if_ptr, &next_hop_address); + ip_0.nx_ip_interface[0].nx_interface_link_up = NX_TRUE; + + /* Test nx_ip_route_find with a invalid interface for link local address. */ + ip_0.nx_ip_interface[0].nx_interface_valid = NX_FALSE; + if_ptr = &ip_0.nx_ip_interface[0]; + _nx_ip_route_find(&ip_0, IP_ADDRESS(169, 254, 3, 2), &if_ptr, &next_hop_address); + ip_0.nx_ip_interface[0].nx_interface_valid = NX_TRUE; + + + /* Test nx_ip_route_find with a null interface for link local address. */ + ip_0.nx_ip_interface[0].nx_interface_link_up = NX_FALSE; + ip_0.nx_ip_interface[4].nx_interface_valid = NX_FALSE; + if_ptr = NX_NULL; + _nx_ip_route_find(&ip_0, IP_ADDRESS(169, 254, 3, 2), &if_ptr, &next_hop_address); + ip_0.nx_ip_interface[0].nx_interface_link_up = NX_TRUE; + ip_0.nx_ip_interface[4].nx_interface_valid = NX_TRUE; + + /* Test nx_ip_route_find with a invalid gateway interface. */ + ip_0.nx_ip_gateway_address = IP_ADDRESS(1, 2, 3, 5); + if_ptr = &ip_0.nx_ip_interface[0]; + _nx_ip_route_find(&ip_0, IP_ADDRESS(2, 3, 4, 5), &if_ptr, &next_hop_address); + ip_0.nx_ip_gateway_interface = &ip_0.nx_ip_interface[4]; + ip_0.nx_ip_interface[4].nx_interface_link_up = NX_FALSE; + _nx_ip_route_find(&ip_0, IP_ADDRESS(2, 3, 4, 5), &if_ptr, &next_hop_address); + ip_0.nx_ip_interface[4].nx_interface_link_up = NX_TRUE; + ip_0.nx_ip_gateway_interface = NX_NULL; + ip_0.nx_ip_gateway_address = 0; + +#ifdef FEATURE_NX_IPV6 + /* Test _nx_ipv4_option_process with invalid options. */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + *(my_packet[0] -> nx_packet_prepend_ptr + 3) = NX_IP_VERSION_V4 << 4 | 15; + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER)) = NX_IP_OPTION_INTERNET_TIMESTAMP; + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + 1) = 40; + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + 2) = 6; + _nx_ipv4_option_process(&ip_0, my_packet[0]); + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + 1) = 39; + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + 2) = 5; + _nx_ipv4_option_process(&ip_0, my_packet[0]); + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + 1) = 41; + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + 2) = 5; + _nx_ipv4_option_process(&ip_0, my_packet[0]); + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + 1) = 40; + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + 3) = 1; + _nx_ipv4_option_process(&ip_0, my_packet[0]); + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER) + 3) = 3; + _nx_ipv4_option_process(&ip_0, my_packet[0]); + nx_packet_release(my_packet[0]); +#endif + +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_ASSERT + /* Test _nx_ip_header_add(). */ + /* Hit NX_ASSERT(packet_ptr -> nx_packet_prepend_ptr >= packet_ptr -> nx_packet_data_start); */ + + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + + /* Test _nx_ip_checksum_compute(). */ + /* Hit condition: src_ip_addr == NX_NULL; + 152 [ + - ][ - + ]: NX_ASSERT((src_ip_addr != NX_NULL) && (dest_ip_addr != NX_NULL)); */ + + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + /* Hit condition: dest_ip_addr == NX_NULL; + 152 [ + - ][ - + ]: NX_ASSERT((src_ip_addr != NX_NULL) && (dest_ip_addr != NX_NULL)); */ + + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); +#endif /* NX_DISABLE_ASSERT */ + + +#ifdef __PRODUCT_NETXDUO__ + /* Test _nx_ip_checksum_compute.*/ + /* Hit condition: 208 [ + - ]: while (current_packet) */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 9; + my_packet[0] -> nx_packet_length = 9; + _nx_ip_checksum_compute(my_packet[0], NX_PROTOCOL_UDP, 9, &src_ip_addr, &dest_ip_addr); + nx_packet_release(my_packet[0]); + + + +#ifndef NX_DISABLE_PACKET_CHAIN + /* Test _nx_ipv4_packet_receive. */ + /* Hit condition: 268 [ + - ]: while (delta) */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + nx_packet_allocate(&pool_0, &my_packet[1], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 30; + my_packet[0] -> nx_packet_length = 30; + my_packet[0] -> nx_packet_next = my_packet[1]; + my_packet[0] -> nx_packet_last = my_packet[1]; + ip_header_ptr = (NX_IPV4_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + ip_header_ptr -> nx_ip_header_word_0 = (NX_IP_VERSION | NX_IP_NORMAL | (0xFFFF & 22)); + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + my_packet[1] -> nx_packet_append_ptr = my_packet[1] -> nx_packet_prepend_ptr + 8; + my_packet[1] -> nx_packet_length = 8; + my_packet[0] -> nx_packet_ip_header = my_packet[0] -> nx_packet_prepend_ptr; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + _nx_ipv4_packet_receive(&ip_0, my_packet[0]); +#endif + + + /* Hit true condition: (ip_header_ptr -> nx_ip_header_destination_ip == 0) */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + memcpy(my_packet[0] ->nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + sizeof(pkt1) - 14; + my_packet[0] -> nx_packet_length = sizeof(pkt1) - 14; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + my_packet[0] -> nx_packet_ip_header = my_packet[0] -> nx_packet_prepend_ptr; + _nx_ipv4_packet_receive(&ip_0, my_packet[0]); + + + /* Hit true condition: src_port = 70; + 755 [ + - ][ + - ]: if ((src_port == 67) && (dest_port == 68)) */ + ip_0.nx_ip_interface[0].nx_interface_ip_address = 0; + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + memcpy(my_packet[0] ->nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) - 14); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + sizeof(pkt2) - 14; + my_packet[0] -> nx_packet_length = sizeof(pkt2) - 14; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + my_packet[0] -> nx_packet_ip_header = my_packet[0] -> nx_packet_prepend_ptr; + _nx_ipv4_packet_receive(&ip_0, my_packet[0]); + ip_0.nx_ip_interface[0].nx_interface_ip_address = IP_ADDRESS(1, 2, 3, 4); + + + /* Hit true condition: dest_port = 70; + 755 [ + - ][ + - ]: if ((src_port == 67) && (dest_port == 68)) */ + ip_0.nx_ip_interface[0].nx_interface_ip_address = 0; + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + memcpy(my_packet[0] ->nx_packet_prepend_ptr, &pkt3[14], sizeof(pkt3) - 14); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + sizeof(pkt3) - 14; + my_packet[0] -> nx_packet_length = sizeof(pkt3) - 14; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + my_packet[0] -> nx_packet_ip_header = my_packet[0] -> nx_packet_prepend_ptr; + _nx_ipv4_packet_receive(&ip_0, my_packet[0]); + ip_0.nx_ip_interface[0].nx_interface_ip_address = IP_ADDRESS(1, 2, 3, 4); + + /* Hit true condition: + 757 [ + - ]: if (ip_ptr -> nx_ip_udp_packet_receive) */ + ip_0.nx_ip_interface[0].nx_interface_ip_address = 0; + ip_0.nx_ip_udp_packet_receive = NX_NULL; + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + memcpy(my_packet[0] ->nx_packet_prepend_ptr, &pkt4[14], sizeof(pkt4) - 14); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + sizeof(pkt4) - 14; + my_packet[0] -> nx_packet_length = sizeof(pkt4) - 14; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + my_packet[0] -> nx_packet_ip_header = my_packet[0] -> nx_packet_prepend_ptr; + _nx_ipv4_packet_receive(&ip_0, my_packet[0]); + ip_0.nx_ip_interface[0].nx_interface_ip_address = IP_ADDRESS(1, 2, 3, 4); + ip_0.nx_ip_udp_packet_receive = _nx_udp_packet_receive; +#endif + + + /* Test _nx_ip_delete. */ + nx_ip_fragment_enable(&ip_0); + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + nx_packet_allocate(&pool_0, &my_packet[1], 0, NX_NO_WAIT); + ip_0.nx_ip_deferred_received_packet_head = my_packet[0]; + ip_0.nx_ip_deferred_received_packet_tail = my_packet[0]; + ip_0.nx_ip_raw_packet_suspension_list = &thread_test1; + ip_0.nx_ip_raw_packet_suspended_count ++; + thread_test1.tx_thread_suspend_cleanup = suspend_cleanup; + thread_test1.tx_thread_suspend_control_block = &ip_0; + thread_test1.tx_thread_suspended_next = &thread_test1; + _nx_ip_delete(&ip_0); + + + + /* Test _nx_ip_thread_entry() */ + /* Hit condition: if ((ip_ptr -> nx_ip_interface[i].nx_interface_valid) && (ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)) */ + /* Create an IP instance. */ + _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, NX_NULL, + pointer, 2048, 1); + pointer = pointer + 2048; + ip_0.nx_ip_interface[0].nx_interface_link_driver_entry = _nx_ram_network_driver_256; + _nx_ip_delete(&ip_0); + + + /* Create an IP instance. */ + nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Hit condition: 394 [ + - ]: if (!ip_events) */ + /* Enable TCP. */ + nx_tcp_enable(&ip_0); + + /* Wakeup IP thread for processing one or more messages in the TCP queue. */ + tx_event_flags_set(&(ip_0.nx_ip_events), NX_IP_TCP_EVENT, TX_OR); + + /* Let IP thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Wakeup IP thread for processing one or more messages in the TCP queue. */ + tx_event_flags_set(&(ip_0.nx_ip_events), NX_IP_TCP_EVENT | NX_IP_ARP_REC_EVENT, TX_OR); + + /* Let IP thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + + /* Hit condition: 546 [ + + ][ + - ]: if ((ip_events & NX_IP_ARP_REC_EVENT) && (ip_ptr -> nx_ip_arp_queue_process)) */ + ip_0.nx_ip_arp_queue_process = NX_NULL; + + /* Set NX_IP_ARP_REC_EVENT. */ + tx_event_flags_set(&(ip_0.nx_ip_events), NX_IP_ARP_REC_EVENT, TX_OR); + + /* Let IP thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + ip_0.nx_ip_arp_queue_process = _nx_arp_queue_process; + + + /* Hit condition: 554 [ + + ][ + - ]: if ((ip_events & NX_IP_RARP_REC_EVENT) && (ip_ptr -> nx_ip_rarp_queue_process)) */ + ip_0.nx_ip_rarp_queue_process = NX_NULL; + + /* Set NX_IP_RARP_REC_EVENT. */ + tx_event_flags_set(&(ip_0.nx_ip_events), NX_IP_RARP_REC_EVENT, TX_OR); + + /* Let IP thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + ip_0.nx_ip_arp_queue_process = _nx_rarp_queue_process; + + +#ifndef NX_DISABLE_LOOPBACK_INTERFACE + /* Hit condition: 627 [ + + ][ + - ]: while ((ip_ptr -> nx_ip_interface[index].nx_interface_valid) && (index < NX_MAX_PHYSICAL_INTERFACES)) */ + /* Set the all interface as valid. */ + for (i = 1; i < NX_MAX_IP_INTERFACES; i++) + { + /* Set all interface as valid. */ + ip_0.nx_ip_interface[i].nx_interface_valid = 1; + ip_0.nx_ip_interface[i].nx_interface_link_driver_entry = _nx_ram_network_driver_256; + } + + /* Set NX_IP_DRIVER_DEFERRED_EVENT. */ + tx_event_flags_set(&(ip_0.nx_ip_events), NX_IP_DRIVER_DEFERRED_EVENT, TX_OR); + + /* Let IP thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Clear the valid flag except interface 0. */ + for (i = 1; i < NX_MAX_IP_INTERFACES; i++) + { + /* Set all interface as valid. */ + ip_0.nx_ip_interface[i].nx_interface_valid = 0; + ip_0.nx_ip_interface[i].nx_interface_link_driver_entry = NX_NULL; + } +#endif + + + +#ifdef __PRODUCT_NETXDUO__ + /* Test _nx_ip_forward_packet_process() */ + /* Hit condition: + 147 [ + + ][ - + ]: 46 : if (((ip_header_ptr -> nx_ip_header_source_ip & 0xFFFF0000) == 0xA9FE0000) || + 148 : 45 : ((ip_header_ptr -> nx_ip_header_destination_ip & 0xFFFF0000) == 0xA9FE0000)) + */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + ip_header_ptr = (NX_IPV4_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + ip_header_ptr -> nx_ip_header_source_ip = 0x01020305; + ip_header_ptr -> nx_ip_header_destination_ip = 0xA9FE0000; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 20; + my_packet[0] -> nx_packet_length = 20; + _nx_ip_forward_packet_process(&ip_0, my_packet[0]); + + + + /* Hit condition: first [ + - ] + 361 [ + - ][ + - ]: 7 : if ((ip_ptr -> nx_ip_fragment_processing) && (!(fragment_bits & NX_IP_DONT_FRAGMENT))) + */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 600; + my_packet[0] -> nx_packet_length = 600; + ip_header_ptr = (NX_IPV4_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + ip_header_ptr -> nx_ip_header_word_0 = (NX_IP_VERSION | NX_IP_NORMAL | (0xFFFF & my_packet[0] -> nx_packet_length)); +#ifdef NX_ENABLE_IP_ID_RANDOMIZATION + ip_header_ptr -> nx_ip_header_word_1 = (((ULONG)NX_RAND()) << NX_SHIFT_BY_16) | NX_FRAGMENT_OKAY; +#else + ip_header_ptr -> nx_ip_header_word_1 = (ip_0.nx_ip_packet_id++ << NX_SHIFT_BY_16) | NX_FRAGMENT_OKAY; +#endif /* NX_ENABLE_IP_ID_RANDOMIZATION */ + ip_header_ptr -> nx_ip_header_word_2 = ((0x80 << NX_IP_TIME_TO_LIVE_SHIFT) | NX_IP_ICMP); + ip_header_ptr -> nx_ip_header_source_ip = 0x02020305; + ip_header_ptr -> nx_ip_header_destination_ip = 0x01020305; + ip_0.nx_ip_fragment_processing = NX_NULL; + _nx_ip_forward_packet_process(&ip_0, my_packet[0]); + + +#ifndef NX_DISABLE_FRAGMENTATION + /* Hit condition: second [ + - ] + 361 [ + - ][ + - ]: 7 : if ((ip_ptr -> nx_ip_fragment_processing) && (!(fragment_bits & NX_IP_DONT_FRAGMENT))) + */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 600; + my_packet[0] -> nx_packet_length = 600; + ip_header_ptr = (NX_IPV4_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + ip_header_ptr -> nx_ip_header_word_0 = (NX_IP_VERSION | NX_IP_NORMAL | (0xFFFF & my_packet[0] -> nx_packet_length)); +#ifdef NX_ENABLE_IP_ID_RANDOMIZATION + ip_header_ptr -> nx_ip_header_word_1 = (((ULONG)NX_RAND()) << NX_SHIFT_BY_16) | NX_DONT_FRAGMENT; +#else + ip_header_ptr -> nx_ip_header_word_1 = (ip_0.nx_ip_packet_id++ << NX_SHIFT_BY_16) | NX_DONT_FRAGMENT; +#endif /* NX_ENABLE_IP_ID_RANDOMIZATION */ + ip_header_ptr -> nx_ip_header_word_2 = ((0x80 << NX_IP_TIME_TO_LIVE_SHIFT) | NX_IP_ICMP); + ip_header_ptr -> nx_ip_header_source_ip = 0x02020305; + ip_header_ptr -> nx_ip_header_destination_ip = 0x01020305; + ip_0.nx_ip_fragment_processing = _nx_ip_fragment_packet; + _nx_ip_forward_packet_process(&ip_0, my_packet[0]); + ip_0.nx_ip_fragment_processing = NX_NULL; +#endif + + + + /* Test _nx_ip_driver_packet_send() */ +#ifndef NX_DISABLE_FRAGMENTATION + /* Hit condition: 263 [ + + ][ - + ]: if ((ip_ptr -> nx_ip_fragment_processing == NX_NULL) || (fragment != NX_FRAGMENT_OKAY)) */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 600; + my_packet[0] -> nx_packet_length = 600; + ip_0.nx_ip_fragment_processing = NX_NULL; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + _nx_ip_driver_packet_send(&ip_0, my_packet[0], IP_ADDRESS(1, 2, 3, 5), NX_DONT_FRAGMENT, IP_ADDRESS(1, 2, 3, 5)); + + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 600; + my_packet[0] -> nx_packet_length = 600; + ip_0.nx_ip_fragment_processing = _nx_ip_fragment_packet; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + _nx_ip_driver_packet_send(&ip_0, my_packet[0], IP_ADDRESS(1, 2, 3, 5), NX_DONT_FRAGMENT, IP_ADDRESS(1, 2, 3, 5)); + ip_0.nx_ip_fragment_processing = NX_NULL; +#endif + + + /* Hit condition: + 378 [ + + - + ]: if ((!ip_ptr -> nx_ip_arp_allocate) || + 379 : ((ip_ptr -> nx_ip_arp_allocate)(ip_ptr, &(ip_ptr -> nx_ip_arp_table[index]), NX_FALSE))) */ + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + temp_arp = ip_0.nx_ip_arp_dynamic_list; + ip_0.nx_ip_arp_dynamic_list = NX_NULL; + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 40; + my_packet[0] -> nx_packet_length = 40; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + _nx_ip_driver_packet_send(&ip_0, my_packet[0], IP_ADDRESS(1, 2, 3, 5), NX_DONT_FRAGMENT, IP_ADDRESS(1, 2, 3, 5)); + ip_0.nx_ip_arp_dynamic_list = temp_arp; + + + /* Hit condition: + 436 [ + + ][ - + ]: 17075 : if ((((destination_ip >= NX_IP_LOOPBACK_FIRST) && + 437 [ + + ]: 593 : (destination_ip <= NX_IP_LOOPBACK_LAST))) || + 438 : 593 : (destination_ip == packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_ip_address)) */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 40; + my_packet[0] -> nx_packet_length = 40; + ip_header_ptr = (NX_IPV4_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + ip_header_ptr -> nx_ip_header_word_0 = (NX_IP_VERSION | NX_IP_NORMAL | (0xFFFF & my_packet[0] -> nx_packet_length)); +#ifdef NX_ENABLE_IP_ID_RANDOMIZATION + ip_header_ptr -> nx_ip_header_word_1 = (((ULONG)NX_RAND()) << NX_SHIFT_BY_16) | NX_FRAGMENT_OKAY; +#else + ip_header_ptr -> nx_ip_header_word_1 = (ip_0.nx_ip_packet_id++ << NX_SHIFT_BY_16) | NX_FRAGMENT_OKAY; +#endif /* NX_ENABLE_IP_ID_RANDOMIZATION */ + ip_header_ptr -> nx_ip_header_word_2 = ((0x80 << NX_IP_TIME_TO_LIVE_SHIFT) | NX_IP_ICMP); + ip_header_ptr -> nx_ip_header_source_ip = 0x01020304; + ip_header_ptr -> nx_ip_header_destination_ip = NX_IP_LOOPBACK_LAST; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + ip_0.nx_ip_interface[0].nx_interface_address_mapping_needed = 0; + _nx_ip_driver_packet_send(&ip_0, my_packet[0], NX_IP_LOOPBACK_LAST, NX_DONT_FRAGMENT, NX_IP_LOOPBACK_LAST); + ip_0.nx_ip_interface[0].nx_interface_address_mapping_needed = 1; + + +#ifndef NX_ENABLE_INTERFACE_CAPABILITY + /* Hit condition: + 436 [ + + ][ + - ]: 17075 : if ((((destination_ip >= NX_IP_LOOPBACK_FIRST) && + 437 [ + + ]: 593 : (destination_ip <= NX_IP_LOOPBACK_LAST))) || + 438 : 593 : (destination_ip == packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_ip_address)) */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 40; + my_packet[0] -> nx_packet_length = 40; + ip_header_ptr = (NX_IPV4_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + ip_header_ptr -> nx_ip_header_word_0 = (NX_IP_VERSION | NX_IP_NORMAL | (0xFFFF & my_packet[0] -> nx_packet_length)); +#ifdef NX_ENABLE_IP_ID_RANDOMIZATION + ip_header_ptr -> nx_ip_header_word_1 = (((ULONG)NX_RAND()) << NX_SHIFT_BY_16) | NX_FRAGMENT_OKAY; +#else + ip_header_ptr -> nx_ip_header_word_1 = (ip_0.nx_ip_packet_id++ << NX_SHIFT_BY_16) | NX_FRAGMENT_OKAY; +#endif /* NX_ENABLE_IP_ID_RANDOMIZATION */ + ip_header_ptr -> nx_ip_header_word_2 = ((0x80 << NX_IP_TIME_TO_LIVE_SHIFT) | NX_IP_ICMP); + ip_header_ptr -> nx_ip_header_source_ip = 0x01020304; + ip_header_ptr -> nx_ip_header_destination_ip = NX_IP_LOOPBACK_LAST + 1; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + ip_0.nx_ip_interface[0].nx_interface_address_mapping_needed = 0; + _nx_ip_driver_packet_send(&ip_0, my_packet[0], NX_IP_LOOPBACK_LAST + 1, NX_DONT_FRAGMENT, NX_IP_LOOPBACK_LAST); + ip_0.nx_ip_interface[0].nx_interface_address_mapping_needed = 1; +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + +#ifndef NX_DISABLE_FRAGMENTATION + /* Hit condition: + 511 [ + + ][ + - ]: 3014 : if ((ip_ptr -> nx_ip_fragment_processing) && (fragment != NX_DONT_FRAGMENT)) */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 600; + my_packet[0] -> nx_packet_length = 600; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + ip_0.nx_ip_fragment_processing = _nx_ip_fragment_packet; + _nx_ip_driver_packet_send(&ip_0, my_packet[0], 0x01020305, NX_DONT_FRAGMENT, 0x01020305); + ip_0.nx_ip_fragment_processing = NX_NULL; +#endif + + +#ifndef NX_DISABLE_ASSERT + /* Hit condition: packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_link_driver_entry = NX_NULL + NX_ASSERT(packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_link_driver_entry != NX_NULL); */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + /* Recover. */ + ip_0.nx_ip_interface[0].nx_interface_link_driver_entry = _nx_ram_network_driver_256; +#endif /* NX_DISABLE_ASSERT */ + + + +#ifdef FEATURE_NX_IPV6 + /* Hit condition: second [ + - ] + 493 [ + + ][ + - ]: 2264309 : if ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) || + 494 [ + - ]: 181 : ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) && + 495 : 181 : (incoming_addr -> nxd_ipv6_address_state == NX_IPV6_ADDR_STATE_VALID))) */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 40; + my_packet[0] -> nx_packet_length = 40; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + my_packet[0] -> nx_packet_ip_version = 5; + _nx_ip_dispatch_process(&ip_0, my_packet[0], NX_PROTOCOL_TCP); + nx_packet_release( my_packet[0]); + + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 40; + my_packet[0] -> nx_packet_length = 40; + my_packet[0] -> nx_packet_address.nx_packet_ipv6_address_ptr = &ip_0.nx_ipv6_address[0]; + my_packet[0] -> nx_packet_ip_version = NX_IP_VERSION_V6; + _nx_ip_dispatch_process(&ip_0, my_packet[0], NX_PROTOCOL_TCP); + nx_packet_release( my_packet[0]); + + /* Hit condition: second [ + - ] + 574 [ + + ][ + - ]: 16830 : if ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) || + 575 [ + - ]: 5041 : ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) && + 576 : 5041 : (incoming_addr -> nxd_ipv6_address_state == NX_IPV6_ADDR_STATE_VALID))) */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 40; + my_packet[0] -> nx_packet_length = 40; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + my_packet[0] -> nx_packet_ip_version = 5; + _nx_ip_dispatch_process(&ip_0, my_packet[0], NX_PROTOCOL_UDP); + nx_packet_release( my_packet[0]); + + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 40; + my_packet[0] -> nx_packet_length = 40; + my_packet[0] -> nx_packet_address.nx_packet_ipv6_address_ptr = &ip_0.nx_ipv6_address[0]; + my_packet[0] -> nx_packet_ip_version = NX_IP_VERSION_V6; + _nx_ip_dispatch_process(&ip_0, my_packet[0], NX_PROTOCOL_UDP); + nx_packet_release( my_packet[0]); + + + /* Hit condition: + 601 [ + - ]: 39 : if ((ip_ptr -> nx_ip_raw_ip_processing)(ip_ptr, protocol << 16, packet_ptr) == NX_SUCCESS) */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_PHYSICAL_HEADER, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 40; + my_packet[0] -> nx_packet_length = 40; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + my_packet[0] -> nx_packet_ip_version = 4; + ip_header_ptr = (NX_IPV4_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + ip_header_ptr -> nx_ip_header_word_0 = (NX_IP_VERSION | NX_IP_NORMAL | (0xFFFF & my_packet[0] -> nx_packet_length)); +#ifdef NX_ENABLE_IP_ID_RANDOMIZATION + ip_header_ptr -> nx_ip_header_word_1 = (((ULONG)NX_RAND()) << NX_SHIFT_BY_16) | NX_FRAGMENT_OKAY; +#else + ip_header_ptr -> nx_ip_header_word_1 = (ip_0.nx_ip_packet_id++ << NX_SHIFT_BY_16) | NX_FRAGMENT_OKAY; +#endif /* NX_ENABLE_IP_ID_RANDOMIZATION */ + ip_header_ptr -> nx_ip_header_word_2 = ((0x80 << NX_IP_TIME_TO_LIVE_SHIFT) | NX_IP_ICMP); + ip_header_ptr -> nx_ip_header_source_ip = 0x01020305; + ip_header_ptr -> nx_ip_header_destination_ip = 0x01020304; + ip_0.nx_ip_raw_ip_processing = my_raw_packet_processing; + _nx_ip_dispatch_process(&ip_0, my_packet[0], 203); + nx_packet_release( my_packet[0]); + ip_0.nx_ip_raw_ip_processing = NX_NULL; + + + /* Hit condition: + 664 [ + - ]: 1145 : if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + memcpy(my_packet[0] -> nx_packet_prepend_ptr, &pkt5[14], sizeof(pkt5) - 14); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + sizeof(pkt5) - 14; + my_packet[0] -> nx_packet_length = sizeof(pkt5) - 14; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + my_packet[0] -> nx_packet_ip_header = my_packet[0] -> nx_packet_prepend_ptr; + ipv6_header_ptr = (NX_IPV6_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(ipv6_header_ptr -> nx_ip_header_word_0); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ipv6_header_ptr -> nx_ip_header_destination_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ipv6_header_ptr -> nx_ip_header_source_ip); + my_packet[0] -> nx_packet_prepend_ptr += 40; + my_packet[0] -> nx_packet_length -= 40; + my_packet[0] -> nx_packet_ip_version = 5; + _nx_ip_dispatch_process(&ip_0, my_packet[0], NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP); +#endif + +#endif + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static VOID suspend_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER) +{ +} + +static VOID link_status_change_callback(NX_IP *ip_ptr, UINT interface_index, UINT link_status) +{ +} + +#if defined __PRODUCT_NETXDUO__ && !defined NX_DISABLE_ASSERT +/* Define the test threads. */ + +static void thread_for_assert_entry(ULONG thread_input) +{ +NX_PACKET *test_packet; +ULONG src_ip_addr = 0x01020304; + + /* Check the count. */ + if (assert_count == 0) + { + + /* Update the count. */ + assert_count ++; + + nx_packet_allocate(&pool_0, &test_packet, 0, NX_NO_WAIT); + test_packet -> nx_packet_prepend_ptr = test_packet -> nx_packet_data_start - 1; + + /* Call function with NULL interface. */ + _nx_ip_header_add(&ip_0, test_packet, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5), 0, 0, 0, NX_FALSE); + } + else if (assert_count == 1) + { + + /* Update the count. */ + assert_count ++; + + /* Call function with NULL src_ip_addr. */ + nx_packet_allocate(&pool_0, &test_packet, 0, NX_NO_WAIT); + _nx_ip_checksum_compute(test_packet, NX_PROTOCOL_UDP, 0, NX_NULL, NX_NULL); + } + else if (assert_count == 2) + { + + /* Update the count. */ + assert_count ++; + + /* Call function with NULL src_ip_addr. */ + nx_packet_allocate(&pool_0, &test_packet, 0, NX_NO_WAIT); + _nx_ip_checksum_compute(test_packet, NX_PROTOCOL_UDP, 0, &src_ip_addr, NX_NULL); + } + else if (assert_count == 3) + { + + /* Update the count. */ + assert_count ++; + + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0x0011, 0x22334457); + nx_packet_allocate(&pool_0, &test_packet, NX_PHYSICAL_HEADER, NX_NO_WAIT); + test_packet -> nx_packet_append_ptr = test_packet -> nx_packet_prepend_ptr + 40; + test_packet -> nx_packet_length = 40; + test_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + ip_0.nx_ip_interface[0].nx_interface_link_driver_entry = NX_NULL; + _nx_ip_driver_packet_send(&ip_0, test_packet, 0x01020305, NX_DONT_FRAGMENT, 0x01020305); + } +} +#endif + +#ifdef FEATURE_NX_IPV6 +static UINT my_raw_packet_processing(NX_IP *ip_ptr, ULONG protocol, NX_PACKET *packet_ptr) +{ + + return(1); +} +#endif +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_branch_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Branch Test............................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_ip_chain_packet_process_test.c b/test/regression/netxduo_test/netx_ip_chain_packet_process_test.c new file mode 100644 index 00000000..33e712fc --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_chain_packet_process_test.c @@ -0,0 +1,358 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UCHAR receive_data_flag = NX_FALSE; +static UCHAR send_data[1000]; +static UCHAR receive_data[1000]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_chain_packet_process_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 10240); + pointer = pointer + 10240; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: IP Chain Packet Process Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let server thread run. */ + tx_thread_relinquish(); + + /* Set the callback function to get the IPv4 packet. */ + ip_1.nx_ipv4_packet_receive = my_packet_process; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Initialize the data. */ + for (i = 0; i < 1000; i ++) + send_data[i] = (UCHAR)rand(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(my_packet, send_data, 1000, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let server thread run. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + status = nx_packet_pool_delete(&pool_0); + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG bytes_copied; +NX_PACKET *my_packet; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the data. */ + status = nx_packet_data_extract_offset(my_packet, 0, receive_data, 1000, &bytes_copied); + + /* Check status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Compare the receive data with send data. */ + if(memcmp(receive_data, send_data, 1000) || (bytes_copied != 1000)) + { + receive_data_flag = NX_TRUE; + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_PACKET *last_packet; + + /* Get the last packet. */ + last_packet = packet_ptr -> nx_packet_last; + + /* Update the last packet and packet length, let NetX correct it. */ + + /* Update the packet length. */ + packet_ptr -> nx_packet_length += 3; + last_packet -> nx_packet_length += 3; + + /* Update the packet append. */ + last_packet -> nx_packet_append_ptr += 3; + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(&ip_1, packet_ptr); + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_chain_packet_process_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: IP Chain Packet Process Test..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_create_test.c b/test/regression/netxduo_test/netx_ip_create_test.c new file mode 100644 index 00000000..6522da1c --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_create_test.c @@ -0,0 +1,126 @@ +/* This NetX test concentrates on the IP Delete operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_system.h" +#include "nx_packet.h" + + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_create_test_application_define(void *first_unused_memory) +#endif +{ + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR id; + + + /* Print out test information banner. */ + printf("NetX Test: IP Create Operation Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Store the ID. */ + id = _nx_version_id[0]; + + /* Clear the ID. */ + _nx_version_id[0] = 0; + + /* Clear the system value. */ + _nx_system_build_options_1 = 0; + _nx_system_build_options_2 = 0; + _nx_system_build_options_3 = 0; + _nx_system_build_options_4 = 0; + _nx_system_build_options_5 = 0; + + /* Set the pool ID. */ + pool_0.nx_packet_pool_id = NX_PACKET_POOL_ID; + + /* Create IP instances with NX_NULL ID before NetX initialize. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + + /* Check the status. */ + if (status != NX_NOT_IMPLEMENTED) + error_counter++; + + /* Reset the ID. */ + _nx_version_id[0] = id; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_ip_delete_test.c b/test/regression/netxduo_test/netx_ip_delete_test.c new file mode 100644 index 00000000..1f40fccc --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_delete_test.c @@ -0,0 +1,727 @@ +/* This NetX test concentrates on the IP Delete operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" +#include "nx_igmp.h" +#include "nx_arp.h" +#include "nx_rarp.h" +#include "nx_udp.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NX_TCP_SOCKET client_socket; +static NX_UDP_SOCKET socket_0; +static UCHAR ip_stack[2048]; +static UCHAR ip_stack_1[2048]; +static UCHAR ip_stack_2[2048]; +static UCHAR arp_stack[1024]; +static UCHAR ping_done; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void _nx_ram_network_driver_test(NX_IP_DRIVER *driver_req_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_delete_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Initialize the counters. */ + error_counter = 0; + ping_done = NX_FALSE; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, arp_stack, sizeof(arp_stack)); + + if (status) + error_counter++; + + /* Enable TCP processing for IP instances. */ + status = nx_tcp_enable(&ip_0); + + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +UINT old_threshold; +#ifdef FEATURE_NX_IPV6 +NXD_ADDRESS ipv6_address; +#endif /* FEATURE_NX_IPV6 */ + + + /* Print out test information banner. */ + printf("NetX Test: IP Delete Operation Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the IP instance. */ + status = nx_ip_delete(&ip_0); + + /* Check for an error. */ + if (status != NX_SOCKETS_BOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the IP instance. */ + status = nx_ip_delete(&ip_0); + + /* Check for an error. */ + if (status != NX_SOCKETS_BOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the IP instance. */ + status = nx_ip_delete(&ip_0); + + /* Check for an error. */ + if (status != NX_SOCKETS_BOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the IP instance. */ + status = nx_ip_delete(&ip_0); + + /* Check for an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + /* Create IP instances. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(2, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack_1, sizeof(ip_stack_1), 1); + + /* Create IP instances. */ + status += nx_ip_create(&ip_2, "NetX IP Instance 2", IP_ADDRESS(3, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack_2, sizeof(ip_stack_2), 1); + + /* Check for an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete IP instances. */ + status = nx_ip_delete(&ip_2); + status += nx_ip_delete(&ip_1); + status += nx_ip_delete(&ip_0); + + /* Check for an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check RAW queue is cleared after IP is deleted. */ + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + /* Enable RAW traffic. */ + status += nx_ip_raw_packet_enable(&ip_0); + + /* Allocate a packet. */ + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(packet_ptr, "ABC", 3, &pool_0, NX_WAIT_FOREVER); + + /* Send the RAW packet. */ + status += nx_ip_raw_packet_send(&ip_0, packet_ptr, IP_ADDRESS(1, 2, 3, 9), NX_IP_NORMAL); + + /* Delete the IP instance. */ + status += nx_ip_delete(&ip_0); + + /* Check for error and pool available. */ + if ((status) || (pool_0.nx_packet_pool_total != pool_0.nx_packet_pool_available)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_LOOPBACK_INTERFACE + /* Check RAW queue is cleared after IP is deleted. */ + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + /* Enable RAW traffic. */ + status += nx_ip_raw_packet_enable(&ip_0); + + /* Allocate a packet. */ + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(packet_ptr, "ABC", 3, &pool_0, NX_WAIT_FOREVER); + + /* Send the RAW packet. */ + status += nx_ip_raw_packet_send(&ip_0, packet_ptr, IP_ADDRESS(127, 0, 0, 1), NX_IP_NORMAL); + + /* Delete the IP instance. */ + status += nx_ip_delete(&ip_0); + + /* Check for error and pool available. */ + if ((status) || (pool_0.nx_packet_pool_total != pool_0.nx_packet_pool_available)) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_LOOPBACK_INTERFACE */ + + +#ifndef NX_ENABLE_ICMP_ADDRESS_CHECK + /* Check ICMP queue is cleared after IP is deleted. */ + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + /* Enable ICMP. */ + status += nx_icmp_enable(&ip_0); + + /* Allocate a packet. */ + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(packet_ptr, "ABCEFGHIJKLMNOPQRSTUVWXYZ", 26, &pool_0, NX_WAIT_FOREVER); + + /* Disable preemption temporarily. */ + tx_thread_preemption_change(&ntest_0, 0, &old_threshold); + + /* Call _nx_icmp_packet_receive to directly receive the packet. */ + _nx_icmp_packet_receive(&ip_0, packet_ptr); + + /* Delete the IP instance. */ + status += nx_ip_delete(&ip_0); + + /* Restore preemption. */ + tx_thread_preemption_change(&ntest_0, old_threshold, &old_threshold); + + /* Check for error and pool available. */ + if ((status) || (pool_0.nx_packet_pool_total != pool_0.nx_packet_pool_available)) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_ENABLE_ICMP_ADDRESS_CHECK */ + + + /* Check IGMP queue is cleared after IP is deleted. */ + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + /* Enable IGMP. */ + status += nx_igmp_enable(&ip_0); + + /* Allocate a packet. */ + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(packet_ptr, "ABCEFGHIJKLMNOPQRSTUVWXYZ", 26, &pool_0, NX_WAIT_FOREVER); + + /* Disable preemption temporarily. */ + tx_thread_preemption_change(&ntest_0, 0, &old_threshold); + + /* Call _nx_igmp_packet_receive to directly receive the packet. */ + _nx_igmp_packet_receive(&ip_0, packet_ptr); + + /* Delete the IP instance. */ + status += nx_ip_delete(&ip_0); + + /* Restore preemption. */ + tx_thread_preemption_change(&ntest_0, old_threshold, &old_threshold); + + /* Check for error and pool available. */ + if ((status) || (pool_0.nx_packet_pool_total != pool_0.nx_packet_pool_available)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Check TCP queue is cleared after IP is deleted. */ + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + /* Enable TCP. */ + status += nx_tcp_enable(&ip_0); + + /* Allocate a packet. */ + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(packet_ptr, "ABCEFGHIJKLMNOPQRSTUVWXYZ", 26, &pool_0, NX_WAIT_FOREVER); + + /* Disable preemption temporarily. */ + tx_thread_preemption_change(&ntest_0, 0, &old_threshold); + + /* Call _nx_tcp_packet_receive to directly receive the packet. */ + _nx_tcp_packet_receive(&ip_0, packet_ptr); + + /* Delete the IP instance. */ + status += nx_ip_delete(&ip_0); + + /* Restore preemption. */ + tx_thread_preemption_change(&ntest_0, old_threshold, &old_threshold); + + /* Check for error and pool available. */ + if ((status) || (pool_0.nx_packet_pool_total != pool_0.nx_packet_pool_available)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Check UDP queue is cleared after IP is deleted. */ + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + /* Enable UDP. */ + status += nx_tcp_enable(&ip_0); + + /* Allocate a packet. */ + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(packet_ptr, "ABCEFGHIJKLMNOPQRSTUVWXYZ", 26, &pool_0, NX_WAIT_FOREVER); + + /* Disable preemption temporarily. */ + tx_thread_preemption_change(&ntest_0, 0, &old_threshold); + + /* Call _nx_udp_packet_receive to directly receive the packet. */ + _nx_udp_packet_receive(&ip_0, packet_ptr); + + /* Delete the IP instance. */ + status += nx_ip_delete(&ip_0); + + /* Restore preemption. */ + tx_thread_preemption_change(&ntest_0, old_threshold, &old_threshold); + + /* Check for error and pool available. */ + if ((status) || (pool_0.nx_packet_pool_total != pool_0.nx_packet_pool_available)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Check ARP queue is cleared after IP is deleted. */ + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + /* Enable ARP. */ + status += nx_arp_enable(&ip_0, arp_stack, sizeof(arp_stack)); + + /* Allocate a packet. */ + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(packet_ptr, "ABCEFGHIJKLMNOPQRSTUVWXYZ", 26, &pool_0, NX_WAIT_FOREVER); + + /* Disable preemption temporarily. */ + tx_thread_preemption_change(&ntest_0, 0, &old_threshold); + + /* Call _nx_arp_packet_deferred_receive to directly receive the packet. */ + _nx_arp_packet_deferred_receive(&ip_0, packet_ptr); + + /* Delete the IP instance. */ + status += nx_ip_delete(&ip_0); + + /* Restore preemption. */ + tx_thread_preemption_change(&ntest_0, old_threshold, &old_threshold); + + /* Check for error and pool available. */ + if ((status) || (pool_0.nx_packet_pool_total != pool_0.nx_packet_pool_available)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Check RARP queue is cleared after IP is deleted. */ + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + /* Enable RARP. */ + status += nx_rarp_enable(&ip_0); + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status += nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(packet_ptr, "ABCEFGHIJKLMNOPQRSTUVWXYZ", 26, &pool_0, NX_WAIT_FOREVER); + + /* Disable preemption temporarily. */ + tx_thread_preemption_change(&ntest_0, 0, &old_threshold); + + /* Call _nx_rarp_packet_deferred_receive to directly receive the packet. */ + _nx_rarp_packet_deferred_receive(&ip_0, packet_ptr); + + /* Delete the IP instance. */ + status += nx_ip_delete(&ip_0); + + /* Restore preemption. */ + tx_thread_preemption_change(&ntest_0, old_threshold, &old_threshold); + + /* Check for error and pool available. */ + if ((status) || (pool_0.nx_packet_pool_total != pool_0.nx_packet_pool_available)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Test packet queued on ND cache. */ + /* Create IP instances. */ + nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + nxd_ipv6_enable(&ip_0); + nxd_icmp_enable(&ip_0); + nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + ipv6_address.nxd_ip_address.v6[1] = 0; + ipv6_address.nxd_ip_address.v6[2] = 0; + ipv6_address.nxd_ip_address.v6[3] = 1; + nxd_icmp_ping(&ip_0, &ipv6_address, "", 0, &packet_ptr, NX_NO_WAIT); + + /* Delete the IP instance. */ + nx_ip_delete(&ip_0); + + /* Check for pool available. */ + if (pool_0.nx_packet_pool_total != pool_0.nx_packet_pool_available) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* FEATURE_NX_IPV6 */ + + +#ifdef __PRODUCT_NETXDUO__ + /* Check ICMP suspension list is cleared after IP is deleted. */ + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_stack, sizeof(ip_stack), 1); + + /* Enable ARP and ICMP. */ + status += nx_arp_enable(&ip_0, arp_stack, sizeof(arp_stack)); + status += nx_icmp_enable(&ip_0); + + /* Resume thread 1 and let it start to ping. */ + tx_thread_resume(&ntest_1); + + /* Delete the IP instance. */ + status += nx_ip_delete(&ip_0); + + /* Check for error and pool available. */ + if ((status) || (pool_0.nx_packet_pool_total != pool_0.nx_packet_pool_available) || + (ping_done == NX_FALSE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_test, + ip_stack, sizeof(ip_stack), 1); + + /* Delete IP with sleep in driver. */ + status += nx_ip_delete(&ip_0); + if (status || error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *packet_ptr; +UINT status; + + /* Ping an address not existed. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 4), "", 0, &packet_ptr, NX_WAIT_FOREVER); + + if (status == NX_SUCCESS) + { + + /* No response should be received. */ + printf("ERROR!\n"); + test_control_return(1); + } + + ping_done = NX_TRUE; +} + +static void _nx_ram_network_driver_test(NX_IP_DRIVER *driver_req_ptr) +{ + if (driver_req_ptr -> nx_ip_driver_command == NX_LINK_UNINITIALIZE) + { + if (tx_thread_sleep(1)) + { + error_counter++; + } + } + _nx_ram_network_driver_256(driver_req_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_delete_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Delete Operation Test..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_driver_deferred_test.c b/test/regression/netxduo_test/netx_ip_driver_deferred_test.c new file mode 100644 index 00000000..2bb497d9 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_driver_deferred_test.c @@ -0,0 +1,308 @@ +/* This NetX test concentrates on NX_IP_DRIVER_DEFERRED_EVENT for NX_LINK_PACKET_SEND command. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static NX_IP_DRIVER driver_request; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void test_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_driver_deferred_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, test_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: IP Driver Deferred Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + + +static void test_driver(struct NX_IP_DRIVER_STRUCT *driver_req) +{ + if (driver_req -> nx_ip_driver_command == NX_LINK_PACKET_SEND) + { + + /* Store the driver request. */ + memcpy(&driver_request, driver_req, sizeof(driver_request)); + + /* Call deferred processing. */ + _nx_ip_driver_deferred_processing(driver_req -> nx_ip_driver_ptr); + } + else if (driver_req -> nx_ip_driver_command == NX_LINK_DEFERRED_PROCESSING) + { + + /* Test if this pointer is initialized. */ + *(driver_req -> nx_ip_driver_return_ptr) = 1; + + /* Pass the unfinished driver request to the real driver. */ + _nx_ram_network_driver_256(&driver_request); + } + else + { + + /* Pass the driver request to the real driver directly. */ + _nx_ram_network_driver_256(driver_req); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_driver_deferred_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Driver Deferred Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_disable_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_disable_test.c new file mode 100644 index 00000000..2f5be491 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_disable_test.c @@ -0,0 +1,277 @@ +/* This NetX test concentrates on IP fragmentation disable operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_FRAGMENT_IMMEDIATE_ASSEMBLY) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG icmp_counter; +static NX_PACKET *copy_packet_0; +static NX_PACKET *copy_packet_1; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_disable_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 500, pointer, 4096); + pointer = pointer + 4096; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP traffic. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check for ICMP enable errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR data[256]; + + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Disable Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to get the IPv4 packet. */ + ip_1.nx_ipv4_packet_receive = my_packet_process; + + /* Now ip_0 ping ip_1 to check nx_ip_received_fragment_head and nx_ip_fragment_assembly_head. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), data, 300, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status == NX_SUCCESS) || (my_packet)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the error counter and icmp counter. */ + if ((error_counter) || (icmp_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the callback function. */ + ip_1.nx_ipv4_packet_receive = _nx_ipv4_packet_receive; + + /* Now ip_0 ping ip_1 to check nx_ipv4_packet_receive after ip_1 disable fragment feature . */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), data, 300, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status == NX_SUCCESS) || (my_packet)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the test threads. */ + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Sleep 100 ticks to receive the fragment packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(&ip_1, copy_packet_0); + + /* Check the received/assembly fragment head. */ + if ((ip_1.nx_ip_received_fragment_head) || ((ip_1.nx_ip_fragment_assembly_head == NX_NULL))) + error_counter ++; + + /* Get mutex protection. */ + tx_mutex_get(&(ip_1.nx_ip_protection), TX_WAIT_FOREVER); + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(&ip_1, copy_packet_1); + + /* Check the received/assembly fragment head. */ + if ((ip_1.nx_ip_received_fragment_head == NX_NULL) || (ip_1.nx_ip_fragment_assembly_head == NX_NULL)) + error_counter ++; + + /* Disable the fragment. */ + status = nx_ip_fragment_disable(&ip_1); + + /* Check the status. */ + if (status) + error_counter++; + + /* Check the received/assembly fragment head. */ + if ((ip_1.nx_ip_received_fragment_head) || (ip_1.nx_ip_fragment_assembly_head)) + error_counter ++; + + /* Release mutex protection. */ + tx_mutex_put(&(ip_1.nx_ip_protection)); +} + +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; + + /* Get the ICMP packet. */ + icmp_counter ++; + + /* Check the icmp counter. */ + if (icmp_counter == 1) + { + + /* First fragmentation. */ + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_0, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + error_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + if (icmp_counter == 2) + { + + /* Second fragmentation. */ + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_1, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + error_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_disable_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Disable Test.............................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_dispatch_fail_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_dispatch_fail_test.c new file mode 100644 index 00000000..aca4d4c8 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_dispatch_fail_test.c @@ -0,0 +1,166 @@ +/* This NetX test concentrates on the failure of dispatch for assembled packets. */ + + +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IP_INFO) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 +#define SEND_SIZE 3000 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR send_buf[SEND_SIZE]; +static UCHAR pool_area[102400]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_dispatch_fail_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the client thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1000, pool_area, sizeof(pool_area)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for both IP instances. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP for IP_0 only. */ + status = nx_icmp_enable(&ip_0); + + /* Check for ICMP enable errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Dispatch Fail Test......................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now send a ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), send_buf, sizeof(send_buf), &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check packet dropped by IP_1. */ + if (ip_1.nx_ip_receive_packets_dropped != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_dispatch_fail_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Dispatch Fail Test.......................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_duplicate_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_duplicate_test.c new file mode 100644 index 00000000..6432e5af --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_duplicate_test.c @@ -0,0 +1,448 @@ +/* This NetX test concentrates on the processing of duplicated fragments. */ + + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 +#define SEND_SIZE 3000 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_0; +static NXD_ADDRESS address_1; +#endif /* FEATURE_NX_IPV6 */ + +static UINT fragments_count; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UCHAR send_buf[SEND_SIZE]; +static UCHAR pool_area[102400]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_duplicate_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the client thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1000, pool_area, sizeof(pool_area)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for both IP instances. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Set global address. */ + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0xFE800000; + address_0.nxd_ip_address.v6[1] = 0x00000000; + address_0.nxd_ip_address.v6[2] = 0x00000000; + address_0.nxd_ip_address.v6[3] = 0x00000001; + + address_1.nxd_ip_version = NX_IP_VERSION_V6; + address_1.nxd_ip_address.v6[0] = 0xFE800000; + address_1.nxd_ip_address.v6[1] = 0x00000000; + address_1.nxd_ip_address.v6[2] = 0x00000000; + address_1.nxd_ip_address.v6[3] = 0x00000002; + + status = nxd_ipv6_address_set(&ip_0, 0, &address_0, 10, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &address_1, 10, NX_NULL); + +#endif /* FEATURE_NX_IPV6 */ + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Duplicate Test..........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + for (i = 0; i < 2; i++) +#else + for (i = 0; i < 1; i++) +#endif + { + + /* Reset the testing data. */ + memset(send_buf, i, sizeof(send_buf)); + fragments_count = 0; + + /* Set callback function to duplicate the second fragments. */ + advanced_packet_process_callback = packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append data. */ + status = nx_packet_data_append(my_packet, send_buf, sizeof(send_buf), &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if (i == 0) + { + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + } +#ifdef FEATURE_NX_IPV6 + else + { + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + } +#endif /* FEATURE_NX_IPV6 */ + + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the callback function. */ + advanced_packet_process_callback = NX_NULL; + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + for (i = 0; i < 2; i++) +#else + for (i = 0; i < 1; i++) +#endif + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if(my_packet -> nx_packet_length != sizeof(send_buf)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Ignore packets from IP_1. */ + if (ip_ptr == &ip_1) + return NX_TRUE; + + if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) + { + if ((packet_ptr -> nx_packet_length > 28) && + (*(packet_ptr -> nx_packet_prepend_ptr + 9) == NX_PROTOCOL_UDP)) + { + + /* It's a UDP packet. */ + if (fragments_count == 1) + { + *operation_ptr = 2 * NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + } + else if (fragments_count == 2) + { + *operation_ptr = NX_RAMDRIVER_OP_DUPLICATE; + } + + fragments_count++; + } + } +#ifdef FEATURE_NX_IPV6 + else + { + if ((packet_ptr -> nx_packet_length > 48) && + (*(packet_ptr -> nx_packet_prepend_ptr + 6) == NX_PROTOCOL_NEXT_HEADER_FRAGMENT)) + { + + /* It's a UDP packet. */ + if(fragments_count == 1) + { + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + } + else if (fragments_count == 2) + { + *operation_ptr = NX_RAMDRIVER_OP_DUPLICATE; + } + + fragments_count++; + } + } +#endif /* FEATURE_NX_IPV6 */ + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_duplicate_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Duplicate Test...........................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_invalid_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_invalid_test.c new file mode 100644 index 00000000..dd10ad42 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_invalid_test.c @@ -0,0 +1,407 @@ +/* This NetX test concentrates on the invalid IP fragmentation. */ + + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_UDP_SOCKET socket_0; + +static UCHAR pool_area[(1536 + sizeof(NX_PACKET)) * 20]; + + +/* Define the packet data. */ +/* Frame (43 bytes) */ +static const unsigned char pkt1[43] = { +0x46, 0xa8, 0xe4, 0x73, 0x5b, 0x56, 0xc8, 0xd9, /* F..s[V.. */ +0xd2, 0x23, 0xe4, 0xab, 0x08, 0x00, 0x45, 0x00, /* .#....E. */ +0x00, 0x1d, 0x11, 0x11, 0x20, 0x00, 0x80, 0x02, /* .... ... */ +0x84, 0x46, 0xc0, 0xa8, 0x02, 0x18, 0xc0, 0xa8, /* ........ */ +0x02, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00 /* ... */ +}; + +/* Frame (1534 bytes) */ +static const unsigned char pkt2[1534] = { +0x46, 0xa8, 0xe4, 0x73, 0x5b, 0x56, 0xc8, 0xd9, /* F..s[V.. */ +0xd2, 0x23, 0xe4, 0xab, 0x08, 0x00, 0x45, 0x00, /* .#....E. */ +0x05, 0xf0, 0x11, 0x11, 0x00, 0x01, 0x80, 0x02, /* .... ... */ +0x9e, 0x72, 0xc0, 0xa8, 0x02, 0x18, 0xc0, 0xa8, /* ........ */ +0x02, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_invalid_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pool_area, sizeof(pool_area)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192, 168, 2, 31), 0xFFFFF000UL, + &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(192, 168, 2, 32), 0xFFFFF000UL, + &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable IGMP. */ + status = nx_igmp_enable(&ip_0); + status += nx_igmp_enable(&ip_1); + + /* Check for IGMP enable errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; + + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Invalid Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 3 seconds and let thread 1 run and thread 0 to assemble packets. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if (nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + + error_counter++; + break; + } + } + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Send the first fragmentation of the first packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, 16, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, (void*)(pkt1 + 14), sizeof(pkt1) - 14, &pool_0, NX_NO_WAIT); + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Send the second fragmentation of the first packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, 16, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, (void*)(pkt2 + 14), sizeof(pkt2) - 14, &pool_0, NX_NO_WAIT); + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Check status. */ + if (status) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_invalid_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Invalid Test.............................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_order_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_order_test.c new file mode 100644 index 00000000..5f7317e4 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_order_test.c @@ -0,0 +1,476 @@ +/* This NetX test concentrates on basic IP fragmentation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG packet_counter; +static ULONG error_counter; +static ULONG notify_calls; +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'}; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_order_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + notify_calls = 0; + packet_counter=0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 1536*16); + pointer = pointer + 1500*16; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG udp_packets_sent, udp_bytes_sent, udp_packets_received, udp_bytes_received, udp_invalid_packets, udp_receive_packets_dropped, udp_checksum_errors; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x88. */ + status = nx_udp_free_port_find(&ip_0, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(31); + } + + /* Disable checksum logic for this socket. */ + status = nx_udp_socket_checksum_disable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup the ARP entry for the UDP send. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0, 0); + + + advanced_packet_process_callback = my_packet_process; + + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, msg, 1500, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + tx_thread_sleep(NX_IP_PERIODIC_RATE/2); + + /* Now, enable the checksum. */ + status = nx_udp_socket_checksum_enable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send another packet with checksum enabled. */ + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, msg, 1500, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE/2); + + + /* Get UDP socket information. */ + status = nx_udp_socket_info_get(&socket_0, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_IP_INFO + + if((packets_sent != 2) || (bytes_sent != 2*1500)) + error_counter++; +#endif + + /* Check status. */ + if ((error_counter) || (status) || + (packets_received) || (bytes_received) || + (packets_queued) || (receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP information. */ + status = nx_udp_info_get(&ip_0, &udp_packets_sent, &udp_bytes_sent, &udp_packets_received, &udp_bytes_received, + &udp_invalid_packets, &udp_receive_packets_dropped, &udp_checksum_errors); + +#ifndef NX_DISABLE_IP_INFO + + if((udp_packets_sent != 2) || (udp_bytes_sent != 2*1500)) + error_counter++; +#endif + + /* Check status. */ + if ((error_counter) || (status) || + (udp_packets_received) || (udp_bytes_received) || + (udp_invalid_packets) || (udp_receive_packets_dropped) || (udp_checksum_errors) || (notify_calls != 2)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Out Of Order Processing Test............."); + + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + error_counter++; + + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&socket_1, receive_packet_function); + + /* Check status. */ + if (status) + error_counter++; + + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + if(status == NX_SUCCESS) + { + + /* Check data length */ + if(my_packet -> nx_packet_length != 1500) + error_counter++; + + /* Check received data. */ + if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26)) + error_counter++; + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Get another packet. */ + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + if(status == NX_SUCCESS) + { + + /* Check data length */ + if(my_packet -> nx_packet_length != 1500) + error_counter++; + + /* Check received data. */ + if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26)) + error_counter++; + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + error_counter++; +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &socket_1) + notify_calls++; +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Check data length and payload */ + if (!memcmp(packet_ptr -> nx_packet_prepend_ptr + 28, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26)) + { + /* Delay some seconds. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE / 5; + + packet_counter++; + } + + if(packet_counter == 2) + advanced_packet_process_callback = NX_NULL; + + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_order_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Out Of Order Processing Test.............N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_packet_copy_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_packet_copy_test.c new file mode 100644 index 00000000..8be8696d --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_packet_copy_test.c @@ -0,0 +1,327 @@ +/* This NetX test concentrates on basic IP fragmentation. */ +/* Requirement: __PRODUCT_NETXDUO__ is defined, NX_DISABLE_FRAGMENTATION is not defined. */ +/* Test sequence: + * 1. Client send 1500 bytes to Server. + * 2. Driver copy the second fragment packet and send the copy packet to Server. + * 3. Check if Server receive the 1500 bytes. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +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'}; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_packet_copy_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + packet_counter=0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 1536*16); + pointer = pointer + 1500*16; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT packet_length; + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Packet Copy Test........................."); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let Socket 0 send all packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Initialize the value. */ + packet_length = 0; + + /* Loop to receive the packets. */ + while(1) + { + + /* Receive the packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, NX_NO_WAIT); + + /* Check status. */ + if(status == NX_SUCCESS) + { + + /* Update the packet length. */ + packet_length += my_packet -> nx_packet_length; + } + else + { + break; + } + } + + /* Check the packet length. */ + if (packet_length != 1500) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if ((error_counter) || (packet_counter < 2)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter++; + + /* Set the callback function. */ + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, msg, 1500, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + error_counter++; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + error_counter++; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Return if it is not an IP packet from ip_0. */ + if ((ip_ptr == &ip_0) && (packet_ptr -> nx_packet_length > 28)) + { + + /* Updated the packet_counter. */ + packet_counter ++; + + /* Copy the second fragmentation packet. */ + if (packet_counter == 2) + { + /* Delay some seconds. */ + *operation_ptr = NX_RAMDRIVER_OP_DUPLICATE; + } + } + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_packet_copy_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Packet Copy Test.........................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_packet_delay_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_packet_delay_test.c new file mode 100644 index 00000000..d4e40233 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_packet_delay_test.c @@ -0,0 +1,328 @@ +/* This NetX test concentrates on basic IP fragmentation. */ +/* Requirement: __PRODUCT_NETXDUO__ is defined, NX_DISABLE_FRAGMENTATION is not defined. */ +/* Test sequence: + * 1. Client send 1500 bytes to Server. + * 2. Driver delay the second fragment packet. + * 3. Check if Server receive the 1500 bytes. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +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'}; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_packet_delay_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + packet_counter=0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 1536*16); + pointer = pointer + 1500*16; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT packet_length; + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Packet Delay Test........................"); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let Socket 0 send all packet. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Initialize the value. */ + packet_length = 0; + + /* Loop to receive the packets. */ + while(1) + { + + /* Receive the packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, NX_NO_WAIT); + + /* Check status. */ + if(status == NX_SUCCESS) + { + + /* Update the packet length. */ + packet_length += my_packet -> nx_packet_length; + } + else + { + break; + } + } + + /* Check the packet length. */ + if (packet_length != 1500) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if ((error_counter) || (packet_counter < 2)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter++; + + /* Set the callback function. */ + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, msg, 1500, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + error_counter++; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + error_counter++; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Return if it is not an IP packet from ip_0. */ + if ((ip_ptr == &ip_0) && (packet_ptr -> nx_packet_length > 28)) + { + + /* Updated the packet_counter. */ + packet_counter ++; + + /* Copy the second fragmentation packet. */ + if (packet_counter == 2) + { + /* Delay some seconds. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + } + } + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_packet_delay_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Packet Delay Test........................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_packet_drop_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_packet_drop_test.c new file mode 100644 index 00000000..20a0700a --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_packet_drop_test.c @@ -0,0 +1,328 @@ +/* This NetX test concentrates on basic IP fragmentation. */ +/* Requirement: __PRODUCT_NETXDUO__ is defined, NX_DISABLE_FRAGMENTATION is not defined. */ +/* Test sequence: + * 1. Client send 1500 bytes to Server. + * 2. Driver drop the first fragment packet. + * 3. Check if Server receive the 1500 bytes. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +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'}; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_packet_drop_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + packet_counter=0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 1536*16); + pointer = pointer + 1500*16; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT packet_length; + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Packet Drop Test........................."); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x08, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let Socket 0 send all packet and fragment timeout. + Cover the branch [ + - ]: if ((ipv4_header -> nx_ip_header_word_1 & NX_IP_OFFSET_MASK) == 0) in _nx_ip_fragment_cleanup() */ + tx_thread_sleep(70 * NX_IP_PERIODIC_RATE); + + /* Initialize the value. */ + packet_length = 0; + + /* Loop to receive the packets. */ + while(1) + { + + /* Receive the packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, NX_NO_WAIT); + + /* Check status. */ + if(status == NX_SUCCESS) + { + + /* Update the packet length. */ + packet_length += my_packet -> nx_packet_length; + } + else + { + break; + } + } + + /* Check the packet length. */ + if (packet_length != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if ((error_counter) || (packet_counter < 2)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x08, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter++; + + /* Set the callback function. */ + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, msg, 1500, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + error_counter++; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + error_counter++; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Return if it is not an IP packet from ip_0. */ + if ((ip_ptr == &ip_0) && (packet_ptr -> nx_packet_length > 28)) + { + + /* Updated the packet_counter. */ + packet_counter ++; + + /* Copy the first fragmentation packet. */ + if (packet_counter == 1) + { + /* Drop the fragmentation. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + } + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_packet_drop_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Packet Drop Test.........................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_test.c new file mode 100644 index 00000000..a457347b --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_test.c @@ -0,0 +1,503 @@ +/* This NetX test concentrates on basic IP fragmentation. */ + + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; +static ULONG notify_calls; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + notify_calls = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 500, pointer, 4096); + pointer = pointer + 4096; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG udp_packets_sent, udp_bytes_sent, udp_packets_received, udp_bytes_received, udp_invalid_packets, udp_receive_packets_dropped, udp_checksum_errors; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Processing Test.........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the IP threads and thread 1 execute. */ + tx_thread_relinquish(); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Pickup the first free port for 0x88. */ + status = nx_udp_free_port_find(&ip_0, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(31); + } + + /* Disable checksum logic for this socket. */ + status = nx_udp_socket_checksum_disable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup the ARP entry for the UDP send. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0, 0); + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Send 1000 packets without checksum. */ + thread_0_counter = 0; + while ((thread_0_counter < 1000) && (error_counter == 0)) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 300; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 300; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Relinquish to thread 1 so it can pickup the message. */ + tx_thread_relinquish(); + } + + /* Now, enable the checksum. */ + status = nx_udp_socket_checksum_enable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send another 1000 packets with checksum enabled. */ + while ((thread_0_counter < 2000) && (error_counter == 0)) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 300; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 300; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Relinquish to thread 1 so it can pickup the message. */ + tx_thread_relinquish(); + } + + /* Get UDP socket information. */ + status = nx_udp_socket_info_get(&socket_0, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_IP_INFO + + if((packets_sent != 2000) || (bytes_sent != 2000*300)) + error_counter++; +#endif + + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != 2000) || (thread_1_counter != 2000) || + (packets_received) || (bytes_received) || + (packets_queued) || (receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP information. */ + status = nx_udp_info_get(&ip_0, &udp_packets_sent, &udp_bytes_sent, &udp_packets_received, &udp_bytes_received, + &udp_invalid_packets, &udp_receive_packets_dropped, &udp_checksum_errors); + +#ifndef NX_DISABLE_IP_INFO + + if((udp_packets_sent != 2000) || (udp_bytes_sent != 2000*300)) + error_counter++; +#endif + + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != 2000) || (thread_1_counter != 2000) || + (udp_packets_received) || (udp_bytes_received) || + (udp_invalid_packets) || (udp_receive_packets_dropped) || (udp_checksum_errors) || (notify_calls != 2000)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_address; +UINT port; +NX_PACKET *my_packet; + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&socket_1, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Get 1000 packets. */ + thread_1_counter = 0; + while (thread_1_counter < 1000) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Get the source IP and port. */ + status = nx_udp_source_extract(my_packet, &ip_address, &port); + + /* Check status. */ + if ((status) || (ip_address != IP_ADDRESS(1,2,3,4)) || (port != 0x88)) + break; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Increment thread 1's counter. */ + thread_1_counter++; + } + + /* Get another 1000 packets. */ + while (thread_1_counter < 2000) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Increment thread 1's counter. */ + thread_1_counter++; + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &socket_1) + notify_calls++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Processing Test..........................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_time_exceeded_message_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_time_exceeded_message_test.c new file mode 100644 index 00000000..d1e8bf0d --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_time_exceeded_message_test.c @@ -0,0 +1,301 @@ +/* This NetX test concentrates on ICMP Time Exceeded Message for IP fragmentation. */ +/* Requirement: __PRODUCT_NETXDUO__ is defined, NX_DISABLE_ICMPV4_ERROR_MESSAGE is not defined. NX_DISABLE_FRAGMENTATION is not defined. */ +/* Test sequence: + * 1. ip_0 send ICMP Ping with 600 bytes to ip_2. It is fragmented into three packets. + * 2. Delay 5 seconds for second fragmentation packet of ip_0 to update the timeout of fragmentation to let ip_1 fragmentation timeout first. + * 3. Delay NX_IP_TIME_TO_LIVE + 4 seconds for third fragmentation of ip_0, send the third fragmentation before ip_0 fragmentation timeout, after ip_1 fragmentation timeout. + * 4. ip_1 send ICMP Ping with 600 bytes to ip_2. It is fragmented into three packets. + * 5. Discard the third fragmentation packet of ip_1 to let ip_1 fragmentation timeout. + * 6. Check if ip_1 instance get the fragmentation time exceeded message from ip_2 instance. + * 7. Check if ip_1 instance get the response from ip_2 instance. + * 7. Check if ip_0 instance get the response from ip_2 instance. + */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_icmp.h" +#include "nx_system.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if defined (__PRODUCT_NETXDUO__) && !defined (NX_DISABLE_ICMPV4_ERROR_MESSAGE) && !defined (NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG ip_0_packet_counter; +static ULONG ip_1_packet_counter; +static UCHAR time_exceeded_message; +static UCHAR icmp_ping_timeout; +static UCHAR icmp_ping_received; +static CHAR msg[600]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_time_exceeded_message_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ip_0_packet_counter = 0; + ip_1_packet_counter = 0; + time_exceeded_message = NX_FALSE; + icmp_ping_received = NX_FALSE; + icmp_ping_timeout = NX_FALSE; + memset(msg, '1', sizeof(msg)); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*20); + pointer = pointer + 1536*20; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_2, "NetX IP Instance 2", IP_ADDRESS(1, 2, 3, 6), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP traffic. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + status += nx_icmp_enable(&ip_2); + + /* Check for ICMP enable errors. */ + if (status) + error_counter++; + + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + status += nx_ip_fragment_enable(&ip_2); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Time Exceeded Message Test..............."); + + /* Set the callback function. */ + advanced_packet_process_callback = my_packet_process; + + /* Ping an IP address that does exist. Set the timeout as NX_IP_TIME_TO_LIVE + 1 + 5. delay the second fragmentation. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 6), msg, 600, &my_packet, (NX_IP_TIME_TO_LIVE + 1 + 5) * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + /* Update the flag. */ + icmp_ping_received = NX_TRUE; + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Check status. */ + if ((error_counter) || (time_exceeded_message != NX_TRUE) || + (icmp_ping_timeout != NX_TRUE) || (icmp_ping_received != NX_TRUE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the test threads. */ + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Ping an IP address that does exist. Set the timeout as NX_IP_TIME_TO_LIVE + 1. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(1, 2, 3, 6), msg, 600, &my_packet, (NX_IP_TIME_TO_LIVE + 1) * NX_IP_PERIODIC_RATE); + + /* Check the status, should not get the response. */ + if (status == NX_NO_RESPONSE) + { + icmp_ping_timeout = NX_TRUE; + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_ICMPV4_ERROR *icmpv4_error; + + /* Return if it is not an IP packet. */ + if (packet_ptr -> nx_packet_length <= 28) + return NX_TRUE; + + /* Check the IP instance. */ + if (ip_ptr == &ip_0) + { + + /* Update the fragmentation packet counter. */ + ip_0_packet_counter ++; + + /* Delay the second fragmentation packet. */ + if (ip_0_packet_counter == 2) + { + + /* Set the discard operation. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + + /* Delay the second fragmentation ping, the timeout of ip_0 fragmentation should be updated. . */ + *delay_ptr = 5 * NX_IP_PERIODIC_RATE; + } + /* Delay the second fragmentation packet. */ + if (ip_0_packet_counter == 3) + { + + /* Set the discard operation. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + + /* Delay the third fragmentation ping, send the third fragmentation ping after ip_1 fragmentation timeout, before ip_0 fragmentation timeout. */ + *delay_ptr = (NX_IP_TIME_TO_LIVE + 4) * NX_IP_PERIODIC_RATE; + } + } + /* Check the IP instance. */ + else if (ip_ptr == &ip_1) + { + + /* Update the fragmentation packet counter. */ + ip_1_packet_counter ++; + + /* Discard the third fragmentation packet. */ + if (ip_1_packet_counter == 3) + { + + /* Set the discard operation. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + } + else + { + + /* Set the ICMP Error Message header. */ + icmpv4_error = (NX_ICMPV4_ERROR*)(packet_ptr -> nx_packet_prepend_ptr + 20); + + /* Check if it is a fragmentation time exceeded message. */ + if ((icmpv4_error -> nx_icmpv4_error_header.nx_icmpv4_header_type == NX_ICMP_TIME_EXCEEDED_TYPE) && + (icmpv4_error -> nx_icmpv4_error_header.nx_icmpv4_header_code == NX_ICMP_FRT_EXCEEDED_CODE)) + time_exceeded_message = NX_TRUE; + } + + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_time_exceeded_message_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Time Exceeded Message Test...............N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_timeout_check_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_timeout_check_test.c new file mode 100644 index 00000000..1f9dd6b3 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_timeout_check_test.c @@ -0,0 +1,346 @@ +/* This NetX test concentrates on basic IP fragmentation. */ +/* Requirement: NX_DISABLE_FRAGMENTATION is not defined. */ +/* Test sequence: + * 1. Client send 600 bytes (all '0') to Server. It is fragmented into three packets. + * First fragment is delayed 10s by driver. Third fragment is delayed 65s by driver. + * 2. Client send another 600 bytes (all '1') to Server. It is fragmented into three packets. + * The third packet is dropped by driver. + * 3. Check fragment tail after 60 second. It should be the packet contains all '0'. + */ + + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) +#define DEMO_STACK_SIZE 2048 + +#include "nx_ipv4.h" +#include "nx_system.h" +#include "nx_ram_network_driver_test_1500.h" + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR msg[2][600]; +static CHAR rcv_buffer[600]; +static UINT operations[] = {NX_RAMDRIVER_OP_DELAY, NX_RAMDRIVER_OP_BYPASS, NX_RAMDRIVER_OP_DELAY, + NX_RAMDRIVER_OP_BYPASS, NX_RAMDRIVER_OP_BYPASS, NX_RAMDRIVER_OP_DROP}; +static UINT delays[] = {1000, 0, (NX_IPV4_MAX_REASSEMBLY_TIME + 5) * NX_IP_PERIODIC_RATE, 0, 0, 0}; +static UINT operation_index; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_timeout_check_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + operation_index = 0; + memset(msg[0], '0', sizeof(msg[0])); + memset(msg[1], '1', sizeof(msg[1])); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet, *rcv_packet; +ULONG len; + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Timeout Check Test......................."); + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 1, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 1, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter++; + + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write all '0' into the packet payload! */ + status = nx_packet_data_append(my_packet, msg[0], sizeof(msg[0]), &pool_0, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write all '0' into the packet payload! */ + status = nx_packet_data_append(my_packet, msg[1], sizeof(msg[1]), &pool_0, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep assembly timeout. */ + tx_thread_sleep((NX_IPV4_MAX_REASSEMBLY_TIME + 1) * NX_IP_PERIODIC_RATE); + + /* Check head and tail fragment link of ip_1. */ + /* The second packet in fragment link is dropped. */ + if (ip_1.nx_ip_fragment_assembly_head != ip_1.nx_ip_fragment_assembly_tail) + error_counter++; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &rcv_packet, 10 * NX_IP_PERIODIC_RATE); + + if(status == NX_SUCCESS) + { + + status = nx_packet_data_retrieve(rcv_packet, rcv_buffer, &len); + + /* Check data length */ + if(len != sizeof(msg[0])) + error_counter++; + + /* Check received data. */ + if(memcmp(rcv_buffer, msg[0], len)) + error_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_IPV4_HEADER *header; + + /* Return if it is not an IP packet. */ + if (packet_ptr -> nx_packet_length <= 28) + return NX_TRUE; + + /* Get IP header. */ + header = (NX_IPV4_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header -> nx_ip_header_word_1); + + /* Is it fragmented? */ + if (header -> nx_ip_header_word_1 & NX_IP_FRAGMENT_MASK) + { + + /* Yes it is. Setup operations. */ + *operation_ptr = operations[operation_index]; + *delay_ptr = delays[operation_index++]; + } + + NX_CHANGE_ULONG_ENDIAN(header -> nx_ip_header_word_1); + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_timeout_check_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Timeout Check Test.......................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_timeout_check_test2.c b/test/regression/netxduo_test/netx_ip_fragmentation_timeout_check_test2.c new file mode 100644 index 00000000..0ab9db9c --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_timeout_check_test2.c @@ -0,0 +1,359 @@ +/* This NetX test concentrates on basic IP fragmentation. */ +/* Requirement: NX_DISABLE_FRAGMENTATION is not defined. */ +/* Test sequence: + * 1. Client send 600 bytes (all '0') to Server. It is fragmented into three packets (A, B and C). + * 2. Client send another 600 bytes (all '1') to Server. It is fragmented into three packets (D, E and F). + * 3. The packets are received in this sequence: C, A, D, E, B. Packet F is dropped. + * 3. Check fragment head and tail after reassembly timeout. No packets are queued any more. + */ + + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +#include "nx_ip.h" +#include "nx_system.h" +#include "nx_ram_network_driver_test_1500.h" + +#ifdef __PRODUCT_NETX__ +#define NX_IPV4_HEADER NX_IP_HEADER +#ifndef NX_IPV4_MAX_REASSEMBLY_TIME +#define NX_IPV4_MAX_REASSEMBLY_TIME 5 +#endif /* NX_IPV4_MAX_REASSEMBLY_TIME */ +#endif /* __PRODUCT_NETX__ */ + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR msg[2][600]; +static CHAR rcv_buffer[600]; +static UINT operations[] = {NX_RAMDRIVER_OP_DELAY, NX_RAMDRIVER_OP_DELAY, NX_RAMDRIVER_OP_BYPASS, + NX_RAMDRIVER_OP_DELAY, NX_RAMDRIVER_OP_DELAY, NX_RAMDRIVER_OP_DROP}; +static UINT delays[] = {1, 10, 0, 2, 2, 0}; +static UINT operation_index; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_timeout_check_test_2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + operation_index = 0; + memset(msg[0], '0', sizeof(msg[0])); + memset(msg[1], '1', sizeof(msg[1])); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet, *rcv_packet; +ULONG len; + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Timeout Check Test 2....................."); + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 1, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 1, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter++; + + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write all '0' into the packet payload! */ + status = nx_packet_data_append(my_packet, msg[0], sizeof(msg[0]), &pool_0, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write all '0' into the packet payload! */ + status = nx_packet_data_append(my_packet, msg[1], sizeof(msg[1]), &pool_0, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep assembly timeout. */ + tx_thread_sleep((NX_IPV4_MAX_REASSEMBLY_TIME + 1) * NX_IP_PERIODIC_RATE); + + /* Check head and tail fragment link of ip_1. */ + /* The second packet in fragment link is dropped. */ + if ((ip_1.nx_ip_fragment_assembly_head != ip_1.nx_ip_fragment_assembly_tail) || + (ip_1.nx_ip_fragment_assembly_head != NX_NULL)) + { + error_counter++; + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &rcv_packet, 10 * NX_IP_PERIODIC_RATE); + + if(status == NX_SUCCESS) + { + + status = nx_packet_data_retrieve(rcv_packet, rcv_buffer, &len); + + /* Check data length */ + if(len != sizeof(msg[0])) + error_counter++; + + /* Check received data. */ + if(memcmp(rcv_buffer, msg[0], len)) + error_counter++; + + /* Release the packet. */ + nx_packet_release(rcv_packet); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + error_counter++; + + /* Check no packet is leak. */ + if (pool_0.nx_packet_pool_total != pool_0.nx_packet_pool_available) + error_counter++; + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_IPV4_HEADER *header; + + /* Return if it is not an IP packet. */ + if (packet_ptr -> nx_packet_length <= 28) + return NX_TRUE; + + /* Get IP header. */ + header = (NX_IPV4_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header -> nx_ip_header_word_1); + + /* Is it fragmented? */ + if (header -> nx_ip_header_word_1 & NX_IP_FRAGMENT_MASK) + { + + /* Yes it is. Setup operations. */ + *operation_ptr = operations[operation_index]; + *delay_ptr = delays[operation_index++]; + } + + NX_CHANGE_ULONG_ENDIAN(header -> nx_ip_header_word_1); + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_timeout_check_test_2_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Timeout Check Test 2.....................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_wrong_destination_address_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_wrong_destination_address_test.c new file mode 100644 index 00000000..e5d24d7a --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_wrong_destination_address_test.c @@ -0,0 +1,361 @@ +/* This NetX test concentrates on basic IP fragmentation. */ +/* Requirement: __PRODUCT_NETXDUO__ is defined, NX_DISABLE_FRAGMENTATION is not defined. */ +/* Test sequence: + * 1. Client send UDP 1500 bytes to Server. + * 2. Modify the destination address with 255.255.255.255 for second fragment packet. + * 3. Check if Server receive the 1500 bytes. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#include "nx_ip.h" +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +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'}; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_wrong_destination_address_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + packet_counter=0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 1536*16); + pointer = pointer + 1500*16; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT packet_length; + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Wrong Destination Address Test..........."); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x08, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let Socket 0 send all packet. test _nx_ip_fragment_assembly() + Hit the false condition: ((search_header -> nx_ip_header_word_2 & NX_IP_PROTOCOL_MASK) == + (current_header -> nx_ip_header_word_2 & NX_IP_PROTOCOL_MASK)) */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Initialize the value. */ + packet_length = 0; + + /* Loop to receive the packets. */ + while(1) + { + + /* Receive the packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, NX_NO_WAIT); + + /* Check status. */ + if(status == NX_SUCCESS) + { + + /* Update the packet length. */ + packet_length += my_packet -> nx_packet_length; + } + else + { + break; + } + } + + /* Check the packet length. */ + if (packet_length != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if ((error_counter) || (packet_counter < 2)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x08, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter++; + + /* Set the callback function. */ + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, msg, 1500, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + error_counter++; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + error_counter++; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_IPV4_HEADER *ip_header_ptr; +ULONG val; +ULONG checksum; + + /* Return if it is not an IP packet from ip_0. */ + if ((ip_ptr == &ip_0) && (packet_ptr -> nx_packet_length > 28)) + { + + /* Updated the packet_counter. */ + packet_counter ++; + + /* Copy the first fragmentation packet. */ + if (packet_counter == 2) + { + + /* Point to the IP HEADER. */ + ip_header_ptr = (NX_IPV4_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Modify the destination address to 255.255.255.255. */ + ip_header_ptr -> nx_ip_header_destination_ip = IP_ADDRESS(255, 255, 255, 255); + + /* Clear the checksume. */ + ip_header_ptr -> nx_ip_header_word_2 &= 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Calculate the IP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, + /* Length is the size of IP header, including options */ + 20, + /* IPv4 header checksum doesn't care src/dest addresses */ + NULL, NULL); + + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + } + } + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_wrong_destination_address_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Wrong Destination Address Test...........N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_wrong_protocol_field_test.c b/test/regression/netxduo_test/netx_ip_fragmentation_wrong_protocol_field_test.c new file mode 100644 index 00000000..bfe42c30 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_wrong_protocol_field_test.c @@ -0,0 +1,359 @@ +/* This NetX test concentrates on basic IP fragmentation. */ +/* Requirement: __PRODUCT_NETXDUO__ is defined, NX_DISABLE_FRAGMENTATION is not defined. */ +/* Test sequence: + * 1. Client send UDP 1500 bytes to Server. + * 2. Modify the protocol with ICMP for second fragment packet. + * 3. Check if Server receive the 1500 bytes. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#include "nx_ip.h" +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +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'}; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_wrong_protocol_field_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + packet_counter=0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 1536*16); + pointer = pointer + 1500*16; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT packet_length; + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Wrong Protocol Field Test................"); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x08, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let Socket 0 send all packet. test _nx_ip_fragment_assembly() + Hit the false condition: ((search_header -> nx_ip_header_word_2 & NX_IP_PROTOCOL_MASK) == + (current_header -> nx_ip_header_word_2 & NX_IP_PROTOCOL_MASK)) */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Initialize the value. */ + packet_length = 0; + + /* Loop to receive the packets. */ + while(1) + { + + /* Receive the packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, NX_NO_WAIT); + + /* Check status. */ + if(status == NX_SUCCESS) + { + + /* Update the packet length. */ + packet_length += my_packet -> nx_packet_length; + } + else + { + break; + } + } + + /* Check the packet length. */ + if (packet_length != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if ((error_counter) || (packet_counter < 2)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x08, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter++; + + /* Set the callback function. */ + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, msg, 1500, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + error_counter++; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + error_counter++; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_IPV4_HEADER *ip_header_ptr; +ULONG val; +ULONG checksum; + + /* Return if it is not an IP packet from ip_0. */ + if ((ip_ptr == &ip_0) && (packet_ptr -> nx_packet_length > 28)) + { + + /* Updated the packet_counter. */ + packet_counter ++; + + /* Copy the first fragmentation packet. */ + if (packet_counter == 2) + { + + /* Point to the IP HEADER. */ + ip_header_ptr = (NX_IPV4_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Modify the protocol to ICMP. */ + ip_header_ptr -> nx_ip_header_word_2 &= 0xFF000000; + ip_header_ptr -> nx_ip_header_word_2 |= NX_IP_ICMP; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Calculate the IP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, + /* Length is the size of IP header, including options */ + 20, + /* IPv4 header checksum doesn't care src/dest addresses */ + NULL, NULL); + + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + } + } + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_wrong_protocol_field_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Wrong Protocol Field Test................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_fragmentation_wrong_protocol_field_test2.c b/test/regression/netxduo_test/netx_ip_fragmentation_wrong_protocol_field_test2.c new file mode 100644 index 00000000..4937ec9a --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_fragmentation_wrong_protocol_field_test2.c @@ -0,0 +1,395 @@ +/* This NetX test concentrates on basic IP fragmentation. */ +/* Requirement: __PRODUCT_NETXDUO__ is defined, NX_DISABLE_FRAGMENTATION is not defined. */ +/* Test sequence: + * 1. Client send UDP 1500 bytes to Server. + * 2. Modify the protocol with ICMP and delay one second for first fragment packet. + * 2. Modify the protocol with ICMP for second fragment packet. + * 3. Check if Server receive the 1500 bytes. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_FRAGMENTATION) && !defined(NX_DISABLE_IPV4) +#include "nx_ip.h" +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +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'}; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_wrong_protocol_field_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + packet_counter=0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 1536*16); + pointer = pointer + 1500*16; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT packet_length; + + /* Print out some test information banners. */ + printf("NetX Test: IP Fragmentation Wrong Protocol Field Test2..............."); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x08, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let Socket 0 send all packet. test _nx_ip_fragment_assembly() + Hit the false condition: 442 [ + - ]: if (fragment_head == ip_ptr -> nx_ip_fragment_assembly_tail) */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Initialize the value. */ + packet_length = 0; + + /* Loop to receive the packets. */ + while(1) + { + + /* Receive the packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, NX_NO_WAIT); + + /* Check status. */ + if(status == NX_SUCCESS) + { + + /* Update the packet length. */ + packet_length += my_packet -> nx_packet_length; + } + else + { + break; + } + } + + /* Check the packet length. */ + if (packet_length != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if ((error_counter) || (packet_counter < 3)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x08, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter++; + + /* Set the callback function. */ + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, msg, 1500, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + error_counter++; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + error_counter++; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_IPV4_HEADER *ip_header_ptr; +ULONG val; +ULONG checksum; + + /* Return if it is not an IP packet from ip_0. */ + if ((ip_ptr == &ip_0) && (packet_ptr -> nx_packet_length > 28)) + { + + /* Updated the packet_counter. */ + packet_counter ++; + + /* Modify the first fragmentation packet. */ + if (packet_counter == 1) + { + + /* Point to the IP HEADER. */ + ip_header_ptr = (NX_IPV4_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Modify the protocol to ICMP. */ + ip_header_ptr -> nx_ip_header_word_2 &= 0xFF000000; + ip_header_ptr -> nx_ip_header_word_2 |= NX_IP_ICMP; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Calculate the IP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, + /* Length is the size of IP header, including options */ + 20, + /* IPv4 header checksum doesn't care src/dest addresses */ + NULL, NULL); + + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + + /* Delay some seconds. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + } + + /* Modify the second fragmentation packet. */ + if (packet_counter == 2) + { + + /* Point to the IP HEADER. */ + ip_header_ptr = (NX_IPV4_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Modify the protocol to ICMP. */ + ip_header_ptr -> nx_ip_header_word_2 &= 0xFF000000; + ip_header_ptr -> nx_ip_header_word_2 |= NX_IP_ICMP; + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Calculate the IP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, + /* Length is the size of IP header, including options */ + 20, + /* IPv4 header checksum doesn't care src/dest addresses */ + NULL, NULL); + + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + } + } + + return NX_TRUE; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_fragmentation_wrong_protocol_field_test2_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Fragmentation Wrong Protocol Field Test2...............N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ip_gateway_address_test.c b/test/regression/netxduo_test/netx_ip_gateway_address_test.c new file mode 100644 index 00000000..41108e87 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_gateway_address_test.c @@ -0,0 +1,237 @@ +/* This NetX test concentrates on the IP Address Set operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#ifdef __PRODUCT_NETX__ +#define nx_udp_socket_source_send nx_udp_socket_interface_send +#endif + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_UDP_SOCKET socket_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_gateway_address_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && defined(__PRODUCT_NETXDUO__) + /* Attach the second interface. */ + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(1, 3, 3, 4), 0xFFFF0000UL, _nx_ram_network_driver_1500); + + if (status) + error_counter++; +#endif + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && defined(__PRODUCT_NETXDUO__) +ULONG ip_address; +#endif +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: IP Gateway Address Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && defined(__PRODUCT_NETXDUO__) + /* Get the gateway address before setting gateway. */ + status = nx_ip_gateway_address_get(&ip_0, &ip_address); + + /* Check the status. */ + if (status != NX_NOT_FOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Set the gateway address with another network address. */ + status = nx_ip_gateway_address_set(&ip_0, IP_ADDRESS(2, 2, 3, 1)); + + /* Check the status. */ + if (status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the gateway address with correct network address. */ + status = nx_ip_gateway_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 1)); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && defined(__PRODUCT_NETXDUO__) + /* Get the gateway address. */ + status = nx_ip_gateway_address_get(&ip_0, &ip_address); + + /* Check the status. */ + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 1))) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(packet_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_IP_INFO + if (ip_0.nx_ip_invalid_transmit_packets != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_IP_INFO */ + + /* Send a packet out of network through the second interface. + * But the default gateway is set at first interface. */ + nx_udp_socket_source_send(&socket_0, packet_ptr, IP_ADDRESS(1, 4, 3, 5), 12, 1); + +#if !defined(NX_DISABLE_IP_INFO) && (NX_MAX_PHYSICAL_INTERFACES > 1) && defined(__PRODUCT_NETXDUO__) + /* Make sure the packet is dropped. */ + if (ip_0.nx_ip_invalid_transmit_packets == 0) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_IP_INFO */ + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_gateway_address_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Gateway Address Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_idle_scan_test.c b/test/regression/netxduo_test/netx_ip_idle_scan_test.c new file mode 100644 index 00000000..9f9614dc --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_idle_scan_test.c @@ -0,0 +1,213 @@ +/* This NetX test concentrates on idle-scan as described in https://www.youtube.com/watch?v=v5QEB-T6pH0. + Idle scans are a way for an attacker to perform a port scan in a way that might evade network restrictions and detection mechanisms. The basic defense is to avoid predictably incrementing the IP Identification field. */ + +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_ENABLE_IP_ID_RANDOMIZATION) + +#define DEMO_STACK_SIZE 2048 +#define DEMO_LOOP 10 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static USHORT ip_ids[DEMO_LOOP]; +static UINT ip_ids_index; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_idle_scan_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + + /* Print out test information banner. */ + printf("NetX Test: IP Idle Scan Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + packet_process_callback = my_packet_process; + + /* Now start ping multiple times. */ + ip_ids_index = 0; + for (i = 0; i < DEMO_LOOP; i++) + { + + /* Initialize IP IDs to be consecutive values. */ + ip_ids[i] = (USHORT)i; + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + nx_packet_release(my_packet); + } + + /* Make sure IP IDs are not consecutive. */ + for (i = 0; i < DEMO_LOOP - 1; i++) + { + if ((ip_ids[i] + 1) != ip_ids[i + 1]) + { + + /* Not consecutive. */ + break; + } + } + + /* Determine if the timeout error occurred. */ + if ((i == (DEMO_LOOP - 1)) || error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +#if defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header_ptr; +#else +NX_IP_HEADER *ip_header_ptr; +#endif +ULONG protocol; + + /* Ignore packet from IP 1. */ + if(ip_ptr == &ip_1) + return NX_TRUE; + + /* Ignore packet that is not IP packet. */ + if(packet_ptr -> nx_packet_length < 20) + return NX_TRUE; + +#if defined(__PRODUCT_NETXDUO__) + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + +#else + ip_header_ptr = (NX_IP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); +#endif + + /* Get IP header. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + ip_ids[ip_ids_index++] = (ip_header_ptr -> nx_ip_header_word_1 >> NX_SHIFT_BY_16) & 0xFFFF; + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_idle_scan_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Idle Scan Test.........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_ip_interface_address_get_test.c b/test/regression/netxduo_test/netx_ip_interface_address_get_test.c new file mode 100644 index 00000000..4cdae2e1 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_address_get_test.c @@ -0,0 +1,208 @@ +/* This NetX test concentrates on the IP Interface Address Get operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_address_get_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG address; +ULONG mask; + + + /* Print out test information banner. */ + printf("NetX Test: IP Interface Address Get Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_address_get(&ip_0, 0, &address, &mask); + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(1,2,3,4)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_address_get(&ip_0, 1, &address, &mask); + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(4, 3, 2, 10)) || (mask != 0xFF000000)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_get(&ip_0, 2, &address, &mask); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + status = nx_ip_interface_address_get(&ip_1, 0, &address, &mask); + + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(1,2,3,5)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_address_get(&ip_1, 1, &address, &mask); + + + if((status != NX_SUCCESS ) || (address != IP_ADDRESS(4,3,2,11)) || (mask != 0xFF000000)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_get(&ip_1, 2, &address, &mask); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + printf("SUCCESS!\n"); + test_control_return(0); + +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_address_get_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Interface Address Get Test.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_interface_address_set_test.c b/test/regression/netxduo_test/netx_ip_interface_address_set_test.c new file mode 100644 index 00000000..ff44ed3a --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_address_set_test.c @@ -0,0 +1,526 @@ +/* This NetX test concentrates on the IP Interface Address Set operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +VOID ip_address_change_notify(NX_IP *ip_ptr, VOID *additional_info); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_address_set_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 14), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 15), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG address; +ULONG mask; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: IP Interface Address Set Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 110), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Attach the same address to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 110), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_DUPLICATED_ENTRY) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Attach the 2nd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 111), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Make sure we can ping using the current IP address. */ + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(4, 3, 2, 91), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(4, 3, 2, 110), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* It should also be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(1, 2, 3, 14), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping via the other direction. */ + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 9), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 111), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* It should also be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 15), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + + if ((pings_sent != 3) || (ping_timeouts != 1) || (ping_responses_received != 2) ||(icmp_checksum_errors) || (icmp_unhandled_messages)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (ping_threads_suspended)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_1, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + + if ((pings_sent != 3) || (ping_timeouts != 1) || (ping_responses_received != 2) ||(icmp_checksum_errors) || (icmp_unhandled_messages)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (ping_threads_suspended)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reconfigure the interface IP addresses. */ + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_address_set(&ip_0, 1, IP_ADDRESS(4, 3, 2, 10), 0xFFFFFF00); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_set(&ip_0, 2, IP_ADDRESS(4, 3, 2, 15), 0xFFFFF000); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + status = nx_ip_interface_address_set(&ip_1, 0, IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_address_set(&ip_1, 1, IP_ADDRESS(4, 3, 2, 11), 0xFFFFFF00); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_set(&ip_1, 2, IP_ADDRESS(4, 3, 2, 15), 0xFFFFF000); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + + /* Make sure we can ping via the new interface IP address. */ + /* Make sure we can ping using the current IP address. */ + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(4, 3, 2, 91), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(4, 3, 2, 10), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* It should also be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_1, IP_ADDRESS(1, 2, 3, 4), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping via the other direction. */ + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 9), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 11), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* It should also be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + + if ((pings_sent != 6) || (ping_timeouts != 2) || (ping_responses_received != 4) ||(icmp_checksum_errors) || (icmp_unhandled_messages)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (ping_threads_suspended)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_1, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + + if ((pings_sent != 6) || (ping_timeouts != 2) || (ping_responses_received != 4) ||(icmp_checksum_errors) || (icmp_unhandled_messages)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (ping_threads_suspended)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + status = nx_ip_interface_address_get(&ip_0, 0, &address, &mask); + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(1, 2, 3, 4)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + status = nx_ip_interface_address_get(&ip_0, 1, &address, &mask); + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(4, 3, 2, 10)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_get(&ip_0, 2, &address, &mask); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + status = nx_ip_interface_address_get(&ip_1, 0, &address, &mask); + + if((status != NX_SUCCESS) || (address != IP_ADDRESS(1, 2, 3, 5)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_address_get(&ip_1, 1, &address, &mask); + + if((status != NX_SUCCESS ) || (address != IP_ADDRESS(4, 3, 2, 11)) || (mask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_address_get(&ip_1, 2, &address, &mask); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Test the condition for network mask if ((address_change_notify) && ((ip_address != previous_ip_address) || (network_mask != previous_network_mask)) in _nx_ip_interface_address_set. + Same network mask. */ + status = nx_ip_address_change_notify(&ip_0, ip_address_change_notify, NX_NULL); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test the condition for network mask if ((address_change_notify) && ((ip_address != previous_ip_address) || (network_mask != previous_network_mask)) in _nx_ip_interface_address_set. + Different network mask. */ + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(1, 2, 3, 4), 0xFFFF0000); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test the condition for network mask if ((address_change_notify) && ((ip_address != previous_ip_address) || (network_mask != previous_network_mask)) in _nx_ip_interface_address_set. + Same network mask. */ + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(1, 2, 3, 39), 0xFFFFFF00); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test the condition for network mask if ((address_change_notify) && ((ip_address != previous_ip_address) || (network_mask != previous_network_mask)) in _nx_ip_interface_address_set. + Different network mask. */ + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(1, 2, 3, 40), 0xFFFF0000); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); + +} + +VOID ip_address_change_notify(NX_IP *ip_ptr, VOID *additional_info) +{ +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_address_set_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Interface Address Set Test.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_interface_attachment_test.c b/test/regression/netxduo_test/netx_ip_interface_attachment_test.c new file mode 100644 index 00000000..8ece0a69 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_attachment_test.c @@ -0,0 +1,229 @@ +/* This NetX test concentrates on the IP Interface Attachment operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_attachment_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; +UINT i; +ULONG ip_address; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + error_counter++; + + /* Attach the 2nd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + error_counter++; + + /* Set the IP address for next interface. */ + ip_address = IP_ADDRESS(5, 3, 2, 10); + + /* Loop to attached the valid interface to IP instance 0. */ + for (i = 2; i< NX_MAX_PHYSICAL_INTERFACES; i++) + { + + /* Attach the interface. */ + status = nx_ip_interface_attach(&ip_0, "New interface", ip_address, 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + error_counter++; + + /* Update the IP address. */ + ip_address += 0x01000000UL; + } + + /* Attach the invalid interface to IP instance 0. */ + status = nx_ip_interface_attach(&ip_0, "New interface", ip_address, 0xFFFFFF00UL, _nx_ram_network_driver_1500); + if(status != NX_NO_MORE_ENTRIES) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: IP Interface Attachment Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 9), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 11), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* It should also be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + + if ((pings_sent != 3) || (ping_timeouts != 1) || (ping_responses_received != 2) || (icmp_checksum_errors) || (icmp_unhandled_messages)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28 /* data only */) || + (ping_threads_suspended)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_attachment_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Interface Attachment Test..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_interface_capability_test.c b/test/regression/netxduo_test/netx_ip_interface_capability_test.c new file mode 100644 index 00000000..4687d57e --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_capability_test.c @@ -0,0 +1,135 @@ +/* This NetX test concentrates on the basic IP static operation: static route add/delete/find */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(NX_ENABLE_INTERFACE_CAPABILITY) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_capability_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check the status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +ULONG interface_capability_flag; + + printf("NetX Test: IP Interface Capability test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface capability. */ + status = nx_ip_interface_capability_set(&ip_0, 0, NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM); + + /* Check the status. */ + if (status) + error_counter++; + + /* Get the interface capability. */ + status = nx_ip_interface_capability_get(&ip_0, 0, &interface_capability_flag); + + /* Check the status. */ + if ((status) || (interface_capability_flag != NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM)) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_capability_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Interface Capability test..............................N/A\n"); + test_control_return(3); +} +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + diff --git a/test/regression/netxduo_test/netx_ip_interface_detachment_arp_table_test.c b/test/regression/netxduo_test/netx_ip_interface_detachment_arp_table_test.c new file mode 100644 index 00000000..39656b77 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_detachment_arp_table_test.c @@ -0,0 +1,257 @@ +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_detachment_arp_table_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main threads. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver); + if(status != NX_SUCCESS) + error_counter++; + + /* Attach the 2nd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver); + if(status != NX_SUCCESS) + error_counter++; + + /* Attach the 3rd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "3rd interface", IP_ADDRESS(4, 3, 2, 12), 0xFF000000, _nx_ram_network_driver); + if(status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +UINT i; +NX_ARP *arp_ptr; +UINT arp_entry_counter = 0; + + printf("NetX Test: IP Interface Detachment ARP table Test...................."); + + /* Check earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an IP address to create dynamic arp entries associated with ip_0's 2nd interface. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 11), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an IP address to create dynamic arp entries associated with ip_0's 2nd interface. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 12), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an IP address to create dynamic arp entries associated with ip_0's 1st interface. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create static arp entries associated with ip_0's 2nd interface. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(4,3,2,13), 0x0011, 0x22334458); + status += nx_arp_static_entry_create(&ip_0, IP_ADDRESS(4,3,2,14), 0x0011, 0x22334459); + if(status) + error_counter++; + + /* Create static arp entries associated with ip_0's 2nd interface. */ + status = nx_arp_static_entry_create(&ip_0, IP_ADDRESS(1,2,3,10), 0x0011, 0x22334460); + if(status) + error_counter++; + + /* Check the whole arp table. */ + for(i = 0; i < NX_ARP_TABLE_SIZE; i++) + { + arp_ptr = ip_0.nx_ip_arp_table[i]; + while(arp_ptr) + { + if((arp_ptr -> nx_arp_ip_address == IP_ADDRESS(4, 3, 2, 11)) || + (arp_ptr -> nx_arp_ip_address == IP_ADDRESS(4, 3, 2, 12)) || + (arp_ptr -> nx_arp_ip_address == IP_ADDRESS(1, 2, 3, 5)) || + (arp_ptr -> nx_arp_ip_address == IP_ADDRESS(4, 3, 2, 13)) || + (arp_ptr -> nx_arp_ip_address == IP_ADDRESS(4, 3, 2, 14)) || + (arp_ptr -> nx_arp_ip_address == IP_ADDRESS(1, 2, 3, 10))) + { + arp_entry_counter++; + } + + /* Move to the next active ARP entry. */ + arp_ptr = arp_ptr -> nx_arp_active_next; + + /* Determine if we are at the end of the ARP list. */ + if(arp_ptr == ip_0.nx_ip_arp_table[i]) + break; + } + } + + if(arp_entry_counter != 6) + error_counter++; + + /* Reset the counter. */ + arp_entry_counter = 0; + + /* Detach the 2nd interface(4.3.2.11) from ip_0. */ + status = nx_ip_interface_detach(&ip_0, 1); + if(status) + error_counter++; + + /* Check the whole arp table. */ + for(i = 0; i < NX_ARP_TABLE_SIZE; i++) + { + arp_ptr = ip_0.nx_ip_arp_table[i]; + while(arp_ptr) + { + /* These entries should have been removed. */ + if((arp_ptr -> nx_arp_ip_address == IP_ADDRESS(4, 3, 2, 11)) || + (arp_ptr -> nx_arp_ip_address == IP_ADDRESS(4, 3, 2, 12)) || + (arp_ptr -> nx_arp_ip_address == IP_ADDRESS(4, 3, 2, 13)) || + (arp_ptr -> nx_arp_ip_address == IP_ADDRESS(4, 3, 2, 14))) + { + error_counter++; + } + + /* These entries should still be exsited. */ + else if((arp_ptr -> nx_arp_ip_address == IP_ADDRESS(1, 2, 3, 5)) || + (arp_ptr -> nx_arp_ip_address == IP_ADDRESS(1, 2, 3, 10))) + { + arp_entry_counter++; + } + + /* Move to the next active ARP entry. */ + arp_ptr = arp_ptr -> nx_arp_active_next; + + /* Determine if we are at the end of the ARP list. */ + if(arp_ptr == ip_0.nx_ip_arp_table[i]) + break; + } + } + + if(arp_entry_counter != 2) + error_counter++; + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_detachment_arp_table_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Interface Detachment ARP table Test....................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_interface_detachment_gateway_test.c b/test/regression/netxduo_test/netx_ip_interface_detachment_gateway_test.c new file mode 100644 index 00000000..a7b8c77e --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_detachment_gateway_test.c @@ -0,0 +1,136 @@ +/* This case test if the gateway has been cleared after interface detachment. */ + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_detachment_gateway_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main threads. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver); + if(status != NX_SUCCESS) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +ULONG gateway_address; + + printf("NetX Test: IP Interface Detachment Gateway Test......................"); + + /* Check earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Set gateway address. */ + status = nx_ip_gateway_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 1)); + if(status) + error_counter++; + + /* Get gateway address. */ + status = nx_ip_gateway_address_get(&ip_0, &gateway_address); + if((status) || (gateway_address != IP_ADDRESS(1, 2, 3, 1))) + error_counter++; + + /* Detach the interface from ip_0. */ + status = nx_ip_interface_detach(&ip_0, 0); + if(status) + error_counter++; + + /* Get gateway address. */ + status = nx_ip_gateway_address_get(&ip_0, &gateway_address); + if(status == NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_detachment_gateway_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Interface Detachment Gateway Test......................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_interface_detachment_tcp_connection_test.c b/test/regression/netxduo_test/netx_ip_interface_detachment_tcp_connection_test.c new file mode 100644 index 00000000..c882a111 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_detachment_tcp_connection_test.c @@ -0,0 +1,369 @@ +/* This case test if the tcp connections has been reset after interface detachment. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG syn_ack_counter; +static ULONG ack_drop_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_detachment_tcp_connection_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_counter = 0; + ack_drop_counter = 0; + + /* Create the main threads. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver); + if(status != NX_SUCCESS) + error_counter++; + + /* Attach the 2nd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + if(status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + printf("NetX Test: IP Interface Detachment TCP connection Test..............."); + + /* Check earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if(status) + error_counter++; + + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, NX_NULL); + if(status) + error_counter++; + + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + if(status != NX_IN_PROGRESS) + error_counter++; + + /* Detach the 2nd interface(4.3.2.10) from ip_0. */ + status = nx_ip_interface_detach(&ip_0, 1); + if(status) + error_counter++; + + /* Detachment should not reset the listening TCP socket. */ + if(server_socket.nx_tcp_socket_state != NX_TCP_SYN_RECEIVED) + error_counter++; + + /* Attach the 2nd interface(4.3.2.10) removed before to ip_0. */ + nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver); + + /* ntest_0 relinquishes the CPU. */ + tx_thread_suspend(&ntest_0); + + /* Check if server is SYN_RECV. Now, the server has receiced a SYN. */ + if(server_socket.nx_tcp_socket_state != NX_TCP_SYN_RECEIVED) + error_counter++; + + /* Detach the 2nd interface(4.3.2.10) from ip_0. */ + status = nx_ip_interface_detach(&ip_0, 1); + if(status) + error_counter++; + + /* Detachment should reset the TCP server socket which is in connection building progress . */ + if(server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* Attach the 2nd interface(4.3.2.10) removed before to ip_0. */ + nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver); + + /* ntest_0 relinquished the CPU. */ + tx_thread_suspend(&ntest_0); + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Relisten the TCP server socket. */ + status += nx_tcp_server_socket_relisten(&ip_0, 12, &server_socket); + + status += nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + if(server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + /* Detach the 2nd interface(4.3.2.10) from ip_0. */ + status = nx_ip_interface_detach(&ip_0, 1); + if(status) + error_counter++; + + /* Detachment should reset the established TCP connection. */ + if(server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* ntest_0 relinquished the CPU. */ + tx_thread_suspend(&ntest_0); + + /* Clean. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + status += nx_tcp_server_socket_unlisten(&ip_0, 12); + status += nx_tcp_socket_delete(&server_socket); + if(status) + error_counter++; + + if((error_counter) || (syn_ack_counter != 1) || (ack_drop_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + status += nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_packet_process; + + /* Deal the packet with my routing. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(4, 3, 2, 10), 12, NX_NO_WAIT); + if(status != NX_IN_PROGRESS) + error_counter++; + + /* ntest_1 relinquishes the CPU. */ + tx_thread_resume(&ntest_0); + + /* Detach the 2nd interface(4.3.2.11) from ip_1. */ + status = nx_ip_interface_detach(&ip_1, 1); + if(status) + error_counter++; + + /* Detachment should reset the TCP server socket which is in connection building progress . */ + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Attach the 2nd interface(4.3.2.11) removed before to ip_1. */ + nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver_1500); + + /* ntest_1 relinquishes the CPU. */ + tx_thread_resume(&ntest_0); + + /* Attempt to connect the socket again. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(4, 3, 2, 10), 12, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + if(client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + error_counter++; + + /* Detach the 2nd interface(4.3.2.11) from ip_1. */ + status = nx_ip_interface_detach(&ip_1, 1); + if(status) + error_counter++; + + /* Detachment should reset the established TCP connection. */ + if(client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Clean. */ + status = nx_tcp_client_socket_unbind(&client_socket); + status += nx_tcp_socket_delete(&client_socket); + if(status) + error_counter++; + + /* ntest_1 relinquishes the CPU. */ + tx_thread_resume(&ntest_0); +} + + +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && + (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + syn_ack_counter++; + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Let server receives the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + if(syn_ack_counter == 1) + { + /* Point to TCP HEADER. */ + tcp_header_ptr = (NX_TCP_HEADER *)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + /* Drop the ACK packet in order to postpone the connection. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + ack_drop_counter++; + + advanced_packet_process_callback = NULL; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_detachment_tcp_connection_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Interface Detachment TCP connection Test...............N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_interface_detachment_test.c b/test/regression/netxduo_test/netx_ip_interface_detachment_test.c new file mode 100644 index 00000000..cd8fa8df --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_detachment_test.c @@ -0,0 +1,321 @@ + + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address; +static NXD_ADDRESS router_address; +#endif + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static TX_MUTEX mutex_0; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_detachment_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main threads. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver); + if(status != NX_SUCCESS) + error_counter++; + + /* Attach the 2nd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver); + if(status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +#ifdef NX_ENABLE_IP_STATIC_ROUTING + status = nx_ip_static_route_add(&ip_1, IP_ADDRESS(4, 3, 2, 1), 0xFFFFFF00UL, IP_ADDRESS(4, 3, 2, 10)); + + /* Check status. */ + if (status) + error_counter++; + +#endif /* NX_ENABLE_IP_STATIC_ROUTING */ + +#ifdef FEATURE_NX_IPV6 + /* Set ipv6 version and address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x10000001; + + /* Set interfaces' address */ + status = nxd_ipv6_address_set(&ip_1, 0, &ipv6_address, 64, NX_NULL); + + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + router_address.nxd_ip_version = NX_IP_VERSION_V6; + router_address.nxd_ip_address.v6[0] = 0x20010000; + router_address.nxd_ip_address.v6[1] = 0x00000000; + router_address.nxd_ip_address.v6[2] = 0x00000000; + router_address.nxd_ip_address.v6[3] = 0x10000002; + + /* Add the default router. */ + status = nxd_ipv6_default_router_add(&ip_1, &router_address, 1500, 0); + + /* Check status. */ + if (status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + + /* Print out test information banner. */ + printf("NetX Test: IP Interface Detachment Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_mutex_create(&mutex_0, "mutex_0", TX_NO_INHERIT); + + tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Ping an unknown IP address. This will timeout after 100 ticks. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 9), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an IP address that does exist. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 11), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* It should also be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let ntest_1 detach the 2nd interface(4.3.2.11) from IP instance1. */ + tx_mutex_put(&mutex_0); + tx_thread_sleep(1); + tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Now ping an IP address that has been detached. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 11), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* It should be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let ntest_1 attach the interface(4.3.2.11) removed before, then detach the 1st interface(1.2.3.5) to IP instance1. */ + tx_mutex_put(&mutex_0); + tx_thread_sleep(1); + tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Now ping an IP address that has been detached. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(4, 3, 2, 11), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* It should be able to ping an IP address that is accessible via the primary interface. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + tx_mutex_delete(&mutex_0); + + /* Get ICMP information. */ + status += nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + + if ((pings_sent != 7) || (ping_timeouts != 3) || (ping_responses_received != 4) || (icmp_checksum_errors) || (icmp_unhandled_messages)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; + + tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Detach the 2nd interface(4.3.2.11) from IP instance1. */ + status = nx_ip_interface_detach(&ip_1, 1); + if(status) + error_counter++; + + tx_mutex_put(&mutex_0); + tx_thread_sleep(1); + tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Attach the 2nd interface(4.3.2.11) removed before to IP instance1. */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver); + + /* Detach the 1st interface(1.2.3.5)from IP instance1. */ + status += nx_ip_interface_detach(&ip_1, 0); + + if(status) + error_counter++; + + tx_mutex_put(&mutex_0); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_detachment_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Interface Detachment Test..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_interface_info_get_test.c b/test/regression/netxduo_test/netx_ip_interface_info_get_test.c new file mode 100644 index 00000000..6b304c03 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_info_get_test.c @@ -0,0 +1,227 @@ +/* This NetX test concentrates on the IP Interface Info Get operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_info_get_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR *interface_name; +ULONG address; +ULONG netmask; +ULONG mtu_size; +ULONG physical_address_msw; +ULONG physical_address_lsw; + + + /* Print out test information banner. */ + printf("NetX Test: IP Interface Info Get Test................................"); + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information before it is valid. */ + status = nx_ip_interface_info_get(&ip_0, 1, &interface_name, &address, &netmask, &mtu_size, &physical_address_msw, &physical_address_lsw); + + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get nothing from interface 0. */ + status = nx_ip_interface_info_get(&ip_0, 0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_info_get(&ip_0, 0, &interface_name, &address, &netmask, &mtu_size, &physical_address_msw, &physical_address_lsw); + + if((status != NX_SUCCESS) || strcmp(interface_name, "PRI") || (address != IP_ADDRESS(1, 2, 3, 4)) || (netmask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + status = nx_ip_interface_info_get(&ip_0, 1, &interface_name, &address, &netmask, &mtu_size, &physical_address_msw, &physical_address_lsw); + + if((status != NX_SUCCESS) || strcmp(interface_name, "2nd interface") || (address != IP_ADDRESS(4, 3, 2, 10)) || (netmask != 0xFF000000)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_info_get(&ip_0, 2, &interface_name, &address, &netmask, &mtu_size, &physical_address_msw, &physical_address_lsw); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + status = nx_ip_interface_info_get(&ip_1, 0, &interface_name, &address, &netmask, &mtu_size, &physical_address_msw, &physical_address_lsw); + + if((status != NX_SUCCESS) || strcmp(interface_name, "PRI") || (address != IP_ADDRESS(1, 2, 3, 5)) || (netmask != 0xFFFFFF00)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_info_get(&ip_1, 1, &interface_name, &address, &netmask, &mtu_size, &physical_address_msw, &physical_address_lsw); + + if((status != NX_SUCCESS) || strcmp(interface_name, "2nd interface") || (address != IP_ADDRESS(4, 3, 2, 11)) || (netmask != 0xFF000000)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_info_get(&ip_1, 2, &interface_name, &address, &netmask, &mtu_size, &physical_address_msw, &physical_address_lsw); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + printf("SUCCESS!\n"); + test_control_return(0); + +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_info_get_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Interface Info Get Test................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_interface_physical_address_set_fail_test.c b/test/regression/netxduo_test/netx_ip_interface_physical_address_set_fail_test.c new file mode 100644 index 00000000..d60fd06c --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_physical_address_set_fail_test.c @@ -0,0 +1,136 @@ +/* This NetX test concentrates on the IGMP join fails when driver returns error. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#ifdef __PRODUCT_NETXDUO__ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void test_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_physical_address_set_fail_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, test_driver, + pointer, 2048, 1); + pointer = pointer + 2048; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: IP Interface Physical Address Set Fail Test..............."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Perform IP interface physcial address set operations. */ + status = nx_ip_interface_physical_address_set(&ip_0, 0, 0x0011, 0x22334458, NX_TRUE); + + /* Check status. */ + if (status != NX_UNHANDLED_COMMAND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void test_driver(struct NX_IP_DRIVER_STRUCT *driver_req) +{ + if (driver_req -> nx_ip_driver_command == NX_LINK_SET_PHYSICAL_ADDRESS) + { + + /* Return not supported. */ + driver_req -> nx_ip_driver_status = NX_UNHANDLED_COMMAND; + } + else + { + + /* Pass the request to ram driver. */ + _nx_ram_network_driver_256(driver_req); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_physical_address_set_fail_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Interface Physical Address Set Fail Test...............N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_interface_physical_address_test.c b/test/regression/netxduo_test/netx_ip_interface_physical_address_test.c new file mode 100644 index 00000000..99a262fc --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_physical_address_test.c @@ -0,0 +1,149 @@ +/* This NetX test concentrates on the basic IP static operation: static route add/delete/find */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#ifdef __PRODUCT_NETXDUO__ +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_physical_address_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check the status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +ULONG physical_msw; +ULONG physical_lsw; + + + printf("NetX Test: IP Interface Physical Address Test........................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the interface physical address. */ + status = nx_ip_interface_physical_address_get(&ip_0, 0, &physical_msw, &physical_lsw); + + /* Check the status. */ + if (status) + error_counter++; + + /* Set the physical address. */ + physical_msw = 0x0102; + physical_lsw = 0x03040506; + + /* Set the interface capability. */ + status = nx_ip_interface_physical_address_set(&ip_0, 0, physical_msw, physical_lsw, NX_TRUE); + + /* Check the status. */ + if (status) + error_counter++; + + /* Get the interface physical address again. */ + status = nx_ip_interface_physical_address_get(&ip_0, 0, &physical_msw, &physical_lsw); + + /* Check the status. */ + if (status) + error_counter++; + + /* Check the physical address. */ + if ((physical_msw != 0x0102) || (physical_lsw != 0x03040506)) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_physical_address_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Interface Physical Address Test........................N/A\n"); + test_control_return(3); +} +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + diff --git a/test/regression/netxduo_test/netx_ip_interface_status_check_fail_test.c b/test/regression/netxduo_test/netx_ip_interface_status_check_fail_test.c new file mode 100644 index 00000000..c6d18032 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_status_check_fail_test.c @@ -0,0 +1,280 @@ +/* This NetX test concentrates on the IP Interface Status Check operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +#define DEMO_STACK_SIZE 2048 + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the test application... */ +static ULONG error_counter; + +static ULONG test_enabled; +static ULONG test_status; +static ULONG reject_command; +static ULONG return_value; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void test_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_status_check_fail_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + reject_command = 0; + test_enabled = NX_FALSE; + return_value = NX_TRUE; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, test_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG val; + + + /* Print out test information banner. */ + printf("NetX Test: IP Interface Status Check Fail Test......................."); + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_ARP_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_UDP_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_TCP_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_IGMP_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the IP address. */ + status = nx_ip_address_set(&ip_0, IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_RARP_COMPLETE, &val, NX_NO_WAIT); + + if(status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address again. */ + status = nx_ip_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver return 1. */ + reject_command = NX_LINK_GET_STATUS; + test_enabled = NX_TRUE; + test_status = 1; + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver return NX_UNHANDLED_COMMAND. */ + reject_command = NX_LINK_GET_STATUS; + test_enabled = NX_TRUE; + test_status = NX_UNHANDLED_COMMAND; + ip_0.nx_ip_interface[0].nx_interface_link_up = 0; + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver return 1. */ + reject_command = NX_LINK_GET_STATUS; + test_enabled = NX_TRUE; + test_status = 1; + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver return NX_UNHANDLED_COMMAND. */ + reject_command = NX_LINK_GET_STATUS; + test_enabled = NX_TRUE; + test_status = NX_UNHANDLED_COMMAND; + ip_0.nx_ip_interface[0].nx_interface_link_up = 0; + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver return NX_SUCCESS. */ + reject_command = NX_LINK_GET_STATUS; + test_enabled = NX_TRUE; + test_status = NX_SUCCESS; + return_value = NX_FALSE; + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver return NX_SUCCESS. */ + reject_command = NX_LINK_GET_STATUS; + test_enabled = NX_TRUE; + test_status = NX_SUCCESS; + return_value = NX_FALSE; + + nx_ip_interface_detach(&ip_0,0); + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void test_driver(struct NX_IP_DRIVER_STRUCT *driver_req) +{ + + /* Inject the command. */ + if ((driver_req -> nx_ip_driver_command == reject_command) && (test_enabled == NX_TRUE)) + { + driver_req -> nx_ip_driver_status = test_status; + *driver_req -> nx_ip_driver_return_ptr = return_value; + test_enabled = NX_FALSE; + } + else + { + _nx_ram_network_driver_1500(driver_req); + } +} + + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_status_check_fail_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Interface Status Check Fail Test.......................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_interface_status_check_test.c b/test/regression/netxduo_test/netx_ip_interface_status_check_test.c new file mode 100644 index 00000000..22112cc5 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_interface_status_check_test.c @@ -0,0 +1,339 @@ +/* This NetX test concentrates on the IP Interface Status Check operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +#define DEMO_STACK_SIZE 2048 + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +/* Define the counters used in the test application... */ +static ULONG error_counter; + +static ULONG test_enabled; +static ULONG test_status; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void test_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_status_check_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + error_counter = 0; + test_enabled = NX_FALSE; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, test_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, test_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + + status = nx_udp_enable(&ip_0); + if (status) + error_counter++; + + status = nx_tcp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_igmp_enable(&ip_0); + if(status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG val; + + + /* Print out test information banner. */ + printf("NetX Test: IP Interface Status Check Test............................"); + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver_1500); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check interface IP address. */ + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_ADDRESS_RESOLVED, &val, NX_NO_WAIT); + if((status != NX_SUCCESS) || !(val & NX_IP_ADDRESS_RESOLVED)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check link status. */ + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_LINK_ENABLED, &val, NX_NO_WAIT); + if((status != NX_SUCCESS) || !(val & NX_IP_LINK_ENABLED)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver return NX_UNHANDLED_COMMAND. */ + test_enabled = NX_TRUE; + test_status = NX_UNHANDLED_COMMAND; + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check ARP status. */ + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_ARP_ENABLED, &val, NX_NO_WAIT); + if((status != NX_SUCCESS) || !(val & NX_IP_ARP_ENABLED)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check UDP status. */ + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_UDP_ENABLED, &val, NX_NO_WAIT); + if((status != NX_SUCCESS) || !(val & NX_IP_UDP_ENABLED)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check TCP status. */ + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_TCP_ENABLED, &val, NX_NO_WAIT); + if((status != NX_SUCCESS) || !(val & NX_IP_TCP_ENABLED)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check IGMP status. */ + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_IGMP_ENABLED, &val, NX_NO_WAIT); + if((status != NX_SUCCESS) || !(val & NX_IP_IGMP_ENABLED)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check RARP status. */ + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_RARP_COMPLETE, &val, NX_NO_WAIT); + /* ip_0 has had an IP address, RARP shoul be in complete status. */ + if((status != NX_SUCCESS) || !(val & NX_IP_RARP_COMPLETE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check an unknown status with wait time 0. the result should be error.*/ + status = nx_ip_interface_status_check(&ip_0, 0, 4343, &val, NX_NO_WAIT); + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check an unknown status with wait time 10. the result should be error.*/ + status = nx_ip_interface_status_check(&ip_0, 0, 4343, &val, 10); + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_status_check(&ip_0, 1, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_status_check(&ip_0, 2, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + + status = nx_ip_interface_status_check(&ip_1, 0, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_ip_interface_status_check(&ip_1, 1, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let driver return NX_UNHANDLED_COMMAND. */ + test_enabled = NX_TRUE; + test_status = NX_UNHANDLED_COMMAND; + + status = nx_ip_interface_status_check(&ip_1, 0, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_ip_interface_status_check(&ip_1, 2, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Modify the ip instance to generate a special test condition. */ + ip_0.nx_ip_id = 1234; + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_INTERFACE_LINK_ENABLED, &val, NX_NO_WAIT); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ip_id = NX_IP_ID; +#endif + + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void test_driver(struct NX_IP_DRIVER_STRUCT *driver_req) +{ + + /* Inject NX_LINK_GET_STATUS command. */ + if ((driver_req -> nx_ip_driver_command == NX_LINK_GET_STATUS) && (test_enabled == NX_TRUE)) + { + driver_req -> nx_ip_driver_status = test_status; + test_enabled = NX_FALSE; + } + else + { + _nx_ram_network_driver_1500(driver_req); + } +} + + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_interface_status_check_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Interface Status Check Test............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_invalid_packet_receive_test.c b/test/regression/netxduo_test/netx_ip_invalid_packet_receive_test.c new file mode 100644 index 00000000..e42fcf0e --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_invalid_packet_receive_test.c @@ -0,0 +1,420 @@ +/* This NetX test concentrates on IP fragmentation disable operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG icmp_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_invalid_packet_receive_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 500, pointer, 4096); + pointer = pointer + 4096; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP traffic. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check for ICMP enable errors. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out some test information banners. */ + printf("NetX Test: IP Invalid Packet Receive Test............................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to get the IPv4 packet. */ + ip_1.nx_ipv4_packet_receive = my_packet_process; + + /* Now ip_0 ping ip_1. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status == NX_SUCCESS) || (my_packet)) + { +#if defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_DISABLE_IP_RX_CHECKSUM) + if (my_packet -> nx_packet_length == 28) +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Check the error counter and icmp counter. */ + if ((error_counter) || (icmp_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +NX_PACKET *copy_packet_0; +NX_PACKET *copy_packet_1; +NX_PACKET *copy_packet_2; +#ifndef NX_DISABLE_PACKET_CHAIN +NX_PACKET *copy_packet_3; +NX_PACKET *copy_packet_4; +NX_PACKET *copy_packet_5; +#endif +#ifdef __PRODUCT_NETXDUO__ +NX_IPV4_HEADER *ip_header_ptr; +#else +NX_IP_HEADER *ip_header_ptr; +#endif + + /* Get the ICMP packet. */ + icmp_counter ++; + + /*************************************************************/ + /* nx_packet_length < header length nx_ipv4_packet_receive() */ + /*************************************************************/ + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_0, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + error_counter++; + + /* Set the invalid packet length. */ + copy_packet_0 -> nx_packet_length = 18; + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(&ip_1, copy_packet_0); + + /**********************************************************/ + /* nx_packet_length < pkt_length nx_ipv4_packet_receive() */ + /**********************************************************/ + + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_1, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + error_counter++; + + /* Get the IPv4 header. */ +#ifdef __PRODUCT_NETXDUO__ + ip_header_ptr = (NX_IPV4_HEADER *)copy_packet_1 -> nx_packet_prepend_ptr; +#else + ip_header_ptr = (NX_IP_HEADER *)copy_packet_1 -> nx_packet_prepend_ptr; +#endif + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Modified the packet length. */ + ip_header_ptr -> nx_ip_header_word_0 += 0x00000001; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(&ip_1, copy_packet_1); + + /****************************************************************************/ + /* nx_packet_length > pkt_length for normal packet nx_ipv4_packet_receive() */ + /****************************************************************************/ + + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_2, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + error_counter++; + + /* Get the IPv4 header. */ +#ifdef __PRODUCT_NETXDUO__ + ip_header_ptr = (NX_IPV4_HEADER *)copy_packet_2 -> nx_packet_prepend_ptr; +#else + ip_header_ptr = (NX_IP_HEADER *)copy_packet_2 -> nx_packet_prepend_ptr; +#endif + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Modified the packet length. */ + ip_header_ptr -> nx_ip_header_word_0 -= 0x00000001; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(&ip_1, copy_packet_2); + +#ifndef NX_DISABLE_PACKET_CHAIN + + /***************************************************************************/ + /* nx_packet_length > pkt_length for chain packet nx_ipv4_packet_receive() */ + /* last packet < delta, two packet chain. */ + /***************************************************************************/ + + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_3, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + error_counter++; + + /* Get the IPv4 header. */ +#ifdef __PRODUCT_NETXDUO__ + ip_header_ptr = (NX_IPV4_HEADER *)copy_packet_3 -> nx_packet_prepend_ptr; +#else + ip_header_ptr = (NX_IP_HEADER *)copy_packet_3 -> nx_packet_prepend_ptr; +#endif + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Modified the packet length. */ + ip_header_ptr -> nx_ip_header_word_0 -= 0x00000004; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, ©_packet_4, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(copy_packet_4 -> nx_packet_prepend_ptr, "ABC", 3); + + /* Adjust the write pointer. bigger than 256 to cause fragmentation. */ + copy_packet_4 -> nx_packet_length = 3; + copy_packet_4 -> nx_packet_append_ptr = copy_packet_4 -> nx_packet_prepend_ptr + 3; + + /* Chain the packet. */ + copy_packet_3 -> nx_packet_next = copy_packet_4; + copy_packet_3 -> nx_packet_last = copy_packet_4; + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(&ip_1, copy_packet_3); + + /***************************************************************************/ + /* nx_packet_length > pkt_length for chain packet nx_ipv4_packet_receive() */ + /* last packet < delta, three packet chain */ + /***************************************************************************/ + + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_3, &pool_0, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + error_counter++; + + /* Get the IPv4 header. */ +#ifdef __PRODUCT_NETXDUO__ + ip_header_ptr = (NX_IPV4_HEADER *)copy_packet_3 -> nx_packet_prepend_ptr; +#else + ip_header_ptr = (NX_IP_HEADER *)copy_packet_3 -> nx_packet_prepend_ptr; +#endif + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Modified the packet length. */ + ip_header_ptr -> nx_ip_header_word_0 -= 0x00000004; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, ©_packet_4, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(copy_packet_4 -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26); + + /* Adjust the write pointer. bigger than 256 to cause fragmentation. */ + copy_packet_4 -> nx_packet_length = 26; + copy_packet_4 -> nx_packet_append_ptr = copy_packet_4 -> nx_packet_prepend_ptr + 26; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, ©_packet_5, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(copy_packet_5 -> nx_packet_prepend_ptr, "ABC", 3); + + /* Adjust the write pointer. bigger than 256 to cause fragmentation. */ + copy_packet_5 -> nx_packet_length = 3; + copy_packet_5 -> nx_packet_append_ptr = copy_packet_5 -> nx_packet_prepend_ptr + 3; + + /* Chain the packet. */ + copy_packet_3 -> nx_packet_next = copy_packet_4; + copy_packet_3 -> nx_packet_last = copy_packet_5; + copy_packet_4 -> nx_packet_next = copy_packet_5; + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(&ip_1, copy_packet_3); +#endif + + /*******************************************************************/ + /* ip_header_length < NX_IP_NORMAL_LENGTH nx_ipv4_packet_receive() */ + /*******************************************************************/ + + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_0, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + error_counter++; + + /* Get the IPv4 header. */ +#ifdef __PRODUCT_NETXDUO__ + ip_header_ptr = (NX_IPV4_HEADER *)copy_packet_0 -> nx_packet_prepend_ptr; +#else + ip_header_ptr = (NX_IP_HEADER *)copy_packet_0 -> nx_packet_prepend_ptr; +#endif + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Modified the header length. */ + ip_header_ptr -> nx_ip_header_word_0 -= 0x01000000; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(&ip_1, copy_packet_0); + + /****************************************************************************/ + /* nx_packet_length = pkt_length and no IP address nx_ipv4_packet_receive() */ + /****************************************************************************/ + + /* Clear the ip_1 instance address. */ + nx_ip_address_set(&ip_1, 0, 0); + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(&ip_1, packet_ptr); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_invalid_packet_receive_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Invalid Packet Receive Test............................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_link_local_address_test.c b/test/regression/netxduo_test/netx_ip_link_local_address_test.c new file mode 100644 index 00000000..743b9673 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_link_local_address_test.c @@ -0,0 +1,314 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_link_local_address_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(169, 254, 3, 4), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT i; +ULONG server_addr; + + /* Print out some test information banners. */ + printf("NetX Test: IP Link-Local Address Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + server_addr = IP_ADDRESS(1, 2, 3, 5); + + for (i = 0; i < 2; i++) + { + + /* Create the client socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Connect to server. */ + status = nx_tcp_client_socket_connect(&client_socket, server_addr, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Disconnect from server. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unbind the client socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Delete the client socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Modify the IP address to routable. */ + nx_ip_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00); + server_addr = IP_ADDRESS(169, 254, 3, 5); + } + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +UINT i; + + for (i = 0; i < 2; i++) + { + + /* Create the server socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Listen the socket. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Accept connection from client. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Disconnect from client. */ + status = nx_tcp_socket_disconnect(&server_socket, 5); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Delete the client socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Modify the IP address to link-local. */ + nx_ip_address_set(&ip_1, IP_ADDRESS(169, 254, 3, 5), 0xFFFF0000); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_link_local_address_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Link-Local Address Test................................N/A\n"); + + test_control_return(3); + +} +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/netxduo_test/netx_ip_link_status_test.c b/test/regression/netxduo_test/netx_ip_link_status_test.c new file mode 100644 index 00000000..bdfcf4c8 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_link_status_test.c @@ -0,0 +1,288 @@ +/* This case tests link status down and up. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static UINT link_up_count; +static UINT link_down_count; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static VOID ntest_0_entry(ULONG thread_input); +static VOID ntest_1_entry(ULONG thread_input); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID link_status_change_notify(NX_IP *ip_ptr, UINT interface_index, UINT link_up); +static VOID set_link_status(NX_IP *ip_ptr, UINT link_status); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_link_status_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + link_up_count = 0; + link_down_count = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check ICMP enable status. */ + if(status) + error_counter++; +} + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: IP Link Status Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let server thread listen first. */ + tx_thread_relinquish(); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Connect to server. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 1 * NX_IP_PERIODIC_RATE); + + /* Check the connection status. */ + if(status != NX_SUCCESS) + error_counter++; + + /* Set link status change notify as NULL. */ + nx_ip_link_status_change_notify_set(&ip_0, NX_NULL); + + /* Simulator link down. */ + set_link_status(&ip_0, NX_FALSE); + + /* Set link status change notify. */ + nx_ip_link_status_change_notify_set(&ip_0, link_status_change_notify); + + /* Simulator link down. */ + set_link_status(&ip_0, NX_FALSE); + + /* Check whether TCP connections are dropped. */ + if (client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Check whether network is reachable. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABC", 3, &packet_ptr, 1 * NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + { + + /* It is not expected to receive a response. */ + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Simulator link up. */ + set_link_status(&ip_0, NX_TRUE); + + /* Check whether network is reachable. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABC", 3, &packet_ptr, 1 * NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + { + + /* It is expected to receive a response. */ + nx_packet_release(packet_ptr); + } + else + { + error_counter++; + } + + /* Determine if the test was successful. */ + if((error_counter) || (link_up_count != 1) || (link_down_count != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; +} + + +static VOID link_status_change_notify(NX_IP *ip_ptr, UINT interface_index, UINT link_up) +{ + if (link_up == NX_TRUE) + { + + /* Link status from down to up. */ + link_up_count++; + } + else + { + /* Link status from up to down. */ + link_down_count++; + + nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + } +} + + +static VOID set_link_status(NX_IP *ip_ptr, UINT link_status) +{ + + /* Set link status and notify IP layer. */ + ip_ptr -> nx_ip_interface[0].nx_interface_link_up = (UCHAR)link_status; + _nx_ip_driver_link_status_event(ip_ptr, 0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_link_status_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Link Status Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_loopback_multihome_test.c b/test/regression/netxduo_test/netx_ip_loopback_multihome_test.c new file mode 100644 index 00000000..99270cad --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_loopback_multihome_test.c @@ -0,0 +1,253 @@ +/* This NetX test concentrates on the ICMP ping through all loopback addresses with multiple addresses. */ + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_LOOPBACK_INTERFACE) && defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_0; +static NXD_ADDRESS ipv6_address_1; +#endif /* FEATURE_NX_IPV6 */ + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_loopback_multihome_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + +#ifndef NX_DISABLE_IPV4 + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +#endif + + /* Enable ICMP processing for IP_0. */ + status = nxd_icmp_enable(&ip_0); + + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + if (status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ + + /* Set the second interface. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, _nx_ram_network_driver_256); + + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Set ipv6 version and address. */ + ipv6_address_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + + if(status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: IP Loopback Multihome Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Wait for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Detect packet in driver callback function. */ + advanced_packet_process_callback = packet_process; + +#ifndef NX_DISABLE_IPV4 + /* Now ping the first IPv4 interface address. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 4), "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + + /* Now ping the second IPv4 interface address. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } +#endif + + +#ifdef FEATURE_NX_IPV6 + /* Now ping the first IPv6 interface address. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_0, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + + /* Now ping the second IPv6 interface address. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28)) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } +#endif /* FEATURE_NX_IPV6 */ + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* No packet is expected to be sent out by driver. */ + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_loopback_multihome_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: IP Loopback Multihome Test................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_malformed_packet_test.c b/test/regression/netxduo_test/netx_ip_malformed_packet_test.c new file mode 100644 index 00000000..497f92cb --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_malformed_packet_test.c @@ -0,0 +1,158 @@ +/* Test processing malformed IP packet. */ + +#include "netx_ip_malformed_packet_test.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_FRAGMENTATION) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static UCHAR pool_area[1024 * 1024]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_malformed_packet_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1552, pool_area, sizeof(pool_area)); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192,168,0,170), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP */ + status = nx_arp_enable(&ip_0, pointer, 1024); + + /* Check ARP enable status. */ + if(status) + error_counter++; + pointer = pointer + 1024; + + /* Enable IP fragmentation logic. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT i; +ULONG packet_available; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: IP Malformed Packet Test.................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get available packets. */ + packet_available = pool_0.nx_packet_pool_available; + + for (i = 0; i < sizeof(raw_packets) / sizeof(RAW_PACKET); i++) + { + + /* Inject all packets. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, raw_packets[i].data, raw_packets[i].length); + packet_ptr -> nx_packet_length = raw_packets[i].length; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the IP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + } + + /* Sleep one second to let all packets consumed by IP thread. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check available packets. */ + if (packet_available != pool_0.nx_packet_pool_available) + { + error_counter++; + } + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_malformed_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Malformed Packet Test..................................N/A\n"); + test_control_return(3); + +} +#endif /* NX_DISABLE_ARP_AUTO_ENTRY */ diff --git a/test/regression/netxduo_test/netx_ip_malformed_packet_test.h b/test/regression/netxduo_test/netx_ip_malformed_packet_test.h new file mode 100644 index 00000000..959f641c --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_malformed_packet_test.h @@ -0,0 +1,9315 @@ +#include "nx_api.h" + +#define TO_RAW_PACKET(p) {(UCHAR *)(&p[14]), sizeof(p) - 14} + +/* Define raw packet data structure. */ +typedef struct +{ + UCHAR *data; + UINT length; +} RAW_PACKET; + +/* Frame (34 bytes) */ +static const unsigned char pkt3700[34] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3c, /* ......@< */ +0xf8, 0xa9, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa /* .. */ +}; + +/* Frame (35 bytes) */ +static const unsigned char pkt3701[35] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3c, /* ......@< */ +0xf8, 0xa8, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78 /* ..x */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3702[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3c, /* ......@< */ +0xf2, 0xe1, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (35 bytes) */ +static const unsigned char pkt3703[35] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3c, /* ......@< */ +0xf8, 0xa8, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0xff /* ... */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3704[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3c, /* ......@< */ +0xf2, 0xe1, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */ +0xff, 0xff /* .. */ +}; + +/* Frame (35 bytes) */ +static const unsigned char pkt3705[35] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3c, /* ......@< */ +0xf8, 0xa8, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x00 /* ... */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3706[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3c, /* ......@< */ +0xf2, 0xe1, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00 /* .. */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3707[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x20, 0x00, 0x40, 0x3c, /* ...= .@< */ +0xd2, 0xa4, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3708[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x20, 0xb9, 0x40, 0x3c, /* ...= .@< */ +0xd1, 0xeb, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (74 bytes) */ +static const unsigned char pkt3709[74] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x00, 0x3c, 0xcd, 0xa9, 0x40, 0x00, 0x40, 0x06, /* .<..@.@. */ +0xeb, 0x0d, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0xca, 0x89, 0x08, 0x4a, 0x40, 0x02, /* .....J@. */ +0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, /* ........ */ +0x72, 0x10, 0x82, 0x33, 0x00, 0x00, 0x02, 0x04, /* r..3.... */ +0x05, 0xb4, 0x04, 0x02, 0x08, 0x0a, 0x0a, 0x14, /* ........ */ +0xcd, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, /* ........ */ +0x03, 0x07 /* .. */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3710[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x21, 0x72, 0x40, 0x3c, /* ...=!r@< */ +0xd1, 0x32, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .2...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3711[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x22, 0x2b, 0x40, 0x3c, /* ...="+@< */ +0xd0, 0x79, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .y...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3712[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x22, 0xe4, 0x40, 0x3c, /* ...=".@< */ +0xcf, 0xc0, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3713[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x23, 0x9d, 0x40, 0x3c, /* ...=#.@< */ +0xcf, 0x07, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3714[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x24, 0x56, 0x40, 0x3c, /* ...=$V@< */ +0xce, 0x4e, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .N...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3715[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x25, 0x0f, 0x40, 0x3c, /* ...=%.@< */ +0xcd, 0x95, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3716[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x25, 0xc8, 0x40, 0x3c, /* ...=%.@< */ +0xcc, 0xdc, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3717[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x26, 0x81, 0x40, 0x3c, /* ...=&.@< */ +0xcc, 0x23, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .#...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3718[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x27, 0x3a, 0x40, 0x3c, /* ...=':@< */ +0xcb, 0x6a, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .j...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3719[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x27, 0xf3, 0x40, 0x3c, /* ...='.@< */ +0xca, 0xb1, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3720[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x28, 0xac, 0x40, 0x3c, /* ...=(.@< */ +0xc9, 0xf8, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3721[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x29, 0x65, 0x40, 0x3c, /* ...=)e@< */ +0xc9, 0x3f, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .?...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3722[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x2a, 0x1e, 0x40, 0x3c, /* ...=*.@< */ +0xc8, 0x86, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3723[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x2a, 0xd7, 0x40, 0x3c, /* ...=*.@< */ +0xc7, 0xcd, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3724[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x2b, 0x90, 0x40, 0x3c, /* ...=+.@< */ +0xc7, 0x14, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3725[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x2c, 0x49, 0x40, 0x3c, /* ...=,I@< */ +0xc6, 0x5b, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .[...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3726[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x2d, 0x02, 0x40, 0x3c, /* ...=-.@< */ +0xc5, 0xa2, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3727[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x2d, 0xbb, 0x40, 0x3c, /* ...=-.@< */ +0xc4, 0xe9, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3728[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x2e, 0x74, 0x40, 0x3c, /* ...=.t@< */ +0xc4, 0x30, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .0...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3729[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x2f, 0x2d, 0x40, 0x3c, /* ...=/-@< */ +0xc3, 0x77, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .w...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3730[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x2f, 0xe6, 0x40, 0x3c, /* ...=/.@< */ +0xc2, 0xbe, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3731[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x30, 0x9f, 0x40, 0x3c, /* ...=0.@< */ +0xc2, 0x05, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3732[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x31, 0x58, 0x40, 0x3c, /* ...=1X@< */ +0xc1, 0x4c, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .L...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3733[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x32, 0x11, 0x40, 0x3c, /* ...=2.@< */ +0xc0, 0x93, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3734[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x32, 0xca, 0x40, 0x3c, /* ...=2.@< */ +0xbf, 0xda, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3735[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x33, 0x83, 0x40, 0x3c, /* ...=3.@< */ +0xbf, 0x21, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .!...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3736[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x34, 0x3c, 0x40, 0x3c, /* ...=4<@< */ +0xbe, 0x68, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .h...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3737[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x34, 0xf5, 0x40, 0x3c, /* ...=4.@< */ +0xbd, 0xaf, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3738[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x35, 0xae, 0x40, 0x3c, /* ...=5.@< */ +0xbc, 0xf6, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3739[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x36, 0x67, 0x40, 0x3c, /* ...=6g@< */ +0xbc, 0x3d, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .=...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3740[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x37, 0x20, 0x40, 0x3c, /* ...=7 @< */ +0xbb, 0x84, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3741[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x37, 0xd9, 0x40, 0x3c, /* ...=7.@< */ +0xba, 0xcb, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3742[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x38, 0x92, 0x40, 0x3c, /* ...=8.@< */ +0xba, 0x12, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3743[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x39, 0x4b, 0x40, 0x3c, /* ...=9K@< */ +0xb9, 0x59, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .Y...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (98 bytes) */ +static const unsigned char pkt3744[98] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x00, 0x54, 0xea, 0x30, 0x00, 0x00, 0x40, 0x01, /* .T.0..@. */ +0x0e, 0x74, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .t...... */ +0x00, 0xaa, 0x08, 0x00, 0xbd, 0x9c, 0xea, 0x30, /* .......0 */ +0x3f, 0x21, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, /* ?!wwwwww */ +0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, /* wwwwwwww */ +0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, /* wwwwwwww */ +0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, /* wwwwwwww */ +0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, /* wwwwwwww */ +0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, /* wwwwwwww */ +0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, /* wwwwwwww */ +0x77, 0x77 /* ww */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3745[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x3a, 0x04, 0x40, 0x3c, /* ...=:.@< */ +0xb8, 0xa0, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3746[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x3a, 0xbd, 0x40, 0x3c, /* ...=:.@< */ +0xb7, 0xe7, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3747[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x3b, 0x76, 0x40, 0x3c, /* ...=;v@< */ +0xb7, 0x2e, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3748[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x3c, 0x2f, 0x40, 0x3c, /* ...=Z@< */ +0xb4, 0x4a, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* .J...... */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt3752[1514] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x05, 0xdc, 0x00, 0x3d, 0x3f, 0x13, 0x40, 0x3c, /* ...=?.@< */ +0xb3, 0x91, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78 /* xx */ +}; + +/* Frame (429 bytes) */ +static const unsigned char pkt3753[429] = { +0x00, 0x06, 0x77, 0x12, 0xfb, 0x99, 0x00, 0x03, /* ..w..... */ +0x1d, 0x10, 0xf4, 0x43, 0x08, 0x00, 0x45, 0x00, /* ...C..E. */ +0x01, 0x9f, 0x00, 0x3d, 0x1f, 0xcc, 0x40, 0x3c, /* ...=..@< */ +0xd7, 0x15, 0xc0, 0xa8, 0x00, 0x0a, 0xc0, 0xa8, /* ........ */ +0x00, 0xaa, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* ..xxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, /* xxxxxxxx */ +0x78, 0x78, 0x78, 0x78, 0x78 /* xxxxx */ +}; + +RAW_PACKET raw_packets[] = +{ + TO_RAW_PACKET(pkt3700), + TO_RAW_PACKET(pkt3701), + TO_RAW_PACKET(pkt3702), + TO_RAW_PACKET(pkt3703), + TO_RAW_PACKET(pkt3704), + TO_RAW_PACKET(pkt3705), + TO_RAW_PACKET(pkt3706), + TO_RAW_PACKET(pkt3707), + TO_RAW_PACKET(pkt3708), +#if 0 /* SYN packet */ + TO_RAW_PACKET(pkt3709), +#endif + TO_RAW_PACKET(pkt3710), + TO_RAW_PACKET(pkt3711), + TO_RAW_PACKET(pkt3712), + TO_RAW_PACKET(pkt3713), + TO_RAW_PACKET(pkt3714), + TO_RAW_PACKET(pkt3715), + TO_RAW_PACKET(pkt3716), + TO_RAW_PACKET(pkt3717), + TO_RAW_PACKET(pkt3718), + TO_RAW_PACKET(pkt3719), + TO_RAW_PACKET(pkt3720), + TO_RAW_PACKET(pkt3721), + TO_RAW_PACKET(pkt3722), + TO_RAW_PACKET(pkt3723), + TO_RAW_PACKET(pkt3724), + TO_RAW_PACKET(pkt3725), + TO_RAW_PACKET(pkt3726), + TO_RAW_PACKET(pkt3727), + TO_RAW_PACKET(pkt3728), + TO_RAW_PACKET(pkt3729), + TO_RAW_PACKET(pkt3730), + TO_RAW_PACKET(pkt3731), + TO_RAW_PACKET(pkt3732), + TO_RAW_PACKET(pkt3733), + TO_RAW_PACKET(pkt3734), + TO_RAW_PACKET(pkt3735), + TO_RAW_PACKET(pkt3736), + TO_RAW_PACKET(pkt3737), + TO_RAW_PACKET(pkt3738), + TO_RAW_PACKET(pkt3739), + TO_RAW_PACKET(pkt3740), + TO_RAW_PACKET(pkt3741), + TO_RAW_PACKET(pkt3742), + TO_RAW_PACKET(pkt3743), +#if 0 /* ICMP packet */ + TO_RAW_PACKET(pkt3744), +#endif + TO_RAW_PACKET(pkt3745), + TO_RAW_PACKET(pkt3746), + TO_RAW_PACKET(pkt3747), + TO_RAW_PACKET(pkt3748), + TO_RAW_PACKET(pkt3749), + TO_RAW_PACKET(pkt3750), + TO_RAW_PACKET(pkt3751), + TO_RAW_PACKET(pkt3752), + TO_RAW_PACKET(pkt3753) +}; \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_ip_max_payload_size_find_test.c b/test/regression/netxduo_test/netx_ip_max_payload_size_find_test.c new file mode 100644 index 00000000..1668eb3a --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_max_payload_size_find_test.c @@ -0,0 +1,296 @@ +/* This NetX test concentrates on the ip max payload size find operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_0; +static NXD_ADDRESS ipv6_address_1; +#endif + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_max_payload_size_find_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + +#ifndef NX_DISABLE_IPV4 + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +#endif + + +#ifdef FEATURE_NX_IPV6 + + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + if(status) + error_counter++; + + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + if(status) + error_counter++; + + ipv6_address_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_1, 64, NX_NULL); + + if(status) + error_counter++; +#endif +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS dest_address; +ULONG start_offset, payload_length; + + /* Print out test information banner. */ + printf("NetX Test: IP Max Payload Size Find Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 10), 0xFF000000, _nx_ram_network_driver_512); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the 2nd interface to IP instance1 */ + status = nx_ip_interface_attach(&ip_1, "2nd interface", IP_ADDRESS(4, 3, 2, 11), 0xFF000000, _nx_ram_network_driver_256); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_IPV4 + dest_address.nxd_ip_version = NX_IP_VERSION_V4; + dest_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + status = nx_ip_max_payload_size_find(&ip_0, &dest_address, 0, 80, 80, NX_PROTOCOL_TCP, + &start_offset, &payload_length); + + if((status != NX_SUCCESS) || (start_offset != 56) || (payload_length != 1460)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + dest_address.nxd_ip_version = NX_IP_VERSION_V4; + dest_address.nxd_ip_address.v4 = IP_ADDRESS(4, 3, 2, 11); + + status = nx_ip_max_payload_size_find(&ip_0, &dest_address, 1, 80, 80, NX_PROTOCOL_TCP, + &start_offset, &payload_length); + + if((status != NX_SUCCESS) ||(start_offset != 56) || (payload_length != 472)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test an invalid address. */ + dest_address.nxd_ip_version = NX_IP_VERSION_V4; + dest_address.nxd_ip_address.v4 = IP_ADDRESS(4, 3, 2, 11); + + status = nx_ip_max_payload_size_find(&ip_0, &dest_address, 3, 80, 80, NX_PROTOCOL_TCP, + &start_offset, &payload_length); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + dest_address.nxd_ip_version = NX_IP_VERSION_V4; + dest_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 4); + + status = nx_ip_max_payload_size_find(&ip_1, &dest_address, 0, 80, 80, NX_PROTOCOL_TCP, + &start_offset, &payload_length); + + if((status != NX_SUCCESS) || (start_offset != 56) || (payload_length != 984)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + dest_address.nxd_ip_version = NX_IP_VERSION_V4; + dest_address.nxd_ip_address.v4 = IP_ADDRESS(4, 3, 2, 10); + + status = nx_ip_max_payload_size_find(&ip_1, &dest_address, 1, 80, 80, NX_PROTOCOL_TCP, + &start_offset, &payload_length); + + /* 56 = 16 + 20 + 20. 216 = 256 + 16 - 56 */ + if((status != NX_SUCCESS) ||(start_offset != 56) || (payload_length != 216)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifdef FEATURE_NX_IPV6 + /* Find the max payload with invalid address index. */ + status = nx_ip_max_payload_size_find(&ip_0, &ipv6_address_1, (NX_MAX_IPV6_ADDRESSES + NX_LOOPBACK_IPV6_ENABLED), 80, 80, NX_PROTOCOL_UDP, &start_offset, &payload_length); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the max payload with valid address index. */ + status = nx_ip_max_payload_size_find(&ip_0, &ipv6_address_1, 0, 80, 80, NX_PROTOCOL_UDP, &start_offset, &payload_length); + /* 64 = 16 + 40 + 8 208 = 1500 + 16 - 64 */ + if((status != NX_SUCCESS) || (start_offset != 64) || (payload_length != 1452)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifndef NX_DISABLE_IPV4 + /* Test an invalid address. */ + dest_address.nxd_ip_version = NX_IP_VERSION_V4; + dest_address.nxd_ip_address.v4 = IP_ADDRESS(4, 3, 2, 11); + + status = nx_ip_max_payload_size_find(&ip_1, &dest_address, 3, 80, 80, NX_PROTOCOL_TCP, + &start_offset, &payload_length); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + + printf("SUCCESS!\n"); + test_control_return(0); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_max_payload_size_find_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Max Payload Size Find Test.............................N/A\n"); + test_control_return(3); + +} +#endif + diff --git a/test/regression/netxduo_test/netx_ip_multicast_interface_detach_test.c b/test/regression/netxduo_test/netx_ip_multicast_interface_detach_test.c new file mode 100644 index 00000000..5b3eac2b --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_multicast_interface_detach_test.c @@ -0,0 +1,216 @@ +/* This NetX test concentrates on the basic multicast IGMP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_multicast_interface_detach_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + /* Check the status. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check the status. */ + if(status) + error_counter++; + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + + /* Check the status. */ + if(status) + error_counter++; + + /* Enable IGMP processing for both this IP instance. */ + status = nx_igmp_enable(&ip_0); + + /* Check enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: IP Multicast Interface Detach Test........................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test the first interface. */ + /* Perform 7 IGMP join operations. */ + status = nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,1), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,2), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,3), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,5), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,6), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,7), 1); + + /* Join one group another 4 times to test the counting operation. */ + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 1); + status += nx_igmp_multicast_interface_join(&ip_0, IP_ADDRESS(224,0,0,4), 1); + + /* Determine if there is an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the groups info. */ + if((ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_count != 1) || + (ip_0.nx_ipv4_multicast_entry[1].nx_ipv4_multicast_join_count != 1) || + (ip_0.nx_ipv4_multicast_entry[2].nx_ipv4_multicast_join_count != 1) || + (ip_0.nx_ipv4_multicast_entry[3].nx_ipv4_multicast_join_count != 5) || + (ip_0.nx_ipv4_multicast_entry[4].nx_ipv4_multicast_join_count != 1) || + (ip_0.nx_ipv4_multicast_entry[5].nx_ipv4_multicast_join_count != 1) || + (ip_0.nx_ipv4_multicast_entry[6].nx_ipv4_multicast_join_count != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_IGMP_INFO + /* Check the groups info. */ + if(ip_0.nx_ip_igmp_groups_joined != 7) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Attempt to join a new group. This should result in an error. */ + status = nx_igmp_multicast_join(&ip_0, IP_ADDRESS(224,0,0,8)); + + /* Determine if an error has occurred. */ + if (status != NX_NO_MORE_ENTRIES) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Detach the seconde interface. */ + status = nx_ip_interface_detach(&ip_0, 1); + + /* Check status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the groups info. */ + if((ip_0.nx_ipv4_multicast_entry[0].nx_ipv4_multicast_join_count != 0) || + (ip_0.nx_ipv4_multicast_entry[1].nx_ipv4_multicast_join_count != 0) || + (ip_0.nx_ipv4_multicast_entry[2].nx_ipv4_multicast_join_count != 0) || + (ip_0.nx_ipv4_multicast_entry[3].nx_ipv4_multicast_join_count != 0) || + (ip_0.nx_ipv4_multicast_entry[4].nx_ipv4_multicast_join_count != 0) || + (ip_0.nx_ipv4_multicast_entry[5].nx_ipv4_multicast_join_count != 0) || + (ip_0.nx_ipv4_multicast_entry[6].nx_ipv4_multicast_join_count != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_IGMP_INFO + /* Check the groups info. */ + if(ip_0.nx_ip_igmp_groups_joined != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_multicast_interface_detach_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IP Multicast Interface Detach Test........................N/A\n"); + test_control_return(3); +} +#endif /* NX_ENABLE_IPV6_MULTICAST */ diff --git a/test/regression/netxduo_test/netx_ip_nxe_api_test.c b/test/regression/netxduo_test/netx_ip_nxe_api_test.c new file mode 100644 index 00000000..99d1f0be --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_nxe_api_test.c @@ -0,0 +1,1746 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "tx_thread.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL invalid_pool; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP invalid_ip; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID link_status_change_notify(NX_IP *ip_ptr, UINT interface_index, UINT link_up); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, pointer, 2048, 1); + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Create an IP instance in ISR with invalid IP address. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 0", IP_ADDRESS(255, 255, 255, 255), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, pointer + 2048, 2048, 1); + + /* Check for IP create errors. */ + if (status != NX_IP_ADDRESS_ERROR) + error_counter++; + + /* Create an IP instance in ISR with corruptted memory. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, pointer + 1, 2048, 1); + + /* Check for IP create errors. */ + if (status != NX_PTR_ERROR) + error_counter++; + + + /* Create an IP instance in ISR with corruptted memory. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, pointer + 1, 2048, 1); + + /* Check for IP create errors. */ + if (status != NX_PTR_ERROR) + error_counter++; + + /* Create an IP instance in ISR with corruptted memory. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, pointer - 1, 2048, 1); + + /* Check for IP create errors. */ + if (status != NX_PTR_ERROR) + error_counter++; + + pointer = pointer + 2048; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_address; +ULONG network_mask; +ULONG return_value_ptr; +ULONG ip_total_packets_sent; +ULONG ip_total_bytes_sent; +ULONG ip_total_packets_received; +ULONG ip_total_bytes_received; +ULONG ip_invalid_packets; +ULONG ip_receive_packets_dropped; +ULONG ip_receive_checksum_errors; +ULONG ip_send_packets_dropped; +ULONG ip_total_fragments_sent; +ULONG ip_total_fragments_received; +#ifdef NX_ENABLE_INTERFACE_CAPABILITY +ULONG interface_capability_flag; +#endif +CHAR *interface_name; +ULONG mtu_size; +ULONG physical_address_msw; +ULONG physical_address_lsw; +ULONG actual_status; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS dest_address; +ULONG start_offset_ptr; +ULONG payload_length_ptr; +#endif + + /* Print out some test information banners. */ + printf("NetX Test: IP NXE API Test..........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_address_change_notify api */ + /************************************************/ + + /* Set the IP address change notify function for NULL IP instance. */ + status = nx_ip_address_change_notify(NX_NULL, NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the IP address change notify function for invalid IP instance. */ + status = nx_ip_address_change_notify(&invalid_ip, NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_address_get api */ + /************************************************/ + + /* Get the IP address for NULL IP instance. */ + status = nx_ip_address_get(NX_NULL, &ip_address, &network_mask); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the IP address for invalid IP instance. */ + status = nx_ip_address_get(&invalid_ip, &ip_address, &network_mask); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IP address with NULL address pointer. */ + status = nx_ip_address_get(&ip_0, NX_NULL, &network_mask); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IP address with NULL network mask pointer. */ + status = nx_ip_address_get(&ip_0, &ip_address, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_address_set api */ + /************************************************/ + + /* Set the IP address for NULL IP instance. */ + status = nx_ip_address_set(NX_NULL, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the IP address for invalid IP instance. */ + status = nx_ip_address_set(&invalid_ip, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address with loopback address. */ + status = nx_ip_address_set(&ip_0, IP_ADDRESS(255, 255, 255, 255), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address with Class C address. */ + status = nx_ip_address_set(&ip_0, IP_ADDRESS(192, 0, 0, 1), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_create api */ + /************************************************/ + +#ifndef NX_DISABLE_ERROR_CHECKING + status = _nxe_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, pointer, 2048, 1, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Create the IP instance with NULL IP instance. */ + status = nx_ip_create(NX_NULL, "NetX IP Instance test", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, pointer, 2048, 1); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the IP instance with NULL pool. */ + status = nx_ip_create(&ip_1, "NetX IP Instance test", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, NX_NULL, _nx_ram_network_driver_256, pointer, 2048, 1); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid pool. */ + invalid_pool.nx_packet_pool_id = NX_NULL; + + /* Create the IP instance with invalid pool. */ + status = nx_ip_create(&ip_1, "NetX IP Instance test", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &invalid_pool, _nx_ram_network_driver_256, pointer, 2048, 1); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the IP instance with NULL driver. */ + status = nx_ip_create(&ip_1, "NetX IP Instance test", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, NX_NULL, pointer, 2048, 1); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the IP instance with NULL memory pointer. */ + status = nx_ip_create(&ip_1, "NetX IP Instance test", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, NX_NULL, 2048, 1); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the IP instance with small memory size. */ + status = nx_ip_create(&ip_1, "NetX IP Instance test", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, pointer, TX_MINIMUM_STACK - 1, 1); + + /* Check for error. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the IP instance with small memory size. */ + status = nx_ip_create(&ip_1, "NetX IP Instance test", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, pointer, 2048, TX_MAX_PRIORITIES); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the IP instance with same IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance test", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, pointer, 2048, 1); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the IP instance with invalid address. */ + status = nx_ip_create(&ip_1, "NetX IP Instance test", IP_ADDRESS(255, 255, 255, 255), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, pointer, 2048, 1); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_delete api */ + /************************************************/ + + /* Delete the IP instance for NULL IP instance. */ + status = nx_ip_delete(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Delete the IP instance for invalid IP instance. */ + status = nx_ip_delete(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_driver_direct_command api */ + /************************************************/ + + /* Set the command for NULL IP instance. */ + status = nx_ip_driver_direct_command(NX_NULL, NX_LINK_GET_STATUS, &return_value_ptr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the command for invalid IP instance. */ + status = nx_ip_driver_direct_command(&invalid_ip, NX_LINK_GET_STATUS, &return_value_ptr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the command with NULL return value pointer. */ + status = nx_ip_driver_direct_command(&ip_0, NX_LINK_GET_STATUS, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /*********************************************************/ + /* Tested the nxe_ip_driver_interface_direct_command api */ + /*********************************************************/ + + /* Set the command for NULL IP instance. */ + status = nx_ip_driver_interface_direct_command(NX_NULL, NX_LINK_GET_STATUS, 0, &return_value_ptr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the command for invalid IP instance. */ + status = nx_ip_driver_interface_direct_command(&invalid_ip, NX_LINK_GET_STATUS, 0, &return_value_ptr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the command with NULL return value pointer. */ + status = nx_ip_driver_interface_direct_command(&ip_0, NX_LINK_GET_STATUS, 0, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the command with error interface index. */ + status = nx_ip_driver_interface_direct_command(&ip_0, NX_LINK_GET_STATUS, NX_MAX_PHYSICAL_INTERFACES, &return_value_ptr); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_forwarding_disable api */ + /************************************************/ + + /* Disable forward feature for NULL IP instance. */ + status = nx_ip_forwarding_disable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Disable forward feature for invalid IP instance. */ + status = nx_ip_forwarding_disable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_forwarding_enable api */ + /************************************************/ + + /* Enable forward feature for NULL IP instance. */ + status = nx_ip_forwarding_enable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Enable forward feature for invalid IP instance. */ + status = nx_ip_forwarding_enable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_fragment_disable api */ + /************************************************/ + + /* Disable fragment feature for NULL IP instance. */ + status = nx_ip_fragment_disable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Disable fragment feature for invalid IP instance. */ + status = nx_ip_fragment_disable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_fragment_enable api */ + /************************************************/ + + /* Enable fragment feature for NULL IP instance. */ + status = nx_ip_forwarding_enable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Enable fragment feature for invalid IP instance. */ + status = nx_ip_fragment_enable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_gateway_address_clear api */ + /************************************************/ + + /* Clear the gateway address for NULL IP instance. */ + status = nx_ip_gateway_address_clear(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Clear the gateway address for invalid IP instance. */ + status = nx_ip_gateway_address_clear(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_gateway_address_get api */ + /************************************************/ + + /* Get the gateway address for NULL IP instance. */ + status = nx_ip_gateway_address_get(NX_NULL, &ip_address); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the gateway address for invalid IP instance. */ + status = nx_ip_gateway_address_get(&invalid_ip, &ip_address); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the gateway address with NULL ip address pointer. */ + status = nx_ip_gateway_address_get(&ip_0, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_gateway_address_set api */ + /************************************************/ + + /* Set the gateway address for NULL IP instance. */ + status = nx_ip_gateway_address_set(NX_NULL, IP_ADDRESS(1, 2, 3, 1)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the gateway address for invalid IP instance. */ + status = nx_ip_gateway_address_set(&invalid_ip, IP_ADDRESS(1, 2, 3, 1)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the gateway address with NULL address. */ + status = nx_ip_gateway_address_set(&ip_0, NX_NULL); + + /* Check the status. */ + if (status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_info_get api */ + /************************************************/ + + /* Get IP info with NULL IP instance. */ + status = nx_ip_info_get(NX_NULL, &ip_total_packets_sent, + &ip_total_bytes_sent, + &ip_total_packets_received, + &ip_total_bytes_received, + &ip_invalid_packets, + &ip_receive_packets_dropped, + &ip_receive_checksum_errors, + &ip_send_packets_dropped, + &ip_total_fragments_sent, + &ip_total_fragments_received); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get IP info with invalid IP instance. */ + status = nx_ip_info_get(&invalid_ip, &ip_total_packets_sent, + &ip_total_bytes_sent, + &ip_total_packets_received, + &ip_total_bytes_received, + &ip_invalid_packets, + &ip_receive_packets_dropped, + &ip_receive_checksum_errors, + &ip_send_packets_dropped, + &ip_total_fragments_sent, + &ip_total_fragments_received); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_interface_address_get api */ + /************************************************/ + + /* Get the interface IP address for NULL IP instance. */ + status = nx_ip_interface_address_get(NX_NULL, 0, &ip_address, &network_mask); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the interface IP address for invalid IP instance. */ + status = nx_ip_interface_address_get(&invalid_ip, 0, &ip_address, &network_mask); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the interface IP address with NULL address pointer. */ + status = nx_ip_interface_address_get(&ip_0, 0, NX_NULL, &network_mask); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the interface IP address with NULL network mask pointer. */ + status = nx_ip_interface_address_get(&ip_0, 0, &ip_address, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the interface IP address with MAX interface index. */ + status = nx_ip_interface_address_get(&ip_0, NX_MAX_PHYSICAL_INTERFACES, &ip_address, &network_mask); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the interface IP address with invalid interface index. */ + status = nx_ip_interface_address_get(&ip_0, 1, &ip_address, &network_mask); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /**************************************************************/ + /* Tested the nxe_ip_interface_address_mapping_configure api */ + /**************************************************************/ + + /* Configure the interface mapping for NULL IP instance. */ + status = nx_ip_interface_address_mapping_configure(NX_NULL, 0, NX_FALSE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Configure the interface mapping for invalid IP instance. */ + status = nx_ip_interface_address_mapping_configure(&invalid_ip, 0, NX_FALSE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Configure the interface mapping with MAX interface index. */ + status = nx_ip_interface_address_mapping_configure(&ip_0, NX_MAX_PHYSICAL_INTERFACES, NX_FALSE); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_interface_address_set api */ + /************************************************/ + + /* Set the IP address with Class B address. */ + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(128, 0, 0, 1), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address with Class C address. */ + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(192, 0, 0, 1), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface IP address for NULL IP instance. */ + status = nx_ip_interface_address_set(NX_NULL, 0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the interface IP address for invalid IP instance. */ + status = nx_ip_interface_address_set(&invalid_ip, 0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface IP address with NULL address pointer. */ + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(255, 255, 255, 255), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface IP address with MAX interface index. */ + status = nx_ip_interface_address_set(&ip_0, NX_MAX_PHYSICAL_INTERFACES, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface IP address with invalid interface index. */ + status = nx_ip_interface_address_set(&ip_0, 1, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + #if (NX_MAX_PHYSICAL_INTERFACES >= 2) + /************************************************/ + /* Tested the nxe_ip_interface_attach api */ + /************************************************/ + + /* Attach the interface for NULL IP instance. */ + status = nx_ip_interface_attach(NX_NULL, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Attach the interface for invalid IP instance. */ + status = nx_ip_interface_attach(&invalid_ip, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the interface for NULL dirver. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the interface for NULL name. */ + status = nx_ip_interface_attach(&ip_0, NX_NULL, IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the interface for invalid IP address. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(255, 255, 255, 255), 0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach the interface for valid IP address. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(192, 0, 0, 2), 0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + nx_ip_interface_detach(&ip_0, 1); +#endif + + + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + /**************************************************/ + /* Tested the nxe_ip_interface_capability_get api */ + /**************************************************/ + + /* Get the interface capability for NULL IP instance. */ + status = nx_ip_interface_capability_get(NX_NULL, 0, &interface_capability_flag); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the interface capability for invalid IP instance. */ + status = nx_ip_interface_capability_get(&invalid_ip, 0, &interface_capability_flag); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the interface capability with MAX interface index. */ + status = nx_ip_interface_capability_get(&ip_0, NX_MAX_PHYSICAL_INTERFACES, &interface_capability_flag); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the interface capability with NULL interface capability pointer. */ + status = nx_ip_interface_capability_get(&ip_0, 0, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /**************************************************/ + /* Tested the nxe_ip_interface_capability_set api */ + /**************************************************/ + + /* Set the interface capability for NULL IP instance. */ + status = nx_ip_interface_capability_set(NX_NULL, 0, NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the interface capability for invalid IP instance. */ + status = nx_ip_interface_capability_set(&invalid_ip, 0, NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface capability with MAX interface index. */ + status = nx_ip_interface_capability_set(&ip_0, NX_MAX_PHYSICAL_INTERFACES, NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /************************************************/ + /* Tested the nxe_ip_interface_detach api */ + /************************************************/ + + /* Detach the interface for NULL IP instance. */ + status = nx_ip_interface_detach(NX_NULL, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Detach the interface for invalid IP instance. */ + status = nx_ip_interface_detach(&invalid_ip, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Detach the interface with MAX interface index. */ + status = nx_ip_interface_detach(&ip_0, NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_interface_info_get api */ + /************************************************/ + + /* Get the interface info for NULL IP instance. */ + status = nx_ip_interface_info_get(NX_NULL, 0, &interface_name, &ip_address, &network_mask, &mtu_size, &physical_address_msw, &physical_address_lsw); + + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the interface info for NULL IP instance. */ + status = nx_ip_interface_info_get(&invalid_ip, 0, &interface_name, &ip_address, &network_mask, &mtu_size, &physical_address_msw, &physical_address_lsw); + + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the interface info with MAX interface index. */ + status = nx_ip_interface_info_get(&ip_0, NX_MAX_PHYSICAL_INTERFACES, &interface_name, &ip_address, &network_mask, &mtu_size, &physical_address_msw, &physical_address_lsw); + + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /*******************************************/ + /* Tested the nxe_ip_interface_mtu_set api */ + /*******************************************/ + + /* Set the interface mtu for NULL IP instance. */ + status = nx_ip_interface_mtu_set(NX_NULL, 0, 512); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the interface mtu for invalid IP instance. */ + status = nx_ip_interface_mtu_set(&invalid_ip, 0, 512); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface mtu with MAX interface index. */ + status = nx_ip_interface_mtu_set(&ip_0, NX_MAX_PHYSICAL_INTERFACES, 512); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /********************************************************/ + /* Tested the nxe_ip_interface_physical_address_get api */ + /********************************************************/ + + /* Get the interface physical address for NULL IP instance. */ + status = nx_ip_interface_physical_address_get(NX_NULL, 0, &physical_address_msw, &physical_address_lsw); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the interface physical address for invalid IP instance. */ + status = nx_ip_interface_physical_address_get(&invalid_ip, 0, &physical_address_msw, &physical_address_lsw); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the interface physical address with NULL physical pointer. */ + status = nx_ip_interface_physical_address_get(&ip_0, 0, NX_NULL, &physical_address_lsw); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the interface physical address with NULL physical pointer. */ + status = nx_ip_interface_physical_address_get(&ip_0, 0, &physical_address_msw, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the interface physical address with MAX interface index. */ + status = nx_ip_interface_physical_address_get(&ip_0, NX_MAX_PHYSICAL_INTERFACES, &physical_address_msw, &physical_address_lsw); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /********************************************************/ + /* Tested the nxe_ip_interface_physical_address_set api */ + /********************************************************/ + + /* Set the interface physical address for NULL IP instance. */ + status = nx_ip_interface_physical_address_set(NX_NULL, 0, 0x0011, 0x0022334457, NX_TRUE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the interface physical address for invalid IP instance. */ + status = nx_ip_interface_physical_address_set(&invalid_ip, 0, 0x0011, 0x0022334457, NX_TRUE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the interface physical address with MAX interface index. */ + status = nx_ip_interface_physical_address_set(&ip_0, NX_MAX_PHYSICAL_INTERFACES, 0x0011, 0x0022334457, NX_TRUE); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_interface_status_check api */ + /************************************************/ + + /* Check the interface status for NULL IP instance. */ + status = nx_ip_interface_status_check(NX_NULL, 0, NX_IP_RARP_COMPLETE, &actual_status, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Check the interface status for invalid IP instance. */ + status = nx_ip_interface_status_check(&invalid_ip, 0, NX_IP_RARP_COMPLETE, &actual_status, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the interface status with NULL actual status pointer. */ + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_RARP_COMPLETE, NX_NULL, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the interface status with MAX interface index. */ + status = nx_ip_interface_status_check(&ip_0, NX_MAX_PHYSICAL_INTERFACES, NX_IP_RARP_COMPLETE, &actual_status, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the interface status with invalid interface index. */ + status = nx_ip_interface_status_check(&ip_0, 1, NX_IP_RARP_COMPLETE, &actual_status, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the interface status with invalid need status. */ + status = nx_ip_interface_status_check(&ip_0, 0, 0x8000, &actual_status, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + + /************************************************/ + /* Tested the nxe_ip_max_payload_size_find api */ + /************************************************/ + + /* Set the dest address. */ + dest_address.nxd_ip_version = NX_IP_VERSION_V4; + dest_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Find the max payload size for NULL IP instance. */ + status = nx_ip_max_payload_size_find(NX_NULL, &dest_address, 0, 80, 80, NX_PROTOCOL_TCP, &start_offset_ptr, &payload_length_ptr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Find the max payload size for invalid IP instance. */ + status = nx_ip_max_payload_size_find(&invalid_ip, &dest_address, 0, 80, 80, NX_PROTOCOL_TCP, &start_offset_ptr, &payload_length_ptr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the max payload size with NULL dest address. */ + status = nx_ip_max_payload_size_find(&ip_0, NX_NULL, 0, 80, 80, NX_PROTOCOL_TCP, &start_offset_ptr, &payload_length_ptr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the dest address. */ + dest_address.nxd_ip_version = 0x80; + dest_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Find the max payload size with invalid dest address. */ + status = nx_ip_max_payload_size_find(&ip_0, &dest_address, 0, 80, 80, NX_PROTOCOL_TCP, &start_offset_ptr, &payload_length_ptr); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the dest address. */ + dest_address.nxd_ip_version = NX_IP_VERSION_V4; + dest_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Find the max payload size with invalid protocol. */ + status = nx_ip_max_payload_size_find(&ip_0, &dest_address, 0, 80, 80, NX_PROTOCOL_ICMP, &start_offset_ptr, &payload_length_ptr); + + /* Check for error. */ + if (status != NX_NOT_SUPPORTED) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifdef NX_ENABLE_DUAL_PACKET_POOL + /************************************************/ + /* Tested the nxe_ip_auxiliary_packet_pool_set api */ + /************************************************/ + + /* Set the auxiliary packet pool for NULL IP instance. */ + status = nx_ip_auxiliary_packet_pool_set(NX_NULL, &pool_0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the auxiliary packet pool for invalid IP instance. */ + status = nx_ip_auxiliary_packet_pool_set(&invalid_ip, &pool_0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the auxiliary packet pool with NULL pool. */ + status = nx_ip_auxiliary_packet_pool_set(&ip_0, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid pool. */ + invalid_pool.nx_packet_pool_id = NX_NULL; + + /* Set the auxiliary packet pool with invalid pool. */ + status = nx_ip_auxiliary_packet_pool_set(&ip_0, &invalid_pool); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ + +#ifdef NX_ENABLE_IP_STATIC_ROUTING + /************************************************/ + /* Tested the nxe_ip_static_route_add api */ + /************************************************/ + + /* Add the static route for NULL IP instance. */ + status = nx_ip_static_route_add(NX_NULL, IP_ADDRESS(1, 2, 3, 10), IP_ADDRESS(255, 255, 255,0 ), IP_ADDRESS(1, 2, 3, 1)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Add the static route for invalid IP instance. */ + status = nx_ip_static_route_add(&invalid_ip, IP_ADDRESS(1, 2, 3, 10), IP_ADDRESS(255, 255, 255, 0), IP_ADDRESS(1, 2, 3, 1)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_ip_static_route_delete api */ + /************************************************/ + + /* Delete the static route for NULL IP instance. */ + status = nx_ip_static_route_delete(NX_NULL, IP_ADDRESS(1, 2, 3, 10), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Delete the static route for invalid IP instance. */ + status = nx_ip_static_route_delete(&invalid_ip, IP_ADDRESS(1, 2, 3, 10), IP_ADDRESS(255, 255, 255, 0)); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /************************************************/ + /* Tested the nxe_ip_status_check api */ + /************************************************/ + + /* Check the status for NULL IP instance. */ + status = nx_ip_status_check(NX_NULL, NX_IP_RARP_COMPLETE, &actual_status, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Check the status for invalid IP instance. */ + status = nx_ip_status_check(&invalid_ip, NX_IP_RARP_COMPLETE, &actual_status, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the status with NULL actual status pointer. */ + status = nx_ip_status_check(&ip_0, NX_IP_RARP_COMPLETE, NX_NULL, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the status with invalid need status. */ + status = nx_ip_status_check(&ip_0, 0x8000, &actual_status, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /******************************************************/ + /* Tested the nx_ip_link_status_change_notify_set api */ + /******************************************************/ + + /* Set link status change notify will NULL IP. */ + status = nx_ip_link_status_change_notify_set(NX_NULL, link_status_change_notify); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set link status change notify will NULL callback function pointer. */ + status = nx_ip_link_status_change_notify_set(&ip_0, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static VOID link_status_change_notify(NX_IP *ip_ptr, UINT interface_index, UINT link_up) +{ +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP NXE API Test...........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_packet_filter_extended_test.c b/test/regression/netxduo_test/netx_ip_packet_filter_extended_test.c new file mode 100644 index 00000000..790c0434 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_packet_filter_extended_test.c @@ -0,0 +1,369 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(NX_ENABLE_IP_PACKET_FILTER) && !defined(NX_DISABLE_ICMP_INFO) && defined(__PRODUCT_NETXDUO__) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; +#endif /* FEATURE_NX_IPV6 */ + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT drop_incoming_packet_extended(struct NX_IP_STRUCT *ip_ptr, NX_PACKET *packet_ptr, UINT direction); +static UINT drop_outgoing_packet_extended(struct NX_IP_STRUCT *ip_ptr, NX_PACKET *packet_ptr, UINT direction); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_packet_filter_extended_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + +#ifndef NX_DISABLE_IPV4 + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +#endif + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT test_sent = 0; +UINT test_responses_received = 0; +UINT test_received = 0; +UINT test_responded_to = 0; + + /* Print out test information banner. */ + printf("NetX Test: IP Packet Filter Extended Test............................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + +#ifndef NX_DISABLE_IPV4 + /* Do not set packet filter. */ + ip_0.nx_ip_packet_filter_extended = NX_NULL; + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + nx_packet_release(my_packet); + + test_sent++; test_responses_received++; + test_received++; test_responded_to++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Set packet filter to drop outgoing packet. */ + ip_0.nx_ip_packet_filter_extended = drop_outgoing_packet_extended; + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + test_sent++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Set packet filter to drop incoming packet. */ + ip_0.nx_ip_packet_filter_extended = drop_incoming_packet_extended; + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + test_sent++; + test_received++; test_responded_to++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifdef FEATURE_NX_IPV6 + /* Do not set packet filter. */ + ip_0.nx_ip_packet_filter_extended = NX_NULL; + + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + nx_packet_release(my_packet); + + test_sent++; test_responses_received++; + test_received++; test_responded_to++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Set packet filter to drop outgoing packet. */ + ip_0.nx_ip_packet_filter_extended = drop_outgoing_packet_extended; + + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + test_sent++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Set packet filter to drop incoming packet. */ + ip_0.nx_ip_packet_filter_extended = drop_incoming_packet_extended; + + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + test_sent++; + test_received++; test_responded_to++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* FEATURE_NX_IPV6 */ + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT drop_incoming_packet_extended(struct NX_IP_STRUCT *ip_ptr, NX_PACKET *packet_ptr, UINT direction) +{ + if (direction == NX_IP_PACKET_IN) + { + return(NX_INVALID_PACKET); + } + return(NX_SUCCESS); +} + +static UINT drop_outgoing_packet_extended(struct NX_IP_STRUCT *ip_ptr, NX_PACKET *packet_ptr, UINT direction) +{ + if (direction == NX_IP_PACKET_OUT) + { + return(NX_INVALID_PACKET); + } + return(NX_SUCCESS); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_packet_filter_extended_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Packet Filter Extended Test............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_packet_filter_test.c b/test/regression/netxduo_test/netx_ip_packet_filter_test.c new file mode 100644 index 00000000..876965d1 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_packet_filter_test.c @@ -0,0 +1,369 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(NX_ENABLE_IP_PACKET_FILTER) && !defined(NX_DISABLE_ICMP_INFO) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; +#endif /* FEATURE_NX_IPV6 */ + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT drop_incoming_packet(VOID *ip_header_ptr, UINT direction); +static UINT drop_outgoing_packet(VOID *ip_header_ptr, UINT direction); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_packet_filter_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + +#ifndef NX_DISABLE_IPV4 + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +#endif + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT test_sent = 0; +UINT test_responses_received = 0; +UINT test_received = 0; +UINT test_responded_to = 0; + + /* Print out test information banner. */ + printf("NetX Test: IP Packet Filter Test....................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + +#ifndef NX_DISABLE_IPV4 + /* Do not set packet filter. */ + ip_0.nx_ip_packet_filter = NX_NULL; + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + nx_packet_release(my_packet); + + test_sent++; test_responses_received++; + test_received++; test_responded_to++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Set packet filter to drop outgoing packet. */ + ip_0.nx_ip_packet_filter = drop_outgoing_packet; + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + test_sent++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Set packet filter to drop incoming packet. */ + ip_0.nx_ip_packet_filter = drop_incoming_packet; + + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + test_sent++; + test_received++; test_responded_to++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifdef FEATURE_NX_IPV6 + /* Do not set packet filter. */ + ip_0.nx_ip_packet_filter = NX_NULL; + + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + nx_packet_release(my_packet); + + test_sent++; test_responses_received++; + test_received++; test_responded_to++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Set packet filter to drop outgoing packet. */ + ip_0.nx_ip_packet_filter = drop_outgoing_packet; + + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + test_sent++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Set packet filter to drop incoming packet. */ + ip_0.nx_ip_packet_filter = drop_incoming_packet; + + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + test_sent++; + test_received++; test_responded_to++; + + /* Check ping sent and ping received. */ + if ((ip_0.nx_ip_pings_sent != test_sent) || + (ip_0.nx_ip_ping_responses_received != test_responses_received) || + (ip_1.nx_ip_pings_received != test_received) || + (ip_1.nx_ip_pings_responded_to != test_responded_to)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* FEATURE_NX_IPV6 */ + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT drop_incoming_packet(VOID *ip_header_ptr, UINT direction) +{ + if (direction == NX_IP_PACKET_IN) + { + return(NX_INVALID_PACKET); + } + return(NX_SUCCESS); +} + +static UINT drop_outgoing_packet(VOID *ip_header_ptr, UINT direction) +{ + if (direction == NX_IP_PACKET_OUT) + { + return(NX_INVALID_PACKET); + } + return(NX_SUCCESS); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_packet_filter_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Packet Filter Test.....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_raw_loopback_test.c b/test/regression/netxduo_test/netx_ip_raw_loopback_test.c new file mode 100644 index 00000000..e6b0c913 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_raw_loopback_test.c @@ -0,0 +1,240 @@ +/* This NetX test concentrates on the raw packet send/receive through loopback interface. */ + +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_LOOPBACK_INTERFACE) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_addr; +#endif /* FEATURE_NX_IPV6 */ +static NXD_ADDRESS ipv4_lo; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_raw_loopback_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status != NX_SUCCESS) + error_counter++; + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status != NX_SUCCESS) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + ipv6_addr.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_addr.nxd_ip_address.v6[0] = 0x20010000; + ipv6_addr.nxd_ip_address.v6[1] = 0x00000000; + ipv6_addr.nxd_ip_address.v6[2] = 0x00000000; + ipv6_addr.nxd_ip_address.v6[3] = 0x00010001; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + status = nxd_icmp_enable(&ip_0); + if(status != NX_SUCCESS) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ + + ipv4_lo.nxd_ip_version = NX_IP_VERSION_V4; + ipv4_lo.nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); + + status = nx_ip_raw_packet_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + + /* Print out test information banner. */ + printf("NetX Test: IP Raw Loopback Test......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + for (i = 0; i < 3; i++) +#else + for (i = 0; i < 2; i++) +#endif + { + + /* Now, pickup the three raw packets that should be queued on the other IP instance. */ + status = nx_ip_raw_packet_receive(&ip_0, &my_packet, NX_WAIT_FOREVER); + if (status != NX_SUCCESS) + error_counter++; + + if((my_packet -> nx_packet_length != 28) || + (memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28))) + error_counter++; + + status = nx_packet_release(my_packet); + if (status != NX_SUCCESS) + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +UINT i; + +#ifdef FEATURE_NX_IPV6 + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_addr, 64, NX_NULL); + if(status != NX_SUCCESS) + error_counter++; + + /* DAD */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + +#ifdef FEATURE_NX_IPV6 + for (i = 0; i < 3; i++) +#else + for (i = 0; i < 2; i++) +#endif + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the raw IP packet. */ + if (i == 0) + { + status = nx_ip_raw_packet_source_send(&ip_0, my_packet, ipv4_lo.nxd_ip_address.v4, + NX_LOOPBACK_INTERFACE, NX_IP_NORMAL); + } + else if (i == 1) + { + status = nxd_ip_raw_packet_source_send(&ip_0, my_packet, &ipv4_lo, + NX_LOOPBACK_INTERFACE, NX_IP_RAW >> 16, 255, NX_IP_NORMAL); + } +#ifdef FEATURE_NX_IPV6 + else + { + status = nxd_ip_raw_packet_source_send(&ip_0, my_packet, &ipv6_addr, + 0, NX_IP_RAW >> 16, 255, NX_IP_NORMAL); + } +#endif + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_raw_loopback_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Raw Loopback Test......................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_raw_packet_filter_test.c b/test/regression/netxduo_test/netx_ip_raw_packet_filter_test.c new file mode 100644 index 00000000..ebd9d43e --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_raw_packet_filter_test.c @@ -0,0 +1,265 @@ +/* This NetX test concentrates on the raw packet IPv6 send/receive operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(NX_ENABLE_IP_RAW_PACKET_FILTER) && !defined(NX_DISABLE_IPV4) +#include "nx_tcp.h" +#include "nx_udp.h" + +#define DEMO_STACK_SIZE 2048 + +#ifdef NX_ENABLE_IP_RAW_PACKET_ALL_STACK +#define PROTOCOL NX_PROTOCOL_ICMP +#else +#define PROTOCOL 0x99 +#endif + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +static UINT flag; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT my_raw_packet_filter(NX_IP *ip_ptr, ULONG protocol, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_raw_packet_filter_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + flag = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status != NX_SUCCESS) + error_counter++; + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status != NX_SUCCESS) + error_counter++; + + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 10), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status != NX_SUCCESS) + error_counter++; + + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status != NX_SUCCESS) + error_counter++; + + /* Enable UDP for IP instances. */ + status = nx_udp_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_udp_enable(&ip_1); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&ip_0); + if(status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&ip_1); + if(status) + error_counter++; + + status = nx_ip_raw_packet_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_ip_raw_packet_enable(&ip_1); + if (status != NX_SUCCESS) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG value; + + + /* Print out test information banner. */ + printf("NetX Test: IP Raw Packet Filter Test................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_INITIALIZE_DONE)) + error_counter++; + + /* Set the filter. */ + status = nx_ip_raw_packet_filter_set(&ip_0, my_raw_packet_filter); + if(status != NX_SUCCESS) + error_counter++; + + /* Let filter been called. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + if (flag != 1) + { + + /* Expect packet received. */ + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +ULONG value; +NXD_ADDRESS dest_addr; + + dest_addr.nxd_ip_version = NX_IP_VERSION_V4; + dest_addr.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 9); + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE); + if ((status) || (value != NX_IP_INITIALIZE_DONE)) + error_counter++; + + /* Allocate another packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + /* Send the raw IP packet. */ + status = nxd_ip_raw_packet_source_send(&ip_1, my_packet, &dest_addr, 0, PROTOCOL, 0x80, NX_IP_NORMAL); + if (status != NX_SUCCESS) + error_counter++; + + /* Send again. */ + /* Allocate another packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + /* Send the second raw IP packet. */ + status = nxd_ip_raw_packet_source_send(&ip_1, my_packet, &dest_addr, 0, PROTOCOL, 0x80, NX_IP_NORMAL); + if (status != NX_SUCCESS) + error_counter++; + +} + +static UINT my_raw_packet_filter(NX_IP *ip_ptr, ULONG protocol, NX_PACKET *packet_ptr) +{ + if (protocol != PROTOCOL) + { + error_counter++; + } + if (memcmp(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", packet_ptr -> nx_packet_length)) + { + error_counter++; + } + if (flag == 0) + { + flag++; + return NX_SUCCESS; + } + else + { + /* In order to test code in _nx_ip_raw_packet_processing. */ + return 123; + } + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_raw_packet_filter_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Raw Packet Filter Test.................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_raw_packet_queue_test.c b/test/regression/netxduo_test/netx_ip_raw_packet_queue_test.c new file mode 100644 index 00000000..a5f33b0c --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_raw_packet_queue_test.c @@ -0,0 +1,252 @@ +/* This NetX test concentrates on the raw packet IPv6 send/receive operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_udp.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_raw_packet_queue_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status != NX_SUCCESS) + error_counter++; + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status != NX_SUCCESS) + error_counter++; + + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 10), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status != NX_SUCCESS) + error_counter++; + + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status != NX_SUCCESS) + error_counter++; + + /* Enable UDP for IP instances. */ + status = nx_udp_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_udp_enable(&ip_1); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&ip_0); + if(status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&ip_1); + if(status) + error_counter++; + + status = nx_ip_raw_packet_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_ip_raw_packet_enable(&ip_1); + if (status != NX_SUCCESS) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG value; +NX_PACKET *my_packet; +UINT i; + + + /* Print out test information banner. */ + printf("NetX Test: IP Raw Packet Queue Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_INITIALIZE_DONE)) + error_counter++; + + /* Set queue size to 2. */ + status = nx_ip_raw_receive_queue_max_set(&ip_0, 2); + if(status != NX_SUCCESS) + error_counter++; + + /* Let thread 1 to send 3 packets. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Receive 2 packets. */ + i = 0; + while(i < 2) + { + i++; + + /* Receive the second packet. */ + status = nx_ip_raw_packet_receive(&ip_0, &my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + error_counter++; + + status = nx_packet_release(my_packet); + if (status != NX_SUCCESS) + error_counter++; + } + + /* Because the queue size is 2, the 3rd packet can't be received. */ + status = nx_ip_raw_packet_receive(&ip_0, &my_packet, NX_IP_PERIODIC_RATE); + + if (status != NX_NO_PACKET) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +ULONG value; +UINT i; + + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_INITIALIZE_DONE)) + error_counter++; + + i = 0; + while(i < 2) + { + i++; + + /* Allocate another packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the second raw IP packet. */ + status = nx_ip_raw_packet_send(&ip_1, my_packet, IP_ADDRESS(1, 2, 3, 9), NX_IP_NORMAL); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + } +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_raw_packet_queue_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Raw Packet Queue Test..................................N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/netxduo_test/netx_ip_raw_packet_test.c b/test/regression/netxduo_test/netx_ip_raw_packet_test.c new file mode 100644 index 00000000..7e2db158 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_raw_packet_test.c @@ -0,0 +1,557 @@ +/* This NetX test concentrates on the raw packet IP send/receive operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_udp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *ip_0_memory_ptr; +static CHAR *ip_1_memory_ptr; +static CHAR *arp_0_memory_ptr; +static CHAR *arp_1_memory_ptr; +static NX_TCP_SOCKET tcp_server_socket; +static NX_TCP_SOCKET tcp_client_socket; +static NX_UDP_SOCKET udp_server_socket; +static NX_UDP_SOCKET udp_client_socket; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_raw_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ip_0_memory_ptr = NX_NULL; + ip_1_memory_ptr = NX_NULL; + arp_0_memory_ptr = NX_NULL; + arp_1_memory_ptr = NX_NULL; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create IP instances. */ + ip_0_memory_ptr = pointer; + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + ip_1_memory_ptr = pointer; + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 10), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + arp_0_memory_ptr = pointer; + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + arp_1_memory_ptr = pointer; + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +} + + +#ifndef NX_DISABLE_FRAGMENTATION +static UCHAR buff[256]; +#endif /* NX_DISABLE_FRAGMENTATION */ + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_address; +ULONG mask; +ULONG value; +ULONG ip_total_packets_sent; +ULONG ip_total_bytes_sent; +ULONG ip_total_packets_received; +ULONG ip_total_bytes_received; +ULONG ip_invalid_packets; +ULONG ip_receive_packets_dropped; +ULONG ip_receive_checksum_errors; +ULONG ip_send_packets_dropped; +ULONG ip_total_fragments_sent; +ULONG ip_total_fragments_received; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: IP Raw Packet Test........................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the IP address. */ + status = nx_ip_address_get(&ip_0, &ip_address, &mask); + + /* Check for an error. */ + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 9))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address. */ + status = nx_ip_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 13), 0xFFFFFF00UL); + status += nx_ip_address_get(&ip_0, &ip_address, &mask); + + /* Check for an error. */ + if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 13))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete both IP instances. */ + status = nx_ip_delete(&ip_0); + status += nx_ip_delete(&ip_1); + + /* Check for an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_0_memory_ptr, 2048, 1); + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + ip_1_memory_ptr, 2048, 1); + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_0, (void *) arp_0_memory_ptr, 1024); + status += nx_arp_enable(&ip_1, (void *) arp_1_memory_ptr, 1024); + + /* Enable TCP for IP instances. */ + status += nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable UDP for IP instances. */ + status += nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check the status of the IP instances. */ + status += nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_INITIALIZE_DONE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call driver directly. */ + status = nx_ip_driver_direct_command(&ip_0, NX_LINK_GET_STATUS, &value); + + /* Check for an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable and disable forwarding. */ + status = nx_ip_forwarding_enable(&ip_0); + status += nx_ip_forwarding_disable(&ip_0); + + /* Check for an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_FRAGMENTATION + /* Enable and disable fragmenting. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_disable(&ip_0); + status += nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + status += nx_ip_fragment_disable(&ip_1); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Set the gateway address. */ + status = nx_ip_gateway_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 87)); + + /* Check for an error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get IP info. */ + status = nx_ip_info_get(&ip_0, &ip_total_packets_sent, + &ip_total_bytes_sent, + &ip_total_packets_received, + &ip_total_bytes_received, + &ip_invalid_packets, + &ip_receive_packets_dropped, + &ip_receive_checksum_errors, + &ip_send_packets_dropped, + &ip_total_fragments_sent, + &ip_total_fragments_received); + + /* Check status. */ + if ((status) || (ip_total_packets_sent) || (ip_total_bytes_sent) || (ip_total_packets_received) || + (ip_total_bytes_received) || (ip_invalid_packets) || (ip_receive_packets_dropped) || (ip_receive_checksum_errors) || + (ip_send_packets_dropped) || (ip_total_fragments_sent) || (ip_total_fragments_received)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable raw IP packet sending and receiving. This can only be done between two NetX nodes. */ + status = nx_ip_raw_packet_enable(&ip_0); + status += nx_ip_raw_packet_enable(&ip_1); + +#ifndef NX_DISABLE_FRAGMENTATION + /* Allocate a packet. */ + status += nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Write ABCs into the packet payload! */ + status += nx_packet_data_append(my_packet, buff, sizeof(buff), &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the raw IP packet. */ + status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_FRAGMENTATION */ + + /* Allocate another packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + +#ifdef __PRODUCT_NETXDUO__ + /* Send the second raw IP packet. */ + status = nx_ip_raw_packet_source_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0, NX_IP_NORMAL); +#else + status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL); +#endif /* __PRODUCT_NETXDUO__ */ + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate another packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the third raw IP packet. */ + status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_FRAGMENTATION + /* Now, pickup the three raw packets that should be queued on the other IP instance. */ + status = nx_ip_raw_packet_receive(&ip_1, &my_packet, NX_IP_PERIODIC_RATE); + status += nx_packet_release(my_packet); + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_FRAGMENTATION */ + + /* Receive the second packet. */ + status = nx_ip_raw_packet_receive(&ip_1, &my_packet, NX_IP_PERIODIC_RATE); + status += nx_packet_release(my_packet); + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive the third packet. */ + status = nx_ip_raw_packet_receive(&ip_1, &my_packet, NX_IP_PERIODIC_RATE); + status += nx_packet_release(my_packet); + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to receive a packet on an empty queue.... should be an error. */ + status = nx_ip_raw_packet_receive(&ip_1, &my_packet, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_NO_PACKET) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check TCP connection when raw packet is enabled. */ + /* Create a server socket. */ + status = nx_tcp_socket_create(&ip_1, &tcp_server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Setup this thread to listen. */ + status += nx_tcp_server_socket_listen(&ip_1, 12, &tcp_server_socket, 5, NX_NULL); + + /* Create a client socket. */ + status += nx_tcp_socket_create(&ip_0, &tcp_client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Bind the socket. */ + status += nx_tcp_client_socket_bind(&tcp_client_socket, 12, NX_WAIT_FOREVER); + + /* Connect to server. */ + nx_tcp_client_socket_connect(&tcp_client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* If accept return successfully, then it handles an illegal option length for MSS. */ + status += nx_tcp_server_socket_accept(&tcp_server_socket, NX_IP_PERIODIC_RATE); + + /* Check if client is in establish state. */ + status += nx_tcp_socket_state_wait(&tcp_client_socket, NX_TCP_ESTABLISHED, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Append data. */ + status += nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_NO_WAIT); + + /* Send a packet from server to client. */ + status += nx_tcp_socket_send(&tcp_server_socket, my_packet, NX_NO_WAIT); + + /* Receive packet from server. */ + status += nx_tcp_socket_receive(&tcp_client_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status and received data. */ + if(status || memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + status++; + + /* Release packet. */ + status += nx_packet_release(my_packet); + + /* Disconnect. */ + nx_tcp_socket_disconnect(&tcp_server_socket, NX_NO_WAIT); + nx_tcp_socket_disconnect(&tcp_client_socket, NX_NO_WAIT); + nx_tcp_server_socket_unaccept(&tcp_server_socket); + + /* Check if both sockets are closed. */ + status += nx_tcp_socket_state_wait(&tcp_client_socket, NX_TCP_CLOSED, NX_NO_WAIT); + status += nx_tcp_socket_state_wait(&tcp_client_socket, NX_TCP_CLOSED, NX_NO_WAIT); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check UDP connection when raw packet is enabled. */ + /* Create two UDP sockets. */ + status = nx_udp_socket_create(&ip_0, &udp_client_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + status += nx_udp_socket_create(&ip_1, &udp_server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the UDP socket to the IP port. */ + status += nx_udp_socket_bind(&udp_client_socket, 0x89, NX_NO_WAIT); + status += nx_udp_socket_bind(&udp_server_socket, 0x89, NX_NO_WAIT); + + /* Allocate a packet. */ + status += nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Append data. */ + status += nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_NO_WAIT); + + /* Send the UDP packet. */ + status += nx_udp_socket_send(&udp_client_socket, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Receive a UDP packet. */ + status += nx_udp_socket_receive(&udp_server_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status and received data. */ + if(status || memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + status++; + + /* Unbind the UDP socket. */ + status += nx_udp_socket_unbind(&udp_client_socket); + status += nx_udp_socket_unbind(&udp_server_socket); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Disable the raw IP capability on both IP instances. */ + status = nx_ip_raw_packet_disable(&ip_0); + status += nx_ip_raw_packet_disable(&ip_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_raw_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Raw Packet Test........................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_ip_route_reachable_test.c b/test/regression/netxduo_test/netx_ip_route_reachable_test.c new file mode 100644 index 00000000..42c701a9 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_route_reachable_test.c @@ -0,0 +1,181 @@ +/* This NetX test concentrates on route reachable. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_route_reachable_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing. */ + status = nx_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: IP Route Reachable Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup gateway. */ + status = nx_ip_gateway_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 1)); + + if (status) + error_counter++; + +#ifdef NX_ENABLE_IP_STATIC_ROUTING + /* Add static routing. */ + status = nx_ip_static_route_add(&ip_0, IP_ADDRESS(3, 2, 3, 0), 0xFFFFFF00, IP_ADDRESS(1, 2, 3, 2)); + + if (status) + error_counter++; +#endif /* NX_ENABLE_IP_STATIC_ROUTING */ + + /* Now ping out of network address through gateway without waiting. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &packet_ptr, NX_NO_WAIT); + + if (status != NX_NO_RESPONSE) + error_counter++; + +#ifdef NX_ENABLE_IP_STATIC_ROUTING + /* Now ping out of network address through static route without waiting. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(3, 2, 3, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &packet_ptr, NX_NO_WAIT); + + if (status != NX_NO_RESPONSE) + error_counter++; +#endif /* NX_ENABLE_IP_STATIC_ROUTING */ + + /* Now set the address to other network. */ + status = nx_ip_interface_address_set(&ip_0, 0, IP_ADDRESS(1, 3, 3, 4), 0xFFFFFF00); + + if (status) + error_counter++; + + /* Now ping out of network address through gateway without waiting. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &packet_ptr, NX_NO_WAIT); + + if (status != NX_IP_ADDRESS_ERROR) + error_counter++; + +#ifdef NX_ENABLE_IP_STATIC_ROUTING + /* Now ping out of network address through static route without waiting. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(3, 2, 3, 1), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &packet_ptr, NX_NO_WAIT); + + if (status != NX_IP_ADDRESS_ERROR) + error_counter++; +#endif /* NX_ENABLE_IP_STATIC_ROUTING */ + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_route_reachable_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Route Reachable Test...................................N/A\n"); + + test_control_return(3); + +} +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/netxduo_test/netx_ip_static_route_add_test.c b/test/regression/netxduo_test/netx_ip_static_route_add_test.c new file mode 100644 index 00000000..319e8680 --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_static_route_add_test.c @@ -0,0 +1,184 @@ +/* This NetX test concentrates on the IP Static Route Add operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_static_route_add_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +#ifdef NX_ENABLE_IP_STATIC_ROUTING +UINT i; +ULONG network_address; +ULONG network_mask; +ULONG next_hop_address; +#endif + + /* Print out test information banner. */ + printf("NetX Test: IP Static Route Add Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the gateway address with another network address. */ + status = nx_ip_static_route_add(&ip_0, IP_ADDRESS(2, 2, 3, 4), IP_ADDRESS(255, 255, 255, 0), IP_ADDRESS(2, 2, 3, 1)); + +#ifdef NX_ENABLE_IP_STATIC_ROUTING + /* Check the status. */ + if (status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#else + /* Check the status. */ + if (status != NX_NOT_SUPPORTED) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifdef NX_ENABLE_IP_STATIC_ROUTING + + /* Set the network_address, networ_mask and next_hop_address. */ + network_address = IP_ADDRESS(2, 2, 3, 4); + network_mask = IP_ADDRESS(255, 255, 0, 0); + next_hop_address = IP_ADDRESS(1, 2, 3, 4); + + /* Loop to add the static route. */ + for (i = 0; i < NX_IP_ROUTING_TABLE_SIZE; i++) + { + + /* Add the static route. */ + status = nx_ip_static_route_add(&ip_0, network_address, network_mask, next_hop_address); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Update the network_address. */ + network_address += 0x00010000; + } + + /* Update the network_mask. */ + network_mask = IP_ADDRESS(255, 254, 0, 0); + + /* Add the static route with larger nets when the table is full. */ + status = nx_ip_static_route_add(&ip_0, network_address, network_mask, next_hop_address); + + /* Check the status. */ + if (status != NX_OVERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Update the network_mask. */ + network_mask = IP_ADDRESS(255, 255, 255, 0); + + /* Add the static route with small nets when the table is full. */ + status = nx_ip_static_route_add(&ip_0, network_address, network_mask, next_hop_address); + + /* Check the status. */ + if (status != NX_OVERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_static_route_add_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP Static Route Add Test..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_static_route_delete_test.c b/test/regression/netxduo_test/netx_ip_static_route_delete_test.c new file mode 100644 index 00000000..ad63eb9c --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_static_route_delete_test.c @@ -0,0 +1,144 @@ +/* This NetX test concentrates on the IP Static Route Delete operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if defined(NX_ENABLE_IP_STATIC_ROUTING) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_static_route_delete_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: IP Static Route Delete Test..............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Add the static route. */ + status = nx_ip_static_route_add(&ip_0, IP_ADDRESS(2, 2, 3, 4), IP_ADDRESS(255, 255, 255, 0), IP_ADDRESS(1, 2, 3, 5)); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the inexistent static route. */ + status = nx_ip_static_route_delete(&ip_0, IP_ADDRESS(3, 2, 3, 4), IP_ADDRESS(255, 255, 255, 0)); + + /* Check the status. */ + if (status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the existent static route. */ + status = nx_ip_static_route_delete(&ip_0, IP_ADDRESS(2, 2, 3, 4), IP_ADDRESS(255, 255, 255, 0)); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the static route when the entry count is zero. */ + status = nx_ip_static_route_delete(&ip_0, IP_ADDRESS(2, 2, 3, 4), IP_ADDRESS(255, 255, 255, 0)); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_static_route_delete_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Static Route Delete Test...............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_static_route_find_test.c b/test/regression/netxduo_test/netx_ip_static_route_find_test.c new file mode 100644 index 00000000..775401db --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_static_route_find_test.c @@ -0,0 +1,216 @@ +/* This NetX test concentrates on the IP Static Route Find operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if defined (__PRODUCT_NETXDUO__) && defined (NX_ENABLE_IP_STATIC_ROUTING) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ +static ULONG error_counter; +static ULONG icmp_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_static_route_find_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG return_value; + + + /* Print out test information banner. */ + printf("NetX Test: IP Static Route Find Test................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the gateway address with another network address. */ + status = nx_ip_static_route_add(&ip_0, IP_ADDRESS(2, 2, 3, 5), IP_ADDRESS(255, 255, 255, 0), IP_ADDRESS(1, 2, 3, 5)); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function to get the IPv4 packet. */ + ip_1.nx_ipv4_packet_receive = my_packet_process; + + /* Ping an IP address in another network. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_NO_RESPONSE) || (my_packet) || (icmp_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set link status from up to down. */ + status = nx_ip_driver_interface_direct_command(&ip_0, NX_LINK_DISABLE, 0, &return_value); + + /* Check for earlier error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an IP address in another network again. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(2, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the timeout error occurred. */ + if ((status != NX_IP_ADDRESS_ERROR) || (my_packet) || (icmp_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_IPV4_HEADER *ip_header_ptr; +ULONG protocol; + + /* Ignore packet that is not ICMP. */ + if(packet_ptr -> nx_packet_length >= 28) + { + + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + + /* Get IP header. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + protocol = (ip_header_ptr -> nx_ip_header_word_2 >> 16) & 0xFF; + + /* Is ICMP packet? */ + if(protocol == 1) + { + + /* Yes it is. Update the counter. */ + icmp_counter ++; + } + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + } + + /* Call the _nx_ipv4_packet_receive function directly receive this packet. */ + _nx_ipv4_packet_receive(ip_ptr, packet_ptr); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_static_route_find_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Static Route Find Test.................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ip_status_check_test.c b/test/regression/netxduo_test/netx_ip_status_check_test.c new file mode 100644 index 00000000..07ce43fc --- /dev/null +++ b/test/regression/netxduo_test/netx_ip_status_check_test.c @@ -0,0 +1,198 @@ +/* This NetX test concentrates on the raw packet IPv6 send/receive operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#include "nx_tcp.h" +#include "nx_udp.h" + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_status_check_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status != NX_SUCCESS) + error_counter++; + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status != NX_SUCCESS) + error_counter++; + + /* Enable UDP for IP instances. */ + status = nx_udp_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + /* Enable TCP for IP instances. */ + status = nx_tcp_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + /* Enable IGMP for IP instances. */ + status = nx_igmp_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG value; + + + /* Print out test information banner. */ + printf("NetX Test: IP status Check Test......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_INITIALIZE_DONE)) + error_counter++; + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_LINK_ENABLED)) + error_counter++; + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_ARP_ENABLED, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_ARP_ENABLED)) + error_counter++; + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_UDP_ENABLED, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_UDP_ENABLED)) + error_counter++; + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_TCP_ENABLED, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_TCP_ENABLED)) + error_counter++; + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_IGMP_ENABLED, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_IGMP_ENABLED)) + error_counter++; + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_RARP_COMPLETE, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_RARP_COMPLETE)) + error_counter++; + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_INTERFACE_LINK_ENABLED, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_INTERFACE_LINK_ENABLED)) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ip_status_check_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IP status Check Test......................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_ipv4_option_process_test.c b/test/regression/netxduo_test/netx_ipv4_option_process_test.c new file mode 100644 index 00000000..5e1b14f4 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv4_option_process_test.c @@ -0,0 +1,523 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG icmp_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv4_option_process_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: IPv4 Option Process Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + packet_process_callback = my_packet_process; + + /* Test NX_IP_OPTION_NO_OPERATION and NX_IP_OPTION_END option by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Test illegal length of NX_IP_OPTION_INTERNET_TIMESTAMP option by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test two NX_IP_OPTION_INTERNET_TIMESTAMP options by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test illegal offset of NX_IP_OPTION_INTERNET_TIMESTAMP option by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test illegal overflow NX_IP_OPTION_INTERNET_TIMESTAMP option by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test illegal flags of NX_IP_OPTION_INTERNET_TIMESTAMP option by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test illegal option length of Stream Identifier option by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test illegal option length of Stream Identifier option by ping. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_NO_RESPONSE) || (my_packet)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_IPV4_HEADER *ip_header_ptr; +NX_ICMP_HEADER *icmp_header_ptr; +ULONG ip_header_length; +ULONG protocol; +ULONG checksum; +ULONG val; +ULONG offset; +ULONG shift; +ULONG message_word; + + /* Get the IP header pointer. */ + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + + /* Get IP header. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + protocol = (ip_header_ptr -> nx_ip_header_word_2 >> 16) & 0xFF; + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2); + + /* Modify the ICMP packet from ip_0 instance. */ + if((protocol == NX_PROTOCOL_ICMP) && (ip_ptr == &ip_0)) + { + + /* Update the icmp_counter. */ + icmp_counter++; + + /* Get the IP header pointer. */ + ip_header_ptr = (NX_IPV4_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + + /* Calculate the IPv4 option length. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + ip_header_length = ((ip_header_ptr -> nx_ip_header_word_0 & NX_IP_LENGTH_MASK) >> 24) * sizeof(ULONG); + + /* Get ICMP header. */ + icmp_header_ptr = (NX_ICMP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + ip_header_length); + + /* Add the NX_IP_OPTION_NO_OPERATION and NX_IP_OPTION_END option. */ + if (icmp_counter == 1) + { + + /* Move the data to add the option. */ + offset = 4; + shift = packet_ptr -> nx_packet_length - ip_header_length; + memmove(((UCHAR *)(icmp_header_ptr)) + offset, icmp_header_ptr, shift); + + /* Clear memory. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add NX_IP_OPTION_NO_OPERATION and NX_IP_OPTION_END. */ + message_word = (ULONG)((NX_IP_OPTION_NO_OPERATION << 24) | (NX_IP_OPTION_END << 16)); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Copy the option into the buffer. */ + memcpy(icmp_header_ptr, &message_word, sizeof(ULONG)); + } + + /* Add the two NX_IP_OPTION_INTERNET_TIMESTAMP options. */ + else if (icmp_counter == 2) + { + + /* Move the data to add the option. */ + offset = 24; + shift = packet_ptr -> nx_packet_length - ip_header_length; + memmove(((UCHAR *)(icmp_header_ptr)) + offset, icmp_header_ptr, shift); + + /* Add the first option. */ + + /* Clear memory. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add type, length, offset, overflw and flags. */ + message_word = (ULONG)((NX_IP_OPTION_INTERNET_TIMESTAMP << 24) | (12 << 16) | (5 << 8)); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Add type, length, offset, overflw and flags. */ + memcpy(icmp_header_ptr, &message_word, sizeof(ULONG)); + + /* Clear the time stamp value. */ + memset(((UCHAR *)(icmp_header_ptr)) + sizeof(ULONG), 0 , 12 - sizeof(ULONG)); + + /* Add the second option. */ + + /* Clear memory. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add type, length, offset, overflw and flags. */ + message_word = (ULONG)((NX_IP_OPTION_INTERNET_TIMESTAMP << 24) | (12 << 16) | (5 << 8)); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Add type, length, offset, overflw and flags. */ + memcpy(((UCHAR *)icmp_header_ptr) + 12, &message_word, sizeof(ULONG)); + + /* Clear the time stamp value. */ + memset(((UCHAR *)(icmp_header_ptr)) + 12 + sizeof(ULONG), 0 , 12 - sizeof(ULONG)); + } + + /* Add the illegal length 7 for NX_IP_OPTION_INTERNET_TIMESTAMP option. */ + else if (icmp_counter == 3) + { + + /* Move the data to add the option. */ + offset = 12; + shift = packet_ptr -> nx_packet_length - ip_header_length; + memmove(((UCHAR *)(icmp_header_ptr)) + offset, icmp_header_ptr, shift); + + /* Clear memory. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add type, length, offset, overflw and flags. */ + message_word = (ULONG)((NX_IP_OPTION_INTERNET_TIMESTAMP << 24) | (7 << 16) | (5 << 8) ); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Add type, length, offset, overflw and flags. */ + memcpy(icmp_header_ptr, &message_word, sizeof(ULONG)); + + /* Clear the time stamp value. */ + memset(((UCHAR *)(icmp_header_ptr)) + sizeof(ULONG), 0 , offset - sizeof(ULONG)); + } + + /* Add the illegal offset 4 for NX_IP_OPTION_INTERNET_TIMESTAMP option. */ + else if (icmp_counter == 4) + { + + /* Move the data to add the option. */ + offset = 12; + shift = packet_ptr -> nx_packet_length - ip_header_length; + memmove(((UCHAR *)(icmp_header_ptr)) + offset, icmp_header_ptr, shift); + + /* Clear memory. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add type, length, offset, overflw and flags. */ + message_word = (ULONG)((NX_IP_OPTION_INTERNET_TIMESTAMP << 24) | (12 << 16) | (4 << 8) ); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Add type, length, offset, overflw and flags. */ + memcpy(icmp_header_ptr, &message_word, sizeof(ULONG)); + + /* Clear the time stamp value. */ + memset(((UCHAR *)(icmp_header_ptr)) + sizeof(ULONG), 0 , offset - sizeof(ULONG)); + } + + /* Add the illegal overflow 15 for NX_IP_OPTION_INTERNET_TIMESTAMP option. */ + else if (icmp_counter == 5) + { + + /* Move the data to add the option. */ + offset = 12; + shift = packet_ptr -> nx_packet_length - ip_header_length; + memmove(((UCHAR *)(icmp_header_ptr)) + offset, icmp_header_ptr, shift); + + /* Clear memory. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add type, length, offset, overflw and flags. */ + message_word = (ULONG)((NX_IP_OPTION_INTERNET_TIMESTAMP << 24) | (12 << 16) | (5 << 8) | (15 << 4)); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Add type, length, offset, overflw and flags. */ + memcpy(icmp_header_ptr, &message_word, sizeof(ULONG)); + + /* Clear the time stamp value. */ + memset(((UCHAR *)(icmp_header_ptr)) + sizeof(ULONG), 0 , offset - sizeof(ULONG)); + } + + /* Add the illegal flags 5 for NX_IP_OPTION_INTERNET_TIMESTAMP option. */ + else if (icmp_counter == 6) + { + + /* Move the data to add the option. */ + offset = 12; + shift = packet_ptr -> nx_packet_length - ip_header_length; + memmove(((UCHAR *)(icmp_header_ptr)) + offset, icmp_header_ptr, shift); + + /* Clear memory. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add type, length, offset, overflw and flags. */ + message_word = (ULONG)((NX_IP_OPTION_INTERNET_TIMESTAMP << 24) | (12 << 16) | (5 << 8) | (5)); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Add type, length, offset, overflw and flags. */ + memcpy(icmp_header_ptr, &message_word, sizeof(ULONG)); + + /* Clear the time stamp value. */ + memset(((UCHAR *)(icmp_header_ptr)) + sizeof(ULONG), 0 , offset - sizeof(ULONG)); + } + + /* Add the illegal length 0 of Stream Identifier option. */ + else if (icmp_counter == 7) + { + + /* Move the data to add the option. */ + offset = 4; + shift = packet_ptr -> nx_packet_length - ip_header_length; + memmove(((UCHAR *)(icmp_header_ptr)) + offset, icmp_header_ptr, shift); + + /* Clear memory. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add type, length, offset, overflw and flags. */ + message_word = (ULONG)((136 << 24) | (0 << 16)); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Add type, length, offset, overflw and flags. */ + memcpy(icmp_header_ptr, &message_word, sizeof(ULONG)); + } + + /* Add the illegal length 5 of Stream Identifier option. */ + else if (icmp_counter == 8) + { + + /* Move the data to add the option. */ + offset = 4; + shift = packet_ptr -> nx_packet_length - ip_header_length; + memmove(((UCHAR *)(icmp_header_ptr)) + offset, icmp_header_ptr, shift); + + /* Clear memory. */ + memset(&message_word, 0, sizeof(ULONG)); + + /* Add type, length, offset, overflw and flags. */ + message_word = (ULONG)((136 << 24) | (5 << 16)); + + /* Adjust for endianness. */ + NX_CHANGE_ULONG_ENDIAN(message_word); + + /* Add type, length, offset, overflw and flags. */ + memcpy(icmp_header_ptr, &message_word, sizeof(ULONG)); + } + + /* Update the header IP length and total length. */ + ip_header_length += offset; + packet_ptr -> nx_packet_append_ptr += offset; + packet_ptr -> nx_packet_length += offset; + + /* Rebuild the first 32-bit word of the IP header. */ + ip_header_ptr -> nx_ip_header_word_0 = (ULONG)((NX_IP_VERSION_V4 << 28) | + ((ip_header_length/sizeof(ULONG)) << 24) | + NX_IP_NORMAL | + (0xFFFF & packet_ptr -> nx_packet_length)); + + /* Endian swapping logic. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0); + + /* Clear the checksum . */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 & 0x0000FFFF; + + /* Calculate the checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4, + /* Length is the size of IP header, including options */ + (UINT)(ip_header_length), + /* IPv4 header checksum does not use src/dest addresses */ + NULL, NULL); + + val = (ULONG)(~checksum); + val = val & NX_LOWER_16_MASK; + + /* Convert to network byte order. */ + NX_CHANGE_ULONG_ENDIAN(val); + + /* Now store the checksum in the IP header. */ + ip_header_ptr -> nx_ip_header_word_2 = ip_header_ptr -> nx_ip_header_word_2 | val; + } + + return NX_TRUE; +} + +#else + +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv4_option_process_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IPv4 Option Process Test..................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_address_delete_test.c b/test/regression/netxduo_test/netx_ipv6_address_delete_test.c new file mode 100644 index 00000000..f792f6f8 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_address_delete_test.c @@ -0,0 +1,373 @@ +/* This test case validates nxd_ipv6_address_delete. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES > 1) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS if0_lla; +static NXD_ADDRESS if1_lla; +static NXD_ADDRESS if0_ga0; +static NXD_ADDRESS if0_ga1; +static NXD_ADDRESS if0_ga2; +static NXD_ADDRESS if1_ga0; +static NXD_ADDRESS if1_ga1; +static NXD_ADDRESS if1_ga2; +static NXD_ADDRESS if1_ga3; +static NXD_ADDRESS if2_ga0; +static UINT if0_lla_index; +static UINT if0_ga0_index; +static UINT if0_ga1_index; +static UINT if0_ga2_index; +static UINT if1_ga0_index; +static UINT if1_ga1_index; + #ifndef NX_DISABLE_ERROR_CHECKING +static UINT if1_ga3_index; +static UINT if2_ga0_index; +#endif /* NX_DISABLE_ERROR_CHECKING */ + + +#define PRIMARY_INTERFACE 0 +#define SECONDARY_INTERFACE 1 + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); + +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_address_delete_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Set up IF0 LLA. */ + if0_lla.nxd_ip_version = NX_IP_VERSION_V6; + if0_lla.nxd_ip_address.v6[0] = 0xFE800000; + if0_lla.nxd_ip_address.v6[1] = 0x00000000; + if0_lla.nxd_ip_address.v6[2] = 0x00000000; + if0_lla.nxd_ip_address.v6[3] = 0x00000001; + + /* Set up IF1 LLA. */ + if1_lla.nxd_ip_version = NX_IP_VERSION_V6; + if1_lla.nxd_ip_address.v6[0] = 0xFE800000; + if1_lla.nxd_ip_address.v6[1] = 0x00000000; + if1_lla.nxd_ip_address.v6[2] = 0x00000000; + if1_lla.nxd_ip_address.v6[3] = 0x00000002; + + /* Set up IF0 GA0 */ + if0_ga0.nxd_ip_version = NX_IP_VERSION_V6; + if0_ga0.nxd_ip_address.v6[0] = 0x20010000; + if0_ga0.nxd_ip_address.v6[1] = 0x00000000; + if0_ga0.nxd_ip_address.v6[2] = 0x00000000; + if0_ga0.nxd_ip_address.v6[3] = 0x00010001; + + /* Set up IF0 GA1 */ + if0_ga1.nxd_ip_version = NX_IP_VERSION_V6; + if0_ga1.nxd_ip_address.v6[0] = 0x20010000; + if0_ga1.nxd_ip_address.v6[1] = 0x00000000; + if0_ga1.nxd_ip_address.v6[2] = 0x00000000; + if0_ga1.nxd_ip_address.v6[3] = 0x00010002; + + /* Set up IF0 GA2 */ + if0_ga2.nxd_ip_version = NX_IP_VERSION_V6; + if0_ga2.nxd_ip_address.v6[0] = 0x20010000; + if0_ga2.nxd_ip_address.v6[1] = 0x00000000; + if0_ga2.nxd_ip_address.v6[2] = 0x00000000; + if0_ga2.nxd_ip_address.v6[3] = 0x00010003; + + /* Set up IF1 GA0 */ + if1_ga0.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga0.nxd_ip_address.v6[0] = 0x20010000; + if1_ga0.nxd_ip_address.v6[1] = 0x00000000; + if1_ga0.nxd_ip_address.v6[2] = 0x00000000; + if1_ga0.nxd_ip_address.v6[3] = 0x00020001; + + /* Set up IF1 GA1 */ + if1_ga1.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga1.nxd_ip_address.v6[0] = 0x20010000; + if1_ga1.nxd_ip_address.v6[1] = 0x00000000; + if1_ga1.nxd_ip_address.v6[2] = 0x00000000; + if1_ga1.nxd_ip_address.v6[3] = 0x00020002; + + /* Set up IF1 GA2 */ + if1_ga2.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga2.nxd_ip_address.v6[0] = 0x20010000; + if1_ga2.nxd_ip_address.v6[1] = 0x00000000; + if1_ga2.nxd_ip_address.v6[2] = 0x00000000; + if1_ga2.nxd_ip_address.v6[3] = 0x00020003; + + /* Set up IF1 GA3 */ + if1_ga3.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga3.nxd_ip_address.v6[0] = 0x20010000; + if1_ga3.nxd_ip_address.v6[1] = 0x00000000; + if1_ga3.nxd_ip_address.v6[2] = 0x00000000; + if1_ga3.nxd_ip_address.v6[3] = 0x00020004; + + /* Set up IF2 GA0 */ + if2_ga0.nxd_ip_version = NX_IP_VERSION_V6; + if2_ga0.nxd_ip_address.v6[0] = 0x20010000; + if2_ga0.nxd_ip_address.v6[1] = 0x00000000; + if2_ga0.nxd_ip_address.v6[2] = 0x00000000; + if2_ga0.nxd_ip_address.v6[3] = 0x00030001; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + UINT i; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Address Delete Test ................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach two more interface. */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", 0x02010101, 0xFFFFFF00, _nx_ram_network_driver_1500); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address0 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_lla, 64, &if0_lla_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address0 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_ga0, 64, &if0_ga0_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address1 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_ga1, 64, &if0_ga1_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address2 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_ga2, 64, &if0_ga2_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address0 on the 2nd interface. */ + status = nxd_ipv6_address_set(&ip_0, SECONDARY_INTERFACE, &if1_ga0, 64, &if1_ga0_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address1 on the 2nd interface. */ + status = nxd_ipv6_address_set(&ip_0, SECONDARY_INTERFACE, &if1_ga1, 64, &if1_ga1_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + #ifndef NX_DISABLE_ERROR_CHECKING + /* This assumes the max entry of IPv6 address is 6. */ + if(NX_MAX_IPV6_ADDRESSES == 6) + { + + /* Set Global address3 on the 2nd interface. This one should fail.*/ + status = nxd_ipv6_address_set(&ip_0, SECONDARY_INTERFACE, &if1_ga3, 64, &if1_ga3_index); + if(status != NX_NO_MORE_ENTRIES) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* This assumes the max physical interface is 2. */ + if(NX_MAX_PHYSICAL_INTERFACES == 2) + { + + /* Set global address0 on the 3rd interface. This one should fail. */ + status = nxd_ipv6_address_set(&ip_0, 2, &if2_ga0, 64, &if2_ga0_index); + if(status != NX_INVALID_INTERFACE) + { + test_control_return(1); + } + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + + /* Verify the IP addresses just set. */ + if((!CHECK_IPV6_ADDRESSES_SAME(ip_0.nx_ipv6_address[if0_lla_index].nxd_ipv6_address, if0_lla.nxd_ip_address.v6)) || + (!CHECK_IPV6_ADDRESSES_SAME(ip_0.nx_ipv6_address[if0_ga0_index].nxd_ipv6_address, if0_ga0.nxd_ip_address.v6)) || + (!CHECK_IPV6_ADDRESSES_SAME(ip_0.nx_ipv6_address[if0_ga1_index].nxd_ipv6_address, if0_ga1.nxd_ip_address.v6)) || + (!CHECK_IPV6_ADDRESSES_SAME(ip_0.nx_ipv6_address[if0_ga2_index].nxd_ipv6_address, if0_ga2.nxd_ip_address.v6)) || + (!CHECK_IPV6_ADDRESSES_SAME(ip_0.nx_ipv6_address[if1_ga0_index].nxd_ipv6_address, if1_ga0.nxd_ip_address.v6)) || + (!CHECK_IPV6_ADDRESSES_SAME(ip_0.nx_ipv6_address[if1_ga1_index].nxd_ipv6_address, if1_ga1.nxd_ip_address.v6))) + + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete all IPv6 addresses on IF0 */ + status = nxd_ipv6_address_delete(&ip_0, if0_lla_index); + status += nxd_ipv6_address_delete(&ip_0, if0_ga0_index); + status += nxd_ipv6_address_delete(&ip_0, if0_ga1_index); + status += nxd_ipv6_address_delete(&ip_0, if0_ga2_index); + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Make sure there are no IPv6 addresses on IF0 */ + if(ip_0.nx_ip_interface[PRIMARY_INTERFACE].nxd_interface_ipv6_address_list_head) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete all IPv6 address on IF1 */ + status = nxd_ipv6_address_delete(&ip_0, if1_ga0_index); + status += nxd_ipv6_address_delete(&ip_0, if1_ga1_index); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Make sure there are no IPv6 addresses on IF0 */ + if(ip_0.nx_ip_interface[SECONDARY_INTERFACE].nxd_interface_ipv6_address_list_head) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + if(ip_0.nx_ipv6_address[0].nxd_ipv6_address_valid || ip_0.nx_ipv6_address[1].nxd_ipv6_address_valid || ip_0.nx_ipv6_address[2].nxd_ipv6_address_valid || + ip_0.nx_ipv6_address[3].nxd_ipv6_address_valid || ip_0.nx_ipv6_address[4].nxd_ipv6_address_valid || ip_0.nx_ipv6_address[5].nxd_ipv6_address_valid || + (ip_0.nx_ip_interface[PRIMARY_INTERFACE].nxd_interface_ipv6_address_list_head != NX_NULL)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the 1nd address on the 2nd interface */ + for(i = 0; i < NX_MAX_IPV6_ADDRESSES; i++) + { + status = nxd_ipv6_address_delete(&ip_0, i); + + if(status != NX_NO_INTERFACE_ADDRESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nxd_ipv6_address_delete(&ip_0, NX_MAX_IPV6_ADDRESSES); + if(status != NX_NO_INTERFACE_ADDRESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + + + printf("SUCCESS!\n"); + test_control_return(0); + +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_address_delete_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Address Delete Test .................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_address_get_test.c b/test/regression/netxduo_test/netx_ipv6_address_get_test.c new file mode 100644 index 00000000..1c05cba5 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_address_get_test.c @@ -0,0 +1,237 @@ +/* This test case validates nxd_ipv6_address_set. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG notify_counter; + +static NXD_ADDRESS if0_ga0; +static NXD_ADDRESS if0_ga1; + +#define PRIMARY_INTERFACE 0 + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +static void my_ipv6_addrress_change_notify(NX_IP *ip_tr, UINT type, UINT interface_index, UINT addr_index, ULONG *addr_ptr); +#endif + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_address_get_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + notify_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set up IF0 GA0 */ + if0_ga0.nxd_ip_version = NX_IP_VERSION_V6; + if0_ga0.nxd_ip_address.v6[0] = 0x20010000; + if0_ga0.nxd_ip_address.v6[1] = 0x00000000; + if0_ga0.nxd_ip_address.v6[2] = 0x00000000; + if0_ga0.nxd_ip_address.v6[3] = 0x00010001; + + /* Set up IF0 GA1 */ + if0_ga1.nxd_ip_version = NX_IP_VERSION_V6; + if0_ga1.nxd_ip_address.v6[0] = 0x20010000; + if0_ga1.nxd_ip_address.v6[1] = 0x00000000; + if0_ga1.nxd_ip_address.v6[2] = 0x00000000; + if0_ga1.nxd_ip_address.v6[3] = 0x00010002; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status != NX_SUCCESS) + error_counter++; + + status = nxd_icmp_enable(&ip_0); + if(status != NX_SUCCESS) + error_counter++; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; + +ULONG prefix_length; +UINT interface_index; +NXD_ADDRESS ipv6_addr; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Address Get Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + status = nxd_ipv6_address_change_notify(&ip_0, my_ipv6_addrress_change_notify); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Set Global address0 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_ga0, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address1 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_ga1, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* DAD */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + status = nxd_ipv6_address_get(&ip_0, 0, &ipv6_addr, &prefix_length, &interface_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if((ipv6_addr.nxd_ip_version != NX_IP_VERSION_V6) || + (ipv6_addr.nxd_ip_address.v6[0] != 0x20010000) || + (ipv6_addr.nxd_ip_address.v6[1] != 0x0) || + (ipv6_addr.nxd_ip_address.v6[2] != 0x0) || + (ipv6_addr.nxd_ip_address.v6[3] != 0x00010001)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_ipv6_address_get(&ip_0, 1, &ipv6_addr, &prefix_length, &interface_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if((ipv6_addr.nxd_ip_version != NX_IP_VERSION_V6) || + (ipv6_addr.nxd_ip_address.v6[0] != 0x20010000) || + (ipv6_addr.nxd_ip_address.v6[1] != 0x0) || + (ipv6_addr.nxd_ip_address.v6[2] != 0x0) || + (ipv6_addr.nxd_ip_address.v6[3] != 0x00010002)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_ipv6_address_get(&ip_0, 2, &ipv6_addr, &prefix_length, &interface_index); + if(status != NX_NO_INTERFACE_ADDRESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable IPv6 */ + status = nxd_ipv6_disable(&ip_0); + + /* notify counter should be 4, ipv6_address_set (ip_0, ip_1), DAD (ip_0, ip_1) calls. */ + if((status != NX_SUCCESS) +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + || (notify_counter != 4) +#endif + ) + { + printf("ERROR!\n"); + test_control_return(1); + + } + + printf("SUCCESS!\n"); + test_control_return(0); + +} + +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +static void my_ipv6_addrress_change_notify(NX_IP *ip_tr, UINT type, UINT interface_index, UINT addr_index, ULONG *addr_ptr) +{ + notify_counter++; +} +#endif + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_address_get_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Address Get Test.....................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_address_set_test.c b/test/regression/netxduo_test/netx_ipv6_address_set_test.c new file mode 100644 index 00000000..b0990346 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_address_set_test.c @@ -0,0 +1,693 @@ +/* This test case validates nxd_ipv6_address_set. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES > 1) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +#ifndef NX_DISABLE_ERROR_CHECKING +static NXD_ADDRESS multicast_addr; +#endif /* NX_DISABLE_ERROR_CHECKING */ +static NXD_ADDRESS if0_lla; +static NXD_ADDRESS if1_lla; +static NXD_ADDRESS if0_ga0; +static NXD_ADDRESS if0_ga1; +static NXD_ADDRESS if0_ga2; +static NXD_ADDRESS if0_gax; +static NXD_ADDRESS if1_ga0; +static NXD_ADDRESS if1_ga1; +static NXD_ADDRESS if1_ga2; +static NXD_ADDRESS if1_ga3; +static NXD_ADDRESS if2_ga0; + +static int if0_lla_check; +static int if0_ga1_check; +static int if0_ga2_check; +static int if1_ga0_check; +static int if1_ga1_check; +static int if1_ga2_check; + +static NXD_ADDRESS if_addr; + +#define PRIMARY_INTERFACE 0 +#define SECONDARY_INTERFACE 1 + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_address_set_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set up IF0 LLA. */ + if0_lla.nxd_ip_version = NX_IP_VERSION_V6; + if0_lla.nxd_ip_address.v6[0] = 0xFE800000; + if0_lla.nxd_ip_address.v6[1] = 0x00000000; + if0_lla.nxd_ip_address.v6[2] = 0x00000000; + if0_lla.nxd_ip_address.v6[3] = 0x00000001; + + /* Set up IF1 LLA. */ + if1_lla.nxd_ip_version = NX_IP_VERSION_V6; + if1_lla.nxd_ip_address.v6[0] = 0xFE800000; + if1_lla.nxd_ip_address.v6[1] = 0x00000000; + if1_lla.nxd_ip_address.v6[2] = 0x00000000; + if1_lla.nxd_ip_address.v6[3] = 0x00000002; + + /* Set up IF0 GA0 */ + if0_ga0.nxd_ip_version = NX_IP_VERSION_V6; + if0_ga0.nxd_ip_address.v6[0] = 0x20010000; + if0_ga0.nxd_ip_address.v6[1] = 0x00000000; + if0_ga0.nxd_ip_address.v6[2] = 0x00000000; + if0_ga0.nxd_ip_address.v6[3] = 0x00010001; + + /* Set up IF0 GA1 */ + if0_ga1.nxd_ip_version = NX_IP_VERSION_V6; + if0_ga1.nxd_ip_address.v6[0] = 0x20010000; + if0_ga1.nxd_ip_address.v6[1] = 0x00000000; + if0_ga1.nxd_ip_address.v6[2] = 0x00000000; + if0_ga1.nxd_ip_address.v6[3] = 0x00010002; + + /* Set up IF0 GA2 */ + if0_ga2.nxd_ip_version = NX_IP_VERSION_V6; + if0_ga2.nxd_ip_address.v6[0] = 0x20010000; + if0_ga2.nxd_ip_address.v6[1] = 0x00000000; + if0_ga2.nxd_ip_address.v6[2] = 0x00000000; + if0_ga2.nxd_ip_address.v6[3] = 0x00010003; + + /* Set up IF1 GA0 */ + if1_ga0.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga0.nxd_ip_address.v6[0] = 0x20010000; + if1_ga0.nxd_ip_address.v6[1] = 0x00000000; + if1_ga0.nxd_ip_address.v6[2] = 0x00000000; + if1_ga0.nxd_ip_address.v6[3] = 0x00020001; + + /* Set up IF1 GA1 */ + if1_ga1.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga1.nxd_ip_address.v6[0] = 0x20010000; + if1_ga1.nxd_ip_address.v6[1] = 0x00000000; + if1_ga1.nxd_ip_address.v6[2] = 0x00000000; + if1_ga1.nxd_ip_address.v6[3] = 0x00020002; + + /* Set up IF1 GA2 */ + if1_ga2.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga2.nxd_ip_address.v6[0] = 0x20010000; + if1_ga2.nxd_ip_address.v6[1] = 0x00000000; + if1_ga2.nxd_ip_address.v6[2] = 0x00000000; + if1_ga2.nxd_ip_address.v6[3] = 0x00020003; + + /* Set up IF1 GA3 */ + if1_ga3.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga3.nxd_ip_address.v6[0] = 0x20010000; + if1_ga3.nxd_ip_address.v6[1] = 0x00000000; + if1_ga3.nxd_ip_address.v6[2] = 0x00000000; + if1_ga3.nxd_ip_address.v6[3] = 0x00020004; + + /* Set up IF2 GA0 */ + if2_ga0.nxd_ip_version = NX_IP_VERSION_V6; + if2_ga0.nxd_ip_address.v6[0] = 0x20010000; + if2_ga0.nxd_ip_address.v6[1] = 0x00000000; + if2_ga0.nxd_ip_address.v6[2] = 0x00000000; + if2_ga0.nxd_ip_address.v6[3] = 0x00030001; + +#ifndef NX_DISABLE_ERROR_CHECKING + /* Set up multicast address. */ + multicast_addr.nxd_ip_version = NX_IP_VERSION_V6; + multicast_addr.nxd_ip_address.v6[0] = 0xFF050000; + multicast_addr.nxd_ip_address.v6[1] = 0x00000000; + multicast_addr.nxd_ip_address.v6[2] = 0x00000000; + multicast_addr.nxd_ip_address.v6[3] = 0x00010003; +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +ULONG prefix_length; +UINT interface_index; +NXD_IPV6_ADDRESS *ipv6_addr_ptr; +UINT address_count; +UINT i; +UINT link_local_address_index; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Address Set Test....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attach two more interface. */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", 0x02010101, 0xFFFFFF00, _nx_ram_network_driver_1500); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + /* Set multicast address on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &multicast_addr, 64, NX_NULL); + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Set Global address0 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_lla, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address1 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_ga1, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address2 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_ga2, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set link local address on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, NX_NULL, 10, &link_local_address_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set link local address on the 1st interface again. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, NX_NULL, 10, NX_NULL); + if(status != NX_DUPLICATED_ENTRY) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the link local address. */ + status = nxd_ipv6_address_delete(&ip_0, link_local_address_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address0 on the 2nd interface. */ + status = nxd_ipv6_address_set(&ip_0, SECONDARY_INTERFACE, &if1_ga0, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address1 on the 2nd interface. */ + status = nxd_ipv6_address_set(&ip_0, SECONDARY_INTERFACE, &if1_ga1, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address2 on the 2nd interface. */ + status = nxd_ipv6_address_set(&ip_0, SECONDARY_INTERFACE, &if1_ga2, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + /* Set global address0 on the 3rd interface. This one should fail. */ + status = nxd_ipv6_address_set(&ip_0, 2, &if2_ga0, 64, NX_NULL); + if(status != NX_INVALID_INTERFACE) + { + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Now go through all the IPv6 addresses and make sure the values are programmed correctly. */ + if((ip_0.nx_ipv6_address[0].nxd_ipv6_address_valid != 1) || + (ip_0.nx_ipv6_address[0].nxd_ipv6_address_type != NX_IP_VERSION_V6) || + (memcmp(ip_0.nx_ipv6_address[0].nxd_ipv6_address, &if0_lla.nxd_ip_address.v6[0], 16)) || + (ip_0.nx_ipv6_address[0].nxd_ipv6_address_prefix_length != 64) || + (ip_0.nx_ipv6_address[0].nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_VALID) || + (ip_0.nx_ipv6_address[0].nxd_ipv6_address_attached != &ip_0.nx_ip_interface[0])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + if((ip_0.nx_ipv6_address[1].nxd_ipv6_address_valid != 1) || + (ip_0.nx_ipv6_address[1].nxd_ipv6_address_type != NX_IP_VERSION_V6) || + (memcmp(ip_0.nx_ipv6_address[1].nxd_ipv6_address, &if0_ga1.nxd_ip_address.v6[0], 16)) || + (ip_0.nx_ipv6_address[1].nxd_ipv6_address_prefix_length != 64) || + (ip_0.nx_ipv6_address[1].nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_VALID) || + (ip_0.nx_ipv6_address[1].nxd_ipv6_address_attached != &ip_0.nx_ip_interface[0])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if((ip_0.nx_ipv6_address[2].nxd_ipv6_address_valid != 1) || + (ip_0.nx_ipv6_address[2].nxd_ipv6_address_type != NX_IP_VERSION_V6) || + (memcmp(ip_0.nx_ipv6_address[2].nxd_ipv6_address, &if0_ga2.nxd_ip_address.v6[0], 16)) || + (ip_0.nx_ipv6_address[2].nxd_ipv6_address_prefix_length != 64) || + (ip_0.nx_ipv6_address[2].nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_VALID) || + (ip_0.nx_ipv6_address[2].nxd_ipv6_address_attached != &ip_0.nx_ip_interface[0])) + { + printf("ERROR!\n"); + test_control_return(1); + } + if((ip_0.nx_ipv6_address[3].nxd_ipv6_address_valid != 1) || + (ip_0.nx_ipv6_address[3].nxd_ipv6_address_type != NX_IP_VERSION_V6) || + (memcmp(ip_0.nx_ipv6_address[3].nxd_ipv6_address, &if1_ga0.nxd_ip_address.v6[0], 16)) || + (ip_0.nx_ipv6_address[3].nxd_ipv6_address_prefix_length != 64) || + (ip_0.nx_ipv6_address[3].nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_VALID) || + (ip_0.nx_ipv6_address[3].nxd_ipv6_address_attached != &ip_0.nx_ip_interface[1])) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check each interface, making sure they have the proper IPv6 addresses configured. */ + if0_lla_check = if0_ga1_check = if0_ga2_check = if1_ga0_check = 0; + ipv6_addr_ptr = ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head; + address_count = 0; + while(ipv6_addr_ptr) + { + if(memcmp(ipv6_addr_ptr -> nxd_ipv6_address, &if0_lla.nxd_ip_address.v6[0], 16) == 0) + if0_lla_check++; + if(memcmp(ipv6_addr_ptr -> nxd_ipv6_address, &if0_ga1.nxd_ip_address.v6[0], 16) == 0) + if0_ga1_check++; + if(memcmp(ipv6_addr_ptr -> nxd_ipv6_address, &if0_ga2.nxd_ip_address.v6[0], 16) == 0) + if0_ga2_check++; + + address_count++; + ipv6_addr_ptr = ipv6_addr_ptr -> nxd_ipv6_address_next; + } + if((address_count != 3) || (if0_lla_check != 1) || (if0_ga1_check != 1) || (if0_ga2_check != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + ipv6_addr_ptr = ip_0.nx_ip_interface[1].nxd_interface_ipv6_address_list_head; + address_count = 0; + while(ipv6_addr_ptr) + { + if(memcmp(ipv6_addr_ptr -> nxd_ipv6_address, &if1_ga0.nxd_ip_address.v6[0], 16) == 0) + if1_ga0_check++; + if(memcmp(ipv6_addr_ptr -> nxd_ipv6_address, &if1_ga1.nxd_ip_address.v6[0], 16) == 0) + if1_ga1_check++; + if(memcmp(ipv6_addr_ptr -> nxd_ipv6_address, &if1_ga2.nxd_ip_address.v6[0], 16) == 0) + if1_ga2_check++; + + address_count++; + ipv6_addr_ptr = ipv6_addr_ptr -> nxd_ipv6_address_next; + } + + if((address_count != 3) || (if1_ga0_check != 1) || (if1_ga1_check != 1) || (if1_ga2_check != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reprogram all the interface IPv6 addresses. */ + + /* Now delete all the IPv6 addresses. */ + for(i = 0; i < 6; i++) + { + status = nxd_ipv6_address_delete(&ip_0, i); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + } + + status = nxd_ipv6_address_delete(&ip_0, 6); + if(status != NX_NO_INTERFACE_ADDRESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Set up IF0 LLA. */ + if0_lla.nxd_ip_version = NX_IP_VERSION_V6; + if0_lla.nxd_ip_address.v6[0] = 0xFE800000; + if0_lla.nxd_ip_address.v6[1] = 0x00000000; + if0_lla.nxd_ip_address.v6[2] = 0x00010000; + if0_lla.nxd_ip_address.v6[3] = 0x00000001; + + /* Set up IF1 LLA. */ + if1_lla.nxd_ip_version = NX_IP_VERSION_V6; + if1_lla.nxd_ip_address.v6[0] = 0xFE800000; + if1_lla.nxd_ip_address.v6[1] = 0x00000000; + if1_lla.nxd_ip_address.v6[2] = 0x00010000; + if1_lla.nxd_ip_address.v6[3] = 0x00000002; + + /* Set up IF0 GA0 */ + if0_ga0.nxd_ip_version = NX_IP_VERSION_V6; + if0_ga0.nxd_ip_address.v6[0] = 0x20010000; + if0_ga0.nxd_ip_address.v6[1] = 0x00000000; + if0_ga0.nxd_ip_address.v6[2] = 0x00010000; + if0_ga0.nxd_ip_address.v6[3] = 0x00010001; + + /* Set up IF0 GA1 */ + if0_ga1.nxd_ip_version = NX_IP_VERSION_V6; + if0_ga1.nxd_ip_address.v6[0] = 0x20010000; + if0_ga1.nxd_ip_address.v6[1] = 0x00000000; + if0_ga1.nxd_ip_address.v6[2] = 0x00010000; + if0_ga1.nxd_ip_address.v6[3] = 0x00010002; + + /* Set up IF0 GA2 */ + if0_ga2.nxd_ip_version = NX_IP_VERSION_V6; + if0_ga2.nxd_ip_address.v6[0] = 0x20010000; + if0_ga2.nxd_ip_address.v6[1] = 0x00000000; + if0_ga2.nxd_ip_address.v6[2] = 0x00010000; + if0_ga2.nxd_ip_address.v6[3] = 0x00010003; + + /* Set up IF1 GA0 */ + if1_ga0.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga0.nxd_ip_address.v6[0] = 0x20010000; + if1_ga0.nxd_ip_address.v6[1] = 0x00000000; + if1_ga0.nxd_ip_address.v6[2] = 0x00010000; + if1_ga0.nxd_ip_address.v6[3] = 0x00020001; + + /* Set up IF1 GA1 */ + if1_ga1.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga1.nxd_ip_address.v6[0] = 0x20010000; + if1_ga1.nxd_ip_address.v6[1] = 0x00000000; + if1_ga1.nxd_ip_address.v6[2] = 0x00010000; + if1_ga1.nxd_ip_address.v6[3] = 0x00020002; + + /* Set up IF1 GA2 */ + if1_ga2.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga2.nxd_ip_address.v6[0] = 0x20010000; + if1_ga2.nxd_ip_address.v6[1] = 0x00000000; + if1_ga2.nxd_ip_address.v6[2] = 0x00010000; + if1_ga2.nxd_ip_address.v6[3] = 0x00020003; + + /* Set up IF1 GA3 */ + if1_ga3.nxd_ip_version = NX_IP_VERSION_V6; + if1_ga3.nxd_ip_address.v6[0] = 0x20010000; + if1_ga3.nxd_ip_address.v6[1] = 0x00000000; + if1_ga3.nxd_ip_address.v6[2] = 0x00000000; + if1_ga3.nxd_ip_address.v6[3] = 0x00020004; + + /* Set up IF2 GA0 */ + if2_ga0.nxd_ip_version = NX_IP_VERSION_V6; + if2_ga0.nxd_ip_address.v6[0] = 0x20010000; + if2_ga0.nxd_ip_address.v6[1] = 0x00000000; + if2_ga0.nxd_ip_address.v6[2] = 0x00010000; + if2_ga0.nxd_ip_address.v6[3] = 0x00030001; + + /* Set Global address0 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_ga0, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address1 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_ga1, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address2 on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_ga2, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set duplicated Global address2 on the 1st interface again. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_ga2, 64, NX_NULL); + if(status != NX_DUPLICATED_ENTRY) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set invalid addrss on the 1st interface. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, NX_NULL, 64, NX_NULL); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address0 on the 2nd interface. */ + status = nxd_ipv6_address_set(&ip_0, SECONDARY_INTERFACE, &if1_ga0, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address1 on the 2nd interface. */ + status = nxd_ipv6_address_set(&ip_0, SECONDARY_INTERFACE, &if1_ga1, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set Global address2 on the 2nd interface. */ + status = nxd_ipv6_address_set(&ip_0, SECONDARY_INTERFACE, &if1_ga2, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + + /* Set global address0 on the 3rd interface. This one should fail. */ + status = nxd_ipv6_address_set(&ip_0, 2, &if2_ga0, 64, NX_NULL); + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Now read back the IP addresses and make sure they match. */ + status = nxd_ipv6_address_get(&ip_0, 0, &if_addr, &prefix_length, &interface_index); + if(status != NX_SUCCESS || (memcmp(&if_addr, &if0_ga0, sizeof(NXD_ADDRESS))) || (prefix_length != 64) || (interface_index != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_ipv6_address_get(&ip_0, 1, &if_addr, &prefix_length, &interface_index); + if((status != NX_SUCCESS || (memcmp(&if_addr, &if0_ga1, sizeof(NXD_ADDRESS)))) || (prefix_length != 64) || (interface_index != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_ipv6_address_get(&ip_0, 2, &if_addr, &prefix_length, &interface_index); + if((status != NX_SUCCESS || (memcmp(&if_addr, &if0_ga2, sizeof(NXD_ADDRESS))) || (prefix_length != 64)) || (interface_index != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_ipv6_address_get(&ip_0, 3, &if_addr, &prefix_length, &interface_index); + if((status != NX_SUCCESS) || (memcmp(&if_addr, &if1_ga0, sizeof(NXD_ADDRESS))) || (prefix_length != 64) || (interface_index != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_ipv6_address_get(&ip_0, 4, &if_addr, &prefix_length, &interface_index); + if((status != NX_SUCCESS) || (memcmp(&if_addr, &if1_ga1, sizeof(NXD_ADDRESS))) || (prefix_length != 64) || (interface_index != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_ipv6_address_get(&ip_0, 5, &if_addr, &prefix_length, &interface_index); + if((status != NX_SUCCESS) || (memcmp(&if_addr, &if1_ga2, sizeof(NXD_ADDRESS))) || (prefix_length != 64) || (interface_index != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set up IF0 GAX */ + if0_gax.nxd_ip_version = NX_IP_VERSION_V6; + if0_gax.nxd_ip_address.v6[0] = 0x20010000; + if0_gax.nxd_ip_address.v6[1] = 0x00000009; + if0_gax.nxd_ip_address.v6[2] = 0x00000000; + if0_gax.nxd_ip_address.v6[3] = 0x00010003; + + /* Loop to add the IPv6 addresses. */ + for(i = 6; i < NX_MAX_IPV6_ADDRESSES; i++) + { + + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_gax, 64, NX_NULL); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Update the IP address IF0 GAX */ + if0_gax.nxd_ip_version = NX_IP_VERSION_V6; + if0_gax.nxd_ip_address.v6[1] += 1; + } + + /* Add the IPv6 address that exceed the max IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_gax, 64, NX_NULL); + if(status != NX_NO_MORE_ENTRIES) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the address on the 1 interface */ + for(i = 0; i < NX_MAX_IPV6_ADDRESSES; i++) + { + status = nxd_ipv6_address_delete(&ip_0, i); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Set up IF0 GAX */ + if0_gax.nxd_ip_version = NX_IP_VERSION_V6; + if0_gax.nxd_ip_address.v6[0] = 0x20010000; + if0_gax.nxd_ip_address.v6[1] = 0x00000009; + if0_gax.nxd_ip_address.v6[2] = 0x00000000; + if0_gax.nxd_ip_address.v6[3] = 0x00010003; + + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_gax, 64, NX_NULL); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set up the address only v6[2] different with the address above. */ + if0_gax.nxd_ip_version = NX_IP_VERSION_V6; + if0_gax.nxd_ip_address.v6[0] = 0x20010000; + if0_gax.nxd_ip_address.v6[1] = 0x00000009; + if0_gax.nxd_ip_address.v6[2] = 0x00000002; + if0_gax.nxd_ip_address.v6[3] = 0x00010003; + + status = nxd_ipv6_address_set(&ip_0, PRIMARY_INTERFACE, &if0_gax, 64, NX_NULL); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_address_set_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Address Set Test.....................................N/A\n"); + test_control_return(3); + +} + +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_branch_test.c b/test/regression/netxduo_test/netx_ipv6_branch_test.c new file mode 100644 index 00000000..f1dd93b4 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_branch_test.c @@ -0,0 +1,871 @@ +/* This NetX test concentrates on the code coverage for IPv6 functions, + * nx_tcp_connect_cleanup.c + * nx_tcp_disconnect_cleanup.c + * nx_udp_bind_cleanup.c */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#ifdef FEATURE_NX_IPV6 + +#include "tx_thread.h" +#include "nx_icmp.h" +#include "nx_ip.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +#ifndef NX_DISABLE_ASSERT +static TX_THREAD thread_for_assert; +static UINT assert_count = 0; +#endif +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static CHAR *pointer; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifndef NX_DISABLE_ASSERT +static void thread_for_assert_entry(ULONG thread_input); +#endif + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_branch_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, + _nx_ram_network_driver_256); + + if (status) + error_counter++; +#endif /* (NX_MAX_PHYSICAL_INTERFACES > 1) */ + + /* Enable ICMP processing for IP instance. */ + status = nxd_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Enable IPv6 processing for IP instance. */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet[2]; +NXD_ADDRESS ipv6_address; +ULONG prefix_address[4]; +ULONG address_1[4]; +ULONG address_2[4]; +ULONG router_address; +void *nd_cache_entry; +ND_CACHE_ENTRY + cache_entry; +NXD_IPV6_ADDRESS + *nxd_ipv6_address; +#ifndef NX_DISABLE_FRAGMENTATION +NX_IP_DRIVER + driver_request; +#endif +UINT address_index; + + + /* Print out some test information banners. */ + printf("NetX Test: IPv6 Branch Test.........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + +#ifndef NX_DISABLE_FRAGMENTATION + /* Hit condition of while (bytes_remaining > 0) and if ((source_pkt == NX_NULL) || (dest_pkt == NX_NULL)) in _nx_ipv6_packet_copy(). */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + nx_packet_allocate(&pool_0, &my_packet[1], 0, NX_NO_WAIT); + _nx_ipv6_packet_copy(my_packet[0], my_packet[1], 0); + my_packet[0] -> nx_packet_last = my_packet[1]; + _nx_ipv6_packet_copy(my_packet[0], my_packet[1], 100); + my_packet[0] -> nx_packet_last = NX_NULL; + my_packet[1] -> nx_packet_last = my_packet[0]; + _nx_ipv6_packet_copy(my_packet[0], my_packet[1], 100); + my_packet[0] -> nx_packet_last = NX_NULL; + my_packet[1] -> nx_packet_last = NX_NULL; + nx_packet_release(my_packet[0]); + nx_packet_release(my_packet[1]); +#endif + + + + /* Hit false condition of CHECK_IPV6_ADDRESSES_SAME(prefix, current -> nx_ipv6_prefix_entry_network_address) in _nx_ipv6_prefix_list_delete . */ + prefix_address[0] = 0x20010001; + prefix_address[1] = 0x00000002; + prefix_address[2] = 0x00000003; + prefix_address[3] = 0x00000004; + _nx_ipv6_prefix_list_add_entry(&ip_0, prefix_address, 64, 100); + _nx_ipv6_prefix_list_delete(&ip_0, prefix_address, 48); + prefix_address[3] = 0x00000005; + _nx_ipv6_prefix_list_delete(&ip_0, prefix_address, 64); + prefix_address[3] = 0x00000004; + _nx_ipv6_prefix_list_delete(&ip_0, prefix_address, 64); + + + /* Hit false condition of if (interface_ipv6_address -> nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_UNKNOWN) in _nx_ipv6_prefix_list_delete_entry . */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0x20010001; + ipv6_address.nxd_ip_address.v6[1] = 0x00000002; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x00000004; + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 64, NX_NULL); + ip_0.nx_ipv6_address[0].nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_UNKNOWN; + _nx_ipv6_prefix_list_delete_entry(&ip_0, ip_0.nx_ipv6_prefix_list_ptr); + nxd_ipv6_address_delete(&ip_0, 0); + + + + /* Hit condition of for (i = 0; i < 4; i++) in _nxd_ipv6_find_max_prefix_length . */ + address_1[0] = 0x20010001; + address_1[1] = 0x00000002; + address_1[2] = 0x00000003; + address_1[3] = 0x00000004; + + address_2[0] = 0x20010001; + address_2[1] = 0x00000002; + address_2[2] = 0x00000003; + address_2[3] = 0x00000004; + _nxd_ipv6_find_max_prefix_length(address_1, address_2, 128); + +#ifndef NX_DISABLE_ASSERT + /* Test _nx_ip_header_add(). */ + /* Hit NX_ASSERT(packet_ptr -> nx_packet_prepend_ptr >= packet_ptr -> nx_packet_data_start); */ + + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + + /* Test _nxd_ipv6_destination_table_find_next_hop */ + /* Hit NX_ASSERT(next_hop != NX_NULL); */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + + /* Test _nxd_ipv6_router_lookup */ + /* Hit NX_ASSERT(routers_checked != NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE); */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + + /* Test _nxd_ipv6_router_lookup */ + /* Hit NX_ASSERT(nd_cache_entry != NX_NULL) */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + + /* Test _nxd_ipv6_interface_find */ + /* Hit NX_ASSERT(ipv6_addr != NX_NULL); */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + + /* Test _nxd_ipv6_interface_find */ + /* Hit NX_ASSERT((*ipv6_addr) -> nxd_ipv6_address_valid); */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + + /* Test _nxd_ipv6_interface_find */ + /* Hit NX_ASSERT((*ipv6_addr) -> nxd_ipv6_address_valid); */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + /* Test _nxd_ipv6_interface_find */ + /* Hit NX_ASSERT((*ipv6_addr) -> nxd_ipv6_address_valid); */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + /* Test _nx_ipv6_header_add */ + /* Hit NX_ASSERT(packet_ptr -> nx_packet_prepend_ptr >= packet_ptr -> nx_packet_data_start); */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + /* Test _nx_ipv6_packet_send */ + /* Hit NX_ASSERT(if_ptr -> nx_interface_link_driver_entry != NX_NULL); */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + ip_0.nx_ip_interface[0].nx_interface_link_driver_entry = _nx_ram_network_driver_256; + + /* Test _nx_ipv6_packet_send */ + /* Hit NX_ASSERT(if_ptr != NX_NULL); */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); + + /* Test _nx_ipv6_packet_send */ + /* Hit NX_ASSERT(NDCacheEntry -> nx_nd_cache_nd_status != ND_CACHE_STATE_INVALID); */ + /* Create the main thread. */ + tx_thread_create(&thread_for_assert, "Assert Test thread", thread_for_assert_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert); + tx_thread_delete(&thread_for_assert); +#else + + /* Set up the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[3] = 0x4; + ipv6_address.nxd_ip_address.v6[2] = 0x0; + ipv6_address.nxd_ip_address.v6[1] = 0x0; + ipv6_address.nxd_ip_address.v6[0] = 0xfe800000; + + /* Add a router. */ + _nxd_ipv6_default_router_add(&ip_0, &ipv6_address, 1000, 0); + +#endif /* NX_DISABLE_ASSERT */ + + /* Hit false condition of for (i = 0; table_size && (i < NX_IPV6_DESTINATION_TABLE_SIZE); i++). */ + ip_0.nx_ipv6_destination_table_size = NX_IPV6_DESTINATION_TABLE_SIZE + 1; + _nxd_ipv6_destination_table_find_next_hop(&ip_0, address_1, address_2); + ip_0.nx_ipv6_destination_table_size = 0; + + /* Cover the branches for NDCacheEntry -> nx_nd_cache_nd_status. */ + cache_entry.nx_nd_cache_nd_status = ND_CACHE_STATE_INVALID; + ip_0.nx_ipv6_default_router_table[0].nx_ipv6_default_router_entry_neighbor_cache_ptr = &cache_entry; + _nxd_ipv6_router_lookup(&ip_0, &ip_0.nx_ip_interface[0], &router_address, &nd_cache_entry); + cache_entry.nx_nd_cache_nd_status = ND_CACHE_STATE_CREATED; + _nxd_ipv6_router_lookup(&ip_0, &ip_0.nx_ip_interface[0], &router_address, &nd_cache_entry); + ip_0.nx_ipv6_default_router_table[0].nx_ipv6_default_router_entry_neighbor_cache_ptr = NX_NULL; + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) + /* Hit the branch + 156 [ + + ][ + - ]: 408 : if ((rt_entry -> nx_ipv6_default_router_entry_flag & NX_IPV6_ROUTE_TYPE_VALID) && + 157 : 378 : (rt_entry -> nx_ipv6_default_router_entry_interface_ptr == if_ptr)) + */ + ip_0.nx_ipv6_default_router_table[0].nx_ipv6_default_router_entry_flag = NX_IPV6_ROUTE_TYPE_VALID; + _nxd_ipv6_router_lookup(&ip_0, &ip_0.nx_ip_interface[1], &router_address, &nd_cache_entry); +#endif /* (NX_MAX_PHYSICAL_INTERFACES > 1) */ + + /* Call nxd_ipv6_default_router_entry_get with NULL pointers. */ + nxd_ipv6_default_router_entry_get(&ip_0, 0, 0, NX_NULL, NX_NULL, NX_NULL, NX_NULL); + + /* Set linklocal address */ + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 10, NX_NULL); + + /* Set up the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[3] = 0x3; + ipv6_address.nxd_ip_address.v6[2] = 0x0; + ipv6_address.nxd_ip_address.v6[1] = 0x0; + ipv6_address.nxd_ip_address.v6[0] = 0xFF000000; + + /* Call _nxd_ipv6_interface_find with multicast destination address. */ + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &nxd_ipv6_address, NX_NULL); + + /* Set up the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[3] = 0x2; + ipv6_address.nxd_ip_address.v6[2] = 0x0; + ipv6_address.nxd_ip_address.v6[1] = 0x0; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address[0] = 0xFE000000; + + /* Call _nxd_ipv6_interface_find with link local destination address. */ + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &nxd_ipv6_address, NX_NULL); + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address[0] = 0xFE800000; + + ipv6_address.nxd_ip_address.v6[0] = 0x20010000; + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_DEPRECATED; + /* Call _nxd_ipv6_interface_find with multicast destination address. */ + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &nxd_ipv6_address, NX_NULL); + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_VALID; + + /* Call _nxd_ipv6_address_delete with invalid interface address list. */ + ip_0.nx_ipv6_address[0].nxd_ipv6_address_attached -> nxd_interface_ipv6_address_list_head = NX_NULL; + _nxd_ipv6_address_delete(&ip_0, 0); + ip_0.nx_ipv6_address[0].nxd_ipv6_address_attached -> nxd_interface_ipv6_address_list_head = &ip_0.nx_ipv6_address[0]; + + /* Call _nx_ipv6_header_add with invalid address state and protocol. */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &my_packet[0] -> nx_packet_address.nx_packet_ipv6_address_ptr, NX_NULL); + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_DEPRECATED; + _nx_ipv6_header_add(&ip_0, &my_packet[0], NX_PROTOCOL_UDP, 10, 10, NX_NULL, NX_NULL, NX_NULL); + nx_packet_release(my_packet[0]); + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_VALID; + + +#ifndef NX_DISABLE_FRAGMENTATION + /* Call _nx_ipv6_fragment_process with a packet with NX_PROTOCOL_NEXT_HEADER_ROUTING. */ + driver_request.nx_ip_driver_ptr = &ip_0; + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + driver_request.nx_ip_driver_packet = my_packet[0]; + my_packet[0] -> nx_packet_length = 48; + my_packet[0] ->nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 48; + + *(my_packet[0] -> nx_packet_prepend_ptr + 6) = NX_PROTOCOL_NEXT_HEADER_ROUTING; + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV6_HEADER)) = NX_PROTOCOL_TCP; + *(my_packet[0] -> nx_packet_prepend_ptr + sizeof(NX_IPV6_HEADER) + 1) = 0; + _nx_ipv6_fragment_process(&driver_request, 1400); +#endif + + + /* Set up the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[3] = 0x4; + ipv6_address.nxd_ip_address.v6[2] = 0x0; + ipv6_address.nxd_ip_address.v6[1] = 0x0; + ipv6_address.nxd_ip_address.v6[0] = 0xfe800000; + + /* Add a duplicated router. */ + _nxd_ipv6_default_router_add(&ip_0, &ipv6_address, 1000, 0); + + /* Add a duplicated router but with a different interface. */ + _nxd_ipv6_default_router_add_internal(&ip_0, ipv6_address.nxd_ip_address.v6, 0xFFFF, &ip_0.nx_ip_interface[1], NX_IPV6_ROUTE_TYPE_STATIC, NX_NULL); + + _nxd_ipv6_prefix_router_timer_tick(&ip_0); + + ip_0.nx_ipv6_default_router_table[0].nx_ipv6_default_router_entry_life_time = 0; + ip_0.nx_ipv6_destination_table_size = NX_IPV6_DESTINATION_TABLE_SIZE + 1; + ip_0.nx_ipv6_default_router_table[0].nx_ipv6_default_router_entry_neighbor_cache_ptr = &cache_entry; + _nxd_ipv6_prefix_router_timer_tick(&ip_0); + ip_0.nx_ipv6_default_router_table[0].nx_ipv6_default_router_entry_neighbor_cache_ptr = NX_NULL; + ip_0.nx_ipv6_destination_table_size = 0; + + /* Test _nxd_ipv6_address_set with different interface address. */ + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address[1] = 1; + _nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address[1] = 0; + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address[2] = 0x021122FF; + _nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Test _nxd_ipv6_disable with null nx_nd_cache_interface_ptr. */ + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_nd_status = ND_CACHE_STATE_CREATED; + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_interface_ptr = NX_NULL; + _nxd_ipv6_disable(&ip_0); + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_nd_status = ND_CACHE_STATE_INVALID; + _nxd_ipv6_enable(&ip_0); + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +#ifndef NX_DISABLE_ASSERT +/* Define the test threads. */ + +static void thread_for_assert_entry(ULONG thread_input) +{ +NX_PACKET *test_packet; +NXD_ADDRESS destination_ip; +ULONG ipv6_destination_address[4]; +NXD_ADDRESS ipv6_address; +ULONG router_address; +void *nd_cache_entry; +NXD_IPV6_ADDRESS + *nxd_ipv6_address; +NX_IPV6_DESTINATION_ENTRY + *dest_entry_ptr; + + + /* Check the count. */ + if (assert_count == 0) + { + + /* Update the count. */ + assert_count ++; + + nx_packet_allocate(&pool_0, &test_packet, 0, NX_NO_WAIT); + test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr = NX_NULL; + + /* Call function with NULL interface. */ + _nxd_ipv6_raw_packet_send_internal(&ip_0, test_packet, &destination_ip, 0); + } + else if (assert_count == 1) + { + + /* Update the count. */ + assert_count ++; + + /* Call function with NULL next hop. */ + _nxd_ipv6_destination_table_find_next_hop(&ip_0, ipv6_destination_address, NX_NULL); + } + else if (assert_count == 2) + { + + /* Update the count. */ + assert_count ++; + + /* Set up the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[3] = 0x3; + ipv6_address.nxd_ip_address.v6[2] = 0x0; + ipv6_address.nxd_ip_address.v6[1] = 0x0; + ipv6_address.nxd_ip_address.v6[0] = 0xfe800000; + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address, 64, NX_NULL); + ipv6_address.nxd_ip_address.v6[3] = 0x4; + + _nxd_ipv6_default_router_add(&ip_0, &ipv6_address, 1000, 0); + + /* Hit false condition of for (i = 0; table_size && (i < NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE); i++). */ + ip_0.nx_ipv6_default_router_table[0].nx_ipv6_default_router_entry_flag = NX_IPV6_ROUTE_TYPE_NOT_ROUTER; + _nxd_ipv6_router_lookup(&ip_0, &ip_0.nx_ip_interface[0], &router_address, &nd_cache_entry); + + } + else if (assert_count == 3) + { + + /* Update the count. */ + assert_count ++; + + ip_0.nx_ipv6_default_router_table[0].nx_ipv6_default_router_entry_flag = NX_IPV6_ROUTE_TYPE_VALID | NX_IPV6_ROUTE_TYPE_STATIC; + + /* Call function with NULL cache entry pointer. */ + _nxd_ipv6_router_lookup(&ip_0, &ip_0.nx_ip_interface[0], &router_address, NX_NULL); + } + else if (assert_count == 4) + { + + /* Update the count. */ + assert_count ++; + + /* Call function with NULL address pointers. */ + _nxd_ipv6_interface_find(&ip_0, ipv6_destination_address, NX_NULL, NX_NULL); + } + else if (assert_count == 5) + { + + /* Update the count. */ + assert_count ++; + + /* This test point is useless since the logic of _nxd_ipv6_interface_find is modified. */ +#if 0 + /* Set up the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[3] = 0x3; + ipv6_address.nxd_ip_address.v6[2] = 0x0; + ipv6_address.nxd_ip_address.v6[1] = 0x0; + ipv6_address.nxd_ip_address.v6[0] = 0xFF020000; + + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address_valid = NX_FALSE; + + /* Call function with invalid address pointers. */ + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &nxd_ipv6_address, NX_NULL); +#else + tx_thread_suspend(tx_thread_identify()); +#endif + + } + else if (assert_count == 6) + { + + /* Update the count. */ + assert_count ++; + + /* This test point is useless since the logic of _nxd_ipv6_interface_find is modified. */ +#if 0 + /* Set up the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[3] = 0x2; + ipv6_address.nxd_ip_address.v6[2] = 0x0; + ipv6_address.nxd_ip_address.v6[1] = 0x0; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address_valid = NX_FALSE; + + /* Call function with invalid address pointers. */ + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &nxd_ipv6_address, NX_NULL); +#else + tx_thread_suspend(tx_thread_identify()); +#endif + + } + else if (assert_count == 7) + { + + /* Update the count. */ + assert_count ++; + + /* This test point is useless since the logic of _nxd_ipv6_interface_find is modified. */ +#if 0 + /* Set up the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[3] = 0x2; + ipv6_address.nxd_ip_address.v6[2] = 0x0; + ipv6_address.nxd_ip_address.v6[1] = 0x0; + ipv6_address.nxd_ip_address.v6[0] = 0x20010000; + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address[0] = 0x20010000; + ip_0.nx_ip_interface[0].nxd_interface_ipv6_address_list_head -> nxd_ipv6_address_valid = NX_FALSE; + + /* Call function with invalid address pointers. */ + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &nxd_ipv6_address, NX_NULL); +#else + tx_thread_suspend(tx_thread_identify()); +#endif + + } + else if (assert_count == 8) + { + + /* Update the count. */ + assert_count ++; + + /* Call _nx_ipv6_header_add with invalid nx_packet_prepend_ptr. */ + nx_packet_allocate(&pool_0, &test_packet, 0, NX_NO_WAIT); + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr, NX_NULL); + test_packet -> nx_packet_prepend_ptr = test_packet -> nx_packet_data_start - 1; + _nx_ipv6_header_add(&ip_0, &test_packet, NX_PROTOCOL_ICMPV6, 10, 10, NX_NULL, NX_NULL, NX_NULL); + + } + else if (assert_count == 9) + { + + /* Update the count. */ + assert_count ++; + + /* Set up the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[3] = 0x2; + ipv6_address.nxd_ip_address.v6[2] = 0x0; + ipv6_address.nxd_ip_address.v6[1] = 0x0; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + + /* Test _nx_ipv6_packet_send with nx_ipv6_destination_table full for on link destination. */ + nx_packet_allocate(&pool_0, &test_packet, NX_IPv6_UDP_PACKET, NX_NO_WAIT); + test_packet -> nx_packet_length = 60; + test_packet -> nx_packet_append_ptr = test_packet -> nx_packet_prepend_ptr + test_packet -> nx_packet_length; + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr, NX_NULL); + ip_0.nx_ipv6_destination_table_size = NX_IPV6_DESTINATION_TABLE_SIZE; + _nx_ipv6_packet_send(&ip_0, test_packet, NX_PROTOCOL_UDP, test_packet -> nx_packet_length, ip_0.nx_ipv6_hop_limit, ip_0.nx_ipv6_address[0].nxd_ipv6_address, ipv6_address.nxd_ip_address.v6); + ip_0.nx_ipv6_destination_table_size = 0; + + /* Test _nx_ipv6_packet_send with nx_ipv6_destination_table full for off link destination. */ + nx_packet_allocate(&pool_0, &test_packet, NX_IPv6_UDP_PACKET, NX_NO_WAIT); + test_packet -> nx_packet_length = 60; + test_packet -> nx_packet_append_ptr = test_packet -> nx_packet_prepend_ptr + test_packet -> nx_packet_length; + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr, NX_NULL); + ipv6_address.nxd_ip_address.v6[0] = 0x20010000; + ip_0.nx_ipv6_destination_table_size = NX_IPV6_DESTINATION_TABLE_SIZE; + _nx_ipv6_packet_send(&ip_0, test_packet, NX_PROTOCOL_UDP, test_packet -> nx_packet_length, ip_0.nx_ipv6_hop_limit, ip_0.nx_ipv6_address[0].nxd_ipv6_address, ipv6_address.nxd_ip_address.v6); + ip_0.nx_ipv6_destination_table_size = 0; + + /* Call _nx_ipv6_packet_send to add ND cache. */ + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + nx_packet_allocate(&pool_0, &test_packet, NX_IPv6_UDP_PACKET, NX_NO_WAIT); + test_packet -> nx_packet_length = 60; + test_packet -> nx_packet_append_ptr = test_packet -> nx_packet_prepend_ptr + test_packet -> nx_packet_length; + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr, NX_NULL); + _nx_ipv6_packet_send(&ip_0, test_packet, NX_PROTOCOL_UDP, test_packet -> nx_packet_length, ip_0.nx_ipv6_hop_limit, ip_0.nx_ipv6_address[0].nxd_ipv6_address, ipv6_address.nxd_ip_address.v6); + + /* Call _nx_ipv6_packet_send to add ND cache. */ + nx_packet_allocate(&pool_0, &test_packet, NX_IPv6_UDP_PACKET, NX_NO_WAIT); + test_packet -> nx_packet_length = 60; + test_packet -> nx_packet_prepend_ptr = test_packet -> nx_packet_data_start + NX_IPv6_UDP_PACKET; + test_packet -> nx_packet_append_ptr = test_packet -> nx_packet_prepend_ptr + test_packet -> nx_packet_length; + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr, NX_NULL); + _nx_ipv6_packet_send(&ip_0, test_packet, NX_PROTOCOL_UDP, test_packet -> nx_packet_length, ip_0.nx_ipv6_hop_limit, ip_0.nx_ipv6_address[0].nxd_ipv6_address, ipv6_address.nxd_ip_address.v6); + + /* Call _nx_ipv6_packet_send with null nx_nd_cache_packet_waiting_head. */ + nx_packet_allocate(&pool_0, &test_packet, NX_IPv6_UDP_PACKET, NX_NO_WAIT); + test_packet -> nx_packet_length = 60; + test_packet -> nx_packet_prepend_ptr = test_packet -> nx_packet_data_start + NX_IPv6_UDP_PACKET; + test_packet -> nx_packet_append_ptr = test_packet -> nx_packet_prepend_ptr + test_packet -> nx_packet_length; + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr, NX_NULL); + ip_0.nx_ipv6_nd_cache[2].nx_nd_cache_packet_waiting_head = NX_NULL; + ip_0.nx_ipv6_nd_cache[2].nx_nd_cache_packet_waiting_queue_length = NX_ND_MAX_QUEUE_DEPTH + 1; + _nx_ipv6_packet_send(&ip_0, test_packet, NX_PROTOCOL_UDP, test_packet -> nx_packet_length, ip_0.nx_ipv6_hop_limit, ip_0.nx_ipv6_address[0].nxd_ipv6_address, ipv6_address.nxd_ip_address.v6); + +#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY + /* Call _nx_ipv6_packet_send with zero nx_ipv6_destination_entry_path_mtu. */ + nx_packet_allocate(&pool_0, &test_packet, NX_IPv6_UDP_PACKET, NX_NO_WAIT); + test_packet -> nx_packet_length = 60; + test_packet -> nx_packet_prepend_ptr = test_packet -> nx_packet_data_start + NX_IPv6_UDP_PACKET; + test_packet -> nx_packet_append_ptr = test_packet -> nx_packet_prepend_ptr + test_packet -> nx_packet_length; + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr, NX_NULL); + ip_0.nx_ipv6_nd_cache[2].nx_nd_cache_nd_status = ND_CACHE_STATE_REACHABLE; + ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_path_mtu = 0; + _nx_ipv6_packet_send(&ip_0, test_packet, NX_PROTOCOL_UDP, test_packet -> nx_packet_length, ip_0.nx_ipv6_hop_limit, ip_0.nx_ipv6_address[0].nxd_ipv6_address, ipv6_address.nxd_ip_address.v6); + + /* Call _nx_ipv6_packet_send with null nx_interface_link_driver_entry. */ + ip_0.nx_ip_interface[0].nx_interface_link_driver_entry = NX_NULL; + nx_packet_allocate(&pool_0, &test_packet, NX_IPv6_UDP_PACKET, NX_NO_WAIT); + test_packet -> nx_packet_length = 60; + test_packet -> nx_packet_prepend_ptr = test_packet -> nx_packet_data_start + NX_IPv6_UDP_PACKET; + test_packet -> nx_packet_append_ptr = test_packet -> nx_packet_prepend_ptr + test_packet -> nx_packet_length; + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr, NX_NULL); + ip_0.nx_ipv6_destination_table[0].nx_ipv6_destination_entry_path_mtu = 256; + _nx_ipv6_packet_send(&ip_0, test_packet, NX_PROTOCOL_UDP, test_packet -> nx_packet_length, ip_0.nx_ipv6_hop_limit, ip_0.nx_ipv6_address[0].nxd_ipv6_address, ipv6_address.nxd_ip_address.v6); +#endif + + } + else if (assert_count == 10) + { + NXD_IPV6_ADDRESS ipv6_address2; + + /* Update the count. */ + assert_count ++; + + /* Set up the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[3] = 0x2; + ipv6_address.nxd_ip_address.v6[2] = 0x0; + ipv6_address.nxd_ip_address.v6[1] = 0x0; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + + /* Test _nx_ipv6_packet_send with null interface pointer. */ + nx_packet_allocate(&pool_0, &test_packet, NX_IPv6_UDP_PACKET, NX_NO_WAIT); + test_packet -> nx_packet_length = 60; + test_packet -> nx_packet_append_ptr = test_packet -> nx_packet_prepend_ptr + test_packet -> nx_packet_length; + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr, NX_NULL); + ipv6_address2 = *test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr; + ipv6_address2.nxd_ipv6_address_attached = NX_NULL; + test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr = &ipv6_address2; + _nx_ipv6_packet_send(&ip_0, test_packet, NX_PROTOCOL_UDP, test_packet -> nx_packet_length, ip_0.nx_ipv6_hop_limit, ip_0.nx_ipv6_address[0].nxd_ipv6_address, ipv6_address.nxd_ip_address.v6); + + } + else if (assert_count == 11) + { + + /* Update the count. */ + assert_count ++; + + /* Set up the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[3] = 0x2; + ipv6_address.nxd_ip_address.v6[2] = 0x0; + ipv6_address.nxd_ip_address.v6[1] = 0x0; + ipv6_address.nxd_ip_address.v6[0] = 0xFE800000; + + + nx_packet_allocate(&pool_0, &test_packet, NX_IPv6_UDP_PACKET, NX_NO_WAIT); + test_packet -> nx_packet_length = 60; + test_packet -> nx_packet_append_ptr = test_packet -> nx_packet_prepend_ptr + test_packet -> nx_packet_length; + _nxd_ipv6_interface_find(&ip_0, ipv6_address.nxd_ip_address.v6, &test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr, NX_NULL); + + /* Test _nx_ipv6_packet_send with state of ND cache invalid. */ + _nx_icmpv6_dest_table_add(&ip_0, ipv6_address.nxd_ip_address.v6, &dest_entry_ptr, + ipv6_address.nxd_ip_address.v6, 1500, NX_WAIT_FOREVER, + test_packet -> nx_packet_address.nx_packet_ipv6_address_ptr); + dest_entry_ptr -> nx_ipv6_destination_entry_nd_entry -> nx_nd_cache_nd_status = ND_CACHE_STATE_INVALID; + + _nx_ipv6_packet_send(&ip_0, test_packet, NX_PROTOCOL_UDP, test_packet -> nx_packet_length, ip_0.nx_ipv6_hop_limit, ip_0.nx_ipv6_address[0].nxd_ipv6_address, ipv6_address.nxd_ip_address.v6); + } + +} +#endif + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_branch_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Branch Test..........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_default_router_api_test.c b/test/regression/netxduo_test/netx_ipv6_default_router_api_test.c new file mode 100644 index 00000000..ddafa75e --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_default_router_api_test.c @@ -0,0 +1,496 @@ +/* Test IPv4 default router set/get APIs. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#define MAX_TEST_INTERFACES 2 + +#if defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES >= MAX_TEST_INTERFACES) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_router_address; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_default_router_api_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x01020304; + + status += nxd_ipv6_address_set(&ip_0, 0,&ipv6_address_1, 64, NX_NULL); + + if(status) + error_counter++; + +#ifndef NX_DISABLE_ERROR_CHECKING + + /* Attempt to set default router on interface 1. Since Interface 1 has no drivers attached yet, this call shall fail. */ + ipv6_router_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_router_address.nxd_ip_address.v6[0] = 0x20010000; + ipv6_router_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_router_address.nxd_ip_address.v6[2] = 100; + ipv6_router_address.nxd_ip_address.v6[3] = 0x01020305; + status = nxd_ipv6_default_router_add(&ip_0, &ipv6_router_address, 100, 1); + if(status != NX_INVALID_INTERFACE) + error_counter++; + +#endif /* NX_DISABLE_ERROR_CHECKING */ + + status = nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_512); + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20020000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x01020304; + + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_1, 64, NX_NULL); + + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Enable ICMP for IP Instance 0. */ + status += nxd_icmp_enable(&ip_0); + + + /* Check status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT i, j; +UINT status; +ULONG router_lifetime; +ULONG prefix_length; +ULONG configuration_method; +UINT entries; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Default Router API Test.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + for(i = 0; i < MAX_TEST_INTERFACES; i++) + { + /* Attempt to get a default router before routers are configured. */ + memset(&ipv6_router_address, 0, sizeof(ipv6_router_address)); + router_lifetime = 0; + prefix_length = 0; + status = nxd_ipv6_default_router_get(&ip_0, i, &ipv6_router_address, &router_lifetime, &prefix_length); + if(status != NX_NOT_FOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to get default router entries. */ + status = nxd_ipv6_default_router_number_of_entries_get(&ip_0, i, &entries); + if(entries !=0) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Fill the interface with different routers. */ + status = 0; + for(i = 0; i < NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE; i++) + { + ipv6_router_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_router_address.nxd_ip_address.v6[0] = 0x20010000 + 0x10000 * (i % MAX_TEST_INTERFACES); + ipv6_router_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_router_address.nxd_ip_address.v6[2] = i; + ipv6_router_address.nxd_ip_address.v6[3] = 0x01020305; + + status += nxd_ipv6_default_router_add(&ip_0, &ipv6_router_address, 100, i % MAX_TEST_INTERFACES); + } + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check router entry for each interface. */ + for(i = 0; i < MAX_TEST_INTERFACES; i++) + { + status = nxd_ipv6_default_router_number_of_entries_get(&ip_0, i, &entries); + + /* Check entries. */ + if(entries != ((NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE + MAX_TEST_INTERFACES - i - 1) / MAX_TEST_INTERFACES)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check router entry for this interface. */ + for(j = 0; j < entries; j++) + { + status = nxd_ipv6_default_router_entry_get(&ip_0, i, j, &ipv6_router_address, &router_lifetime, &prefix_length, &configuration_method); + if(status != NX_SUCCESS) + { + error_counter++; + } + if(prefix_length != 64) + error_counter++; + if (configuration_method != NX_IPV6_ROUTE_TYPE_STATIC) + error_counter++; + + if(ipv6_router_address.nxd_ip_version != NX_IP_VERSION_V6) + { + error_counter++; + } + if((ipv6_router_address.nxd_ip_address.v6[0] != 0x20010000 + 0x10000 * (i % MAX_TEST_INTERFACES)) || + (ipv6_router_address.nxd_ip_address.v6[1] != 0x00000000) || + (ipv6_router_address.nxd_ip_address.v6[2] != (j * MAX_TEST_INTERFACES + i)) || + (ipv6_router_address.nxd_ip_address.v6[3] != 0x01020305)) + { + error_counter++; + } + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + } + + /* Delete a not existing router. */ + ipv6_router_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_router_address.nxd_ip_address.v6[0] = 0x20010000; + ipv6_router_address.nxd_ip_address.v6[1] = 0; + ipv6_router_address.nxd_ip_address.v6[2] = 0; + ipv6_router_address.nxd_ip_address.v6[3] = 1; + status = nxd_ipv6_default_router_delete(&ip_0, &ipv6_router_address); + + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete all routers. */ + status = 0; + for(i = 0; i < NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE; i++) + { + ipv6_router_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_router_address.nxd_ip_address.v6[0] = 0x20010000 + 0x10000 * (i % MAX_TEST_INTERFACES); + ipv6_router_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_router_address.nxd_ip_address.v6[2] = i; + ipv6_router_address.nxd_ip_address.v6[3] = 0x01020305; + + status += nxd_ipv6_default_router_delete(&ip_0, &ipv6_router_address); + } + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Fill the IPv6 default router table. */ + status = 0; + for(i = 0; i < NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE; i++) + { + ipv6_router_address.nxd_ip_version = NX_IP_VERSION_V6; + if(i == 0) + /* Set the first default router to be link local. */ + ipv6_router_address.nxd_ip_address.v6[0] = 0xFE800000; + else + ipv6_router_address.nxd_ip_address.v6[0] = 0x20010000 + 0x10000 * (i % MAX_TEST_INTERFACES); + ipv6_router_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_router_address.nxd_ip_address.v6[2] = i + 1; + ipv6_router_address.nxd_ip_address.v6[3] = 0x01020305; + + status += nxd_ipv6_default_router_add(&ip_0, &ipv6_router_address, 100, i % MAX_TEST_INTERFACES); + } + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Read back the default routers. */ + for(i = 0; i < MAX_TEST_INTERFACES; i++) + { + memset(&ipv6_router_address, 0, sizeof(ipv6_router_address)); + router_lifetime = 0; + prefix_length = 0; + status = nxd_ipv6_default_router_get(&ip_0, i, &ipv6_router_address, &router_lifetime, &prefix_length); + if(status != NX_SUCCESS) + { + error_counter++; + } + if(i == 0) + { + if(prefix_length != 10) + error_counter++; + } + else if(prefix_length != 64) + error_counter++; + + if(ipv6_router_address.nxd_ip_version != NX_IP_VERSION_V6) + { + error_counter++; + } + if(i == 0) + { + if(ipv6_router_address.nxd_ip_address.v6[0] != 0xFE800000) + error_counter++; + if(prefix_length != 10) + error_counter++; + + } + else + { + if(ipv6_router_address.nxd_ip_address.v6[0] != 0x20010000 + 0x10000 * (i % MAX_TEST_INTERFACES)) + error_counter++; + if(prefix_length != 64) + error_counter++; + } + if((ipv6_router_address.nxd_ip_address.v6[1] != 0x00000000) || + (ipv6_router_address.nxd_ip_address.v6[2] != (i + 1)) || + (ipv6_router_address.nxd_ip_address.v6[3] != 0x01020305)) + { + error_counter++; + } + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Now delete the 1st entry. */ + ipv6_router_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_router_address.nxd_ip_address.v6[0] = 0xFE800000; + ipv6_router_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_router_address.nxd_ip_address.v6[2] = 1; + ipv6_router_address.nxd_ip_address.v6[3] = 0x01020305; + status = nxd_ipv6_default_router_delete(&ip_0, &ipv6_router_address); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Read back the router address. The 2nd entry should be returned. */ + memset(&ipv6_router_address, 0, sizeof(ipv6_router_address)); + router_lifetime = 0; + prefix_length = 0; + + status = nxd_ipv6_default_router_get(&ip_0, 0, &ipv6_router_address, &router_lifetime, &prefix_length); + if((status != NX_SUCCESS) || (prefix_length != 64)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if(ipv6_router_address.nxd_ip_version != NX_IP_VERSION_V6) + { + printf("ERROR!\n"); + test_control_return(1); + } + if((ipv6_router_address.nxd_ip_address.v6[0] != 0x20010000) || + (ipv6_router_address.nxd_ip_address.v6[1] != 0x00000000) || + (ipv6_router_address.nxd_ip_address.v6[2] != (MAX_TEST_INTERFACES + 1)) || + (ipv6_router_address.nxd_ip_address.v6[3] != 0x01020305)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now add another router. It should be stored at the 1st slot. */ + ipv6_router_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_router_address.nxd_ip_address.v6[0] = 0x20010000; + ipv6_router_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_router_address.nxd_ip_address.v6[2] = 0x00010001; + ipv6_router_address.nxd_ip_address.v6[3] = 0x01020305; + status = nxd_ipv6_default_router_add(&ip_0, &ipv6_router_address, 100, 0); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Read back the default routers. */ + /* In this case the 1st entry (updated) should be returned. */ + memset(&ipv6_router_address, 0, sizeof(ipv6_router_address)); + router_lifetime = 0; + prefix_length = 0; + status = nxd_ipv6_default_router_get(&ip_0, 0, &ipv6_router_address, &router_lifetime, &prefix_length); + if((status != NX_SUCCESS) || (prefix_length != 64)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if(ipv6_router_address.nxd_ip_version != NX_IP_VERSION_V6) + { + printf("ERROR!\n"); + test_control_return(1); + } + if((ipv6_router_address.nxd_ip_address.v6[0] != 0x20010000) || + (ipv6_router_address.nxd_ip_address.v6[1] != 0x00000000) || + (ipv6_router_address.nxd_ip_address.v6[2] != 0x00010001) || + (ipv6_router_address.nxd_ip_address.v6[3] != 0x01020305)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the last entry. */ + ipv6_router_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_router_address.nxd_ip_address.v6[0] = 0x20010000 + 0x10000 * ((NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE - 1) % MAX_TEST_INTERFACES); + ipv6_router_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_router_address.nxd_ip_address.v6[2] = NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE; + ipv6_router_address.nxd_ip_address.v6[3] = 0x01020305; + status = nxd_ipv6_default_router_delete(&ip_0, &ipv6_router_address); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Add another entry. This one should take the last spot in the IPv6 default router table */ + ipv6_router_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_router_address.nxd_ip_address.v6[0] = 0x20020000; + ipv6_router_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_router_address.nxd_ip_address.v6[2] = NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE; + ipv6_router_address.nxd_ip_address.v6[3] = 0x01020305; + status = nxd_ipv6_default_router_add(&ip_0, &ipv6_router_address, 100, 1); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Make sure the last entry is correctly set. */ + i = NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE - 1; + if((ip_0.nx_ipv6_default_router_table[i].nx_ipv6_default_router_entry_flag == 0) || + (ip_0.nx_ipv6_default_router_table[i].nx_ipv6_default_router_entry_router_address[0] != 0x20020000) || + (ip_0.nx_ipv6_default_router_table[i].nx_ipv6_default_router_entry_router_address[1] != 0x00000000) || + (ip_0.nx_ipv6_default_router_table[i].nx_ipv6_default_router_entry_router_address[2] != (i + 1)) | + (ip_0.nx_ipv6_default_router_table[i].nx_ipv6_default_router_entry_router_address[3] != 0x01020305)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + ipv6_router_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_router_address.nxd_ip_address.v6[0] = 0x20010000; + ipv6_router_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_router_address.nxd_ip_address.v6[2] = NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE; + ipv6_router_address.nxd_ip_address.v6[3] = 0x01020305; + status = nxd_ipv6_default_router_add(&ip_0, &ipv6_router_address, 100, 0); + if(status != NX_NO_MORE_ENTRIES) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* All done. Return Success */ + printf("SUCCESS!\n"); + + test_control_return(0); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_default_router_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Default Router API Test..............................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_ipv6_default_router_test.c b/test/regression/netxduo_test/netx_ipv6_default_router_test.c new file mode 100644 index 00000000..4cf57c19 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_default_router_test.c @@ -0,0 +1,316 @@ +/* This NetX test concentrates on the IPv6 default router. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV6_DAD) +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_nd_cache.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +static NXD_ADDRESS ipv6_address_3; +static NXD_ADDRESS ipv6_address_4; +static NXD_ADDRESS ipv6_multicast; + + + +/* Define the counters used in the test application... */ +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_default_router_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, + &pool_0, _nx_ram_network_driver_512, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Set the second interface. */ + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), + 0xFFFFFF00UL, _nx_ram_network_driver_512); + if (status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x10000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x40010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x10000003; + + ipv6_multicast.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_multicast.nxd_ip_address.v6[0] = 0xFF020000; + ipv6_multicast.nxd_ip_address.v6[1] = 0x00000000; + ipv6_multicast.nxd_ip_address.v6[2] = 0x00000000; + ipv6_multicast.nxd_ip_address.v6[3] = 0x00000001; + + /* Check ipv6 address set status. */ + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&ip_0); + + /* Check enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status = 0; +NX_PACKET *my_packet; +NXD_IPV6_ADDRESS *ipv6_address; +CHAR mac_address[6]; +ND_CACHE_ENTRY *nd_cache_entry; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Default Router Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set default router to primary interface before setting IPv6 address. */ + status = nxd_ipv6_default_router_add(&ip_0, &ipv6_address_1, 60, 0); + + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_2, 64, NX_NULL); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set multicast address default router to primary interface. */ + status = nxd_ipv6_default_router_add(&ip_0, &ipv6_multicast, 60, 0); + + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set default router to primary interface. */ + status = nxd_ipv6_default_router_add(&ip_0, &ipv6_address_1, 60, 0); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set default router to an address which isn't on link. */ + status = nxd_ipv6_default_router_add(&ip_0, &ipv6_address_3, 60, 0); + + if(status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Try to send a ping. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_3, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_NO_WAIT); + + /* Since the state of address is tentative, no interface can be found. */ + if(status != NX_NO_INTERFACE_ADDRESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_4, 64, NX_NULL); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let DAD finishes. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Try to send a ping. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_3, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_NO_WAIT); + + /* Router is found. Since it doesn't wait, the result is no response. */ + if(status != NX_NO_RESPONSE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* The interface index of default router is 0. */ + /* Outgoing interface should be found. */ + status = _nxd_ipv6_interface_find(&ip_0, ipv6_address_3.nxd_ip_address.v6, &ipv6_address, + &ip_0.nx_ip_interface[0]); + + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Outgoing interface should not be found. */ + status = _nxd_ipv6_interface_find(&ip_0, ipv6_address_3.nxd_ip_address.v6, &ipv6_address, + &ip_0.nx_ip_interface[1]); + + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the link. */ + ip_0.nx_ip_interface[0].nx_interface_link_up = NX_FALSE; + + /* Try to send a ping. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_3, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_NO_WAIT); + + /* Since the link is down, no interface can be found. */ + if(status != NX_NO_INTERFACE_ADDRESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the link. */ + ip_0.nx_ip_interface[0].nx_interface_link_up = NX_TRUE; + + + /* Added the ND Cache entry. */ + mac_address[0] = 0x11; + mac_address[1] = 0x11; + mac_address[2] = 0x22; + mac_address[3] = 0x33; + mac_address[4] = 0x44; + mac_address[5] = 0x57; + + /* Call the function to added the same entry. */ + status = _nx_nd_cache_add(&ip_0, &ipv6_address_1.nxd_ip_address.v6[0], &ip_0.nx_ip_interface[0], &mac_address[0], 0, ND_CACHE_STATE_REACHABLE, &ip_0.nx_ipv6_address[0], &nd_cache_entry); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Try to send a ping. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_3, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_NO_WAIT); + + /* Since the link is down, no interface can be found. */ + if(status != NX_NO_RESPONSE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + printf("SUCCESS!\n"); + test_control_return(0); + + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_default_router_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Default Router Test..................................N/A\n"); + + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_ipv6_disable_test.c b/test/regression/netxduo_test/netx_ipv6_disable_test.c new file mode 100644 index 00000000..c1bf1c09 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_disable_test.c @@ -0,0 +1,231 @@ +/* This NetX test concentrates on the IPv6 disable operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +extern void test_control_return(UINT status); +#ifdef FEATURE_NX_IPV6 + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_disable_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Disable Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Ping an IP address that does exist. */ + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status != NX_SUCCESS) || (my_packet -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable IPv6. */ + status = nxd_ipv6_disable(&ip_0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable IPv6 again. */ + status = nxd_ipv6_disable(&ip_0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ping an IP address that does exist again. */ + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address indexes are still valid after IPv6 enabled. */ + status = nxd_ipv6_enable(&ip_0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + for (i = 0; i < NX_MAX_IPV6_ADDRESSES; i++) + { + if (ip_0.nx_ipv6_address[i].nxd_ipv6_address_index != (UCHAR)i) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_disable_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Disable Test.........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_fragment_fail_test.c b/test/regression/netxduo_test/netx_ipv6_fragment_fail_test.c new file mode 100644 index 00000000..5daaf6d5 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_fragment_fail_test.c @@ -0,0 +1,188 @@ +/* This NetX test concentrates on fragment IPv6 packet fail due to empty packet pool. */ + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(FEATURE_NX_IPV6) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NXD_ADDRESS addr_0, addr_1; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR send_buff[2000]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_fragment_fail_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool with two packets available. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 4000); + pointer = pointer + 4000; + + if (status) + error_counter++; + + /* Create another packet pool. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 1536, pointer, 15360); + pointer = pointer + 15360; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ICMP processing. */ + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Enable fragmentation */ + status += nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check status. */ + if(status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Fragment Fail Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set IPv6 address. */ + addr_0.nxd_ip_version = NX_IP_VERSION_V6; + addr_0.nxd_ip_address.v6[0] = 0xFE800000; + addr_0.nxd_ip_address.v6[1] = 0x00000000; + addr_0.nxd_ip_address.v6[2] = 0x00000000; + addr_0.nxd_ip_address.v6[3] = 0x00000001; + addr_1.nxd_ip_version = NX_IP_VERSION_V6; + addr_1.nxd_ip_address.v6[0] = 0xFE800000; + addr_1.nxd_ip_address.v6[1] = 0x00000000; + addr_1.nxd_ip_address.v6[2] = 0x00000000; + addr_1.nxd_ip_address.v6[3] = 0x00000002; + + status = nxd_ipv6_address_set(&ip_0, 0, &addr_0, 10, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &addr_1, 10, NX_NULL); + + /* Check status */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Ping IP_1 to make sure ND cache is filled. */ + status = nxd_icmp_ping(&ip_0, &addr_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + nx_packet_release(packet_ptr); + + /* Now send a ping that takes two packets. */ + status = nxd_icmp_ping(&ip_0, &addr_1, send_buff, sizeof(send_buff), &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_fragment_fail_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: IPv6 Fragment Fail Test...................................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_ICMP_INFO */ diff --git a/test/regression/netxduo_test/netx_ipv6_fragmentation_error_test1.c b/test/regression/netxduo_test/netx_ipv6_fragmentation_error_test1.c new file mode 100644 index 00000000..aa82b00d --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_fragmentation_error_test1.c @@ -0,0 +1,248 @@ +/* This NetX test concentrates on basic IPv6 fragmentation. */ +/* Test sequence: + * 1. ip_0 allocate 1000 bytes. + * 2. ip_0 discard the packets excpet the header packet, packet length also is 1000. + * 3. ip_0 call nxd_ip_raw_packet_send to send packet. + * 4. ip_0 call nx_ipv6_fragment_process to fragment packet and send the fragmentation packets. + * 5. check if the driver receive fragmentation packet form ip_0. + Test pointer: + * 1. in _nx_ipv6_packet_copy failure since the next packet of source packet is NX_NULL, cover the following code. + if ((source_pkt == NX_NULL) || (dest_pkt == NX_NULL)) + return(NX_NOT_SUCCESSFUL); + * 2. in nx_ipv6_fragment_process failure since _nx_ipv6_packet_copy failure, cover the following code: + // Copy the rest of the frame. + if (_nx_ipv6_packet_copy(source_packet, first_fragment, fragment_size)) + break; +*/ + + +#include "tx_api.h" +#include "nx_api.h" +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(FEATURE_NX_IPV6) +#include "nx_ipv6.h" +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +static NXD_ADDRESS ipv6_address_0; +static NXD_ADDRESS ipv6_address_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fragmentation_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +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'}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_fragmentation_error_test1_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fragmentation_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 128, pointer, 128*60); + pointer = pointer + 128*60; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + if (status) + error_counter++; + + /* Enable IP raw feature on both IP instances. */ + status = nx_ip_raw_packet_enable(&ip_0); + status += nx_ip_raw_packet_enable(&ip_1); + if (status) + error_counter++; + + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + if (status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_1, 64, NX_NULL); + + if(status) + error_counter++; + +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out some test information banners. */ + printf("NetX Test: IPv6 Fragmentation Error Test1............................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* DAD */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set the callback function. */ + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, msg, 1000, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Discard the packets except the header packet. */ + my_packet -> nx_packet_next = NX_NULL; + my_packet -> nx_packet_last = NX_NULL; + + /* Send the raw packet. */ + status = nxd_ip_raw_packet_send(&ip_0, my_packet, &ipv6_address_1, 23, 255, NX_IP_NORMAL); + + /* Check for error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check for error. */ + if((error_counter) || (fragmentation_counter)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Check if receive IPv6 fragmentation packet from ip_0, except NA and NS(IPv6(40) + NS/NA(32)). */ + if ((ip_ptr == &ip_0) && (packet_ptr -> nx_packet_length > 72)) + { + + /* Updated the packet_counter. */ + fragmentation_counter ++; + } + + return NX_TRUE; +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_fragmentation_error_test1_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IPv6 Fragmentation Error Test1............................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ipv6_fragmentation_error_test2.c b/test/regression/netxduo_test/netx_ipv6_fragmentation_error_test2.c new file mode 100644 index 00000000..77b42145 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_fragmentation_error_test2.c @@ -0,0 +1,271 @@ +/* This NetX test concentrates on basic IPv6 fragmentation. */ +/* Test sequence: + * 1. ip_0 allocate one packets. + * 1. ip_0 add the Hop-by-Hop Option, 2 bytes(next header, option length) + 128 bytes(option length). + * 1. ip_0 append the data 1000 bytes. + * 2. ip_0 discard the packets excpet the header packet, packet length also is 2 + 128 + 1000. + * 3. ip_0 call nxd_ip_raw_packet_send to send the packet with Hop-by-Hop Option. + * 4. ip_0 call nx_ipv6_fragment_process to fragment packet and send the fragmentation packets. + * 5. check if the driver receive fragmentation packet form ip_0. + Test pointer: + * 1. in _nx_ipv6_packet_copy failure since the next packet of source packet is NX_NULL, cover the following code. + if ((source_pkt == NX_NULL) || (dest_pkt == NX_NULL)) + return(NX_NOT_SUCCESSFUL); + * 2. in nx_ipv6_fragment_process failure since _nx_ipv6_packet_copy failure, cover the following code: + // For the first packet, the prepend pointer is already at the begining of the IP header. + if (_nx_ipv6_packet_copy(source_packet, first_fragment, fragment_size)) + break; +*/ + + +#include "tx_api.h" +#include "nx_api.h" +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(FEATURE_NX_IPV6) +#include "nx_ipv6.h" +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +static NXD_ADDRESS ipv6_address_0; +static NXD_ADDRESS ipv6_address_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fragmentation_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +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'}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_fragmentation_error_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fragmentation_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 128, pointer, 128*60); + pointer = pointer + 128*60; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + if (status) + error_counter++; + + /* Enable IP raw feature on both IP instances. */ + status = nx_ip_raw_packet_enable(&ip_0); + status += nx_ip_raw_packet_enable(&ip_1); + if (status) + error_counter++; + + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + if (status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_1, 64, NX_NULL); + + if(status) + error_counter++; + +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UCHAR data; +NX_PACKET *my_packet; + + + /* Print out some test information banners. */ + printf("NetX Test: IPv6 Fragmentation Error Test2............................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* DAD */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set the callback function. */ + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Added Hop-by-Hop Options header to let the unfragmentable size exceed one packet. */ + + /* Added the Next header. */ + data = 23; + status = nx_packet_data_append(my_packet, &data, 1, &pool_0, NX_IP_PERIODIC_RATE); + + /* Added the Hdr Ext Len. */ + data = 16; + status += nx_packet_data_append(my_packet, &data, 1, &pool_0, NX_IP_PERIODIC_RATE); + + /* Added the Options. */ + status += nx_packet_data_append(my_packet, msg, 16 * 8, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, msg, 1000, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Discard the packets except the header packet. */ + my_packet -> nx_packet_next = NX_NULL; + my_packet -> nx_packet_last = NX_NULL; + + /* Send the raw packet for Hop-by-Hop Option. */ + status = nxd_ip_raw_packet_send(&ip_0, my_packet, &ipv6_address_1, NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, 255, NX_IP_NORMAL); + + /* Check for error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check for error. */ + if((error_counter) || (fragmentation_counter)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Check if receive IPv6 fragmentation packet from ip_0, except NA and NS(IPv6(40) + NS/NA(32)). */ + if ((ip_ptr == &ip_0) && (packet_ptr -> nx_packet_length > 72)) + { + + /* Updated the packet_counter. */ + fragmentation_counter ++; + } + + return NX_TRUE; +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_fragmentation_error_test2_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IPv6 Fragmentation Error Test2............................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ipv6_fragmentation_test.c b/test/regression/netxduo_test/netx_ipv6_fragmentation_test.c new file mode 100644 index 00000000..2624bc68 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_fragmentation_test.c @@ -0,0 +1,275 @@ +/* This NetX test concentrates on basic IP fragmentation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(FEATURE_NX_IPV6) +#include "nx_ipv6.h" +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +static NXD_ADDRESS ipv6_address_0; +static NXD_ADDRESS ipv6_address_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG fragmentation_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UCHAR buffer[4500]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_fragmentation_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + fragmentation_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 4800, pointer, 5000*10); + pointer = pointer + 5000*10; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + if (status) + error_counter++; + + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + if (status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_1, 64, NX_NULL); + + if(status) + error_counter++; + +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out some test information banners. */ + printf("NetX Test: IPv6 Fragmentation Processing Test........................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* DAD */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + /* Force enable ICMPv6 checksum capability. */ + ip_0.nx_ip_interface[0].nx_interface_capability_flag |= NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM; +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + /* Disable IP fragmentation logic on IP instance 1. */ + status = nx_ip_fragment_disable(&ip_1); + + /* Check the status. */ + if (status) + error_counter++; + + /* Now ping an IP address that does exist. */ + memcpy(buffer, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26); + status = nxd_icmp_ping(&ip_0, &ipv6_address_1, buffer, 4500, &my_packet, TX_TIMER_TICKS_PER_SECOND); + + /* Check the status. */ + if (status == NX_SUCCESS) + error_counter++; + + /* Enable IP fragmentation logic on IP instance 1. */ + status = nx_ip_fragment_enable(&ip_1); + + /* Check the status. */ + if (status) + error_counter++; + + /* Install IPv6 packet receive processing function pointer */ + ip_1.nx_ipv6_packet_receive = my_packet_process; + + /* Now ping an IP address that does exist. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_1, buffer, 4500, &my_packet, TX_TIMER_TICKS_PER_SECOND); + + /* Check the status. */ + if (status == NX_SUCCESS) + error_counter++; + + /* Install IPv6 packet receive processing function pointer */ + ip_1.nx_ipv6_packet_receive = _nx_ipv6_packet_receive; + + /* Disable IP fragmentation logic on IP instance 1 to release the fragmentation packet. */ + status = nx_ip_fragment_disable(&ip_1); + + /* Check the status. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on IP instance 1. */ + status = nx_ip_fragment_enable(&ip_1); + + /* Check the status. */ + if (status) + error_counter++; + + /* Now ping an IP address that does exist. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_1, buffer, 4500, &my_packet, TX_TIMER_TICKS_PER_SECOND); + + /* Check the status. */ + if ((status != NX_SUCCESS) || (my_packet -> nx_packet_length != 4500)) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_IPV6_HEADER *ip_header_ptr; +UCHAR next_header_type; + + /* Points to the base of IPv6 header. */ + ip_header_ptr = (NX_IPV6_HEADER*)packet_ptr -> nx_packet_prepend_ptr; + + /* Byte swap WORD 1 to obtain IPv6 payload length. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /* Get the next header type. */ + next_header_type = (UCHAR)((ip_header_ptr -> nx_ip_header_word_1 >> 8) & 0xFF); + + /* Check the next header type. */ + if (next_header_type == NX_PROTOCOL_NEXT_HEADER_FRAGMENT) + { + + /* Update the counter. */ + fragmentation_counter ++; + + if (fragmentation_counter == 3) + { + + /* Modified the packet length. */ + packet_ptr -> nx_packet_length = 65000; + + /* Modified the payload length. */ + ip_header_ptr -> nx_ip_header_word_1 &= 0x0000FFFF; + ip_header_ptr -> nx_ip_header_word_1 |= ((packet_ptr -> nx_packet_length - sizeof(NX_IPV6_HEADER)) << 16); + } + } + + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /* Directly receive the packet. */ + _nx_ipv6_packet_receive (ip_ptr, packet_ptr); +} + +#else +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_fragmentation_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IPv6 Fragmentation Processing Test........................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_ipv6_hop_by_hop_fragment_test.c b/test/regression/netxduo_test/netx_ipv6_hop_by_hop_fragment_test.c new file mode 100644 index 00000000..120f10b4 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_hop_by_hop_fragment_test.c @@ -0,0 +1,400 @@ +/* This NetX test concentrates on fragment IPv6 packet with hop by hop option. */ + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(FEATURE_NX_IPV6) && !defined(NX_ENABLE_INTERFACE_CAPABILITY) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NXD_ADDRESS addr_0, addr_1; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* ICMPv6 echo request packet with hop by hop option. + * src: 0xFE80::1 + * dst: 0xFE80::2 + * length of ping data: 1400. */ +static char icmp_pkt[] = { +0xa4, 0x1f, 0x72, 0x53, 0xa0, 0xf7, 0x18, 0x03, /* ..rS.... */ +0x73, 0x29, 0x5f, 0x66, 0x86, 0xdd, 0x60, 0x00, /* s)_f..`. */ +0x00, 0x00, 0x05, 0x88, 0x00, 0x40, 0xfe, 0x80, /* .....@.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x3a, 0x00, /* ......:. */ +0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* ........ */ +0x18, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x61, 0x62, /* ......ab */ +0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, /* cdefghij */ +0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, /* klmnopqr */ +0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, /* stuvwabc */ +0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, /* defghijk */ +0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, /* lmnopqrs */ +0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, /* tuvwabcd */ +0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, /* efghijkl */ +0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, /* mnopqrst */ +0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, /* uvwabcde */ +0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, /* fghijklm */ +0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, /* nopqrstu */ +0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* vwabcdef */ +0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, /* ghijklmn */ +0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, /* opqrstuv */ +0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* wabcdefg */ +0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* hijklmno */ +0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* pqrstuvw */ +0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, /* abcdefgh */ +0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* ijklmnop */ +0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, /* qrstuvwa */ +0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, /* bcdefghi */ +0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, /* jklmnopq */ +0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, /* rstuvwab */ +0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, /* cdefghij */ +0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, /* klmnopqr */ +0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, /* stuvwabc */ +0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, /* defghijk */ +0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, /* lmnopqrs */ +0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, /* tuvwabcd */ +0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, /* efghijkl */ +0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, /* mnopqrst */ +0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, /* uvwabcde */ +0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, /* fghijklm */ +0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, /* nopqrstu */ +0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* vwabcdef */ +0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, /* ghijklmn */ +0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, /* opqrstuv */ +0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* wabcdefg */ +0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* hijklmno */ +0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* pqrstuvw */ +0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, /* abcdefgh */ +0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* ijklmnop */ +0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, /* qrstuvwa */ +0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, /* bcdefghi */ +0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, /* jklmnopq */ +0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, /* rstuvwab */ +0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, /* cdefghij */ +0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, /* klmnopqr */ +0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, /* stuvwabc */ +0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, /* defghijk */ +0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, /* lmnopqrs */ +0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, /* tuvwabcd */ +0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, /* efghijkl */ +0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, /* mnopqrst */ +0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, /* uvwabcde */ +0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, /* fghijklm */ +0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, /* nopqrstu */ +0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* vwabcdef */ +0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, /* ghijklmn */ +0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, /* opqrstuv */ +0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* wabcdefg */ +0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* hijklmno */ +0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* pqrstuvw */ +0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, /* abcdefgh */ +0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* ijklmnop */ +0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, /* qrstuvwa */ +0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, /* bcdefghi */ +0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, /* jklmnopq */ +0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, /* rstuvwab */ +0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, /* cdefghij */ +0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, /* klmnopqr */ +0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, /* stuvwabc */ +0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, /* defghijk */ +0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, /* lmnopqrs */ +0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, /* tuvwabcd */ +0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, /* efghijkl */ +0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, /* mnopqrst */ +0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, /* uvwabcde */ +0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, /* fghijklm */ +0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, /* nopqrstu */ +0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* vwabcdef */ +0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, /* ghijklmn */ +0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, /* opqrstuv */ +0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* wabcdefg */ +0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* hijklmno */ +0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* pqrstuvw */ +0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, /* abcdefgh */ +0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* ijklmnop */ +0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, /* qrstuvwa */ +0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, /* bcdefghi */ +0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, /* jklmnopq */ +0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, /* rstuvwab */ +0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, /* cdefghij */ +0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, /* klmnopqr */ +0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, /* stuvwabc */ +0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, /* defghijk */ +0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, /* lmnopqrs */ +0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, /* tuvwabcd */ +0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, /* efghijkl */ +0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, /* mnopqrst */ +0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, /* uvwabcde */ +0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, /* fghijklm */ +0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, /* nopqrstu */ +0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* vwabcdef */ +0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, /* ghijklmn */ +0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, /* opqrstuv */ +0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* wabcdefg */ +0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* hijklmno */ +0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* pqrstuvw */ +0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, /* abcdefgh */ +0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* ijklmnop */ +0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, /* qrstuvwa */ +0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, /* bcdefghi */ +0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, /* jklmnopq */ +0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, /* rstuvwab */ +0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, /* cdefghij */ +0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, /* klmnopqr */ +0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, /* stuvwabc */ +0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, /* defghijk */ +0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, /* lmnopqrs */ +0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, /* tuvwabcd */ +0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, /* efghijkl */ +0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, /* mnopqrst */ +0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, /* uvwabcde */ +0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, /* fghijklm */ +0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, /* nopqrstu */ +0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* vwabcdef */ +0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, /* ghijklmn */ +0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, /* opqrstuv */ +0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* wabcdefg */ +0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* hijklmno */ +0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* pqrstuvw */ +0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, /* abcdefgh */ +0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* ijklmnop */ +0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, /* qrstuvwa */ +0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, /* bcdefghi */ +0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, /* jklmnopq */ +0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, /* rstuvwab */ +0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, /* cdefghij */ +0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, /* klmnopqr */ +0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, /* stuvwabc */ +0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, /* defghijk */ +0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, /* lmnopqrs */ +0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, /* tuvwabcd */ +0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, /* efghijkl */ +0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, /* mnopqrst */ +0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, /* uvwabcde */ +0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, /* fghijklm */ +0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, /* nopqrstu */ +0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* vwabcdef */ +0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, /* ghijklmn */ +0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, /* opqrstuv */ +0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* wabcdefg */ +0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* hijklmno */ +0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* pqrstuvw */ +0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, /* abcdefgh */ +0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* ijklmnop */ +0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, /* qrstuvwa */ +0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, /* bcdefghi */ +0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, /* jklmnopq */ +0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, /* rstuvwab */ +0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, /* cdefghij */ +0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, /* klmnopqr */ +0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, /* stuvwabc */ +0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, /* defghijk */ +0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, /* lmnopqrs */ +0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, /* tuvwabcd */ +0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, /* efghijkl */ +0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, /* mnopqrst */ +0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, /* uvwabcde */ +0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, /* fghijklm */ +0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, /* nopqrstu */ +0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* vwabcdef */ +0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, /* ghijklmn */ +0x6f, 0x70, 0x71, 0x72, 0x73, 0x74 /* opqrst */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_hop_by_hop_fragment_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 15360); + pointer = pointer + 15360; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ICMP processing. */ + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Enable fragmentation */ + status += nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Enable RAW packet for IP_0.*/ + status += nx_ip_raw_packet_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Hop by Hop Fragment Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set IPv6 address. */ + addr_0.nxd_ip_version = NX_IP_VERSION_V6; + addr_0.nxd_ip_address.v6[0] = 0xFE800000; + addr_0.nxd_ip_address.v6[1] = 0x00000000; + addr_0.nxd_ip_address.v6[2] = 0x00000000; + addr_0.nxd_ip_address.v6[3] = 0x00000001; + addr_1.nxd_ip_version = NX_IP_VERSION_V6; + addr_1.nxd_ip_address.v6[0] = 0xFE800000; + addr_1.nxd_ip_address.v6[1] = 0x00000000; + addr_1.nxd_ip_address.v6[2] = 0x00000000; + addr_1.nxd_ip_address.v6[3] = 0x00000002; + + status = nxd_ipv6_address_set(&ip_0, 0, &addr_0, 10, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &addr_1, 10, NX_NULL); + + /* Check status */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set driver filter to replace echo request packet. */ + advanced_packet_process_callback = packet_process; + + /* Ping IP_1. */ + status = nxd_icmp_ping(&ip_0, &addr_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check status */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the length. */ + if (packet_ptr -> nx_packet_length != 1400) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + nx_packet_release(packet_ptr); + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_PACKET *my_packet; + + if ((ip_ptr == &ip_0) && (packet_ptr -> nx_packet_length == 76)) + { + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + /* Inject Echo Request packet. */ + if (nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, NX_WAIT_FOREVER) == NX_SUCCESS) + { + + /* Fill in the packet with data. Skip the MAC and IPv6 header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &icmp_pkt[54], sizeof(icmp_pkt) - 54); + my_packet -> nx_packet_length = sizeof(icmp_pkt) - 54; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + /* Send by RAW service. */ + nxd_ip_raw_packet_send(ip_ptr, my_packet, &addr_1, NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, 255, NX_IP_NORMAL); + } + } + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_hop_by_hop_fragment_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: IPv6 Hop by Hop Fragment Test.............................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_ICMP_INFO */ diff --git a/test/regression/netxduo_test/netx_ipv6_hop_by_hop_option_error_test.c b/test/regression/netxduo_test/netx_ipv6_hop_by_hop_option_error_test.c new file mode 100644 index 00000000..4e2a133a --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_hop_by_hop_option_error_test.c @@ -0,0 +1,279 @@ +/* This NetX test to test the IPv6 onlink search. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMP_INFO) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_ram_network_driver_test_1500.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void icmp_checksum_compute(NX_PACKET *packet_ptr); + + +static char pkt1[78] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x18, 0x00, 0xff, 0xfe, 0x80, /* ... .... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x3a, 0x00, /* "..3DV:. */ +0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* ........ */ +0x09, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* ........ */ +0x03, 0x04, 0x05, 0x06, 0x07, 0x08 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_hop_by_hop_option_error_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*4); + pointer = pointer + 1536*4; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check IP create status. */ + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ICMP enable status. */ + if(status) + error_counter++; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Hop By Hop Option Error Test........................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address*/ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Write data into the packet payload, ignore the physical header! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], 64); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 64; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 64; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Calculate the ICMP checksum. */ + icmp_checksum_compute(my_packet); + + /* Call the _nx_ip_packet_receive function directly receive the ICMPv6 Request with hop by hop option. */ + _nx_ip_packet_receive(&ip_0, my_packet); + + /* Check the value. */ + if ((ip_0.nx_ip_pings_received != 1) || (ip_0.nx_ip_pings_responded_to != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Write data into the packet payload, ignore the physical header! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], 64); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 64; + + /* Set the error append pointer. */ + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 46; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* Calculate the ICMP checksum. */ + icmp_checksum_compute(my_packet); + + /* Call the _nx_ip_packet_receive function directly receive the ICMPv6 Request with hop by hop option. */ + _nx_ip_packet_receive(&ip_0, my_packet); + + /* Check the value. */ + if ((ip_0.nx_ip_pings_received != 1) || (ip_0.nx_ip_pings_responded_to != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* buffer overread test */ + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Write data into the packet payload, ignore the physical header! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], 64); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 64; + + /* Set the error append pointer. */ + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 1; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + /* invoke _nx_ipv6_process_hop_by_hop_option with error packet. */ + status = _nx_ipv6_process_hop_by_hop_option(NX_NULL, my_packet); + + /* Check the status. */ + if (status != NX_OPTION_HEADER_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Out successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +static void icmp_checksum_compute(NX_PACKET *packet_ptr) +{ +NX_ICMPV6_HEADER *header_ptr; +ULONG *source_ip, *dest_ip; +ULONG checksum; + + /* Set packet version. */ + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V6; + + /* Get IPv6 addresses. */ + source_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8); + dest_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 24); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(dest_ip); + + /* Skip IPv6 header and hop by hop header. */ + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV6_HEADER) + 8; + packet_ptr -> nx_packet_length -= sizeof(NX_IPV6_HEADER) + 8; + + header_ptr = (NX_ICMPV6_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + /* Calculate the ICMP checksum. */ + header_ptr -> nx_icmpv6_header_checksum = 0; + + /* Calculate the checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_ICMPV6, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + header_ptr -> nx_icmpv6_header_checksum = checksum; + NX_CHANGE_USHORT_ENDIAN(header_ptr -> nx_icmpv6_header_checksum); + + /* Recover IPv6 header. */ + NX_IPV6_ADDRESS_CHANGE_ENDIAN(source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(dest_ip); + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV6_HEADER) + 8; + packet_ptr -> nx_packet_length += sizeof(NX_IPV6_HEADER) + 8; +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_hop_by_hop_option_error_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Hop By Hop Option Error Test.........................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_interface_detachment_router_test.c b/test/regression/netxduo_test/netx_ipv6_interface_detachment_router_test.c new file mode 100644 index 00000000..4b475655 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_interface_detachment_router_test.c @@ -0,0 +1,196 @@ +/* Test the default router after interface detachment. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static VOID thread_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static char ra_pkt[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x1c, 0xb4, 0x40, 0x00, 0x00, 0x14, 0x00, 0x01, /* ..@..... */ +0x86, 0xa0, 0x00, 0x00, 0x03, 0xe8, 0x01, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0xa0, 0xa0, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* :.....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_interface_detachment_router_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +UINT num_entries; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Interface Detachment Router Test....................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + + /* Inject RA packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &ra_pkt[14], sizeof(ra_pkt) - 14); + packet_ptr -> nx_packet_length = sizeof(ra_pkt) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Check whether one router is added. */ + status = nxd_ipv6_default_router_number_of_entries_get(&ip_0, 0, &num_entries); + + /* Check status */ + if(status) + error_counter++; + + if (num_entries != 1) + error_counter++; + + + /* Detach the interface from IP instance. */ + status += nx_ip_interface_detach(&ip_0, 0); + + if(status) + error_counter++; + + + /* Check whether no router is available. */ + status = nxd_ipv6_default_router_number_of_entries_get(&ip_0, 0, &num_entries); + + /* Check status */ + if(status) + error_counter++; + + if (num_entries != 0) + error_counter++; + + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_interface_detachment_router_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Interface Detachment Router Test.....................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_ipv6_invalid_packet_receive_test.c b/test/regression/netxduo_test/netx_ipv6_invalid_packet_receive_test.c new file mode 100644 index 00000000..24cb2e90 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_invalid_packet_receive_test.c @@ -0,0 +1,333 @@ +/* This NetX test concentrates on the IPv6 receive the invalid packet operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +extern void test_control_return(UINT status); +#ifdef FEATURE_NX_IPV6 + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG icmp_counter; +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static char pkt1[] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x07, 0x2b, 0xff, 0x20, 0x01, /* ... .... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x20, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x3a, 0x00, /* "..3DV:. */ +0x01, 0x04, 0x00, 0x00, 0x00, +}; + +static char pkt2[] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x18, 0x3c, 0xff, 0x20, 0x01, /* ... .... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x20, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x3c, 0x00, /* "..3DV:. */ +0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, /* ........ */ +0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, /* ........ */ +0x03, 0x04, 0x05, 0x06, 0x07, 0x08 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_invalid_packet_receive_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ICMPv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT drop_counter = 0; + + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Invalid Packet Receive Test.........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set the callback function to get the IPv6 packet. */ + ip_1.nx_ipv6_packet_receive = my_packet_process; + + /* Ping an IP address that does exist. */ + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status == NX_SUCCESS) || (my_packet)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Write data into the packet payload, ignore the physical header! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14 + 40], sizeof(pkt1) - 14 - 40); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = sizeof(pkt1) - 14 - 40; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + + status = _nx_ipv6_process_routing_option(&ip_0, my_packet); + + /* Check the status. */ + if (status != NX_OPTION_HEADER_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_FRAGMENTATION + + nx_ip_fragment_enable(&ip_0); + + status = _nx_ipv6_process_fragment_option(&ip_0, my_packet); + + /* Check the status. */ + if (status != NX_OPTION_HEADER_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + nx_packet_release(my_packet); + + /* Allocate one packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Write data into the packet payload, ignore the physical header! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) - 14); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = sizeof(pkt2) - 14; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + /* Set the interface. */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + my_packet -> nx_packet_ip_version = NX_IP_VERSION_V6; + + drop_counter = ip_0.nx_ip_receive_packets_dropped; + + /* Cover nx_ip_dispatch_process.c line 185. */ + _nx_ipv6_packet_receive(&ip_0, my_packet); +#ifndef NX_DISABLE_IP_INFO + if (drop_counter == ip_0.nx_ip_receive_packets_dropped) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check the error counter and icmp counter. */ + if ((error_counter) || (icmp_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +NX_PACKET *my_packet; +NX_IPV6_HEADER *ip_header_ptr; + + + /* Check the packet length. */ + if (packet_ptr ->nx_packet_length == 76) // 28(DATA) + 8(ICMP HEADER) + 40(IPV6 HEADER) + { + + /* Get the ICMP packet. */ + icmp_counter ++; + + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, &my_packet, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter ++; + + + /**********************************************************/ + /* nx_packet_length < pkt_length nx_ipv6_packet_receive() */ + /**********************************************************/ + + /* Get the IPv6 header. */ + ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /* Modified the packet length. */ + ip_header_ptr -> nx_ip_header_word_1 += 0x00010000; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /* Set the address state as NX_IPV6_ADDR_STATE_UNKNOWN, and receive the packet again, then recover the state. + Cover the code if (interface_ipv6_address_next -> nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_UNKNOWN) in _nx_ipv6_packet_receive. */ + ip_1.nx_ipv6_address[0].nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_UNKNOWN; + _nx_ipv6_packet_receive(&ip_1, my_packet); + ip_1.nx_ipv6_address[0].nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_VALID; + } + + /* Call the _nx_ipv6_packet_receive function directly receive this packet. */ + _nx_ipv6_packet_receive(&ip_1, packet_ptr); + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_invalid_packet_receive_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Invalid Packet Receive Test..........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_multicast_basic_test.c b/test/regression/netxduo_test/netx_ipv6_multicast_basic_test.c new file mode 100644 index 00000000..242b7195 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_multicast_basic_test.c @@ -0,0 +1,296 @@ +/* This NetX test concentrates on the basic multicast IGMP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_multicast_basic_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS group_address[8]; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Multicast Basic Operation Test......................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the group address . */ + group_address[0].nxd_ip_version = NX_IP_VERSION_V6; + group_address[0].nxd_ip_address.v6[0] = 0xff020000; + group_address[0].nxd_ip_address.v6[1] = 0x00000000; + group_address[0].nxd_ip_address.v6[2] = 0x00000000; + group_address[0].nxd_ip_address.v6[3] = 0x01020301; + + /* Set the group address . */ + group_address[1].nxd_ip_version = NX_IP_VERSION_V6; + group_address[1].nxd_ip_address.v6[0] = 0xff020000; + group_address[1].nxd_ip_address.v6[1] = 0x00000000; + group_address[1].nxd_ip_address.v6[2] = 0x00000000; + group_address[1].nxd_ip_address.v6[3] = 0x01020302; + + /* Set the group address . */ + group_address[2].nxd_ip_version = NX_IP_VERSION_V6; + group_address[2].nxd_ip_address.v6[0] = 0xff020000; + group_address[2].nxd_ip_address.v6[1] = 0x00000000; + group_address[2].nxd_ip_address.v6[2] = 0x00000000; + group_address[2].nxd_ip_address.v6[3] = 0x01020303; + + /* Set the group address . */ + group_address[3].nxd_ip_version = NX_IP_VERSION_V6; + group_address[3].nxd_ip_address.v6[0] = 0xff020000; + group_address[3].nxd_ip_address.v6[1] = 0x00000000; + group_address[3].nxd_ip_address.v6[2] = 0x00000000; + group_address[3].nxd_ip_address.v6[3] = 0x01020304; + + /* Set the group address . */ + group_address[4].nxd_ip_version = NX_IP_VERSION_V6; + group_address[4].nxd_ip_address.v6[0] = 0xff020000; + group_address[4].nxd_ip_address.v6[1] = 0x00000000; + group_address[4].nxd_ip_address.v6[2] = 0x00000000; + group_address[4].nxd_ip_address.v6[3] = 0x01020305; + + /* Set the group address . */ + group_address[5].nxd_ip_version = NX_IP_VERSION_V6; + group_address[5].nxd_ip_address.v6[0] = 0xff020000; + group_address[5].nxd_ip_address.v6[1] = 0x00000000; + group_address[5].nxd_ip_address.v6[2] = 0x00000000; + group_address[5].nxd_ip_address.v6[3] = 0x01020306; + + /* Set the group address . */ + group_address[6].nxd_ip_version = NX_IP_VERSION_V6; + group_address[6].nxd_ip_address.v6[0] = 0xff020000; + group_address[6].nxd_ip_address.v6[1] = 0x00000000; + group_address[6].nxd_ip_address.v6[2] = 0x00000000; + group_address[6].nxd_ip_address.v6[3] = 0x01020307; + + /* Set the group address . */ + group_address[7].nxd_ip_version = NX_IP_VERSION_V6; + group_address[7].nxd_ip_address.v6[0] = 0xff020000; + group_address[7].nxd_ip_address.v6[1] = 0x00000000; + group_address[7].nxd_ip_address.v6[2] = 0x00000000; + group_address[7].nxd_ip_address.v6[3] = 0x01020308; + + /* Perform IGMP join operations. */ + status = nxd_ipv6_multicast_interface_join(&ip_0, &group_address[0], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[1], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[1], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[2], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[2], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[2], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[3], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[3], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[3], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[3], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[4], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[4], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[4], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[4], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[4], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 0); + + /* Check status. */ + if(status) + error_counter ++; + + /* Attempt to join a new group. This should result in an error. */ + status = nxd_ipv6_multicast_interface_join(&ip_0, &group_address[7], 0); + + /* Check status. */ + if(!status) + error_counter ++; + + /* Check the groups info. */ + if((ip_0.nx_ipv6_multicast_groups_joined != 7) || + (ip_0.nx_ipv6_multicast_entry[0].nx_ip_mld_join_count != 1) || + (ip_0.nx_ipv6_multicast_entry[1].nx_ip_mld_join_count != 2) || + (ip_0.nx_ipv6_multicast_entry[2].nx_ip_mld_join_count != 3) || + (ip_0.nx_ipv6_multicast_entry[3].nx_ip_mld_join_count != 4) || + (ip_0.nx_ipv6_multicast_entry[4].nx_ip_mld_join_count != 5) || + (ip_0.nx_ipv6_multicast_entry[5].nx_ip_mld_join_count != 6) || + (ip_0.nx_ipv6_multicast_entry[6].nx_ip_mld_join_count != 7)) + error_counter ++; + + /* Leave the every group . */ + status = nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[0], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[1], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[2], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[3], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[4], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[6], 0); + + /* Check status. */ + if(status) + error_counter ++; + + /* Check the groups info. */ + if((ip_0.nx_ipv6_multicast_groups_joined != 6) || + (ip_0.nx_ipv6_multicast_entry[0].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[1].nx_ip_mld_join_count != 1) || + (ip_0.nx_ipv6_multicast_entry[2].nx_ip_mld_join_count != 2) || + (ip_0.nx_ipv6_multicast_entry[3].nx_ip_mld_join_count != 3) || + (ip_0.nx_ipv6_multicast_entry[4].nx_ip_mld_join_count != 4) || + (ip_0.nx_ipv6_multicast_entry[5].nx_ip_mld_join_count != 5) || + (ip_0.nx_ipv6_multicast_entry[6].nx_ip_mld_join_count != 6)) + error_counter ++; + + /* Leave the group 0 again. This should result in an error. */ + status = nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[0], 0); + + /* Check status. */ + if(!status) + error_counter ++; + + /* Leave the every group . */ + status = nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[1], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[2], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[2], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[3], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[3], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[3], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[4], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[4], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[4], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[4], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[5], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[6], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[6], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[6], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[6], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[6], 0); + status += nxd_ipv6_multicast_interface_leave(&ip_0, &group_address[6], 0); + + /* Check status. */ + if(status) + error_counter ++; + + /* Check the groups info. */ + if((ip_0.nx_ipv6_multicast_groups_joined != 0) || + (ip_0.nx_ipv6_multicast_entry[0].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[1].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[2].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[3].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[4].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[5].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[6].nx_ip_mld_join_count != 0)) + error_counter ++; + + /* Check for status. */ + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_multicast_basic_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IPv6 Multicast Basic Operation Test.......................N/A\n"); + test_control_return(3); + +} +#endif /* NX_ENABLE_IPV6_MULTICAST */ diff --git a/test/regression/netxduo_test/netx_ipv6_multicast_interface_detach_test.c b/test/regression/netxduo_test/netx_ipv6_multicast_interface_detach_test.c new file mode 100644 index 00000000..2ac5b88c --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_multicast_interface_detach_test.c @@ -0,0 +1,232 @@ +/* This NetX test concentrates on the basic multicast IGMP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES > 1) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_multicast_interface_detach_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + /* Check the status. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check the status. */ + if(status) + error_counter++; + + /* Attach the 2nd interface to IP instance0 */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + + /* Check the status. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS group_address[8]; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Multicast Interface Detach Test......................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the group address . */ + group_address[0].nxd_ip_version = NX_IP_VERSION_V6; + group_address[0].nxd_ip_address.v6[0] = 0xff020000; + group_address[0].nxd_ip_address.v6[1] = 0x00000000; + group_address[0].nxd_ip_address.v6[2] = 0x00000000; + group_address[0].nxd_ip_address.v6[3] = 0x01020301; + + /* Set the group address . */ + group_address[1].nxd_ip_version = NX_IP_VERSION_V6; + group_address[1].nxd_ip_address.v6[0] = 0xff020000; + group_address[1].nxd_ip_address.v6[1] = 0x00000000; + group_address[1].nxd_ip_address.v6[2] = 0x00000000; + group_address[1].nxd_ip_address.v6[3] = 0x01020302; + + /* Set the group address . */ + group_address[2].nxd_ip_version = NX_IP_VERSION_V6; + group_address[2].nxd_ip_address.v6[0] = 0xff020000; + group_address[2].nxd_ip_address.v6[1] = 0x00000000; + group_address[2].nxd_ip_address.v6[2] = 0x00000000; + group_address[2].nxd_ip_address.v6[3] = 0x01020303; + + /* Set the group address . */ + group_address[3].nxd_ip_version = NX_IP_VERSION_V6; + group_address[3].nxd_ip_address.v6[0] = 0xff020000; + group_address[3].nxd_ip_address.v6[1] = 0x00000000; + group_address[3].nxd_ip_address.v6[2] = 0x00000000; + group_address[3].nxd_ip_address.v6[3] = 0x01020304; + + /* Set the group address . */ + group_address[4].nxd_ip_version = NX_IP_VERSION_V6; + group_address[4].nxd_ip_address.v6[0] = 0xff020000; + group_address[4].nxd_ip_address.v6[1] = 0x00000000; + group_address[4].nxd_ip_address.v6[2] = 0x00000000; + group_address[4].nxd_ip_address.v6[3] = 0x01020305; + + /* Set the group address . */ + group_address[5].nxd_ip_version = NX_IP_VERSION_V6; + group_address[5].nxd_ip_address.v6[0] = 0xff020000; + group_address[5].nxd_ip_address.v6[1] = 0x00000000; + group_address[5].nxd_ip_address.v6[2] = 0x00000000; + group_address[5].nxd_ip_address.v6[3] = 0x01020306; + + /* Set the group address . */ + group_address[6].nxd_ip_version = NX_IP_VERSION_V6; + group_address[6].nxd_ip_address.v6[0] = 0xff020000; + group_address[6].nxd_ip_address.v6[1] = 0x00000000; + group_address[6].nxd_ip_address.v6[2] = 0x00000000; + group_address[6].nxd_ip_address.v6[3] = 0x01020307; + + /* Set the group address . */ + group_address[7].nxd_ip_version = NX_IP_VERSION_V6; + group_address[7].nxd_ip_address.v6[0] = 0xff020000; + group_address[7].nxd_ip_address.v6[1] = 0x00000000; + group_address[7].nxd_ip_address.v6[2] = 0x00000000; + group_address[7].nxd_ip_address.v6[3] = 0x01020308; + + /* Perform IGMP join operations. */ + status = nxd_ipv6_multicast_interface_join(&ip_0, &group_address[0], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[1], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[1], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[2], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[2], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[2], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[3], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[3], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[3], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[3], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[4], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[4], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[4], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[4], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[4], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[5], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 1); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address[6], 1); + + /* Check status. */ + if(status) + error_counter ++; + + /* Detach the seconde interface. */ + status = nx_ip_interface_detach(&ip_0, 1); + + /* Check status. */ + if(status) + error_counter ++; + + /* Check the groups info. */ + if((ip_0.nx_ipv6_multicast_groups_joined != 0) || + (ip_0.nx_ipv6_multicast_entry[0].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[1].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[2].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[3].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[4].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[5].nx_ip_mld_join_count != 0) || + (ip_0.nx_ipv6_multicast_entry[6].nx_ip_mld_join_count != 0)) + error_counter ++; + + /* Check for status. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_multicast_interface_detach_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IPv6 Multicast Interface Detach Test......................N/A\n"); + test_control_return(3); +} +#endif /* NX_ENABLE_IPV6_MULTICAST */ diff --git a/test/regression/netxduo_test/netx_ipv6_multicast_ping_test.c b/test/regression/netxduo_test/netx_ipv6_multicast_ping_test.c new file mode 100644 index 00000000..9c555065 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_multicast_ping_test.c @@ -0,0 +1,311 @@ +/* This NetX test concentrates on the basic multicast IGMP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES > 1) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_0_1; +static NXD_ADDRESS global_address_1; +static NXD_ADDRESS global_address_2; +static UINT address_index_0_1; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_multicast_ping_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 2); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_2, "NetX IP Instance 2", IP_ADDRESS(1, 2, 3, 6), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Set the second interface. */ + status = nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + status += nxd_ipv6_enable(&ip_2); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + status += nxd_icmp_enable(&ip_2); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set the second ipv6 global address for IP instance 0. */ + global_address_0_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_0_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_0_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_0_1.nxd_ip_address.v6[3] = 0x20000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 1, &global_address_0_1, 64, &address_index_0_1); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 2. */ + global_address_2.nxd_ip_version = NX_IP_VERSION_V6; + global_address_2.nxd_ip_address.v6[0] = 0x20010000; + global_address_2.nxd_ip_address.v6[1] = 0x00000000; + global_address_2.nxd_ip_address.v6[2] = 0x00000000; + global_address_2.nxd_ip_address.v6[3] = 0x10000003; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_2, 0, &global_address_2, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS group_address; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Multicast Ping Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set the group address . */ + group_address.nxd_ip_version = NX_IP_VERSION_V6; + group_address.nxd_ip_address.v6[0] = 0xff020000; + group_address.nxd_ip_address.v6[1] = 0x00000000; + group_address.nxd_ip_address.v6[2] = 0x00000000; + group_address.nxd_ip_address.v6[3] = 0x01020301; + + /* Ping group address before joining. */ + status = nxd_icmp_ping(&ip_0, &group_address, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Perform IGMP join operations. */ + status = nxd_ipv6_multicast_interface_join(&ip_0, &group_address, 0); + status += nxd_ipv6_multicast_interface_join(&ip_0, &group_address, 1); + status += nxd_ipv6_multicast_interface_join(&ip_1, &group_address, 0); + status += nxd_ipv6_multicast_interface_join(&ip_2, &group_address, 0); + + /* Check status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Now ping an Multicast address that does exist. */ + /* The reply packet contains checksum 0. */ + status = nxd_icmp_ping(&ip_0, &group_address, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_IPV4 + /* Get ICMP information. */ + status = nx_icmp_info_get(&ip_0, &pings_sent, &ping_timeouts, &ping_threads_suspended, &ping_responses_received, &icmp_checksum_errors, &icmp_unhandled_messages); + +#ifndef NX_DISABLE_ICMP_INFO + if ((ping_timeouts != 0) || (pings_sent != 1) || (ping_responses_received != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS) || (my_packet == NX_NULL) || (my_packet -> nx_packet_length != 28 /* data only */) || + (ping_threads_suspended) || (icmp_checksum_errors) || (icmp_unhandled_messages)) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Release the response packet. */ + nx_packet_release(my_packet); + + /* Disable the primary interace. */ + ip_0.nx_ip_interface[0].nx_interface_link_up = NX_FALSE; + + /* And now ping an Multicast address that does exist. */ + status = nxd_icmp_ping(&ip_0, &group_address, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the response packet. */ + nx_packet_release(my_packet); + + /* Delete the address of the second interface. */ + nxd_ipv6_address_delete(&ip_0, address_index_0_1); + + /* And now ping an Multicast address that does exist. */ + status = nxd_icmp_ping(&ip_0, &group_address, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + if (status != NX_NO_INTERFACE_ADDRESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_multicast_ping_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IPv6 Multicast Ping Test..................................N/A\n"); + test_control_return(3); + +} +#endif /* NX_ENABLE_IPV6_MULTICAST */ diff --git a/test/regression/netxduo_test/netx_ipv6_multicast_ping_test1.c b/test/regression/netxduo_test/netx_ipv6_multicast_ping_test1.c new file mode 100644 index 00000000..ae020154 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_multicast_ping_test1.c @@ -0,0 +1,193 @@ +/* This NetX test concentrates on the basic multicast ICMPv6 operation. + * Two nodes (A and B) with link local addresses. + * Let node A finish DAD first. + * Let node A ping all node multicast address. + * Since the state of address for node B is still tentative, B would not respond A. + * Let node B finish DAD. + * Let node A ping all node multicast address. + * Check the return status of ping from A. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_IPV6_DAD) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); + +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_multicast_ping_test1_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS multicast_address; +NX_PACKET *my_packet; +ULONG pings_sent; +ULONG ping_timeouts; +ULONG ping_threads_suspended; +ULONG ping_responses_received; +ULONG icmp_checksum_errors; +ULONG icmp_unhandled_messages; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Multicast Ping Test 1................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, NX_NULL, 10, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set the group address . */ + multicast_address.nxd_ip_version = NX_IP_VERSION_V6; + multicast_address.nxd_ip_address.v6[0] = 0xff020000; + multicast_address.nxd_ip_address.v6[1] = 0x00000000; + multicast_address.nxd_ip_address.v6[2] = 0x00000000; + multicast_address.nxd_ip_address.v6[3] = 0x00000001; + + /* Ping multicast address before DAD of IP_1 is done. */ + status = nxd_icmp_ping(&ip_0, &multicast_address, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Now ping an Multicast address that does exist. */ + /* The reply packet contains checksum 0. */ + status = nxd_icmp_ping(&ip_0, &multicast_address, "PjCZEZGZIZKZMZOZQZSZUZWZYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_multicast_ping_test1_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: IPv6 Multicast Ping Test 1................................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_ipv6_nd_cache_api_test.c b/test/regression/netxduo_test/netx_ipv6_nd_cache_api_test.c new file mode 100644 index 00000000..f5341c49 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_nd_cache_api_test.c @@ -0,0 +1,384 @@ +/* Test IPv6 ND CACHE APIs. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#define MAX_TEST_INTERFACES 2 + +#if defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES >= MAX_TEST_INTERFACES) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_0; +static NXD_ADDRESS ipv6_address_1; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_nd_cache_api_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + ipv6_address_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[3] = 0x01020304; + + status += nxd_ipv6_address_set(&ip_0, 0,&ipv6_address_0, 64, NX_NULL); + + if(status) + error_counter++; + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_512); + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20020000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x01020304; + + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_1, 64, NX_NULL); + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS dest_address[4]; +CHAR dest_mac[4][6]; +NXD_ADDRESS ipv6_address; +NXD_ADDRESS invalid_address; +ULONG physical_msw; +ULONG physical_lsw; +UINT interface_index; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 ND Cache API Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the Destination address and mac address. */ + dest_address[0].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[0].nxd_ip_address.v6[0] = 0x20010000; + dest_address[0].nxd_ip_address.v6[1] = 0x00000000; + dest_address[0].nxd_ip_address.v6[2] = 0x00000000; + dest_address[0].nxd_ip_address.v6[3] = 0x01020305; + + dest_mac[0][0] = 0x11; + dest_mac[0][1] = 0x22; + dest_mac[0][2] = 0x33; + dest_mac[0][3] = 0x44; + dest_mac[0][4] = 0x55; + dest_mac[0][5] = 0x69; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[0].nxd_ip_address.v6[0], 0, &dest_mac[0][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Set the Destination address and mac address. */ + dest_address[1].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[1].nxd_ip_address.v6[0] = 0x20010000; + dest_address[1].nxd_ip_address.v6[1] = 0x00000000; + dest_address[1].nxd_ip_address.v6[2] = 0x00000000; + dest_address[1].nxd_ip_address.v6[3] = 0x01020306; + + dest_mac[1][0] = 0x11; + dest_mac[1][1] = 0x22; + dest_mac[1][2] = 0x33; + dest_mac[1][3] = 0x44; + dest_mac[1][4] = 0x55; + dest_mac[1][5] = 0x70; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[1].nxd_ip_address.v6[0], 0, &dest_mac[1][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Set the Destination address and mac address. */ + dest_address[2].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[2].nxd_ip_address.v6[0] = 0x20020000; + dest_address[2].nxd_ip_address.v6[1] = 0x00000000; + dest_address[2].nxd_ip_address.v6[2] = 0x00000000; + dest_address[2].nxd_ip_address.v6[3] = 0x01020305; + + dest_mac[2][0] = 0x11; + dest_mac[2][1] = 0x22; + dest_mac[2][2] = 0x33; + dest_mac[2][3] = 0x44; + dest_mac[2][4] = 0x66; + dest_mac[2][5] = 0x69; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[2].nxd_ip_address.v6[0], 1, &dest_mac[2][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Set the Destination address and mac address. */ + dest_address[3].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[3].nxd_ip_address.v6[0] = 0x20020000; + dest_address[3].nxd_ip_address.v6[1] = 0x00000000; + dest_address[3].nxd_ip_address.v6[2] = 0x00000000; + dest_address[3].nxd_ip_address.v6[3] = 0x01020306; + + dest_mac[3][0] = 0x11; + dest_mac[3][1] = 0x22; + dest_mac[3][2] = 0x33; + dest_mac[3][3] = 0x44; + dest_mac[3][4] = 0x66; + dest_mac[3][5] = 0x70; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[3].nxd_ip_address.v6[0], 1, &dest_mac[3][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Find the hardware address and interface index by ipv6 address. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[0], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 0) || + (physical_msw != 0x00001122) || + (physical_lsw != 0x33445569)) + error_counter ++; + + /* Find the hardware address and interface index by ipv6 address. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[3], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 1) || + (physical_msw != 0x00001122) || + (physical_lsw != 0x33446670)) + error_counter ++; + + /* Find the ipv6 address and interface index by hardware address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33445570, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 0) || + (ipv6_address.nxd_ip_address.v6[0] != dest_address[1].nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != dest_address[1].nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != dest_address[1].nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != dest_address[1].nxd_ip_address.v6[3])) + error_counter ++; + + /* Find the ipv6 address and interface index by hardware address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33446669, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 1) || + (ipv6_address.nxd_ip_address.v6[0] != dest_address[2].nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != dest_address[2].nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != dest_address[2].nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != dest_address[2].nxd_ip_address.v6[3])) + error_counter ++; + + /* Set an invalid address. */ + invalid_address.nxd_ip_version = NX_IP_VERSION_V6; + invalid_address.nxd_ip_address.v6[0] = 0x30000000; + invalid_address.nxd_ip_address.v6[1] = 0x00000000; + invalid_address.nxd_ip_address.v6[2] = 0x00000000; + invalid_address.nxd_ip_address.v6[3] = 0x11111111; + + /* Delete the ND Cache entry with invalid address. */ + status = nxd_nd_cache_entry_delete(&ip_0, &invalid_address.nxd_ip_address.v6[0]); + + /* Check status. */ + if(status != NX_ENTRY_NOT_FOUND) + error_counter++; + + /* Delete the ND Cache entry. */ + status = nxd_nd_cache_entry_delete(&ip_0, &dest_address[0].nxd_ip_address.v6[0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Find the destination address 0. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[0], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Invalidate the all address. */ + status = nxd_nd_cache_invalidate(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Find the mac address 0 by destination address 0. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[0], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the mac address 1 by destination address 1. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[1], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the mac address 2 by destination address 2. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[2], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the mac address 3 by destination address 3. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[3], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the ipv6 address 0 by hardware address 0. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33445569, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the ipv6 address 1 by hardware address 1. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33445570, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the ipv6 address 2 by hardware address 2. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33446669, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the ipv6 address 3 by hardware address 3. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33446670, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_nd_cache_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 ND Cache API Test....................................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_ipv6_nxe_api_test.c b/test/regression/netxduo_test/netx_ipv6_nxe_api_test.c new file mode 100644 index 00000000..61ee1de2 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_nxe_api_test.c @@ -0,0 +1,991 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP invalid_ip; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG prefix_length; +UINT interface_index; +UINT address_index; +ULONG router_lifetime; +ULONG configuration_method; +UINT num_entries; +NXD_ADDRESS ip_address; +NXD_ADDRESS router_addr; +#ifdef NX_ENABLE_IPV6_MULTICAST +NXD_ADDRESS group_address; +#endif + + + /* Print out some test information banners. */ + printf("NetX Test: IPv6 NXE API Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + /**************************************************/ + /* Tested the nxde_ipv6_address_change_notify api */ + /**************************************************/ + + /* Set the IPV6 address change notify function for NULL IP instance. */ + status = nxd_ipv6_address_change_notify(NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the IPv6 address change notify function for invalid IP instance. */ + status = nxd_ipv6_address_change_notify(&invalid_ip, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /************************************************/ + /* Tested the nxde_ipv6_address_delete api */ + /************************************************/ + + /* Delete the IPv6 address with NULL IP instance. */ + status = nxd_ipv6_address_delete(NX_NULL, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Delete the IPv6 address with invalid IP instance. */ + status = nxd_ipv6_address_delete(&invalid_ip, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the IPv6 address with invalid address index. */ + status = nxd_ipv6_address_delete(&ip_0, NX_MAX_IPV6_ADDRESSES); + + /* Check for error. */ + if (status != NX_NO_INTERFACE_ADDRESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxde_ipv6_address_get api */ + /************************************************/ + + /* Get the IPv6 address with NULL IP instance. */ + status = nxd_ipv6_address_get(NX_NULL, 0, &ip_address, &prefix_length, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the IPv6 address with invalid IP instance. */ + status = nxd_ipv6_address_get(&invalid_ip, 0, &ip_address, &prefix_length, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IP address with NULL address pointer. */ + status = nxd_ipv6_address_get(&ip_0, 0, NX_NULL, &prefix_length, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address with NULL prefix length pointer. */ + status = nxd_ipv6_address_get(&ip_0, 0, &ip_address, NX_NULL, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address with NULL interface index pointer. */ + status = nxd_ipv6_address_get(&ip_0, 0, &ip_address, &prefix_length, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IPv6 address with invalid address index. */ + status = nxd_ipv6_address_get(&ip_0, (NX_MAX_IPV6_ADDRESSES + NX_LOOPBACK_IPV6_ENABLED), &ip_address, &prefix_length, &interface_index); + + /* Check for error. */ + if (status != NX_NO_INTERFACE_ADDRESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxde_ipv6_address_set api */ + /************************************************/ + + /* Set the IPv6 address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x20010000; + ip_address.nxd_ip_address.v6[1] = 0x00000000; + ip_address.nxd_ip_address.v6[2] = 0x00000000; + ip_address.nxd_ip_address.v6[3] = 0x00001234; + + /* Set the IPv6 address with NULL IP instance. */ + status = nxd_ipv6_address_set(NX_NULL, 0, &ip_address, 64, &address_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the IPv6 address with invalid IP instance. */ + status = nxd_ipv6_address_set(&invalid_ip, 0, &ip_address, 64, &address_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 address with invalid version. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + /* Set the IP address with invalid address version. */ + status = nxd_ipv6_address_set(&ip_0, 0, &ip_address, 64, &address_index); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the IPv6 address version. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + + /* Set the IP address with invalid interface index. */ + status = nxd_ipv6_address_set(&ip_0, NX_MAX_PHYSICAL_INTERFACES, &ip_address, 64, &address_index); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the IPv6 address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V6; + ip_address.nxd_ip_address.v6[0] = 0x00000000; + ip_address.nxd_ip_address.v6[1] = 0x00000000; + ip_address.nxd_ip_address.v6[2] = 0x00000000; + ip_address.nxd_ip_address.v6[3] = 0x00000000; + + /* Set the IPv6 address with NULL prefix length pointer. */ + status = nxd_ipv6_address_set(&ip_0, 0, &ip_address, 64, &address_index); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxde_ipv6_default_router_add api */ + /************************************************/ + + /* Set the router IPv6 address. */ + router_addr.nxd_ip_version = NX_IP_VERSION_V6; + router_addr.nxd_ip_address.v6[0] = 0x20010000; + router_addr.nxd_ip_address.v6[1] = 0x00000000; + router_addr.nxd_ip_address.v6[2] = 0x00000000; + router_addr.nxd_ip_address.v6[3] = 0x00000001; + + /* Add the default router address with NULL IP instance. */ + status = nxd_ipv6_default_router_add(NX_NULL, &router_addr, 1000, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Add the default router address with invalid IP instance. */ + status = nxd_ipv6_default_router_add(&invalid_ip, &router_addr, 1000, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Add the default router address with NULL router address pointer. */ + status = nxd_ipv6_default_router_add(&ip_0, NX_NULL, 1000, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 address with invalid address version. */ + router_addr.nxd_ip_version = NX_IP_VERSION_V4; + + /* Add the default router address with invalid address version. */ + status = nxd_ipv6_default_router_add(&ip_0, &router_addr, 1000, 0); + + /* Check for error. */ + if (status != NX_INVALID_PARAMETERS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the IPv6 address version. */ + router_addr.nxd_ip_version = NX_IP_VERSION_V6; + + /* Add the default router address with invalid interface index. */ + status = nxd_ipv6_default_router_add(&ip_0, &router_addr, 1000, NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Add the default router address with invalid interface index. */ + status = nxd_ipv6_default_router_add(&ip_0, &router_addr, 1000, 1); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***************************************************/ + /* Tested the nxde_ipv6_default_router_delete api */ + /***************************************************/ + + /* Set the router IPv6 address. */ + router_addr.nxd_ip_version = NX_IP_VERSION_V6; + router_addr.nxd_ip_address.v6[0] = 0x20010000; + router_addr.nxd_ip_address.v6[1] = 0x00000000; + router_addr.nxd_ip_address.v6[2] = 0x00000000; + router_addr.nxd_ip_address.v6[3] = 0x00000001; + + /* Delete the default router address with NULL IP instance. */ + status = nxd_ipv6_default_router_delete(NX_NULL, &router_addr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Delete the default router address with invalid IP instance. */ + status = nxd_ipv6_default_router_delete(&invalid_ip, &router_addr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the default router address with NULL router address pointer. */ + status = nxd_ipv6_default_router_delete(&ip_0, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 address with invalid address version. */ + router_addr.nxd_ip_version = NX_IP_VERSION_V4; + + /* Delete the default router address with invalid address version. */ + status = nxd_ipv6_default_router_delete(&ip_0, &router_addr); + + /* Check for error. */ + if (status != NX_INVALID_PARAMETERS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /*****************************************************/ + /* Tested the nxde_ipv6_default_router_entry_get api */ + /*****************************************************/ + + /* Get the default router address with NULL IP instance. */ + status = nxd_ipv6_default_router_entry_get(NX_NULL, 0, 0, &router_addr, &router_lifetime, &prefix_length, &configuration_method); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the default router address with invalid IP instance. */ + status = nxd_ipv6_default_router_entry_get(&invalid_ip, 0, 0, &router_addr, &router_lifetime, &prefix_length, &configuration_method); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the default router address with invalid interface index. */ + status = nxd_ipv6_default_router_entry_get(&ip_0, NX_MAX_PHYSICAL_INTERFACES, 0, &router_addr, &router_lifetime, &prefix_length, &configuration_method); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the default router address with invalid entry index. */ + status = nxd_ipv6_default_router_entry_get(&ip_0, 0, NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE, &router_addr, &router_lifetime, &prefix_length, &configuration_method); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /*****************************************************/ + /* Tested the nxde_ipv6_default_router_get api */ + /*****************************************************/ + + /* Get the default router address with NULL IP instance. */ + status = nxd_ipv6_default_router_get(NX_NULL, 0, &router_addr, &router_lifetime, &prefix_length); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the default router address with invalid IP instance. */ + status = nxd_ipv6_default_router_get(&invalid_ip, 0, &router_addr, &router_lifetime, &prefix_length); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the default router address with NULL router address pointer. */ + status = nxd_ipv6_default_router_get(&ip_0, 0, NX_NULL, &router_lifetime, &prefix_length); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the default router address with NULL router lifetime pointer. */ + status = nxd_ipv6_default_router_get(&ip_0, 0, &router_addr, NX_NULL, &prefix_length); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the default router address with NULL prefix length. */ + status = nxd_ipv6_default_router_get(&ip_0, 0, &router_addr, &router_lifetime, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the default router address with invalid interface index. */ + status = nxd_ipv6_default_router_get(&ip_0, NX_MAX_PHYSICAL_INTERFACES, &router_addr, &router_lifetime, &prefix_length); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /*****************************************************************/ + /* Tested the nxde_ipv6_default_router_number_of_entries_get api */ + /*****************************************************************/ + + /* Get the default router number with NULL IP instance. */ + status = nxd_ipv6_default_router_number_of_entries_get(NX_NULL, 0, &num_entries); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the default router number with invalid IP instance. */ + status = nxd_ipv6_default_router_number_of_entries_get(&invalid_ip, 0, &num_entries); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the default router number with NULL num entries pointer. */ + status = nxd_ipv6_default_router_number_of_entries_get(&ip_0, 0, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the default router address with invalid interface index. */ + status = nxd_ipv6_default_router_number_of_entries_get(&ip_0, NX_MAX_PHYSICAL_INTERFACES, &num_entries); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxde_ipv6_disable api */ + /************************************************/ + + /* Disable the IPv6 feature with NULL IP instance. */ + status = nxd_ipv6_disable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Disable the IPv6 feature with invalid IP instance. */ + status = nxd_ipv6_disable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxde_ipv6_enable api */ + /************************************************/ + + /* Enable the IPv6 feature with NULL IP instance. */ + status = nxd_ipv6_enable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Enable the IPv6 feature with invalid IP instance. */ + status = nxd_ipv6_enable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_IPV6_MULTICAST + /*************************************************************/ + /* Tested the nxde_ipv6_multicast_interface_join api */ + /*************************************************************/ + + /* Set the IPv6 Multicast group address. */ + group_address.nxd_ip_version = NX_IP_VERSION_V6; + group_address.nxd_ip_address.v6[0] = 0xFF020000; + group_address.nxd_ip_address.v6[1] = 0x00000000; + group_address.nxd_ip_address.v6[2] = 0x00000000; + group_address.nxd_ip_address.v6[3] = 0x000000FB; + + /* Join the IPv6 multicast group with NULL IP instance. */ + status = nxd_ipv6_multicast_interface_join(NX_NULL, &group_address, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Join the IPv6 multicast group with invalid IP instance. */ + status = nxd_ipv6_multicast_interface_join(&invalid_ip, &group_address, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Join the IPv6 multicast group with NULL group address pointer. */ + status = nxd_ipv6_multicast_interface_join(&ip_0, NX_NULL, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the invalid multicast address. */ + group_address.nxd_ip_version = NX_IP_VERSION_V6; + group_address.nxd_ip_address.v6[0] = 0x20010000; + group_address.nxd_ip_address.v6[1] = 0x00000000; + group_address.nxd_ip_address.v6[2] = 0x00000000; + group_address.nxd_ip_address.v6[3] = 0x00001234; + + /* Join the IPv6 multicast group with invalid multicast address. */ + status = nxd_ipv6_multicast_interface_join(&ip_0, &group_address, 0); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the IPv6 Multicast group address. */ + group_address.nxd_ip_version = NX_IP_VERSION_V6; + group_address.nxd_ip_address.v6[0] = 0xFF020000; + group_address.nxd_ip_address.v6[1] = 0x00000000; + group_address.nxd_ip_address.v6[2] = 0x00000000; + group_address.nxd_ip_address.v6[3] = 0x000000FB; + + /* Join the IPv6 multicast group with invalid interface index. */ + status = nxd_ipv6_multicast_interface_join(&ip_0, &group_address, NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Join the IPv6 multicast group with invalid interface index. */ + status = nxd_ipv6_multicast_interface_join(&ip_0, &group_address, 1); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /*************************************************************/ + /* Tested the nxde_ipv6_multicast_interface_leave api */ + /*************************************************************/ + + /* Set the IPv6 Multicast group address. */ + group_address.nxd_ip_version = NX_IP_VERSION_V6; + group_address.nxd_ip_address.v6[0] = 0xFF020000; + group_address.nxd_ip_address.v6[1] = 0x00000000; + group_address.nxd_ip_address.v6[2] = 0x00000000; + group_address.nxd_ip_address.v6[3] = 0x000000FB; + + /* Leave the IPv6 multicast group with NULL IP instance. */ + status = nxd_ipv6_multicast_interface_leave(NX_NULL, &group_address, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Leave the IPv6 multicast group with invalid IP instance. */ + status = nxd_ipv6_multicast_interface_leave(&invalid_ip, &group_address, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Leave the IPv6 multicast group with NULL group address pointer. */ + status = nxd_ipv6_multicast_interface_leave(&ip_0, NX_NULL, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the invalid multicast address. */ + group_address.nxd_ip_version = NX_IP_VERSION_V6; + group_address.nxd_ip_address.v6[0] = 0x20010000; + group_address.nxd_ip_address.v6[1] = 0x00000000; + group_address.nxd_ip_address.v6[2] = 0x00000000; + group_address.nxd_ip_address.v6[3] = 0x00001234; + + /* Leave the IPv6 multicast group with invalid multicast address. */ + status = nxd_ipv6_multicast_interface_leave(&ip_0, &group_address, 0); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the IPv6 Multicast group address. */ + group_address.nxd_ip_version = NX_IP_VERSION_V6; + group_address.nxd_ip_address.v6[0] = 0xFF020000; + group_address.nxd_ip_address.v6[1] = 0x00000000; + group_address.nxd_ip_address.v6[2] = 0x00000000; + group_address.nxd_ip_address.v6[3] = 0x000000FB; + + /* Leave the IPv6 multicast group with invalid interface index. */ + status = nxd_ipv6_multicast_interface_leave(&ip_0, &group_address, NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifdef NX_IPV6_STATELESS_AUTOCONFIG_CONTROL + /*****************************************************************/ + /* Tested the nxde_ipv6_stateless_address_autoconfig_disable api */ + /*****************************************************************/ + + /* Disable the IPv6 stateless address autoconfig feature with NULL IP instance. */ + status = nxd_ipv6_stateless_address_autoconfig_disable(NX_NULL, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Disable the IPv6 stateless address autoconfig feature with invalid IP instance. */ + status = nxd_ipv6_stateless_address_autoconfig_disable(&invalid_ip, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the IPv6 stateless address autoconfig feature with invalid interface index. */ + status = nxd_ipv6_stateless_address_autoconfig_disable(&ip_0, NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /*****************************************************************/ + /* Tested the nxde_ipv6_stateless_address_autoconfig_enable api */ + /*****************************************************************/ + + /* Enable the IPv6 stateless address autoconfig feature with NULL IP instance. */ + status = nxd_ipv6_stateless_address_autoconfig_enable(NX_NULL, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Enable the IPv6 stateless address autoconfig feature with invalid IP instance. */ + status = nxd_ipv6_stateless_address_autoconfig_enable(&invalid_ip, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the IPv6 stateless address autoconfig feature with invalid interface index. */ + status = nxd_ipv6_stateless_address_autoconfig_enable(&ip_0, NX_MAX_PHYSICAL_INTERFACES); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 NXE API Test.........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_packet_chain_test.c b/test/regression/netxduo_test/netx_ipv6_packet_chain_test.c new file mode 100644 index 00000000..ef374473 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_packet_chain_test.c @@ -0,0 +1,346 @@ +/* Test processing of packet chain. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_PACKET_CHAIN) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG icmp_counter; +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_packet_chain_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ICMPv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Packet Chain Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set the callback function to get the IPv6 packet. */ + ip_1.nx_ipv6_packet_receive = my_packet_process; + + /* Ping an IP address that does exist. */ + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if ((status == NX_SUCCESS) || (my_packet)) + { +#if defined(NX_ENABLE_INTERFACE_CAPABILITY) + printf("ERROR!\n"); + test_control_return(1); +#endif + } + + /* Check the error counter and icmp counter. */ + if ((error_counter) || (icmp_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static VOID my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +UINT status; +NX_PACKET *my_packet_1; +NX_PACKET *my_packet_2; +NX_PACKET *my_packet_3; +NX_IPV6_HEADER *ip_header_ptr; + + + /* Check the packet length. */ + if (packet_ptr ->nx_packet_length == 76) // 28(DATA) + 8(ICMP HEADER) + 40(IPV6 HEADER) + { + + /* Get the ICMP packet. */ + icmp_counter ++; + + /***************************************************************************/ + /* nx_packet_length > pkt_length for chain packet nx_ipv6_packet_receive() */ + /* last packet < delta, two packet chain. */ + /***************************************************************************/ + + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, &my_packet_1, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter ++; + + /* Get the IPv6 header. */ + ip_header_ptr = (NX_IPV6_HEADER *)my_packet_1 -> nx_packet_prepend_ptr; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /* Modified the packet length. */ + ip_header_ptr -> nx_ip_header_word_1 -= 0x00040000; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet_2, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet_2 -> nx_packet_prepend_ptr, "ABC", 3); + + /* Adjust the write pointer. bigger than 256 to cause fragmentation. */ + my_packet_2 -> nx_packet_length = 3; + my_packet_2 -> nx_packet_append_ptr = my_packet_2 -> nx_packet_prepend_ptr + 3; + + /* Chain the packet. */ + my_packet_1 -> nx_packet_next = my_packet_2; + my_packet_1 -> nx_packet_last = my_packet_2; + + /* Call the _nx_ipv6_packet_receive function directly receive this packet. */ + _nx_ipv6_packet_receive(&ip_1, my_packet_1); + + /***************************************************************************/ + /* nx_packet_length > pkt_length for chain packet nx_ipv6_packet_receive() */ + /* last packet < delta, three packet chain */ + /***************************************************************************/ + + /* Copy the packet. */ + status = nx_packet_copy(packet_ptr, &my_packet_1, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status) + error_counter ++; + + /* Get the IPv6 header. */ + ip_header_ptr = (NX_IPV6_HEADER *)my_packet_1 -> nx_packet_prepend_ptr; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /* Modified the packet length. */ + ip_header_ptr -> nx_ip_header_word_1 -= 0x00040000; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet_2, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet_2 -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26); + + /* Adjust the write pointer. bigger than 256 to cause fragmentation. */ + my_packet_2 -> nx_packet_length = 26; + my_packet_2 -> nx_packet_append_ptr = my_packet_2 -> nx_packet_prepend_ptr + 26; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet_3, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet_3 -> nx_packet_prepend_ptr, "ABC", 3); + + /* Adjust the write pointer. bigger than 256 to cause fragmentation. */ + my_packet_3 -> nx_packet_length = 3; + my_packet_3 -> nx_packet_append_ptr = my_packet_3 -> nx_packet_prepend_ptr + 3; + + /* Chain the packet. */ + my_packet_1 -> nx_packet_next = my_packet_2; + my_packet_1 -> nx_packet_last = my_packet_3; + my_packet_2 -> nx_packet_next = my_packet_3; + + /* Call the _nx_ipv6_packet_receive function directly receive this packet. */ + _nx_ipv6_packet_receive(&ip_1, my_packet_1); + + /***************************************************************************/ + /* nx_packet_length > pkt_length for chain packet nx_ipv6_packet_receive() */ + /* last packet < delta, while(delta == 0). */ + /***************************************************************************/ + + /* Get the IPv6 header. */ + ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /* Modified the packet length. */ + ip_header_ptr -> nx_ip_header_word_1 -= 0x00030000; + + /* Convert to host byte order. */ + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet_1, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet_1 -> nx_packet_prepend_ptr, "ABC", 3); + + /* Adjust the write pointer. bigger than 256 to cause fragmentation. */ + my_packet_1 -> nx_packet_length = 3; + my_packet_1 -> nx_packet_append_ptr = my_packet_1 -> nx_packet_prepend_ptr + 3; + + /* Chain the packet. */ + packet_ptr -> nx_packet_next = my_packet_1; + packet_ptr -> nx_packet_last = my_packet_1; + } + + /* Call the _nx_ipv6_packet_receive function directly receive this packet. */ + _nx_ipv6_packet_receive(&ip_1, packet_ptr); + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_packet_chain_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Packet Chain Test....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_pmtu_test.c b/test/regression/netxduo_test/netx_ipv6_pmtu_test.c new file mode 100644 index 00000000..9882528a --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_pmtu_test.c @@ -0,0 +1,650 @@ +/* This test case is modified from IPv6 TAHI 4-13. + * It aims to test PMTU when NA is received. */ + +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +static char pkt5[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0xa4, 0x26, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, /* .&...x.. */ +0x75, 0x30, 0x00, 0x00, 0x03, 0xe8, 0x05, 0x01, /* u0...... */ +0x00, 0x00, 0x00, 0x00, 0x05, 0xdc, 0x03, 0x04, /* ........ */ +0x40, 0xc0, 0x00, 0x27, 0x8d, 0x00, 0x00, 0x09, /* @..'.... */ +0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* :.....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +static char pkt6[] = { +0x33, 0x33, 0xff, 0x33, 0x44, 0x56, 0x00, 0x11, +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x18, 0x3a, 0xff, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0xff, 0x33, 0x44, 0x56, 0x87, 0x00, +0x88, 0x85, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56 }; + +static char pkt9[86] = { +0x33, 0x33, 0xff, 0x00, 0x01, 0x00, 0x00, 0x11, /* 33...... */ +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, /* "3DV..`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0x3f, 0xfe, /* ... :.?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0xff, 0x02, /* "..3DV.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0xff, 0x00, 0x01, 0x00, 0x87, 0x00, /* ........ */ +0x63, 0xea, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x80, /* c....... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x01, 0x01, /* ........ */ +0x00, 0x11, 0x22, 0x33, 0x44, 0x56 /* .."3DV */ +}; + +static char pkt10[86] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, /* .."3DV.. */ +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x20, 0x3a, 0xff, 0xfe, 0x80, /* ... :... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x88, 0x00, /* "..3DV.. */ +0xe6, 0x07, 0xe0, 0x00, 0x00, 0x00, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0x02, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x01, 0x00 /* ...... */ +}; + +static char pkt14[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x18, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, +0x45, 0x1b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, +0x27, 0x10, 0x00, 0x00, 0x03, 0xe8, 0x05, 0x01, +0x00, 0x00, 0x00, 0x00, 0x05, 0x00 }; + +static char pkt15[] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x04, 0xd8, 0x2c, 0x40, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x02, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0xa2, 0xa2, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x3a, 0x00, +0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x80, 0x00, +0x55, 0x45, 0xff, 0xff, 0x00, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05 }; + +static char pkt16[] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0xec, 0x2c, 0x40, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x02, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0xa2, 0xa2, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x3a, 0x00, +0x04, 0xd0, 0x00, 0x00, 0x01, 0x00, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06 }; + +static char pkt17[] = { +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x11, +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x04, 0xd8, 0x2c, 0xff, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x02, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0xa2, 0xa2, 0x3a, 0x00, +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x81, 0x00, +0x54, 0x45, 0xff, 0xff, 0x00, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, +0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05 }; + +static char pkt18[] = { +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x11, +0x22, 0x33, 0x44, 0x56, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0xec, 0x2c, 0xff, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x02, 0x11, +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x02, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0xa2, 0xa2, 0x3a, 0x00, +0x04, 0xd0, 0x00, 0x00, 0x00, 0x01, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, +0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, +0x06, 0x06 }; + +static TAHI_TEST_SEQ pmtu_seq[] = { + {WAIT, NX_NULL, 0, 3}, + + {INJECT, &pkt5[0], sizeof(pkt5), 0}, + {INJECT, &pkt14[0], sizeof(pkt14), 0}, + {CHECK, &pkt6[0], sizeof(pkt6), 1}, + {WAIT, NX_NULL, 0, 3}, + + {INJECT, &pkt15[0], sizeof(pkt15), 0}, + {INJECT, &pkt16[0], sizeof(pkt16), 0}, + {CHECK, &pkt9[0], sizeof(pkt9), 1}, + {INJECT, &pkt10[0], sizeof(pkt10), 0}, + {CHECK, &pkt17[0], sizeof(pkt17), 1}, + {CHECK, &pkt18[0], sizeof(pkt18), 1}, + + {CLEANUP, NX_NULL, 0, 0}, + {DUMP, NX_NULL, 0, 0} +}; + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &pmtu_seq[0];test_suite[0].test_case_size = sizeof(pmtu_seq) / sizeof(TAHI_TEST_SEQ); +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_pmtu_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + printf("NetX Test: IPv6 PMTU Test............................................"); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_pmtu_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 PMTU Test............................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_prefix_test.c b/test/regression/netxduo_test/netx_ipv6_prefix_test.c new file mode 100644 index 00000000..371a6066 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_prefix_test.c @@ -0,0 +1,407 @@ +/* Test IPv6 prefix with length not equal 64. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && (NX_IPV6_PREFIX_LIST_TABLE_SIZE == 8) + +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* RA packet with prefix length 128. */ +static char pkt_prefix_128[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, +0xed, 0xeb, 0x40, 0x00, 0x07, 0x0d, 0x00, 0x00, +0x75, 0x35, 0x00, 0x00, 0x03, 0xed, 0x01, 0x01, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x04, +0x80, 0xc0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +/* RA packet with prefix length 120. */ +static char pkt_prefix_120[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, +0xf5, 0xeb, 0x40, 0x00, 0x07, 0x0d, 0x00, 0x00, +0x75, 0x35, 0x00, 0x00, 0x03, 0xed, 0x01, 0x01, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x04, +0x78, 0xc0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +/* RA packet with prefix length 100. */ +static char pkt_prefix_100[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x57, 0x01, 0x40, 0x00, 0x00, 0x14, 0x00, 0x01, /* W.@..... */ +0x86, 0xa0, 0x00, 0x00, 0x03, 0xe8, 0x05, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x05, 0xdc, 0x03, 0x04, /* ........ */ +0x64, 0xc0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, /* d....... */ +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* RA packet with prefix length 96. */ +static char pkt_prefix_96[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x5b, 0x01, 0x40, 0x00, 0x00, 0x14, 0x00, 0x01, /* [.@..... */ +0x86, 0xa0, 0x00, 0x00, 0x03, 0xe8, 0x05, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x05, 0xdc, 0x03, 0x04, /* ........ */ +0x60, 0xc0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, /* `....... */ +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* RA packet with prefix length 92. */ +static char pkt_prefix_92[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x5f, 0x01, 0x40, 0x00, 0x00, 0x14, 0x00, 0x01, /* _.@..... */ +0x86, 0xa0, 0x00, 0x00, 0x03, 0xe8, 0x05, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x05, 0xdc, 0x03, 0x04, /* ........ */ +0x5c, 0xc0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, /* \....... */ +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* RA packet with prefix length 88. */ +static char pkt_prefix_88[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, /* ........ */ +0x63, 0x01, 0x40, 0x00, 0x00, 0x14, 0x00, 0x01, /* c.@..... */ +0x86, 0xa0, 0x00, 0x00, 0x03, 0xe8, 0x05, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x05, 0xdc, 0x03, 0x04, /* ........ */ +0x58, 0xc0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, /* X....... */ +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* ......?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* RA packet with prefix length 64. */ +static char pkt_prefix_64[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, +0x2d, 0xf6, 0x40, 0x00, 0x07, 0x0d, 0x00, 0x00, +0x75, 0x35, 0x00, 0x00, 0x03, 0xed, 0x01, 0x01, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x04, +0x40, 0xc0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, +0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +/* RA packet with prefix length 0. */ +static char pkt_prefix_0[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, +0x6d, 0xec, 0x40, 0x00, 0x07, 0x0d, 0x00, 0x00, +0x75, 0x35, 0x00, 0x00, 0x03, 0xed, 0x01, 0x01, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x04, +0x00, 0xc0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +/* RA packet with prefix length 64. */ +static char pkt_prefix_full[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, +0x2d, 0xe6, 0x40, 0x00, 0x07, 0x0d, 0x00, 0x00, +0x75, 0x35, 0x00, 0x00, 0x03, 0xed, 0x01, 0x01, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x04, +0x40, 0xc0, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, +0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_prefix_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *packet_ptr; +NX_IPV6_PREFIX_ENTRY *current_prefix; +UINT i; +CHAR *pkt_data[] = {pkt_prefix_64, pkt_prefix_128, + pkt_prefix_0, pkt_prefix_120, + pkt_prefix_100, pkt_prefix_96, + pkt_prefix_92, pkt_prefix_88, pkt_prefix_full}; +UINT pkt_len[] = {sizeof(pkt_prefix_64), sizeof(pkt_prefix_128), + sizeof(pkt_prefix_0), sizeof(pkt_prefix_120), + sizeof(pkt_prefix_100), sizeof(pkt_prefix_96), + sizeof(pkt_prefix_92), sizeof(pkt_prefix_88), sizeof(pkt_prefix_full)}; +ULONG prefix_len[] = {128, 120, 100, 96, 92, 88, 64, 0}; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Prefix Test.........................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + for (i = 0; i < sizeof(pkt_data) / sizeof(CHAR *); i++) + { + + /* Inject RA with prefix length 64. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt_data[i][14], pkt_len[i] - 14); + packet_ptr -> nx_packet_length = pkt_len[i] - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + if (i == 0) + { + + /* Sleep one second and let prefix 64 bits timeout first. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + } + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the first global address. */ + status = nxd_ipv6_address_get(&ip_0, address_index + 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 64) || (interface_index != 0)) + error_counter++; + + /* Get the second global address. */ + status = nxd_ipv6_address_get(&ip_0, address_index + 2, &ipv6_address, &prefix_length, &interface_index); + + /* No IPv6 address should be formed since prefix length is not 64. */ + if (status != NX_NO_INTERFACE_ADDRESS) + { + error_counter++; + } + + /* Check prefix list. It should be linked from largest to smallest. */ + current_prefix = ip_0.nx_ipv6_prefix_list_ptr; + + for (i = 0; i < sizeof(prefix_len) / sizeof(ULONG); i++) + { + + /* Check length of prefix. */ + if (current_prefix) + { + if (current_prefix -> nx_ipv6_prefix_entry_prefix_length != prefix_len[i]) + { + error_counter++; + break; + } + + /* Move to next prefix entry. */ + current_prefix = current_prefix -> nx_ipv6_prefix_entry_next; + } + else + { + error_counter++; + break; + } + } + + /* No more prefix. */ + if (current_prefix) + { + error_counter++; + } + + /* Sleep 30 seconds for prefix timeout. */ + tx_thread_sleep(30 * NX_IP_PERIODIC_RATE); + + /* All prefixes are timeout. */ + if (ip_0.nx_ipv6_prefix_list_ptr != NX_NULL) + { + error_counter++; + } + + /* Check the error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_prefix_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Prefix Test..........................................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_ipv6_raw_packet_test.c b/test/regression/netxduo_test/netx_ipv6_raw_packet_test.c new file mode 100644 index 00000000..29de4ddd --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_raw_packet_test.c @@ -0,0 +1,389 @@ +/* This NetX test concentrates on the raw packet IPv6 send/receive operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) +#include "nx_tcp.h" +#include "nx_udp.h" +#include "nx_ip.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +static NXD_ADDRESS ipv6_addr_0; +static NXD_ADDRESS ipv6_addr_1; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_raw_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status != NX_SUCCESS) + error_counter++; + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status != NX_SUCCESS) + error_counter++; + + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 10), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status != NX_SUCCESS) + error_counter++; + +#ifndef NX_DISABLE_IPV4 + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status != NX_SUCCESS) + error_counter++; + + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status != NX_SUCCESS) + error_counter++; +#endif + + /* Enable UDP for IP instances. */ + status = nx_udp_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_udp_enable(&ip_1); + if (status != NX_SUCCESS) + error_counter++; + + ipv6_addr_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_addr_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_addr_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_addr_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_addr_0.nxd_ip_address.v6[3] = 0x00010001; + + ipv6_addr_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_addr_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_addr_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_addr_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_addr_1.nxd_ip_address.v6[3] = 0x00010002; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + status = nxd_ipv6_enable(&ip_1); + if (status != NX_SUCCESS) + error_counter++; + + status = nxd_icmp_enable(&ip_0); + if(status != NX_SUCCESS) + error_counter++; + + status = nxd_icmp_enable(&ip_1); + if(status) + error_counter++; + + status = nx_ip_raw_packet_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_ip_raw_packet_enable(&ip_1); + if (status != NX_SUCCESS) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG value; + + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Raw Packet Test......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_addr_0, 64, NX_NULL); + if(status != NX_SUCCESS) + error_counter++; + + /* DAD */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_INITIALIZE_DONE)) + error_counter++; + + /* Now, pickup the three raw packets that should be queued on the other IP instance. */ + status = nx_ip_raw_packet_receive(&ip_0, &my_packet, 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + error_counter++; + + status = nx_packet_release(my_packet); + if (status != NX_SUCCESS) + error_counter++; + +#ifndef NX_DISABLE_IPV4 + /* Receive the second packet. */ + status = nx_ip_raw_packet_receive(&ip_0, &my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + error_counter++; + + status = nx_packet_release(my_packet); + if (status != NX_SUCCESS) + error_counter++; +#endif + + /* Receive the third packet. */ + status = nx_ip_raw_packet_receive(&ip_0, &my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + error_counter++; + + status = nx_packet_release(my_packet); + if (status != NX_SUCCESS) + error_counter++; + + /* Receive the last packet. */ + status = nx_ip_raw_packet_receive(&ip_0, &my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + error_counter++; + + status = nx_packet_release(my_packet); + if (status != NX_SUCCESS) + error_counter++; + + /* Attempt to receive a packet on an empty queue.... should be an error. */ + status = nx_ip_raw_packet_receive(&ip_0, &my_packet, NX_IP_PERIODIC_RATE); + + if (status != NX_NO_PACKET) + error_counter++; + + /* Suspend thread_0 to let thread_1 disable the raw, which will call raw_packet_cleanup */ + nx_ip_raw_packet_receive(&ip_0, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +ULONG value; +NXD_ADDRESS dest_addr; + + + status = nxd_ipv6_address_set(&ip_1, 0, &ipv6_addr_1, 64, NX_NULL); + if(status != NX_SUCCESS) + error_counter++; + + /* DAD */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE); + + /* Check for an error. */ + if ((status) || (value != NX_IP_INITIALIZE_DONE)) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the raw IP packet. */ + status = nxd_ip_raw_packet_send(&ip_1, my_packet, &ipv6_addr_0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + +#ifndef NX_DISABLE_IPV4 + /* Allocate another packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + dest_addr.nxd_ip_version = NX_IP_VERSION_V4; + dest_addr.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 9); + + /* Send the second raw IP packet. */ + status = nxd_ip_raw_packet_source_send(&ip_1, my_packet, &dest_addr, 0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; +#endif + + /* Allocate another packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + + /* Send the third raw IP packet. */ + status = nxd_ip_raw_packet_send(&ip_1, my_packet, &ipv6_addr_0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the raw IP packet using API without error checking. */ + status = _nxd_ip_raw_packet_send(&ip_1, my_packet, &ipv6_addr_0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + status = nx_ip_raw_packet_disable(&ip_0); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_raw_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Raw Packet Test......................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_search_onlink_test.c b/test/regression/netxduo_test/netx_ipv6_search_onlink_test.c new file mode 100644 index 00000000..f8de7a0d --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_search_onlink_test.c @@ -0,0 +1,481 @@ +/* This NetX test to test the IPv6 onlink search. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#ifdef FEATURE_NX_IPV6 +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +static NXD_ADDRESS test_address; +static NXD_ADDRESS prefix_0; /* 1111:0001:1000:0003::/64 */ +static NXD_ADDRESS prefix_1; /* 2222:1111:1001:1002::/63 */ +static NXD_ADDRESS prefix_2; /* 3333:0001:1234:1002:1234::/72 */ + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_search_onlink_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*4); + pointer = pointer + 1536*4; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + + /* Enable ICMP for IP Instance 0. */ + status += nxd_icmp_enable(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT i; +UINT status; +UINT address1_index, address2_index; +UINT prefix_length; +NXD_ADDRESS temp_prefix; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Search Onlink Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* prefix_0: 1111:0001:1000:0003::/64 */ + prefix_0.nxd_ip_address.v6[0] = 0x11110001; + prefix_0.nxd_ip_address.v6[1] = 0x10000003; + prefix_0.nxd_ip_address.v6[2] = 0; + prefix_0.nxd_ip_address.v6[3] = 0; + + /* prefix_1: 2222:1111:1001:1002::/63 */ + prefix_1.nxd_ip_address.v6[0] = 0x22221111; + prefix_1.nxd_ip_address.v6[1] = 0x10011002; + prefix_1.nxd_ip_address.v6[2] = 0; + prefix_1.nxd_ip_address.v6[3] = 0; + + /* prefix_2: 3333:0001:1234:1002:1234::/72 */ + prefix_2.nxd_ip_address.v6[0] = 0x33330001; + prefix_2.nxd_ip_address.v6[1] = 0x12341002; + prefix_2.nxd_ip_address.v6[2] = 0x12000000; + prefix_2.nxd_ip_address.v6[3] = 0; + + status = _nx_ipv6_prefix_list_add_entry(&ip_0, &prefix_0.nxd_ip_address.v6[0], 64, 1800); + status += _nx_ipv6_prefix_list_add_entry(&ip_0, &prefix_1.nxd_ip_address.v6[0], 63, 1800); + status += _nx_ipv6_prefix_list_add_entry(&ip_0, &prefix_2.nxd_ip_address.v6[0], 72, 1800); + + if(status) + error_counter++; + + /* Manually configure an IPv6 address that is on the prefix list */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x33330001; + ipv6_address_1.nxd_ip_address.v6[1] = 0x12341002; + ipv6_address_1.nxd_ip_address.v6[2] = 0x12340000; + ipv6_address_1.nxd_ip_address.v6[3] = 1; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 72, &address1_index); + + /* Manually configure an IPv6 address that is NOT on the prefix list */ + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x44440000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x12341002; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 1; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_2, 71, &address2_index); + if(status) + error_counter++; + + /* Test an onlink entry. */ + test_address.nxd_ip_address.v6[0] = 0x11110001; + test_address.nxd_ip_address.v6[1] = 0x10000003; + test_address.nxd_ip_address.v6[2] = 0; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + /* Modify the previous test to make it offlink. */ + test_address.nxd_ip_address.v6[0] = 0x11110001; + test_address.nxd_ip_address.v6[1] = 0x10000002; + test_address.nxd_ip_address.v6[2] = 0; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status == 1) + error_counter++; + + /* Test the 2nd onlink entry */ + test_address.nxd_ip_address.v6[0] = 0x22221111; + test_address.nxd_ip_address.v6[1] = 0x10011002; + test_address.nxd_ip_address.v6[2] = 0; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + /* This one should also be onlink */ + test_address.nxd_ip_address.v6[0] = 0x22221111; + test_address.nxd_ip_address.v6[1] = 0x10011003; + test_address.nxd_ip_address.v6[2] = 0; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + + /* This one should be offlink */ + test_address.nxd_ip_address.v6[0] = 0x22221111; + test_address.nxd_ip_address.v6[1] = 0x10011006; + test_address.nxd_ip_address.v6[2] = 0; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 0) + error_counter++; + + /* Test the 3rd onlink entry */ + test_address.nxd_ip_address.v6[0] = 0x33330001; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x12000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + + /* This one should also be onlink. */ + test_address.nxd_ip_address.v6[0] = 0x33330001; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x12800000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + /* This one should also be offlink. */ + test_address.nxd_ip_address.v6[0] = 0x33330001; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x13000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 0) + error_counter++; + + + /* Test the manually configured one. */ + test_address.nxd_ip_address.v6[0] = 0x44440000; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x01000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + /* Test the manually configured one. */ + test_address.nxd_ip_address.v6[0] = 0x44440000; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x00800000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + /* Test the manually configured one. This one should be offlink. */ + test_address.nxd_ip_address.v6[0] = 0x44440000; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x02000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 0) + error_counter++; + + /* Test the manually configured one. This one should be onlink. */ + test_address.nxd_ip_address.v6[0] = 0x44440000; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x01000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + + /* Delete the 3rd onlink entry. */ + _nx_ipv6_prefix_list_delete(&ip_0, &prefix_2.nxd_ip_address.v6[0], 72); + + /* Test the 3rd onlink entry */ + test_address.nxd_ip_address.v6[0] = 0x33330001; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x12000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + /* Make sure the 1st and the 2nd prefix entry is still there. */ + test_address.nxd_ip_address.v6[0] = 0x11110001; + test_address.nxd_ip_address.v6[1] = 0x10000003; + test_address.nxd_ip_address.v6[2] = 0; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + /* Test the 2nd onlink entry */ + test_address.nxd_ip_address.v6[0] = 0x22221111; + test_address.nxd_ip_address.v6[1] = 0x10011002; + test_address.nxd_ip_address.v6[2] = 0; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + /* Now delete 1st and 2nd, and then make sure they are indeed removed. */ + _nx_ipv6_prefix_list_delete(&ip_0, &prefix_1.nxd_ip_address.v6[0], 63); + _nx_ipv6_prefix_list_delete(&ip_0, &prefix_0.nxd_ip_address.v6[0], 64); + + /* The first prefix should still be there because it is also set manually. */ + test_address.nxd_ip_address.v6[0] = 0x33330001; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x12000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + /* Test the 2nd onlink entry */ + test_address.nxd_ip_address.v6[0] = 0x22221111; + test_address.nxd_ip_address.v6[1] = 0x10011002; + test_address.nxd_ip_address.v6[2] = 0; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 0) + error_counter++; + + + /* Make sure the manually configured entry is still there. */ + test_address.nxd_ip_address.v6[0] = 0x44440000; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x01000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + /* Now delete the 1st manually configured IPv6 address, verify that the 1st prefix is + no longer onlink but the 2nd manually configure IPv6 address is onlink. */ + nxd_ipv6_address_delete(&ip_0, address1_index); + test_address.nxd_ip_address.v6[0] = 0x33330001; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x12000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 0) + error_counter++; + + test_address.nxd_ip_address.v6[0] = 0x44440000; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x01000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 1) + error_counter++; + + /* delete the 2nd manually configured address, and verify that all the entries are gone. */ + nxd_ipv6_address_delete(&ip_0, address2_index); + test_address.nxd_ip_address.v6[0] = 0x11110001; + test_address.nxd_ip_address.v6[1] = 0x10000003; + test_address.nxd_ip_address.v6[2] = 0; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 0) + error_counter++; + + test_address.nxd_ip_address.v6[0] = 0x22221111; + test_address.nxd_ip_address.v6[1] = 0x10011003; + test_address.nxd_ip_address.v6[2] = 0; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 0) + error_counter++; + + + test_address.nxd_ip_address.v6[0] = 0x33330001; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x12000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 0) + error_counter++; + + test_address.nxd_ip_address.v6[0] = 0x44440000; + test_address.nxd_ip_address.v6[1] = 0x12341002; + test_address.nxd_ip_address.v6[2] = 0x01000000; + test_address.nxd_ip_address.v6[3] = 1; + + status = _nxd_ipv6_search_onlink(&ip_0, &test_address.nxd_ip_address.v6[0]); + if(status != 0) + error_counter++; + + /* temp_prefix: 4444:0001:1234:1002:1200::1/64 */ + temp_prefix.nxd_ip_address.v6[0] = 0x44440001; + temp_prefix.nxd_ip_address.v6[1] = 0x12341002; + temp_prefix.nxd_ip_address.v6[2] = 0x12000000; + temp_prefix.nxd_ip_address.v6[3] = 0x00000001; + + prefix_length = 64; + + /* Loop to add entry with prefix. */ + for (i = 0; i < NX_IPV6_PREFIX_LIST_TABLE_SIZE; i++) + { + + /* Added the entry. */ + status = _nx_ipv6_prefix_list_add_entry(&ip_0, &temp_prefix.nxd_ip_address.v6[0], prefix_length, 1800); + + /* Check the status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Update the address. */ + temp_prefix.nxd_ip_address.v6[0]++; + + if (i % 2) + prefix_length = 64 + i; + else + prefix_length = 64 - i; + } + } + + /* Added the entry. */ + status = _nx_ipv6_prefix_list_add_entry(&ip_0, &temp_prefix.nxd_ip_address.v6[0], prefix_length, 1800); + + /* Check the status. */ + if (status != NX_OVERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + + test_control_return(0); + } + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_search_onlink_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Search Onlink Test...................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_send_fail_test.c b/test/regression/netxduo_test/netx_ipv6_send_fail_test.c new file mode 100644 index 00000000..5fcca7f7 --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_send_fail_test.c @@ -0,0 +1,295 @@ +/* This NetX test concentrates on failure situation of IPv6 send. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#ifdef FEATURE_NX_IPV6 +#include "nx_nd_cache.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +#ifndef NX_DISABLE_LOOPBACK_INTERFACE +static NXD_ADDRESS lo_address; +static NX_PACKET *consume_packet[20]; +static ULONG consumed; +#endif /* NX_DISABLE_LOOPBACK_INTERFACE */ + +#ifdef NX_DISABLE_FRAGMENTATION +static CHAR send_buffer[256]; +#endif /* NX_DISABLE_FRAGMENTATION */ + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_send_fail_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "Pool 0", 512, pointer, 4096); + pointer = pointer + 4096; + + /* Create a packet pool. */ + status += nx_packet_pool_create(&pool_1, "Pool 1", 512, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Enable ICMP for IP Instance 0 and 1. */ + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + if(status) + error_counter++; + +#ifndef NX_DISABLE_LOOPBACK_INTERFACE + /* Set IPv6 loopback address. */ + lo_address.nxd_ip_version = NX_IP_VERSION_V6; + lo_address.nxd_ip_address.v6[0] = 0x00000000; + lo_address.nxd_ip_address.v6[1] = 0x00000000; + lo_address.nxd_ip_address.v6[2] = 0x00000000; + lo_address.nxd_ip_address.v6[3] = 0x00000001; +#endif /* FEATURE_NX_IPV6 */ +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *pkt_ptr; +NXD_ADDRESS address_1; +NXD_ADDRESS address_unknown; +ULONG prefix_length; +UINT interface_index; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: IPv6 send fail Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set interfaces' address */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, NX_NULL, 10, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Sleep 5 seconds for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + +#ifndef NX_DISABLE_LOOPBACK_INTERFACE + /* Now ping loopback address. */ + status = nxd_icmp_ping(&ip_0, &lo_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &pkt_ptr, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + nx_packet_release(pkt_ptr); + } + + /* Now consume packets from pool_0. */ + consumed = 0; + while (pool_0.nx_packet_pool_available > 1) + { + nx_packet_allocate(&pool_0, &consume_packet[consumed++], 0, NX_NO_WAIT); + } + + /* Now ping loopback address. Only one packet is left so it is not possible to receive the packet. */ + status = nxd_icmp_ping(&ip_0, &lo_address, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &pkt_ptr, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + error_counter++; + nx_packet_release(pkt_ptr); + } + + /* Release consumed packets. */ + while (consumed) + { + consumed--; + nx_packet_release(consume_packet[consumed]); + } +#endif /* NX_DISABLE_LOOPBACK_INTERFACE */ + + /* Get the link local address of ip_1. */ + status = nxd_ipv6_address_get(&ip_1, 0, &address_1, &prefix_length, &interface_index); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Set function pointer of ICMPv6 to NULL. */ + ip_0.nx_ip_icmpv6_packet_process = NX_NULL; + + /* Now ping ip_1's address. ICMPv6 process function pointer is set to NULL. */ + status = nxd_icmp_ping(&ip_0, &address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &pkt_ptr, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + error_counter++; + nx_packet_release(pkt_ptr); + } + + /* Recover function pointer of ICMPv6. */ + ip_0.nx_ip_icmpv6_packet_process = _nx_icmpv6_packet_process; + + /* Now ping ip_1's address. */ + status = nxd_icmp_ping(&ip_0, &address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &pkt_ptr, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + nx_packet_release(pkt_ptr); + } + +#ifdef NX_DISABLE_FRAGMENTATION + /* Now ping ip_1's address. Fragment is disabled but sizeof data is larger than MTU. */ + status = nxd_icmp_ping(&ip_0, &address_1, send_buffer, sizeof(send_buffer), &pkt_ptr, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + error_counter++; + nx_packet_release(pkt_ptr); + } +#endif /* NX_DISABLE_FRAGMENTATION */ + + /* Set an unknown destination. */ + address_unknown.nxd_ip_version = NX_IP_VERSION_V6; + address_unknown.nxd_ip_address.v6[0] = 0xFE800000; + address_unknown.nxd_ip_address.v6[1] = 0x00000000; + address_unknown.nxd_ip_address.v6[2] = 0x00000000; + address_unknown.nxd_ip_address.v6[3] = 0x00000001; + + /* Ping unknow address until ND queue depth. */ + for (i = 0; i <= NX_ND_MAX_QUEUE_DEPTH; i++) + { + status = nxd_icmp_ping(&ip_0, &address_unknown, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &pkt_ptr, NX_NO_WAIT); + + /* Check status. */ + if (status == NX_SUCCESS) + { + error_counter++; + nx_packet_release(pkt_ptr); + } + } + + /* Determine how to report error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_send_fail_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 send fail Test.......................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_ipv6_stateless_address_autoconfig_test.c b/test/regression/netxduo_test/netx_ipv6_stateless_address_autoconfig_test.c new file mode 100644 index 00000000..1e5fa85b --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_stateless_address_autoconfig_test.c @@ -0,0 +1,460 @@ +/* Test IPv6 ND CACHE APIs. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && defined(NX_IPV6_STATELESS_AUTOCONFIG_CONTROL) && !defined(NX_DISABLE_ICMPV6_ROUTER_SOLICITATION) + +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +#ifdef NX_ENABLE_DUAL_PACKET_POOL +static NX_PACKET_POOL auxiliary_pool; +#endif +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rs_counter; +static ULONG address_expired; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +static VOID ip_address_change_notify(NX_IP *ip_ptr, UINT operation, UINT if_index, UINT address_index, ULONG *address); +#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */ + +/* RA packet. */ +/* Two prefixes, 3ffe:0501:ffff:0100:: and 3ffe:0501:ffff:0101:: */ +static char pkt1[] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, +0x00, 0x00, 0x01, 0x00, 0x86, 0xdd, 0x60, 0x00, +0x00, 0x00, 0x00, 0x58, 0x3a, 0xff, 0xfe, 0x80, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, +0x00, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x86, 0x00, +0xa3, 0xd5, 0x40, 0x00, 0x07, 0x0d, 0x00, 0x00, +0x75, 0x35, 0x00, 0x00, 0x03, 0xed, 0x01, 0x01, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x04, +0x40, 0xc0, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, +0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04, +0x40, 0xc0, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, +0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, +0x05, 0x01, 0xff, 0xff, 0x01, 0x01, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +/* One prefix 3ffe:0501:ffff:0100. */ +static const unsigned char pkt2[110] = { +0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* 33...... */ +0x00, 0x00, 0xa0, 0xa0, 0x86, 0xdd, 0x60, 0x00, /* ......`. */ +0x00, 0x00, 0x00, 0x38, 0x3a, 0xff, 0xfe, 0x80, /* ...8:... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* ........ */ +0x00, 0xff, 0xfe, 0x00, 0xa0, 0xa0, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x86, 0x00, /* "..3DV.. */ +0x7f, 0xd1, 0x40, 0x00, 0x07, 0x08, 0x00, 0x00, /* ..@..... */ +0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x05, 0x01, /* ........ */ +0x00, 0x00, 0x00, 0x0f, 0x14, 0x40, 0x03, 0x04, /* .....@.. */ +0x40, 0xc0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* @....... */ +0x09, 0x60, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xfe, /* .`....?. */ +0x05, 0x01, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_stateless_address_autoconfig_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the value. */ + error_counter = 0; + rs_counter = 0; + address_expired = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + +#ifdef NX_ENABLE_DUAL_PACKET_POOL + /* Create a auxiliary pool. */ + status = nx_packet_pool_create(&auxiliary_pool, "NetX Main Auxiliary Pool", 256, pointer, 256*16); + pointer = pointer + 256*16; + + if(status) + error_counter++; +#endif + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 ICMP */ + status += nxd_icmp_enable(&ip_0); + + /* Check IPv6 ICMP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +UINT i, packet_counter_0; +#ifdef NX_ENABLE_DUAL_PACKET_POOL +UINT packet_counter_1; +NX_PACKET *tmp_auxiliary_packet[16]; +#endif +UINT address_index; +NXD_ADDRESS ipv6_address; +ULONG prefix_length; +UINT interface_index; +NX_PACKET *tmp_packet[16]; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Stateless Address Autoconfig Test...................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + /* Set address change notify. */ + nxd_ipv6_address_change_notify(&ip_0, ip_address_change_notify); +#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */ + + /* Disable the Stateless Address Autoconfig feature. */ + status = nxd_ipv6_stateless_address_autoconfig_disable(&ip_0, 0); + + /* Check the status. */ + if(status) + error_counter++; + + /* Disable the Stateless Address Autoconfig feature again. */ + status = nxd_ipv6_stateless_address_autoconfig_disable(&ip_0, 0); + + /* Check the status. */ + if(status) + error_counter++; + + /* Set the linklocal address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the linklocal address. */ + status = nxd_ipv6_address_get(&ip_0, address_index, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 10) || (interface_index != 0)) + error_counter++; + + /* Set the callback function to process the RS packet. */ + advanced_packet_process_callback = my_packet_process; + + packet_counter_0 = pool_0.nx_packet_pool_available; + + /* Loop to allocate the all packets from pool_0. */ + for (i = 0; i < packet_counter_0; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &tmp_packet[i], NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check the status. */ + if (status) + error_counter++; + } + +#ifdef NX_ENABLE_DUAL_PACKET_POOL + packet_counter_1 = auxiliary_pool.nx_packet_pool_available; + + /* Loop to allocate the all packets from auxiliary_pool. */ + for (i = 0; i < packet_counter_1; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&auxiliary_pool, &tmp_auxiliary_packet[i], NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check the status. */ + if (status) + error_counter++; + } +#endif + + /* Enable the Stateless Address Autoconfig feature. */ + status = nxd_ipv6_stateless_address_autoconfig_enable(&ip_0, 0); + + /* Check the status. */ + if(status) + error_counter++; + + /* Enable the Stateless Address Autoconfig feature again. */ + status = nxd_ipv6_stateless_address_autoconfig_enable(&ip_0, 0); + + /* Check the status. */ + if(status != NX_ALREADY_ENABLED) + error_counter++; + + /* Sleep 5 seconds for NetX sending RS message. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check the error. */ + if(rs_counter != 0) + error_counter++; + + /* Disable the Stateless Address Autoconfig feature. */ + status = nxd_ipv6_stateless_address_autoconfig_disable(&ip_0, 0); + + /* Check the status. */ + if(status) + error_counter++; + + /* Loop to release the all packets for pool_0. */ + for (i = 0; i < packet_counter_0; i++) + { + + /* Allocate a packet. */ + status = nx_packet_release(tmp_packet[i]); + + /* Check the status. */ + if (status) + error_counter++; + } + +#ifdef NX_ENABLE_DUAL_PACKET_POOL + /* Loop to release the all packets for auxiliary_pool. */ + for (i = 0; i < packet_counter_1; i++) + { + + /* Allocate a packet. */ + status = nx_packet_release(tmp_auxiliary_packet[i]); + + /* Check the status. */ + if (status) + error_counter++; + } +#endif + + /* Enable the Stateless Address Autoconfig feature. */ + status = nxd_ipv6_stateless_address_autoconfig_enable(&ip_0, 0); + + /* Check the status. */ + if(status) + error_counter++; + + /* Sleep 5 seconds for Stateless Address Autoconfig. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the Stateless address. */ + status = nxd_ipv6_address_get(&ip_0, 1, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 64) || (interface_index != 0)) + error_counter++; + + /* Get the Stateless address. */ + status = nxd_ipv6_address_get(&ip_0, 2, &ipv6_address, &prefix_length, &interface_index); + + /* Check the status. */ + if((status) || (prefix_length != 64) || (interface_index != 0)) + error_counter++; + + /* Send the RA packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_ICMP_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) - 14); + my_packet -> nx_packet_length = sizeof(pkt2) - 14; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + sizeof(pkt2) - 14; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Sleep 5 seconds for linklocal address DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Get the Stateless address. No new addresses are generated. */ + status = nxd_ipv6_address_get(&ip_0, 3, &ipv6_address, &prefix_length, &interface_index); + + if (status == NX_SUCCESS) + error_counter++; + +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + /* Sleep 40 seconds and let prefix timeout. */ + tx_thread_sleep(40 * NX_IP_PERIODIC_RATE); + + /* Get the Stateless address. */ + status = nxd_ipv6_address_get(&ip_0, 1, &ipv6_address, &prefix_length, &interface_index); + + if (status == NX_SUCCESS) + error_counter++; + + /* Get the Stateless address. */ + status = nxd_ipv6_address_get(&ip_0, 2, &ipv6_address, &prefix_length, &interface_index); + + if (status == NX_SUCCESS) + error_counter++; + + /* Check whether two addresses are expired. */ + if (address_expired != 2) + error_counter++; +#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */ + + /* Check the error. */ + if((error_counter) ||(rs_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +static VOID ip_address_change_notify(NX_IP *ip_ptr, UINT operation, UINT if_index, + UINT address_index, ULONG *address) +{ + if (operation == NX_IPV6_ADDRESS_LIFETIME_EXPIRED) + { + address_expired++; + + /* Check prefix. */ + if ((address[0] != 0x3ffe0501) || + ((address[1] != 0xffff0100) && (address[1] !=0xffff0101))) + { + error_counter++; + } + + } +} +#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */ + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +UINT status; +NX_ICMPV6_HEADER *header_ptr; +NX_PACKET *my_packet; + + /* Clean the callback function. */ + advanced_packet_process_callback = NX_NULL; + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + /* Points to the ICMP message header. */ + header_ptr = (NX_ICMPV6_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV6_HEADER)); + + /* Determine the message type and call the appropriate handler. */ + if (header_ptr -> nx_icmpv6_header_type == NX_ICMPV6_ROUTER_SOLICITATION_TYPE) + { + + /* Update the RS counter. */ + rs_counter ++; + + /* Send the RA packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_ICMP_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + my_packet -> nx_packet_length = sizeof(pkt1) - 14; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + sizeof(pkt1) - 14; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + } + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_stateless_address_autoconfig_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Stateless Address Autoconfig Test....................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_ipv6_util_api_test.c b/test/regression/netxduo_test/netx_ipv6_util_api_test.c new file mode 100644 index 00000000..bc70a2ae --- /dev/null +++ b/test/regression/netxduo_test/netx_ipv6_util_api_test.c @@ -0,0 +1,1139 @@ +/* This test case validates nxd_ipv6_address_delete. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_util_api_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ipv6_address_1[4]; +ULONG ipv6_address_2[4]; + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Util API Test........................................"); + + /* Set address 1. */ + ipv6_address_1[0] = 0x20010000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x10000000; + ipv6_address_1[3] = 0x00000011; + + /* Set address 2. */ + ipv6_address_2[0] = 0x20010000; + ipv6_address_2[1] = 0x00000000; + ipv6_address_2[2] = 0x20000000; + ipv6_address_2[3] = 0x00000022; + + /* Check the address by prefixe length. */ + status = CHECK_IP_ADDRESSES_BY_PREFIX(ipv6_address_1, ipv6_address_2, 48); + + /* Check the status. */ + if (status != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address by prefixe length. */ + status = CHECK_IP_ADDRESSES_BY_PREFIX(ipv6_address_1, ipv6_address_2, 64); + + /* Check the status. */ + if (status != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the address by prefixe length. */ + status = CHECK_IP_ADDRESSES_BY_PREFIX(ipv6_address_1, ipv6_address_2, 96); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x20010000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000011; + + /* Set address 2. */ + ipv6_address_2[0] = 0x20010000; + ipv6_address_2[1] = 0x00000000; + ipv6_address_2[2] = 0x00000000; + ipv6_address_2[3] = 0x00000022; + + /* Check the address by prefixe length. */ + status = CHECK_IP_ADDRESSES_BY_PREFIX(ipv6_address_1, ipv6_address_2, 127); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x20010000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000011; + + /* Set address 2. */ + ipv6_address_2[0] = 0x20010000; + ipv6_address_2[1] = 0x00000000; + ipv6_address_2[2] = 0x00000000; + ipv6_address_2[3] = 0x00000022; + + /* Check the address by prefixe length. */ + status = CHECK_IP_ADDRESSES_BY_PREFIX(ipv6_address_1, ipv6_address_2, 16); + + /* Check the status. */ + if (status != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x20010000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x20010000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x20010000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x20010000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000003; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x20010000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x20010000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000003; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x20010000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000003; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x20010000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000003; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000003; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000003; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000003; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000003; + + /* Check the address by prefixe length. */ + status = CHECK_UNSPECIFIED_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000002; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000002; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000002; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000002; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000002; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000002; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000002; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000002; + + /* Check if the address is router multicast address. */ + status = CHECK_ALL_ROUTER_MCAST_ADDRESS(ipv6_address_1); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00010000; + + /* Set address 2. */ + ipv6_address_2[0] = 0x20010000; + ipv6_address_2[1] = 0x00000000; + ipv6_address_2[2] = 0x00000000; + ipv6_address_2[3] = 0x00000022; + + /* Check if the address is node multicast address. */ + status = CHECK_IPV6_SOLICITED_NODE_MCAST_ADDRESS(ipv6_address_1, ipv6_address_2); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00010003; + + /* Set address 2. */ + ipv6_address_2[0] = 0x20010000; + ipv6_address_2[1] = 0x00000000; + ipv6_address_2[2] = 0x00000000; + ipv6_address_2[3] = 0x00000022; + + /* Check if the address is node multicast address. */ + status = CHECK_IPV6_SOLICITED_NODE_MCAST_ADDRESS(ipv6_address_1, ipv6_address_2); + + /* Check the status. */ + if (status == 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00010003; + + /* Set address 2. */ + ipv6_address_2[0] = 0x20010000; + ipv6_address_2[1] = 0x00000000; + ipv6_address_2[2] = 0x00000000; + ipv6_address_2[3] = 0x00000022; + + /* Check if the address is node multicast address. */ + status = CHECK_IPV6_SOLICITED_NODE_MCAST_ADDRESS(ipv6_address_1, ipv6_address_2); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00010003; + + /* Set address 2. */ + ipv6_address_2[0] = 0x20010000; + ipv6_address_2[1] = 0x00000000; + ipv6_address_2[2] = 0x00000000; + ipv6_address_2[3] = 0x00000022; + + /* Check if the address is node multicast address. */ + status = CHECK_IPV6_SOLICITED_NODE_MCAST_ADDRESS(ipv6_address_1, ipv6_address_2); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x20010004; + + /* Set address 2. */ + ipv6_address_2[0] = 0x20010000; + ipv6_address_2[1] = 0x00000000; + ipv6_address_2[2] = 0x00000000; + ipv6_address_2[3] = 0x00000022; + + /* Check if the address is node multicast address. */ + status = CHECK_IPV6_SOLICITED_NODE_MCAST_ADDRESS(ipv6_address_1, ipv6_address_2); + + /* Check the status. */ + if (status != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF030000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000004; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF010000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000004; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00010003; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != (IPV6_ADDRESS_MULTICAST | IPV6_ALL_NODE_MCAST)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00010003; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00010003; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF050000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00010003; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF000001; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF000001; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000000; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF000001; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF000001; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00010003; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF000001; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00000000; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF000001; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00010003; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF000001; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00010003; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF000001; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000002; + ipv6_address_1[3] = 0x00010003; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0x00000000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000000; + ipv6_address_1[3] = 0x00000003; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != (IPV6_ADDRESS_UNICAST | IPV6_ADDRESS_GLOBAL)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000001; + ipv6_address_1[2] = 0x00000001; + ipv6_address_1[3] = 0x00000000; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000001; + ipv6_address_1[3] = 0x00000000; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != IPV6_ADDRESS_MULTICAST) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set address 1. */ + ipv6_address_1[0] = 0xFF020000; + ipv6_address_1[1] = 0x00000000; + ipv6_address_1[2] = 0x00000001; + ipv6_address_1[3] = 0xFF000000; + + /* Check the address type. */ + status = IPv6_Address_Type(ipv6_address_1); + + /* Check the status. */ + if (status != (IPV6_ADDRESS_MULTICAST | IPV6_SOLICITED_NODE_MCAST)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Change the IPv6 address with NULL pointer. */ + NX_IPV6_ADDRESS_CHANGE_ENDIAN(NX_NULL); + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ipv6_util_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Util API Test........................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_low_watermark_fragment_test.c b/test/regression/netxduo_test/netx_low_watermark_fragment_test.c new file mode 100644 index 00000000..c5436e07 --- /dev/null +++ b/test/regression/netxduo_test/netx_low_watermark_fragment_test.c @@ -0,0 +1,308 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_LOW_WATERMARK) +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 +#define PACKET_SIZE 1536 +#define POOL_0_COUNT 20 +#define POOL_1_COUNT 10 +#define TEST_LOOP 100 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static ULONG fragments_count; +static ULONG drop_count; + + +/* Define pool area. */ +static UCHAR pool_area_0[POOL_0_COUNT * (sizeof(NX_PACKET) + PACKET_SIZE)]; +static UCHAR pool_area_1[POOL_1_COUNT * (sizeof(NX_PACKET) + PACKET_SIZE)]; + +static UCHAR ping_buffer[2048]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_low_watermark_fragment_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create two packet pools. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pool_area_0, sizeof(pool_area_0)); + status += nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", PACKET_SIZE, pool_area_1, sizeof(pool_area_1)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ICMP enable status. */ + if (status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ + + /* Enable ICMP processing for both IP instances. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ICMP enable status. */ + if (status) + error_counter++; + + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT i; +NX_PACKET *packet_ptr; +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: Low Watermark Fragment Test..............................."); + + /* Setup driver callback to drop last fragment of each ICMP packet. */ + advanced_packet_process_callback = packet_process; + +#ifdef FEATURE_NX_IPV6 + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Set low_watermark. */ + nx_packet_pool_low_watermark_set(&pool_1, 2); + fragments_count = 0; + drop_count = 0; + for (i = 0; (i < TEST_LOOP) && (error_counter == 0); i++) + { + +#ifndef NX_DISABLE_IPV4 + /* Ping IP1 address with fragments. The first fragment will be dropped by driver. */ + nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), ping_buffer, sizeof(ping_buffer), + &packet_ptr, NX_NO_WAIT); + fragments_count++; + + /* Ping IP1 address without fragments. */ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1, 2, 3, 5), "", 0, &packet_ptr, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(packet_ptr); +#endif /* NX_DISABLE_IPV4 */ + +#ifdef FEATURE_NX_IPV6 + /* Ping IP1 address with fragments. The first fragment will be dropped by driver. */ + nxd_icmp_ping(&ip_0, &ipv6_address_2, ping_buffer, sizeof(ping_buffer), + &packet_ptr, NX_NO_WAIT); + fragments_count++; + + /* Ping IP1 address without fragments. */ + status = nxd_icmp_ping(&ip_0, &ipv6_address_2, "", 0, &packet_ptr, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(packet_ptr); +#endif /* FEATURE_NX_IPV6 */ + } + + /* Check status. */ + if (error_counter || (drop_count != fragments_count)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +ULONG ip_version; +#ifndef NX_DISABLE_IPV4 +NX_IPV4_HEADER *ip_header_ptr; +#endif /* NX_DISABLE_IPV4 */ +#ifdef FEATURE_NX_IPV6 +NX_IPV6_HEADER *ipv6_header_ptr; +NX_IPV6_HEADER_FRAGMENT_OPTION *ipv6_fragment_option; +#endif /* FEATURE_NX_IPV6 */ + + if (ip_ptr == &ip_1) + return NX_TRUE; + + ip_version = packet_ptr -> nx_packet_ip_version; + + if (ip_version == NX_IP_VERSION_V6) + { +#ifdef FEATURE_NX_IPV6 + if (packet_ptr -> nx_packet_length < 40) + { + return NX_TRUE; + } + ipv6_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(ipv6_header_ptr -> nx_ip_header_word_1); + if (((ipv6_header_ptr -> nx_ip_header_word_1 >> 8) & 0xFF) == NX_PROTOCOL_NEXT_HEADER_FRAGMENT) + { + ipv6_fragment_option = (NX_IPV6_HEADER_FRAGMENT_OPTION *)(packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV6_HEADER)); + NX_CHANGE_USHORT_ENDIAN(ipv6_fragment_option -> nx_ipv6_header_fragment_option_offset_flag); + if (ipv6_fragment_option -> nx_ipv6_header_fragment_option_offset_flag & 1) + { + *operation_ptr = NX_RAMDRIVER_OP_DROP; + drop_count++; + } + NX_CHANGE_USHORT_ENDIAN(ipv6_fragment_option -> nx_ipv6_header_fragment_option_offset_flag); + } + NX_CHANGE_ULONG_ENDIAN(ipv6_header_ptr -> nx_ip_header_word_1); +#endif /* FEATURE_NX_IPV6 */ + } +#ifndef NX_DISABLE_IPV4 + else + { + if ((packet_ptr -> nx_packet_length < 20) || (packet_ptr -> nx_packet_length == 28)) + { + return NX_TRUE; + } + ip_header_ptr = (NX_IPV4_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + if (ip_header_ptr -> nx_ip_header_word_1 & (NX_IP_FRAGMENT_MASK | NX_IP_MORE_FRAGMENT) == + (NX_IP_FRAGMENT_MASK | NX_IP_MORE_FRAGMENT)) + { + *operation_ptr = NX_RAMDRIVER_OP_DROP; + drop_count++; + } + NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1); + } +#endif /* NX_DISABLE_IPV4 */ + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_low_watermark_fragment_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Low Watermark Fragment Test...............................N/A\n"); + + test_control_return(3); + +} +#endif /* NX_ENABLE_LOW_WATERMARK */ diff --git a/test/regression/netxduo_test/netx_low_watermark_test.c b/test/regression/netxduo_test/netx_low_watermark_test.c new file mode 100644 index 00000000..55c4d2d3 --- /dev/null +++ b/test/regression/netxduo_test/netx_low_watermark_test.c @@ -0,0 +1,502 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_LOW_WATERMARK) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 +#define PACKET_SIZE 1536 +#define POOL_0_COUNT 20 +#define POOL_1_COUNT 10 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET tcp_client; +static NX_TCP_SOCKET tcp_server; +static NX_UDP_SOCKET udp_client; +static NX_UDP_SOCKET udp_server; +static ULONG zero_window_received = 0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define pool area. */ +static UCHAR pool_area_0[POOL_0_COUNT * (sizeof(NX_PACKET) + PACKET_SIZE)]; +static UCHAR pool_area_1[POOL_1_COUNT * (sizeof(NX_PACKET) + PACKET_SIZE)]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void verify_tcp(UINT low_watermark, UINT receive_queue_maximum, + UINT expected_packet_available, + UINT expected_receive_queue_count); +static void verify_udp(UINT low_watermark, UINT receive_queue_maximum, + UINT expected_packet_available, + UINT expected_receive_queue_count); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_low_watermark_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create two packet pools. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pool_area_0, sizeof(pool_area_0)); + status += nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", PACKET_SIZE, pool_area_1, sizeof(pool_area_1)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Enable UDP processing for both IP instances. */ + status += nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT i, j; +UINT max; + + /* Print out some test information banners. */ + printf("NetX Test: Low Watermark Test........................................"); + + /* Setup driver callback. */ + advanced_packet_process_callback = packet_process; + + /* 1. Do not set low watermark or receive queue maximum. + * All packets in pool_1 should be queued in TCP socket. + * */ + verify_tcp(0, POOL_1_COUNT, 0, POOL_1_COUNT); + verify_udp(0, POOL_1_COUNT, 0, POOL_1_COUNT); + + /* 2. Set low watermark but do not set receive queue maximum. */ + for (i = 1; i < POOL_1_COUNT; i++) + { + verify_tcp(i, POOL_1_COUNT, i, POOL_1_COUNT - i); + verify_udp(i, POOL_1_COUNT, i, POOL_1_COUNT - i); + + /* Check status. */ + if (error_counter) + { + break; + } + } + + /* 3. Do not set low watermark but set receive queue maximum. */ + for (i = 1; i < POOL_1_COUNT; i++) + { + verify_tcp(0, POOL_1_COUNT - i, i, POOL_1_COUNT - i); + verify_udp(0, POOL_1_COUNT - i, i, POOL_1_COUNT - i); + + /* Check status. */ + if (error_counter) + { + break; + } + } + + /* 4. Set low watermark and receive queue maximum. */ + for (i = 1; i < POOL_1_COUNT; i++) + { + for (j = 1; j < POOL_1_COUNT; j++) + { + + /* Get maximum limitation. */ + if (i > j) + max = i; + else + max = j; + + verify_tcp(i, POOL_1_COUNT - j, max, POOL_1_COUNT - max); + verify_udp(i, POOL_1_COUNT - j, max, POOL_1_COUNT - max); + + /* Check status. */ + if (error_counter) + { + break; + } + } + } + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void verify_tcp(UINT low_watermark, UINT receive_queue_maximum, + UINT expected_packet_available, + UINT expected_receive_queue_count) +{ +UINT status; +NX_PACKET *send_packet; +NX_PACKET *recv_packet; +UINT i; +CHAR ch; + + /* Create server socket. */ + status = nx_tcp_socket_create(&ip_1, &tcp_server, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &tcp_server, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + nx_tcp_server_socket_accept(&tcp_server, NX_NO_WAIT); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &tcp_client, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&tcp_client, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&tcp_client, IP_ADDRESS(1, 2, 3, 5), 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Set low watermark and receive queue maximum. */ + nx_packet_pool_low_watermark_set(&pool_1, low_watermark); + nx_tcp_socket_receive_queue_max_set(&tcp_server, receive_queue_maximum); + zero_window_received = 0; + for (i = 0; i < POOL_1_COUNT; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + break; + } + + ch = 'A' + i; + status = nx_packet_data_append(send_packet, &ch, 1, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + break; + } + + /* Send the packet out! */ + status = nx_tcp_socket_send(&tcp_client, send_packet, NX_NO_WAIT); + + /* Determine if the status is valid. */ + if (status) + { + + if (status != NX_WINDOW_OVERFLOW) + error_counter++; + nx_packet_release(send_packet); + break; + } + } + + /* Check whether zero window has been sent. */ + if ((tcp_server.nx_tcp_socket_receive_queue_count != POOL_1_COUNT) && + (zero_window_received == 0)) + { + error_counter++; + } + else if ((tcp_server.nx_tcp_socket_receive_queue_count == POOL_1_COUNT) && + (zero_window_received != 0)) + { + error_counter++; + } + + /* Verify packets in server's receive queue. */ + if (tcp_server.nx_tcp_socket_receive_queue_count != expected_receive_queue_count) + { + error_counter++; + } + + /* Verify packets in server's pool. */ + if (pool_1.nx_packet_pool_available != expected_packet_available) + { + error_counter++; + } + + /* Receive all packets. */ + for (i = tcp_server.nx_tcp_socket_receive_queue_count; i > 0; i--) + { + if (nx_tcp_socket_receive(&tcp_server, &recv_packet, NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + nx_packet_release(recv_packet); + } + else + { + error_counter++; + } + } + + /* Force close the connection. */ + nx_tcp_socket_disconnect(&tcp_client, NX_NO_WAIT); + nx_tcp_client_socket_unbind(&tcp_client); + nx_tcp_socket_delete(&tcp_client); + nx_tcp_socket_disconnect(&tcp_server, NX_NO_WAIT); + nx_tcp_server_socket_unaccept(&tcp_server); + nx_tcp_server_socket_unlisten(&ip_1, 12); + nx_tcp_socket_delete(&tcp_server); +} + + +static void verify_udp(UINT low_watermark, UINT receive_queue_maximum, + UINT expected_packet_available, + UINT expected_receive_queue_count) +{ +UINT status; +NX_PACKET *send_packet; +NX_PACKET *recv_packet; +UINT i; +CHAR ch; + + /* Create server socket. */ + status = nx_udp_socket_create(&ip_1, &udp_server, "Server Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, receive_queue_maximum); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind to port 12. */ + status = nx_udp_socket_bind(&udp_server, 12, TX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create client socket. */ + status = nx_udp_socket_create(&ip_0, &udp_client, "Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 20); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind to port 12. */ + status = nx_udp_socket_bind(&udp_client, 12, TX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Set low watermark and receive queue maximum. */ + nx_packet_pool_low_watermark_set(&pool_1, low_watermark); + for (i = 0; i < POOL_1_COUNT; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + break; + } + + ch = 'A' + i; + status = nx_packet_data_append(send_packet, &ch, 1, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + break; + } + + /* Send the packet out! */ + status = nx_udp_socket_send(&udp_client, send_packet, IP_ADDRESS(1, 2, 3, 5), 12); + + /* Determine if the status is valid. */ + if (status) + { + + error_counter++; + nx_packet_release(send_packet); + break; + } + } + + /* Verify packets in server's receive queue. */ + if (udp_server.nx_udp_socket_receive_count != expected_receive_queue_count) + { + error_counter++; + } + + /* Verify packets in server's pool. */ + if (pool_1.nx_packet_pool_available != expected_packet_available) + { + error_counter++; + } + + /* Receive all packets. */ + for (i = udp_server.nx_udp_socket_receive_count; i > 0; i--) + { + if (nx_udp_socket_receive(&udp_server, &recv_packet, NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + nx_packet_release(recv_packet); + } + else + { + error_counter++; + } + } + + /* Force close the connection. */ + nx_udp_socket_unbind(&udp_client); + nx_udp_socket_delete(&udp_client); + nx_udp_socket_unbind(&udp_server); + nx_udp_socket_delete(&udp_server); +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Skip packets that are not TCP. */ + if ((packet_ptr -> nx_packet_length < 40) || + (*(packet_ptr -> nx_packet_prepend_ptr + 9) != NX_PROTOCOL_TCP)) + return NX_TRUE; + + /* Get TCP header. */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check window size. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_LOWER_16_MASK) == 0) + zero_window_received++; + + /* Restore endian. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_low_watermark_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Low Watermark Test........................................N/A\n"); + + test_control_return(3); + +} +#endif /* NX_ENABLE_LOW_WATERMARK */ diff --git a/test/regression/netxduo_test/netx_low_watermark_zero_window_test.c b/test/regression/netxduo_test/netx_low_watermark_zero_window_test.c new file mode 100644 index 00000000..d081a213 --- /dev/null +++ b/test/regression/netxduo_test/netx_low_watermark_zero_window_test.c @@ -0,0 +1,330 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && defined(NX_ENABLE_LOW_WATERMARK) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 +#define PACKET_SIZE 1536 +#define POOL_0_COUNT 20 +#define POOL_1_COUNT 10 +#define SERVER_IP_ADDRESS IP_ADDRESS(1, 2, 3, 99) +#define CLIENT_IP_ADDRESS IP_ADDRESS(1, 2, 3, 4) + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD client_thread; +static TX_THREAD server_thread; + +static NX_PACKET_POOL client_pool; +static NX_PACKET_POOL server_pool; +static NX_IP client_ip; +static NX_IP server_ip; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static ULONG zero_window_received = 0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT client_running = NX_TRUE; + + +/* Define pool area. */ +static UCHAR client_pool_area[POOL_0_COUNT * (sizeof(NX_PACKET) + PACKET_SIZE)]; +static UCHAR server_pool_area[POOL_1_COUNT * (sizeof(NX_PACKET) + PACKET_SIZE)]; + + +/* Define thread prototypes. */ + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_low_watermark_zero_window_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the Client thread. */ + tx_thread_create(&client_thread, "Client thread", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the Server thread. */ + tx_thread_create(&server_thread, "Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create two packet pools. */ + status = nx_packet_pool_create(&client_pool, "ClientPacket Pool", PACKET_SIZE, client_pool_area, sizeof(client_pool_area)); + status += nx_packet_pool_create(&server_pool, "Server Packet Pool", PACKET_SIZE, server_pool_area, sizeof(server_pool_area)); + + if (status) + error_counter++; + + /* Create client IP instance. */ + status = nx_ip_create(&client_ip, "Client IP Instance", CLIENT_IP_ADDRESS, 0xFFFFFF00UL, &client_pool, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create sever IP instance. */ + status += nx_ip_create(&server_ip, "Server IP Instance", SERVER_IP_ADDRESS, 0xFFFFFF00UL, &server_pool, + _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&client_ip); + status += nx_tcp_enable(&server_ip); + + + /* Check enable status. */ + if (status) + error_counter++; + + return; +} + +static void thread_server_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *send_packet; + + + tx_thread_sleep(10); + + /* Print out some test information banners. */ + printf("NetX Test: Low Watermark Zero Window Test..........................."); + + /* Setup driver callback. */ + advanced_packet_process_callback = packet_process; + + /* Create server socket. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&server_ip, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + zero_window_received = 0; + + /* Allocate a packet. */ + status = nx_packet_allocate(&server_pool, &send_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Write ABCs into the first packet payload! */ + memcpy(send_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + send_packet -> nx_packet_length = 28; + send_packet -> nx_packet_append_ptr = send_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, send_packet, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + nx_packet_release(send_packet); + error_counter++; + } + + while(client_running) + tx_thread_sleep(100); + + nx_tcp_socket_disconnect(&server_socket, 200); + nx_tcp_server_socket_unaccept(&server_socket); + nx_tcp_server_socket_unlisten(&server_ip, 12); + nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void thread_client_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *recv_packet; + + tx_thread_sleep(50); + + /* Create a socket. */ + status = nx_tcp_socket_create(&client_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, SERVER_IP_ADDRESS, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Set low watermark to prevent using any packets. */ + status = nx_packet_pool_low_watermark_set(&client_pool, client_pool.nx_packet_pool_total); + + /* Check for error. */ + if (status) + error_counter++; + + status = nx_tcp_socket_receive(&client_socket, &recv_packet, NX_IP_PERIODIC_RATE); + + if (status && (status != NX_NO_PACKET)) + { + error_counter++; + } + else if (status == NX_SUCCESS) + { + error_counter++; + nx_packet_release(recv_packet); + } + + /* Set low watermark to allow using all packets. */ + nx_packet_pool_low_watermark_set(&client_pool, 0); + + status = nx_tcp_socket_receive(&client_socket, &recv_packet, 5*NX_IP_PERIODIC_RATE); + + if (status != NX_SUCCESS) + { + error_counter++; + } + else + nx_packet_release(recv_packet); + + /* Check whether zero window has been sent. */ + if (zero_window_received == 0) + { + error_counter++; + } + + client_running = NX_FALSE; + + /* Force close the connection. */ + nx_tcp_socket_disconnect(&client_socket, 300); + nx_tcp_client_socket_unbind(&client_socket); + nx_tcp_socket_delete(&client_socket); + + return; + +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Get TCP header. */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check window size. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_LOWER_16_MASK) == 0) + zero_window_received++; + + /* Restore endian. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_low_watermark_zero_window_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Low Watermark Zero Window Test...........................N/A\n"); + test_control_return(3); + +} +#endif /* NX_ENABLE_LOW_WATERMARK */ diff --git a/test/regression/netxduo_test/netx_nd_cache_add_test.c b/test/regression/netxduo_test/netx_nd_cache_add_test.c new file mode 100644 index 00000000..0e6e4371 --- /dev/null +++ b/test/regression/netxduo_test/netx_nd_cache_add_test.c @@ -0,0 +1,404 @@ +/* This NetX test concentrates on the ICMP ping operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_icmp.h" + +extern void test_control_return(UINT status); +#ifdef FEATURE_NX_IPV6 +#include "nx_nd_cache.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static NXD_ADDRESS global_address_0; +static NXD_ADDRESS global_address_1; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_add_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check ipv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 processing for IP instances0 . */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ICMPv6 enable status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 0. */ + global_address_0.nxd_ip_version = NX_IP_VERSION_V6; + global_address_0.nxd_ip_address.v6[0] = 0x20010000; + global_address_0.nxd_ip_address.v6[1] = 0x00000000; + global_address_0.nxd_ip_address.v6[2] = 0x00000000; + global_address_0.nxd_ip_address.v6[3] = 0x10000001; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, &global_address_0, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; + + /* Set ipv6 global address for IP instance 1. */ + global_address_1.nxd_ip_version = NX_IP_VERSION_V6; + global_address_1.nxd_ip_address.v6[0] = 0x20010000; + global_address_1.nxd_ip_address.v6[1] = 0x00000000; + global_address_1.nxd_ip_address.v6[2] = 0x00000000; + global_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, &global_address_1, 64, NX_NULL); + + /* Check status. */ + if(status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet; +ND_CACHE_ENTRY *nd_cache_entry; +NXD_ADDRESS dest_ip; +CHAR mac_address[6]; + + + /* Print out test information banner. */ + printf("NetX Test: ND Cache Add Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Ping an IP address that does exist. One entry status is ND_CACHE_STATE_REACHABLE, one entry status is ND_CACHE_STATE_DELAY. */ + status = nxd_icmp_ping(&ip_0, &global_address_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Added the same ND Cache entry. */ + mac_address[0] = 0x00; + mac_address[1] = 0x11; + mac_address[2] = 0x22; + mac_address[3] = 0x33; + mac_address[4] = 0x44; + mac_address[5] = 0x57; + + /* Call the function to added the same entry. */ + status = _nx_nd_cache_add(&ip_0, &global_address_1.nxd_ip_address.v6[0], &ip_0.nx_ip_interface[0], &mac_address[0], 0, ND_CACHE_STATE_CREATED, &ip_0.nx_ipv6_address[0], &nd_cache_entry); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Added the same ND Cache entry with different first short. */ + mac_address[0] = 0x11; + mac_address[1] = 0x11; + mac_address[2] = 0x22; + mac_address[3] = 0x33; + mac_address[4] = 0x44; + mac_address[5] = 0x57; + + /* Call the function to added the same entry. */ + status = _nx_nd_cache_add(&ip_0, &global_address_1.nxd_ip_address.v6[0], &ip_0.nx_ip_interface[0], &mac_address[0], 0, ND_CACHE_STATE_REACHABLE, &ip_0.nx_ipv6_address[0], &nd_cache_entry); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Added the same ND Cache entry with different second short. */ + mac_address[0] = 0x11; + mac_address[1] = 0x11; + mac_address[2] = 0x33; + mac_address[3] = 0x33; + mac_address[4] = 0x44; + mac_address[5] = 0x57; + + /* Call the function to added the same entry. */ + status = _nx_nd_cache_add(&ip_0, &global_address_1.nxd_ip_address.v6[0], &ip_0.nx_ip_interface[0], &mac_address[0], 0, ND_CACHE_STATE_REACHABLE, &ip_0.nx_ipv6_address[0], &nd_cache_entry); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Added the same ND Cache entry with different third short. */ + mac_address[0] = 0x11; + mac_address[1] = 0x11; + mac_address[2] = 0x33; + mac_address[3] = 0x33; + mac_address[4] = 0x44; + mac_address[5] = 0x44; + + /* Call the function to added the same entry. */ + status = _nx_nd_cache_add(&ip_0, &global_address_1.nxd_ip_address.v6[0], &ip_0.nx_ip_interface[0], &mac_address[0], 0, ND_CACHE_STATE_REACHABLE, &ip_0.nx_ipv6_address[0], &nd_cache_entry); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Set ipv6 global address for IP instance 1. */ + dest_ip.nxd_ip_version = NX_IP_VERSION_V6; + dest_ip.nxd_ip_address.v6[0] = 0x20010000; + dest_ip.nxd_ip_address.v6[1] = 0x00000000; + dest_ip.nxd_ip_address.v6[2] = 0x00000000; + dest_ip.nxd_ip_address.v6[3] = 0x10000003; + + /* Added the same ND Cache entry. */ + mac_address[0] = 0x00; + mac_address[1] = 0x11; + mac_address[2] = 0x22; + mac_address[3] = 0x33; + mac_address[4] = 0x44; + mac_address[5] = 0x58; + + /* Loop to added the ND CACHE ENTRY. */ + for (i = 0; i < NX_IPV6_NEIGHBOR_CACHE_SIZE - 1; i ++) + { + + /* Update the IP address and mac address. */ + dest_ip.nxd_ip_address.v6[3] += 1; + mac_address[5] += 1; + + /* Call the function to added the same entry. */ + status = _nx_nd_cache_add(&ip_0, &dest_ip.nxd_ip_address.v6[0], &ip_0.nx_ip_interface[0], &mac_address[0], 0, ND_CACHE_STATE_CREATED, &ip_0.nx_ipv6_address[0], &nd_cache_entry); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Set the status to stale. */ + ip_0.nx_ipv6_nd_cache[NX_IPV6_NEIGHBOR_CACHE_SIZE - 1].nx_nd_cache_nd_status = ND_CACHE_STATE_STALE; + ip_0.nx_ipv6_nd_cache[NX_IPV6_NEIGHBOR_CACHE_SIZE - 1].nx_nd_cache_timer_tick = 10; + ip_0.nx_ipv6_nd_cache[NX_IPV6_NEIGHBOR_CACHE_SIZE - 2].nx_nd_cache_nd_status = ND_CACHE_STATE_STALE; + ip_0.nx_ipv6_nd_cache[NX_IPV6_NEIGHBOR_CACHE_SIZE - 2].nx_nd_cache_timer_tick = 20; + + /* Update the IP address and mac address. */ + dest_ip.nxd_ip_address.v6[3] += 1; + mac_address[5] += 1; + + /* Call the function to added the new entry. the entry status is ND_CACHE_STATE_REACHABLE can be replaced when disable the NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES. */ + status = _nx_nd_cache_add(&ip_0, &dest_ip.nxd_ip_address.v6[0], &ip_0.nx_ip_interface[0], &mac_address[0], 0, ND_CACHE_STATE_CREATED, &ip_0.nx_ipv6_address[0], &nd_cache_entry); + +#ifndef NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#else + /* Check status. */ + if (status != NX_NOT_SUCCESSFUL) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Loop to mark all the ND CACHE ENTRY as static. */ + for (i = 0; i < NX_IPV6_NEIGHBOR_CACHE_SIZE; i++) + { + ip_0.nx_ipv6_nd_cache[i].nx_nd_cache_is_static = NX_TRUE; + } + + /* Update the IP address and mac address. */ + dest_ip.nxd_ip_address.v6[3] += 1; + mac_address[5] += 1; + + /* Call the function to added the new entry. the entry status is ND_CACHE_STATE_REACHABLE can be replaced when disable the NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES. */ + status = _nx_nd_cache_add(&ip_0, &dest_ip.nxd_ip_address.v6[0], &ip_0.nx_ip_interface[0], &mac_address[0], 0, ND_CACHE_STATE_CREATED, &ip_0.nx_ipv6_address[0], &nd_cache_entry); + + /* Check status. */ + if (status != NX_NOT_SUCCESSFUL) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES + /* Cover branch in nx_nd_cache_add_entry.c + 212 [ + - ]: 8 : if (ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_timer_tick < timer_ticks_left) */ + /* Invalidate all ND caches. */ + nxd_nd_cache_invalidate(&ip_0); + + /* Set ipv6 global address for IP instance 1. */ + dest_ip.nxd_ip_version = NX_IP_VERSION_V6; + dest_ip.nxd_ip_address.v6[0] = 0x20010000; + dest_ip.nxd_ip_address.v6[1] = 0x00000000; + dest_ip.nxd_ip_address.v6[2] = 0x00000000; + dest_ip.nxd_ip_address.v6[3] = 0x10000003; + + /* Added the same ND Cache entry. */ + mac_address[0] = 0x00; + mac_address[1] = 0x11; + mac_address[2] = 0x22; + mac_address[3] = 0x33; + mac_address[4] = 0x44; + mac_address[5] = 0x58; + + /* Loop to added the ND CACHE ENTRY. */ + for (i = 0; i < NX_IPV6_NEIGHBOR_CACHE_SIZE; i++) + { + + /* Update the IP address and mac address. */ + dest_ip.nxd_ip_address.v6[3] += 1; + mac_address[5] += 1; + + /* Call the function to added the same entry. */ + status = _nx_nd_cache_add(&ip_0, &dest_ip.nxd_ip_address.v6[0], &ip_0.nx_ip_interface[0], &mac_address[0], 0, ND_CACHE_STATE_REACHABLE, &ip_0.nx_ipv6_address[0], &nd_cache_entry); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_timer_tick -= 1; + ip_0.nx_ipv6_nd_cache[1].nx_nd_cache_timer_tick -= 2; + + dest_ip.nxd_ip_address.v6[3] += 1; + mac_address[5] += 1; + status = _nx_nd_cache_add(&ip_0, &dest_ip.nxd_ip_address.v6[0], &ip_0.nx_ip_interface[0], &mac_address[0], 0, ND_CACHE_STATE_CREATED, &ip_0.nx_ipv6_address[0], &nd_cache_entry); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES */ + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_add_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ND Cache Add Test.........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_nd_cache_api_test.c b/test/regression/netxduo_test/netx_nd_cache_api_test.c new file mode 100644 index 00000000..24efed4d --- /dev/null +++ b/test/regression/netxduo_test/netx_nd_cache_api_test.c @@ -0,0 +1,384 @@ +/* Test IPv6 ND CACHE APIs. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#define MAX_TEST_INTERFACES 2 + +#if defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES >= MAX_TEST_INTERFACES) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_0; +static NXD_ADDRESS ipv6_address_1; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_api_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + ipv6_address_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[3] = 0x01020304; + + status += nxd_ipv6_address_set(&ip_0, 0,&ipv6_address_0, 64, NX_NULL); + + if(status) + error_counter++; + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_512); + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20020000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x01020304; + + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_1, 64, NX_NULL); + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS dest_address[4]; +CHAR dest_mac[4][6]; +NXD_ADDRESS ipv6_address; +NXD_ADDRESS invalid_address; +ULONG physical_msw; +ULONG physical_lsw; +UINT interface_index; + + /* Print out test information banner. */ + printf("NetX Test: ND Cache API Test........................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the Destination address and mac address. */ + dest_address[0].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[0].nxd_ip_address.v6[0] = 0x20010000; + dest_address[0].nxd_ip_address.v6[1] = 0x00000000; + dest_address[0].nxd_ip_address.v6[2] = 0x00000000; + dest_address[0].nxd_ip_address.v6[3] = 0x01020305; + + dest_mac[0][0] = 0x11; + dest_mac[0][1] = 0x22; + dest_mac[0][2] = 0x33; + dest_mac[0][3] = 0x44; + dest_mac[0][4] = 0x55; + dest_mac[0][5] = 0x69; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[0].nxd_ip_address.v6[0], 0, &dest_mac[0][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Set the Destination address and mac address. */ + dest_address[1].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[1].nxd_ip_address.v6[0] = 0x20010000; + dest_address[1].nxd_ip_address.v6[1] = 0x00000000; + dest_address[1].nxd_ip_address.v6[2] = 0x00000000; + dest_address[1].nxd_ip_address.v6[3] = 0x01020306; + + dest_mac[1][0] = 0x11; + dest_mac[1][1] = 0x22; + dest_mac[1][2] = 0x33; + dest_mac[1][3] = 0x44; + dest_mac[1][4] = 0x55; + dest_mac[1][5] = 0x70; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[1].nxd_ip_address.v6[0], 0, &dest_mac[1][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Set the Destination address and mac address. */ + dest_address[2].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[2].nxd_ip_address.v6[0] = 0x20020000; + dest_address[2].nxd_ip_address.v6[1] = 0x00000000; + dest_address[2].nxd_ip_address.v6[2] = 0x00000000; + dest_address[2].nxd_ip_address.v6[3] = 0x01020305; + + dest_mac[2][0] = 0x11; + dest_mac[2][1] = 0x22; + dest_mac[2][2] = 0x33; + dest_mac[2][3] = 0x44; + dest_mac[2][4] = 0x66; + dest_mac[2][5] = 0x69; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[2].nxd_ip_address.v6[0], 1, &dest_mac[2][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Set the Destination address and mac address. */ + dest_address[3].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[3].nxd_ip_address.v6[0] = 0x20020000; + dest_address[3].nxd_ip_address.v6[1] = 0x00000000; + dest_address[3].nxd_ip_address.v6[2] = 0x00000000; + dest_address[3].nxd_ip_address.v6[3] = 0x01020306; + + dest_mac[3][0] = 0x11; + dest_mac[3][1] = 0x22; + dest_mac[3][2] = 0x33; + dest_mac[3][3] = 0x44; + dest_mac[3][4] = 0x66; + dest_mac[3][5] = 0x70; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[3].nxd_ip_address.v6[0], 1, &dest_mac[3][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Find the hardware address and interface index by ipv6 address. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[0], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 0) || + (physical_msw != 0x00001122) || + (physical_lsw != 0x33445569)) + error_counter ++; + + /* Find the hardware address and interface index by ipv6 address. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[3], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 1) || + (physical_msw != 0x00001122) || + (physical_lsw != 0x33446670)) + error_counter ++; + + /* Find the ipv6 address and interface index by hardware address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33445570, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 0) || + (ipv6_address.nxd_ip_address.v6[0] != dest_address[1].nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != dest_address[1].nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != dest_address[1].nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != dest_address[1].nxd_ip_address.v6[3])) + error_counter ++; + + /* Find the ipv6 address and interface index by hardware address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33446669, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 1) || + (ipv6_address.nxd_ip_address.v6[0] != dest_address[2].nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != dest_address[2].nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != dest_address[2].nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != dest_address[2].nxd_ip_address.v6[3])) + error_counter ++; + + /* Set an invalid address. */ + invalid_address.nxd_ip_version = NX_IP_VERSION_V6; + invalid_address.nxd_ip_address.v6[0] = 0x30000000; + invalid_address.nxd_ip_address.v6[1] = 0x00000000; + invalid_address.nxd_ip_address.v6[2] = 0x00000000; + invalid_address.nxd_ip_address.v6[3] = 0x11111111; + + /* Delete the ND Cache entry with invalid address. */ + status = nxd_nd_cache_entry_delete(&ip_0, &invalid_address.nxd_ip_address.v6[0]); + + /* Check status. */ + if(status != NX_ENTRY_NOT_FOUND) + error_counter++; + + /* Delete the ND Cache entry. */ + status = nxd_nd_cache_entry_delete(&ip_0, &dest_address[0].nxd_ip_address.v6[0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Find the destination address 0. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[0], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Invalidate the all address. */ + status = nxd_nd_cache_invalidate(&ip_0); + + /* Check status. */ + if(status) + error_counter++; + + /* Find the mac address 0 by destination address 0. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[0], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the mac address 1 by destination address 1. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[1], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the mac address 2 by destination address 2. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[2], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the mac address 3 by destination address 3. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[3], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the ipv6 address 0 by hardware address 0. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33445569, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the ipv6 address 1 by hardware address 1. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33445570, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the ipv6 address 2 by hardware address 2. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33446669, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the ipv6 address 3 by hardware address 3. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33446670, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ND Cache API Test.........................................N/A\n"); + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_nd_cache_branch_test.c b/test/regression/netxduo_test/netx_nd_cache_branch_test.c new file mode 100644 index 00000000..d42718bc --- /dev/null +++ b/test/regression/netxduo_test/netx_nd_cache_branch_test.c @@ -0,0 +1,187 @@ +/* This NetX test concentrates on the code coverage for ND functions, + * _nx_nd_cache_delete_internal.c + * _nx_nd_cache_find_entry.c + * _nx_nd_cache_find_entry_by_mac_addr.c + */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#ifdef FEATURE_NX_IPV6 +#include "tx_thread.h" +#include "nx_icmp.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_branch_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ICMP processing for IP instance. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ICMP enable status. */ + if (status) + error_counter++; + + /* Enable IPv6 processing for IP instance. */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + +ULONG address_1[4]; +ND_CACHE_ENTRY *cache_entry; + + /* Print out some test information banners. */ + printf("NetX Test: ND CACHE Branch Test......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + + + /* Hit false condition of while (table_size && i < NX_IPV6_DESTINATION_TABLE_SIZE) in _nx_nd_cache_delete_internal . */ + ip_0.nx_ipv6_destination_table_size = NX_IPV6_DESTINATION_TABLE_SIZE + 1; + _nx_nd_cache_delete_internal(&ip_0, &ip_0.nx_ipv6_nd_cache[0]); + ip_0.nx_ipv6_destination_table_size = 0; + + + /* Hit false condition of (ip_0.nx_ipv6_nd_cache[index].nx_nd_cache_interface_ptr) in _nx_nd_cache_find_entry . */ + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_nd_status = ND_CACHE_STATE_CREATED; + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_interface_ptr = NX_NULL; + address_1[0] = 0x00000000; + address_1[1] = 0x00000000; + address_1[2] = 0x00000000; + address_1[3] = 0x00000000; + _nx_nd_cache_find_entry(&ip_0, address_1, &cache_entry); + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_nd_status = ND_CACHE_STATE_INVALID; + + + /* Hit condition of if ((mac_msw == physical_msw) && (mac_lsw == physical_lsw)) in _nx_nd_cache_find_entry_by_mac_addr. */ + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_nd_status = ND_CACHE_STATE_CREATED; + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_interface_ptr = &ip_0.nx_ip_interface[0]; + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_mac_addr[0] = 0x00; + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_mac_addr[1] = 0x11; + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_mac_addr[2] = 0x22; + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_mac_addr[3] = 0x33; + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_mac_addr[4] = 0x44; + ip_0.nx_ipv6_nd_cache[0].nx_nd_cache_mac_addr[5] = 0x56; + _nx_nd_cache_find_entry_by_mac_addr(&ip_0, 0x0000, 0x22334456, &cache_entry); + _nx_nd_cache_find_entry_by_mac_addr(&ip_0, 0x0011, 0x22334456, &cache_entry); + memset(&ip_0.nx_ipv6_nd_cache[0], 0, sizeof(ip_0.nx_ipv6_nd_cache[0])); + + + /* Hit false condition of (i < NX_IPV6_DESTINATION_TABLE_SIZE) in _nx_invalidate_destination_entry. */ + ip_0.nx_ipv6_destination_table_size = NX_IPV6_DESTINATION_TABLE_SIZE + 1; + address_1[0] = 0x90010001; + address_1[1] = 0x00000002; + address_1[2] = 0x00000003; + address_1[3] = 0x00000004; + _nx_invalidate_destination_entry(&ip_0, address_1); + ip_0.nx_ipv6_destination_table_size = 0; + + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_branch_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ND CACHE Branch Test......................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_nd_cache_nxe_api_test.c b/test/regression/netxduo_test/netx_nd_cache_nxe_api_test.c new file mode 100644 index 00000000..985bd251 --- /dev/null +++ b/test/regression/netxduo_test/netx_nd_cache_nxe_api_test.c @@ -0,0 +1,420 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined NX_DISABLE_ERROR_CHECKING && defined FEATURE_NX_IPV6 +#include "nx_nd_cache.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP invalid_ip; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS ipv6_address; +CHAR mac_addr[6]; +ULONG physical_msw; +ULONG physical_lsw; +UINT interface_index; + + /* Print out some test information banners. */ + printf("NetX Test: ND CACHE NXE API Test....................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 address. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address.nxd_ip_address.v6[0] = 0x20020000; + ipv6_address.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address.nxd_ip_address.v6[3] = 0x01020306; + + /* Set the MAC address. */ + mac_addr[0] = 0x00; + mac_addr[0] = 0x11; + mac_addr[0] = 0x22; + mac_addr[0] = 0x33; + mac_addr[0] = 0x44; + mac_addr[0] = 0x58; + + /************************************************/ + /* Tested the nxe_arp_entry_delete api */ + /************************************************/ + + /* Delete the entry for NULL IP instance. */ + status = nxd_nd_cache_entry_delete(NX_NULL, &ipv6_address.nxd_ip_address.v6[0]); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the entry for invalid IP instance. */ + status = nxd_nd_cache_entry_delete(&invalid_ip, &ipv6_address.nxd_ip_address.v6[0]); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the entry with NULL IP address pointer. */ + status = nxd_nd_cache_entry_delete(&ip_0, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /**********************************************/ + /* Tested the nxde_nd_cache_entry_set api */ + /**********************************************/ + + /* Set the ND CACHE entry for NULL IP instance. */ + status = nxd_nd_cache_entry_set(NX_NULL, &ipv6_address.nxd_ip_address.v6[0], 0, mac_addr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Set the ND CACHE entry for invalid IP instance. */ + status = nxd_nd_cache_entry_set(&invalid_ip, &ipv6_address.nxd_ip_address.v6[0], 0, mac_addr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the ND CACHE entry with NULL ipv6 address pointer. */ + status = nxd_nd_cache_entry_set(&ip_0, NX_NULL, 0, mac_addr); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the ND CACHE entry with NULL mac address pointer. */ + status = nxd_nd_cache_entry_set(&ip_0, &ipv6_address.nxd_ip_address.v6[0], 0, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the ND CACHE entry with MAX interface index. */ + status = nxd_nd_cache_entry_set(&ip_0, &ipv6_address.nxd_ip_address.v6[0], NX_MAX_PHYSICAL_INTERFACES, mac_addr); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /******************************************************/ + /* Tested the nxde_nd_cache_hardware_address_find api */ + /******************************************************/ + + /* Find the hardware address for NULL IP instance. */ + status = nxd_nd_cache_hardware_address_find(NX_NULL, &ipv6_address, &physical_msw, &physical_lsw, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Find the hardware address for invalid IP instance. */ + status = nxd_nd_cache_hardware_address_find(&invalid_ip, &ipv6_address, &physical_msw, &physical_lsw, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address with NULL address pointer. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, NX_NULL, &physical_msw, &physical_lsw, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address for valid IP instance with invalid physical_msw pointer. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &ipv6_address, NX_NULL, &physical_lsw, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address for valid IP instance with invalid physical_msw pointer. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &ipv6_address, &physical_msw, NX_NULL, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the hardware address for valid IP instance with NULL interface index pointer. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &ipv6_address, &physical_msw, &physical_lsw, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 address with invalid version. */ + ipv6_address.nxd_ip_version = NX_IP_VERSION_V4; + + /* Find the hardware address with invalid address version. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &ipv6_address, &physical_msw, &physical_lsw, &interface_index); + + /* Check for error. */ + if (status != NX_INVALID_PARAMETERS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /*******************************************/ + /* Tested the nxde_nd_cache_invalidate api */ + /*******************************************/ + + /* Delete the ND Cache entries for NULL IP instance. */ + status = nxd_nd_cache_invalidate(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Delete the ND Cache entries for invalid IP instance. */ + status = nxd_nd_cache_invalidate(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxde_nd_cache_ip_address_find api */ + /************************************************/ + + /* Find the ip address for NULL IP instance. */ + status = nxd_nd_cache_ip_address_find(NX_NULL, &ipv6_address, 0x0011, 0x22334456, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Find the ip address for invalid IP instance. */ + status = nxd_nd_cache_ip_address_find(&invalid_ip, &ipv6_address, 0x0011, 0x22334456, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the ip address with NULL ip address pointer. */ + status = nxd_nd_cache_ip_address_find(&ip_0, NX_NULL, 0x0011, 0x22334456, &interface_index); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the ip address with NULL interface index pointer. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x0011, 0x22334456, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the ip address with invalid physcial address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0, 0, &interface_index); + + /* Check for error. */ + if (status != NX_INVALID_PARAMETERS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the ip address with valid physcial address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0, 1, &interface_index); + + /* Check for error. */ + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ND CACHE NXE API Test.....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_nd_cache_under_interface_detach_test.c b/test/regression/netxduo_test/netx_nd_cache_under_interface_detach_test.c new file mode 100644 index 00000000..e745e0a2 --- /dev/null +++ b/test/regression/netxduo_test/netx_nd_cache_under_interface_detach_test.c @@ -0,0 +1,324 @@ +/* Test IPv6 ND CACHE APIs. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#define MAX_TEST_INTERFACES 2 + +#if defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES >= MAX_TEST_INTERFACES) +#include "nx_ip.h" +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static NXD_ADDRESS ipv6_address_0; +static NXD_ADDRESS ipv6_address_1; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_under_interface_detach_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + ipv6_address_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[3] = 0x01020304; + + status += nxd_ipv6_address_set(&ip_0, 0,&ipv6_address_0, 64, NX_NULL); + + if(status) + error_counter++; + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_512); + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20020000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x01020304; + + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_1, 64, NX_NULL); + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS dest_address[4]; +CHAR dest_mac[4][6]; +NXD_ADDRESS ipv6_address; +ULONG physical_msw; +ULONG physical_lsw; +UINT interface_index; + + /* Print out test information banner. */ + printf("NetX Test: ND Cache Under Interface Detach Test......................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the Destination address and mac address. */ + dest_address[0].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[0].nxd_ip_address.v6[0] = 0x20010000; + dest_address[0].nxd_ip_address.v6[1] = 0x00000000; + dest_address[0].nxd_ip_address.v6[2] = 0x00000000; + dest_address[0].nxd_ip_address.v6[3] = 0x01020305; + + dest_mac[0][0] = 0x11; + dest_mac[0][1] = 0x22; + dest_mac[0][2] = 0x33; + dest_mac[0][3] = 0x44; + dest_mac[0][4] = 0x55; + dest_mac[0][5] = 0x69; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[0].nxd_ip_address.v6[0], 0, &dest_mac[0][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Set the Destination address and mac address. */ + dest_address[1].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[1].nxd_ip_address.v6[0] = 0x20010000; + dest_address[1].nxd_ip_address.v6[1] = 0x00000000; + dest_address[1].nxd_ip_address.v6[2] = 0x00000000; + dest_address[1].nxd_ip_address.v6[3] = 0x01020306; + + dest_mac[1][0] = 0x11; + dest_mac[1][1] = 0x22; + dest_mac[1][2] = 0x33; + dest_mac[1][3] = 0x44; + dest_mac[1][4] = 0x55; + dest_mac[1][5] = 0x70; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[1].nxd_ip_address.v6[0], 0, &dest_mac[1][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Set the Destination address and mac address. */ + dest_address[2].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[2].nxd_ip_address.v6[0] = 0x20020000; + dest_address[2].nxd_ip_address.v6[1] = 0x00000000; + dest_address[2].nxd_ip_address.v6[2] = 0x00000000; + dest_address[2].nxd_ip_address.v6[3] = 0x01020305; + + dest_mac[2][0] = 0x11; + dest_mac[2][1] = 0x22; + dest_mac[2][2] = 0x33; + dest_mac[2][3] = 0x44; + dest_mac[2][4] = 0x66; + dest_mac[2][5] = 0x69; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[2].nxd_ip_address.v6[0], 1, &dest_mac[2][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Set the Destination address and mac address. */ + dest_address[3].nxd_ip_version = NX_IP_VERSION_V6; + dest_address[3].nxd_ip_address.v6[0] = 0x20020000; + dest_address[3].nxd_ip_address.v6[1] = 0x00000000; + dest_address[3].nxd_ip_address.v6[2] = 0x00000000; + dest_address[3].nxd_ip_address.v6[3] = 0x01020306; + + dest_mac[3][0] = 0x11; + dest_mac[3][1] = 0x22; + dest_mac[3][2] = 0x33; + dest_mac[3][3] = 0x44; + dest_mac[3][4] = 0x66; + dest_mac[3][5] = 0x70; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address[3].nxd_ip_address.v6[0], 1, &dest_mac[3][0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Find the hardware address and interface index by ipv6 address. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[2], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 1) || + (physical_msw != 0x00001122) || + (physical_lsw != 0x33446669)) + error_counter ++; + + /* Find the hardware address and interface index by ipv6 address. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[3], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 1) || + (physical_msw != 0x00001122) || + (physical_lsw != 0x33446670)) + error_counter ++; + + /* Find the ipv6 address and interface index by hardware address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33446669, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 1) || + (ipv6_address.nxd_ip_address.v6[0] != dest_address[2].nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != dest_address[2].nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != dest_address[2].nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != dest_address[2].nxd_ip_address.v6[3])) + error_counter ++; + + /* Find the ipv6 address and interface index by hardware address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33446670, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 1) || + (ipv6_address.nxd_ip_address.v6[0] != dest_address[3].nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != dest_address[3].nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != dest_address[3].nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != dest_address[3].nxd_ip_address.v6[3])) + error_counter ++; + + /* Detach the second interface. */ + status = nx_ip_interface_detach(&ip_0, 1); + + /* Check status. */ + if(status) + error_counter++; + + /* Find the hardware address and interface index by ipv6 address. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[2], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status != NX_ENTRY_NOT_FOUND) + error_counter++; + + /* Find the hardware address and interface index by ipv6 address. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address[3], &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status != NX_ENTRY_NOT_FOUND) + error_counter++; + + /* Find the ipv6 address and interface index by hardware address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33446669, &interface_index); + + /* Check status. */ + if(status != NX_ENTRY_NOT_FOUND) + error_counter++; + + /* Find the ipv6 address and interface index by hardware address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00001122, 0x33446670, &interface_index); + + /* Check status. */ + if(status != NX_ENTRY_NOT_FOUND) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_under_interface_detach_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ND Cache Under Interface Detach Test......................N/A\n"); + test_control_return(3); +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_nd_cache_with_own_address_test.c b/test/regression/netxduo_test/netx_nd_cache_with_own_address_test.c new file mode 100644 index 00000000..5ef0ba12 --- /dev/null +++ b/test/regression/netxduo_test/netx_nd_cache_with_own_address_test.c @@ -0,0 +1,239 @@ +/* Test IPv6 ND CACHE APIs. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_IPV6_DAD) +#include "nx_ip.h" +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_with_own_address_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMPv6 */ + status = nxd_icmp_enable(&ip_0); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS dest_address; +CHAR dest_mac[6]; +NXD_ADDRESS ipv6_address; +ULONG physical_msw; +ULONG physical_lsw; +UINT interface_index; +UINT address_index; + + /* Print out test information banner. */ + printf("NetX Test: ND Cache With Own Address Test............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IPv6 linklocal address for IP instance 0. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Set the Destination address and mac address. */ + dest_address.nxd_ip_version = NX_IP_VERSION_V6; + dest_address.nxd_ip_address.v6[0] = 0xfe800000; + dest_address.nxd_ip_address.v6[1] = 0x00000000; + dest_address.nxd_ip_address.v6[2] = 0x021122ff; + dest_address.nxd_ip_address.v6[3] = 0xfe334457; + + dest_mac[0] = 0x00; + dest_mac[1] = 0x11; + dest_mac[2] = 0x22; + dest_mac[3] = 0x33; + dest_mac[4] = 0x44; + dest_mac[5] = 0x57; + + /* Set the ND CACHE entry. */ + status = nxd_nd_cache_entry_set(&ip_0, &dest_address.nxd_ip_address.v6[0], 0, &dest_mac[0]); + + /* Check status. */ + if(status) + error_counter++; + + /* Find the hardware address and interface index by ipv6 address. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address, &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 0) || + (physical_msw != 0x00000011) || + (physical_lsw != 0x22334457)) + error_counter ++; + + /* Find the ipv6 address and interface index by hardware address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00000011, 0x22334457, &interface_index); + + /* Check status. */ + if(status) + error_counter++; + + /* Match the mac address and interface index. */ + if ((interface_index != 0) || + (ipv6_address.nxd_ip_address.v6[0] != dest_address.nxd_ip_address.v6[0]) || + (ipv6_address.nxd_ip_address.v6[1] != dest_address.nxd_ip_address.v6[1]) || + (ipv6_address.nxd_ip_address.v6[2] != dest_address.nxd_ip_address.v6[2]) || + (ipv6_address.nxd_ip_address.v6[3] != dest_address.nxd_ip_address.v6[3])) + error_counter ++; + + /* Delete the linklocal address. */ + nxd_ipv6_address_delete(&ip_0, address_index); + + /* Set the physical address. */ + physical_msw = 0x00000011; + physical_lsw = 0x22334457; + + /* Set the interface capability. */ + status = nx_ip_interface_physical_address_set(&ip_0, 0, physical_msw, physical_lsw, NX_TRUE); + + /* Check the status. */ + if (status) + error_counter++; + + /* Set the IPv6 linklocal address for IP instance 0. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); + + /* Check the status. */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 5 seconds for Duplicate Address Detected. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* The linklocal address is same as nd cache address, the ND entry should be invalid. */ + + /* Find the hardware address and interface index by ipv6 address. */ + status = nxd_nd_cache_hardware_address_find(&ip_0, &dest_address, &physical_msw, &physical_lsw, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Find the ipv6 address and interface index by hardware address. */ + status = nxd_nd_cache_ip_address_find(&ip_0, &ipv6_address, 0x00000011, 0x22334456, &interface_index); + + /* Check status. */ + if(status == NX_SUCCESS) + error_counter++; + + /* Check the error counter. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nd_cache_with_own_address_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: ND Cache With Own Address Test............................N/A\n"); + test_control_return(3); +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_nxd_udp_socket_send_special_test.c b/test/regression/netxduo_test/netx_nxd_udp_socket_send_special_test.c new file mode 100644 index 00000000..ee89ae43 --- /dev/null +++ b/test/regression/netxduo_test/netx_nxd_udp_socket_send_special_test.c @@ -0,0 +1,269 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static NX_UDP_SOCKET socket_0; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_0; +static NXD_ADDRESS address_1; +static NXD_ADDRESS address_3; +/* Used to construct a packet whose checksum is 0. */ +static UCHAR data[4096 * 32 + 2]; +#endif +static NXD_ADDRESS address_2; + +static UCHAR pool_area[1536*120]; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nxd_udp_socket_send_special_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pool_area, sizeof(pool_area)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable IPv6 traffic. */ +#ifdef FEATURE_NX_IPV6 + status = nxd_ipv6_enable(&ip_0); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Set source and destination address with global address. */ + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0x20010DB8; + address_0.nxd_ip_address.v6[1] = 0x00010001; + address_0.nxd_ip_address.v6[2] = 0x021122FF; + address_0.nxd_ip_address.v6[3] = 0xFE334456; + + /* Set the destination address. */ + address_1.nxd_ip_version = NX_IP_VERSION_V6; + address_1.nxd_ip_address.v6[0] = 0x20010DB8; + address_1.nxd_ip_address.v6[1] = 0x00010001; + address_1.nxd_ip_address.v6[2] = 0x021122FF; + address_1.nxd_ip_address.v6[3] = 0xFE334499; + + /* Set the IPv6 address. */ + status += nxd_ipv6_address_set(&ip_0, 0, &address_0, 64, NX_NULL); + + /* Check for status. */ + if (status) + error_counter++; + + address_3.nxd_ip_version = NX_IP_VERSION_V6; + address_3.nxd_ip_address.v6[0] = 0x30010DB8; + address_3.nxd_ip_address.v6[1] = 0x00010001; + address_3.nxd_ip_address.v6[2] = 0x021122FF; + address_3.nxd_ip_address.v6[3] = 0xFE334499; +#endif /* FEATURE_NX_IPV6 */ + + address_2.nxd_ip_version = NX_IP_VERSION_V4; + address_2.nxd_ip_address.v4 = IP_ADDRESS(111, 222, 222, 222); +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: NXD UDP Socket Send Special Test.........................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Create udp socket without ip instance. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the packet. */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Socket is not bound, should return error. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_2, 0x89); + if(status != NX_NOT_BOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, 2 * NX_IP_PERIODIC_RATE); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the the packet with an address that will cause route fail. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_2, 0x89); + if (status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Send the the packet with an address that will cause route fail. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_3, 0x89); + if (status != NX_NO_INTERFACE_ADDRESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + + nx_packet_release(my_packet); + +#ifdef FEATURE_NX_IPV6 + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set data to let checksum be 0. */ + memset(data, 0xff, 4096 * 32 + 2); + data[4096*32 - 1] = 0x9f; + data[4096*32] = 0xd5; + data[4096*32 + 1] = 0x39; + + status = nx_packet_data_append(my_packet, data, sizeof(data), &pool_0, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the UDP packet. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_nxd_udp_socket_send_special_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NXD UDP Socket Send Special Test..........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_old_api_test.c b/test/regression/netxduo_test/netx_old_api_test.c new file mode 100644 index 00000000..9cad2919 --- /dev/null +++ b/test/regression/netxduo_test/netx_old_api_test.c @@ -0,0 +1,141 @@ +/* This case tests if compile works with old APIs. */ + +#include "nx_api.h" +#include "tx_api.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static TX_THREAD ntest_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +static void ntest_0_entry(ULONG thread_input); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_old_api_application_define(void *first_unused_memory) +#endif +{ +UCHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +#if defined(__PRODUCT_NETXDUO__) +NX_PACKET *packet_ptr; +NX_UDP_SOCKET udp_socket; +#ifdef FEATURE_NX_IPV6 + +NXD_ADDRESS src_address; + + /* Set source and destination address with global address. */ + src_address.nxd_ip_version = NX_IP_VERSION_V6; + src_address.nxd_ip_address.v6[0] = 0x20010DB8; + src_address.nxd_ip_address.v6[1] = 0x00010001; + src_address.nxd_ip_address.v6[2] = 0x021122FF; + src_address.nxd_ip_address.v6[3] = 0xFE334456; + + nxd_ipv6_address_set(&ip_0, 0, &src_address, 64, NX_NULL); +#endif + + /* Test old APIs. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, TX_NO_WAIT); + nx_ip_raw_packet_interface_send(&ip_0, packet_ptr, IP_ADDRESS(1, 2, 3, 5), 0, NX_IP_NORMAL); + + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, TX_NO_WAIT); + nx_udp_socket_create(&ip_0, &udp_socket, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + nx_udp_socket_bind(&udp_socket, 0x88, TX_WAIT_FOREVER); + nx_udp_socket_interface_send(&udp_socket, packet_ptr, IP_ADDRESS(1, 2, 3, 5), 87, 0); + +#ifdef FEATURE_NX_IPV6 + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, TX_NO_WAIT); + nxd_ip_raw_packet_interface_send(&ip_0, packet_ptr, &src_address, 0, 100, 255, NX_IP_NORMAL); + + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, TX_NO_WAIT); + nxd_udp_socket_interface_send(&udp_socket, packet_ptr, &src_address, 87, 0); + + nxd_icmp_interface_ping(&ip_0, &src_address, 0, "test", 4, &packet_ptr, TX_NO_WAIT); +#endif + + /* Test new APIs. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, TX_NO_WAIT); + nx_ip_raw_packet_interface_send(&ip_0, packet_ptr, IP_ADDRESS(1, 2, 3, 5), 0, NX_IP_NORMAL); + + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, TX_NO_WAIT); + nx_udp_socket_source_send(&udp_socket, packet_ptr, IP_ADDRESS(1, 2, 3, 5), 87, 0); + +#ifdef FEATURE_NX_IPV6 + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, TX_NO_WAIT); + nxd_ip_raw_packet_source_send(&ip_0, packet_ptr, &src_address, 0, 100, 255, NX_IP_NORMAL); + + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, TX_NO_WAIT); + nxd_udp_socket_source_send(&udp_socket, packet_ptr, &src_address, 87, 0); + + nxd_icmp_source_ping(&ip_0, &src_address, 0, "test", 4, &packet_ptr, TX_NO_WAIT); +#endif + + printf("NetX Test: Old APIs Test.............................................SUCCESS!\n"); + test_control_return(0); +#endif +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_old_api_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: Old APIs Test.............................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_packet_basic_test.c b/test/regression/netxduo_test/netx_packet_basic_test.c new file mode 100644 index 00000000..114030c0 --- /dev/null +++ b/test/regression/netxduo_test/netx_packet_basic_test.c @@ -0,0 +1,733 @@ +/* This NetX test concentrates on the basic packet operations. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_packet.h" + +#define DEMO_STACK_SIZE 2048 + +#define TEST_SIZE (NX_UDP_PACKET+28) + +#ifndef NX_PACKET_ALIGNMENT +#define NX_PACKET_ALIGNMENT sizeof(ULONG) +#endif /* NX_PACKET_ALIGNMENT */ + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_PACKET_POOL pool_2; +#ifdef NX_DISABLE_ERROR_CHECKING +static NX_PACKET_POOL pool_3; +#endif +static NX_PACKET_POOL pool_4; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pool_0_ptr; +static CHAR *pool_1_ptr; +static CHAR *pool_2_ptr; +#ifdef NX_DISABLE_ERROR_CHECKING +static CHAR *pool_3_ptr; +#endif +static CHAR *pool_4_ptr; +static ULONG pool_0_size; + + +static UCHAR buffer[2048]; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_packet_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + pool_0_ptr = NX_NULL; + pool_1_ptr = NX_NULL; + pool_2_ptr = NX_NULL; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create first packet pool. */ + pointer = (CHAR *)(((ALIGN_TYPE)pointer + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)); + pool_0_ptr = pointer; + pool_0_size = (((TEST_SIZE + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)) + ((sizeof(NX_PACKET) + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1))) * 3; + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", TEST_SIZE, pool_0_ptr, pool_0_size); + + pointer = pointer + pool_0_size; + if (status) + error_counter++; + + /* Create second packet pool. */ + pointer = (CHAR *)(((ALIGN_TYPE)pointer + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)); + status = nx_packet_pool_create(&pool_1, "NetX Second Packet Pool", 200, pointer, 1000); + pool_1_ptr = pointer; + pointer = pointer + 1000; + + if (status) + error_counter++; + + /* Create third packet pool. */ + pointer = (CHAR *)(((ALIGN_TYPE)pointer + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)); + status = nx_packet_pool_create(&pool_2, "NetX Third Packet Pool", 256, pointer, 8192); + pool_2_ptr = pointer; + pointer = pointer + 8192; + + if (status) + error_counter++; + +#ifdef NX_DISABLE_ERROR_CHECKING + /* Create fourth packet pool, small pool size. */ + status = nx_packet_pool_create(&pool_3, "NetX Fourth Packet Pool", 256, pointer, 200); + pool_3_ptr = pointer; + pointer = pointer + 200; + + if (status) + error_counter++; +#endif + + /* Create fourth packet pool, small pool size. */ + pointer = (CHAR *)(((ALIGN_TYPE)pointer + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)); + status = nx_packet_pool_create(&pool_4, "NetX Fifth Packet Pool", 252, pointer, 8192); + pool_4_ptr = pointer; + pointer = pointer + 8192; + + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +NX_PACKET *my_packet4; +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) +NX_PACKET *packet_ptr; +#endif /* !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) */ +ULONG size; +UCHAR local_buffer[300]; +ULONG total_packets, free_packets, empty_pool_requests, empty_pool_suspensions, invalid_packet_releases; + + /* Print out test information banner. */ + printf("NetX Test: Packet Basic Processing Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete all the packet pools. */ + status = nx_packet_pool_delete(&pool_0); + status += nx_packet_pool_delete(&pool_1); + status += nx_packet_pool_delete(&pool_2); +#ifdef NX_DISABLE_ERROR_CHECKING + status += nx_packet_pool_delete(&pool_3); +#endif + status += nx_packet_pool_delete(&pool_4); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the pools again. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", TEST_SIZE, pool_0_ptr, pool_0_size); + status += nx_packet_pool_create(&pool_1, "NetX Second Packet Pool", TEST_SIZE, pool_1_ptr, 1000); + status += nx_packet_pool_create(&pool_2, "NetX Third Packet Pool", 256, pool_2_ptr, 8192); +#ifdef NX_DISABLE_ERROR_CHECKING + status += nx_packet_pool_create(&pool_3, "NetX Fourth Packet Pool", 256, pool_3_ptr, 200); +#endif + status += nx_packet_pool_create(&pool_4, "NetX Fifth Packet Pool", 252, pool_4_ptr, 8192); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate packets. */ + status = nx_packet_allocate(&pool_4, &my_packet1, NX_UDP_PACKET, 10); + status += nx_packet_allocate(&pool_4, &my_packet2, NX_UDP_PACKET, 10); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check alignment. */ + if(((ALIGN_TYPE)my_packet1 & (NX_PACKET_ALIGNMENT - 1)) || + ((ALIGN_TYPE)my_packet2 & (NX_PACKET_ALIGNMENT - 1)) || + ((ALIGN_TYPE)(my_packet1 -> nx_packet_data_start) & (NX_PACKET_ALIGNMENT - 1)) || + ((ALIGN_TYPE)(my_packet2 -> nx_packet_data_start) & (NX_PACKET_ALIGNMENT - 1))) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_release(my_packet1); + status += nx_packet_release(my_packet2); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Allocate packets. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_UDP_PACKET, 10); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_UDP_PACKET, 10); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_UDP_PACKET, 10); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to allocate another packet to get the error return. */ + status = nx_packet_allocate(&pool_0, &my_packet4, NX_UDP_PACKET, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_NO_PACKET) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release all the packets but the first. */ + status = nx_packet_release(my_packet2); + status += nx_packet_release(my_packet3); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Place the alphabet in the packet. */ + status = nx_packet_data_append(my_packet1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Copy the packet to another pool. */ + status = nx_packet_copy(my_packet1, &my_packet2, &pool_1, NX_NO_WAIT); + + /* Check status. */ + if ((status != NX_SUCCESS) || (my_packet2 -> nx_packet_length != 28)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Retrieve the payload from new packet. */ + local_buffer[0] = 0; + status = nx_packet_data_retrieve(my_packet2, local_buffer, &size); + + /* Check status. */ + if ((status) || (my_packet2 -> nx_packet_length != 28) || (size != 28) || (local_buffer[0] != 'A')) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet copy. */ + status = nx_packet_release(my_packet2); + +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) + /* Make sure the packet is chained. */ + while(my_packet1 -> nx_packet_next == (NX_PACKET *)NX_NULL) + { + + /* Append numbers to first message. This will introduce packet chaining. */ + status += nx_packet_data_append(my_packet1, "0102030405060708091011121314151617181920", 40, &pool_0, NX_NO_WAIT); + } + + /* Trim data in the last packet. */ + my_packet1 -> nx_packet_length -= (ULONG)((ALIGN_TYPE)my_packet1 -> nx_packet_last -> nx_packet_append_ptr - (ALIGN_TYPE)my_packet1 -> nx_packet_last -> nx_packet_append_ptr); + my_packet1 -> nx_packet_last = my_packet1; + packet_ptr = my_packet1 -> nx_packet_next; + + /* Append numbers to first message. This will reuse the packet chaining. */ + status += nx_packet_data_append(my_packet1, "abc", 3, &pool_0, NX_NO_WAIT); + + /* Check status. */ + if ((status != NX_SUCCESS) || (my_packet1 -> nx_packet_next != packet_ptr)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Copy the packet to a packet in both pools. This requires chaining and non-chaining. */ + status = nx_packet_copy(my_packet1, &my_packet2, &pool_1, NX_NO_WAIT); + status += nx_packet_copy(my_packet2, &my_packet3, &pool_2, NX_NO_WAIT); + + /* Check status. */ + if ((status != NX_SUCCESS) || + (my_packet2 -> nx_packet_length != my_packet1 -> nx_packet_length) || + (my_packet3 -> nx_packet_length != my_packet2 -> nx_packet_length)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Retrieve the payload from the first new packet. */ + local_buffer[0] = 0; + status = nx_packet_data_retrieve(my_packet2, local_buffer, &size); + + /* Check status. */ + if ((status) || + (my_packet1 -> nx_packet_length != my_packet2 -> nx_packet_length) || + (size != my_packet2 -> nx_packet_length) || + (local_buffer[0] != 'A') || (local_buffer[28] != '0')) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Retrieve the payload from the second new packet. */ + local_buffer[0] = 0; + status = nx_packet_data_retrieve(my_packet3, local_buffer, &size); + + /* Check status. */ + if ((status) || (my_packet3 -> nx_packet_length != my_packet2 -> nx_packet_length) || + (size != my_packet2 -> nx_packet_length) || + (local_buffer[0] != 'A') || (local_buffer[28] != '0')) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_PACKET_CHAIN && __PRODUCT_NETXDUO__ */ + + /* Transmit release all packets. */ + status = nx_packet_transmit_release(my_packet1); + +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) + status += nx_packet_transmit_release(my_packet2); + status += nx_packet_transmit_release(my_packet3); +#endif /* NX_DISABLE_PACKET_CHAIN && __PRODUCT_NETXDUO__ */ + + /* Get nothing from the first pool. */ + status += nx_packet_pool_info_get(&pool_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL); + + /* Get information about the first pool. */ + status += nx_packet_pool_info_get(&pool_0, &total_packets, &free_packets, &empty_pool_requests, &empty_pool_suspensions, &invalid_packet_releases); + +#ifndef NX_DISABLE_PACKET_INFO + + if(empty_pool_requests != 1) + status++; +#endif + + /* Check status. */ + if ((status) || (total_packets != 3) || (free_packets != 3) || (empty_pool_suspensions) || (invalid_packet_releases)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete all the packet pools. */ + status = nx_packet_pool_delete(&pool_0); + status += nx_packet_pool_delete(&pool_1); + status += nx_packet_pool_delete(&pool_2); +#ifdef NX_DISABLE_ERROR_CHECKING + status += nx_packet_pool_delete(&pool_3); +#endif + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Tested the abnormal operation. */ + + /* Create the pools again. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", TEST_SIZE, pool_0_ptr, pool_0_size); + status += nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", TEST_SIZE, pool_1_ptr, 1000); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate the packet. */ + status = nx_packet_allocate(&pool_0, &my_packet1, 0, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Append data that is larger than whole pool. */ + status = nx_packet_data_append(my_packet1, buffer, sizeof(buffer), &pool_0, NX_NO_WAIT); + + /* Check the status. */ + if((!status) ||(pool_0.nx_packet_pool_invalid_releases)) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ + + /* Copy the packet with length 0. */ + status = nx_packet_copy(my_packet1, &my_packet2, &pool_0, NX_NO_WAIT); + + /* Check the status. */ + if(!status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) + /* Append data that is two packet size. */ + status = nx_packet_data_append(my_packet1, buffer, TEST_SIZE * 2, &pool_0, NX_NO_WAIT); + + /* Check the status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Copy the packet when the pool size not enough. */ + status = nx_packet_copy(my_packet1, &my_packet2, &pool_0, NX_NO_WAIT); + + /* Check the status. */ + if(!status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Modify the first packet prepend and append. */ + my_packet1 -> nx_packet_prepend_ptr = my_packet1 -> nx_packet_append_ptr; + my_packet1 -> nx_packet_length = TEST_SIZE; + + /* Copy the packet . */ + status = nx_packet_copy(my_packet1, &my_packet2, &pool_1, NX_NO_WAIT); + + /* Check the status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Release the packet. */ + nx_packet_release(my_packet1); + + /* Allocate the packet. */ + status = nx_packet_allocate(&pool_0, &my_packet1, 0, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Construct the packet data. */ + memcpy(my_packet1 -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 28; + + /* Set the invalid length. */ + my_packet1 -> nx_packet_length = 30; + + /* Copy the packet when the pool size not enough. */ + status = nx_packet_copy(my_packet1, &my_packet2, &pool_0, NX_NO_WAIT); + + /* Check the status. */ + if(!status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Retrieve the packet data. */ + status = nx_packet_data_retrieve(my_packet1, buffer, &size); + + /* Check the status. */ + if(!status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Extract the packet with zero offset. */ + status = nx_packet_data_extract_offset(my_packet1, 30, buffer, sizeof(buffer), &size); + + /* Check the status. */ + if(!status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the invalid packet length. */ + my_packet1 -> nx_packet_length = 0; + + /* Extract the packet with zero offset. */ + status = nx_packet_data_extract_offset(my_packet1, 0, buffer, sizeof(buffer), &size); + + /* Check the status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the valid packet length. */ + my_packet1 -> nx_packet_length = 28; + + /* Extract the packet with small buffer. */ + status = nx_packet_data_extract_offset(my_packet1, 0, buffer, 26, &size); + + /* Check the status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + nx_packet_release(my_packet1); + +#ifndef NX_DISABLE_PACKET_CHAIN + + /* Allocate the packet. */ + status = nx_packet_allocate(&pool_0, &my_packet1, 0, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append data that is two packet size. */ + status = nx_packet_data_append(my_packet1, buffer, TEST_SIZE * 2, &pool_0, NX_NO_WAIT); + + /* Check the status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Extract the packet. */ + status = nx_packet_data_extract_offset(my_packet1, TEST_SIZE, buffer, sizeof(buffer), &size); + + /* Check the status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Extract the packet with small buffer. */ + status = nx_packet_data_extract_offset(my_packet1, 0, buffer, TEST_SIZE, &size); + + /* Check the status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the invalid length. */ + my_packet1 -> nx_packet_length = TEST_SIZE * 3; + + /* Extract the packet with invalid length. */ + status = nx_packet_data_extract_offset(my_packet1, TEST_SIZE * 2, buffer, sizeof(buffer), &size); + + /* Check the status. */ + if(!status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the packet length. */ + my_packet1 -> nx_packet_length = TEST_SIZE * 2; + + /* Try to release this packet. */ + status = nx_packet_release(my_packet1); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + +#ifndef NX_DISABLE_ERROR_CHECKING + /* Allocate the packet with large packet type. */ + status = nx_packet_allocate(&pool_0, &my_packet1, (pool_0.nx_packet_pool_payload_size + 4), NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_INVALID_PARAMETERS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate the packet. */ + status = nx_packet_allocate(&pool_0, &my_packet1, 0, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Modifed the pool owner. */ + my_packet1 -> nx_packet_pool_owner = NX_NULL; + + /* Try to release this packet. */ + status = nx_packet_release(my_packet1); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Modifed the pool owner ID. */ + my_packet1 -> nx_packet_pool_owner = &pool_0; + my_packet1 -> nx_packet_pool_owner -> nx_packet_pool_id = 0; + + /* Try to release this packet. */ + status = nx_packet_release(my_packet1); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Recover the pool ID. */ + my_packet1 -> nx_packet_pool_owner -> nx_packet_pool_id = NX_PACKET_POOL_ID; + + /* Try to release this packet. */ + status = nx_packet_release(my_packet1); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + printf("SUCCESS!\n"); + test_control_return(0); +} + diff --git a/test/regression/netxduo_test/netx_packet_branch_test.c b/test/regression/netxduo_test/netx_packet_branch_test.c new file mode 100644 index 00000000..ad300a65 --- /dev/null +++ b/test/regression/netxduo_test/netx_packet_branch_test.c @@ -0,0 +1,248 @@ +/* This NetX test concentrates on the code coverage for packet functions, + * _nx_packet_transmit_release.c + * _nx_packet_release.c + * _nx_packet_pool_cleanup.c +*/ + +#include "nx_api.h" +#include "tx_thread.h" +#include "nx_packet.h" +#include "nx_ip.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_test1; +static TX_THREAD thread_test2; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static UCHAR buffer[256]; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID suspend_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_packet_branch_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable UDP processing for IP instance. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for IP instance. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG thread_state; +NX_PACKET *my_packet[2]; + + /* Print out some test information banners. */ + printf("NetX Test: Packet Branch Test........................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + +#ifdef __PRODUCT_NETXDUO__ + /* Test _nx_packet_data_adjust() */ + /* header size (512) is larger than the payload size (256). */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + if (_nx_packet_data_adjust(my_packet[0], 512) == NX_SUCCESS) + { + error_counter++; + } + nx_packet_release(my_packet[0]); + +#ifndef NX_DISABLE_PACKET_CHAIN + /* header size (255) is odd and larger than the available size of the first packet. */ + nx_packet_allocate(&pool_0, &my_packet[0], 128, NX_NO_WAIT); + nx_packet_data_append(my_packet[0], buffer, sizeof(buffer), &pool_0, NX_NO_WAIT); + if (_nx_packet_data_adjust(my_packet[0], 255) == NX_SUCCESS) + { + error_counter++; + } + nx_packet_release(my_packet[0]); + + /* Adjust packet with packet chain. */ + nx_packet_allocate(&pool_0, &my_packet[0], 128, NX_NO_WAIT); + nx_packet_data_append(my_packet[0], buffer, sizeof(buffer), &pool_0, NX_NO_WAIT); + if (_nx_packet_data_adjust(my_packet[0], 256) != NX_SUCCESS) + { + error_counter++; + } + nx_packet_release(my_packet[0]); +#endif /* NX_DISABLE_PACKET_CHAIN */ +#endif /* __PRODUCT_NETXDUO__ */ + + + /* Allocate the packet. */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + + /* Release the packet. */ + _nx_packet_transmit_release(my_packet[0]); + + /* Release the packet again. */ + _nx_packet_transmit_release(my_packet[0]); + + + +#ifdef __PRODUCT_NETXDUO__ + /* Hit condition of if ((pool_ptr) && (pool_ptr -> nx_packet_pool_id == NX_PACKET_POOL_ID)) in _nx_packet_release(). */ + /* Allocate the packet. */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + nx_packet_allocate(&pool_0, &my_packet[1], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ENQUEUED; + my_packet[0] -> nx_packet_pool_owner -> nx_packet_pool_id = 0; + _nx_packet_release(my_packet[0]); +#ifndef NX_DISABLE_PACKET_CHAIN + my_packet[0] -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; + my_packet[0] -> nx_packet_next = my_packet[1]; + my_packet[1] -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ENQUEUED; + my_packet[1] -> nx_packet_pool_owner = NX_NULL; + _nx_packet_release(my_packet[0]); + + /* Recover. */ + my_packet[0] -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; + my_packet[0] -> nx_packet_pool_owner = &pool_0; + my_packet[0] -> nx_packet_pool_owner -> nx_packet_pool_id = NX_PACKET_POOL_ID; + my_packet[0] -> nx_packet_next = NX_NULL; + my_packet[1] -> nx_packet_pool_owner = &pool_0; +#else + + /* Recover. */ + my_packet[0] -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; + my_packet[0] -> nx_packet_pool_owner = &pool_0; + my_packet[0] -> nx_packet_pool_owner -> nx_packet_pool_id = NX_PACKET_POOL_ID; +#endif + _nx_packet_release(my_packet[0]); + _nx_packet_release(my_packet[1]); +#endif /* __PRODUCT_NETXDUO__ */ + + + + /* Test _nx_packet_pool_cleanup(). */ + /* tx_thread_suspend_control_block is set to NULL. */ + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + _nx_packet_pool_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* tx_thread_suspend_control_block is set to POOL but tx_thread_suspend_cleanup is set to NULL. */ + tx_thread_identify() -> tx_thread_suspend_control_block = &pool_0; + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + _nx_packet_pool_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* tx_thread_suspend_control_block is set to IP and tx_thread_suspend_cleanup is set to suspend_cleanup, but clear the IP ID. */ + tx_thread_identify() -> tx_thread_suspend_control_block = &pool_0; + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + pool_0.nx_packet_pool_id = 0; + _nx_packet_pool_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + pool_0.nx_packet_pool_id = NX_PACKET_POOL_ID; + + pool_0.nx_packet_pool_suspended_count ++; + tx_thread_identify() -> tx_thread_suspend_control_block = &pool_0; + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspended_next = tx_thread_identify(); + thread_state = tx_thread_identify() -> tx_thread_state; + tx_thread_identify() -> tx_thread_state = 0; + _nx_packet_pool_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + tx_thread_identify() -> tx_thread_state = thread_state; + + pool_0.nx_packet_pool_suspended_count ++; + tx_thread_identify() -> tx_thread_suspend_control_block = &pool_0; + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspended_next = &thread_test1; + tx_thread_identify() -> tx_thread_suspended_previous = &thread_test2; + thread_state = tx_thread_identify() -> tx_thread_state; + tx_thread_identify() -> tx_thread_state = 0; + _nx_packet_pool_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + tx_thread_identify() -> tx_thread_state = thread_state; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static VOID suspend_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER) +{ +} + diff --git a/test/regression/netxduo_test/netx_packet_data_append_test.c b/test/regression/netxduo_test/netx_packet_data_append_test.c new file mode 100644 index 00000000..e0e8695e --- /dev/null +++ b/test/regression/netxduo_test/netx_packet_data_append_test.c @@ -0,0 +1,131 @@ +/* This NetX test concentrates on the basic packet operations. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_packet.h" + +#define DEMO_STACK_SIZE 2048 + +#define TEST_SIZE (NX_UDP_PACKET+28) + +#ifndef NX_PACKET_ALIGNMENT +#define NX_PACKET_ALIGNMENT sizeof(ULONG) +#endif /* NX_PACKET_ALIGNMENT */ + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) +static UCHAR buffer[2048]; +#endif + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_packet_data_append_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the pools again. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", TEST_SIZE, pointer, (TEST_SIZE + sizeof(NX_PACKET)) * 10); + pointer = pointer + ((TEST_SIZE + sizeof(NX_PACKET)) * 10); + + /* Check status */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) +UINT status; +NX_PACKET *my_packet; +#endif /* !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) */ + + /* Print out test information banner. */ + printf("NetX Test: Packet Data Append Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) + + /* Allocate the packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, 0, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append data that is two packet size. */ + status = nx_packet_data_append(my_packet, buffer, TEST_SIZE * 4, &pool_0, NX_NO_WAIT); + + /* Check the status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check the status. */ + if(status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + printf("SUCCESS!\n"); + test_control_return(0); +} + diff --git a/test/regression/netxduo_test/netx_packet_debug_info_test.c b/test/regression/netxduo_test/netx_packet_debug_info_test.c new file mode 100644 index 00000000..112cc0db --- /dev/null +++ b/test/regression/netxduo_test/netx_packet_debug_info_test.c @@ -0,0 +1,553 @@ +/* This NetX test concentrates on the packet debug information. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_packet.h" +#include "nx_ram_network_driver_test_1500.h" +extern VOID test_control_return(UINT status); + +#if defined(NX_ENABLE_PACKET_DEBUG_INFO) && defined(__PRODUCT_NETXDUO__) && (__NETXDUO_MINOR_VERSION__ > 8) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +#define TEST_SIZE 1536 +#define PACKET_NUM 16 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET temp_socket; +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_0; +static NXD_ADDRESS address_1; +#endif /* FEATURE_NX_IPV6 */ + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +#ifndef NX_DISABLE_FRAGMENTATION +static UCHAR buffer[2048]; +#endif /* NX_DISABLE_FRAGMENTATION */ +static CHAR *verify_file; +static NX_PACKET_POOL *verify_pool; +static UINT count; +static UINT operation; +static UINT delay; + +/* Define thread prototypes. */ + +static VOID ntest_0_entry(ULONG thread_input); +static VOID ntest_1_entry(ULONG thread_input); +static VOID verify_packet(NX_PACKET_POOL *pool_ptr, CHAR *in_files); +extern VOID _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +VOID netx_packet_debug_info_test_application_define(VOID *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create first packet pool. */ + pointer = (CHAR *)(((ALIGN_TYPE)pointer + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)); + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", TEST_SIZE, pointer, ((TEST_SIZE + sizeof(NX_PACKET) + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)) * PACKET_NUM); + + pointer = pointer + (TEST_SIZE + NX_PACKET_ALIGNMENT + sizeof(NX_PACKET)) * PACKET_NUM; + if (status) + error_counter++; + + /* Create second packet pool. */ + pointer = (CHAR *)(((ALIGN_TYPE)pointer + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)); + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", TEST_SIZE, pointer, ((TEST_SIZE + sizeof(NX_PACKET) + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)) * PACKET_NUM); + + pointer = pointer + (TEST_SIZE + NX_PACKET_ALIGNMENT + sizeof(NX_PACKET)) * PACKET_NUM; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (VOID *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (VOID *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + /* Enable ICMP processing for both IP instances. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ICMP enable status. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check UDP enable status. */ + if (status) + error_counter++; + +#ifndef NX_DISABLE_FRAGMENTATION + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +#endif /* NX_DISABLE_FRAGMENTATION */ + + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check IPv6 enable status. */ + if (status) + error_counter++; + + /* Set source and destination address with global address. */ + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0x20010DB8; + address_0.nxd_ip_address.v6[1] = 0x00010001; + address_0.nxd_ip_address.v6[2] = 0x021122FF; + address_0.nxd_ip_address.v6[3] = 0xFE334456; + + address_1.nxd_ip_version = NX_IP_VERSION_V6; + address_1.nxd_ip_address.v6[0] = 0x20010DB8; + address_1.nxd_ip_address.v6[1] = 0x00010001; + address_1.nxd_ip_address.v6[2] = 0x021122FF; + address_1.nxd_ip_address.v6[3] = 0xFE334499; + + status = nxd_ipv6_address_set(&ip_0, 0, &address_0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &address_1, 64, NX_NULL); + + /* Check for IPv6 enable errors. */ + if (status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ +} + + +static VOID verify_packet(NX_PACKET_POOL *pool_ptr, CHAR *in_files) +{ +UINT i; +CHAR *file_info, *p; +ULONG packet_status; +UINT packet_found = NX_FALSE; +NX_PACKET *packet_ptr; +CHAR *thread_info; +ULONG line_info; + + for (i = 0; i < pool_ptr -> nx_packet_pool_total; i++) + { + /* Get debug information. */ + _nx_packet_debug_info_get(pool_ptr, i, &packet_ptr, &packet_status, &thread_info, &file_info, &line_info); + + /* Check if no packets are expected to be allocated. */ + if (in_files == NX_NULL) + { + if (packet_status == NX_PACKET_ALLOCATED) + { + error_counter++; + break; + } + } + else + { + + /* Check if is the packet looking for? */ + /* Trim path. */ + for(p = file_info + strlen(file_info); p != file_info && *p != '\\' && *p != '/'; p--); + + if(*p == '\\' || *p == '/') + p++; + + /* Is expected packet found? */ + if(strcmp(in_files, p) == 0) + packet_found = NX_TRUE; + } + } + + /* Check whether packet is found in specified file. */ + if((in_files != NX_NULL) && (packet_found == NX_FALSE)) + error_counter++; +} + + +/* Define the test threads. */ +static VOID ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + printf("NetX Test: Packet Debug Info Test...................................."); + + /* Verify no packet used. */ + verify_packet(&pool_0, NX_NULL); + verify_packet(&pool_1, NX_NULL); + +#ifdef FEATURE_NX_IPV6 + /* Sleep 3 seconds to finish DAD. */ + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + + /* Verify ARP/ND and ICMP packet debug information. */ + /* Ping between two IPs. */ + verify_pool = &pool_0; + verify_file = NX_PACKET_ARP_WAITING_QUEUE; + advanced_packet_process_callback = my_packet_process; + operation = NX_RAMDRIVER_OP_BYPASS; + delay = 0; + count = 0; + status = nx_icmp_ping(&ip_0, IP_ADDRESS(1,2,3,5), "", 0, &packet_ptr, NX_IP_PERIODIC_RATE); + if(status == NX_SUCCESS) + { + + /* Verify packet is processed by nx_icmp_interface_ping.c before passing to application. */ + verify_packet(&pool_0, "nx_icmp_interface_ping.c"); + verify_packet(&pool_1, NX_NULL); + nx_packet_release(packet_ptr); + + /* Verify no packet used. */ + verify_packet(&pool_0, NX_NULL); + } + +#ifdef FEATURE_NX_IPV6 + verify_pool = &pool_0; + verify_file = NX_PACKET_ND_WAITING_QUEUE; + status = nxd_icmp_ping(&ip_0, &address_1, "zzzNzFzHbJKLMNOPQRSTUVWXYZ", 28, &packet_ptr, NX_IP_PERIODIC_RATE); + if(status == NX_SUCCESS) + { + + /* Verify packet is processed by nx_icmp_interface_ping6.c before passing to application. */ + verify_packet(&pool_0, "nx_icmp_interface_ping6.c"); + verify_packet(&pool_1, NX_NULL); + nx_packet_release(packet_ptr); + + /* Verify no packet used. */ + verify_packet(&pool_0, NX_NULL); + } +#endif /* FEATURE_NX_IPV6 */ + + + /* Verify TCP packet debug information. */ + /* Create two TCP socket socket. */ + nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + nx_tcp_socket_create(&ip_0, &temp_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Bind the socket. */ + nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + nx_tcp_client_socket_bind(&temp_socket, 13, NX_WAIT_FOREVER); + + /* Attempt to connect server at the same time. */ + nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + nx_tcp_client_socket_connect(&temp_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Verify a SYN packet is in peer's listen queue. */ + verify_packet(&pool_0, NX_NULL); + verify_packet(&pool_1, NX_PACKET_TCP_LISTEN_QUEUE); + + /* Let remote accpet the connection. */ + tx_thread_resume(&ntest_1); + + /* Disconnect the connection and let the SYN packet be processed. */ + nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + nx_tcp_socket_disconnect(&temp_socket, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&temp_socket); + + /* Verify no packet used. */ + verify_packet(&pool_0, NX_NULL); + verify_packet(&pool_1, NX_NULL); + + /* Connect server. */ + nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_WAIT_FOREVER); + + /* Allocate a packet and send to peer. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + verify_packet(&pool_0, "nx_packet_allocate.c"); + nx_packet_data_append(packet_ptr, "ABCD", 4, &pool_0, NX_WAIT_FOREVER); + verify_packet(&pool_0, "nx_packet_data_append.c"); + + /* The packet is in send queue before ACKed. */ + nx_tcp_socket_send(&client_socket, packet_ptr, NX_WAIT_FOREVER); + + /* Verify a packet is in TCP send/receive queue. */ + verify_packet(&pool_0, "nx_tcp_socket_send_internal.c"); + verify_packet(&pool_1, NX_PACKET_TCP_RECEIVE_QUEUE); + + /* Let remote receive the pakcet. */ + tx_thread_resume(&ntest_1); + + nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + + /* Verify UDP packet debug information. */ + nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the UDP socket to the IP port. */ + nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + nx_udp_socket_bind(&socket_1, 0x88, TX_WAIT_FOREVER); + + /* Allocate a packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, TX_WAIT_FOREVER); + nx_packet_data_append(packet_ptr, "ABCD", 4, &pool_0, NX_WAIT_FOREVER); + + /* Send the UDP packet. */ + if(nx_udp_socket_send(&socket_0, packet_ptr, IP_ADDRESS(1, 2, 3, 5), 0x88)) + { + error_counter++; + nx_packet_release(packet_ptr); + } + else + { + + /* Verify a packet is in UDP receive queue. */ + verify_packet(&pool_1, NX_PACKET_UDP_RECEIVE_QUEUE); + + /* Receive a UDP packet. */ + nx_udp_socket_receive(&socket_1, &packet_ptr, NX_WAIT_FOREVER); + nx_packet_release(packet_ptr); + + /* Verify no packet used. */ + verify_packet(&pool_0, NX_NULL); + verify_packet(&pool_1, NX_NULL); + } + + +#ifndef NX_DISABLE_FRAGMENTATION + /* Verify fragmentation packet debug information. */ + /* Allocate a packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_UDP_PACKET, TX_WAIT_FOREVER); + nx_packet_data_append(packet_ptr, buffer, sizeof(buffer), &pool_0, NX_WAIT_FOREVER); + + /* Let driver delay the second fragmentation for one second. */ + operation = NX_RAMDRIVER_OP_DELAY; + delay = 100; + count = 1; + + /* Send the UDP packet. */ + if(nx_udp_socket_send(&socket_0, packet_ptr, IP_ADDRESS(1, 2, 3, 5), 0x88)) + { + error_counter++; + nx_packet_release(packet_ptr); + } + else + { + + /* Verify a packet is in UDP receive queue. */ + verify_packet(&pool_1, NX_PACKET_IP_FRAGMENT_QUEUE); + + /* Receive a UDP packet. */ + nx_udp_socket_receive(&socket_1, &packet_ptr, NX_WAIT_FOREVER); + nx_packet_release(packet_ptr); + + /* Verify no packet used. */ + verify_packet(&pool_0, NX_NULL); + verify_packet(&pool_1, NX_NULL); + } +#endif /* NX_DISABLE_FRAGMENTATION */ + + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + tx_thread_suspend(&ntest_1); + + /* Accept a client socket connection. */ + nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Disconnect the connection and let the SYN packet be processed. */ + nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&server_socket); + + /* Verify the SYN packet is still in listen queue. */ + verify_packet(&pool_1, NX_PACKET_TCP_LISTEN_QUEUE); + nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Accept a client socket connection. */ + nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Disconnect the connection and let the SYN packet be processed. */ + nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&server_socket); + nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Accept a client socket connection. */ + nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + tx_thread_suspend(&ntest_1); + + if(nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER)) + { + error_counter++; + } + else + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + nx_packet_release(packet_ptr); + + /* Verify no packet used. */ + verify_packet(&pool_0, NX_NULL); + verify_packet(&pool_1, NX_NULL); + } + + nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + if(verify_pool) + { + + /* Verify packet used. */ + verify_packet(verify_pool, verify_file); + verify_pool = NX_NULL; + } + + /* Is there an operation needed? */ + if(operation != NX_RAMDRIVER_OP_BYPASS) + { + count--; + if(count == 0) + { + *operation_ptr = operation; + *delay_ptr = delay; + operation = NX_RAMDRIVER_OP_BYPASS; + } + } + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +VOID netx_packet_debug_info_test_application_define(VOID *first_unused_memory) +#endif +{ + + printf("NetX Test: Packet Debug Info Test....................................N/A\n"); + + test_control_return(3); +} +#endif /* NX_ENABLE_PACKET_DEBUG_INFO */ diff --git a/test/regression/netxduo_test/netx_packet_nxe_api_test.c b/test/regression/netxduo_test/netx_packet_nxe_api_test.c new file mode 100644 index 00000000..a477e9af --- /dev/null +++ b/test/regression/netxduo_test/netx_packet_nxe_api_test.c @@ -0,0 +1,911 @@ +/* This NetX test concentrates on the basic packet operations. */ + +#include "nx_packet.h" +#include "tx_api.h" +#include "nx_api.h" +#include "tx_thread.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && !defined(NX_PACKET_HEADER_PAD) + +#define DEMO_STACK_SIZE 2048 + +#ifndef NX_PACKET_ALIGNMENT +#define NX_PACKET_ALIGNMENT 4 +#endif /* NX_PACKET_ALIGNMENT */ + +#define TEST_SIZE (((NX_UDP_PACKET+28)+NX_PACKET_ALIGNMENT - 1)/NX_PACKET_ALIGNMENT*NX_PACKET_ALIGNMENT) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_PACKET_POOL invalid_pool; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static CHAR *pointer; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_packet_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ +UINT status; +ULONG header_size = (sizeof(NX_PACKET) + NX_PACKET_ALIGNMENT - 1)/NX_PACKET_ALIGNMENT*NX_PACKET_ALIGNMENT; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create packet pool with valid parameters in NULL thread. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", TEST_SIZE, pointer,(TEST_SIZE + header_size) * 3); + + /* Check for error. */ + if (status) + { + error_counter++; + } + + /* Create packet pool with corruptted memory. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", TEST_SIZE, pointer - 1,(TEST_SIZE + header_size) * 3); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + error_counter++; + } + + /* Create packet pool with corruptted memory. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", TEST_SIZE, pointer + 1,(TEST_SIZE + header_size) * 3); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + error_counter++; + } + + /* Create the same packet pool with valid parameters in NULL thread. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", TEST_SIZE, pointer,(TEST_SIZE + header_size) * 3); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + error_counter++; + } + + /* Update the pointer. */ + pointer = pointer + (TEST_SIZE + header_size) * 3; + + if (NX_PACKET_ALIGNMENT != sizeof(ULONG)) + { + + /* Print out test information banner. */ + printf("NetX Test: Packet NXE API Test.......................................N/A\n"); + + test_control_return(3); + } +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG total_packets, free_packets, empty_pool_requests, empty_pool_suspensions, invalid_packet_releases; +ULONG packet_length; +ULONG buffer[200]; +ULONG bytes_copied; +NX_PACKET *my_packet_1; +NX_PACKET *my_packet_2; +NX_PACKET invalid_packet; +NX_PACKET *invalid_packet_2; +ULONG header_size = (sizeof(NX_PACKET) + NX_PACKET_ALIGNMENT - 1)/NX_PACKET_ALIGNMENT*NX_PACKET_ALIGNMENT; + + /* Print out test information banner. */ + printf("NetX Test: Packet NXE API Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_packet_pool_create api */ + /************************************************/ + +#ifndef NX_DISABLE_ERROR_CHECKING + /* Create packet pool with invalid pool size. */ + status = _nxe_packet_pool_create(&pool_0, "NetX Main Packet Pool", TEST_SIZE, pointer, (TEST_SIZE + header_size) * 3, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Create packet pool with null pool. */ + status = nx_packet_pool_create(NX_NULL, "NetX Main Packet Pool", TEST_SIZE, pointer, (TEST_SIZE + header_size) * 3); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create packet pool with null pointer. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", TEST_SIZE, NX_NULL, (TEST_SIZE + header_size) * 3); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create packet pool with invalid payload size. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 0, pointer, (TEST_SIZE + header_size) * 3); + + /* Check for error. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create packet pool with invalid pool size. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", TEST_SIZE, pointer, 0); + + /* Check for error. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the same packet pool with valid parameters. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", TEST_SIZE, pointer,(TEST_SIZE + header_size) * 3); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_packet_pool_delete api */ + /************************************************/ + + /* Delete packet pool with null pool. */ + status = nx_packet_pool_delete(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete packet pool with invalid pool. */ + status = nx_packet_pool_delete(&invalid_pool); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_packet_pool_info_get api */ + /************************************************/ + + /* Get the packet pool info with null pool. */ + status = nx_packet_pool_info_get(NX_NULL, &total_packets, &free_packets, &empty_pool_requests, &empty_pool_suspensions, &invalid_packet_releases); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the packet pool info with invalid pool. */ + status = nx_packet_pool_info_get(&invalid_pool, &total_packets, &free_packets, &empty_pool_requests, &empty_pool_suspensions, &invalid_packet_releases); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_LOW_WATERMARK + /************************************************/ + /* Tested the nxe_packet_pool_low_watermark api */ + /************************************************/ + + /* Delete packet pool with null pool. */ + status = nx_packet_pool_low_watermark_set(NX_NULL, 5); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete packet pool with invalid pool. */ + status = nx_packet_pool_low_watermark_set(&invalid_pool, 5); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_ENABLE_LOW_WATERMARK */ + + /************************************************/ + /* Tested the nxe_packet_allocate api */ + /************************************************/ + + /* Allocate packet with null pool. */ + status = nx_packet_allocate(NX_NULL, &my_packet_1, NX_UDP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate packet with invalid pool. */ + status = nx_packet_allocate(&invalid_pool, &my_packet_1, NX_UDP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate packet with null packet. */ + status = nx_packet_allocate(&pool_0, NX_NULL, NX_UDP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate packet with Four byte unaligned packet type. */ + status = nx_packet_allocate(&pool_0, &my_packet_1, 5, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate packet with big packet type. */ + status = nx_packet_allocate(&pool_0, &my_packet_1, TEST_SIZE + 4, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_PARAMETERS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate packet with valid parameter. */ + status = nx_packet_allocate(&pool_0, &my_packet_1, NX_UDP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_packet_data_append api */ + /************************************************/ + + /* Append the packet data with null packet. */ + status = nx_packet_data_append(NX_NULL, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the packet data with null data. */ + status = nx_packet_data_append(my_packet_1, NX_NULL, 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the packet data with null data size. */ + status = nx_packet_data_append(my_packet_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 0, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the packet data with null pool. */ + status = nx_packet_data_append(my_packet_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, NX_NULL, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the packet data with invalid pool. */ + status = nx_packet_data_append(my_packet_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &invalid_pool, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the packet with invalid packet that prepend pointer is less than data start. */ + invalid_packet.nx_packet_data_start = (UCHAR *)0x20; + invalid_packet.nx_packet_prepend_ptr = (UCHAR *)0x10; + invalid_packet.nx_packet_append_ptr = (UCHAR *)0x30; + invalid_packet.nx_packet_data_end = (UCHAR *)0x40; + status = nx_packet_data_append(&invalid_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_UNDERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append packet with invalid packet that prepend pointer is less than data start. */ + invalid_packet.nx_packet_data_start = (UCHAR *)0x10; + invalid_packet.nx_packet_prepend_ptr = (UCHAR *)0x20; + invalid_packet.nx_packet_append_ptr = (UCHAR *)0x40; + invalid_packet.nx_packet_data_end = (UCHAR *)0x20; + status = nx_packet_data_append(&invalid_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_OVERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the packet data with valid parameters. */ + status = nx_packet_data_append(my_packet_1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_packet_copy api */ + /************************************************/ + + /* Copy packet with null original packet. */ + status = nx_packet_copy(NX_NULL, &my_packet_2, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Copy packet with null new packet. */ + status = nx_packet_copy(my_packet_1, NX_NULL, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Copy packet with null pool. */ + status = nx_packet_copy(my_packet_1, &my_packet_2, NX_NULL, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Copy packet with invalid pool. */ + status = nx_packet_copy(my_packet_1, &my_packet_2, &invalid_pool, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Copy packet with invalid original packet that prepend pointer is less than data start. */ + invalid_packet.nx_packet_data_start = (UCHAR *)0x20; + invalid_packet.nx_packet_prepend_ptr = (UCHAR *)0x10; + invalid_packet.nx_packet_append_ptr = (UCHAR *)0x30; + invalid_packet.nx_packet_data_end = (UCHAR *)0x40; + status = nx_packet_copy(&invalid_packet, &my_packet_2, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_UNDERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Copy packet with invalid original packet that prepend pointer is less than data start. */ + invalid_packet.nx_packet_data_start = (UCHAR *)0x10; + invalid_packet.nx_packet_prepend_ptr = (UCHAR *)0x20; + invalid_packet.nx_packet_append_ptr = (UCHAR *)0x40; + invalid_packet.nx_packet_data_end = (UCHAR *)0x20; + status = nx_packet_copy(&invalid_packet, &my_packet_2, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_OVERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Copy packet with valid parameters. */ + status = nx_packet_copy(my_packet_1, &my_packet_2, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_packet_length_get api */ + /************************************************/ + + /* Get packet length with null packet. */ + status = nx_packet_length_get(NX_NULL, &packet_length); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get packet length with null length pointer. */ + status = nx_packet_length_get(my_packet_1, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get packet length with invalid packet pool owner. */ + invalid_packet_2 = (NX_PACKET *) &invalid_packet; + invalid_packet_2 -> nx_packet_pool_owner = NX_NULL; + status = nx_packet_length_get(invalid_packet_2, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get packet length with invalid packet pool ID. */ + invalid_packet_2 = (NX_PACKET *) &invalid_packet; + invalid_packet_2 -> nx_packet_pool_owner = (NX_PACKET_POOL *) &invalid_pool; + invalid_packet_2 -> nx_packet_pool_owner -> nx_packet_pool_id = 0; + status = nx_packet_length_get(invalid_packet_2, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get packet length with valid parameters. */ + status = nx_packet_length_get(my_packet_1, &packet_length); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_packet_data_extract_offset api*/ + /************************************************/ + + /* Extract the packet data with null packet. */ + status = nx_packet_data_extract_offset(NX_NULL, 0, buffer, 200, &bytes_copied); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Extract the packet data with invalid buffer. */ + status = nx_packet_data_extract_offset(my_packet_1, 0, NX_NULL, 200, &bytes_copied); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Extract the packet data with null bytes copied parameter. */ + status = nx_packet_data_extract_offset(my_packet_1, 0, buffer, 200, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Extract the packet data with valid parameter. */ + status = nx_packet_data_extract_offset(my_packet_1, 0, buffer, 200, &bytes_copied); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_packet_data_retrieve api */ + /************************************************/ + + /* Retrieve the packet data with null packet. */ + status = nx_packet_data_retrieve(NX_NULL, buffer, &bytes_copied); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Extract the packet data with invalid buffer. */ + status = nx_packet_data_retrieve(my_packet_1, NX_NULL, &bytes_copied); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Extract the packet data with valid parameter. */ + status = nx_packet_data_retrieve(my_packet_1, buffer, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Extract the packet data with valid parameter. */ + status = nx_packet_data_retrieve(my_packet_1, buffer, &bytes_copied); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_packet_release api */ + /************************************************/ + + /* Release the packet with invalid packet. */ + invalid_packet_2 = NX_NULL; + status = nx_packet_release(invalid_packet_2); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet with invalid original packet that prepend pointer is less than data start. */ + invalid_packet_2 = (NX_PACKET *) &invalid_packet; + invalid_packet_2 -> nx_packet_pool_owner = (NX_PACKET_POOL *) &invalid_pool; + invalid_packet_2 -> nx_packet_pool_owner -> nx_packet_pool_id = NX_PACKET_POOL_ID; + invalid_packet_2 -> nx_packet_data_start = (UCHAR *)0x20; + invalid_packet_2 -> nx_packet_prepend_ptr = (UCHAR *)0x10; + invalid_packet_2 -> nx_packet_append_ptr = (UCHAR *)0x30; + invalid_packet_2 -> nx_packet_data_end = (UCHAR *)0x40; + status = nx_packet_release(invalid_packet_2); + + /* Check for error. */ + if (status != NX_UNDERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet with invalid original packet that prepend pointer is less than data start. */ + invalid_packet_2 = (NX_PACKET *) &invalid_packet; + invalid_packet_2 -> nx_packet_pool_owner = (NX_PACKET_POOL *) &invalid_pool; + invalid_packet_2 -> nx_packet_pool_owner -> nx_packet_pool_id = NX_PACKET_POOL_ID; + invalid_packet_2 -> nx_packet_data_start = (UCHAR *)0x10; + invalid_packet_2 -> nx_packet_prepend_ptr = (UCHAR *)0x20; + invalid_packet_2 -> nx_packet_append_ptr = (UCHAR *)0x40; + invalid_packet_2 -> nx_packet_data_end = (UCHAR *)0x20; + status = nx_packet_release(invalid_packet_2); + + /* Check for error. */ + if (status != NX_OVERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet data with valid packet. */ + status = nx_packet_release(my_packet_1); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_packet_transmit_release api */ + /************************************************/ + + /* Release the packet with invalid packet. */ + invalid_packet_2 = NX_NULL; + status = nx_packet_transmit_release(invalid_packet_2); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet with no packet pool owner. */ + invalid_packet_2 = (NX_PACKET *) &invalid_packet; + invalid_packet_2 -> nx_packet_pool_owner = NX_NULL; + status = nx_packet_transmit_release(invalid_packet_2); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet with invalid packet owner. */ + invalid_packet_2 = (NX_PACKET *) &invalid_packet; + invalid_packet_2 -> nx_packet_pool_owner = (NX_PACKET_POOL *) &invalid_pool; + invalid_packet_2 -> nx_packet_pool_owner -> nx_packet_pool_id = 0; + status = nx_packet_transmit_release(invalid_packet_2); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet with invalid packet nx_packet_tcp_queue_next. */ + invalid_packet_2 = (NX_PACKET *) &invalid_packet; + invalid_packet_2 -> nx_packet_append_ptr = invalid_packet_2 -> nx_packet_data_end; + invalid_packet_2 -> nx_packet_pool_owner = (NX_PACKET_POOL *) &pool_0; +#ifdef __PRODUCT_NETXDUO__ + invalid_packet_2 -> nx_packet_union_next.nx_packet_tcp_queue_next = ((NX_PACKET *)NX_PACKET_FREE); +#else + invalid_packet_2 -> nx_packet_tcp_queue_next = ((NX_PACKET *)NX_PACKET_FREE); +#endif + status = nx_packet_transmit_release(invalid_packet_2); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet with invalid original packet that prepend pointer is less than data start. */ + invalid_packet_2 = (NX_PACKET *) &invalid_packet; + invalid_packet_2 -> nx_packet_pool_owner = (NX_PACKET_POOL *) &invalid_pool; + invalid_packet_2 -> nx_packet_pool_owner -> nx_packet_pool_id = NX_PACKET_POOL_ID; + invalid_packet_2 -> nx_packet_data_start = (UCHAR *)0x20; + invalid_packet_2 -> nx_packet_prepend_ptr = (UCHAR *)0x10; + invalid_packet_2 -> nx_packet_append_ptr = (UCHAR *)0x30; + invalid_packet_2 -> nx_packet_data_end = (UCHAR *)0x40; + status = nx_packet_transmit_release(invalid_packet_2); + + /* Check for error. */ + if (status != NX_UNDERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet with invalid original packet that prepend pointer is less than data start. */ + invalid_packet_2 = (NX_PACKET *) &invalid_packet; + invalid_packet_2 -> nx_packet_pool_owner = (NX_PACKET_POOL *) &invalid_pool; + invalid_packet_2 -> nx_packet_pool_owner -> nx_packet_pool_id = NX_PACKET_POOL_ID; + invalid_packet_2 -> nx_packet_data_start = (UCHAR *)0x10; + invalid_packet_2 -> nx_packet_prepend_ptr = (UCHAR *)0x20; + invalid_packet_2 -> nx_packet_append_ptr = (UCHAR *)0x40; + invalid_packet_2 -> nx_packet_data_end = (UCHAR *)0x20; + status = nx_packet_transmit_release(invalid_packet_2); + + /* Check for error. */ + if (status != NX_OVERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet data with valid packet. */ + status = nx_packet_transmit_release(my_packet_2); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete packet pool with valid pool. */ + status = nx_packet_pool_delete(&pool_0); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_packet_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Packet NXE API Test.......................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_packet_payload_size_test.c b/test/regression/netxduo_test/netx_packet_payload_size_test.c new file mode 100644 index 00000000..7d6cfde7 --- /dev/null +++ b/test/regression/netxduo_test/netx_packet_payload_size_test.c @@ -0,0 +1,384 @@ +/* This case tests payload that is only two bytes aligned. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +#ifdef __PRODUCT_NETXDUO__ +static NX_PACKET_POOL pool_2; +#endif /* __PRODUCT_NETXDUO__ */ +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static CHAR send_buff[250]; +static CHAR recv_buff[250]; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_packet_payload_size_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; +#ifdef __PRODUCT_NETXDUO__ +ULONG header_size; +#endif /* __PRODUCT_NETXDUO__ */ + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool with payload not four bytes aligned. */ + memset(pointer, 0, 8192); + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 202, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create a packet pool. */ + memset(pointer, 0, 8192); + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + pointer += 1; + pointer = (CHAR *)((((ALIGN_TYPE)pointer + NX_PACKET_ALIGNMENT - 1) / NX_PACKET_ALIGNMENT) * NX_PACKET_ALIGNMENT); + + /* Calculate the rounded payload size. */ + header_size = ((sizeof(NX_PACKET) + NX_PACKET_ALIGNMENT - 1)/NX_PACKET_ALIGNMENT) * NX_PACKET_ALIGNMENT; +#ifndef NX_DISABLE_ERROR_CHECKING + /* Create a packet pool with starting address not four byte aligned. The pool size is not enough. */ + status = nx_packet_pool_create(&pool_2, "NetX Main Packet Pool", 512, (pointer - 1), 512 + header_size); + + if (status == NX_SUCCESS) + error_counter++; +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Create a packet pool with starting address not four byte aligned. The pool size is enough. */ + status = nx_packet_pool_create(&pool_2, "NetX Main Packet Pool", 512, (pointer - 1), 516 + header_size); + pointer = pointer + 516 + header_size; + + if (status != NX_SUCCESS) + error_counter++; +#endif /* __PRODUCT_NETXDUO__ */ + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: Packet Payload Size Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset send buffer and recv buffer. */ + for (i = 0; i < sizeof(send_buff); i++) + { + send_buff[i] = 0x01; + recv_buff[i] = 0x00; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write send_buff into the packet payload! */ + status = nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG byte_copied; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check for error. */ + if (status) + error_counter++; + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + { + + /* Retrieve data. */ + status = nx_packet_data_retrieve(packet_ptr, recv_buff, &byte_copied); + + /* Check for error. */ + if (status) + error_counter++; + + /* Compare with send buffer. */ + if (byte_copied != sizeof(send_buff)) + error_counter++; + else if (memcmp(send_buff, recv_buff, sizeof(send_buff))) + error_counter++; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_packet_payload_size_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: Packet Payload Size Test..................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_packet_suspension_test.c b/test/regression/netxduo_test/netx_packet_suspension_test.c new file mode 100644 index 00000000..596fb49f --- /dev/null +++ b/test/regression/netxduo_test/netx_packet_suspension_test.c @@ -0,0 +1,241 @@ +/* This NetX test concentrates on the packet suspension operations. */ + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + +#ifndef NX_PACKET_ALIGNMENT +#define NX_PACKET_ALIGNMENT sizeof(ULONG) +#endif /* NX_PACKET_ALIGNMENT */ + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static TX_THREAD ntest_2; + +static NX_PACKET_POOL pool_0; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ntest_1_counter; +static ULONG ntest_2_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_2_entry(ULONG thread_input); +extern void test_control_return(UINT status); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_packet_suspension_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ntest_1_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create another thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create another thread. */ + tx_thread_create(&ntest_2, "thread 2", ntest_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Align the starting address. */ + pointer = (CHAR *)(((ALIGN_TYPE)pointer + NX_PACKET_ALIGNMENT - 1) / NX_PACKET_ALIGNMENT * NX_PACKET_ALIGNMENT); + + /* Create first packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_UDP_PACKET, pointer, + ((NX_UDP_PACKET + sizeof(NX_PACKET) + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)) * 3); + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +ULONG total_packets, free_packets, empty_pool_requests, empty_pool_suspensions, invalid_packet_releases; + + + /* Print out test information banner. */ + printf("NetX Test: Packet Suspension Processing Test........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate the three packets to ensure the other thread will suspend. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_UDP_PACKET, NX_IP_PERIODIC_RATE/10); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_UDP_PACKET, NX_IP_PERIODIC_RATE/10); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_UDP_PACKET, NX_IP_PERIODIC_RATE/10); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Suspend for 1 second ticks to let the other thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Ensure the other thread is where it is supposed to be. */ + if (ntest_1_counter != 1) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release a packet, which should cause the other thread to resume. */ + status = nx_packet_release(my_packet1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release a packet, which should cause the other thread to resume. */ + status = nx_packet_release(my_packet3); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Relinquish to the other thread so it can complete. */ + tx_thread_relinquish(); + + /* Get information about the pool. */ + status += nx_packet_pool_info_get(&pool_0, &total_packets, &free_packets, &empty_pool_requests, &empty_pool_suspensions, &invalid_packet_releases); + +#ifndef NX_DISABLE_PACKET_INFO + + if((empty_pool_requests != 4) || (empty_pool_suspensions != 4)) + status++; +#endif + + /* Check status. */ + if ((status) || (total_packets != 3) || (free_packets != 0) || (invalid_packet_releases) || (ntest_1_counter != 2) || (ntest_2_counter != 2) || (error_counter)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet1; + + + /* Set the counter to zero! */ + ntest_1_counter = 0; + + /* Attempt to allocate a packet with a timeout. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_UDP_PACKET, NX_IP_PERIODIC_RATE/10); + + /* Determine if we received a timeout error. */ + if (status != NX_NO_PACKET) + error_counter++; + + /* Increment counter. */ + ntest_1_counter++; + + /* Allocate packet again. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Determine if we received a timeout error. */ + if (status) + error_counter++; + + /* Increment counter. */ + ntest_1_counter++; +} + +static void ntest_2_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet1; + + + /* Set the counter to zero! */ + ntest_2_counter = 0; + + /* Attempt to allocate a packet with a timeout. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_UDP_PACKET, NX_IP_PERIODIC_RATE/10); + + /* Determine if we received a timeout error. */ + if (status != NX_NO_PACKET) + error_counter++; + + /* Increment counter. */ + ntest_2_counter++; + + /* Allocate packet again. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Determine if we received a timeout error. */ + if (status) + error_counter++; + + /* Increment counter. */ + ntest_2_counter++; +} diff --git a/test/regression/netxduo_test/netx_ramdriver_callback_test.c b/test/regression/netxduo_test/netx_ramdriver_callback_test.c new file mode 100644 index 00000000..97931bee --- /dev/null +++ b/test/regression/netxduo_test/netx_ramdriver_callback_test.c @@ -0,0 +1,358 @@ +/* This case tests advanced packet process callback feature for ramdriver. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET client_socket; +static NX_UDP_SOCKET server_socket; +static NX_PACKET *send_packet, *recv_packet; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static UINT driver_op; +static UINT driver_delay; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT advanced_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_netx_ramdriver_callback_application_define(void *first_unused_memory) +#endif +{ + +UCHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (UCHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +CHAR msg[20]; + + + printf("NetX Test: RAMDriver callback test..................................."); + + /* Create client socket. */ + status = nx_udp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the socket. */ + status += nx_udp_socket_bind(&client_socket, 0x88, TX_WAIT_FOREVER); + + /* Create server socket. */ + status += nx_udp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the socket. */ + status += nx_udp_socket_bind(&server_socket, 0x88, TX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup advanced callback function. */ + advanced_packet_process_callback = advanced_packet_process; + + + /* Test delay feature. */ + driver_op = NX_RAMDRIVER_OP_DELAY; + driver_delay = 4 * NX_IP_PERIODIC_RATE; + + /* Create a packet. */ + status = nx_packet_allocate(&pool_0, &send_packet, NX_UDP_PACKET, NX_IP_PERIODIC_RATE); + + /* Set message for delayed packet. */ + memcpy(msg, "1234567890", 10); + + /* Fill in the packet with data. */ + status += nx_packet_data_append(send_packet, msg, 10, &pool_0, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_udp_socket_send(&client_socket, send_packet, IP_ADDRESS(1, 2, 3, 5), 0x88); + + /* Check status. */ + if(status) + { + error_counter++; + nx_packet_release(send_packet); + } + + /* Try to receive on server socket. */ + status = nx_udp_socket_receive(&server_socket, &recv_packet, driver_delay / 2); + + /* No packet should be received. */ + if(status != NX_NO_PACKET) + { + error_counter++; + if(status == NX_SUCCESS) + nx_packet_release(recv_packet); + } + + /* Try to receive on server socket. */ + status = nx_udp_socket_receive(&server_socket, &recv_packet, (driver_delay / 2 + 1 * NX_IP_PERIODIC_RATE)); + + /* The packet should be received. */ + if(status) + error_counter++; + else + { + + /* Check packet data. */ + if(memcmp(msg, recv_packet -> nx_packet_prepend_ptr, 10)) + error_counter++; + + /* Release the packet */ + status = nx_packet_release(recv_packet); + + /* Check for error. */ + if(status) + error_counter++; + } + + + /* Test drop feature. */ + driver_op = NX_RAMDRIVER_OP_DROP; + + /* Create a packet. */ + status = nx_packet_allocate(&pool_0, &send_packet, NX_UDP_PACKET, NX_IP_PERIODIC_RATE); + + /* Set message for dropped packet. */ + memcpy(msg, "abcdefghij", 10); + + /* Fill in the packet with data. */ + status += nx_packet_data_append(send_packet, msg, 10, &pool_0, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_udp_socket_send(&client_socket, send_packet, IP_ADDRESS(1, 2, 3, 5), 0x88); + + /* Check status. */ + if(status) + { + error_counter++; + nx_packet_release(send_packet); + } + + /* Try to receive on server socket. */ + status = nx_udp_socket_receive(&server_socket, &recv_packet, 5 * NX_IP_PERIODIC_RATE); + + /* No packet should be received. */ + if(status != NX_NO_PACKET) + { + error_counter++; + if(status == NX_SUCCESS) + nx_packet_release(recv_packet); + } + + + /* Test duplicate feature. */ + driver_op = NX_RAMDRIVER_OP_DUPLICATE; + + /* Create a packet. */ + status = nx_packet_allocate(&pool_0, &send_packet, NX_UDP_PACKET, NX_IP_PERIODIC_RATE); + + /* Set message for duplicated packet. */ + memcpy(msg, "ABCDEFGHIJ", 10); + + /* Fill in the packet with data. */ + status += nx_packet_data_append(send_packet, msg, 10, &pool_0, NX_NO_WAIT); + + /* Check for error. */ + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_udp_socket_send(&client_socket, send_packet, IP_ADDRESS(1, 2, 3, 5), 0x88); + + /* Check status. */ + if(status) + { + error_counter++; + nx_packet_release(send_packet); + } + + /* Try to receive on server socket. */ + status = nx_udp_socket_receive(&server_socket, &recv_packet, 5 * NX_IP_PERIODIC_RATE); + + /* The original packet received. */ + if(status) + error_counter++; + else + { + + /* Check packet data. */ + if(memcmp(msg, recv_packet -> nx_packet_prepend_ptr, 10)) + error_counter++; + + /* Release the packet */ + status = nx_packet_release(recv_packet); + + /* Check for error. */ + if(status) + error_counter++; + } + + /* Try to receive on server socket. */ + status = nx_udp_socket_receive(&server_socket, &recv_packet, 5 * NX_IP_PERIODIC_RATE); + + /* The duplicated packet received. */ + if(status) + error_counter++; + else + { + + /* Check packet data. */ + if(memcmp(msg, recv_packet -> nx_packet_prepend_ptr, 10)) + error_counter++; + + /* Release the packet */ + status = nx_packet_release(recv_packet); + + /* Check for error. */ + if(status) + error_counter++; + } + + /* Cleanup */ + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&client_socket); + status += nx_udp_socket_unbind(&server_socket); + + /* Delete the UDP socket. */ + status += nx_udp_socket_delete(&client_socket); + status += nx_udp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Clean advanced callback function. */ + advanced_packet_process_callback = NX_NULL; + + /* Determine if the test was successful. */ + if((error_counter)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT advanced_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + if(packet_ptr == send_packet) + { + *operation_ptr = driver_op; + *delay_ptr = driver_delay; + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_netx_ramdriver_callback_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RAMDriver callback test...................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_rarp_basic_processing_test.c b/test/regression/netxduo_test/netx_rarp_basic_processing_test.c new file mode 100644 index 00000000..4f928bc3 --- /dev/null +++ b/test/regression/netxduo_test/netx_rarp_basic_processing_test.c @@ -0,0 +1,453 @@ +/* This NetX test concentrates on the RARP dynamic entry operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_rarp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_RARP_INFO) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static UINT response_type; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_rarp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static VOID ip_address_change_notify(NX_IP *ip_ptr, VOID *additional_info); +static VOID fake_rarp_response_packet(NX_PACKET **my_packet, UINT type); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +void _nx_ram_network_driver_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT interface_instance_id); + +#define NX_ETHERNET_RARP 0x8035 +#define NX_ETHERNET_SIZE 14 + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rarp_basic_processing_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", 0, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Attach the 2nd interface IP address so it dosn't need RARP service. */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", IP_ADDRESS(4, 3, 2, 111), 0xFF000000, _nx_ram_network_driver_256); + if(status != NX_SUCCESS) + { + error_counter++; + } + +#if (NX_MAX_PHYSICAL_INTERFACES > 2) && defined(__PRODUCT_NETXDUO__) + /* Attach the 3rd interface IP address so it dosn't need RARP service. */ + status = nx_ip_interface_attach(&ip_0, "3rd interface", 0, 0xFFFFFF00, _nx_ram_network_driver_256); + if(status != NX_SUCCESS) + { + error_counter++; + } +#endif +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +ULONG ip_address, network_mask; +ULONG rarp_requests_sent, rarp_responses_received, rarp_invalid_messages; + + + /* Print out some test information banners. */ + printf("NetX Test: RARP Basic Processing Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#if (NX_MAX_PHYSICAL_INTERFACES > 2) && defined(__PRODUCT_NETXDUO__) + /* Disable address mapping. */ + nx_ip_interface_address_mapping_configure(&ip_0, 2, NX_FALSE); +#endif + + /* Enable RARP for IP Instance 0. */ + status = nx_rarp_enable(&ip_0); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the rarp feature again. */ + status = nx_rarp_enable(&ip_0); + + /* Check status... */ + if (status != NX_ALREADY_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Register IP address change callback. */ + status = nx_ip_address_change_notify(&ip_0, ip_address_change_notify, NX_NULL); + + /* Check for error */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = my_rarp_packet_process; + + /* Set the response type as 0 . */ + response_type = 0; + + /* Waiting NetX sending the RARP request to get the address. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_ADDRESS_RESOLVED, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable RARP for IP Instance 0. */ + status = nx_rarp_enable(&ip_0); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the response type as 0 . */ + response_type = 1; + + /* Waiting NetX sending the RARP request to get the address. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_ADDRESS_RESOLVED, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the IP instance address. */ + status = nx_ip_interface_address_get(&ip_0, 0, &ip_address, &network_mask); + + /* Check status... */ + if((status != NX_SUCCESS) || (ip_address != IP_ADDRESS(1,2,3,4)) || (network_mask != 0xFFFFFF00UL)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information about RARP. */ + status = nx_rarp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_rarp_info_get(&ip_0, &rarp_requests_sent, &rarp_responses_received, &rarp_invalid_messages); + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ARP_INFO + if((rarp_requests_sent != 2) || (rarp_responses_received != 1) || (rarp_invalid_messages != 3)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifdef __PRODUCT_NETXDUO__ + /* Tested the nx_rarp_enable feature after IP address resloved. */ + + /* Enable the rarp feature again. */ + status = nx_rarp_enable(&ip_0); + + /* Check status... */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the rarp feature. */ + status = nx_rarp_disable(&ip_0); + + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_rarp_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +UINT status; +NX_PACKET *fake_packet_1; +NX_PACKET *fake_packet_2; +NX_PACKET *fake_packet_3; + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + /* Check the response type. */ + if (response_type == 0) + { + + /* Disable the rarp feature. */ + status = nx_rarp_disable(&ip_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Fake the response packet. */ + fake_rarp_response_packet(&fake_packet_1, NX_RARP_OPTION_RESPONSE); + + /* Call the driver to receive this packet. */ + _nx_ram_network_driver_receive(&ip_0, fake_packet_1, 0); + } + else if (response_type == 1) + { + + /* Fake a request packet. */ + fake_rarp_response_packet(&fake_packet_1, NX_RARP_OPTION_REQUEST); + + /* Call the driver to receive this packet. */ + _nx_ram_network_driver_receive(&ip_0, fake_packet_1, 0); + + /* Fake a invalid packet. */ + fake_rarp_response_packet(&fake_packet_2, 0); + + /* Call the driver to receive this packet. */ + _nx_ram_network_driver_receive(&ip_0, fake_packet_2, 0); + + /* Fake the response packet. */ + fake_rarp_response_packet(&fake_packet_3, NX_RARP_OPTION_RESPONSE); + + /* Call the driver to receive this packet. */ + _nx_ram_network_driver_receive(&ip_0, fake_packet_3, 0); + } + + return NX_TRUE; +} +static VOID fake_rarp_response_packet(NX_PACKET **packet_ptr, UINT type) +{ +UINT status; +NX_PACKET *my_packet; +ULONG *ethernet_frame_ptr; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create a fake RARP response packet to assign address(1.2.3.4)! */ + my_packet -> nx_packet_prepend_ptr[0] = 0x00; /* Ethernet header */ + my_packet -> nx_packet_prepend_ptr[1] = 0x01; + my_packet -> nx_packet_prepend_ptr[2] = 0x80; /* IP address */ + my_packet -> nx_packet_prepend_ptr[3] = 0x00; + my_packet -> nx_packet_prepend_ptr[4] = 0x06; /* Hardware address size */ + my_packet -> nx_packet_prepend_ptr[5] = 0x04; /* IP address size */ + + /* Check the type. */ + if (type == NX_RARP_OPTION_REQUEST) + { + my_packet -> nx_packet_prepend_ptr[6] = 0x00; /* RARP request */ + my_packet -> nx_packet_prepend_ptr[7] = 0x03; + } + else if (type == NX_RARP_OPTION_RESPONSE) + { + my_packet -> nx_packet_prepend_ptr[6] = 0x00; /* RARP response */ + my_packet -> nx_packet_prepend_ptr[7] = 0x04; + } + else + { + my_packet -> nx_packet_prepend_ptr[6] = 0x00; /* Invalid RARP type */ + my_packet -> nx_packet_prepend_ptr[7] = 0x00; + } + my_packet -> nx_packet_prepend_ptr[8] = 0x11; /* Sender Ethernet hardware address */ + my_packet -> nx_packet_prepend_ptr[9] = 0x22; + my_packet -> nx_packet_prepend_ptr[10] = 0x33; + my_packet -> nx_packet_prepend_ptr[11] = 0x44; + my_packet -> nx_packet_prepend_ptr[12] = 0x55; + my_packet -> nx_packet_prepend_ptr[13] = 0x67; + my_packet -> nx_packet_prepend_ptr[14] = 0x01; /* Sender IP address */ + my_packet -> nx_packet_prepend_ptr[15] = 0x02; + my_packet -> nx_packet_prepend_ptr[16] = 0x03; + my_packet -> nx_packet_prepend_ptr[17] = 0x87; + my_packet -> nx_packet_prepend_ptr[18] = 0x11; /* Target hardware address */ + my_packet -> nx_packet_prepend_ptr[19] = 0x22; + my_packet -> nx_packet_prepend_ptr[20] = 0x33; + my_packet -> nx_packet_prepend_ptr[21] = 0x44; + my_packet -> nx_packet_prepend_ptr[22] = 0x55; + my_packet -> nx_packet_prepend_ptr[23] = 0x66; + my_packet -> nx_packet_prepend_ptr[24] = 0x01; /* Target IP address */ + my_packet -> nx_packet_prepend_ptr[25] = 0x02; + my_packet -> nx_packet_prepend_ptr[26] = 0x03; + my_packet -> nx_packet_prepend_ptr[27] = 0x04; + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Fake a receive RARP packet. */ + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[TEST_INTERFACE]; + + /* Adjust the prepend pointer. */ + my_packet -> nx_packet_prepend_ptr = my_packet -> nx_packet_prepend_ptr - NX_ETHERNET_SIZE; + + /* Adjust the packet length. */ + my_packet -> nx_packet_length = my_packet -> nx_packet_length + NX_ETHERNET_SIZE; + + /* Setup the ethernet frame pointer to build the ethernet frame. Backup another 2 + bytes to get 32-bit word alignment. */ + ethernet_frame_ptr = (ULONG *) (my_packet -> nx_packet_prepend_ptr - 2); + + /* Build the ethernet frame. */ + *ethernet_frame_ptr = 0x00000011; + *(ethernet_frame_ptr+1) = 0x22334456; + *(ethernet_frame_ptr+2) = (0x00000011 << 16) | (0x22334457 >> 16); + *(ethernet_frame_ptr+3) = ((0x22334457 & 0xFFFF) << 16); + *(ethernet_frame_ptr+3) |= NX_ETHERNET_RARP; + + /* Endian swapping if NX_LITTLE_ENDIAN is defined. */ + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr)); + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr+3)); + + /* Set the packet pointer. */ + *packet_ptr = my_packet; +} +static VOID ip_address_change_notify(NX_IP *ip_ptr, VOID *additional_info) +{ +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rarp_basic_processing_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: RARP Basic Processing Test................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_rarp_branch_test.c b/test/regression/netxduo_test/netx_rarp_branch_test.c new file mode 100644 index 00000000..9e03c02f --- /dev/null +++ b/test/regression/netxduo_test/netx_rarp_branch_test.c @@ -0,0 +1,383 @@ +/* This NetX test concentrates on the code coverage for RARP functions, + *_nx_rarp_packet_receive +*/ + +#include "nx_api.h" +#include "tx_thread.h" +#include "nx_rarp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static CHAR *pointer; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT rarp_packet_allocate(NX_IP *ip_ptr, NX_PACKET **packet_ptr, UINT arp_type, + UCHAR *source_ip, UCHAR *source_physical, + UCHAR *target_ip, UCHAR *target_physical); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rarp_branch_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UCHAR source_mac[6]; +UCHAR source_ip[4]; +UCHAR destination_mac[6]; +UCHAR destination_ip[6]; + + /* Print out some test information banners. */ + printf("NetX Test: RARP Branch Test.........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Test _nx_rarp_packet_receive. */ + /* Hit condition of if (*(message_ptr + 6)) */ + source_mac[0] = 0x11; + source_mac[1] = 0x22; + source_mac[2] = 0x33; + source_mac[3] = 0x44; + source_mac[4] = 0x55; + source_mac[5] = 0x67; + source_ip[0] = 0x01; + source_ip[1] = 0x02; + source_ip[2] = 0x03; + source_ip[3] = 0x87; + + destination_mac[0] = 0x11; + destination_mac[1] = 0x22; + destination_mac[2] = 0x33; + destination_mac[3] = 0x44; + destination_mac[4] = 0x55; + destination_mac[5] = 0x66; + destination_ip[0] = 0x01; + destination_ip[1] = 0x02; + destination_ip[2] = 0x03; + destination_ip[3] = 0x04; + + /* Allocate ARP packet, */ + status = rarp_packet_allocate(&ip_0, &my_packet, NX_RARP_OPTION_RESPONSE, source_ip, source_mac, destination_ip, destination_mac); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + + /* Call function. */ + _nx_rarp_packet_receive(&ip_0, my_packet); + + /* Set the MAC and IP address. */ + source_mac[0] = 0x11; + source_mac[1] = 0x22; + source_mac[2] = 0x33; + source_mac[3] = 0x44; + source_mac[4] = 0x55; + source_mac[5] = 0x67; + source_ip[0] = 0x01; + source_ip[1] = 0x02; + source_ip[2] = 0x03; + source_ip[3] = 0x87; + + destination_mac[0] = 0x11; + destination_mac[1] = 0x22; + destination_mac[2] = 0x33; + destination_mac[3] = 0x44; + destination_mac[4] = 0x55; + destination_mac[5] = 0x66; + destination_ip[0] = 0x00; + destination_ip[1] = 0x00; + destination_ip[2] = 0x00; + destination_ip[3] = 0x00; + + /* Allocate ARP packet, */ + status = rarp_packet_allocate(&ip_0, &my_packet, NX_RARP_OPTION_RESPONSE, source_ip, source_mac, destination_ip, destination_mac); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + + /* Call function. */ + _nx_rarp_packet_receive(&ip_0, my_packet); + + + /* Hit condition of if (previous_ip_address != *(message_ptr + 6)) */ + source_mac[0] = 0x11; + source_mac[1] = 0x22; + source_mac[2] = 0x33; + source_mac[3] = 0x44; + source_mac[4] = 0x55; + source_mac[5] = 0x67; + source_ip[0] = 0x01; + source_ip[1] = 0x02; + source_ip[2] = 0x03; + source_ip[3] = 0x87; + + destination_mac[0] = 0x11; + destination_mac[1] = 0x22; + destination_mac[2] = 0x33; + destination_mac[3] = 0x44; + destination_mac[4] = 0x55; + destination_mac[5] = 0x66; + destination_ip[0] = 0x01; + destination_ip[1] = 0x02; + destination_ip[2] = 0x03; + destination_ip[3] = 0x04; + + /* Allocate ARP packet, */ + status = rarp_packet_allocate(&ip_0, &my_packet, NX_RARP_OPTION_RESPONSE, source_ip, source_mac, destination_ip, destination_mac); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + + /* Call function. */ + _nx_rarp_packet_receive(&ip_0, my_packet); + + /* Set the MAC and IP address. */ + source_mac[0] = 0x11; + source_mac[1] = 0x22; + source_mac[2] = 0x33; + source_mac[3] = 0x44; + source_mac[4] = 0x55; + source_mac[5] = 0x67; + source_ip[0] = 0x01; + source_ip[1] = 0x02; + source_ip[2] = 0x03; + source_ip[3] = 0x87; + + destination_mac[0] = 0x11; + destination_mac[1] = 0x22; + destination_mac[2] = 0x33; + destination_mac[3] = 0x44; + destination_mac[4] = 0x55; + destination_mac[5] = 0x66; + destination_ip[0] = 0x01; + destination_ip[1] = 0x02; + destination_ip[2] = 0x03; + destination_ip[3] = 0x05; + + /* Allocate ARP packet, */ + status = rarp_packet_allocate(&ip_0, &my_packet, NX_RARP_OPTION_RESPONSE, source_ip, source_mac, destination_ip, destination_mac); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + + /* Call function. */ + _nx_rarp_packet_receive(&ip_0, my_packet); + + /* Allocate ARP packet, */ + status = rarp_packet_allocate(&ip_0, &my_packet, NX_RARP_OPTION_RESPONSE, source_ip, source_mac, destination_ip, destination_mac); + + /* Check status. */ + if (status != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[0]; + my_packet -> nx_packet_length -= 1; + + /* Call function. */ + _nx_rarp_packet_receive(&ip_0, my_packet); + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +UINT rarp_packet_allocate(NX_IP *ip_ptr, NX_PACKET **packet_ptr, UINT arp_type, + UCHAR *source_ip, UCHAR *source_physical, + UCHAR *target_ip, UCHAR *target_physical) +{ + +NX_PACKET *my_packet; + + + /* Allocate a packet to build the ARP message in. */ + if (nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet, NX_PHYSICAL_HEADER, NX_NO_WAIT)) + { + + /* Error getting packet, so just get out! */ + return (NX_FALSE); + } + + /* Create a fake RARP response packet to assign address(1.2.3.4)! */ + my_packet -> nx_packet_prepend_ptr[0] = 0x00; /* Ethernet header */ + my_packet -> nx_packet_prepend_ptr[1] = 0x01; + my_packet -> nx_packet_prepend_ptr[2] = 0x80; /* IP address */ + my_packet -> nx_packet_prepend_ptr[3] = 0x00; + my_packet -> nx_packet_prepend_ptr[4] = 0x06; /* Hardware address size */ + my_packet -> nx_packet_prepend_ptr[5] = 0x04; /* IP address size */ + + /* Check the type. */ + if (arp_type == NX_RARP_OPTION_REQUEST) + { + my_packet -> nx_packet_prepend_ptr[6] = 0x00; /* RARP request */ + my_packet -> nx_packet_prepend_ptr[7] = 0x03; + } + else if (arp_type == NX_RARP_OPTION_RESPONSE) + { + my_packet -> nx_packet_prepend_ptr[6] = 0x00; /* RARP response */ + my_packet -> nx_packet_prepend_ptr[7] = 0x04; + } + else + { + my_packet -> nx_packet_prepend_ptr[6] = 0x00; /* Invalid RARP type */ + my_packet -> nx_packet_prepend_ptr[7] = 0x00; + } + + my_packet -> nx_packet_prepend_ptr[8] = source_physical[0]; /* Sender Ethernet hardware address */ + my_packet -> nx_packet_prepend_ptr[9] = source_physical[1];; + my_packet -> nx_packet_prepend_ptr[10] = source_physical[2];; + my_packet -> nx_packet_prepend_ptr[11] = source_physical[3];; + my_packet -> nx_packet_prepend_ptr[12] = source_physical[4];; + my_packet -> nx_packet_prepend_ptr[13] = source_physical[5];; + my_packet -> nx_packet_prepend_ptr[14] = source_ip[0]; /* Sender IP address */ + my_packet -> nx_packet_prepend_ptr[15] = source_ip[1]; + my_packet -> nx_packet_prepend_ptr[16] = source_ip[2]; + my_packet -> nx_packet_prepend_ptr[17] = source_ip[3]; + my_packet -> nx_packet_prepend_ptr[18] = target_physical[0]; /* Target hardware address */ + my_packet -> nx_packet_prepend_ptr[19] = target_physical[1]; + my_packet -> nx_packet_prepend_ptr[20] = target_physical[2]; + my_packet -> nx_packet_prepend_ptr[21] = target_physical[3]; + my_packet -> nx_packet_prepend_ptr[22] = target_physical[4]; + my_packet -> nx_packet_prepend_ptr[23] = target_physical[5]; + my_packet -> nx_packet_prepend_ptr[24] = target_ip[0]; /* Target IP address */ + my_packet -> nx_packet_prepend_ptr[25] = target_ip[1]; + my_packet -> nx_packet_prepend_ptr[26] = target_ip[2]; + my_packet -> nx_packet_prepend_ptr[27] = target_ip[3]; + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Return packet. */ + *packet_ptr = my_packet; + + return (NX_TRUE); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rarp_branch_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RARP Branch Test..........................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_rarp_multiple_interfaces_test.c b/test/regression/netxduo_test/netx_rarp_multiple_interfaces_test.c new file mode 100644 index 00000000..44f9e5c1 --- /dev/null +++ b/test/regression/netxduo_test/netx_rarp_multiple_interfaces_test.c @@ -0,0 +1,292 @@ +/* This NetX test concentrates on the RARP for multiple interfaces. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_rarp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static VOID ntest_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static VOID fake_rarp_response_packet(NX_PACKET **my_packet, UINT type); +extern VOID _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern VOID _nx_ram_network_driver_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT interface_instance_id); + +#define NX_ETHERNET_RARP 0x8035 +#define NX_ETHERNET_SIZE 14 + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rarp_multiple_interfaces_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", 0, 0, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Attach the 2nd interface IP address so it dosn't need RARP service. */ + status = nx_ip_interface_attach(&ip_0, "2nd interface", 0, 0, _nx_ram_network_driver_256); + if(status != NX_SUCCESS) + { + error_counter++; + } +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Print out some test information banners. */ + printf("NetX Test: RARP Multiple interfaces Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable RARP for IP Instance 0. */ + status = nx_rarp_enable(&ip_0); + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = packet_process; + + /* Verify the address of interface 0 is resolved. */ + status = nx_ip_interface_status_check(&ip_0, 0, NX_IP_ADDRESS_RESOLVED, &actual_status, 2 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if ((status != NX_SUCCESS) || (actual_status != NX_IP_ADDRESS_RESOLVED)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Verify the address of interface 1 is not resolved. */ + status = nx_ip_interface_status_check(&ip_0, 1, NX_IP_ADDRESS_RESOLVED, &actual_status, 2 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_PACKET *fake_packet; + + /* Fake the response packet. */ + fake_rarp_response_packet(&fake_packet, NX_RARP_OPTION_RESPONSE); + + /* Call the driver to receive this packet. */ + _nx_ram_network_driver_receive(&ip_0, fake_packet, 0); + + /* Clear the callback function. */ + advanced_packet_process_callback = NX_NULL; + + return NX_TRUE; +} +static VOID fake_rarp_response_packet(NX_PACKET **packet_ptr, UINT type) +{ +UINT status; +NX_PACKET *my_packet; +ULONG *ethernet_frame_ptr; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create a fake RARP response packet to assign address(1.2.3.4)! */ + my_packet -> nx_packet_prepend_ptr[0] = 0x00; /* Ethernet header */ + my_packet -> nx_packet_prepend_ptr[1] = 0x01; + my_packet -> nx_packet_prepend_ptr[2] = 0x80; /* IP address */ + my_packet -> nx_packet_prepend_ptr[3] = 0x00; + my_packet -> nx_packet_prepend_ptr[4] = 0x06; /* Hardware address size */ + my_packet -> nx_packet_prepend_ptr[5] = 0x04; /* IP address size */ + + /* Check the type. */ + if (type == NX_RARP_OPTION_REQUEST) + { + my_packet -> nx_packet_prepend_ptr[6] = 0x00; /* RARP request */ + my_packet -> nx_packet_prepend_ptr[7] = 0x03; + } + else if (type == NX_RARP_OPTION_RESPONSE) + { + my_packet -> nx_packet_prepend_ptr[6] = 0x00; /* RARP response */ + my_packet -> nx_packet_prepend_ptr[7] = 0x04; + } + else + { + my_packet -> nx_packet_prepend_ptr[6] = 0x00; /* Invalid RARP type */ + my_packet -> nx_packet_prepend_ptr[7] = 0x00; + } + my_packet -> nx_packet_prepend_ptr[8] = 0x11; /* Sender Ethernet hardware address */ + my_packet -> nx_packet_prepend_ptr[9] = 0x22; + my_packet -> nx_packet_prepend_ptr[10] = 0x33; + my_packet -> nx_packet_prepend_ptr[11] = 0x44; + my_packet -> nx_packet_prepend_ptr[12] = 0x55; + my_packet -> nx_packet_prepend_ptr[13] = 0x67; + my_packet -> nx_packet_prepend_ptr[14] = 0x01; /* Sender IP address */ + my_packet -> nx_packet_prepend_ptr[15] = 0x02; + my_packet -> nx_packet_prepend_ptr[16] = 0x03; + my_packet -> nx_packet_prepend_ptr[17] = 0x87; + my_packet -> nx_packet_prepend_ptr[18] = 0x11; /* Target hardware address */ + my_packet -> nx_packet_prepend_ptr[19] = 0x22; + my_packet -> nx_packet_prepend_ptr[20] = 0x33; + my_packet -> nx_packet_prepend_ptr[21] = 0x44; + my_packet -> nx_packet_prepend_ptr[22] = 0x55; + my_packet -> nx_packet_prepend_ptr[23] = 0x66; + my_packet -> nx_packet_prepend_ptr[24] = 0x01; /* Target IP address */ + my_packet -> nx_packet_prepend_ptr[25] = 0x02; + my_packet -> nx_packet_prepend_ptr[26] = 0x03; + my_packet -> nx_packet_prepend_ptr[27] = 0x04; + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Fake a receive RARP packet. */ + my_packet -> nx_packet_ip_interface = &ip_0.nx_ip_interface[TEST_INTERFACE]; + + /* Adjust the prepend pointer. */ + my_packet -> nx_packet_prepend_ptr = my_packet -> nx_packet_prepend_ptr - NX_ETHERNET_SIZE; + + /* Adjust the packet length. */ + my_packet -> nx_packet_length = my_packet -> nx_packet_length + NX_ETHERNET_SIZE; + + /* Setup the ethernet frame pointer to build the ethernet frame. Backup another 2 + bytes to get 32-bit word alignment. */ + ethernet_frame_ptr = (ULONG *) (my_packet -> nx_packet_prepend_ptr - 2); + + /* Build the ethernet frame. */ + *ethernet_frame_ptr = 0x00000011; + *(ethernet_frame_ptr+1) = 0x22334456; + *(ethernet_frame_ptr+2) = (0x00000011 << 16) | (0x22334457 >> 16); + *(ethernet_frame_ptr+3) = ((0x22334457 & 0xFFFF) << 16); + *(ethernet_frame_ptr+3) |= NX_ETHERNET_RARP; + + /* Endian swapping if NX_LITTLE_ENDIAN is defined. */ + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr)); + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr+1)); + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr+2)); + NX_CHANGE_ULONG_ENDIAN(*(ethernet_frame_ptr+3)); + + /* Set the packet pointer. */ + *packet_ptr = my_packet; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rarp_multiple_interfaces_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: RARP Basic Processing Test................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_rarp_nxe_api_test.c b/test/regression/netxduo_test/netx_rarp_nxe_api_test.c new file mode 100644 index 00000000..c704534e --- /dev/null +++ b/test/regression/netxduo_test/netx_rarp_nxe_api_test.c @@ -0,0 +1,218 @@ +/* This NetX test concentrates on the basic UDP operation. */ + +#include "nx_rarp.h" +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP invalid_ip; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rarp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG rarp_requests_sent; +ULONG rarp_responses_received; +ULONG rarp_invalid_messages; + + + /* Print out some test information banners. */ + printf("NetX Test: RARP NXE API Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_rarp_disable api */ + /************************************************/ + + /* Enable the RARP feature for NULL IP instance. */ + status = nx_rarp_disable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Disable the RARP feature for invalid IP instance. */ + status = nx_rarp_disable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_rarp_enable api */ + /************************************************/ + + /* Enable the RARP feature for NULL IP instance. */ + status = nx_rarp_enable(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Enable the RARP feature for invalid IP instance. */ + status = nx_rarp_enable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***********************************************/ + /* Tested the nxe_rarp_info_get api */ + /************************************************/ + + /* Get the RARP information for NULL IP instance. */ + status = nx_rarp_info_get(NX_NULL, &rarp_requests_sent, &rarp_responses_received, &rarp_invalid_messages); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the ID for invalid IP instance. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the RARP information for invalid IP instance. */ + status = nx_rarp_info_get(&invalid_ip, &rarp_requests_sent, &rarp_responses_received, &rarp_invalid_messages); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable the RARP feature. */ + ip_0.nx_ip_rarp_queue_process = NX_NULL; + ip_0.nx_ip_rarp_responses_received = NX_NULL; + + /* Get the RARP information for invalid IP instance. */ + status = nx_rarp_info_get(&ip_0, &rarp_requests_sent, &rarp_responses_received, &rarp_invalid_messages); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output success. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rarp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RARP NXE API Test.........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_rarp_packet_allocate_fail_test.c b/test/regression/netxduo_test/netx_rarp_packet_allocate_fail_test.c new file mode 100644 index 00000000..7c61b997 --- /dev/null +++ b/test/regression/netxduo_test/netx_rarp_packet_allocate_fail_test.c @@ -0,0 +1,186 @@ +/* This NetX test concentrates on the auxiliary packet usage of RARP module. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_rarp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern VOID test_control_return(UINT status); + +#if !defined(NX_DISABLE_RARP_INFO) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL no_packet_pool_0; +static NX_PACKET_POOL no_packet_pool_1; +static NX_IP ip_0; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static VOID ntest_0_entry(ULONG thread_input); +extern VOID test_control_return(UINT status); +extern VOID _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +#define NX_ETHERNET_RARP 0x8035 +#define NX_ETHERNET_SIZE 14 + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +VOID netx_rarp_packet_allocate_fail_test_application_define(VOID *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; +NX_PACKET *pkt_ptr; +UINT header_size = sizeof(NX_PACKET); + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an auxiliary packet pool. */ +#if defined(__PRODUCT_NETXDUO__) && defined(NX_PACKET_ALIGNMENT) + header_size = (sizeof(NX_PACKET) + NX_PACKET_ALIGNMENT - 1) / NX_PACKET_ALIGNMENT * NX_PACKET_ALIGNMENT; + pointer = (CHAR *)(((ALIGN_TYPE)pointer + NX_PACKET_ALIGNMENT - 1) / NX_PACKET_ALIGNMENT * NX_PACKET_ALIGNMENT); +#endif + status = nx_packet_pool_create(&no_packet_pool_0, "NetX Auxiliary Packet Pool", 256, pointer, (256 + header_size)); + pointer = pointer + 256 + header_size; + + if (status) + error_counter++; + + /* Create a packet pool with no packet. */ + status = nx_packet_pool_create(&no_packet_pool_1, "NetX No Packet Pool", 256, pointer, (256 + header_size)); + pointer = pointer + 256 + header_size; + + if (status) + error_counter++; + + /* Allocate the only one packet from pool. */ + nx_packet_allocate(&no_packet_pool_0, &pkt_ptr, NX_TCP_PACKET, NX_NO_WAIT); + nx_packet_allocate(&no_packet_pool_1, &pkt_ptr, NX_TCP_PACKET, NX_NO_WAIT); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", 0, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (VOID *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static VOID ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: RARP Packet Allocate Fail Test............................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set packet pool to empty one. */ + ip_0.nx_ip_default_packet_pool = &no_packet_pool_0; +#ifdef NX_ENABLE_DUAL_PACKET_POOL + ip_0.nx_ip_auxiliary_packet_pool = &no_packet_pool_0; +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ + + /* Enable RARP for IP Instance 0. */ + status = nx_rarp_enable(&ip_0); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Waiting NetX sending the RARP request to get the address. */ + tx_thread_sleep(1.5 * NX_IP_PERIODIC_RATE); + + /* No RARP request should be sent due to no packet. */ + if ((ip_0.nx_ip_rarp_requests_sent) || (no_packet_pool_0.nx_packet_pool_empty_requests == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_DUAL_PACKET_POOL + /* Set auxiliry packet pool to empty one. */ + ip_0.nx_ip_auxiliary_packet_pool = &no_packet_pool_1; + + /* Waiting NetX sending the RARP request to get the address. */ + tx_thread_sleep(1.5 * NX_IP_PERIODIC_RATE); + + /* No RARP request should be sent due to no packet. */ + if ((ip_0.nx_ip_rarp_requests_sent) || (no_packet_pool_1.nx_packet_pool_empty_requests == 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +VOID netx_rarp_packet_allocate_fail_test_application_define(VOID *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: RARP Packet Allocate Fail Test............................N/A\n"); + + test_control_return(3); + +} +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ diff --git a/test/regression/netxduo_test/netx_raw_nxe_api_test.c b/test/regression/netxduo_test/netx_raw_nxe_api_test.c new file mode 100644 index 00000000..0e5b6a43 --- /dev/null +++ b/test/regression/netxduo_test/netx_raw_nxe_api_test.c @@ -0,0 +1,744 @@ +/* This NetX test concentrates on the raw nxe API. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_tcp.h" +#include "nx_udp.h" +#include "nx_packet.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_ERROR_CHECKING) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP invalid_ip; +#ifdef __PRODUCT_NETXDUO__ +NXD_ADDRESS des_address; +#endif +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_raw_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +NX_PACKET *invalid_packet; +NX_PACKET *invalid_packet2; +UCHAR *temp_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: IP Raw Nxe API Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(my_packet, "ABCD", 4, &pool_0, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable raw with null pointer, should return error. */ + status = nx_ip_raw_packet_enable(NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable raw with invalid IP ID, should return error. */ + invalid_ip.nx_ip_id = 0; + status = nx_ip_raw_packet_enable(&invalid_ip); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable raw with null pointer, should return error. */ + status = nx_ip_raw_packet_disable(NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable raw with invalid IP. */ + status = nx_ip_raw_packet_disable(&invalid_ip); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive raw packet before enable, error should be returned. */ + status = nx_ip_raw_packet_receive(&ip_0, &my_packet, NX_IP_PERIODIC_RATE); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive raw packet without null packet pointer. */ + status = nx_ip_raw_packet_receive(&ip_0, NX_NULL, NX_IP_PERIODIC_RATE); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive raw packet with invalid IP instance. */ + ip_0.nx_ip_id = 0; + status = nx_ip_raw_packet_receive(&ip_0, &my_packet, NX_IP_PERIODIC_RATE); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ip_id = NX_IP_ID; + + /* Send the raw IP packet before enable. */ + status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL); + if (status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ +#ifdef FEATURE_NX_IPV6 + des_address.nxd_ip_version = NX_IP_VERSION_V6; + des_address.nxd_ip_address.v6[0] = 0x20010DB8; + des_address.nxd_ip_address.v6[1] = 0x00010001; + des_address.nxd_ip_address.v6[2] = 0x021122FF; + des_address.nxd_ip_address.v6[3] = 0xFE334456; + + /* Send raw packet with null IP instance. */ + status = nxd_ip_raw_packet_send(&ip_0, my_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif +#endif + + + /* Enable RAW. */ + status = nx_ip_raw_packet_enable(&ip_0); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set raw filter with null IP instance, should return error. */ + status = nx_ip_raw_packet_filter_set(NX_NULL, NX_NULL); +#ifdef NX_ENABLE_IP_RAW_PACKET_FILTER + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#else + if(status != NX_NOT_SUPPORTED) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Receive raw packet with null IP instance, should return error. */ + status = nx_ip_raw_packet_receive(NX_NULL, NX_NULL, NX_IP_PERIODIC_RATE); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Send the raw IP packet with null IP instance. */ + status = nx_ip_raw_packet_send(NX_NULL, my_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL); + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the raw IP packet with invalid IP instance. */ + status = nx_ip_raw_packet_send(&invalid_ip, my_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL); + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the raw IP packet with NULL packet. */ + invalid_packet2 = NX_NULL; + status = nx_ip_raw_packet_send(&ip_0, invalid_packet2, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL); + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the raw IP packet with invalid packet state. */ +#ifdef __PRODUCT_NETXDUO__ + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_FREE; +#else + my_packet -> nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_FREE; +#endif + status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL); + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef __PRODUCT_NETXDUO__ + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; +#else + my_packet -> nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; +#endif + + /* Send the raw IP packet with invalid IP address. */ + status = nx_ip_raw_packet_send(&ip_0, my_packet, 0, NX_IP_NORMAL); + if (status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the raw IP packet with invalid type of service. */ + status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0xffffffff); + if (status != NX_OPTION_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &invalid_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + temp_ptr = invalid_packet -> nx_packet_prepend_ptr; + invalid_packet -> nx_packet_prepend_ptr = invalid_packet -> nx_packet_data_start; + /* Send the invalid raw IP packet. */ + status = nx_ip_raw_packet_send(&ip_0, invalid_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL); + if (status != NX_UNDERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_prepend_ptr = temp_ptr; + + temp_ptr = invalid_packet -> nx_packet_append_ptr; + invalid_packet -> nx_packet_append_ptr = invalid_packet -> nx_packet_data_end + 1; + /* Send the invalid raw IP packet. */ + status = nx_ip_raw_packet_send(&ip_0, invalid_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL); + if (status != NX_OVERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_append_ptr = temp_ptr; + + + /* Send raw packet with null IP instance. */ + status = nx_ip_raw_packet_source_send(NX_NULL, my_packet, IP_ADDRESS(1, 2, 3, 5), 0, NX_IP_NORMAL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send raw packet with null packet. */ + invalid_packet2 = NX_NULL; + status = nx_ip_raw_packet_source_send(&ip_0, invalid_packet2, IP_ADDRESS(1, 2, 3, 5), 0, NX_IP_NORMAL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send raw packet with invalid IP instance. */ + ip_0.nx_ip_id = 0; + status = nx_ip_raw_packet_source_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0, NX_IP_NORMAL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ip_id = NX_IP_ID; + + /* Send raw packet with invalid IP address. */ + status = nx_ip_raw_packet_source_send(&ip_0, my_packet, 0, 0, NX_IP_NORMAL); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send raw packet with invalid packet state. */ +#ifdef __PRODUCT_NETXDUO__ + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_FREE; +#else + my_packet -> nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_FREE; +#endif + status = nx_ip_raw_packet_source_send(&ip_0, my_packet, 0, 0, NX_IP_NORMAL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef __PRODUCT_NETXDUO__ + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; +#else + my_packet -> nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; +#endif + + /* Send raw packet with invalid type of service. */ + status = nx_ip_raw_packet_source_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0, 0xffffffff); + if(status != NX_OPTION_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + temp_ptr = invalid_packet -> nx_packet_prepend_ptr; + invalid_packet -> nx_packet_prepend_ptr = invalid_packet -> nx_packet_data_start; + /* Send the invalid raw IP packet. */ + status = nx_ip_raw_packet_source_send(&ip_0, invalid_packet, IP_ADDRESS(1, 2, 3, 5), 0, NX_IP_NORMAL); + if (status != NX_UNDERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_prepend_ptr = temp_ptr; + + temp_ptr = invalid_packet -> nx_packet_append_ptr; + invalid_packet -> nx_packet_append_ptr = invalid_packet -> nx_packet_data_end + 1; + /* Send the invalid raw IP packet. */ + status = nx_ip_raw_packet_source_send(&ip_0, invalid_packet, IP_ADDRESS(1, 2, 3, 5), 0, NX_IP_NORMAL); + if (status != NX_OVERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_append_ptr = temp_ptr; + + /* Send raw packet with invalid interface index. */ + status = nx_ip_raw_packet_source_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0xffff, NX_IP_NORMAL); + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + ip_0.nx_ip_interface[0].nx_interface_valid = NX_FALSE; + /* Send raw packet with invalid interface. */ + status = nx_ip_raw_packet_source_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0, NX_IP_NORMAL); + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ip_interface[0].nx_interface_valid = NX_TRUE; + + /* Set raw packet receive queue size with null ip instance. */ + status = nx_ip_raw_receive_queue_max_set(NX_NULL, 5); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set raw packet receive queue size with invalid IP instance. */ + ip_0.nx_ip_id = 0; + status = nx_ip_raw_receive_queue_max_set(&ip_0, 5); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ip_id = NX_IP_ID; + +#ifdef __PRODUCT_NETXDUO__ + +#ifdef FEATURE_NX_IPV6 + /* Send raw packet with null IP instance. */ + status = nxd_ip_raw_packet_send(NX_NULL, my_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send raw packet with invalid IP instance. */ + invalid_ip.nx_ip_id = 0; + status = nxd_ip_raw_packet_send(&invalid_ip, my_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send raw packet with NULL packet. */ + invalid_ip.nx_ip_id = 0; + invalid_packet2 = NX_NULL; + status = nxd_ip_raw_packet_send(&ip_0, invalid_packet2, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send raw packet with invalid packet state. */ +#ifdef __PRODUCT_NETXDUO__ + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_FREE; +#else + my_packet -> nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_FREE; +#endif + status = nxd_ip_raw_packet_send(&ip_0, my_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef __PRODUCT_NETXDUO__ + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; +#else + my_packet -> nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; +#endif + + /* Send raw packet to NULL IP address. */ + status = nxd_ip_raw_packet_send(&ip_0, my_packet, NX_NULL, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send raw packet to an invalid IP address. */ + des_address.nxd_ip_version = 8; + status = nxd_ip_raw_packet_send(&ip_0, my_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + des_address.nxd_ip_version = NX_IP_VERSION_V6; + + /* Send raw packet with invalid protocol. */ + status = nxd_ip_raw_packet_send(&ip_0, my_packet, &des_address, 0xffff, 0x80, NX_IP_NORMAL); + if(status != NX_INVALID_PARAMETERS) + { + printf("ERROR!\n"); + test_control_return(1); + } + des_address.nxd_ip_version = NX_IP_VERSION_V4; + + temp_ptr = invalid_packet -> nx_packet_prepend_ptr; + invalid_packet -> nx_packet_prepend_ptr = invalid_packet -> nx_packet_data_start; + /* Send the invalid raw IP packet. */ + status = nxd_ip_raw_packet_send(&ip_0, invalid_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if (status != NX_UNDERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_prepend_ptr = temp_ptr; + + temp_ptr = invalid_packet -> nx_packet_append_ptr; + invalid_packet -> nx_packet_append_ptr = invalid_packet -> nx_packet_data_end + 1; + /* Send the invalid raw IP packet. */ + status = nxd_ip_raw_packet_send(&ip_0, invalid_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if (status != NX_OVERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_append_ptr = temp_ptr; + + des_address.nxd_ip_version = NX_IP_VERSION_V6; + + temp_ptr = invalid_packet -> nx_packet_prepend_ptr; + invalid_packet -> nx_packet_prepend_ptr = invalid_packet -> nx_packet_data_start; + /* Send the invalid raw IP packet. */ + status = nxd_ip_raw_packet_send(&ip_0, invalid_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if (status != NX_UNDERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_prepend_ptr = temp_ptr; + + /* Send to unspecified IP address. */ + memset(des_address.nxd_ip_address.v6, 0, sizeof(des_address.nxd_ip_address.v6)); + status = nxd_ip_raw_packet_send(&ip_0, my_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if (status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + des_address.nxd_ip_address.v6[0] = 1; + + temp_ptr = invalid_packet -> nx_packet_prepend_ptr; + invalid_packet -> nx_packet_prepend_ptr = invalid_packet -> nx_packet_data_start; + /* Send the invalid raw IP packet. */ + status = nxd_ip_raw_packet_source_send(&ip_0, invalid_packet, &des_address, 0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if (status != NX_UNDERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_prepend_ptr = temp_ptr; + + temp_ptr = invalid_packet -> nx_packet_append_ptr; + invalid_packet -> nx_packet_append_ptr = invalid_packet -> nx_packet_data_end + 1; + /* Send the invalid raw IP packet. */ + status = nxd_ip_raw_packet_source_send(&ip_0, invalid_packet, &des_address, 0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if (status != NX_OVERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_append_ptr = temp_ptr; + + /* Send to an invalid IPv6 addres. */ + des_address.nxd_ip_address.v6[0] = 0; + des_address.nxd_ip_address.v6[1] = 0; + des_address.nxd_ip_address.v6[2] = 0; + des_address.nxd_ip_address.v6[3] = 0; + status = nxd_ip_raw_packet_send(&ip_0, my_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Send to an invalid IPv4 address. */ + des_address.nxd_ip_version = NX_IP_VERSION_V4; + des_address.nxd_ip_address.v4 = 0; + status = nxd_ip_raw_packet_send(&ip_0, my_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send to an valid IPv4 address with an invalid packet. */ + des_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + invalid_packet -> nx_packet_prepend_ptr = invalid_packet -> nx_packet_data_start; + /* Send the invalid raw IP packet. */ + status = nxd_ip_raw_packet_send(&ip_0, invalid_packet, &des_address, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if (status != NX_UNDERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_prepend_ptr = temp_ptr; + + /* Send to an valid IPv4 address with an invalid packet. */ + des_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + invalid_packet -> nx_packet_prepend_ptr = invalid_packet -> nx_packet_data_start; + /* Send the invalid raw IP packet. */ + status = nxd_ip_raw_packet_source_send(&ip_0, invalid_packet, &des_address, 0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if (status != NX_UNDERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_prepend_ptr = temp_ptr; + +#ifdef FEATURE_NX_IPV6 + /* Send to an valid IPv6 address with an invalid packet. */ + des_address.nxd_ip_version = NX_IP_VERSION_V6; + invalid_packet -> nx_packet_prepend_ptr = invalid_packet -> nx_packet_data_start; + /* Send the invalid raw IP packet. */ + status = nxd_ip_raw_packet_source_send(&ip_0, invalid_packet, &des_address, 0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if (status != NX_UNDERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + invalid_packet -> nx_packet_prepend_ptr = temp_ptr; +#endif /* FEATURE_NX_IPV6 */ + + + /* Send raw packet with null IP instance. */ + status = nxd_ip_raw_packet_source_send(NX_NULL, my_packet, &des_address, 0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send raw packet with null packet. */ + status = nxd_ip_raw_packet_source_send(&ip_0, NX_NULL, &des_address, 0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send raw packet with null destination. */ + status = nxd_ip_raw_packet_source_send(&ip_0, my_packet, NX_NULL, 0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send to an invalid IP address. */ + des_address.nxd_ip_version = 8; + status = nxd_ip_raw_packet_source_send(&ip_0, my_packet, &des_address, 0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send to an invalid IPv4 address. */ + des_address.nxd_ip_version = NX_IP_VERSION_V4; + des_address.nxd_ip_address.v4 = 0; + status = nxd_ip_raw_packet_source_send(&ip_0, my_packet, &des_address, 0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send with an invalid interface. */ + des_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + status = nxd_ip_raw_packet_source_send(&ip_0, my_packet, &des_address, 0xffff, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Send to an invalid IPv6 address. */ + des_address.nxd_ip_version = NX_IP_VERSION_V6; + des_address.nxd_ip_address.v6[0] = 0; + des_address.nxd_ip_address.v6[1] = 0; + des_address.nxd_ip_address.v6[2] = 0; + des_address.nxd_ip_address.v6[3] = 0; + status = nxd_ip_raw_packet_source_send(&ip_0, my_packet, &des_address, 0, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send with invalid IPv6 address index. */ + des_address.nxd_ip_address.v6[0] = 0x20010DB8; + des_address.nxd_ip_address.v6[1] = 0x00010001; + des_address.nxd_ip_address.v6[2] = 0x021122FF; + des_address.nxd_ip_address.v6[3] = 0xFE334456; + status = nxd_ip_raw_packet_source_send(&ip_0, my_packet, &des_address, 0xffff, NX_IP_RAW >> 16, 0x80, NX_IP_NORMAL); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#endif + + + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_raw_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: IP Raw Nxe API Test.......................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_raw_special_test.c b/test/regression/netxduo_test/netx_raw_special_test.c new file mode 100644 index 00000000..e822dafd --- /dev/null +++ b/test/regression/netxduo_test/netx_raw_special_test.c @@ -0,0 +1,324 @@ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_udp.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static TX_THREAD ntest_2; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_2_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_addr_0; +static NXD_ADDRESS ipv6_addr_1; +#endif + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_raw_special_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&ntest_2, "thread 2", ntest_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + if (status != NX_SUCCESS) + error_counter++; + + /* Create IP instances. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status != NX_SUCCESS) + error_counter++; + + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 10), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status != NX_SUCCESS) + error_counter++; + + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status != NX_SUCCESS) + error_counter++; + + /* Enable UDP for IP instances. */ + status = nx_udp_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_udp_enable(&ip_1); + if (status != NX_SUCCESS) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + ipv6_addr_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_addr_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_addr_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_addr_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_addr_0.nxd_ip_address.v6[3] = 0x00010001; + + ipv6_addr_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_addr_1.nxd_ip_address.v6[0] = 0x30010000; + ipv6_addr_1.nxd_ip_address.v6[1] = 0x02300000; + ipv6_addr_1.nxd_ip_address.v6[2] = 0x00440000; + ipv6_addr_1.nxd_ip_address.v6[3] = 0x00010002; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + status = nxd_ipv6_enable(&ip_1); + if (status != NX_SUCCESS) + error_counter++; + + status = nxd_icmp_enable(&ip_0); + if(status != NX_SUCCESS) + error_counter++; + + status = nxd_icmp_enable(&ip_1); + if(status) + error_counter++; + + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_addr_0, 64, NX_NULL); + if(status != NX_SUCCESS) + error_counter++; +#endif + + +} + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG value; +UINT i; + + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Raw Special Test....................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* DAD */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE); + if ((status) || (value != NX_IP_INITIALIZE_DONE)) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + +#ifndef NX_DISABLE_ERROR_CHECKING + /* Send the raw IP packet Before enable. */ + status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 10), NX_IP_NORMAL); + if (status != NX_NOT_ENABLED) + error_counter++; +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Enable RAW. */ + status = nx_ip_raw_packet_enable(&ip_0); + if (status != NX_SUCCESS) + error_counter++; + + /* Send to a address that can't be routed. */ + status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(23, 42, 3, 10), NX_IP_NORMAL); + if (status != NX_IP_ADDRESS_ERROR) + error_counter++; + + /* Let ntest_1 do its job. */ + tx_thread_resume(&ntest_1); + tx_thread_suspend(&ntest_0); + + /* Two threads ntest_1 and ntest_2 suspend on the packet now. This will cover some code in raw_packet_processing */ + status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 10), NX_IP_NORMAL); + if(status != NX_SUCCESS) + error_counter++; + + /* Send packets to fill the raw packet receive queue. This will cover some code in raw_packet_processing */ + for(i = 0; i < ip_0.nx_ip_raw_received_packet_max + 5; i++) + { + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 10), NX_IP_NORMAL); + if(status != NX_SUCCESS) + { + nx_packet_release(my_packet); + } + } + + /* Disable RAW for ip_1. To test the situation that there are packets in the RAW packet queue. */ + status = nx_ip_raw_packet_disable(&ip_1); + if(status != NX_SUCCESS) + error_counter++; + + /* Enable again. */ + status = nx_ip_raw_packet_enable(&ip_1); + if(status != NX_SUCCESS) + error_counter++; + + tx_thread_suspend(&ntest_0); + + /* When thread ends, raw_packet_cleanup will be called. */ + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +ULONG value; + + /* Check the status of the IP instances. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE); + if ((status) || (value != NX_IP_INITIALIZE_DONE)) + error_counter++; + + status = nx_ip_raw_packet_enable(&ip_1); + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_resume(&ntest_2); + status = nx_ip_raw_packet_receive(&ip_1, &my_packet, 5 * NX_IP_PERIODIC_RATE); + if(status == NX_SUCCESS) + { + status = nx_packet_release(my_packet); + if (status != NX_SUCCESS) + error_counter++; + } + + /* Suspend on the packet to test raw_packet_cleanup. */ + status = nx_ip_raw_packet_receive(&ip_1, &my_packet, 5 * NX_IP_PERIODIC_RATE); + +} + +static void ntest_2_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + tx_thread_resume(&ntest_0); + + status = nx_ip_raw_packet_receive(&ip_1, &my_packet, 5 * NX_IP_PERIODIC_RATE); + if(status == NX_SUCCESS) + { + status = nx_packet_release(my_packet); + if (status != NX_SUCCESS) + error_counter++; + } + + tx_thread_resume(&ntest_0); + /* Suspend on the packet to test raw_packet_cleanup. */ + status = nx_ip_raw_packet_receive(&ip_1, &my_packet, 5 * NX_IP_PERIODIC_RATE); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_raw_special_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: IPv6 Raw Special Test.....................................N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/netxduo_test/netx_tcp_4_duplicate_ack_test.c b/test/regression/netxduo_test/netx_tcp_4_duplicate_ack_test.c new file mode 100644 index 00000000..aa0dcbeb --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_4_duplicate_ack_test.c @@ -0,0 +1,340 @@ +/* This NetX test concentrates on the processing 4 duplicate ACK packets. */ + +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static ULONG duplicate_ack = 0; +static ULONG ack_number = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_4_duplicate_ack_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + duplicate_ack = 0; + ack_number = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; +UINT old_threshold; + + /* Print out some test information banners. */ + printf("NetX Test: TCP 4 Duplicate ACK Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Disable preemption from IP thread 1. */ + tx_thread_preemption_change(&thread_0, 2, &old_threshold); + + /* Set ACK number that should be duplicated. */ + ack_number = client_socket.nx_tcp_socket_tx_sequence; + + /* Set driver filter to drop the first packet. */ + advanced_packet_process_callback = packet_process; + + /* Set the TCP filter to check duplicate ACK. */ + ip_0.nx_ip_tcp_packet_receive = tcp_packet_receive; + + for (i = 0; i < 5; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_NO_WAIT); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Enable preemption. */ + tx_thread_preemption_change(&thread_0, old_threshold, &old_threshold); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +UINT i; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + for (i = 0; i < 5; i++) + { + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + error_counter++; + + nx_packet_release(packet_ptr); + } + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Simply drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + advanced_packet_process_callback = NX_NULL; + return NX_TRUE; +} + +static void tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Get the TCP header pointer. */ + tcp_header_ptr = (NX_TCP_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + if (tcp_header_ptr -> nx_tcp_acknowledgment_number == ack_number) + { + + /* It is duplicate ACK. */ + duplicate_ack++; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_4_duplicate_ack_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP 4 Duplicate ACK Test..................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_ack_before_release_test.c b/test/regression/netxduo_test/netx_tcp_ack_before_release_test.c new file mode 100644 index 00000000..eef390b5 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_ack_before_release_test.c @@ -0,0 +1,313 @@ +/* This NetX test concentrates on the TCP receives ACK for the transmitting packet + * that has not been released by driver. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket_0; +static NX_TCP_SOCKET server_socket_0; +static NX_PACKET *process_packet; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, + UINT *operation_ptr, UINT *delay_ptr); +static UINT driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, + UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ack_before_release_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + process_packet = NX_NULL; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; + + /* Print out some test information banners. */ + printf("NetX Test: TCP ACK Before Release Test..............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_0, "Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket_0, 12, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket_0, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(packet_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Set the driver filter to delay the packet and receive fake ACK packet. */ + advanced_packet_process_callback = driver_packet_process; + process_packet = packet_ptr; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket_0, packet_ptr, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Check the packet is not ACKed yet since driver should delay it for 1s. */ + if (client_socket_0.nx_tcp_socket_transmit_sent_count != 1) + { + error_counter++; + } + +#ifdef __PRODUCT_NETXDUO__ + /* Wakeup server thread. */ + tx_thread_resume(&thread_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; +#endif /* __PRODUCT_NETXDUO__ */ + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_0, "Server Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket_0, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket_0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + /* Let client run. */ + tx_thread_suspend(&thread_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; +#endif /* __PRODUCT_NETXDUO__ */ +} + +static UINT driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, + UINT *operation_ptr, UINT *delay_ptr) +{ +ULONG seq; + + if (packet_ptr == process_packet) + { + + /* Delay the packet by driver. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + advanced_packet_process_callback = NX_NULL; + + /* Send a fake packet that ACKs the delayed packet. */ + seq = server_socket_0.nx_tcp_socket_rx_sequence; + server_socket_0.nx_tcp_socket_rx_sequence = client_socket_0.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_ack(&server_socket_0, + server_socket_0.nx_tcp_socket_tx_sequence); + server_socket_0.nx_tcp_socket_rx_sequence = seq; + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ack_before_release_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP ACK Before Release Test...............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_ack_check_for_syn_message_test.c b/test/regression/netxduo_test/netx_tcp_ack_check_for_syn_message_test.c new file mode 100644 index 00000000..ec486264 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_ack_check_for_syn_message_test.c @@ -0,0 +1,383 @@ +/* This NetX test concentrates on fast retransmit. */ + +/* Procedure: +1. Client connect with Server. +2. Check the socket state. +3. Modify client socket state to unbind the client socket. +4. Check the socket state. +5. Set the callback function to check the TCP message. +6. Bind the client socket again. +7. Call nx_tcp_client_socket_connect to send SYN messsage. +8. Modify the server rx_sequence to let the SYN sequence number in server socket window in callback function. +9. Check if the server send the RST message. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ack_check_for_syn_message_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 512 * 30); + pointer = pointer + 512 * 30; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP ACK Check For SYN Message Test........................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Let thread 1 run. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Check the socket state. */ + if ((client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) || + (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + { + error_counter++; + } + + /* Modified the socket state as NX_TCP_TIMED_WAIT to unbind client socket. */ + client_socket.nx_tcp_socket_state = NX_TCP_TIMED_WAIT; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Check the socket state. */ + if ((client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) || + (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + { + error_counter++; + } + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = client_driver_packet_process; + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = client_tcp_packet_receive; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Call connection. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status == NX_SUCCESS) + { + error_counter++; + } + + /* Check the socket state. */ + if ((client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) || + (server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE)) + { + error_counter++; + } + + /* Reset the callback functions. */ + advanced_packet_process_callback = NX_NULL; + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Let thread 0 run. */ + tx_thread_relinquish(); + + /* Determine if the test was successful. */ + if ((error_counter) || (syn_counter != 1) || (rst_counter != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Ingore the server packet. */ + if (ip_ptr != &ip_0) + return NX_TRUE; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an SYN packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) + { + + /* Update the counter. */ + syn_counter++; + + /* Modified the server rx_sequence to let the SYN sequence number in server socket window. */ + server_socket.nx_tcp_socket_rx_sequence = tcp_header_ptr -> nx_tcp_sequence_number - 1; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an RST packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + + /* Update the counter. */ + rst_counter++; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ack_check_for_syn_message_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP ACK Check For SYN Message Test........................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_ack_check_issue_test.c b/test/regression/netxduo_test/netx_tcp_ack_check_issue_test.c new file mode 100644 index 00000000..0e257888 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_ack_check_issue_test.c @@ -0,0 +1,328 @@ +/* This NetX test concentrates a bug in nx_tcp_socket_state_ack_check.c. */ +/* When the packet is in TCP transmit queue but not sent by driver yet, + * an incoming ACK packet will trigger an ACK response. That is a bug. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static ULONG ack_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, + UINT *operation_ptr, UINT *delay_ptr); +static UINT driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, + UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ack_check_issue_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP ACK Check Issue Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Set the driver filter to delay the packet. */ + advanced_packet_process_callback = driver_packet_process; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Wakeup the server thread. */ + tx_thread_resume(&thread_1); + + /* Sleep one second. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if ((error_counter) || (ack_counter)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Let client thread run. */ + tx_thread_suspend(&thread_1); + + /* Setup the TCP receive filter to verify whether client sends ACK to server. */ + ip_1.nx_ip_tcp_packet_receive = tcp_packet_receive; + + /* Send an ACK to client. */ + _nx_tcp_packet_send_ack(&server_socket, server_socket.nx_tcp_socket_tx_sequence); + + /* Remove the filter function before disconnect. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + +static UINT driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, + UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Delay the packet by driver. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + advanced_packet_process_callback = NX_NULL; + + return NX_TRUE; +} + +static void tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && + (packet_ptr -> nx_packet_length == 20)) + { + ack_counter++; + } + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ack_check_issue_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP ACK Check Issue Test..................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_advertised_window_update_test.c b/test/regression/netxduo_test/netx_tcp_advertised_window_update_test.c new file mode 100644 index 00000000..dcca5772 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_advertised_window_update_test.c @@ -0,0 +1,331 @@ +/* This NetX test updating advertise window. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +static UINT updated_window; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_advertised_window_update_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +char *msg = MSG; + + /* Print out test information banner. */ + printf("NetX Test: TCP Advertised Window Update Test........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 37 + Packet 2 contains bytes 38 - 75 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 38); + my_packet1 -> nx_packet_length = 38; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 38; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[38], 38); + my_packet2 -> nx_packet_length = 38; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 38; + + /* Set a fixed sequence number to make sure + "nx_tcp_socket_state_ack_check.c: ((INT)tcp_header_ptr -> nx_tcp_sequence_number - (INT)ending_rx_sequence > 0)" + will not be hit. */ + client_socket.nx_tcp_socket_tx_sequence = 0x00221122; + client_socket.nx_tcp_socket_tx_sequence_recover = 0x00221121; + server_socket.nx_tcp_socket_rx_sequence = 0x00221122; + server_socket.nx_tcp_socket_rx_sequence_acked = 0x00221122; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Set the callback function. */ + updated_window = 0x200; + client_socket.nx_tcp_socket_rx_window_current = updated_window; + + /* Send packet 2. */ + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + if (status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 76) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + if(server_socket.nx_tcp_socket_tx_window_advertised != updated_window) + error_counter++; + +#ifndef NX_DISABLE_PACKET_INFO + /* Check packet pool state. */ + if(pool_0.nx_packet_pool_invalid_releases) + error_counter++; +#endif + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_advertised_window_update_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Advertised Window Update Test.........................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_basic_processing_test.c b/test/regression/netxduo_test/netx_tcp_basic_processing_test.c new file mode 100644 index 00000000..17f6642d --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_basic_processing_test.c @@ -0,0 +1,646 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +#ifdef __PRODUCT_NETXDUO__ +static NX_PACKET_POOL my_auxiliary_pool; +#endif +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket); +#ifndef NX_DISABLE_EXTENDED_NOTIFY_SUPPORT +static void thread_0_establish_notify(NX_TCP_SOCKET *client_socket); +static void thread_0_disconnect_complete_notify(NX_TCP_SOCKET *client_socket); +#endif +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket); +#ifdef NX_ENABLE_EXTENDED_NOTIFY_SUPPORT +static void timed_wait_notify(NX_TCP_SOCKET *client_socket); +#endif +static void window_update_notify(NX_TCP_SOCKET *client_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_basic_processing_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + /* Create a auxiliary packet pool. 128*10 = 1280 */ + status = nx_packet_pool_create(&my_auxiliary_pool, "NetX Auxiliary Packet Pool", 128, pointer, 1280); + pointer = pointer + 1280; + + if (status) + error_counter++; +#endif + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +#if defined(__PRODUCT_NETXDUO__) + + /* Set the auxiliary packet pool for IP instance 0. */ + status = nx_ip_auxiliary_packet_pool_set(&ip_0, &my_auxiliary_pool); + + /* Check the status. */ +#ifdef NX_ENABLE_DUAL_PACKET_POOL + if(status != NX_SUCCESS) + error_counter++; +#else + if(status != NX_NOT_SUPPORTED) + error_counter++; +#endif + + /* Set the auxiliary packet pool for IP instance 1. */ + status = nx_ip_auxiliary_packet_pool_set(&ip_1, &my_auxiliary_pool); + + /* Check the status. */ +#ifdef NX_ENABLE_DUAL_PACKET_POOL + if(status != NX_SUCCESS) + error_counter++; +#else + if(status != NX_NOT_SUPPORTED) + error_counter++; +#endif + +#endif +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT compare_port; +ULONG mss, peer_mss, peer_ip_address, peer_port, bytes_available; +ULONG tcp_packets_sent, tcp_bytes_sent, tcp_packets_received, tcp_bytes_received, tcp_invalid_packets, tcp_receive_packets_dropped, tcp_checksum_errors, tcp_connections, tcp_disconnections, tcp_connections_dropped, tcp_retransmit_packets; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; +ULONG window_size = 200; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Basic Processing Test................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_TCP_WINDOW_SCALING + window_size = 0xFFFFFF; +#endif /* NX_ENABLE_TCP_WINDOW_SCALING */ + + /* Loop to establish 1000 connections, send one message, and disconnect. */ + while ((thread_0_counter < 1000) && (error_counter == 0)) + { + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, window_size, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup a receive notify function. */ + status = nx_tcp_socket_receive_notify(&client_socket, thread_0_receive_notify); + + /* Check for error. */ + if (status) + error_counter++; + +#ifndef NX_DISABLE_EXTENDED_NOTIFY_SUPPORT + status = nx_tcp_socket_establish_notify(&client_socket, thread_0_establish_notify); + + /* Check for error. */ + if (status) + error_counter++; + + status = nx_tcp_socket_disconnect_complete_notify(&client_socket, thread_0_disconnect_complete_notify); + + /* Check for error. */ + if (status) + error_counter++; +#endif + +#ifdef NX_ENABLE_EXTENDED_NOTIFY_SUPPORT + /* Setup a receive notify function. */ + status = nx_tcp_socket_timed_wait_callback(&client_socket, timed_wait_notify); + + /* Check for error. */ + if (status) + error_counter++; +#endif + + /* Setup a receive notify function. */ + status = nx_tcp_socket_window_update_notify_set(&client_socket, window_update_notify); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Pickup the port for the client socket. */ + status = nx_tcp_client_socket_port_get(&client_socket, &compare_port); + + /* Check for error. */ + if ((status) || (client_port != compare_port)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get information about peer socket before connection. */ + status = nx_tcp_socket_peer_info_get(&client_socket, &peer_ip_address, &peer_port); + + /* The status should not be successful since the connection is not established. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + status = nx_tcp_socket_mss_set(&client_socket, 200); + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get the socket mss. */ + status = nx_tcp_socket_mss_get(&client_socket, &mss); + + /* Check for error. */ + if (status) + error_counter++; + + /* Set the socket mss. */ + status = nx_tcp_socket_mss_set(&client_socket, mss - 1); + + /* Check for error. */ + if (status == NX_SUCCESS) + error_counter++; + + /* Get the peer socket mss. */ + status = nx_tcp_socket_mss_peer_get(&client_socket, &peer_mss); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get the socket bytes available. */ + status = nx_tcp_socket_bytes_available(&client_socket, &bytes_available); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get information about peer socket. */ + status = nx_tcp_socket_peer_info_get(&client_socket, &peer_ip_address, &peer_port); + + /* Check for errors. */ + if ((status) || (peer_ip_address != IP_ADDRESS(1, 2, 3, 5)) || (peer_port != 12)) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get nothing from the socket. */ + status = nx_tcp_socket_info_get(&client_socket, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&client_socket, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + + if((packets_sent != 1) || (bytes_sent != 28)) + error_counter++; +#endif + + /* Check for errors. */ + if ((error_counter) || (status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != window_size)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + } + + /* Get nothing from the overall TCP information. */ + status = nx_tcp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get the overall TCP information. */ + status = nx_tcp_info_get(&ip_0, &tcp_packets_sent, &tcp_bytes_sent, &tcp_packets_received, &tcp_bytes_received, + &tcp_invalid_packets, &tcp_receive_packets_dropped, &tcp_checksum_errors, &tcp_connections, + &tcp_disconnections, &tcp_connections_dropped, &tcp_retransmit_packets); + +#ifndef NX_DISABLE_TCP_INFO + if((tcp_packets_sent != 1000) || (tcp_bytes_sent != 1000*28) || (tcp_connections != 1000) || (tcp_disconnections != 2000)) + error_counter++; +#endif + + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != 1000) || (thread_1_counter != 1000) || (connections != 1000) || (disconnections) || + (tcp_packets_received) || (tcp_bytes_received) || (tcp_invalid_packets) ||(tcp_receive_packets_dropped) || (tcp_checksum_errors) || + (tcp_connections_dropped) || (tcp_retransmit_packets)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup a receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, thread_1_receive_notify); + + /* Check for error. */ + if (status) + error_counter++; + + /* Configure the socket further. */ + status = nx_tcp_socket_transmit_configure(&server_socket, 10, 300, 10, 0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Loop to create and establish server connections. */ + while((thread_1_counter < 1000) && (error_counter == 0)) + { + + /* Increment thread 1's counter. */ + thread_1_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; + else + connections++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket) +{ + + client_receives++; +} + +#ifndef NX_DISABLE_EXTENDED_NOTIFY_SUPPORT +static void thread_0_establish_notify(NX_TCP_SOCKET *client_socket) +{ + ; +} + +static void thread_0_disconnect_complete_notify(NX_TCP_SOCKET *client_socket) +{ + ; +} +#endif + +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket) +{ + + server_receives++; +} + +#ifdef NX_ENABLE_EXTENDED_NOTIFY_SUPPORT +static void timed_wait_notify(NX_TCP_SOCKET *client_socket) +{ +} +#endif + +static void window_update_notify(NX_TCP_SOCKET *client_socket) +{ +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_basic_processing_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Basic Processing Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_branch_test.c b/test/regression/netxduo_test/netx_tcp_branch_test.c new file mode 100644 index 00000000..5cbe96d0 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_branch_test.c @@ -0,0 +1,2150 @@ +/* This NetX test concentrates on the code coverage for TCP functions, + * _nx_tcp_connect_cleanup.c + * _nx_tcp_disconnect_cleanup.c + * _nx_tcp_client_bind_cleanup.c + * _nx_tcp_receive_cleanup.c + * _nx_tcp_transmit_cleanup.c + * _nx_tcp_socket_thread_resume.c + * _nx_tcp_packet_receive.c + * _nx_tcp_server_socket_listen.c + * _nx_tcp_socket_mss_set.c + * _nx_tcp_socket_state_fin_wait2.c + * _nx_tcp_socket_state_data_trim.c + * _nx_tcp_client_socket_unbind.c + * _nx_tcp_socket_disconnect.c + * _nx_tcp_client_bind_cleanup.c + */ + +#include "nx_api.h" +#include "tx_thread.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_packet.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define ASSERT_THREAD_COUNT 1 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_test1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET tcp_socket; +static NX_TCP_SOCKET tcp_socket_2; +static NX_TCP_SOCKET test_socket; +static NX_TCP_LISTEN tcp_listen[2]; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UCHAR pool_area[102400]; +#ifdef __PRODUCT_NETXDUO__ +static UINT disconnect_flag = NX_FALSE; + +#if defined FEATURE_NX_IPV6 && !defined NX_DISABLE_ASSERT +static TX_THREAD thread_for_assert[ASSERT_THREAD_COUNT]; +static UCHAR stack_for_assert[ASSERT_THREAD_COUNT][DEMO_STACK_SIZE]; +#endif + +#if !defined NX_DISABLE_PACKET_CHAIN && !defined NX_DISABLE_ASSERT +static TX_THREAD thread_for_assert_1; +static UCHAR stack_for_assert_1[DEMO_STACK_SIZE]; +#endif /* __PRODUCT_NETXDUO__ */ + +#endif +#ifdef FEATURE_NX_IPV6 +static UINT address_index; +#endif /* FEATURE_NX_IPV6 */ + +#ifdef __PRODUCT_NETXDUO__ +/* TCP packet. 192.168.100.23:6206 -> 192.168.100.4:80 */ +static unsigned char pkt1[54] = { +0x00, 0x1e, 0x8f, 0xb1, 0x7a, 0xd4, 0xf4, 0x8e, /* ....z... */ +0x38, 0xa3, 0x25, 0xb3, 0x08, 0x00, 0x45, 0x00, /* 8.%...E. */ +0x00, 0x28, 0x10, 0x9d, 0x00, 0x00, 0x80, 0x06, /* .(...... */ +0xe0, 0xc6, 0xc0, 0xa8, 0x64, 0x17, 0xc0, 0xa8, /* ....d... */ +0x64, 0x04, 0x18, 0x3e, 0x00, 0x50, 0x62, 0xf3, /* d..>.Pb. */ +0xa5, 0x46, 0x54, 0x7e, 0x0c, 0xe7, 0x50, 0x10, /* .FT~..P. */ +0x01, 0x00, 0xe3, 0x3a, 0x00, 0x00 /* ...:.. */ +}; + +#ifdef FEATURE_NX_IPV6 +/* TCP packet. [fe80::1]:6206 -> [fe80::211:22ff:fe33:4456]:80 */ +static unsigned char pkt2[74] = { +0x00, 0x1e, 0x8f, 0xb1, 0x7a, 0xd4, 0xf4, 0x8e, /* ....z... */ +0x38, 0xa3, 0x25, 0xb3, 0x86, 0xdd, 0x60, 0x00, /* 8.%...`. */ +0x00, 0x00, 0x00, 0x14, 0x06, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x18, 0x3e, /* "..3DV.> */ +0x00, 0x50, 0x62, 0xf3, 0xa5, 0x46, 0x54, 0x7e, /* .Pb..FT~ */ +0x0c, 0xe7, 0x50, 0x10, 0x01, 0x00, 0xc8, 0x0a, /* ..P..... */ +0x00, 0x00 /* .. */ +}; + +/* TCP packet with invalid option. SYN bits are set. */ +static unsigned char pkt3[78] = { +0x00, 0x1e, 0x8f, 0xb1, 0x7a, 0xd4, 0xf4, 0x8e, /* ....z... */ +0x38, 0xa3, 0x25, 0xb3, 0x86, 0xdd, 0x60, 0x00, /* 8.%...`. */ +0x00, 0x00, 0x00, 0x18, 0x06, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x18, 0x3e, /* "..3DV.> */ +0x00, 0x50, 0x62, 0xf3, 0xa5, 0x46, 0x54, 0x7e, /* .Pb..FT~ */ +0x0c, 0xe7, 0x60, 0x02, 0x01, 0x00, 0xb6, 0x14, /* ..`..... */ +0x00, 0x00, 0x02, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* TCP packet with invalid option. SYN bits are set. */ +static unsigned char pkt4[78] = { +0x00, 0x1e, 0x8f, 0xb1, 0x7a, 0xd4, 0xf4, 0x8e, /* ....z... */ +0x38, 0xa3, 0x25, 0xb3, 0x86, 0xdd, 0x60, 0x00, /* 8.%...`. */ +0x00, 0x00, 0x00, 0x18, 0x06, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x18, 0x3e, /* "..3DV.> */ +0x00, 0x50, 0x62, 0xf3, 0xa5, 0x46, 0x54, 0x7e, /* .Pb..FT~ */ +0x0c, 0xe7, 0x60, 0x00, 0x01, 0x00, 0xb6, 0x16, /* ..`..... */ +0x00, 0x00, 0x02, 0x00, 0x00, 0x00 /* ...... */ +}; +#endif + +/* TCP packet. 192.168.100.4:80 -> 192.168.100.4:80 */ +static unsigned char pkt5[60] = { +0xf4, 0x8e, 0x38, 0xa3, 0x25, 0xb3, 0x20, 0x0b, /* ..8.%. . */ +0xc7, 0x94, 0x45, 0x96, 0x08, 0x00, 0x45, 0x10, /* ..E...E. */ +0x00, 0x28, 0x02, 0x6b, 0x40, 0x00, 0x3a, 0x06, /* .(.k@.:. */ +0xf4, 0xfb, 0xc0, 0xa8, 0x64, 0x04, 0xc0, 0xa8, /* ....d... */ +0x64, 0x04, 0x00, 0x50, 0x00, 0x50, 0x9e, 0xc2, /* d..P.P.. */ +0x86, 0xc6, 0x18, 0xc8, 0x09, 0x1a, 0x50, 0x00, /* ......P. */ +0x01, 0xf9, 0x1c, 0x87, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + +/* TCP packet. [fe80::211:22ff:fe33:4456]:6206 -> [fe80::211:22ff:fe33:4456]:80 */ +static unsigned char pkt6[78] = { +0x00, 0x1e, 0x8f, 0xb1, 0x7a, 0xd4, 0xf4, 0x8e, /* ....z... */ +0x38, 0xa3, 0x25, 0xb3, 0x86, 0xdd, 0x60, 0x00, /* 8.%...`. */ +0x00, 0x00, 0x00, 0x18, 0x06, 0xff, 0xff, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0xff, 0x33, 0x44, 0x56, 0xff, 0x02, /* ...3DV.. */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0xff, 0x33, 0x44, 0x56, 0x18, 0x3e, /* ...3DV.> */ +0x00, 0x50, 0x62, 0xf3, 0xa5, 0x46, 0x54, 0x7e, /* .Pb..FT~ */ +0x0c, 0xe7, 0x60, 0x00, 0x01, 0x00, 0x96, 0x97, /* ..`..... */ +0x00, 0x00, 0x01, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* TCP packet. 255.255.255.255:80 -> 192.168.100.4:80 */ +static unsigned char pkt7[60] = { +0xf4, 0x8e, 0x38, 0xa3, 0x25, 0xb3, 0x20, 0x0b, /* ..8.%. . */ +0xc7, 0x94, 0x45, 0x96, 0x08, 0x00, 0x45, 0x10, /* ..E...E. */ +0x00, 0x28, 0x02, 0x6b, 0x40, 0x00, 0x3a, 0x06, /* .(.k@.:. */ +0x19, 0xa9, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xa8, /* ........ */ +0x64, 0x04, 0x00, 0x50, 0x00, 0x50, 0x9e, 0xc2, /* d..P.P.. */ +0x86, 0xc6, 0x18, 0xc8, 0x09, 0x1a, 0x50, 0x00, /* ......P. */ +0x01, 0xf9, 0x41, 0x34, 0x00, 0x00, 0x00, 0x00, /* ..A4.... */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + +/* TCP RST packet. 192.168.100.23:80 -> 192.168.100.4:80 */ +static unsigned char pkt8[60] = { +0xf4, 0x8e, 0x38, 0xa3, 0x25, 0xb3, 0x20, 0x0b, /* ..8.%. . */ +0xc7, 0x94, 0x45, 0x96, 0x08, 0x00, 0x45, 0x10, /* ..E...E. */ +0x00, 0x28, 0x02, 0x6b, 0x40, 0x00, 0x3a, 0x06, /* .(.k@.:. */ +0xf4, 0xe8, 0xc0, 0xa8, 0x64, 0x17, 0xc0, 0xa8, /* ....d... */ +0x64, 0x04, 0x00, 0x50, 0x00, 0x50, 0x9e, 0xc2, /* d..P.P.. */ +0x86, 0xc6, 0x18, 0xc8, 0x09, 0x1a, 0x50, 0x04, /* ......P. */ +0x01, 0xf9, 0x1c, 0x70, 0x00, 0x00, 0x00, 0x00, /* ...p.... */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + +/* TCP packet. 224.0.0.1:80 -> 192.168.100.4:80 */ +static unsigned char pkt9[60] = { +0xf4, 0x8e, 0x38, 0xa3, 0x25, 0xb3, 0x20, 0x0b, /* ..8.%. . */ +0xc7, 0x94, 0x45, 0x96, 0x08, 0x00, 0x45, 0x10, /* ..E...E. */ +0x00, 0x28, 0x02, 0x6b, 0x40, 0x00, 0x3a, 0x06, /* .(.k@.:. */ +0x39, 0xa7, 0xe0, 0x00, 0x00, 0x01, 0xc0, 0xa8, /* 9....... */ +0x64, 0x04, 0x00, 0x50, 0x00, 0x50, 0x9e, 0xc2, /* d..P.P.. */ +0x86, 0xc6, 0x18, 0xc8, 0x09, 0x1a, 0x50, 0x04, /* ......P. */ +0x01, 0xf9, 0x61, 0x2e, 0x00, 0x00, 0x00, 0x00, /* ..a..... */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + +/* TCP SYN packet. 192.168.100.24:80 -> 192.168.100.4:80 */ +static unsigned char pkt10[60] = { +0xf4, 0x8e, 0x38, 0xa3, 0x25, 0xb3, 0x20, 0x0b, /* ..8.%. . */ +0xc7, 0x94, 0x45, 0x96, 0x08, 0x00, 0x45, 0x10, /* ..E...E. */ +0x00, 0x28, 0x02, 0x6b, 0x40, 0x00, 0x3a, 0x06, /* .(.k@.:. */ +0xf4, 0xe7, 0xc0, 0xa8, 0x64, 0x18, 0xc0, 0xa8, /* ....d... */ +0x64, 0x04, 0x00, 0x50, 0x00, 0x50, 0x9e, 0xc2, /* d..P.P.. */ +0x86, 0xc6, 0x18, 0xc8, 0x09, 0x1a, 0x50, 0x02, /* ......P. */ +0x01, 0xf9, 0x1c, 0x71, 0x00, 0x00, 0x00, 0x00, /* ...q.... */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + +/* TCP SYN packet. 192.168.100.23:81 -> 192.168.100.4:80 */ +static unsigned char pkt11[60] = { +0xf4, 0x8e, 0x38, 0xa3, 0x25, 0xb3, 0x20, 0x0b, /* ..8.%. . */ +0xc7, 0x94, 0x45, 0x96, 0x08, 0x00, 0x45, 0x10, /* ..E...E. */ +0x00, 0x28, 0x02, 0x6b, 0x40, 0x00, 0x3a, 0x06, /* .(.k@.:. */ +0xf4, 0xe8, 0xc0, 0xa8, 0x64, 0x17, 0xc0, 0xa8, /* ....d... */ +0x64, 0x04, 0x00, 0x51, 0x00, 0x50, 0x9e, 0xc2, /* d..Q.P.. */ +0x86, 0xc6, 0x18, 0xc8, 0x09, 0x1a, 0x50, 0x02, /* ......P. */ +0x01, 0xf9, 0x1c, 0x71, 0x00, 0x00, 0x00, 0x00, /* ...q.... */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + +/* TCP SYN packet. [fe80::211:22ff:fe33:4456]:6206 -> [fe80::211:22ff:fe33:4456]:80 */ +static unsigned char pkt12[78] = { +0x00, 0x1e, 0x8f, 0xb1, 0x7a, 0xd4, 0xf4, 0x8e, /* ....z... */ +0x38, 0xa3, 0x25, 0xb3, 0x86, 0xdd, 0x60, 0x00, /* 8.%...`. */ +0x00, 0x00, 0x00, 0x18, 0x06, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x18, 0x3e, /* "..3DV.> */ +0x00, 0x50, 0x62, 0xf3, 0xa5, 0x46, 0x54, 0x7e, /* .Pb..FT~ */ +0x0c, 0xe7, 0x60, 0x02, 0x01, 0x00, 0xb7, 0x14, /* ..`..... */ +0x00, 0x00, 0x01, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* TCP RST packet. [fe80::211:22ff:fe33:4456]:6207 -> [fe80::211:22ff:fe33:4456]:80 */ +static unsigned char pkt13[78] = { +0x00, 0x1e, 0x8f, 0xb1, 0x7a, 0xd4, 0xf4, 0x8e, /* ....z... */ +0x38, 0xa3, 0x25, 0xb3, 0x86, 0xdd, 0x60, 0x00, /* 8.%...`. */ +0x00, 0x00, 0x00, 0x18, 0x06, 0xff, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 0x80, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, /* ........ */ +0x22, 0xff, 0xfe, 0x33, 0x44, 0x56, 0x18, 0x3f, /* "..3DV.? */ +0x00, 0x50, 0x62, 0xf3, 0xa5, 0x46, 0x54, 0x7e, /* .Pb..FT~ */ +0x0c, 0xe7, 0x60, 0x04, 0x01, 0x00, 0xb7, 0x11, /* ..`..... */ +0x00, 0x00, 0x01, 0x00, 0x00, 0x00 /* ...... */ +}; + +/* TCP RST packet. 192.168.100.24:80 -> 192.168.100.4:80 */ +static unsigned char pkt14[60] = { +0xf4, 0x8e, 0x38, 0xa3, 0x25, 0xb3, 0x20, 0x0b, /* ..8.%. . */ +0xc7, 0x94, 0x45, 0x96, 0x08, 0x00, 0x45, 0x10, /* ..E...E. */ +0x00, 0x28, 0x02, 0x6b, 0x40, 0x00, 0x3a, 0x06, /* .(.k@.:. */ +0xf4, 0xe7, 0xc0, 0xa8, 0x64, 0x18, 0xc0, 0xa8, /* ....d... */ +0x64, 0x04, 0x00, 0x50, 0x00, 0x50, 0x9e, 0xc2, /* d..P.P.. */ +0x86, 0xc6, 0x18, 0xc8, 0x09, 0x1a, 0x50, 0x04, /* ......P. */ +0x01, 0xf9, 0x1c, 0x6f, 0x00, 0x00, 0x00, 0x00, /* ...o.... */ +0x00, 0x00, 0x00, 0x00 /* .... */ +}; + +#endif /* __PRODUCT_NETXDUO__ */ + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID suspend_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER); +#ifdef __PRODUCT_NETXDUO__ +static VOID tcp_fast_periodic_processing(NX_IP *ip_ptr); +static VOID my_tcp_queue_process(NX_IP *ip_ptr); +static VOID ack_check_test(); +static VOID data_check_test(); +static VOID socket_packet_process_test(); + +#if defined FEATURE_NX_IPV6 && !defined NX_DISABLE_ASSERT +static VOID thread_for_assert_entry_0(ULONG thread_input); +static VOID (*thread_for_assert_entry[])(ULONG) = +{ + thread_for_assert_entry_0, +}; +#endif + +#if !defined NX_DISABLE_PACKET_CHAIN && !defined NX_DISABLE_ASSERT +static VOID thread_for_assert_entry_1(ULONG thread_input); +#endif + +#endif /* __PRODUCT_NETXDUO__ */ + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_branch_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Print out some test information banners. */ + printf("NetX Test: TCP Branch Test..........................................."); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pool_area, sizeof(pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for IP instance. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 processing for IP instance. */ + status = nxd_ipv6_enable(&ip_0); + + /* Check IPv6 enable status. */ + if (status) + error_counter++; + +#endif /* FEATURE_NX_IPV6 */ +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG system_state; +ULONG thread_state; +NX_PACKET *my_packet[3]; +TX_THREAD *suspension_list; +TX_INTERRUPT_SAVE_AREA + +#ifdef __PRODUCT_NETXDUO__ +NX_PACKET *packet_ptr; +NX_TCP_HEADER tcp_header, *tcp_header_ptr; +TX_THREAD *temp_suspend_thread; +NX_IPV4_HEADER *ipv4_header_ptr; +#ifndef NX_DISABLE_PACKET_CHAIN +UINT packet_counter; +#endif +#endif /* __PRODUCT_NETXDUO__ */ +#if defined FEATURE_NX_IPV6 && !defined NX_DISABLE_ASSERT +UINT i; +#endif /* NX_DISABLE_ASSERT */ + + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &tcp_socket, "TCP Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + status += nx_tcp_socket_create(&ip_0, &tcp_socket_2, "TCP Socket 2", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + +#ifdef FEATURE_NX_IPV6 + nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, &address_index); +#endif /* FEATURE_NX_IPV6 */ + if (nx_tcp_client_socket_bind(&tcp_socket, 80, 0)) + { + error_counter++; + } + + /* Test bind again. */ + if (nx_tcp_client_socket_bind(&tcp_socket, 80, 0) != NX_ALREADY_BOUND) + { + error_counter++; + } + + /* Cover true branch of (socket_ptr -> nx_tcp_socket_bind_in_progress). */ + tcp_socket_2.nx_tcp_socket_bind_in_progress = _tx_thread_current_ptr; + if (nx_tcp_client_socket_bind(&tcp_socket_2, 81, 0) != NX_ALREADY_BOUND) + { + error_counter++; + } + tcp_socket_2.nx_tcp_socket_bind_in_progress = NX_NULL; + if (nx_tcp_client_socket_bind(&tcp_socket_2, 81, 0)) + { + error_counter++; + } + +#if defined FEATURE_NX_IPV6 && !defined NX_DISABLE_ASSERT + for (i = 0; i < ASSERT_THREAD_COUNT; i++) + { + + /* Create the assert thread. */ + tx_thread_create(&thread_for_assert[i], "Assert Test thread", thread_for_assert_entry[i], 0, + stack_for_assert[i], DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert[i]); + tx_thread_delete(&thread_for_assert[i]); + } +#endif +#ifdef FEATURE_NX_IPV6 + ip_0.nx_ipv6_address[address_index].nxd_ipv6_address_attached = &ip_0.nx_ip_interface[0]; + nxd_ipv6_address_delete(&ip_0, address_index); +#endif /* FEATURE_NX_IPV6 */ + nx_tcp_client_socket_unbind(&tcp_socket); + + + /* suspension list is set to NULL. */ + suspension_list = NX_NULL; + _nx_tcp_socket_thread_resume(&suspension_list, 0); + + /* tx_thread_suspend_control_block is set to NULL. */ + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + _nx_tcp_client_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_connect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_transmit_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Test for invalid nx_tcp_socket_id */ + tx_thread_identify() -> tx_thread_suspend_control_block = (VOID*)&tcp_socket; + tcp_socket.nx_tcp_socket_id = 0; + _nx_tcp_client_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_connect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_transmit_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + tcp_socket.nx_tcp_socket_id = NX_TCP_ID; + + + TX_DISABLE + /* Test for Thread state in ISR. */ + tx_thread_identify() -> tx_thread_suspend_control_block = (VOID*)&tcp_socket; + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tcp_socket.nx_tcp_socket_connect_suspended_thread = tx_thread_identify(); + tcp_socket.nx_tcp_socket_disconnect_suspended_thread = tx_thread_identify(); + system_state = _tx_thread_system_state; + _tx_thread_system_state = 1; + _nx_tcp_client_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_connect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_transmit_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _tx_thread_system_state = 0; + _tx_thread_system_state = system_state; + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + TX_RESTORE + tx_thread_sleep(1); + + + /* tx_thread_suspend_control_block is set to TCP socket but tx_thread_suspend_cleanup is set to NULL. */ + tx_thread_identify() -> tx_thread_suspend_control_block = &tcp_socket; + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + _nx_tcp_client_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_connect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_transmit_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup and tx_thread_suspended_next. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspended_next = tx_thread_identify(); + tcp_socket.nx_tcp_socket_transmit_suspended_count = 1; + _nx_tcp_transmit_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspended_next = tx_thread_identify(); + tcp_socket.nx_tcp_socket_receive_suspended_count = 1; + _nx_tcp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspended_next = tx_thread_identify(); + tcp_socket.nx_tcp_socket_bound_previous = &tcp_socket; + tcp_socket.nx_tcp_socket_bind_suspended_count = 1; + _nx_tcp_client_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspended_next = tx_thread_identify(); + _nx_tcp_connect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + + /* Hit condition of if ((_tx_thread_system_state) || (&(ip_ptr -> nx_ip_thread) != _tx_thread_current_ptr)) in _nx_tcp_packet_receive(). */ + tx_mutex_get(&(ip_0.nx_ip_protection), TX_WAIT_FOREVER); + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + nx_packet_data_append(my_packet[0], "abcdefghijklmnopqrstuvwxyz", 26, &pool_0, NX_NO_WAIT); + + system_state = _tx_thread_system_state; + _tx_thread_system_state = 0; + + _nx_tcp_packet_receive(&ip_0, my_packet[0]); + ip_0.nx_ip_tcp_queue_head = NX_NULL; + ip_0.nx_ip_tcp_received_packet_count = 0; + + _tx_thread_system_state = system_state; + nx_packet_release(my_packet[0]); + + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + nx_packet_data_append(my_packet[0], "abcdefghijklmnopqrstuvwxyz", 26, &pool_0, NX_NO_WAIT); + system_state = _tx_thread_system_state; + _tx_thread_system_state = 1; + + _nx_tcp_packet_receive(&ip_0, my_packet[0]); + ip_0.nx_ip_tcp_queue_head = NX_NULL; + ip_0.nx_ip_tcp_received_packet_count = 0; + + _tx_thread_system_state = system_state; + nx_packet_release(my_packet[0]); + tx_mutex_put(&(ip_0.nx_ip_protection)); + + + /* Test _nx_tcp_server_socket_listen() */ + /* Hit condition: + 143 [ + - ][ + + ]: 2428 : if ((socket_ptr -> nx_tcp_socket_bound_next) || + 144 : 2428 : (socket_ptr -> nx_tcp_socket_bind_in_progress)) + */ + tcp_socket.nx_tcp_socket_bound_next = &tcp_socket; + _nx_tcp_server_socket_listen(&ip_0, 12, &tcp_socket, 5, NX_NULL); + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + + + /* Test _nx_tcp_server_socket_listen() */ + /* Hit condition: + 144 [ + + ][ - + ]: 305 : if ((socket_ptr -> nx_tcp_socket_bound_next) || + 145 : 303 : (socket_ptr -> nx_tcp_socket_bind_in_progress)). */ + tcp_socket.nx_tcp_socket_bind_in_progress = tx_thread_identify(); + _nx_tcp_server_socket_listen(&ip_0, 12, &tcp_socket, 5, NX_NULL); + tcp_socket.nx_tcp_socket_bind_in_progress = NX_NULL; + + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + tcp_socket.nx_tcp_socket_bind_in_progress = tx_thread_identify(); + _nx_tcp_server_socket_listen(&ip_0, 12, &tcp_socket, 5, NX_NULL); + tcp_socket.nx_tcp_socket_bind_in_progress = NX_NULL; + + + /* Hit condition of if ((mss > ((if_mtu - ip_header_size) - sizeof(NX_TCP_HEADER))) || (mss == 0)) in _nx_tcp_socket_mss_set. */ + tcp_socket.nx_tcp_socket_connect_interface = &ip_0.nx_ip_interface[0]; +#ifdef __PRODUCT_NETXDUO__ + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; +#endif + _nx_tcp_socket_mss_set(&tcp_socket, 5); + _nx_tcp_socket_mss_set(&tcp_socket, 0); + + +#ifdef __PRODUCT_NETXDUO__ + /* Hit condition of if (socket_ptr -> nx_tcp_socket_disconnect_suspended_thread) in _nx_tcp_socket_state_fin_wait2. */ + tcp_socket.nx_tcp_socket_fin_received = NX_TRUE; + tcp_socket.nx_tcp_socket_fin_sequence = tcp_socket.nx_tcp_socket_rx_sequence; + temp_suspend_thread = tcp_socket.nx_tcp_socket_disconnect_suspended_thread; + tcp_socket.nx_tcp_socket_disconnect_suspended_thread = NX_NULL; + _nx_tcp_socket_state_fin_wait2(&tcp_socket); + tcp_socket.nx_tcp_socket_disconnect_suspended_thread = temp_suspend_thread; + + + /* Hit condition of if (amount >= packet_ptr -> nx_packet_length) in _nx_tcp_socket_state_data_trim. */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + _nx_tcp_socket_state_data_trim(my_packet[0], 1); + _nx_tcp_socket_state_data_trim_front(my_packet[0], 0); + my_packet[0] -> nx_packet_length = 1; + _nx_tcp_socket_state_data_trim_front(my_packet[0], 0); + my_packet[0] -> nx_packet_length = 0; + _nx_tcp_socket_state_data_trim_front(my_packet[0], 1); + nx_packet_release(my_packet[0]); +#endif + + /* Test _nx_tcp_connect_cleanup */ + tcp_socket.nx_tcp_socket_id = 1; + _nx_tcp_connect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + + /* Test _nx_tcp_disconnect_cleanup(). */ + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + tcp_socket.nx_tcp_socket_id = NX_TCP_ID; + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = &tcp_socket; + tcp_socket.nx_tcp_socket_id = 0; + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + tcp_socket.nx_tcp_socket_id = 0; + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = &tcp_socket; + tcp_socket.nx_tcp_socket_id = NX_TCP_ID; + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + tcp_socket.nx_tcp_socket_id = NX_TCP_ID; + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = &tcp_socket; + tcp_socket.nx_tcp_socket_id = 0; + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + tcp_socket.nx_tcp_socket_id = 0; + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = &tcp_socket; + tcp_socket.nx_tcp_socket_id = NX_TCP_ID; + system_state = _tx_thread_system_state; + _tx_thread_system_state = 0; + _nx_tcp_connect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + _tx_thread_system_state = system_state; + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = &tcp_socket; + tcp_socket.nx_tcp_socket_id = NX_TCP_ID; + thread_state = tx_thread_identify() -> tx_thread_state; + tx_thread_identify() -> tx_thread_state = 0; + _nx_tcp_disconnect_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + tx_thread_identify() -> tx_thread_state = thread_state; + + + + /* Test _nx_tcp_client_socket_unbind(). */ + /* Hit false condition of if (socket_ptr -> nx_tcp_socket_state != NX_TCP_CLOSED) */ + tcp_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + _nx_tcp_client_socket_unbind(&tcp_socket); + + + /* Test _nx_tcp_socket_disconnect */ + /* Hit false condition of if ((socket_ptr -> nx_tcp_socket_state == NX_TCP_SYN_RECEIVED) && + (socket_ptr -> nx_tcp_socket_connect_interface != NX_NULL)) */ + tcp_socket.nx_tcp_socket_state = NX_TCP_SYN_SENT; + tcp_socket.nx_tcp_socket_client_type = NX_FALSE; + _nx_tcp_socket_disconnect(&tcp_socket, 1); + + /* Hit false condition of (wait_option) && (_tx_thread_current_ptr != &(ip_ptr -> nx_ip_thread) */ + tcp_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + tcp_socket.nx_tcp_socket_receive_suspension_list = &thread_test1; + tcp_socket.nx_tcp_socket_receive_suspended_count ++; + thread_test1.tx_thread_suspend_cleanup = suspend_cleanup; + thread_test1.tx_thread_suspend_control_block = &tcp_socket; + thread_test1.tx_thread_suspended_next = &thread_test1; + _nx_tcp_socket_disconnect(&tcp_socket, 0); + + /* Recover. */ + tcp_socket.nx_tcp_socket_receive_suspension_list = NX_NULL; + + +#ifdef __PRODUCT_NETXDUO__ + /* Hit false condition of (_tx_thread_current_ptr != &(ip_ptr -> nx_ip_thread) in _nx_tcp_socket_disconnect() */ + ip_0.nx_ip_tcp_fast_periodic_processing = tcp_fast_periodic_processing; + + /* Let trigger TCP fast periodic notify function. s*/ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the flag. */ + if (disconnect_flag != NX_TRUE) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + + /* Test _nx_tcp_server_socket_unaccept() */ + /* Hit false condition of (socket_ptr -> nx_tcp_socket_state == NX_TCP_CLOSED) && (socket_ptr -> nx_tcp_socket_bound_next)) */ + tcp_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + _nx_tcp_server_socket_unaccept(&tcp_socket); + + /* Hit false condition of (ip_ptr -> nx_ip_tcp_port_table[index] == socket_ptr) */ + tcp_socket.nx_tcp_socket_state = NX_TCP_LISTEN_STATE; + tcp_socket.nx_tcp_socket_bound_next = &test_socket; + tcp_socket.nx_tcp_socket_bound_previous = &test_socket; + test_socket.nx_tcp_socket_bound_next = NX_NULL; + test_socket.nx_tcp_socket_bound_previous = NX_NULL; + _nx_tcp_server_socket_unaccept(&tcp_socket); + + /* Hit false condition of if (listen_ptr) */ + tcp_socket.nx_tcp_socket_state = NX_TCP_LISTEN_STATE; + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + tcp_socket.nx_tcp_socket_bound_previous = NX_NULL; + _nx_tcp_server_socket_unaccept(&tcp_socket); + + /* Hit false condition of if (listen_ptr -> nx_tcp_listen_socket_ptr == socket_ptr) */ + tcp_socket.nx_tcp_socket_state = NX_TCP_LISTEN_STATE; + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + tcp_socket.nx_tcp_socket_bound_previous = NX_NULL; + ip_0.nx_ip_tcp_active_listen_requests = &tcp_listen[0]; + tcp_listen[0].nx_tcp_listen_next = &tcp_listen[1]; + tcp_listen[1].nx_tcp_listen_next = &tcp_listen[0]; + _nx_tcp_server_socket_unaccept(&tcp_socket); + + /* Hit condition: + 130 [ + + ][ + + ]: 2314 : if ((socket_ptr -> nx_tcp_socket_state >= NX_TCP_CLOSE_WAIT) || + 131 [ - + ]: 54 : ((socket_ptr -> nx_tcp_socket_state == NX_TCP_CLOSED) && (socket_ptr -> nx_tcp_socket_bound_next))) + */ + tcp_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + tcp_socket.nx_tcp_socket_bound_next = &tcp_socket; + _nx_tcp_server_socket_unaccept(&tcp_socket); + + /* Hit condition + 201 [ + - ]: 5 : if (ip_ptr -> nx_ip_tcp_port_table[index] == socket_ptr) + */ + tcp_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + tcp_socket.nx_tcp_socket_bound_next = &test_socket; + tcp_socket.nx_tcp_socket_bound_previous = &test_socket; + test_socket.nx_tcp_socket_bound_next = NX_NULL; + test_socket.nx_tcp_socket_bound_previous = NX_NULL; + _nx_tcp_server_socket_unaccept(&tcp_socket); + ip_0.nx_ip_tcp_active_listen_requests = NX_NULL; + +#ifdef __PRODUCT_NETXDUO__ + /* Test _nx_tcp_socket_state_syn_received */ + /* Test line: + 140 [ + - ][ + + ]: 2278 : if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && + 141 : 2278 : (tcp_header_ptr -> nx_tcp_acknowledgment_number == socket_ptr -> nx_tcp_socket_tx_sequence)) + */ + tcp_socket.nx_tcp_socket_connect_interface = &ip_0.nx_ip_interface[0]; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + tcp_socket.nx_tcp_socket_tx_sequence = 10; + tcp_header.nx_tcp_acknowledgment_number = 9; + tcp_header.nx_tcp_header_word_3 = 0; + _nx_tcp_socket_state_syn_received(&tcp_socket, &tcp_header); + + /* Test line: + 235 [ + - ][ + - ]: 1 : else if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && + 236 : 1 : (tcp_header_ptr -> nx_tcp_acknowledgment_number != socket_ptr -> nx_tcp_socket_tx_sequence)) + */ + tcp_socket.nx_tcp_socket_tx_sequence = 10; + tcp_header.nx_tcp_acknowledgment_number = 9; + tcp_header.nx_tcp_header_word_3 = 0; + _nx_tcp_socket_state_syn_received(&tcp_socket, &tcp_header); + + tcp_socket.nx_tcp_socket_tx_sequence = 10; + tcp_header.nx_tcp_acknowledgment_number = 9; + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + _nx_tcp_socket_state_syn_received(&tcp_socket, &tcp_header); + + + /* Test nx_tcp_socket_state_syn_sent.c */ + /* Test line: + 158 [ + + ][ + + ]: 2296 : else if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && + 159 [ + - ]: 2281 : (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && + 160 : 2281 : (tcp_header_ptr -> nx_tcp_acknowledgment_number == socket_ptr -> nx_tcp_socket_tx_sequence)) + + 262 [ + + ][ + - ]: 15 : else if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && + 263 : 3 : (!(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT))) + + */ + tcp_header.nx_tcp_header_word_3 = NX_TCP_SYN_BIT | NX_TCP_ACK_BIT; + tcp_header.nx_tcp_acknowledgment_number = 10; + tcp_socket.nx_tcp_socket_tx_sequence = 9; + _nx_tcp_socket_state_syn_sent(&tcp_socket, &tcp_header, my_packet[0]); + + + /* Test line: + 310 [ + - ][ + + ]: 12 : else if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && + 311 : 12 : (tcp_header_ptr -> nx_tcp_acknowledgment_number != socket_ptr -> nx_tcp_socket_tx_sequence)) + */ + tcp_header.nx_tcp_header_word_3 = 0; + tcp_header.nx_tcp_acknowledgment_number = 10; + tcp_socket.nx_tcp_socket_rx_sequence = 9; + _nx_tcp_socket_state_syn_sent(&tcp_socket, &tcp_header, my_packet[0]); + + + /* Test nx_tcp_socket_state_last_ack.c + 117 [ + - ]: 1188 : if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + */ + tcp_header.nx_tcp_header_word_3 = 0; + _nx_tcp_socket_state_last_ack(&tcp_socket, &tcp_header); + + /* + 121 [ + + ][ + - ]: 1188 : if ((tcp_header_ptr -> nx_tcp_acknowledgment_number == socket_ptr -> nx_tcp_socket_tx_sequence) && + 122 : 1187 : (tcp_header_ptr -> nx_tcp_sequence_number == socket_ptr -> nx_tcp_socket_rx_sequence)) + */ + + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_acknowledgment_number = 10; + tcp_socket.nx_tcp_socket_tx_sequence = 10; + tcp_header.nx_tcp_sequence_number = 9; + tcp_socket.nx_tcp_socket_rx_sequence = 8; + _nx_tcp_socket_state_last_ack(&tcp_socket, &tcp_header); + + /* + 129 [ + - ]: 1187 : if (socket_ptr -> nx_tcp_socket_disconnect_suspended_thread) + */ + + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_acknowledgment_number = 10; + tcp_socket.nx_tcp_socket_tx_sequence = 10; + tcp_header.nx_tcp_sequence_number = 9; + tcp_socket.nx_tcp_socket_rx_sequence = 9; + tcp_socket.nx_tcp_socket_disconnect_suspended_thread = NULL; + _nx_tcp_socket_state_last_ack(&tcp_socket, &tcp_header); + + + + + + /* Test nx_tcp_socket_receive.c: + 168 [ + + ][ + + ]: 116763 : if ((socket_ptr -> nx_tcp_socket_state < NX_TCP_SYN_SENT) || + 169 [ - + ]: 116749 : (socket_ptr -> nx_tcp_socket_state == NX_TCP_CLOSE_WAIT) || + 170 : 116749 : (socket_ptr -> nx_tcp_socket_state >= NX_TCP_CLOSING)) + */ + tcp_socket.nx_tcp_socket_state = NX_TCP_CLOSING; + tcp_socket.nx_tcp_socket_bound_next = &test_socket; + tcp_socket.nx_tcp_socket_receive_queue_head = NX_NULL; + _nx_tcp_socket_receive(&tcp_socket, &packet_ptr, 0); + + /* Test nx_tcp_server_socket_relisten() + 174 [ + + ][ - + ]: 2078 : if ((socket_ptr -> nx_tcp_socket_bound_next) || + 175 : 2076 : (socket_ptr -> nx_tcp_socket_bind_in_progress)) + */ + tcp_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + tcp_socket.nx_tcp_socket_bound_next = 0; + tcp_socket.nx_tcp_socket_bind_in_progress = _tx_thread_current_ptr; + _nx_tcp_server_socket_relisten(&ip_0, 80, &tcp_socket); + + /* Test nx_tcp_server_socket_accept(): + 142 [ + + ][ + - ]: 2302 : if ((socket_ptr -> nx_tcp_socket_state != NX_TCP_LISTEN_STATE) && (socket_ptr -> nx_tcp_socket_state != NX_TCP_SYN_RECEIVED)) + */ + tcp_socket.nx_tcp_socket_state = NX_TCP_SYN_RECEIVED; + _nx_tcp_server_socket_accept(&tcp_socket, 1); + + + /* Test nx_tcp_socket_state_fin_wait1.c: + 132 [ + + ][ + - ]: 12 : else if ((socket_ptr -> nx_tcp_socket_fin_acked) && + 133 [ + - ]: 1 : (socket_ptr -> nx_tcp_socket_fin_received) && + 134 : 1 : (socket_ptr -> nx_tcp_socket_fin_sequence == socket_ptr -> nx_tcp_socket_rx_sequence)) + */ + + + tcp_socket.nx_tcp_socket_fin_acked = NX_TRUE; + tcp_socket.nx_tcp_socket_fin_received = NX_TRUE; + tcp_socket.nx_tcp_socket_fin_sequence = tcp_socket.nx_tcp_socket_rx_sequence + 1; + _nx_tcp_socket_state_fin_wait1(&tcp_socket); + + + /* + 159 [ + - ]: 1 : if (socket_ptr -> nx_tcp_socket_disconnect_suspended_thread) + 168 [ + - ]: 2 : if (socket_ptr -> nx_tcp_disconnect_callback) + */ + + tcp_socket.nx_tcp_socket_fin_acked = NX_TRUE; + tcp_socket.nx_tcp_socket_fin_received = NX_TRUE; + tcp_socket.nx_tcp_socket_fin_sequence = tcp_socket.nx_tcp_socket_rx_sequence; + tcp_socket.nx_tcp_socket_disconnect_suspended_thread = NX_NULL; + tcp_socket.nx_tcp_disconnect_callback = NX_NULL; + tcp_socket.nx_tcp_socket_connect_interface = &ip_0.nx_ip_interface[0]; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + _nx_tcp_socket_state_fin_wait1(&tcp_socket); + + /* + 197 [ + + ][ + - ]: 11 : else if ((socket_ptr -> nx_tcp_socket_fin_received) && + 198 : 1 : (socket_ptr -> nx_tcp_socket_fin_sequence == socket_ptr -> nx_tcp_socket_rx_sequence)) + */ + + tcp_socket.nx_tcp_socket_fin_acked = NX_FALSE; + tcp_socket.nx_tcp_socket_fin_received = NX_TRUE; + tcp_socket.nx_tcp_socket_fin_sequence = tcp_socket.nx_tcp_socket_rx_sequence + 1; + _nx_tcp_socket_state_fin_wait1(&tcp_socket); + + /* Test nx_tcp_socket_state_closing.c + 118 [ + - ]: 1 : if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + */ + tcp_header.nx_tcp_header_word_3 = 0; + _nx_tcp_socket_state_closing(&tcp_socket, &tcp_header); + + /* + 122 [ + - ][ + - ]: 1 : if ((tcp_header_ptr -> nx_tcp_acknowledgment_number == socket_ptr -> nx_tcp_socket_tx_sequence) && + 123 : 1 : (tcp_header_ptr -> nx_tcp_sequence_number == socket_ptr -> nx_tcp_socket_rx_sequence)) + */ + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_acknowledgment_number = tcp_socket.nx_tcp_socket_tx_sequence; + tcp_header.nx_tcp_sequence_number = tcp_socket.nx_tcp_socket_rx_sequence + 1; + _nx_tcp_socket_state_closing(&tcp_socket, &tcp_header); + + tcp_header.nx_tcp_acknowledgment_number = tcp_socket.nx_tcp_socket_tx_sequence + 1; + tcp_header.nx_tcp_sequence_number = tcp_socket.nx_tcp_socket_rx_sequence; + _nx_tcp_socket_state_closing(&tcp_socket, &tcp_header); + + /* + 140 [ + - ]: 1 : if (socket_ptr -> nx_tcp_socket_disconnect_suspended_thread) + 149 [ + - ]: 1 : if (socket_ptr -> nx_tcp_disconnect_callback) + */ + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_acknowledgment_number = tcp_socket.nx_tcp_socket_tx_sequence; + tcp_header.nx_tcp_sequence_number = tcp_socket.nx_tcp_socket_rx_sequence; + tcp_socket.nx_tcp_socket_disconnect_suspended_thread = NX_NULL; + tcp_socket.nx_tcp_disconnect_callback = NX_NULL; + _nx_tcp_socket_state_closing(&tcp_socket, &tcp_header); + + /* Test nx_tcp_socket_delete.c: + 136 [ + + ][ + - ]: 2482 : if ((socket_ptr -> nx_tcp_socket_bound_next) || + 137 [ - + ]: 2477 : (socket_ptr -> nx_tcp_socket_bind_in_progress) || + 138 : 2477 : (socket_ptr -> nx_tcp_socket_state != NX_TCP_CLOSED)) + */ + tcp_socket.nx_tcp_socket_id = NX_TCP_ID; + tcp_socket.nx_tcp_socket_bound_next = 0; + tcp_socket.nx_tcp_socket_bind_in_progress = NX_FALSE; + tcp_socket.nx_tcp_socket_state = NX_TCP_LISTEN_STATE; + _nx_tcp_socket_delete(&tcp_socket); + + tcp_socket.nx_tcp_socket_id = NX_TCP_ID; + tcp_socket.nx_tcp_socket_bound_next = 0; + tcp_socket.nx_tcp_socket_bind_in_progress = tx_thread_identify(); + tcp_socket.nx_tcp_socket_state = NX_TCP_LISTEN_STATE; + _nx_tcp_socket_delete(&tcp_socket); + tcp_socket.nx_tcp_socket_bind_in_progress = TX_NULL; + + /* Test nx_tcp_fast_periodic_processing.c + 216 [ + + ][ + + ]: 2559 : else if (socket_ptr -> nx_tcp_socket_transmit_sent_head || + 217 [ + - ]: 137 : ((socket_ptr -> nx_tcp_socket_tx_window_advertised == 0) && + 218 : 137 : (socket_ptr -> nx_tcp_socket_state <= NX_TCP_CLOSE_WAIT))) + */ + tcp_socket.nx_tcp_socket_id = NX_TCP_ID; + tcp_socket.nx_tcp_socket_timeout = _nx_tcp_fast_timer_rate; + tcp_socket.nx_tcp_socket_state = NX_TCP_FIN_WAIT_2; + _nx_tcp_fast_periodic_processing(&ip_0); + + /* Test nx_tcp_fast_periodic_processing.c + 231 [ + + ][ + + ]: 2374 : else if ((socket_ptr -> nx_tcp_socket_state == NX_TCP_FIN_WAIT_1) || + 232 [ - + ]: 2371 : (socket_ptr -> nx_tcp_socket_state == NX_TCP_CLOSING) || + 233 : 2371 : (socket_ptr -> nx_tcp_socket_state == NX_TCP_LAST_ACK)) + */ + ip_0.nx_ip_tcp_active_listen_requests = NX_NULL; + tcp_socket.nx_tcp_socket_timeout = _nx_tcp_fast_timer_rate; + tcp_socket.nx_tcp_socket_state = NX_TCP_LAST_ACK; + _nx_tcp_fast_periodic_processing(&ip_0); + + /* Test nx_tcp_fast_periodic_processing.c + 187 [ + + ][ + + ]: 2857 : else if (((socket_ptr -> nx_tcp_socket_timeout_retries >= socket_ptr -> nx_tcp_socket_timeout_max_retries) && + 188 [ + + ]: 2856 : (socket_ptr -> nx_tcp_socket_zero_window_probe_has_data == NX_FALSE)) || + 189 [ + - ]: 4 : ((socket_ptr -> nx_tcp_socket_zero_window_probe_failure >= socket_ptr -> nx_tcp_socket_timeout_max_retries) && + 190 : 4 : (socket_ptr -> nx_tcp_socket_zero_window_probe_has_data == NX_TRUE)) + */ + tcp_socket.nx_tcp_socket_timeout = _nx_tcp_fast_timer_rate; + tcp_socket.nx_tcp_socket_zero_window_probe_failure = tcp_socket.nx_tcp_socket_timeout_max_retries; + _nx_tcp_fast_periodic_processing(&ip_0); + tcp_socket.nx_tcp_socket_zero_window_probe_failure = 0; + + + /* Test nx_tcp_no_connection_reset.c + 227 [ + - ]: 9 : if (tcp_header_ptr -> nx_tcp_header_word_3 & (NX_TCP_SYN_BIT | NX_TCP_FIN_BIT)) + */ + tcp_header.nx_tcp_header_word_3 = 0; + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_ip_version = NX_IP_VERSION_V4; + my_packet[0] -> nx_packet_ip_header = my_packet[0] -> nx_packet_prepend_ptr; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + _nx_tcp_no_connection_reset(&ip_0, my_packet[0], &tcp_header); + + + /* Test nx_tcp_packet_process.c + 402 [ + - ]: 2261852 : if (socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_version == packet_ptr -> nx_packet_ip_version) + */ + tcp_socket.nx_tcp_socket_id = NX_TCP_ID; + tcp_socket.nx_tcp_socket_port = 80; + tcp_socket.nx_tcp_socket_connect_port = 6206; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V6; + ip_0.nx_ip_tcp_port_table[80 & NX_TCP_PORT_TABLE_MASK] = &tcp_socket; + tcp_socket.nx_tcp_socket_bound_next = &tcp_socket; + nx_ip_address_set(&ip_0, IP_ADDRESS(192,168,100,4), 0xFFFFFF00); + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Test nx_tcp_packet_process.c + 409 [ + - ]: 2261688 : if (socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v4 == *source_ip) + */ + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(192,168,100,20); + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + +#ifdef FEATURE_NX_IPV6 + /* Test nx_tcp_packet_process.c + 415 [ + - ]: 164 : else if (CHECK_IPV6_ADDRESSES_SAME(socket_ptr -> nx_tcp_socket_connect_ip.nxd_ip_address.v6, source_ip)) + */ + nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V6; + tcp_socket.nx_tcp_socket_ipv6_addr = &ip_0.nx_ipv6_address[0]; + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt2) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Test nx_tcp_packet_process.c + 442 [ + - ][ + - ]: 1 : if ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) || + 443 : 1 : (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT)) + */ + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v6[0] = 0xFE800000; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v6[1] = 0; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v6[2] = 0; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v6[3] = 1; + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt3[14], sizeof(pkt3) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt3) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + tcp_socket.nx_tcp_socket_port = 80; + tcp_socket.nx_tcp_socket_connect_port = 6206; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V6; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v6[0] = 0xFE800000; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v6[1] = 0; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v6[2] = 0; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v6[3] = 1; + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt4[14], sizeof(pkt4) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt4) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); +#endif /* FEATURE_NX_IPV6 */ + + ip_0.nx_ip_tcp_port_table[80 & NX_TCP_PORT_TABLE_MASK] = NX_NULL; + + + /* Test nx_tcp_packet_process.c + 562 [ + + ][ + + ]: 2342 : if (((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) && (*source_ip == *dest_ip) && (source_port == port)) + [ + - ] + 563 : : #ifdef FEATURE_NX_IPV6 + 564 [ + + ][ + + ]: 2342 : || ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) && (CHECK_IPV6_ADDRESSES_SAME(source_ip, dest_ip)) && (source_port == port)) + [ + - ] + 565 : : #endif + 566 : : ) + */ + ip_0.nx_ip_tcp_active_listen_requests = ip_0.nx_ip_tcp_available_listen_requests; + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt5[14], sizeof(pkt5) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt5) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt6[14], sizeof(pkt6) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt6) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Test nx_tcp_packet_process.c + 589 [ + - ]: 2300 : ((*source_ip & NX_IP_CLASS_D_MASK) == NX_IP_CLASS_D_TYPE) || + 591 [ + + ]: 2295 : (((*source_ip & interface_ptr -> nx_interface_ip_network_mask) == interface_ptr -> nx_interface_ip_network) && + 592 [ + + ]: 2299 : ((*source_ip & ~(interface_ptr -> nx_interface_ip_network_mask)) == ~(interface_ptr -> nx_interface_ip_network_mask))) || + 594 [ - + ]: 2298 : (*source_ip == interface_ptr -> nx_interface_ip_network) || + 596 : 2298 : (*source_ip == NX_IP_LIMITED_BROADCAST) + */ + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt7[14], sizeof(pkt7) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt7) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt9[14], sizeof(pkt9) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt9) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Test nx_tcp_packet_process.c + 900 [ + - ][ + - ]: 6 : if ((*queued_source_ip == *source_ip) && (queued_source_port == source_port)) + */ + ip_0.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_port = 80; + ip_0.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_queue_current = 0; + ip_0.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_socket_ptr = NX_NULL; + ip_0.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_queue_maximum = 5; + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt10[14], sizeof(pkt10) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt10) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt11[14], sizeof(pkt11) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt11) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Test nx_tcp_packet_process.c + 677 [ + + ][ + - ]: 2335 : if ((listen_ptr -> nx_tcp_listen_socket_ptr) && + 678 : 2284 : ((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) == NX_NULL)) + */ + ip_0.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_port = 80; + ip_0.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_socket_ptr = &tcp_socket; + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt8[14], sizeof(pkt8) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt8) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Test nx_tcp_packet_process.c + 983 [ + - ]: 7 : if (queued_ptr == listen_ptr -> nx_tcp_listen_queue_tail) + */ + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt14[14], sizeof(pkt14) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt14) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Test nx_tcp_packet_process.c + 934 [ + + ][ + - ]: 52 : if ((CHECK_IPV6_ADDRESSES_SAME(queued_source_ip, source_ip)) && (queued_source_port == source_port)) + */ + ip_0.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_socket_ptr = NX_NULL; + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt12[14], sizeof(pkt12) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt12) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt13[14], sizeof(pkt13) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt13) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + + /* Test nx_tcp_no_connection_reset: + 227 [ + - ]: 9 : if (tcp_header_ptr -> nx_tcp_header_word_3 & (NX_TCP_SYN_BIT | NX_TCP_FIN_BIT)) + */ + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt8[14], sizeof(pkt8) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt8) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + tcp_header.nx_tcp_header_word_3 = 0; + _nx_tcp_no_connection_reset(&ip_0, packet_ptr, &tcp_header); + /* Do not release this packet. We will reuse it in the next test case. */ + + /* Test nx_tcp_server_socket_relisten.c: + 187 : 2076 : listen_ptr = ip_ptr -> nx_ip_tcp_active_listen_requests; + 188 [ + - ]: 2076 : if (listen_ptr) + */ + tcp_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + tcp_socket.nx_tcp_socket_bind_in_progress = 0; + ip_0.nx_ip_tcp_active_listen_requests = NX_NULL; + _nx_tcp_server_socket_relisten(&ip_0, 80, &tcp_socket); + + /* + 246 [ + - ]: 9 : if (packet_ptr == listen_ptr -> nx_tcp_listen_queue_tail) + */ + + ip_0.nx_ip_tcp_active_listen_requests = &tcp_listen[0]; + tcp_listen[0].nx_tcp_listen_next = NX_NULL; + tcp_listen[0].nx_tcp_listen_port = 80; + tcp_listen[0].nx_tcp_listen_socket_ptr = NX_NULL; + tcp_listen[0].nx_tcp_listen_queue_current = 1; + tcp_listen[0].nx_tcp_listen_queue_head = packet_ptr; + tcp_listen[0].nx_tcp_listen_queue_tail = NX_NULL; + tcp_listen[0].nx_tcp_listen_callback = NX_NULL; + packet_ptr -> nx_packet_queue_next = NX_NULL; + tcp_header_ptr = (NX_TCP_HEADER*)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_3 = 0; + _nx_tcp_server_socket_relisten(&ip_0, 80, &tcp_socket); + + /* 262 [ + - ]: 9 : if (option_words > 0) */ + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt8[14], sizeof(pkt8) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt8) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr; + packet_ptr -> nx_packet_address.nx_packet_interface_ptr = NX_NULL; + tcp_header.nx_tcp_header_word_3 = 0; + + ip_0.nx_ip_tcp_active_listen_requests = &tcp_listen[0]; + tcp_listen[0].nx_tcp_listen_next = NX_NULL; + tcp_listen[0].nx_tcp_listen_port = 80; + tcp_listen[0].nx_tcp_listen_socket_ptr = NX_NULL; + tcp_listen[0].nx_tcp_listen_queue_current = 1; + tcp_listen[0].nx_tcp_listen_queue_head = packet_ptr; + tcp_listen[0].nx_tcp_listen_queue_tail = NX_NULL; + tcp_listen[0].nx_tcp_listen_callback = NX_NULL; + packet_ptr -> nx_packet_queue_next = NX_NULL; + tcp_header_ptr = (NX_TCP_HEADER*)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_3 = NX_TCP_SYN_BIT | (5 << 28); + _nx_tcp_server_socket_relisten(&ip_0, 80, &tcp_socket); + + ip_0.nx_ip_tcp_active_listen_requests = NX_NULL; + + + /* Test _nx_tcp_socket_state_transmit_check() */ + /* Hit condition: + 169 [ + + ][ + - ]: 332 : if ((tx_window_current) && + 170 : 262 : (socket_ptr -> nx_tcp_socket_transmit_sent_count < socket_ptr -> nx_tcp_socket_transmit_queue_maximum)) */ + /* suspension list is set to NULL. */ + tcp_socket.nx_tcp_socket_transmit_suspension_list = &thread_test1; + tcp_socket.nx_tcp_socket_tx_window_advertised = 100; + tcp_socket.nx_tcp_socket_tx_window_congestion = 100; + tcp_socket.nx_tcp_socket_transmit_sent_count = 10; + tcp_socket.nx_tcp_socket_transmit_queue_maximum = 5; + _nx_tcp_socket_state_transmit_check(&tcp_socket); + tcp_socket.nx_tcp_socket_transmit_suspension_list = TX_NULL; + tcp_socket.nx_tcp_socket_tx_window_advertised = 0; + tcp_socket.nx_tcp_socket_tx_window_congestion = 0; + tcp_socket.nx_tcp_socket_transmit_sent_count = 0; + tcp_socket.nx_tcp_socket_transmit_queue_maximum = 0x14; + + /* Test _nx_tcp_socket_state_transmit_check() */ + /* Hit condition of if (socket_ptr -> nx_tcp_socket_duplicated_ack_received == 2) */ + tcp_socket.nx_tcp_socket_transmit_suspension_list = &thread_test1; + tcp_socket.nx_tcp_socket_tx_window_congestion = 100; + tcp_socket.nx_tcp_socket_tx_window_advertised = tcp_socket.nx_tcp_socket_tx_window_congestion + 10; + tcp_socket.nx_tcp_socket_duplicated_ack_received = 2; + tcp_socket.nx_tcp_socket_transmit_sent_count = 10; + tcp_socket.nx_tcp_socket_transmit_queue_maximum = 5; + _nx_tcp_socket_state_transmit_check(&tcp_socket); + tcp_socket.nx_tcp_socket_duplicated_ack_received = 0; + _nx_tcp_socket_state_transmit_check(&tcp_socket); + tcp_socket.nx_tcp_socket_transmit_suspension_list = TX_NULL; + tcp_socket.nx_tcp_socket_tx_window_advertised = 0; + tcp_socket.nx_tcp_socket_tx_window_congestion = 0; + tcp_socket.nx_tcp_socket_transmit_sent_count = 0; + tcp_socket.nx_tcp_socket_transmit_queue_maximum = 0x14; + + + /* Test nx_tcp_server_socket_accept(): + 222 [ + + ][ + - ]: 2302 : if ((wait_option) && (_tx_thread_current_ptr != &(ip_ptr -> nx_ip_thread))) + */ + ip_0.nx_ip_tcp_queue_process = my_tcp_queue_process; + + /* Wakeup IP thread for processing one or more messages in the TCP queue. */ + tx_event_flags_set(&(ip_0.nx_ip_events), NX_IP_TCP_EVENT, TX_OR); + + /* Let IP thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + ip_0.nx_ip_tcp_queue_process = _nx_tcp_queue_process; + + + + /* Test _nx_tcp_server_socket_relisten(): + 262 [ + - ]: 9 : if (option_words > 0) + */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + /* Skip ipv4 header. */ + my_packet[0] -> nx_packet_ip_header = my_packet[0] -> nx_packet_prepend_ptr; + ipv4_header_ptr = (NX_IPV4_HEADER *)my_packet[0] -> nx_packet_ip_header; + ipv4_header_ptr -> nx_ip_header_source_ip = 0x01020305; + ipv4_header_ptr -> nx_ip_header_destination_ip = 0x01020304; + my_packet[0] -> nx_packet_prepend_ptr += 20; + my_packet[0] -> nx_packet_ip_version = NX_IP_VERSION_V4; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 20; + my_packet[0] -> nx_packet_length = 20; + tcp_header_ptr = (NX_TCP_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_0 = (0x1235 << NX_SHIFT_BY_16) | 0x1234; + tcp_header_ptr -> nx_tcp_acknowledgment_number = 1; + tcp_header_ptr -> nx_tcp_header_word_3 = NX_TCP_HEADER_SIZE | NX_TCP_SYN_BIT | tcp_socket.nx_tcp_socket_rx_window_current; + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + tcp_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + tcp_listen[0].nx_tcp_listen_port = 0x1234; + tcp_listen[0].nx_tcp_listen_socket_ptr = NX_NULL; + tcp_listen[0].nx_tcp_listen_queue_current = 1; + tcp_listen[0].nx_tcp_listen_queue_head = my_packet[0]; + tcp_listen[0].nx_tcp_listen_queue_tail = my_packet[0]; + ip_0.nx_ip_tcp_active_listen_requests = &tcp_listen[0]; + _nx_tcp_server_socket_relisten(&ip_0, 0x1234, &tcp_socket); + ip_0.nx_ip_tcp_active_listen_requests = NX_NULL; + ip_0.nx_ip_tcp_port_table[6] = NX_NULL; + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + tcp_socket.nx_tcp_socket_bound_previous = NX_NULL; + ip_0.nx_ip_tcp_active_listen_requests = NX_NULL; + + + /* Test _nx_tcp_socket_retransmit() */ + /* Hit condition: + 212 [ + - ][ + - ]: 159 : while (packet_ptr && (packet_ptr -> nx_packet_queue_next == (NX_PACKET *)NX_DRIVER_TX_DONE)) + */ + tcp_socket.nx_tcp_socket_tx_window_advertised = 65535; + tcp_socket.nx_tcp_socket_transmit_sent_head = NX_NULL; + _nx_tcp_socket_retransmit(&ip_0, &tcp_socket, NX_FALSE); + + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + tcp_socket.nx_tcp_socket_tx_window_advertised = 65535; + tcp_socket.nx_tcp_socket_transmit_sent_head = my_packet[0]; + my_packet[0] -> nx_packet_queue_next = NX_NULL; + _nx_tcp_socket_retransmit(&ip_0, &tcp_socket, NX_FALSE); + nx_packet_release(my_packet[0]); + + /* Hit condition: + 315 [ + + ][ + - ]: 158 : if ((header_ptr -> nx_tcp_acknowledgment_number == original_acknowledgment_number) && + 316 [ + + ]: 152 : (header_ptr -> nx_tcp_header_word_3 == original_header_word_3) && + 317 : 152 : (header_ptr -> nx_tcp_header_word_4 == original_header_word_4)) + */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 20; + my_packet[0] -> nx_packet_length = 20; + tcp_header_ptr = (NX_TCP_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_0 = (0x1235 << NX_SHIFT_BY_16) | 0x1234; + tcp_header_ptr -> nx_tcp_acknowledgment_number = tcp_socket.nx_tcp_socket_rx_sequence; + tcp_header_ptr -> nx_tcp_header_word_3 = NX_TCP_HEADER_SIZE | NX_TCP_SYN_BIT | tcp_socket.nx_tcp_socket_rx_window_current; + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_socket.nx_tcp_socket_tx_window_advertised = 65535; + tcp_socket.nx_tcp_socket_transmit_sent_head = my_packet[0]; + my_packet[0] -> nx_packet_queue_next = (NX_PACKET *)NX_DRIVER_TX_DONE; + my_packet[0] -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + _nx_tcp_socket_retransmit(&ip_0, &tcp_socket, NX_FALSE); + my_packet[0] -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *) NX_PACKET_ALLOCATED; + nx_packet_release(my_packet[0]); + + /* Hit condition: + 355 [ + + ][ + + ]: 488 : if ((header_ptr -> nx_tcp_acknowledgment_number == original_acknowledgment_number) && + 356 [ + - ]: 462 : (header_ptr -> nx_tcp_header_word_3 == original_header_word_3) && + 357 : 462 : (header_ptr -> nx_tcp_header_word_4 == original_header_word_4)) + */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 20; + my_packet[0] -> nx_packet_length = 20; + tcp_header_ptr = (NX_TCP_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_0 = (0x1235 << NX_SHIFT_BY_16) | 0x1234; + tcp_header_ptr -> nx_tcp_acknowledgment_number = tcp_socket.nx_tcp_socket_rx_sequence; + tcp_header_ptr -> nx_tcp_header_word_3 = NX_TCP_HEADER_SIZE | NX_TCP_ACK_BIT | NX_TCP_PSH_BIT | tcp_socket.nx_tcp_socket_rx_window_current; + tcp_header_ptr -> nx_tcp_header_word_4 = 0xFFFF0000; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_socket.nx_tcp_socket_tx_window_advertised = 65535; + tcp_socket.nx_tcp_socket_transmit_sent_head = my_packet[0]; + my_packet[0] -> nx_packet_queue_next = (NX_PACKET *)NX_DRIVER_TX_DONE; + my_packet[0] -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + _nx_tcp_socket_retransmit(&ip_0, &tcp_socket, NX_FALSE); + my_packet[0] -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *) NX_PACKET_ALLOCATED; + nx_packet_release(my_packet[0]); + + + + /* Test _nx_tcp_socket_receive() */ + /* Hit condition: + 262 [ + + ][ + + ]: 19398 : if (((socket_ptr -> nx_tcp_socket_rx_window_current - socket_ptr -> nx_tcp_socket_rx_window_last_sent) >= (socket_ptr -> nx_tcp_socket_rx_window_default / 2)) && + 263 [ + - ][ - + ]: 3 : ((socket_ptr -> nx_tcp_socket_state == NX_TCP_ESTABLISHED) || (socket_ptr -> nx_tcp_socket_state == NX_TCP_FIN_WAIT_1) || (socket_ptr -> nx_tcp_socket_state == NX_TCP_FIN_WAIT_2))) + */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_queue_next = ((NX_PACKET *)NX_PACKET_READY); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 20; + my_packet[0] -> nx_packet_length = 20; + tcp_header_ptr = (NX_TCP_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_0 = (0x1235 << NX_SHIFT_BY_16) | 0x1234; + tcp_header_ptr -> nx_tcp_acknowledgment_number = tcp_socket.nx_tcp_socket_rx_sequence; + tcp_header_ptr -> nx_tcp_header_word_3 = NX_TCP_HEADER_SIZE | NX_TCP_SYN_BIT | tcp_socket.nx_tcp_socket_rx_window_current; + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + tcp_socket.nx_tcp_socket_state = NX_TCP_FIN_WAIT_1; + tcp_socket.nx_tcp_socket_receive_queue_head = my_packet[0]; + tcp_socket.nx_tcp_socket_bound_next = &test_socket; + tcp_socket.nx_tcp_socket_receive_queue_count ++; + tcp_socket.nx_tcp_socket_rx_window_last_sent = 0; + _nx_tcp_socket_receive(&tcp_socket, &packet_ptr, NX_NO_WAIT); + nx_packet_release(packet_ptr); + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_queue_next = ((NX_PACKET *)NX_PACKET_READY); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 20; + my_packet[0] -> nx_packet_length = 20; + tcp_header_ptr = (NX_TCP_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_0 = (0x1235 << NX_SHIFT_BY_16) | 0x1234; + tcp_header_ptr -> nx_tcp_acknowledgment_number = tcp_socket.nx_tcp_socket_rx_sequence; + tcp_header_ptr -> nx_tcp_header_word_3 = NX_TCP_HEADER_SIZE | NX_TCP_SYN_BIT | tcp_socket.nx_tcp_socket_rx_window_current; + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + tcp_socket.nx_tcp_socket_state = NX_TCP_FIN_WAIT_2; + tcp_socket.nx_tcp_socket_receive_queue_head = my_packet[0]; + tcp_socket.nx_tcp_socket_bound_next = &test_socket; + tcp_socket.nx_tcp_socket_receive_queue_count ++; + tcp_socket.nx_tcp_socket_rx_window_last_sent = 0; + _nx_tcp_socket_receive(&tcp_socket, &packet_ptr, NX_NO_WAIT); + nx_packet_release(packet_ptr); + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + + + + /* Test _nx_tcp_socket_send_internal() */ + +#ifndef NX_DISABLE_PACKET_CHAIN + /* Hit condition: + 377 [ + + ][ + + ]: 125717 : else if ((packet_ptr -> nx_packet_next != NX_NULL) && + 378 [ + - ]: 6631 : ((packet_ptr -> nx_packet_length + data_offset) < pool_ptr -> nx_packet_pool_payload_size) && + 379 : 6631 : (pool_ptr -> nx_packet_pool_available > 0)) + */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_TCP_PACKET, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 20; + my_packet[0] -> nx_packet_length = 40; + nx_packet_allocate(&pool_0, &my_packet[1], NX_TCP_PACKET, NX_NO_WAIT); + my_packet[1] -> nx_packet_append_ptr = my_packet[1] -> nx_packet_prepend_ptr + 20; + my_packet[1] -> nx_packet_length = 20; + my_packet[0] -> nx_packet_next = my_packet[1]; + tcp_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + tcp_socket.nx_tcp_socket_connect_interface = &ip_0.nx_ip_interface[0]; + tcp_socket.nx_tcp_socket_bound_next = &tcp_socket; + packet_counter = pool_0.nx_packet_pool_available; + pool_0.nx_packet_pool_available = 0; + tcp_socket.nx_tcp_socket_transmit_sent_head = NX_NULL; + _nx_tcp_socket_send_internal(&tcp_socket, my_packet[0], 1); + pool_0.nx_packet_pool_available = packet_counter; + + + /* Hit condition: + 391 [ + - ][ + + ]: 5 : while ((current_packet != NX_NULL) && (current_packet -> nx_packet_prepend_ptr == current_packet -> nx_packet_append_ptr)) + + 399 [ - + ]: 2 : NX_ASSERT(current_packet != NX_NULL); + */ + +#ifndef NX_DISABLE_ASSERT + /* Create the assert thread. */ + tx_thread_create(&thread_for_assert_1, "Assert Test thread", thread_for_assert_entry_1, 0, + stack_for_assert_1, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Let test thread run. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Terminate the test thread. */ + tx_thread_terminate(&thread_for_assert_1); + tx_thread_delete(&thread_for_assert_1); +#endif /* NX_DISABLE_ASSERT */ + + + /* Hit condition: + 454 [ + - ]: 1 : if (preempted == NX_TRUE) + */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_TCP_PACKET, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 20; + my_packet[0] -> nx_packet_length = 40; + tcp_socket.nx_tcp_socket_tx_window_advertised = tcp_socket.nx_tcp_socket_tx_outstanding_bytes + 30; + tcp_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + tcp_socket.nx_tcp_socket_connect_interface = &ip_0.nx_ip_interface[0]; + tcp_socket.nx_tcp_socket_bound_next = &tcp_socket; + packet_counter = pool_0.nx_packet_pool_available; + tcp_socket.nx_tcp_socket_transmit_sent_head = NX_NULL; + packet_counter = pool_0.nx_packet_pool_available; + pool_0.nx_packet_pool_available = 0; + _nx_tcp_socket_send_internal(&tcp_socket, my_packet[0], 1); + pool_0.nx_packet_pool_available = packet_counter; + tcp_socket.nx_tcp_socket_tx_window_advertised = 65535; + + /* Hit condition: + 490 [ + - ]: 2 : if (preempted == NX_TRUE) + */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_TCP_PACKET, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr; + my_packet[0] -> nx_packet_length = 40; + tcp_socket.nx_tcp_socket_tx_window_advertised = tcp_socket.nx_tcp_socket_tx_outstanding_bytes + 30; + tcp_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + tcp_socket.nx_tcp_socket_connect_interface = &ip_0.nx_ip_interface[0]; + tcp_socket.nx_tcp_socket_bound_next = &tcp_socket; + packet_counter = pool_0.nx_packet_pool_available; + tcp_socket.nx_tcp_socket_transmit_sent_head = NX_NULL; + _nx_tcp_socket_send_internal(&tcp_socket, my_packet[0], 0); + tcp_socket.nx_tcp_socket_tx_window_advertised = 65535; + + /* Hit condition: + 550 [ + - ]: 1 : if (preempted == NX_TRUE) + */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_TCP_PACKET, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr; + my_packet[0] -> nx_packet_length = 400; + nx_packet_allocate(&pool_0, &my_packet[1], NX_TCP_PACKET, NX_NO_WAIT); + my_packet[1] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_data_end; + my_packet[1] -> nx_packet_length = 200; + my_packet[0] -> nx_packet_next = my_packet[1]; + nx_packet_allocate(&pool_0, &my_packet[2], NX_TCP_PACKET, NX_NO_WAIT); + my_packet[2] -> nx_packet_append_ptr = my_packet[2] -> nx_packet_data_end; + my_packet[2] -> nx_packet_length = 200; + my_packet[1] -> nx_packet_next = my_packet[2]; + tcp_socket.nx_tcp_socket_tx_window_advertised = tcp_socket.nx_tcp_socket_tx_outstanding_bytes + 300; + tcp_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + tcp_socket.nx_tcp_socket_connect_interface = &ip_0.nx_ip_interface[0]; + tcp_socket.nx_tcp_socket_bound_next = &tcp_socket; + packet_counter = pool_0.nx_packet_pool_available; + pool_0.nx_packet_pool_available = 1; + tcp_socket.nx_tcp_socket_transmit_sent_head = NX_NULL; + tcp_socket.nx_tcp_socket_connect_mss = 536; + tcp_socket.nx_tcp_socket_tx_window_congestion = 536; + _nx_tcp_socket_send_internal(&tcp_socket, my_packet[0], 0); + pool_0.nx_packet_pool_available = packet_counter; + tcp_socket.nx_tcp_socket_tx_window_advertised = 65535; + tcp_socket.nx_tcp_socket_connect_mss = 216; +#endif /* NX_DISABLE_PACKET_CHAIN */ + + /* Hit condition: + 344 [ - + ]: 10 : if (tx_window_current > socket_ptr -> nx_tcp_socket_tx_window_advertised) + */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_TCP_PACKET, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 20; + my_packet[0] -> nx_packet_length = 20; + tcp_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + tcp_socket.nx_tcp_socket_connect_interface = &ip_0.nx_ip_interface[0]; + tcp_socket.nx_tcp_socket_bound_next = &tcp_socket; + tcp_socket.nx_tcp_socket_tx_window_congestion = 100; + tcp_socket.nx_tcp_socket_tx_window_advertised = 200; + tcp_socket.nx_tcp_socket_duplicated_ack_received = 2; + tcp_socket.nx_tcp_socket_connect_mss = 0x218; + tcp_socket.nx_tcp_socket_transmit_sent_head = NX_NULL; + _nx_tcp_socket_send_internal(&tcp_socket, my_packet[0], 1); + tcp_socket.nx_tcp_socket_tx_window_congestion = 0x218; + tcp_socket.nx_tcp_socket_tx_window_advertised = 0xffff; + tcp_socket.nx_tcp_socket_duplicated_ack_received = 0; + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + + /* Test nx_tcp_socket_state_ack_check.c */ + ack_check_test(); + + /* Test nx_tcp_socket_state_data_check.c */ + data_check_test(); + + /* Test nx_tcp_socket_packet_process.c */ + socket_packet_process_test(); +#endif + + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static VOID suspend_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER) +{ +} + +#ifdef __PRODUCT_NETXDUO__ +static VOID tcp_fast_periodic_processing(NX_IP *ip_ptr) +{ +NXD_ADDRESS server_ip; +UINT status; + + /* Check the flag. */ + if (disconnect_flag == NX_FALSE) + { + + /* Update the flag. */ + disconnect_flag = NX_TRUE; + + /* Set the condition. */ + tcp_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + tcp_socket.nx_tcp_socket_next_hop_address = IP_ADDRESS(1, 2, 3, 5); + _nx_tcp_socket_disconnect(&tcp_socket, 1); + + /* Recover. */ + ip_0.nx_ip_tcp_fast_periodic_processing = _nx_tcp_fast_periodic_processing; + + /* Connect to addrss not reachable. */ + server_ip.nxd_ip_version = NX_IP_VERSION_V4; + server_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 6); + status = nxd_tcp_client_socket_connect(&tcp_socket_2, &server_ip, 80, 1); + if (status != NX_IN_PROGRESS) + { + error_counter++; + } + } +} + +static VOID my_tcp_queue_process(NX_IP *ip_ptr) +{ +NX_PACKET *packet_ptr; + + /* Test nx_tcp_server_socket_accept(): + 222 [ + + ][ + - ]: 2302 : if ((wait_option) && (_tx_thread_current_ptr != &(ip_ptr -> nx_ip_thread))) + */ + tcp_socket.nx_tcp_socket_state = NX_TCP_SYN_RECEIVED; + _nx_tcp_server_socket_accept(&tcp_socket, 1); + + + /* Test _nx_tcp_socket_receive() */ + /* + 283 [ + + ][ + - ]: 118586 : else if ((wait_option) && (_tx_thread_current_ptr != &(ip_ptr -> nx_ip_thread))) + */ + tcp_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + tcp_socket.nx_tcp_socket_receive_queue_head = NX_NULL; + tcp_socket.nx_tcp_socket_bound_next = &test_socket; + _nx_tcp_socket_receive(&tcp_socket, &packet_ptr, 1); + tcp_socket.nx_tcp_socket_bound_next = NX_NULL; + + + /* Test _nx_tcp_socket_send_internal() */ + /* Hit condition: + 867 [ + + ][ + - ]: 281 : else if ((wait_option) && (_tx_thread_current_ptr != &(ip_ptr -> nx_ip_thread))) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + 20; + packet_ptr -> nx_packet_length = 20; + tcp_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + tcp_socket.nx_tcp_socket_connect_interface = &ip_0.nx_ip_interface[0]; + tcp_socket.nx_tcp_socket_bound_next = &tcp_socket; + tcp_socket.nx_tcp_socket_transmit_sent_head = NX_NULL; + _nx_tcp_socket_send_internal(&tcp_socket, packet_ptr, 1); + tcp_socket.nx_tcp_socket_connect_mss = 216; + nx_packet_release(packet_ptr); +} + + +static VOID ack_check_test() +{ +NX_TCP_HEADER tcp_header; +NX_TCP_HEADER *tcp_header_ptr; +NX_PACKET *packet_ptr; + + /* Test nx_tcp_socket_state_ack_check.c + 283 [ + - ][ + - ]: 14 : else if ((socket_ptr -> nx_tcp_socket_tx_window_congestion > socket_ptr -> nx_tcp_socket_connect_mss) && + 284 : 28 : ((INT)(tcp_header_ptr -> nx_tcp_acknowledgment_number - (socket_ptr -> nx_tcp_socket_previous_highest_ack + + 285 : 14 : (socket_ptr -> nx_tcp_socket_connect_mss << 2))) < 0)) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_queue_next = (NX_PACKET *)NX_DRIVER_TX_DONE; + packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr - 20; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_sequence_number = 0; + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_acknowledgment_number = 0; + tcp_socket.nx_tcp_socket_tx_sequence = 1; + tcp_socket.nx_tcp_socket_duplicated_ack_received = 2; + tcp_socket.nx_tcp_socket_tx_sequence_recover = 0; + tcp_socket.nx_tcp_socket_tx_window_congestion = 1000; + tcp_socket.nx_tcp_socket_connect_mss = 1460; + tcp_socket.nx_tcp_socket_transmit_sent_head = packet_ptr; + tcp_socket.nx_tcp_socket_transmit_sent_count = 1; + tcp_socket.nx_tcp_socket_tx_sequence = 20; + tcp_socket.nx_tcp_socket_tx_outstanding_bytes = 20; + _nx_tcp_socket_state_ack_check(&tcp_socket, &tcp_header); + + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_queue_next = (NX_PACKET *)NX_DRIVER_TX_DONE; + packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr - 20; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_sequence_number = 0; + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_acknowledgment_number = 0; + tcp_socket.nx_tcp_socket_tx_sequence = 1; + tcp_socket.nx_tcp_socket_duplicated_ack_received = 2; + tcp_socket.nx_tcp_socket_tx_sequence_recover = 0; + tcp_socket.nx_tcp_socket_tx_window_congestion = 1500; + tcp_socket.nx_tcp_socket_connect_mss = 1460; + tcp_socket.nx_tcp_socket_transmit_sent_head = packet_ptr; + tcp_socket.nx_tcp_socket_previous_highest_ack = 0xFFFF0000; + tcp_socket.nx_tcp_socket_connect_mss = 1460; + tcp_socket.nx_tcp_socket_transmit_sent_count = 1; + tcp_socket.nx_tcp_socket_tx_sequence = 20; + tcp_socket.nx_tcp_socket_tx_outstanding_bytes = 20; + _nx_tcp_socket_state_ack_check(&tcp_socket, &tcp_header); + + /* Test nx_tcp_socket_state_ack_check.c + 295 [ + + ][ + - ]: 38 : else if ((socket_ptr -> nx_tcp_socket_duplicated_ack_received > 3) && + 296 : 1 : (socket_ptr -> nx_tcp_socket_fast_recovery == NX_TRUE)) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_queue_next = (NX_PACKET *)NX_DRIVER_TX_DONE; + packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr - 20; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_sequence_number = 0; + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_acknowledgment_number = 0; + tcp_socket.nx_tcp_socket_tx_sequence = 1; + tcp_socket.nx_tcp_socket_duplicated_ack_received = 4; + tcp_socket.nx_tcp_socket_tx_sequence_recover = 0; + tcp_socket.nx_tcp_socket_tx_window_congestion = 1000; + tcp_socket.nx_tcp_socket_connect_mss = 1460; + tcp_socket.nx_tcp_socket_transmit_sent_head = packet_ptr; + tcp_socket.nx_tcp_socket_transmit_sent_count = 1; + tcp_socket.nx_tcp_socket_fast_recovery = NX_FALSE; + tcp_socket.nx_tcp_socket_tx_sequence = 20; + tcp_socket.nx_tcp_socket_tx_outstanding_bytes = 20; + _nx_tcp_socket_state_ack_check(&tcp_socket, &tcp_header); + + /* Test nx_tcp_socket_state_ack_check.c + 295 [ + + ][ - + ]: 38 : else if ((socket_ptr -> nx_tcp_socket_duplicated_ack_received > 3) && + 296 : 1 : (socket_ptr -> nx_tcp_socket_fast_recovery == NX_TRUE)) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_queue_next = (NX_PACKET *)NX_DRIVER_TX_DONE; + packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr - 20; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_sequence_number = 0; + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_acknowledgment_number = 0; + tcp_socket.nx_tcp_socket_tx_sequence = 1; + tcp_socket.nx_tcp_socket_duplicated_ack_received = 4; + tcp_socket.nx_tcp_socket_tx_sequence_recover = 0; + tcp_socket.nx_tcp_socket_tx_window_congestion = 1000; + tcp_socket.nx_tcp_socket_connect_mss = 1460; + tcp_socket.nx_tcp_socket_transmit_sent_head = packet_ptr; + tcp_socket.nx_tcp_socket_transmit_sent_count = 1; + tcp_socket.nx_tcp_socket_fast_recovery = NX_TRUE; + tcp_socket.nx_tcp_socket_tx_sequence = 20; + tcp_socket.nx_tcp_socket_tx_outstanding_bytes = 20; + _nx_tcp_socket_state_ack_check(&tcp_socket, &tcp_header); + + + /* Test nx_tcp_socket_state_ack_check.c + 727 [ + + ][ + - ]: 44949 : if ((socket_ptr -> nx_tcp_socket_state == NX_TCP_FIN_WAIT_1) || + 728 [ + + ]: 44892 : (socket_ptr -> nx_tcp_socket_state == NX_TCP_CLOSING) || + 729 : 44892 : (socket_ptr -> nx_tcp_socket_state == NX_TCP_LAST_ACK)) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_queue_next = (NX_PACKET *)NX_DRIVER_TX_DONE; + packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr - 20; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_sequence_number = 0; + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_acknowledgment_number = 0; + tcp_socket.nx_tcp_socket_tx_sequence = 0; + tcp_socket.nx_tcp_socket_duplicated_ack_received = 4; + tcp_socket.nx_tcp_socket_tx_sequence_recover = 0; + tcp_socket.nx_tcp_socket_tx_window_congestion = 1000; + tcp_socket.nx_tcp_socket_connect_mss = 1460; + tcp_socket.nx_tcp_socket_transmit_sent_head = packet_ptr; + tcp_socket.nx_tcp_socket_transmit_sent_tail = packet_ptr; + tcp_socket.nx_tcp_socket_transmit_sent_count = 1; + tcp_socket.nx_tcp_socket_state = NX_TCP_CLOSING; + _nx_tcp_socket_state_ack_check(&tcp_socket, &tcp_header); + + /* Test nx_tcp_socket_state_ack_check.c + 479 [ - + ]: 12 : if (tcp_header_ptr -> nx_tcp_acknowledgment_number < ending_packet_sequence) + 480 : : { + 481 : : + 482 : : / * ACK does not cover the search packet. Break out of the loop. * / + 483 : 0 : break; + 484 : : } + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_queue_next = (NX_PACKET *)NX_DRIVER_TX_DONE; + packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr - 20; + packet_ptr -> nx_packet_length = 20; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_sequence_number = 0xEEEEEEEE; + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_sequence_number = 0; + tcp_header.nx_tcp_acknowledgment_number = 0; + tcp_socket.nx_tcp_socket_tx_sequence = 4; + tcp_socket.nx_tcp_socket_duplicated_ack_received = 0; + tcp_socket.nx_tcp_socket_tx_sequence_recover = 0; + tcp_socket.nx_tcp_socket_tx_window_congestion = 1000; + tcp_socket.nx_tcp_socket_connect_mss = 1460; + tcp_socket.nx_tcp_socket_transmit_sent_head = packet_ptr; + tcp_socket.nx_tcp_socket_transmit_sent_count = 1; + tcp_socket.nx_tcp_socket_fast_recovery = NX_FALSE; + tcp_socket.nx_tcp_socket_tx_outstanding_bytes = 20; + _nx_tcp_socket_state_ack_check(&tcp_socket, &tcp_header); + + /* Test nx_tcp_socket_state_ack_check.c + 500 [ + - ]: 9 : if (tcp_header_ptr -> nx_tcp_acknowledgment_number >= starting_tx_sequence) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_queue_next = (NX_PACKET *)NX_DRIVER_TX_DONE; + packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr - 20; + packet_ptr -> nx_packet_length = 10; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_sequence_number = 0xFFFFFFF0; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_sequence_number = 0; + tcp_header.nx_tcp_acknowledgment_number = 0; + tcp_socket.nx_tcp_socket_tx_sequence = 4; + tcp_socket.nx_tcp_socket_duplicated_ack_received = 0; + tcp_socket.nx_tcp_socket_tx_sequence_recover = 0; + tcp_socket.nx_tcp_socket_tx_window_congestion = 1000; + tcp_socket.nx_tcp_socket_connect_mss = 1460; + tcp_socket.nx_tcp_socket_transmit_sent_head = packet_ptr; + tcp_socket.nx_tcp_socket_transmit_sent_count = 1; + tcp_socket.nx_tcp_socket_fast_recovery = NX_FALSE; + tcp_socket.nx_tcp_socket_tx_outstanding_bytes = 20; + _nx_tcp_socket_state_ack_check(&tcp_socket, &tcp_header); + + /* Test nx_tcp_socket_state_ack_check.c + 679 [ + + ][ - + ]: 164665 : if ((((INT)tcp_header_ptr -> nx_tcp_acknowledgment_number - (INT)starting_tx_sequence > 0) && + 680 [ + + ]: 125179 : ((INT)tcp_header_ptr -> nx_tcp_acknowledgment_number - (INT)ending_tx_sequence <= 0)) || + 681 [ + + ]: 118418 : ((INT)tcp_header_ptr -> nx_tcp_sequence_number - (INT)ending_rx_sequence > 0) || + 682 [ + + ]: 112183 : (((INT)tcp_header_ptr -> nx_tcp_sequence_number == (INT)ending_rx_sequence) && + 683 : 112183 : ((INT)tcp_header_ptr -> nx_tcp_acknowledgment_number - (INT)starting_tx_sequence >= 0))) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_queue_next = (NX_PACKET *)NX_DRIVER_TX_DONE; + packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + packet_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr - 20; + packet_ptr -> nx_packet_length = 10; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_sequence_number = 0; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_sequence_number = 0; + tcp_header.nx_tcp_acknowledgment_number = 20; + tcp_socket.nx_tcp_socket_tx_sequence = 4; + tcp_socket.nx_tcp_socket_duplicated_ack_received = 0; + tcp_socket.nx_tcp_socket_tx_sequence_recover = 0; + tcp_socket.nx_tcp_socket_tx_window_congestion = 1000; + tcp_socket.nx_tcp_socket_connect_mss = 1460; + tcp_socket.nx_tcp_socket_transmit_sent_head = packet_ptr; + tcp_socket.nx_tcp_socket_transmit_sent_count = 1; + tcp_socket.nx_tcp_socket_fast_recovery = NX_FALSE; + tcp_socket.nx_tcp_socket_tx_outstanding_bytes = 20; + _nx_tcp_socket_state_ack_check(&tcp_socket, &tcp_header); + + /* Test nx_tcp_socket_state_ack_check.c + [+ -] 114 if (search_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_queue_next = (NX_PACKET *)NX_DRIVER_TX_DONE; + packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + packet_ptr -> nx_packet_ip_version = 0; + packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr - 20; + packet_ptr -> nx_packet_length = 10; + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + tcp_header.nx_tcp_sequence_number = 0; + tcp_header.nx_tcp_acknowledgment_number = 0; + tcp_socket.nx_tcp_socket_tx_sequence = 4; + tcp_socket.nx_tcp_socket_tx_outstanding_bytes = 0; + tcp_socket.nx_tcp_socket_receive_queue_tail = packet_ptr; + _nx_tcp_socket_state_ack_check(&tcp_socket, &tcp_header); +} + +static VOID data_check_test() +{ +NX_TCP_HEADER *tcp_header_ptr; +NX_PACKET *packet_ptr; + + /* Test nx_tcp_socket_state_data_check.c + 729 [ + - ]: 185 : while (search_ptr) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next = NX_NULL; + packet_ptr -> nx_packet_length = 30; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_3 = 0x50000000; + tcp_header_ptr -> nx_tcp_sequence_number = 0; + tcp_socket.nx_tcp_socket_receive_queue_head = packet_ptr; + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_length = 30; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_3 = 0x50000000; + tcp_header_ptr -> nx_tcp_sequence_number = 20; + tcp_socket.nx_tcp_socket_rx_sequence = 0; + _nx_tcp_socket_state_data_check(&tcp_socket, packet_ptr); + +} + +static VOID socket_packet_process_test() +{ +NX_TCP_HEADER *tcp_header_ptr; +NX_PACKET *packet_ptr; + + /* Test nx_tcp_socket_packet_process.c + 210 [ + + ][ + + ]: 3 : else if ((tcp_header_copy.nx_tcp_header_word_3 & NX_TCP_RST_BIT) || + 211 [ + - ]: 1 : (tcp_header_copy.nx_tcp_header_word_3 & NX_TCP_URG_BIT) || + 212 : 1 : ((tcp_header_copy.nx_tcp_header_word_3 & NX_TCP_CONTROL_MASK) == NX_TCP_ACK_BIT)) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_length = 20; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_3 = 0x50000000; + tcp_header_ptr -> nx_tcp_sequence_number = 0; + tcp_socket.nx_tcp_socket_rx_window_current = 0; + tcp_socket.nx_tcp_socket_rx_sequence = 1; + tcp_socket.nx_tcp_socket_state = NX_TCP_TIMED_WAIT; + _nx_tcp_socket_packet_process(&tcp_socket, packet_ptr); + + + /* Test nx_tcp_socket_packet_process.c + 229 [ + + ][ + + ]: 136515 : if ((rx_window > 0) && + 230 [ - + ]: 136280 : ((((INT)packet_sequence - (INT)rx_sequence >= 0) && + 231 [ + + ]: 134 : ((INT)rx_sequence + (INT)rx_window - (INT)packet_sequence > 0)) || + 232 [ + - ]: 10 : (((INT)packet_sequence + ((INT)packet_data_length - 1) - (INT)rx_sequence >= 0) && + 233 : 10 : ((INT)rx_sequence + 1 + ((INT)rx_window - (INT)packet_sequence) - (INT)packet_data_length > 0)))) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_length = 30; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_3 = 0x50000000; + tcp_header_ptr -> nx_tcp_sequence_number = 2; + tcp_socket.nx_tcp_socket_rx_window_current = 1; + tcp_socket.nx_tcp_socket_rx_sequence = 1; + tcp_socket.nx_tcp_socket_state = NX_TCP_TIMED_WAIT; + _nx_tcp_socket_packet_process(&tcp_socket, packet_ptr); + + /* Test nx_tcp_socket_packet_process.c + 452 [ + - ]: 1 : if (urgent_callback) + */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 0); + packet_ptr -> nx_packet_length = 20; + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_3 = 0x50000000 | NX_TCP_URG_BIT | NX_TCP_ACK_BIT; + tcp_header_ptr -> nx_tcp_sequence_number = 0; + tcp_socket.nx_tcp_socket_rx_window_current = 0; + tcp_socket.nx_tcp_socket_rx_sequence = 0; + tcp_socket.nx_tcp_socket_state = NX_TCP_TIMED_WAIT; + tcp_socket.nx_tcp_socket_receive_queue_tail = NX_NULL; + _nx_tcp_socket_packet_process(&tcp_socket, packet_ptr); +} + +#if defined FEATURE_NX_IPV6 && !defined NX_DISABLE_ASSERT +static VOID thread_for_assert_entry_0(ULONG thread_input) +{ +NXD_ADDRESS server_ip; +UINT status; + + /* Connect to addrss not reachable. */ + server_ip.nxd_ip_version = NX_IP_VERSION_V6; + server_ip.nxd_ip_address.v6[0] = 0xFE800000; + server_ip.nxd_ip_address.v6[1] = 0; + server_ip.nxd_ip_address.v6[2] = 0; + server_ip.nxd_ip_address.v6[3] = 0x1; + ip_0.nx_ipv6_address[address_index].nxd_ipv6_address_attached = NX_NULL; + status = nxd_tcp_client_socket_connect(&tcp_socket, &server_ip, 80, 0); + if (status != NX_INVALID_INTERFACE) + { + error_counter++; + } +} +#endif /* NX_DISABLE_ASSERT */ + +#if !defined NX_DISABLE_PACKET_CHAIN && !defined NX_DISABLE_ASSERT +static VOID thread_for_assert_entry_1(ULONG thread_input) +{ +NX_PACKET *test_packet; + + /* Hit condition: + 391 [ + - ][ + + ]: 5 : while ((current_packet != NX_NULL) && (current_packet -> nx_packet_prepend_ptr == current_packet -> nx_packet_append_ptr)) + + 399 [ - + ]: 2 : NX_ASSERT(current_packet != NX_NULL); + */ + nx_packet_allocate(&pool_0, &test_packet, NX_TCP_PACKET, NX_NO_WAIT); + if (nx_tcp_socket_send(&tcp_socket, test_packet, 0) != NX_INVALID_PACKET) + { + error_counter++; + } + + test_packet -> nx_packet_length = 10; + nx_tcp_socket_send(&tcp_socket, test_packet, 0); +} +#endif + +#endif /* __PRODUCT_NETXDUO__ */ +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_branch_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Branch Test...........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_chained_packet_test.c b/test/regression/netxduo_test/netx_tcp_chained_packet_test.c new file mode 100644 index 00000000..3d74387c --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_chained_packet_test.c @@ -0,0 +1,295 @@ +/* This NetX test concentrates on the chained packet of TCP transmission. */ +/* Window size is 1200 bytes. Payload size of pool is 512. Host A sends 2000 bytes. */ + +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static UCHAR send_buff[3000]; +static UCHAR recv_buff[3000]; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_chained_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; +UINT i; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + for (i = 0; i < sizeof(send_buff); i++) + { + send_buff[i] = i & 0xFF; + recv_buff[i] = 0xFF - (i & 0xFF); + } + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 10240); + pointer = pointer + 10240; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Chained Packet Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), + &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG total_length = 0; +ULONG bytes_copied; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1202, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 3 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + /* Retrieve data. */ + nx_packet_data_retrieve(packet_ptr, recv_buff + total_length, &bytes_copied); + total_length += bytes_copied; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Check received data. */ + if (total_length != sizeof(send_buff)) + error_counter++; + else if (memcmp(send_buff, recv_buff, sizeof(send_buff)) != 0) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_chained_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Chained Packet Test...................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_client_bind_cleanup_test.c b/test/regression/netxduo_test/netx_tcp_client_bind_cleanup_test.c new file mode 100644 index 00000000..44f6a26b --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_client_bind_cleanup_test.c @@ -0,0 +1,305 @@ +/* This NetX test concentrates on the TCP Client Bind Cleanup operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static TX_THREAD ntest_2; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket_0; +static NX_TCP_SOCKET client_socket_1; +static NX_TCP_SOCKET client_socket_2; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_2_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_client_bind_cleanup_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_2, "thread 2", ntest_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Client Bind Cleanup Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket 0. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_0, "Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create a socket 1. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_1, "Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create a socket 2. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_2, "Client Socket 2", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_0.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_1.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_2.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Bind the client_socket_0 port to 12. */ + status = nx_tcp_client_socket_bind(&client_socket_0, 12, NX_NO_WAIT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_0.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_1.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_2.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Bind the client_socket_1 port to same port. */ + status = nx_tcp_client_socket_bind(&client_socket_1, 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PORT_UNAVAILABLE) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_0.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_1.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_2.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Unbind the socket 0. */ + status = nx_tcp_client_socket_unbind(&client_socket_0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket 1. */ + status = nx_tcp_client_socket_unbind(&client_socket_1); + + /* Check for error. */ + if (status != NX_NOT_BOUND) + error_counter++; + + /* Unbind the socket 2. */ + status = nx_tcp_client_socket_unbind(&client_socket_2); + + /* Check for error. */ + if (status != NX_NOT_BOUND) + error_counter++; + + /* Delete the socket 0. */ + status = nx_tcp_socket_delete(&client_socket_0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket 1. */ + status = nx_tcp_socket_delete(&client_socket_1); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket 2. */ + status = nx_tcp_socket_delete(&client_socket_2); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the error counter. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; + + + /* Check the TCP socket bind suspended count. */ + if (client_socket_0.nx_tcp_socket_bind_suspended_count != 1) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_1.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_2.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Bind the client_socket_3 port to same port. */ + status = nx_tcp_client_socket_bind(&client_socket_2, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PORT_UNAVAILABLE) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_0.nx_tcp_socket_bind_suspended_count != 1) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_1.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_2.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_2_entry(ULONG thread_input) +{ + + /* Check the TCP socket bind suspended count. */ + if (client_socket_0.nx_tcp_socket_bind_suspended_count != 2) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_1.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket_2.nx_tcp_socket_bind_suspended_count != 0) + error_counter++; +} + diff --git a/test/regression/netxduo_test/netx_tcp_client_packet_leak_test.c b/test/regression/netxduo_test/netx_tcp_client_packet_leak_test.c new file mode 100644 index 00000000..31efaec0 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_client_packet_leak_test.c @@ -0,0 +1,333 @@ +/* This NetX test concentrates TCP client packet leak issue + * JIRA: https://expresslogic.atlassian.net/browse/NETXDUO-144. */ + +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_client_packet_leak_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +ULONG tcp_transmit_window; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Packet Leak Test......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create the client socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Connect to server. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Disconnect from server. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Connect to server again without unbind. */ + nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Unbind the client socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Delete the client socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + error_counter++; + } + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Create the server socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Listen the socket. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Accept connection from client. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + packet_ptr -> nx_packet_length = 28; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + nx_packet_release(packet_ptr); + error_counter++; + } + + /* Disconnect from client. */ + status = nx_tcp_socket_disconnect(&server_socket, 5); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + nx_tcp_server_socket_unaccept(&server_socket); + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Delete the client socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_client_packet_leak_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Packet Leak Test......................................N/A\n"); + + test_control_return(3); + +} +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/netxduo_test/netx_tcp_client_socket_bind_test.c b/test/regression/netxduo_test/netx_tcp_client_socket_bind_test.c new file mode 100644 index 00000000..ff39e547 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_client_socket_bind_test.c @@ -0,0 +1,206 @@ +/* This NetX test concentrates on the TCP free port find operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static NX_TCP_SOCKET socket_0; +static NX_TCP_SOCKET my_socket[NX_MAX_PORT - NX_SEARCH_PORT_START + 1]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* The 2 ports will hashed to the same index. */ +#define CLIENT_PORT_1 0x00000100 +#define CLIENT_PORT_2 0x00008100 + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void test_control_return(UINT status); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_client_socket_bind_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&ip_0); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT free_port; +UINT i; + + + /* Print out some test information banners. */ + printf("NetX Test: TCP Clinet Socket Bind Test..............................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket. */ + status = nx_tcp_socket_create(&ip_0, &socket_0, "Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&socket_0, CLIENT_PORT_1, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* CLIENT_PORT_1 has been bound. */ + status = nx_tcp_free_port_find(&ip_0, CLIENT_PORT_1, &free_port); + if((status != NX_SUCCESS) && (free_port != CLIENT_PORT_1 + 1)) + error_counter++; + + /* CLIENT_PORT_2 and CLIENT_PORT_1 are mapped to the same index. */ + status = nx_tcp_free_port_find(&ip_0, CLIENT_PORT_2, &free_port); + if ((status != NX_SUCCESS) || (free_port != CLIENT_PORT_2)) + error_counter++; + + /* Unbind the TCP socket. */ + status = nx_tcp_client_socket_unbind(&socket_0); + if (status != NX_SUCCESS) + error_counter++; + + /* Test port wrap around. */ + status = nx_tcp_client_socket_bind(&socket_0, NX_MAX_PORT, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + status = nx_tcp_free_port_find(&ip_0, NX_MAX_PORT, &free_port); + if ((status != NX_SUCCESS) || (free_port != NX_SEARCH_PORT_START)) + error_counter++; + + /* Unbind the TCP socket. */ + status = nx_tcp_client_socket_unbind(&socket_0); + if (status != NX_SUCCESS) + error_counter++; + + for(i = 0; i <= (NX_MAX_PORT - NX_SEARCH_PORT_START); i++) + { + + /* Create a TCP socket. */ + status = nx_tcp_socket_create(&ip_0, &my_socket[i], "Socket Array", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_tcp_client_socket_bind(&my_socket[i], i + NX_SEARCH_PORT_START, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&socket_0, NX_ANY_PORT, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status != NX_NO_FREE_PORTS) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&socket_0, NX_SEARCH_PORT_START, NX_NO_WAIT); + + /* Check for error. */ + if(status != NX_PORT_UNAVAILABLE) + error_counter++; + + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&socket_0); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + diff --git a/test/regression/netxduo_test/netx_tcp_client_socket_port_get_test.c b/test/regression/netxduo_test/netx_tcp_client_socket_port_get_test.c new file mode 100644 index 00000000..ffa17584 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_client_socket_port_get_test.c @@ -0,0 +1,179 @@ +/* This NetX test concentrates on the fast disconnect TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket; + + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_client_socket_port_get_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT client_port; +UINT compare_port; + + + /* Print out some test information banners. */ + printf("NetX Test: TCP Client Socket Port Get Test..........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the port for the client socket before port bind. */ + status = nx_tcp_client_socket_port_get(&client_socket, &compare_port); + + /* Check for error. */ + if (status != NX_NOT_BOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the port for the client socket. */ + status = nx_tcp_client_socket_port_get(&client_socket, &compare_port); + + /* Check for error. */ + if ((status) || (client_port != compare_port)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_client_socket_unbind_test.c b/test/regression/netxduo_test/netx_tcp_client_socket_unbind_test.c new file mode 100644 index 00000000..00548f10 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_client_socket_unbind_test.c @@ -0,0 +1,193 @@ +/* This NetX test concentrates on the TCP Client Bind Cleanup operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket_0; +static NX_TCP_SOCKET client_socket_1; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_client_socket_unbind_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Client Socket Unbind Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket 0. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_0, "Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the client_socket_0 port to 12. */ + status = nx_tcp_client_socket_bind(&client_socket_0, 12, NX_NO_WAIT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Let thread 1 run. */ + tx_thread_relinquish(); + + /* Check the socket 1. */ + if (!client_socket_1.nx_tcp_socket_bind_in_progress) + error_counter++; + + /* Unbind the socket 1 when the socket 1 bind in progress. */ + status = nx_tcp_client_socket_unbind(&client_socket_1); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Check the socket 1. */ + if (client_socket_1.nx_tcp_socket_bind_in_progress) + error_counter++; + + /* Unbind the socket 0. */ + status = nx_tcp_client_socket_unbind(&client_socket_0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket 1. */ + status = nx_tcp_socket_delete(&client_socket_1); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket 0. */ + status = nx_tcp_socket_delete(&client_socket_0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the error counter. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket 1. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_1, "Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the client_socket_1 port to same port. */ + nx_tcp_client_socket_bind(&client_socket_1, 12, 2 * NX_IP_PERIODIC_RATE); +} \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_connection_reset_test.c b/test/regression/netxduo_test/netx_tcp_connection_reset_test.c new file mode 100644 index 00000000..dea9072d --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_connection_reset_test.c @@ -0,0 +1,359 @@ +/* This NetX test concentrates on connection reset. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define a packet data send FIN from 192.168.1.10 to 192.168.1.8. The ACK bit is not set. */ +static const unsigned char pkt_fin[] = { +0x00, 0x08, 0xee, 0x03, 0x6a, 0xc6, 0x00, 0x50, /* ....j..P */ +0xb6, 0x07, 0xa1, 0x69, 0x08, 0x00, 0x45, 0x00, /* ...i..E. */ +0x00, 0x28, 0x57, 0x1c, 0x40, 0x00, 0x80, 0x06, /* .(W.@... */ +0x20, 0x51, 0xc0, 0xa8, 0x01, 0x0a, 0xc0, 0xa8, /* Q...... */ +0x01, 0x08, 0xd3, 0xed, 0x1f, 0x90, 0x66, 0xe8, /* ......f. */ +0x6b, 0x67, 0x28, 0xd9, 0x25, 0x44, 0x50, 0x01, /* kg(.%DP. */ +0xfa, 0xf0, 0x1d, 0xa5, 0x00, 0x00 /* ...... */ +}; +#ifdef __PRODUCT_NETXDUO__ +static const ULONG fin_sequence = 0x66e86b67; +#endif /* __PRODUCT_NETXDUO__ */ + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG rst_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_connection_reset_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + rst_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192, 168, 1, 10), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(192, 168, 1, 8), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /*Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status = nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP Connection Reset Test................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + /*Send an echo request to make arp*/ + status = nx_icmp_ping(&ip_0, IP_ADDRESS(192, 168, 1, 8), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 28, &my_packet, TX_TIMER_TICKS_PER_SECOND); + + /* Determine if the timeout error occurred. */ + if ((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /*Deal the syn+ack packet with my routing*/ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + advanced_packet_process_callback = my_packet_process; + + /*Call connect to send an syn*/ + nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(192, 168, 1, 8), 12, 5 * TX_TIMER_TICKS_PER_SECOND); + + /*Let server deal with rst*/ + tx_thread_relinquish(); + + status = nx_packet_allocate(&pool_0, &my_packet, NX_ICMP_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + error_counter ++; + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(my_packet -> nx_packet_prepend_ptr, &pkt_fin[14], sizeof(pkt_fin) - 14); + my_packet -> nx_packet_length = sizeof(pkt_fin) - 14; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + sizeof(pkt_fin) - 14; + + /* Directly receive the RA packet. */ + _nx_ip_packet_deferred_receive(&ip_1, my_packet); + + /* Determine if the test was successful. */ +#ifdef __PRODUCT_NETXDUO__ + if ((error_counter) || (rst_counter != 1)) +#else + if (error_counter) +#endif + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + if(server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + + tx_thread_resume(&thread_0); +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER header_ptr; + + /*Send rst*/ + header_ptr.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_tx_sequence; + _nx_tcp_packet_send_rst(&client_socket, &header_ptr); + _nx_tcp_socket_thread_resume(&(client_socket.nx_tcp_socket_connect_suspended_thread), NX_NOT_ENABLED); + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Do not process packets that are not TCP. */ + if ((packet_ptr -> nx_packet_length < 40) || (ip_ptr != &ip_1)) + return NX_TRUE; + + /* Get TCP header. */ + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check whether it is a RST packet. */ + if (header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + + /* Yes it is. */ + rst_counter++; + +#ifdef __PRODUCT_NETXDUO__ + /* Check whether the ACK equals SEQ in FIN plus one. */ + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); + if (header_ptr -> nx_tcp_acknowledgment_number != fin_sequence + 1) + { + error_counter++; + } + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_acknowledgment_number); +#endif + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_connection_reset_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Connection Reset Test.................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_cwnd_test.c b/test/regression/netxduo_test/netx_tcp_cwnd_test.c new file mode 100644 index 00000000..59557ef8 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_cwnd_test.c @@ -0,0 +1,395 @@ +/* This NetX test concentrates on the congestion window increasement during slow start and congestion avoidance. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static CHAR send_buff[1500]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_cwnd_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG cwnd; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: TCP CWND Test............................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Reset the send_buff. */ + for (i = 0; i < sizeof(send_buff); i++) + { + send_buff[i] = (CHAR)(i & 0xFF); + } + + /* Store the congestion window before sending. */ + cwnd = client_socket.nx_tcp_socket_tx_window_congestion; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, client_socket.nx_tcp_socket_connect_mss, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Sleep 1 second to make sure ACK is received. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the congestion window increased by one MSS. */ + if (client_socket.nx_tcp_socket_tx_window_congestion != cwnd + client_socket.nx_tcp_socket_connect_mss) + error_counter++; + + + /* Send packet to enter congestion avoidance. */ + while (client_socket.nx_tcp_socket_tx_window_congestion < client_socket.nx_tcp_socket_tx_slow_start_threshold) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, client_socket.nx_tcp_socket_connect_mss, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + + /* Store the congestion window before sending. */ + cwnd = client_socket.nx_tcp_socket_tx_window_congestion; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, client_socket.nx_tcp_socket_connect_mss, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Sleep 1 second to make sure ACK is received. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the congestion window increased by MSS * MSS / CWND. */ + if (client_socket.nx_tcp_socket_tx_window_congestion != cwnd + client_socket.nx_tcp_socket_connect_mss2 / cwnd) + error_counter++; + + + /* Send packet to let cwnd > MSS * MSS. */ + while (client_socket.nx_tcp_socket_tx_window_congestion <= client_socket.nx_tcp_socket_connect_mss2) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, client_socket.nx_tcp_socket_connect_mss, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + + /* Store the congestion window before sending. */ + cwnd = client_socket.nx_tcp_socket_tx_window_congestion; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, client_socket.nx_tcp_socket_connect_mss, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Sleep 1 second to make sure ACK is received. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the congestion window increased by 1 byte. */ + if (client_socket.nx_tcp_socket_tx_window_congestion != cwnd + 1) + error_counter++; + + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, send_buff, packet_ptr -> nx_packet_length)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_cwnd_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP CWND Test.............................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_data_transfer_test.c b/test/regression/netxduo_test/netx_tcp_data_transfer_test.c new file mode 100644 index 00000000..8858a6c5 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_data_transfer_test.c @@ -0,0 +1,545 @@ +/* This NetX test concentrates on the TCP data transfer operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket); +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_data_transfer_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT compare_port; +ULONG tcp_packets_sent, tcp_bytes_sent, tcp_packets_received, tcp_bytes_received, tcp_invalid_packets, tcp_receive_packets_dropped, tcp_checksum_errors, tcp_connections, tcp_disconnections, tcp_connections_dropped, tcp_retransmit_packets; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Data Transfer Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 12, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup a receive notify function. */ + status = nx_tcp_socket_receive_notify(&client_socket, thread_0_receive_notify); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Pickup the port for the client socket. */ + status = nx_tcp_client_socket_port_get(&client_socket, &compare_port); + + /* Check for error. */ + if ((status) || (client_port != compare_port)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Loop to send 1000 messages! */ + while ((thread_0_counter < 1000) && (error_counter == 0)) + { + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + +#if !defined(FEATURE_NX_IPV6) && defined(__PRODUCT_NETXDUO__) + /* Sleep 2MSL and check the state of socket from timed_wait to closed. */ + if (client_socket.nx_tcp_socket_state != NX_TCP_TIMED_WAIT) + { + error_counter++; + } + else + { + tx_thread_sleep(_nx_tcp_2MSL_timer_rate + 1); + if (client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + { + error_counter++; + } + } +#endif /* FEATURE_NX_IPV6 */ + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&client_socket, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + if((packets_sent != 1000) || (bytes_sent != 1000*28)) + error_counter++; +#endif + + /* Check for errors. */ + if ((error_counter) || (status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get the overall TCP information. */ + status = nx_tcp_info_get(&ip_0, &tcp_packets_sent, &tcp_bytes_sent, &tcp_packets_received, &tcp_bytes_received, + &tcp_invalid_packets, &tcp_receive_packets_dropped, &tcp_checksum_errors, &tcp_connections, + &tcp_disconnections, &tcp_connections_dropped, &tcp_retransmit_packets); + +#ifndef NX_DISABLE_TCP_INFO + if((tcp_packets_sent != 1000) || (tcp_bytes_sent != 1000*28) || (tcp_connections != 1)) + error_counter++; +#endif + + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != 1000) || (thread_1_counter != 1000) || (connections != 1) || (disconnections) || + (tcp_packets_received) || (tcp_bytes_received) || (tcp_invalid_packets) || (tcp_receive_packets_dropped) || (tcp_checksum_errors) || + (tcp_connections_dropped) || (tcp_retransmit_packets)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup a receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, thread_1_receive_notify); + + /* Check for error. */ + if (status) + error_counter++; + + /* Configure the socket further. */ + status = nx_tcp_socket_transmit_configure(&server_socket, 10, 300, 10, 0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Inject the SYN packet. */ + ip_1.nx_ip_tcp_packet_receive = tcp_packet_receive; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Loop to accept 1000 messages. */ + while((thread_1_counter < 1000) && (error_counter == 0)) + { + + /* Increment thread 1's counter. */ + thread_1_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Let client disconnect first. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; + else + connections++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket) +{ + + client_receives++; +} + + +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket) +{ + + server_receives++; +} + +static void tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +#if defined(NX_ENABLE_INTERFACE_CAPABILITY) && defined(__PRODUCT_NETXDUO__) +NX_IPV4_HEADER *ip_header; +NX_PACKET *loopback_src_port; +NX_PACKET *broadcast_source; + + /* Set the source IP equal to destination IP. Verify whether or not system crashes. */ + /* Set the interface capability to ignore the checksum. */ + packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_capability_flag |= NX_INTERFACE_CAPABILITY_TCP_RX_CHECKSUM; + + /* Copy from the original packet. */ + nx_packet_copy(packet_ptr, &loopback_src_port, &pool_0, NX_NO_WAIT); + nx_packet_copy(packet_ptr, &broadcast_source, &pool_0, NX_NO_WAIT); + + /* Get IP header. */ + ip_header = (NX_IPV4_HEADER *)loopback_src_port -> nx_packet_ip_header; + + /* Copy the dest ip to source ip field. */ + ip_header -> nx_ip_header_source_ip = ip_header -> nx_ip_header_destination_ip; + + /* Pass the packet. */ + _nx_tcp_packet_receive(ip_ptr, loopback_src_port); + +#ifndef NX_DISABLE_TCP_INFO + if (ip_ptr -> nx_ip_tcp_invalid_packets != 1) + error_counter++; +#endif /* NX_DISABLE_TCP_INFO */ + + /* Get IP header. */ + ip_header = (NX_IPV4_HEADER *)broadcast_source -> nx_packet_ip_header; + + /* Copy the dest ip to source ip field. */ + ip_header -> nx_ip_header_source_ip = NX_IP_LIMITED_BROADCAST; + + /* Pass the packet. */ + _nx_tcp_packet_receive(ip_ptr, broadcast_source); + +#ifndef NX_DISABLE_TCP_INFO + if (ip_ptr -> nx_ip_tcp_invalid_packets != 2) + error_counter++; +#endif /* NX_DISABLE_TCP_INFO */ +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + /* Restore tcp receive function pointer. */ + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Pass the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_data_transfer_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Data Transfer Test....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_data_trim_test.c b/test/regression/netxduo_test/netx_tcp_data_trim_test.c new file mode 100644 index 00000000..76f597d6 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_data_trim_test.c @@ -0,0 +1,335 @@ +/* This NetX test concentrates on the TCP data trim operation. */ +/* Cover the code line 115-124 and line 136-146 for _nx_tcp_socket_state_trim(); */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define NX_PACKET_SIZE (1536 + sizeof(NX_PACKET)) +#define NX_PACKET_POOL_SIZE (NX_PACKET_SIZE * 20) +#define NX_PACKET_SMALL_SIZE (256 + sizeof(NX_PACKET)) +#define NX_PACKET_POOL_SMALL_SIZE (NX_PACKET_SMALL_SIZE * 20) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static UCHAR message[1000]; +static ULONG data_counter; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_data_trim_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + error_counter = 0; + data_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool for IP instance 0. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_PACKET_SIZE, pointer, NX_PACKET_POOL_SIZE); + pointer = pointer + NX_PACKET_POOL_SIZE; + + if (status) + error_counter++; + + /* Create a packet pool for IP instance 1. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Let the other thread run first. */ + tx_thread_relinquish(); + + /* Print out test information banner. */ + printf("NetX Test: TCP Data Trim Test........................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_relinquish(); + + /* Check the window size. */ + if ((client_socket.nx_tcp_socket_rx_window_current != 300) || (client_socket.nx_tcp_socket_tx_window_advertised != 300) || + (server_socket.nx_tcp_socket_rx_window_current != 300) || (server_socket.nx_tcp_socket_tx_window_advertised != 300)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the tx_window_advertised value to let client send large packet to server. */ + client_socket.nx_tcp_socket_tx_window_advertised = 1000; + + /* Allocate the packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write data that is larger than window size. */ + status = nx_packet_data_append(my_packet, message, 1000, &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_relinquish(); + + /* Check the data length. Server socket should trim the data if the data length is larger than the window. */ + + /* Determine if the test was successful. */ + if ((data_counter != 300) || (error_counter)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket with the window size 300(2 packets, one packet payload size is 256). */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive the packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Record the received data counter. */ + data_counter = packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); +} + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_data_trim_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Data Trim Test........................................N/A\n"); + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_delayed_retransmission_test.c b/test/regression/netxduo_test/netx_tcp_delayed_retransmission_test.c new file mode 100644 index 00000000..b331ece2 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_delayed_retransmission_test.c @@ -0,0 +1,371 @@ +/* This NetX test concentrates on delayed retransmission TCP packet. + * 1. Send packet A. + * 2. Drop packet A in driver. + * 3. Send packet B, C and D. + * 4. Retransmit packet A. + * 5. Copy the data in A and transmit it. Delay packet A for 1 seconds. + * 6. Wait 2 seconds. + * 7. Check all packets are released. + * 8. Check no invalid packet released. */ + +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#include "nx_ram_network_driver_test_1500.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + +static NX_PACKET *drop_packet; +static NX_PACKET *duplicate_packet; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_delayed_retransmission_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + drop_packet = NX_NULL; + duplicate_packet = NX_NULL; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Delayed Retransmission Test..........................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Set driver packet process callback. */ + advanced_packet_process_callback = packet_process; + + for (i = 0; i < 4; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "A", 1, &pool_0, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + if (i == 0) + { + + /* Drop the first packet. */ + drop_packet = my_packet; + } + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + /* Wait two seconds. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Verify all packets are released from TX queue. */ + if (client_socket.nx_tcp_socket_tx_outstanding_bytes != 0) + error_counter++; + + /* Verify pool is full. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + error_counter++; + +#ifndef NX_DISABLE_PACKET_INFO + /* Verify no packet is released invalid. */ + if (pool_0.nx_packet_pool_invalid_releases != 0) + error_counter++; +#endif /* NX_DISABLE_PACKET_INFO */ + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +UINT i; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + for (i = 0; i < 4; i++) + { + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, "A", 1)) + error_counter++; + + nx_packet_release(packet_ptr); + } + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + if (packet_ptr == drop_packet) + { + + /* This packet should be dropped. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + /* Duplicate this packet next time. */ + duplicate_packet = drop_packet; + drop_packet = NX_NULL; + } + else if (packet_ptr == duplicate_packet) + { + + /* This packet should be duplicated and delayed for 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + if (nx_packet_allocate(&pool_0, &duplicate_packet, 16, NX_NO_WAIT) == NX_SUCCESS) + { + + /* Copy data from original packet. */ + memcpy(duplicate_packet -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_prepend_ptr, + packet_ptr -> nx_packet_length); + duplicate_packet -> nx_packet_length = packet_ptr -> nx_packet_length; + duplicate_packet -> nx_packet_append_ptr += duplicate_packet -> nx_packet_length; + + /* Let IP 0 receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_1, duplicate_packet); + } + else + { + error_counter++; + } + + duplicate_packet = NX_NULL; + } + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_delayed_retransmission_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Delayed Retransmission Test...........................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_delayed_retransmission_test2.c b/test/regression/netxduo_test/netx_tcp_delayed_retransmission_test2.c new file mode 100644 index 00000000..74204503 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_delayed_retransmission_test2.c @@ -0,0 +1,359 @@ +/* This NetX test concentrates on delayed retransmission TCP packet. + * 1. Send packet A. + * 2. Drop packet A in driver. + * 4. Retransmit packet A. + * 5. Copy the data in A and transmit it. Delay packet A for 1 seconds. + * 6. Wait 2 seconds. + * 7. Check all packets are released. + * 8. Check no invalid packet released. */ + +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#include "nx_ram_network_driver_test_1500.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + +static NX_PACKET *drop_packet; +static NX_PACKET *duplicate_packet; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_delayed_retransmission_test_2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + drop_packet = NX_NULL; + duplicate_packet = NX_NULL; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Delayed Retransmission Test 2........................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Set driver packet process callback. */ + advanced_packet_process_callback = packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "A", 1, &pool_0, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Drop the first packet. */ + drop_packet = my_packet; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Wait two seconds. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Verify all packets are released from TX queue. */ + if (client_socket.nx_tcp_socket_tx_outstanding_bytes != 0) + error_counter++; + + /* Verify pool is full. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + error_counter++; + +#ifndef NX_DISABLE_PACKET_INFO + /* Verify no packet is released invalid. */ + if (pool_0.nx_packet_pool_invalid_releases != 0) + error_counter++; +#endif /* NX_DISABLE_PACKET_INFO */ + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, "A", 1)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + if (packet_ptr == drop_packet) + { + + /* This packet should be dropped. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + if (duplicate_packet == NX_NULL) + { + + /* Duplicate this packet next time. */ + duplicate_packet = drop_packet; + } + drop_packet = NX_NULL; + } + else if (packet_ptr == duplicate_packet) + { + + /* This packet should be duplicated and delayed for 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + if (nx_packet_allocate(&pool_0, &duplicate_packet, 16, NX_NO_WAIT) == NX_SUCCESS) + { + + /* Copy data from original packet. */ + memcpy(duplicate_packet -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_prepend_ptr, + packet_ptr -> nx_packet_length); + duplicate_packet -> nx_packet_length = packet_ptr -> nx_packet_length; + duplicate_packet -> nx_packet_append_ptr += duplicate_packet -> nx_packet_length; + + /* Let IP 0 receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_1, duplicate_packet); + } + else + { + error_counter++; + } + + duplicate_packet = NX_NULL; + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_delayed_retransmission_test_2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Delayed Retransmission Test 2.........................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_dropped_packet_test.c b/test/regression/netxduo_test/netx_tcp_dropped_packet_test.c new file mode 100644 index 00000000..60ca400c --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_dropped_packet_test.c @@ -0,0 +1,502 @@ +/* This NetX test concentrates on dropping of TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; + + +extern ULONG packet_gather; +extern ULONG packet_drop; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_dropped_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + + /* Print out test information banner. */ + printf("NetX Test: TCP Dropped Packet Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + tx_thread_relinquish(); + + /* Loop to repeat things over and over again! */ + thread_0_counter = 0; + while ((thread_0_counter < 2000) && (!error_counter)) + { + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Set the gather flag to instruct the test driver to save the packets and reverse the order. */ + packet_gather = 1; + + /* Set the dropped packet variable to drop a packet. */ + packet_drop = (thread_0_counter & 3) + 1; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 100 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 20 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 20 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 20 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_suspend(&thread_0); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Determine if the test was successful. */ + if ((error_counter) || (thread_0_counter != 2000) || (thread_1_counter != 2000)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG sequence_increment = 1; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Supsend thread 0. */ + tx_thread_suspend(&thread_0); + nx_tcp_socket_state_wait(&server_socket, NX_TCP_ESTABLISHED, 2 * NX_IP_PERIODIC_RATE); + tx_thread_resume(&thread_0); + + /* Set all the sequence numbers the way we want them for our test. */ + client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00; + client_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00; + client_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00; + server_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00; + server_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00; + server_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00; + + /* Loop to create and establish server connections. */ + thread_1_counter = 0; + while ((thread_1_counter < 2000) && (!error_counter)) + { + + /* Increment thread 1's counter. */ + thread_1_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 20 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 20 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 20 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive a TCP message from the socket. */ + server_socket.nx_tcp_socket_rx_window_last_sent = 0; /* Force an ACK out! */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 20 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Set all the sequence numbers the way we want them for our test. */ + if ((server_socket.nx_tcp_socket_rx_sequence < 0xFFFFFF00) && + (server_socket.nx_tcp_socket_rx_sequence > 0x100)) + { + /* Wait for client socket to empty. */ + while (client_socket.nx_tcp_socket_transmit_sent_count) + { + tx_thread_sleep(1); + } + + client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + client_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + client_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00 + (sequence_increment & 0xFF); + server_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + server_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + server_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00 + (sequence_increment++ & 0xFF); + } + + /* Resume thread 0. */ + tx_thread_resume(&thread_0); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_dropped_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Dropped Packet Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_dropped_packet_test2.c b/test/regression/netxduo_test/netx_tcp_dropped_packet_test2.c new file mode 100644 index 00000000..78f1cadd --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_dropped_packet_test2.c @@ -0,0 +1,314 @@ +/* This NetX test concentrates on TCP packet drop. + * Client sends 5 packet to server. Each packet size is MSS. + * The first and the third packets are dropped. */ + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static CHAR send_buff[1500]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_dropped_packet_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Dropped Packet Test 2................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Reset the send_buff. */ + for (i = 0; i < sizeof(send_buff); i++) + { + send_buff[i] = (CHAR)(i & 0xFF); + } + + for (i = 0; i < 5; i++) + { + + if ((i == 0) || (i == 2)) + { + + /* Set driver filter to drop the first and third packets. */ + advanced_packet_process_callback = packet_process; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, client_socket.nx_tcp_socket_connect_mss, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +UINT i; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + for (i = 0; i < 5; i++) + { + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, send_buff, packet_ptr -> nx_packet_length)) + error_counter++; + + nx_packet_release(packet_ptr); + } + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Simply drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + advanced_packet_process_callback = NX_NULL; + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_dropped_packet_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Dropped Packet Test 2.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_duplicate_accept_test.c b/test/regression/netxduo_test/netx_tcp_duplicate_accept_test.c new file mode 100644 index 00000000..874b6efd --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_duplicate_accept_test.c @@ -0,0 +1,294 @@ +/* This NetX test concentrates on calling nx_tcp_server_socket_accept() for multiple times. + * It verifies a bug that TCP server would send SYN+ACK on each accept() call. The ACK number in each packet is different. */ + +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT syn_ack_received; +static UINT sequence[10]; +static UINT ack_number[10]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_duplicate_accept_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_ack_received = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 10240); + pointer = pointer + 10240; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Duplicate Accept Test................................."); + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Filter the TCP packet received by client. */ + ip_0.nx_ip_tcp_packet_receive = tcp_packet_receive; + + /* Attempt to connect the socket. */ + nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +UINT i; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1460, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Sleep one second. Let client send SYN first. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + if (status != NX_IN_PROGRESS) + error_counter++; + + /* Accept a client socket connection again. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_NO_WAIT); + if (status != NX_IN_PROGRESS) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + + /* Only one SYN+ACK packet is expected. */ + if (syn_ack_received != 1) + { + error_counter++; + + /* Check whether all sequence and ACK numbers are the same. */ + for (i = 1; i < syn_ack_received; i++) + { + if (sequence[i] != sequence[0]) + error_counter++; + if (ack_number[i] != ack_number[0]) + error_counter++; + } + } + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Get the TCP header pointer. */ + tcp_header_ptr = (NX_TCP_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && + (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + + /* Get Sequence and ACK numbers. */ + sequence[syn_ack_received] = tcp_header_ptr -> nx_tcp_sequence_number; + ack_number[syn_ack_received] = tcp_header_ptr -> nx_tcp_acknowledgment_number; + syn_ack_received++; + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + /* Drop the packet to avoid RST. */ + nx_packet_release(packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_duplicate_accept_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Duplicate Accept Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_error_operation_check_test.c b/test/regression/netxduo_test/netx_tcp_error_operation_check_test.c new file mode 100644 index 00000000..9681384c --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_error_operation_check_test.c @@ -0,0 +1,235 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_error_operation_check_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for IP instances 0. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NXD_ADDRESS server_ip; + + + /* Print out some test information banners. */ + printf("NetX Test: TCP Error Operation Check Test............................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the server IP address. */ + server_ip.nxd_ip_version = NX_IP_VERSION_V4; + server_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Call connect before port bound. */ + status = nxd_tcp_client_socket_connect(&client_socket, &server_ip, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_BOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the unreachable IPv4 address. */ + server_ip.nxd_ip_version = NX_IP_VERSION_V4; + server_ip.nxd_ip_address.v4 = IP_ADDRESS(2, 2, 3, 5); + + /* Call connect with error address. */ + status = nxd_tcp_client_socket_connect(&client_socket, &server_ip, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Set the unreachable IPv6 address. */ + server_ip.nxd_ip_version = NX_IP_VERSION_V6; + server_ip.nxd_ip_address.v6[0] = 0x20010000; + server_ip.nxd_ip_address.v6[1] = 0x00000000; + server_ip.nxd_ip_address.v6[2] = 0x00000000; + server_ip.nxd_ip_address.v6[3] = 0x10000002; + + /* Call connect with error address. */ + status = nxd_tcp_client_socket_connect(&client_socket, &server_ip, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NO_INTERFACE_ADDRESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifndef NX_DISABLE_ERROR_CHECKING + /* Set the error address version. */ + server_ip.nxd_ip_version = 0x05; + server_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Call connect with error address. */ + status = nxd_tcp_client_socket_connect(&client_socket, &server_ip, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Set the server address. */ + server_ip.nxd_ip_version = NX_IP_VERSION_V4; + server_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Set the small interface mtu. */ + status = nx_ip_interface_mtu_set(&ip_0, 0, 20); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect with small interface mtu. */ + status = nxd_tcp_client_socket_connect(&client_socket, &server_ip, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_error_operation_check_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Error Operation Check Test............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_fast_disconnect_test.c b/test/regression/netxduo_test/netx_tcp_fast_disconnect_test.c new file mode 100644 index 00000000..850a1a9e --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_fast_disconnect_test.c @@ -0,0 +1,475 @@ +/* This NetX test concentrates on the fast disconnect TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#define DEMO_STACK_SIZE 2048 + +#if !defined(NX_DISABLE_RESET_DISCONNECT) && !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket); +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_fast_disconnect_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT compare_port; +ULONG tcp_packets_sent, tcp_bytes_sent, tcp_packets_received, tcp_bytes_received, tcp_invalid_packets, tcp_receive_packets_dropped, tcp_checksum_errors, tcp_connections, tcp_disconnections, tcp_connections_dropped, tcp_retransmit_packets; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Fast Disconnect Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Loop to establish 1000 connections, send one message, and disconnect. */ + while ((thread_0_counter < 1000) && (error_counter == 0)) + { + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup a receive notify function. */ + status = nx_tcp_socket_receive_notify(&client_socket, thread_0_receive_notify); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Pickup the port for the client socket. */ + status = nx_tcp_client_socket_port_get(&client_socket, &compare_port); + + /* Check for error. */ + if ((status) || (client_port != compare_port)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Determine if the status is valid. */ + if (status != NX_NOT_CONNECTED) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&client_socket, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + if((packets_sent != 1) || (bytes_sent != 28)) + error_counter++; +#endif + + /* Check for errors. */ + if ((error_counter) || (status) || (packets_received) || (bytes_received) || (retransmit_packets) || (packets_queued) || + (checksum_errors) || (socket_state != NX_TCP_CLOSED) || (transmit_queue_depth) || (receive_window != 200)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + } + + /* Get the overall TCP information. */ + status = nx_tcp_info_get(&ip_0, &tcp_packets_sent, &tcp_bytes_sent, &tcp_packets_received, &tcp_bytes_received, + &tcp_invalid_packets, &tcp_receive_packets_dropped, &tcp_checksum_errors, &tcp_connections, + &tcp_disconnections, &tcp_connections_dropped, &tcp_retransmit_packets); + +#ifndef NX_DISABLE_TCP_INFO + if((tcp_packets_sent != 1000) || (tcp_bytes_sent != 1000*28) || (tcp_connections != 1000) || (tcp_disconnections != 1000)) + error_counter++; +#endif + + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != 1000) || (thread_1_counter != 1000) || (connections != 1000) || (disconnections) || + (tcp_packets_received) || (tcp_bytes_received) || (tcp_invalid_packets) || (tcp_receive_packets_dropped) || (tcp_checksum_errors) || + (tcp_connections_dropped) || (tcp_retransmit_packets)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup a receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, thread_1_receive_notify); + + /* Check for error. */ + if (status) + error_counter++; + + /* Configure the socket further. */ + status = nx_tcp_socket_transmit_configure(&server_socket, 10, 300, 10, 0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Loop to create and establish server connections. */ + while((thread_1_counter < 1000) && (error_counter == 0)) + { + + /* Increment thread 1's counter. */ + thread_1_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + +#ifndef NX_DISABLE_RESET_DISCONNECT + if (status != NX_IN_PROGRESS) + error_counter++; +#endif + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; + else + connections++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; + else + disconnections++; +} + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket) +{ + + client_receives++; +} + + +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket) +{ + + server_receives++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_fast_disconnect_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Fast Disconnect Test..................................N/A\n"); + + test_control_return(3); + +} + +#endif diff --git a/test/regression/netxduo_test/netx_tcp_fast_retransmit_test.c b/test/regression/netxduo_test/netx_tcp_fast_retransmit_test.c new file mode 100644 index 00000000..8edfdda6 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_fast_retransmit_test.c @@ -0,0 +1,362 @@ +/* This NetX test concentrates on fast retransmit. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_f_r(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_fast_retransmit_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet1; + NX_PACKET *my_packet2; + NX_PACKET *my_packet3; + NX_PACKET *my_packet4; + char *msg = MSG; + + /* Print out test information banner. */ + printf("NetX Test: TCP Fast Retransmit Test.................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[20], 20); + my_packet2 -> nx_packet_length = 20; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet3 -> nx_packet_length = 20; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet4 -> nx_packet_prepend_ptr, &msg[60], 20); + my_packet4 -> nx_packet_length = 20; + my_packet4 -> nx_packet_append_ptr = my_packet4 -> nx_packet_prepend_ptr + 20; + + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_f_r; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Send the 2nd one */ + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Send the 3rd one */ + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Send the 4th one */ + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + + if(status) + { + error_counter++; + } + + /* Disable timeout retransmit. */ + client_socket.nx_tcp_socket_timeout = 60 * 60 * _nx_tcp_fast_timer_rate; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 80) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_relinquish(); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_f_r(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + nx_packet_release(packet_ptr); + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_fast_retransmit_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Fast Retransmit Test..................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_fin_wait1_to_time_wait_test.c b/test/regression/netxduo_test/netx_tcp_fin_wait1_to_time_wait_test.c new file mode 100644 index 00000000..4dc9ddc8 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_fin_wait1_to_time_wait_test.c @@ -0,0 +1,306 @@ +/* This NetX test concentrates on TCP state change from FIN-WIAT1 to TIME-WAIT. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void tcp_packet_receive_catch_fin(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void tcp_packet_receive_drop_ack(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_fin_wait1_to_time_wait_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP FIN-WAIT1 to TIME-WAIT Test..........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Let server thread send FIN first. */ + tx_thread_suspend(&thread_0); + + /* Check the state of server socket. */ + if (server_socket.nx_tcp_socket_state != NX_TCP_FIN_WAIT_1) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Check the state of server socket. */ + if (server_socket.nx_tcp_socket_state != NX_TCP_TIMED_WAIT) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Sleep 1 second to make sure client thread is suspended. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Inject FIN packet. */ + ip_0.nx_ip_tcp_packet_receive = tcp_packet_receive_catch_fin; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static VOID tcp_packet_receive_catch_fin(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Process FIN packet. */ + if (header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) + { + + /* Let client thread start to disconnect. */ + tx_thread_resume(&thread_0); + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Let server drop the ACK to prevent state FIN-WAIT2. */ + ip_1.nx_ip_tcp_packet_receive = tcp_packet_receive_drop_ack; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static void tcp_packet_receive_drop_ack(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Point to TCP header */ + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Process FIN packet. */ + if ((header_ptr -> nx_tcp_header_word_3 & NX_TCP_CONTROL_MASK) == NX_TCP_ACK_BIT) + { + + /* Drop the ACK packet. . */ + nx_packet_release(packet_ptr); + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + return; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_fin_wait1_to_time_wait_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: TCP FIN-WAIT1 to TIME-WAIT Test...........................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_tcp_fin_wait_recv_test.c b/test/regression/netxduo_test/netx_tcp_fin_wait_recv_test.c new file mode 100644 index 00000000..c3d2bcb4 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_fin_wait_recv_test.c @@ -0,0 +1,300 @@ +/* This NetX test concentrates on receiving retransmitted packet when FIN is received at FIN_WAIT1/FIN_WAIT2 state. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#define DEMO_STACK_SIZE 2048 + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static NX_PACKET *operation_packet; +static CHAR *test_buffer = "ABCDEFGH"; +static UCHAR recv_buffer[10]; +static ULONG recv_len; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_fin_wait_recv_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; +ULONG pool_size; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + recv_len = 0; + operation_packet = NX_NULL; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + pool_size = (sizeof(NX_PACKET) + 256) * 16; + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, pool_size); + pointer = pointer + pool_size; + + if (status) + error_counter++; + + /* Create a packet pool. */ + pool_size = (sizeof(NX_PACKET) + 256) * 16; + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 256, pointer, pool_size); + pointer = pointer + pool_size; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out test information banner. */ + printf("NetX Test: TCP receive on FIN_WAIT1 and FIN_WAIT2 state.............."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 500); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup callback function to drop packets once. */ + advanced_packet_process_callback = my_packet_process; + + nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + nx_packet_data_append(my_packet, test_buffer, strlen(test_buffer), &pool_0, NX_WAIT_FOREVER); + + operation_packet = my_packet; + nx_tcp_socket_send(&client_socket, my_packet, NX_WAIT_FOREVER); + + /* Make sure peer send FIN first so peer will enter FIN_WAIT1 state. */ + tx_thread_relinquish(); + + /* Disconnect immediately. */ + nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 500); + + /* Check for error. */ + if (status) + error_counter++; + + /* Let thread 2 start to receive. */ + tx_thread_resume(&thread_2); + + /* Disconnect immediately. */ + nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check received data. */ + if(recv_len != strlen(test_buffer)) + { + error_counter++; + } + else if(memcmp(test_buffer, recv_buffer, recv_len)) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_2_entry(ULONG thread_input) +{ +NX_PACKET *packet_ptr; + + /* Receive one packet. */ + if (nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER)) + { + error_counter++; + } + else + { + + /* Retrieve data from packet. */ + nx_packet_data_retrieve(packet_ptr, recv_buffer, &recv_len); + nx_packet_release(packet_ptr); + } +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + if(packet_ptr == operation_packet) + { + operation_packet = NX_NULL; + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_fin_wait_recv_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP receive on FIN_WAIT1 and FIN_WAIT2 state..............N/A\n"); + test_control_return(2); +} +#endif /* NX_TCP_MAX_OUT_OF_ORDER_PACKETS */ diff --git a/test/regression/netxduo_test/netx_tcp_invalid_length_test.c b/test/regression/netxduo_test/netx_tcp_invalid_length_test.c new file mode 100644 index 00000000..c708691c --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_invalid_length_test.c @@ -0,0 +1,222 @@ +/* This NetX test concentrates on the code coverage for TCP functions, + * _nx_tcp_packet_receive.c + */ + +#include "nx_api.h" +#include "tx_thread.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_packet.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_RX_SIZE_CHECKING) + +#define DEMO_STACK_SIZE 2048 +#define ASSERT_THREAD_COUNT 1 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET tcp_socket; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UCHAR pool_area[102400]; + +/* TCP packet. 192.168.100.23:6206 -> 192.168.100.4:80 */ +/* Invalid TCP length. */ +static unsigned char pkt1[54] = { +0x00, 0x1e, 0x8f, 0xb1, 0x7a, 0xd4, 0xf4, 0x8e, /* ....z... */ +0x38, 0xa3, 0x25, 0xb3, 0x08, 0x00, 0x45, 0x00, /* 8.%...E. */ +0x00, 0x28, 0x10, 0x9d, 0x00, 0x00, 0x80, 0x06, /* .(...... */ +0xe0, 0xc6, 0xc0, 0xa8, 0x64, 0x17, 0xc0, 0xa8, /* ....d... */ +0x64, 0x04, 0x18, 0x3e, 0x00, 0x50, 0x62, 0xf3, /* d..>.Pb. */ +0xa5, 0x46, 0x54, 0x7e, 0x0c, 0xe7, 0x40, 0x10, /* .FT~..P. */ +0x01, 0x00, 0xf3, 0x3a, 0x00, 0x00 /* ...:.. */ +}; + +/* TCP packet. 192.168.100.23:6206 -> 192.168.100.4:80 */ +/* Invalid TCP length. */ +static unsigned char pkt2[54] = { +0x00, 0x1e, 0x8f, 0xb1, 0x7a, 0xd4, 0xf4, 0x8e, /* ....z... */ +0x38, 0xa3, 0x25, 0xb3, 0x08, 0x00, 0x45, 0x00, /* 8.%...E. */ +0x00, 0x28, 0x10, 0x9d, 0x00, 0x00, 0x80, 0x06, /* .(...... */ +0xe0, 0xc6, 0xc0, 0xa8, 0x64, 0x17, 0xc0, 0xa8, /* ....d... */ +0x64, 0x04, 0x18, 0x3e, 0x00, 0x50, 0x62, 0xf3, /* d..>.Pb. */ +0xa5, 0x46, 0x54, 0x7e, 0x0c, 0xe7, 0x60, 0x10, /* .FT~..P. */ +0x01, 0x00, 0xd3, 0x3a, 0x00, 0x00 /* ...:.. */ +}; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_invalid_length_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Print out some test information banners. */ + printf("NetX Test: TCP Invalid Length Test..................................."); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pool_area, sizeof(pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for IP instance. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; + + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &tcp_socket, "TCP Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&tcp_socket, 80, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + nx_ip_address_set(&ip_0, IP_ADDRESS(192,168,100,4), 0xFFFFFF00); + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(192,168,100,4); + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt1[14], sizeof(pkt1) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt1) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + + /* Inject TCP packet. */ + nx_packet_allocate(&pool_0, &packet_ptr, NX_PHYSICAL_HEADER, NX_WAIT_FOREVER); + + /* Fill in the packet with data. Skip the MAC header. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr, &pkt2[14], sizeof(pkt2) - 14); + packet_ptr -> nx_packet_length = sizeof(pkt2) - 14; + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&ip_0, packet_ptr); + +#ifndef NX_DISABLE_TCP_INFO + if (ip_0.nx_ip_tcp_invalid_packets != 2) + error_counter++; +#endif /* NX_DISABLE_ICMP_INFO */ + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_invalid_length_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Invalid Length Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_invalid_option_test.c b/test/regression/netxduo_test/netx_tcp_invalid_option_test.c new file mode 100644 index 00000000..a9a45477 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_invalid_option_test.c @@ -0,0 +1,492 @@ +/* This NetX test concentrates on the TCP Socket relisten operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#include "nx_tcp.h" +#include "nx_ip.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +#define CLIENT_PORT 0x88 +#define SERVER_PORT 0x89 + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT fin_counter = 0; +static UINT rst_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static VOID inject_invalid_option(); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_invalid_option_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + /* Check the status. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check the status. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Invalid Option Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, CLIENT_PORT, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to establish connection. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the client and server socket state. */ + if ((client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) || (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Inject invalid option with invalid SEQ and ACK. */ + /* The receiver is expected to drop the packet. */ + inject_invalid_option(); + + /* Check the client and server socket state. */ + if ((client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) || (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + advanced_packet_process_callback = my_packet_process; + + /* Call connect to send a SYN */ + status = nx_tcp_socket_disconnect(&client_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the client and server socket state. */ +#ifdef __PRODUCT_NETXDUO__ + if ((client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) || (server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE)) +#else + if ((client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) || (server_socket.nx_tcp_socket_state != NX_TCP_CLOSED)) +#endif + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if ((error_counter) || (fin_counter != 1) || (rst_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; +} + +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word; +ULONG checksum; +ULONG *source_ip, *dest_ip; + + /* Set the tcp header pointer. */ + tcp_header_ptr = (NX_TCP_HEADER *) packet_ptr ->nx_packet_prepend_ptr; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a FIN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_FIN_BIT) && + (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + + /* Update the fin_counter. */ + fin_counter++; + + /* Add the option. */ + option_word = (ULONG *) (packet_ptr ->nx_packet_prepend_ptr + 20 ); + + /* Add the invalid MSS option. */ + *option_word = 0x02030000 | 536; + NX_CHANGE_ULONG_ENDIAN(*option_word); + + /* Update the option word pointer. */ + option_word ++; + *option_word = NX_TCP_OPTION_END; + NX_CHANGE_ULONG_ENDIAN(*option_word); + + /* The ACK must be set or else the packet is dropped before parsing TCP option. */ +#if 0 + /* Clean the ACK bit. */ + tcp_header_ptr -> nx_tcp_header_word_3 = (tcp_header_ptr -> nx_tcp_header_word_3 & (~NX_TCP_ACK_BIT)); +#endif + + /* Update the TCP header length. */ + tcp_header_ptr -> nx_tcp_header_word_3 += 0x20000000; + + /* Update the packet length. */ + packet_ptr -> nx_packet_length += 8; + packet_ptr -> nx_packet_append_ptr += 8; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Clear the checksum field. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + /* Calculate the checksum . */ +#ifdef __PRODUCT_NETXDUO__ + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#else + checksum = _nx_tcp_checksum(packet_ptr, client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address, client_socket.nx_tcp_socket_connect_ip); +#endif + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + } + else + { + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + } + + /* Clear the callback function. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Set the TCP header pointer. */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a RST packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + + /* It is a RST packet. */ + rst_counter++; + + /* Clear the callback. */ + advanced_packet_process_callback = NX_NULL; + } + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +static VOID inject_invalid_option() +{ +NX_PACKET *packet_ptr; +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word; +ULONG checksum; +#ifdef __PRODUCT_NETXDUO__ +ULONG *source_ip, *dest_ip; +#endif + + if (nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_IP_PERIODIC_RATE)) + { + error_counter++; + return; + } + + /* Construct TCP header with invalid SEQ and ACK. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_0 = (((ULONG)(client_socket.nx_tcp_socket_port)) << NX_SHIFT_BY_16) | (ULONG)client_socket.nx_tcp_socket_connect_port; + tcp_header_ptr -> nx_tcp_sequence_number = 0; + tcp_header_ptr -> nx_tcp_acknowledgment_number = 0; + tcp_header_ptr -> nx_tcp_header_word_3 = NX_TCP_SYN_HEADER | NX_TCP_ACK_BIT | NX_TCP_PSH_BIT | 200; + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + /* Add invalid TCP option. */ + option_word = (ULONG *)(packet_ptr ->nx_packet_prepend_ptr + 20); + + /* Add the invalid MSS option. */ + *option_word = 0x02030000 | 536; + NX_CHANGE_ULONG_ENDIAN(*option_word); + + /* Update the option word pointer. */ + option_word ++; + *option_word = NX_TCP_OPTION_END; + NX_CHANGE_ULONG_ENDIAN(*option_word); + + /* Setup the packet payload pointers and length for a basic TCP packet. */ + packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_TCP_HEADER) + 8; + + /* Setup the packet length. */ + packet_ptr -> nx_packet_length = sizeof(NX_TCP_HEADER) + 8; + + + /* Write ABCs into the packet payload! */ + if (nx_packet_data_append(packet_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE)) + { + nx_packet_release(packet_ptr); + error_counter++; + return; + } + + /* Calculate the checksum . */ +#ifdef __PRODUCT_NETXDUO__ + packet_ptr -> nx_packet_address.nx_packet_interface_ptr = client_socket.nx_tcp_socket_connect_interface; + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#else + packet_ptr -> nx_packet_ip_interface = client_socket.nx_tcp_socket_connect_interface; + packet_ptr -> nx_packet_next_hop_address = client_socket.nx_tcp_socket_next_hop_address; + checksum = _nx_tcp_checksum(packet_ptr, packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address, client_socket.nx_tcp_socket_connect_ip); +#endif + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + /* Send the TCP packet. */ + tx_mutex_get(&(ip_0.nx_ip_protection), TX_WAIT_FOREVER); +#ifdef __PRODUCT_NETXDUO__ + _nx_ip_packet_send(&ip_0, packet_ptr, client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4, + client_socket.nx_tcp_socket_type_of_service, client_socket.nx_tcp_socket_time_to_live, NX_IP_TCP, + client_socket.nx_tcp_socket_fragment_enable, + client_socket.nx_tcp_socket_next_hop_address); +#else + _nx_ip_packet_send(&ip_0, packet_ptr, client_socket.nx_tcp_socket_connect_ip, + client_socket.nx_tcp_socket_type_of_service, client_socket.nx_tcp_socket_time_to_live, NX_IP_TCP, + client_socket.nx_tcp_socket_fragment_enable); +#endif + + tx_mutex_put(&(ip_0.nx_ip_protection)); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_invalid_option_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Invalid Option Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_invalid_option_test2.c b/test/regression/netxduo_test/netx_tcp_invalid_option_test2.c new file mode 100644 index 00000000..2677b21e --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_invalid_option_test2.c @@ -0,0 +1,459 @@ +/* This NetX test concentrates on the invalid TCP option when the ACK bit is not set. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#include "nx_tcp.h" +#include "nx_ip.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +#define CLIENT_PORT 0x88 +#define SERVER_PORT 0x89 + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT rst_counter = 0; +static UINT hacked_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_invalid_option_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + /* Check the status. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check the status. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Invalid Option Test2.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Set the callback function. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + advanced_packet_process_callback = my_packet_process; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to establish connection. */ + /* The received SYN+ACK is modified to clean ACK bit and invalid option length. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_CONNECTED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Cleanup TCP socket. */ + nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&client_socket); + + tx_thread_sleep(NX_IP_PERIODIC_RATE * 2); + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + advanced_packet_process_callback = my_packet_process; + + /* Call connect to establish connection. */ + /* The received SYN+ACK is modified to FIN packet without ACK bit and invalid option length. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_CONNECTED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Cleanup TCP socket. */ + nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&client_socket); + + tx_thread_sleep(NX_IP_PERIODIC_RATE * 2); + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function. */ + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + advanced_packet_process_callback = my_packet_process; + + /* Call connect to establish connection. */ + /* The received SYN+ACK is modified clear all bits and invalid option length. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_CONNECTED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Cleanup TCP socket. */ + nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + nx_tcp_client_socket_unbind(&client_socket); + + tx_thread_sleep(NX_IP_PERIODIC_RATE * 2); + + /* Check status. */ + if ((error_counter) || (rst_counter != 3)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + + /* Clear TCP socket. */ + nx_tcp_server_socket_unaccept(&server_socket); + + /* Relisten for next round. */ + nx_tcp_server_socket_relisten(&ip_1, SERVER_PORT, &server_socket); + + /* Accept a client socket connection. */ + nx_tcp_server_socket_accept(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + + /* Clear TCP socket. */ + nx_tcp_server_socket_unaccept(&server_socket); + + /* Relisten for next round. */ + nx_tcp_server_socket_relisten(&ip_1, SERVER_PORT, &server_socket); + + /* Accept a client socket connection. */ + nx_tcp_server_socket_accept(&server_socket, 2 * NX_IP_PERIODIC_RATE); +} + +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word; +ULONG checksum; +ULONG *source_ip, *dest_ip; + + /* Set the tcp header pointer. */ + tcp_header_ptr = (NX_TCP_HEADER *) packet_ptr ->nx_packet_prepend_ptr; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is an SYN+ACK packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && + (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT)) + { + + /* Add the option. */ + option_word = (ULONG *) (packet_ptr ->nx_packet_prepend_ptr + 20 ); + + /* Add the invalid MSS option. */ + *option_word = 0x02030000 | 536; + NX_CHANGE_ULONG_ENDIAN(*option_word); + + /* Update the option word pointer. */ + option_word ++; + *option_word = NX_TCP_OPTION_END; + NX_CHANGE_ULONG_ENDIAN(*option_word); + + /* Clear ACK bit. */ + tcp_header_ptr -> nx_tcp_header_word_3 &= ~NX_TCP_ACK_BIT; + + if (hacked_counter == 1) + { + + /* Clear SYN bit and set FIN bit. */ + tcp_header_ptr -> nx_tcp_header_word_3 &= ~NX_TCP_SYN_BIT; + tcp_header_ptr -> nx_tcp_header_word_3 |= NX_TCP_FIN_BIT; + } + else if (hacked_counter == 2) + { + + /* Clear SYN bit. */ + tcp_header_ptr -> nx_tcp_header_word_3 &= ~NX_TCP_SYN_BIT; + } + hacked_counter++; + + /* Update the TCP header length. */ + tcp_header_ptr -> nx_tcp_header_word_3 += 0x20000000; + + /* Update the packet length. */ + packet_ptr -> nx_packet_length += 8; + packet_ptr -> nx_packet_append_ptr += 8; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Clear the checksum field. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + /* Calculate the checksum . */ +#ifdef __PRODUCT_NETXDUO__ + dest_ip = &server_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &server_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; +#else + checksum = _nx_tcp_checksum(packet_ptr, server_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address, server_socket.nx_tcp_socket_connect_ip); +#endif + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + } + else + { + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + } + + /* Clear the callback function. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Set the TCP header pointer. */ + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if it is a RST packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT) + { + + /* It is a RST packet. */ + rst_counter++; + + /* Clear the callback. */ + advanced_packet_process_callback = NX_NULL; + } + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_invalid_option_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Invalid Option Test2..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_invalid_packet_chain_test.c b/test/regression/netxduo_test/netx_tcp_invalid_packet_chain_test.c new file mode 100644 index 00000000..705fcae3 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_invalid_packet_chain_test.c @@ -0,0 +1,397 @@ +/* This NetX test concentrates on the TCP header span in multiple packets. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_RX_SIZE_CHECKING) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UINT client_port; +static ULONG packet_offset; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static UINT my_advanced_packet_process_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_invalid_packet_chain_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT compare_port; +ULONG mss, peer_mss, peer_ip_address, peer_port, bytes_available; +ULONG tcp_packets_sent, tcp_bytes_sent, tcp_packets_received, tcp_bytes_received, tcp_invalid_packets, tcp_receive_packets_dropped, tcp_checksum_errors, tcp_connections, tcp_disconnections, tcp_connections_dropped, tcp_retransmit_packets; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; +ULONG window_size = 200; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Invalid Packet Chain Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set callback function in network driver to bypass dispatch in network driver. */ + advanced_packet_process_callback = my_advanced_packet_process_callback; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, window_size, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Set offset to 20. The size of TCP plus IP header is larger than 40. + This packet can not be processed by TCP. */ + packet_offset = 20; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status == NX_SUCCESS) + error_counter++; + + /* Set offset to 40. Since size of SYN more than 20, with IP header, the total size is larger than 40. + This packet can not be processed by TCP. */ + packet_offset = 40; + + /* Attempt to connect the socket again. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status == NX_SUCCESS) + error_counter++; + + /* Set offset to 80. This packet can be processed by TCP. */ + packet_offset = 80; + + /* Attempt to connect the socket again. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check for errors. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; +} + +static UINT my_advanced_packet_process_callback(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_PACKET *packet_copy_ptr; + + if (ip_ptr != &ip_0) + { + + /* Handle packets from IP 0 only. */ + return(NX_TRUE); + } + + /* Check if this is an IPv4 packet. */ + if ((*(packet_ptr -> nx_packet_prepend_ptr) != 0x45) || (packet_ptr -> nx_packet_next)) + { + + /* Handle IPv4 packets only. */ + return(NX_TRUE); + } + + /* Allocate a packet with insufficient space for TCP header in first packet. */ + if (nx_packet_allocate(&pool_0, &packet_copy_ptr, + (pool_0.nx_packet_pool_payload_size - packet_offset) & 0xFFFFFFFC, NX_NO_WAIT)) + { + error_counter++; + return(NX_TRUE); + } + + /* Copy data into packet. */ + if (nx_packet_data_append(packet_copy_ptr, packet_ptr -> nx_packet_prepend_ptr, + packet_ptr -> nx_packet_length, &pool_0, NX_NO_WAIT)) + { + error_counter++; + nx_packet_release(packet_copy_ptr); + return(NX_TRUE); + } + _nx_ip_packet_deferred_receive(&ip_1, packet_copy_ptr); + + /* Let network driver to drop this packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + return(NX_TRUE); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_invalid_packet_chain_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Invalid Packet Chain Test.............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_ipv4_interface2_mss_test.c b/test/regression/netxduo_test/netx_tcp_ipv4_interface2_mss_test.c new file mode 100644 index 00000000..75cb0790 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_ipv4_interface2_mss_test.c @@ -0,0 +1,336 @@ +/* This NetX test use the second interface send a larger packet with IPv4 address + to test the TCP MSS process procedure. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#include "nx_tcp.h" +#include "nx_ip.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static CHAR rcv_buffer[600]; +static INT recv_length = 0; + +static CHAR msg[600]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ipv4_interface2_mss_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += _nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2,2,3,4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + status += nx_ip_interface_attach(&ip_1, "Second Interface", IP_ADDRESS(2,2,3,5), 0xFFFFFF00UL, _nx_ram_network_driver_512); + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ +#ifdef __PRODUCT_NETXDUO__ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); +#else + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); +#endif /* __PRODUCT_NETXDUO__ */ + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet1; + UINT i; + + /* Use random number generator to fill the outgoing packet. */ + for(i = 0; i < 600; i++) + { + msg[i] = rand(); + } + + /* Print out test information banner. */ + printf("NetX Test: TCP IPv4 Interface2 MSS Test.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 600, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + /* Determine if the timeout error occurred. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect. */ + status = _nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(2,2,3,5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check for error. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Point to new receive function */ + ip_1.nx_ip_tcp_packet_receive = packet_receive; + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 550); + my_packet1 -> nx_packet_length = 550; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 550; + + /* Check for error. */ + if(status) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + my_packet1 -> nx_packet_ip_version = NX_IP_VERSION_V4; +#endif /* __PRODUCT_NETXDUO__ */ + + /* Send the packet. */ + status += nx_tcp_socket_send(&client_socket, my_packet1, 2 * NX_IP_PERIODIC_RATE); + + tx_thread_relinquish(); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 650, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + +} + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + UINT length; + + /* Data length equal to packet length - 20. */ + length = packet_ptr -> nx_packet_length - 20; + + if(length > client_socket.nx_tcp_socket_connect_mss) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Copy the packet. */ + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr + 20, length); + recv_length += length; + + /* Check whether or not the last packet. */ + if(length < client_socket.nx_tcp_socket_connect_mss) + { + + /* The packet is the last packet, compare the packet and receive_length. */ + if(memcmp(rcv_buffer,msg,packet_ptr -> nx_packet_length) || recv_length != 550) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Point to default function. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + } + + /* Set client_socket's outstanding bytes to 0. */ + client_socket.nx_tcp_socket_tx_outstanding_bytes = 0; + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ipv4_interface2_mss_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP IPv4 Interface2 MSS Test..............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_ipv6_basic_processing_test.c b/test/regression/netxduo_test/netx_tcp_ipv6_basic_processing_test.c new file mode 100644 index 00000000..018f40b0 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_ipv6_basic_processing_test.c @@ -0,0 +1,546 @@ +/* This NetX test use the second interface send a larger packet with IPv6 address + to test the TCP MSS process procedure. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#ifdef FEATURE_NX_IPV6 +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ipv6_basic_processing_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += _nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; +NXD_ADDRESS peer_address; +ULONG peer_port; +ULONG mss; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + /* Print out test information banner. */ + printf("NetX Test: TCP IPv6 Basic Processing Test............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + /* Get the peer socket info before connection established, should be fail. */ + status = nxd_tcp_socket_peer_info_get(&client_socket, &peer_address, &peer_port); + + /* Check for error. */ + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Call connect to send a SYN */ + status = nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_2, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Get the socket mss. */ + status = nx_tcp_socket_mss_get(&client_socket, &mss); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get the peer socket info. */ + status = nxd_tcp_socket_peer_info_get(&client_socket, &peer_address, &peer_port); + + /* Check for error. */ + if(status) + error_counter++; + + /* Check the peer address and peer port. */ + if((peer_port != 12) || + (peer_address.nxd_ip_version != NX_IP_VERSION_V6) || + (peer_address.nxd_ip_address.v6[0] != 0x20010000) || + (peer_address.nxd_ip_address.v6[1] != 0x00000000) || + (peer_address.nxd_ip_address.v6[2] != 0x00000000) || + (peer_address.nxd_ip_address.v6[3] != 0x10000002)) + error_counter++; + + /* Send the packet to server. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_IPv6_TCP_PACKET, NX_WAIT_FOREVER); + + if(status) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + my_packet -> nx_packet_ip_version = NX_IP_VERSION_V6; + +#ifndef NX_DISABLE_ERROR_CHECKING + /* Modify the ip version of connect address. */ + client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = 0; + + /* Send the packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* It must fail since ip version is invalid. */ + if (status != NX_NOT_CONNECTED) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + client_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V6; + + /* Delete the Ipv6 address. */ + nxd_ipv6_address_delete(&ip_0, 0); + + /* Send the packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* It must fail since address is invalid. */ + if (status != NX_NO_INTERFACE_ADDRESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the address. */ + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + + /* Wait 5 seconds for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Send packet */ + status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Get the peer socket info before connection established, should be fail. */ + status = nxd_tcp_socket_peer_info_get(&client_socket, &peer_address, &peer_port); + + /* Check for error. */ + if(status != NX_NOT_CONNECTED) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get information about this socket. */ + status = nx_tcp_socket_info_get(&client_socket, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + +#ifndef NX_DISABLE_TCP_INFO + + if((packets_sent != 1) || (bytes_sent != 28)) + error_counter++; +#endif + + /* Check for errors. */ + if ((error_counter) || (status) || (packets_received) || (bytes_received) || + (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) || + (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + tx_thread_relinquish(); + + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if(status) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + ULONG actual_status; + NX_PACKET *packet_ptr; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Inject the SYN packet. */ + ip_1.nx_ip_tcp_packet_receive = tcp_packet_receive; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + +} + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_IPV6_HEADER *ipv6_header; +NX_PACKET *loopback_src_port; +NX_PACKET *broadcast_source; +ULONG broadcast[4] = {0xFF020000, 0, 0, 0x01}; +ULONG checksum; +ULONG *source_ip, *dest_ip; +NX_TCP_HEADER *tcp_header_ptr; + + /* Set the source IP equal to destination IP. Verify whether or not system crashes. */ + + /* Copy from the original packet. */ + nx_packet_copy(packet_ptr, &loopback_src_port, &pool_0, NX_NO_WAIT); + + /* Get IPv6 header. */ + ipv6_header = (NX_IPV6_HEADER *)loopback_src_port -> nx_packet_ip_header; + + /* Copy the dest ip to source ip field. */ + COPY_IPV6_ADDRESS(ipv6_header -> nx_ip_header_destination_ip, + ipv6_header -> nx_ip_header_source_ip); + + /* Calculate the checksum. */ + source_ip = ipv6_header -> nx_ip_header_source_ip; + dest_ip = ipv6_header -> nx_ip_header_destination_ip; + tcp_header_ptr = (NX_TCP_HEADER *) loopback_src_port -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + checksum = _nx_ip_checksum_compute(loopback_src_port, NX_PROTOCOL_TCP, + loopback_src_port -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + /* Pass the packet. */ + _nx_tcp_packet_receive(ip_ptr, loopback_src_port); + +#ifndef NX_DISABLE_TCP_INFO + if (ip_ptr -> nx_ip_tcp_invalid_packets != 1) + error_counter++; +#endif /* NX_DISABLE_TCP_INFO */ + + /* Copy from the original packet. */ + nx_packet_copy(packet_ptr, &broadcast_source, &pool_0, NX_NO_WAIT); + + /* Get IPv6 header. */ + ipv6_header = (NX_IPV6_HEADER *)broadcast_source -> nx_packet_ip_header; + + /* Copy the broadcast address to source IP field. */ + COPY_IPV6_ADDRESS(broadcast, ipv6_header -> nx_ip_header_source_ip); + + /* Calculate the checksum. */ + source_ip = ipv6_header -> nx_ip_header_source_ip; + dest_ip = ipv6_header -> nx_ip_header_destination_ip; + tcp_header_ptr = (NX_TCP_HEADER *)broadcast_source -> nx_packet_prepend_ptr; + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + checksum = _nx_ip_checksum_compute(broadcast_source, NX_PROTOCOL_TCP, + broadcast_source -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + /* Pass the packet. */ + _nx_tcp_packet_receive(ip_ptr, broadcast_source); + +#ifndef NX_DISABLE_TCP_INFO + if (ip_ptr -> nx_ip_tcp_invalid_packets != 2) + error_counter++; +#endif /* NX_DISABLE_TCP_INFO */ + + /* Restore tcp receive function pointer. */ + ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Pass the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ipv6_basic_processing_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP IPv6 Basic Processing Test............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_ipv6_delayed_retransmission_test.c b/test/regression/netxduo_test/netx_tcp_ipv6_delayed_retransmission_test.c new file mode 100644 index 00000000..05a94165 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_ipv6_delayed_retransmission_test.c @@ -0,0 +1,390 @@ +/* This NetX test concentrates on delayed retransmission TCP packet. + * 1. Send packet A. + * 2. Drop packet A in driver. + * 3. Send packet B, C and D. + * 4. Retransmit packet A. + * 5. Copy the data in A and transmit it. Delay packet A for 1 seconds. + * 6. Wait 2 seconds. + * 7. Check all packets are released. + * 8. Check no invalid packet released. */ + +#include "nx_api.h" +extern void test_control_return(UINT status); + +#ifdef FEATURE_NX_IPV6 +#include "nx_ram_network_driver_test_1500.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static NXD_ADDRESS ipv6_address_0; +static NXD_ADDRESS ipv6_address_1; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + +static NX_PACKET *drop_packet; +static NX_PACKET *duplicate_packet; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ipv6_delayed_retransmission_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + drop_packet = NX_NULL; + duplicate_packet = NX_NULL; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_0.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_0.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_0.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_0.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_1, 64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Enable ICMP for IP Instance 0 and 1. */ + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: TCP IPv6 Delayed Retransmission Test......................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_1, 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Set driver packet process callback. */ + advanced_packet_process_callback = packet_process; + + for (i = 0; i < 4; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "A", 1, &pool_0, NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + if (i == 0) + { + + /* Drop the first packet. */ + drop_packet = my_packet; + } + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + /* Wait two seconds. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Verify all packets are released from TX queue. */ + if (client_socket.nx_tcp_socket_tx_outstanding_bytes != 0) + error_counter++; + + /* Verify pool is full. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + error_counter++; + +#ifndef NX_DISABLE_PACKET_INFO + /* Verify no packet is released invalid. */ + if (pool_0.nx_packet_pool_invalid_releases != 0) + error_counter++; +#endif /* NX_DISABLE_PACKET_INFO */ + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +UINT i; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + for (i = 0; i < 4; i++) + { + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, "A", 1)) + error_counter++; + + nx_packet_release(packet_ptr); + } + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + if (packet_ptr == drop_packet) + { + + /* This packet should be dropped. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + /* Duplicate this packet next time. */ + duplicate_packet = drop_packet; + drop_packet = NX_NULL; + } + else if (packet_ptr == duplicate_packet) + { + + /* This packet should be duplicated and delayed for 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + if (nx_packet_allocate(&pool_0, &duplicate_packet, 16, NX_NO_WAIT) == NX_SUCCESS) + { + + /* Copy data from original packet. */ + memcpy(duplicate_packet -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_prepend_ptr, + packet_ptr -> nx_packet_length); + duplicate_packet -> nx_packet_length = packet_ptr -> nx_packet_length; + duplicate_packet -> nx_packet_append_ptr += duplicate_packet -> nx_packet_length; + + /* Let IP 0 receive the packet. */ + _nx_ip_packet_deferred_receive(&ip_1, duplicate_packet); + } + else + { + error_counter++; + } + + duplicate_packet = NX_NULL; + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ipv6_delayed_retransmission_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP IPv6 Delayed Retransmission Test......................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_ipv6_interface2_mss_test.c b/test/regression/netxduo_test/netx_tcp_ipv6_interface2_mss_test.c new file mode 100644 index 00000000..e08475d6 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_ipv6_interface2_mss_test.c @@ -0,0 +1,379 @@ +/* This NetX test use the second interface send a larger packet with IPv6 address + to test the TCP MSS process procedure. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES > 1) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static CHAR rcv_buffer[600]; +static INT recv_length = 0; + +static CHAR msg[600]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +static NXD_ADDRESS ipv6_address_3; +static NXD_ADDRESS ipv6_address_4; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ipv6_interface2_mss_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += _nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_512); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_512); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet1; + int i; + + for(i=0;i<600;i++) + { + msg[i]=rand(); + } + + /* Print out test information banner. */ + printf("NetX Test: TCP IPv6 Interface2 MSS Test.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 600, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + /* Determine if the timeout error occurred. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to send a SYN */ + status = _nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_4, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Point to new receive function */ + ip_1.nx_ip_tcp_packet_receive = packet_receive; + + status = nx_packet_allocate(&pool_0, &my_packet1, NX_IPv6_TCP_PACKET, NX_WAIT_FOREVER); + + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* create packet */ + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 550); + my_packet1 -> nx_packet_length = 550; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 550; + my_packet1 -> nx_packet_ip_version = NX_IP_VERSION_V6; + + /* Check for error. */ + if(status) + error_counter++; + + /* Send packet */ + status += nx_tcp_socket_send(&client_socket, my_packet1, 2 * NX_IP_PERIODIC_RATE); + + tx_thread_relinquish(); + + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if(status) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + ULONG actual_status; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 650, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + +} + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + UINT length; + + /* Data length equal to packet length - 20 */ + length = packet_ptr -> nx_packet_length - 20; + + if(length > client_socket.nx_tcp_socket_connect_mss) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Copy the packet */ + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr + 20, length); + recv_length += length; + + /* Check whether or not the last packet */ + if(length < client_socket.nx_tcp_socket_connect_mss) + { + /* The packet is the lastest packet, compare the packet and receive_length */ + if(memcmp(rcv_buffer,msg,packet_ptr -> nx_packet_length) || recv_length != 550) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Point to default function */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + } + + /* Set client_socket's outstangding bytes to 0 */ + client_socket.nx_tcp_socket_tx_outstanding_bytes = 0; + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); + +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ipv6_interface2_mss_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP IPv6 Interface2 MSS Test..............................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_ipv6_window_scale_test.c b/test/regression/netxduo_test/netx_tcp_ipv6_window_scale_test.c new file mode 100644 index 00000000..e7a82aad --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_ipv6_window_scale_test.c @@ -0,0 +1,361 @@ +/* This NetX test to test the TCP window scale with IPv6 address. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && defined(NX_ENABLE_TCP_WINDOW_SCALING) && (NX_MAX_PHYSICAL_INTERFACES > 1) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" + +#define MSG "----------abcdefgh20----------ABCDEFGH40----------klmnopqr60----------KLMNOPQR80----------" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; +NXD_ADDRESS ipv6_address_5; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ipv6_window_scale_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += _nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_512); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_512); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + ipv6_address_5.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_5.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_5.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_5.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_5.nxd_ip_address.v6[3] = 0x10000005; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2,64, NX_NULL); + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3,64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4,64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + /* Check ICMP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet; + char *msg = MSG; + + /* Print out test information banner. */ + printf("NetX Test: TCP ipv6 window scale Test................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 66000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + /* Determine if the timeout error occurred. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to send a SYN */ + status = _nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_4, 12, 5 * NX_IP_PERIODIC_RATE); + + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check WINDOW SCALE information */ + if(server_socket.nx_tcp_rcv_win_scale_value != 1 || client_socket.nx_tcp_rcv_win_scale_value != 1 || server_socket.nx_tcp_socket_tx_window_advertised != 66000) + { + error_counter ++; + } + + /* Create a packet */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Fill in the packet with data */ + memcpy(my_packet -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet -> nx_packet_length = 20; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 20; + + /* Send the my_packet */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + tx_thread_relinquish(); + + /* Check status */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the information about WINDOW SCALE */ + if(server_socket.nx_tcp_socket_tx_window_advertised != 66000 || client_socket.nx_tcp_socket_tx_window_advertised != 65980) + { + error_counter ++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + ULONG actual_status; + NX_PACKET *my_packet1; + char *msg = MSG; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 66000, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Create a packet */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check the status */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Fill in the packet with data */ + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + /* Send the my_packet1 */ + status = nx_tcp_socket_send(&server_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Check the status */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + +} + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_ipv6_window_scale_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP ipv6 window scale Test................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_keepalive_test.c b/test/regression/netxduo_test/netx_tcp_keepalive_test.c new file mode 100644 index 00000000..4e61b091 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_keepalive_test.c @@ -0,0 +1,302 @@ +/* This NetX test concentrates on the basic TCP Keepalive operation. + keepalive expiration time is 60s, + After initial expiration, retry every 10s, + Retry a maximum of 10 tims. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(NX_ENABLE_TCP_KEEPALIVE) && (NX_TCP_KEEPALIVE_INITIAL == 60) && (NX_TCP_KEEPALIVE_RETRY == 10) && (NX_TCP_KEEPALIVE_RETRIES == 10) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static ULONG ip_0_ack_counter = 0; +static ULONG ip_1_ack_counter = 0; +static ULONG ip_0_rst_counter = 0; +static ULONG ip_1_rst_counter = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_0_disconnect_received(NX_TCP_SOCKET *server_socket); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_keepalive_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Keepalive Test........................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_0_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 11, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Set the callback function to detect the socket keepalive packet. */ + advanced_packet_process_callback = my_packet_process; + + /* Waiting for keepalive message. */ + tx_thread_sleep(200 * NX_IP_PERIODIC_RATE); + + /* Check the socket state. */ +#ifdef __PRODUCT_NETXDUO__ + if ((client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) || (server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE)) +#else + if ((client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) || (server_socket.nx_tcp_socket_state != NX_TCP_CLOSED)) +#endif + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the counter. */ +#ifdef __PRODUCT_NETXDUO__ + if ((error_counter !=0) || (ip_0_ack_counter != 10) || (ip_0_rst_counter != 1) || (ip_1_ack_counter != 10) || (ip_1_rst_counter != 1)) +#else + if ((error_counter !=0) || (ip_0_ack_counter != 9) || (ip_0_rst_counter != 1) || (ip_1_ack_counter != 9) || (ip_1_rst_counter != 1)) +#endif + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + + /* Only detect the TCP packet. */ + if (packet_ptr ->nx_packet_length < 40) + return NX_TRUE; + + /* Get the TCP header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + + /* Swap the data. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + + /* Check the IP ptr. */ + if (ip_ptr == &ip_0) + ip_0_ack_counter ++; + else + ip_1_ack_counter ++; + } + + /* Release the keepalive packet to let socket resend the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + return NX_TRUE; +} + +static void thread_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket == &client_socket) + ip_0_rst_counter++; +} + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket == &server_socket) + ip_1_rst_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_keepalive_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Keepalive Test........................................N/A\n"); + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_tcp_large_data_transfer_test.c b/test/regression/netxduo_test/netx_tcp_large_data_transfer_test.c new file mode 100644 index 00000000..bbf75566 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_large_data_transfer_test.c @@ -0,0 +1,295 @@ +/* This NetX test concentrates on the large data of TCP transmission. */ +/* Payload size of pool is 1536. Host A sends 8k bytes. */ + +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static UCHAR send_buff[8192]; +static UCHAR recv_buff[8192]; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_large_data_transfer_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; +UINT i; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + for (i = 0; i < sizeof(send_buff); i++) + { + send_buff[i] = 0xFF; + recv_buff[i] = 0; + } + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1516, pointer, 30000); + pointer = pointer + 30000; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Large Data Transfer Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), + &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG total_length = 0; +ULONG bytes_copied; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 3 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + /* Retrieve data. */ + nx_packet_data_retrieve(packet_ptr, recv_buff + total_length, &bytes_copied); + total_length += bytes_copied; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Check received data. */ + if (total_length != sizeof(send_buff)) + error_counter++; + else if (memcmp(send_buff, recv_buff, sizeof(send_buff)) != 0) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_large_data_transfer_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Large Data Transfer Test..............................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_large_mtu_test.c b/test/regression/netxduo_test/netx_tcp_large_mtu_test.c new file mode 100644 index 00000000..dd40f231 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_large_mtu_test.c @@ -0,0 +1,318 @@ +/* This NetX test concentrates initial cwnd size with large MTU. */ + +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_3000(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_large_mtu_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_3000, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_3000, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +ULONG tcp_transmit_window; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Large MTU Test........................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create the client socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Connect to server. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Get TCP transmit window size. */ + status = nx_tcp_socket_info_get(&client_socket, NX_NULL, NX_NULL, + NX_NULL, NX_NULL, + NX_NULL, NX_NULL, + NX_NULL, NX_NULL, + NX_NULL, &tcp_transmit_window, + NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Verify the cwnd is 2MSS. */ + if ((tcp_transmit_window != client_socket.nx_tcp_socket_connect_mss * 2) || + (tcp_transmit_window != client_socket.nx_tcp_socket_tx_window_congestion)) + { + error_counter++; + } + + /* Disconnect from server. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unbind the client socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Delete the client socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create the server socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Listen the socket. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Accept connection from client. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Verify the cwnd is 2MSS. */ + if (server_socket.nx_tcp_socket_tx_window_congestion != server_socket.nx_tcp_socket_connect_mss * 2) + { + error_counter++; + } + + /* Disconnect from client. */ + status = nx_tcp_socket_disconnect(&server_socket, 5); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Delete the client socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_large_mtu_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Large MTU Test........................................N/A\n"); + + test_control_return(3); + +} +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/netxduo_test/netx_tcp_large_mtu_test2.c b/test/regression/netxduo_test/netx_tcp_large_mtu_test2.c new file mode 100644 index 00000000..bf340f8a --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_large_mtu_test2.c @@ -0,0 +1,351 @@ +/* This NetX test concentrates initial cwnd size with large MTU. */ + +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_3000(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_large_mtu_test_2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver_3000, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +ULONG tcp_transmit_window; +ULONG mss; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Large MTU Test 2......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create the client socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Connect to server. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Get TCP transmit window size. */ + status = nx_tcp_socket_info_get(&client_socket, NX_NULL, NX_NULL, + NX_NULL, NX_NULL, + NX_NULL, NX_NULL, + NX_NULL, NX_NULL, + NX_NULL, &tcp_transmit_window, + NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Verify the cwnd is 3MSS. */ + if ((tcp_transmit_window != client_socket.nx_tcp_socket_connect_mss * 3) || + (tcp_transmit_window != client_socket.nx_tcp_socket_tx_window_congestion)) + { + error_counter++; + } + + /* Get client MSS. */ + status = nx_tcp_socket_mss_get(&client_socket, &mss); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Verify connection MSS. */ + if (mss != 1460) + { + error_counter++; + } + + /* Disconnect from server. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unbind the client socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Delete the client socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +ULONG mss; + + /* Create the server socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Listen the socket. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Accept connection from client. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Get client MSS. */ + status = nx_tcp_socket_mss_get(&server_socket, &mss); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Verify connection MSS. */ + if (mss != 1460) + { + error_counter++; + } + + /* Verify the cwnd is 3MSS. */ + if (server_socket.nx_tcp_socket_tx_window_congestion != server_socket.nx_tcp_socket_connect_mss * 3) + { + error_counter++; + } + + /* Disconnect from client. */ + status = nx_tcp_socket_disconnect(&server_socket, 5); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Delete the client socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_large_mtu_test_2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Large MTU Test 2......................................N/A\n"); + + test_control_return(3); + +} +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/netxduo_test/netx_tcp_listen_packet_leak_test.c b/test/regression/netxduo_test/netx_tcp_listen_packet_leak_test.c new file mode 100644 index 00000000..b580853e --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_listen_packet_leak_test.c @@ -0,0 +1,339 @@ +/* This NetX test concentrates on the basic TCP operation. */ +/* Test Process: +Step1. Let IP1(Server Socket) is on listen mode. +step2. Client Socket send SYN packet to IP1, IP1 queue the SYN packet on listen queue. +Step3. Client Socket send RST packet to IP1 +Step4. Check if SYN and RST packet both are released. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET client_socket_2; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_listen_packet_leak_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_TCP_HEADER tcp_header; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Listen Packet Leak Test..............................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Check status. */ + if (status == NX_SUCCESS) + error_counter++; + + /* Check if queue the SYN packet. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_queue_current != 1) + error_counter++; + + /* Build TCP header. */ + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + + /* Send the RST packet. We just want to create a fake header, so assume this packet is incoming packet. */ + tcp_header.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_tx_sequence; + tcp_header.nx_tcp_sequence_number = client_socket.nx_tcp_socket_rx_sequence; + + /* Send RST. */ + _nx_tcp_packet_send_rst(&client_socket, &tcp_header); + + /* Check if the SYN and RST both are released. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + error_counter++; + } + + /* Check the queue count. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_queue_current != 0) + error_counter++; + + /* Disconnect the socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + + /* Test multiple SYN packet with different source port. */ + /* Create a socket 2. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_2, "Client Socket 2", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket_2, 0x90, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket_2, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Check status. */ + if (status == NX_SUCCESS) + error_counter++; + + /* Check if queue the SYN packet. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_queue_current != 1) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT); + + /* Check status. */ + if (status == NX_SUCCESS) + error_counter++; + + /* Check if queue the SYN packet. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_queue_current != 2) + error_counter++; + + /* Build TCP header. */ + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + + /* Send the RST packet. We just want to create a fake header, so assume this packet is incoming packet. */ + tcp_header.nx_tcp_acknowledgment_number = client_socket.nx_tcp_socket_tx_sequence; + tcp_header.nx_tcp_sequence_number = client_socket.nx_tcp_socket_rx_sequence; + + /* Send RST to reset the second SYN. */ + _nx_tcp_packet_send_rst(&client_socket, &tcp_header); + + /* Check if the second SYN and the third RST both are released. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total - 1) + { + error_counter++; + } + + /* Check the queue count. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_queue_current != 1) + error_counter++; + + /* Build TCP header. */ + tcp_header.nx_tcp_header_word_3 = NX_TCP_ACK_BIT; + + /* Send the RST packet. We just want to create a fake header, so assume this packet is incoming packet. */ + tcp_header.nx_tcp_acknowledgment_number = client_socket_2.nx_tcp_socket_tx_sequence; + tcp_header.nx_tcp_sequence_number = client_socket_2.nx_tcp_socket_rx_sequence; + + /* Send RST to reset the first SYN. */ + _nx_tcp_packet_send_rst(&client_socket_2, &tcp_header); + + /* Check if the first SYN and RST both are released. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + error_counter++; + } + + /* Check the queue count. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_queue_current != 0) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Unaccept the server socket to let IP1 on listen mode. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check status. */ + if(status) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_listen_packet_leak_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Listen Packet Leak Test...............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_listen_test.c b/test/regression/netxduo_test/netx_tcp_listen_test.c new file mode 100644 index 00000000..d8c86254 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_listen_test.c @@ -0,0 +1,332 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET server_socket_1; +static NX_TCP_SOCKET server_socket_2; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_listen_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Listen Test..........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Should return some error message. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &client_socket, 5, NX_NULL); + if (status != NX_ALREADY_BOUND) + error_counter++; + +#ifdef __PRODUCT_NETXDUO__ + /* Should return some error message since server socket is accepting. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status != NX_NOT_LISTEN_STATE) + error_counter++; +#endif /* __PRODUCT_NETXDUO__ */ + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_1, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_2, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* server_socket listen again. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status != NX_NOT_CLOSED) + error_counter++; + + /* server_socket_1 listen at port 13. */ + status = nx_tcp_server_socket_listen(&ip_1, 13, &server_socket_1, 5, NX_NULL); + if (status) + error_counter++; + + /* server_socket_2 listen at port 13. Should return duplicate error */ + status = nx_tcp_server_socket_listen(&ip_1, 13, &server_socket_2, 5, NX_NULL); + if (status != NX_DUPLICATE_LISTEN) + error_counter++; + + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 13. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 13); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_listen_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Listen Test...........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_loopback_test.c b/test/regression/netxduo_test/netx_tcp_loopback_test.c new file mode 100644 index 00000000..1da64a78 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_loopback_test.c @@ -0,0 +1,391 @@ +/* This NetX test concentrates on the TCP loopback operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_loopback_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 4096; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable TCP processing for IP instance. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + tx_thread_relinquish(); + + + /* Print out some test information banners. */ + printf("NetX Test: TCP Loopback Processing Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 13, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Loop to send 1,000 packets. */ + thread_0_counter = 0; + while (thread_0_counter < 1000) + { + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + if ((thread_0_counter & 3) == 0) + { + + /* Disable all interface capability. */ + nx_ip_interface_capability_set(&ip_0, 0, 0); + } + else if ((thread_0_counter & 3) == 1) + { + + /* Enable all TX checksum capability. */ + nx_ip_interface_capability_set(&ip_0, 0, NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM); + } + else if ((thread_0_counter & 3) == 2) + { + + /* Enable all RX checksum capability. */ + nx_ip_interface_capability_set(&ip_0, 0, NX_INTERFACE_CAPABILITY_IPV4_RX_CHECKSUM | + NX_INTERFACE_CAPABILITY_TCP_RX_CHECKSUM | + NX_INTERFACE_CAPABILITY_UDP_RX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV4_RX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV6_RX_CHECKSUM | + NX_INTERFACE_CAPABILITY_IGMP_RX_CHECKSUM); + } + else if ((thread_0_counter & 3) == 3) + { + + /* Enable all checksum capability. */ + nx_ip_interface_capability_set(&ip_0, 0, NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_IPV4_RX_CHECKSUM | + NX_INTERFACE_CAPABILITY_TCP_RX_CHECKSUM | + NX_INTERFACE_CAPABILITY_UDP_RX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV4_RX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV6_RX_CHECKSUM | + NX_INTERFACE_CAPABILITY_IGMP_RX_CHECKSUM); + } +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Determine how to report error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG expected_length = 0; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Loop to create and establish server connections. */ + thread_1_counter = 0; + while(thread_1_counter < 1000) + { + + if(expected_length == 0) + { + + /* Increment thread 1's counter. */ + thread_1_counter++; + expected_length = 28; + } + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + { + + expected_length -= packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_0, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_loopback_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Loopback Processing Test..............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_max_window_scale_test.c b/test/regression/netxduo_test/netx_tcp_max_window_scale_test.c new file mode 100644 index 00000000..2d2a9664 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_max_window_scale_test.c @@ -0,0 +1,454 @@ +/* This NetX test concentrates on the TCP MAX windows scale operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +extern void test_control_return(UINT status); + +#if defined(NX_ENABLE_TCP_WINDOW_SCALING) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG syn_counter; + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +extern USHORT _nx_ip_checksum_compute(NX_PACKET *packet_ptr, ULONG protocol, + UINT data_length, ULONG* src_ip_addr, + ULONG* dest_ip_addr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_max_window_scale_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + syn_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_tcp_enable(&ip_1); + if(status) + error_counter++; + +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; + + /* Print out test information banner. */ + printf("NetX Test: TCP MAX Window Scale Test................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, ((1<<30)-1), + NX_NULL, ntest_0_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + ip_0.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + + /* The window scale value is modified to 0xFF which is larger than 14. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + if(syn_counter == 1) + { + /*Check whether the connection has crashed*/ + if((client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) || (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + error_counter++; + + /* Check the windows size. */ + if ((client_socket.nx_tcp_socket_rx_window_default != ((1<<30)-1)) || (client_socket.nx_tcp_socket_rx_window_current != ((1<<30)-1)) || + (server_socket.nx_tcp_socket_rx_window_default != ((1<<30)-1)) || (server_socket.nx_tcp_socket_rx_window_current != ((1<<30)-1))) + error_counter++; + } + else + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Relisten. */ + status = nx_tcp_server_socket_relisten(&ip_0, 12, &server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* The window scale option is removed from syn packet. */ + status = nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /*Check whether the connection has crashed*/ + if((client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) || (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + error_counter++; + + /* Check the windows size. */ + if ((client_socket.nx_tcp_socket_rx_window_default != 0xFFFF) || (client_socket.nx_tcp_socket_rx_window_current != 0xFFFF) || + (server_socket.nx_tcp_socket_rx_window_default != 0xFFFF) || (server_socket.nx_tcp_socket_rx_window_current != 0xFFFF)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, ((1<<30)-1), + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Set the window size no less than 2^30. */ + client_socket.nx_tcp_socket_rx_window_default = ((ULONG)1<<31) - 1; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /*To handle the syn packet.*/ + advanced_packet_process_callback = my_packet_process; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if((error_counter != 0) || (syn_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void ntest_0_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG *option_word_2; +ULONG checksum; +ULONG *source_ip, *dest_ip; + + tcp_header_ptr = (NX_TCP_HEADER*)((packet_ptr -> nx_packet_prepend_ptr) + 20); + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + option_word_2 = option_word_1 + 1; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* If this is a tcp packet but not an ARP packet or other kind packet. */ + if(packet_ptr -> nx_packet_length >= 40) + { + /* Chcek whether it is a SYN packet. */ + if((tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + NX_CHANGE_ULONG_ENDIAN(*option_word_2); + + if (syn_counter == 0) + { + + /* Modify the Window scale option to 0xFF which is larger than 14. */ + *option_word_2 = *option_word_2 | 0x0000FF00; + } + else + { + + /* Remove window scale option. */ + *option_word_2 = NX_TCP_OPTION_END; + } + + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + NX_CHANGE_ULONG_ENDIAN(*option_word_2); + + /*Put the packet pointer to tcp*/ + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket. nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* Move the checksum into header. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); + + } + else + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + return NX_TRUE; + } + +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *header_ptr; +ULONG *option_word_2; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + option_word_2 = ((ULONG *)(header_ptr + 1)) + 1; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Server receives a SYN packet. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && !(header_ptr -> nx_tcp_header_word_3 & NX_TCP_RST_BIT)) + { + NX_CHANGE_ULONG_ENDIAN(*option_word_2); + syn_counter++; + + NX_CHANGE_ULONG_ENDIAN(*option_word_2); + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Pass the packet to the default function. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_max_window_scale_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP MAX Window Scale Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_mss_option_test.c b/test/regression/netxduo_test/netx_tcp_mss_option_test.c new file mode 100644 index 00000000..d8a0c055 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_mss_option_test.c @@ -0,0 +1,428 @@ +/* This NetX test concentrates on the TCP Socket relisten operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +#define CLIENT_PORT 0x88 +#define SERVER_PORT 0x89 + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT syn_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void tcp_checksum_compute(NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_mss_option_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + /* Check the status. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check the status. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP MSS Option Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, CLIENT_PORT, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + + /* Send NOP KIND option in my_tcp_packet_receive. */ + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + + /* Send invalid option in my_tcp_packet_receive. */ + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + + /* Send invalid option in my_tcp_packet_receive. */ + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_TCP_MSS_CHECK + /* Set the callback function. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + + /* Send mss smaller than minimum in my_tcp_packet_receive. */ + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_ENABLE_TCP_MSS_CHECK */ + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + while (1) + { + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the mss value. */ + if (server_socket.nx_tcp_socket_peer_mss != 536) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, SERVER_PORT, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; + } +} + +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; + + /* Update the counter. */ + syn_counter ++; + + /* Get the TCP header pointer. */ + tcp_header_ptr = (NX_TCP_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /* Check the counter. */ + if (syn_counter == 1) + { + + /* Set the NOP KIND option. */ + *option_word_1 = NX_TCP_NOP_KIND << 24; + } + + /* Check the counter. */ + if (syn_counter == 2) + { + + /* Set the invalid Option. */ + *option_word_1 = 0x04000000; + } + + /* Check the counter. */ + if (syn_counter == 3) + { + + /* Set the invalid Option. */ + *option_word_1 = 0x04090000; + } + +#ifdef NX_ENABLE_TCP_MSS_CHECK + /* Check the counter. */ + if (syn_counter == 4) + { + + /* Set the mss smaller than minimum. */ + *option_word_1 = NX_TCP_MSS_OPTION | (NX_TCP_MSS_MINIMUM - 1); + } +#endif /* NX_ENABLE_TCP_MSS_CHECK */ + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + + /* Calculate the TCP checksum. */ + tcp_checksum_compute(packet_ptr); + + /* Clear the callback function. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +static void tcp_checksum_compute(NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *source_ip, *dest_ip; +ULONG checksum; + + if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) + { + + /* Get IPv4 addresses. */ + source_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 8); + dest_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 4); + } + else + { + + /* Get IPv6 addresses. */ + source_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 32); + dest_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 16); + } + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + /* Calculate the checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_mss_option_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP MSS Option Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_multiple_send_test.c b/test/regression/netxduo_test/netx_tcp_multiple_send_test.c new file mode 100644 index 00000000..664b948d --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_multiple_send_test.c @@ -0,0 +1,342 @@ +/* This NetX test concentrates on sending TCP packets in multiple threads simultaneously. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +static UCHAR pool_area_0[20480]; +static UCHAR pool_area_1[20480]; + +static CHAR send_buff[512]; + +static ULONG end_time; + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG thread_2_counter; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_multiple_send_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + thread_0_counter = 0; + thread_1_counter = 0; + thread_2_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, 1, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, 1, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create two packet pools. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pool_area_0, sizeof(pool_area_0)); + status += nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 256, pool_area_1, sizeof(pool_area_1)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Multiple Send Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Reset the system timer. */ + tx_time_set(0); + + /* Set the timer that stops sending. */ + end_time = NX_IP_PERIODIC_RATE; + + /* Resume thread 1. */ + tx_thread_resume(&thread_1); + + while (tx_time_get() < end_time) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + thread_0_counter++; + } + + /* Sleep 1 second to make sure thread 1 exists. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + while (tx_time_get() < end_time) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + /* Release the packet. */ + nx_packet_release(packet_ptr); + thread_2_counter++; + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_multiple_send_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Multiple Send Test....................................N/A\n"); + + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_tcp_multiple_send_test2.c b/test/regression/netxduo_test/netx_tcp_multiple_send_test2.c new file mode 100644 index 00000000..e2ecc7a6 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_multiple_send_test2.c @@ -0,0 +1,343 @@ +/* This NetX test concentrates on sending TCP packets in multiple threads simultaneously. + Hit the conidtion in _nx_tcp_socket_send_internal: 684 [ + - ]: if (send_packet != packet_ptr) */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +static UCHAR pool_area_0[20480]; +static UCHAR pool_area_1[20480]; + +static CHAR send_buff[200]; + +static ULONG end_time; + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG thread_2_counter; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_multiple_send_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + thread_0_counter = 0; + thread_1_counter = 0; + thread_2_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, 1, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, 1, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create two packet pools. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pool_area_0, sizeof(pool_area_0)); + status += nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 256, pool_area_1, sizeof(pool_area_1)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Multiple Send Test2..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Reset the system timer. */ + tx_time_set(0); + + /* Set the timer that stops sending. */ + end_time = NX_IP_PERIODIC_RATE; + + /* Resume thread 1. */ + tx_thread_resume(&thread_1); + + while (tx_time_get() < end_time) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + thread_0_counter++; + } + + /* Sleep 1 second to make sure thread 1 exists. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + while (tx_time_get() < end_time) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + thread_1_counter++; + } +} + + +static void thread_2_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + /* Release the packet. */ + nx_packet_release(packet_ptr); + thread_2_counter++; + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_multiple_send_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Multiple Send Test2...................................N/A\n"); + + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test1.c b/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test1.c new file mode 100644 index 00000000..299fe340 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test1.c @@ -0,0 +1,616 @@ +/* This NetX test concentrates on fast retransmit. */ + +/* Procedure: +1. Client connect with Server. +2. Client send five segments to Server. +3. Drop the first and second segments in the driver. +4. Server send three duplicate ACKs with acknowledgment number as the sequence number of first segment. +5. Client fast retransmits the first segment. +6. Server send ACK with acknowledgment number as the second number of first segment. +7. Client fast retransmits the second segment. +8. Server receives the segment and check the segments data. +9. Disconnect. +10. Print the result. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the messsage. */ +static CHAR msg[200]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +static ULONG ack_counter; +static ULONG client_tx_sequnce; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_new_reno_algorithm_test1_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + packet_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet[5]; + + /* Print out test information banner. */ + printf("NetX Test: TCP New Reno Algorithm Test1.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Random genearte the data. */ + for (i = 0; i < 200; i ++) + msg[i] = (CHAR)rand(); + + /* Create 5 packets. */ + for (i = 0; i < 5; i ++) + { + + /* Allocate the packet. */ + status += nx_packet_allocate(&pool_0, &my_packet[i], NX_TCP_PACKET, NX_NO_WAIT); + + /* Check the status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + memcpy(my_packet[i] -> nx_packet_prepend_ptr, &msg[i*20], 20); + my_packet[i] -> nx_packet_length = 20; + my_packet[i] -> nx_packet_append_ptr = my_packet[i] -> nx_packet_prepend_ptr + 20; + } + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = client_driver_packet_process; + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = client_tcp_packet_receive; + + /* Record the client tx_sequence. */ + client_tx_sequnce = client_socket.nx_tcp_socket_tx_sequence; + + /* Loop to send packets. */ + for (i = 0; i < 5; i ++) + { + + /* Send the packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet[i], NX_NO_WAIT); + + /* Check the status. */ + if(status) + { + error_counter++; + } + } + + /* Disable timeout retransmit. */ + client_socket.nx_tcp_socket_timeout = 60 * 60 * _nx_tcp_fast_timer_rate; + + /* Sleep 1 second to let server receive segments. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 0) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 100) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + error_counter ++; + } + + /* Reset the callback functions. */ + advanced_packet_process_callback = NX_NULL; + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Check the data length. */ + if(recv_length != 100) + error_counter++; + + /* Check the data. */ + if(memcmp(rcv_buffer, msg, recv_length)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_relinquish(); + + /* Determine if the test was successful. */ + if ((error_counter) || (packet_counter != 7) || (ack_counter < 5)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Ingore the server packet. */ + if (ip_ptr != &ip_0) + return NX_TRUE; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + /* Check the data length. */ + if(packet_ptr -> nx_packet_length == 60) + { + + /* Update the counter. */ + packet_counter ++; + + /* Check the packet counter. */ + if ((packet_counter == 1) || (packet_counter == 2)) + { + + /* Discard the first and second segments. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + /* Check the sequence number. */ + if (packet_counter == 1) + { + + /* Should be 1th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce) + { + error_counter ++; + } + } + else if (packet_counter == 2) + { + + /* Should be 2th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 20) + { + error_counter ++; + } + } + else if (packet_counter == 3) + { + + /* Should be 3th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 40) + { + error_counter ++; + } + } + else if (packet_counter == 4) + { + + /* Should be 4th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 60) + { + error_counter ++; + } + } + else if (packet_counter == 5) + { + + /* Should be 5th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 80) + { + error_counter ++; + } + } + else if (packet_counter == 6) + { + + /* Should be 1th segment retransmitted. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 100) + { + error_counter ++; + } + } + else if (packet_counter == 7) + { + + /* Should be 2th segment retransmitted. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 20) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 100) + { + error_counter ++; + } + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + return NX_TRUE; +} + +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + + /* Update the counter. */ + ack_counter++; + + /* This should be duplicate ACKs. */ + if ((ack_counter == 1) || (ack_counter == 2) || (ack_counter == 3)) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != ack_counter - 1) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + error_counter ++; + } + } + /* This should be normal ACK for 1th segment in fast recovery. */ + else if (ack_counter == 4) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce + 20) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 100) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 3) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + } + /* This should be normal ACK for 2th segment in fast recovery. */ + else if (ack_counter == 5) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce + 100) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 0) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 100) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + } + /* Other ACKs for window update when call nx_tcp_socket_receive API. */ + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_new_reno_algorithm_test1_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP New Reno Algorithm Test1..............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test2.c b/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test2.c new file mode 100644 index 00000000..e769eab1 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test2.c @@ -0,0 +1,711 @@ +/* This NetX test concentrates on fast retransmit. */ + +/* Procedure: +1. Client connect with Server. +2. Client send ten segments to Server. +3. Drop the 2th, 3th, 4th, 6th, 7th, 8th segments in the driver. +4. Server send three duplicate ACKs with acknowledgment number as the sequence number of 2th segment. +5. Client should fast retransmits the 2th, 3th, 4th, 6th, 7th, 8th segment. +6. Server receives the segment and check the segments data. +7. Disconnect. +8. Print the result. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the messsage. */ +static CHAR msg[200]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +static ULONG ack_counter; +static ULONG client_tx_sequnce; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_new_reno_algorithm_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + packet_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 512 * 30); + pointer = pointer + 512 * 30; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet[10]; + + /* Print out test information banner. */ + printf("NetX Test: TCP New Reno Algorithm Test2.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Random genearte the data. */ + for (i = 0; i < 200; i ++) + msg[i] = (CHAR)rand(); + + /* Create 10 packets. */ + for (i = 0; i < 10; i ++) + { + + /* Allocate the packet. */ + status += nx_packet_allocate(&pool_0, &my_packet[i], NX_TCP_PACKET, NX_NO_WAIT); + + /* Check the status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + memcpy(my_packet[i] -> nx_packet_prepend_ptr, &msg[i*20], 20); + my_packet[i] -> nx_packet_length = 20; + my_packet[i] -> nx_packet_append_ptr = my_packet[i] -> nx_packet_prepend_ptr + 20; + } + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = client_driver_packet_process; + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = client_tcp_packet_receive; + + /* Record the client tx_sequence. */ + client_tx_sequnce = client_socket.nx_tcp_socket_tx_sequence; + + /* Loop to send packets. */ + for (i = 0; i < 10; i ++) + { + + /* Send the packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet[i], NX_NO_WAIT); + + /* Check the status. */ + if(status) + { + error_counter++; + } + } + + /* Disable timeout retransmit. */ + client_socket.nx_tcp_socket_timeout = 60 * 60 * _nx_tcp_fast_timer_rate; + + /* Sleep 2 second to let server receive segments. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 0) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 200) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + error_counter ++; + } + + /* Reset the callback functions. */ + advanced_packet_process_callback = NX_NULL; + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Check the data length. */ + if(recv_length != 200) + error_counter++; + + /* Check the data. */ + if(memcmp(rcv_buffer, msg, recv_length)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_relinquish(); + + /* Determine if the test was successful. */ + if ((error_counter) || (packet_counter != 16) || (ack_counter < 10)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Ingore the server packet. */ + if (ip_ptr != &ip_0) + return NX_TRUE; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + /* Check the data length. */ + if(packet_ptr -> nx_packet_length == 60) + { + + /* Update the counter. */ + packet_counter ++; + + /* Discard the 2th, 3th, 4th, 6th, 7th, 8th segments. */ + if ((packet_counter == 2) || (packet_counter == 3) || (packet_counter == 4) || + (packet_counter == 6) || (packet_counter == 7) || (packet_counter == 8)) + { + + /* Discard the segments. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + /* Check the sequence number. */ + if ((packet_counter <= 10)) + { + + /* Should be 1th ~ 10th segments. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != (client_tx_sequnce + (packet_counter -1) * 20)) + { + error_counter ++; + } + } + else if ((packet_counter >= 11) && + (packet_counter <= 16)) + { + + if ((packet_counter >= 11) && + (packet_counter <= 13)) + { + + /* Should be 2th, 3th, 4th segments retransmitted. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + (packet_counter -10) * 20) + { + error_counter ++; + } + } + else if ((packet_counter >= 14) && + (packet_counter <= 16)) + { + + /* Should be 6th, 7th, 8th segments retransmitted. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + (packet_counter - 9) * 20) + { + error_counter ++; + } + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 200) + { + error_counter ++; + } + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + return NX_TRUE; +} + +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + + /* Update the counter. */ + ack_counter++; + + /* This should be normal ACK for 2th segment. */ + if (ack_counter == 1) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce + 20) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 0) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + error_counter ++; + } + } + /* This should be duplicate ACKs for 2th segment. */ + else if ((ack_counter == 2) || (ack_counter == 3) || (ack_counter == 4)) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce + 20) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != ack_counter - 2) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + error_counter ++; + } + } + /* This should be normal ACK for 3th segment in fast recovery. */ + else if (ack_counter == 5) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce + 40) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 200) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 3) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + } + + /* This should be normal ACK for 4th segment in fast recovery. */ + else if (ack_counter == 6) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce + 60) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 200) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 0) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + } + + /* This should be normal ACK for 6th segment in fast recovery. */ + else if (ack_counter == 7) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce + 100) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 200) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 0) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + } + + /* This should be normal ACK for 7th segment in fast recovery. */ + else if (ack_counter == 8) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce + 120) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 200) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 0) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + } + /* This should be normal ACK for 8th segment in fast recovery. */ + else if (ack_counter == 9) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce + 140) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 0) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 200) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + } + /* This should be normal ACK for 11th segment . */ + else if (ack_counter == 10) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce + 200) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 0) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 200) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + } + /* Other ACKs for window update when call nx_tcp_socket_receive API. */ + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_new_reno_algorithm_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP New Reno Algorithm Test2..............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test3.c b/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test3.c new file mode 100644 index 00000000..2317bf55 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test3.c @@ -0,0 +1,684 @@ +/* This NetX test concentrates on fast retransmit. */ + +/* Procedure: +1. Client connect with Server. +2. Client send three segments to Server. +3. Drop the 1th segments in the driver. +4. Server send two duplicate ACKs with acknowledgment number as the sequence number of 1th segment. +5. Client should retransmit the 1th when timeout. +6. Server receives the segment and check the segments data. +7. Disconnect. +8. Print the result. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define notify printf("line %d failed.\n", __LINE__) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the messsage. */ +static CHAR msg[200]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +static ULONG ack_counter; +static ULONG client_tx_sequnce; +static ULONG start_ticks; +static ULONG end_ticks; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_new_reno_algorithm_test3_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + packet_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 512 * 30); + pointer = pointer + 512 * 30; + + if(status) + { + notify; + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + { + notify; + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + { + notify; + error_counter++; + } + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + { + notify; + error_counter++; + } +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet[3]; + + /* Print out test information banner. */ + printf("NetX Test: TCP New Reno Algorithm Test3.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + notify; + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + { + notify; + error_counter++; + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + { + notify; + error_counter++; + } + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + { + notify; + error_counter++; + } + + /* Random genearte the data. */ + for (i = 0; i < 200; i ++) + msg[i] = (CHAR)rand(); + + /* Create 3 packets. */ + for (i = 0; i < 3; i ++) + { + + /* Allocate the packet. */ + status += nx_packet_allocate(&pool_0, &my_packet[i], NX_TCP_PACKET, NX_NO_WAIT); + + /* Check the status. */ + if(status) + { + notify; + error_counter++; + } + + /* Fill in the packet with data. */ + memcpy(my_packet[i] -> nx_packet_prepend_ptr, &msg[i*20], 20); + my_packet[i] -> nx_packet_length = 20; + my_packet[i] -> nx_packet_append_ptr = my_packet[i] -> nx_packet_prepend_ptr + 20; + } + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = client_driver_packet_process; + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = client_tcp_packet_receive; + + /* Record the client tx_sequence. */ + client_tx_sequnce = client_socket.nx_tcp_socket_tx_sequence; + + /* Loop to send packets. */ + for (i = 0; i < 3; i ++) + { + + /* Send the packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet[i], NX_NO_WAIT); + + /* Check the status. */ + if(status) + { + notify; + error_counter++; + } + } + + /* Sleep 2 seconds to let client retransmit the 1th segments and server receive segments. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 0) + { + notify; + error_counter++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + notify; + error_counter++; + } + + /* Reset the callback functions. */ + advanced_packet_process_callback = NX_NULL; + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + { + notify; + error_counter++; + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + { + notify; + error_counter++; + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + { + notify; + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + notify; + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + { + notify; + error_counter++; + } + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + { + notify; + error_counter++; + } + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + { + notify; + error_counter++; + } + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + { + notify; + error_counter++; + } + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Check the data length. */ + if(recv_length != 60) + { + notify; + error_counter++; + } + + /* Check the data. */ + if(memcmp(rcv_buffer, msg, recv_length)) + { + notify; + error_counter++; + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + { + notify; + error_counter++; + } + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + { + notify; + error_counter++; + } + + tx_thread_relinquish(); + + /* Determine if the test was successful. */ + if ((error_counter) || (packet_counter != 6) || (ack_counter < 3)) + { + notify; + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Ingore the server packet. */ + if (ip_ptr != &ip_0) + return NX_TRUE; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + /* Check the data length. */ + if(packet_ptr -> nx_packet_length == 60) + { + + /* Update the counter. */ + packet_counter ++; + + /* Discard the 1th segment. */ + if (packet_counter == 1) + { + + /* Discard the segments. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + /* Check the sequence number. */ + if (packet_counter == 1) + { + + /* Should be 1th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce) + { + notify; + error_counter++; + } + + /* Get the time. */ + start_ticks = tx_time_get(); + } + else if (packet_counter == 2) + { + + /* Should be 2th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 20) + { + notify; + error_counter ++; + } + } + else if (packet_counter == 3) + { + + /* Should be 3th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 40) + { + notify; + error_counter ++; + } + } + else if (packet_counter == 4) + { + + /* Should be 1th segment retransmitted. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce) + { + notify; + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + notify; + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 60) + { + notify; + error_counter ++; + } + + /* Get the time. */ + end_ticks = tx_time_get(); + + /* Check the time interval, should be in NX_IP_PERIODIC_RATE - _nx_tcp_fast_timer_rate and NX_IP_PERIODIC_RATE. */ + if (((end_ticks - start_ticks) < (NX_IP_PERIODIC_RATE - _nx_tcp_fast_timer_rate)) || + ((end_ticks - start_ticks) > NX_IP_PERIODIC_RATE)) + { + notify; + error_counter ++; + } + } + + else if (packet_counter == 5) + { + + /* Should be 2th segment retransmitted. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 20) + { + notify; + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + notify; + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 60) + { + notify; + error_counter ++; + } + + /* Get the time. */ + end_ticks = tx_time_get(); + + /* Check the time interval, should be in NX_IP_PERIODIC_RATE - _nx_tcp_fast_timer_rate and NX_IP_PERIODIC_RATE. */ + if (((end_ticks - start_ticks) < (NX_IP_PERIODIC_RATE - _nx_tcp_fast_timer_rate)) || + ((end_ticks - start_ticks) > NX_IP_PERIODIC_RATE)) + { + notify; + error_counter ++; + } + } + + else if (packet_counter == 6) + { + + /* Should be 1th segment retransmitted. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 40) + { + notify; + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + notify; + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 60) + { + notify; + error_counter ++; + } + + /* Get the time. */ + end_ticks = tx_time_get(); + + /* Check the time interval, should be in NX_IP_PERIODIC_RATE - _nx_tcp_fast_timer_rate and NX_IP_PERIODIC_RATE. */ + if (((end_ticks - start_ticks) < (NX_IP_PERIODIC_RATE - _nx_tcp_fast_timer_rate)) || + ((end_ticks - start_ticks) > NX_IP_PERIODIC_RATE)) + { + notify; + error_counter ++; + } + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + return NX_TRUE; +} + +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + + /* Update the counter. */ + ack_counter++; + + /* This should be duplicate ACKs for 1th segment. */ + if ((ack_counter == 1) || (ack_counter == 2)) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce) + { + notify; + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1) + { + notify; + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != ack_counter - 1) + { + notify; + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + notify; + error_counter ++; + } + } + /* This should be normal ACK for 4th segment . */ + else if (ack_counter == 3) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce + 60) + { + notify; + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + notify; + error_counter ++; + } + } + /* Other ACKs for window update when call nx_tcp_socket_receive API. */ + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_new_reno_algorithm_test3_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP New Reno Algorithm Test3..............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test4.c b/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test4.c new file mode 100644 index 00000000..c3b22cf6 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test4.c @@ -0,0 +1,590 @@ +/* This NetX test concentrates on fast retransmit. */ + +/* Procedure: +1. Client connect with Server. The sequence number of client is modified to the edge of 32 bit number. +2. Client send five segments to Server. +3. Drop the first segment in the driver. +4. Server send three duplicate ACKs with acknowledgment number as the sequence number of first segment. +5. Client fast retransmits the first segment. +6. Server receives the segment and check the segments data. +7. Disconnect. +8. Print the result. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the messsage. */ +static CHAR msg[200]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG packet_counter; +static ULONG ack_counter; +static ULONG client_tx_sequnce; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_new_reno_algorithm_test4_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + packet_counter = 0; + ack_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *my_packet[5]; + + /* Print out test information banner. */ + printf("NetX Test: TCP New Reno Algorithm Test4.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = client_driver_packet_process; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Random genearte the data. */ + for (i = 0; i < 200; i ++) + msg[i] = (CHAR)rand(); + + /* Create 5 packets. */ + for (i = 0; i < 5; i ++) + { + + /* Allocate the packet. */ + status += nx_packet_allocate(&pool_0, &my_packet[i], NX_TCP_PACKET, NX_NO_WAIT); + + /* Check the status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + memcpy(my_packet[i] -> nx_packet_prepend_ptr, &msg[i*20], 20); + my_packet[i] -> nx_packet_length = 20; + my_packet[i] -> nx_packet_append_ptr = my_packet[i] -> nx_packet_prepend_ptr + 20; + } + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = client_tcp_packet_receive; + + /* Record the client tx_sequence. */ + client_tx_sequnce = client_socket.nx_tcp_socket_tx_sequence; + + /* Loop to send packets. */ + for (i = 0; i < 5; i ++) + { + + /* Send the packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet[i], NX_NO_WAIT); + + /* Check the status. */ + if(status) + { + error_counter++; + } + } + + /* Disable timeout retransmit. */ + client_socket.nx_tcp_socket_timeout = 60 * 60 * _nx_tcp_fast_timer_rate; + + /* Sleep 1 second to let server receive segments. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != 0) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + error_counter ++; + } + + /* Reset the callback functions. */ + advanced_packet_process_callback = NX_NULL; + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Check the data length. */ + if(recv_length != 100) + error_counter++; + + /* Check the data. */ + if(memcmp(rcv_buffer, msg, recv_length)) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_relinquish(); + + /* Determine if the test was successful. */ + if ((error_counter) || (packet_counter != 6) || (ack_counter < 4)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; +#ifdef __PRODUCT_NETXDUO__ +ULONG *source_ip, *dest_ip; +#else +ULONG source_ip, dest_ip; +#endif + + /* Ingore the server packet. */ + if (ip_ptr != &ip_0) + return NX_TRUE; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + + /* Check the data length. */ + if(packet_ptr -> nx_packet_length == 60) + { + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + + /* Update the counter. */ + packet_counter ++; + + /* Check the packet counter. */ + if (packet_counter == 1) + { + + /* Discard the first and second segments. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + /* Check the sequence number. */ + if (packet_counter == 1) + { + + /* Should be 1th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce) + { + error_counter ++; + } + } + else if (packet_counter == 2) + { + + /* Should be 2th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 20) + { + error_counter ++; + } + } + else if (packet_counter == 3) + { + + /* Should be 3th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 40) + { + error_counter ++; + } + } + else if (packet_counter == 4) + { + + /* Should be 4th segment. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce + 60) + { + error_counter ++; + } + } + else if (packet_counter == 5) + { + + /* Should be 1th segment retransmitted. */ + if (tcp_header_ptr -> nx_tcp_sequence_number != client_tx_sequnce) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_TRUE) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1 + 80) + { + error_counter ++; + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + } + else if(packet_ptr -> nx_packet_length > 40) + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_SYN_BIT) + { + + /* It is a SYN packet. */ + /* Modify the sequence number. */ + client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFFFF - 90 + 1; + client_socket.nx_tcp_socket_tx_sequence_recover = client_socket.nx_tcp_socket_tx_sequence - 1; + client_socket.nx_tcp_socket_previous_highest_ack = client_socket.nx_tcp_socket_tx_sequence - 1; + tcp_header_ptr -> nx_tcp_sequence_number = client_socket.nx_tcp_socket_tx_sequence - 1; + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_sequence_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Clear the checksum field. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + /* Calculate the checksum . */ +#if defined(__PRODUCT_NETXDUO__) + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IPV4_HEADER); + + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket. nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV4_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IPV4_HEADER); +#else + packet_ptr -> nx_packet_prepend_ptr += sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length -= sizeof(NX_IP_HEADER); + + dest_ip = client_socket.nx_tcp_socket_connect_ip; + source_ip = ip_0.nx_ip_address; + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IP_HEADER); + packet_ptr -> nx_packet_length += sizeof(NX_IP_HEADER); +#endif + + } + else + { + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + } + + return NX_TRUE; +} + +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + + /* Update the counter. */ + ack_counter++; + + /* This should be duplicate ACKs. */ + if ((ack_counter == 1) || (ack_counter == 2) || (ack_counter == 3)) + { + + /* Check the acknowledgment number. */ + if (tcp_header_ptr -> nx_tcp_acknowledgment_number != client_tx_sequnce) + { + error_counter ++; + } + + /* Check the recover value. */ + if (client_socket.nx_tcp_socket_tx_sequence_recover != client_tx_sequnce - 1) + { + error_counter ++; + } + + /* Check the duplicate ACKs. */ + if (client_socket.nx_tcp_socket_duplicated_ack_received != ack_counter - 1) + { + error_counter ++; + } + + /* Check the socket fast recovery status. */ + if (client_socket.nx_tcp_socket_fast_recovery != NX_FALSE) + { + error_counter ++; + } + } + } + + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_acknowledgment_number); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_new_reno_algorithm_test4_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP New Reno Algorithm Test4..............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test5.c b/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test5.c new file mode 100644 index 00000000..40c1a20e --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_new_reno_algorithm_test5.c @@ -0,0 +1,370 @@ +/* This NetX test concentrates on fast retransmit. */ + +/* Procedure: +1. Client connect with Server. The sequence number of client is modified to the edge of 32 bit number. +2. Client send five segments to Server. +3. Drop the first segment in the driver. +4. Server send three duplicate ACKs with acknowledgment number as the sequence number of first segment. +5. Client fast retransmits the first segment. +6. Server receives the segment and check the segments data. +7. Disconnect. +8. Print the result. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the messsage. */ +static CHAR msg[3000]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG window_size; +static NX_PACKET *drop_packet; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_new_reno_algorithm_test5_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + window_size = 0; + drop_packet = NX_NULL; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +UINT old_threshold; +NX_PACKET *my_packet[5]; + + /* Print out test information banner. */ + printf("NetX Test: TCP New Reno Algorithm Test5.............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Random genearte the data. */ + for (i = 0; i < sizeof(msg); i ++) + msg[i] = (CHAR)rand(); + + /* Record the window size of server. */ + window_size = client_socket.nx_tcp_socket_tx_window_advertised; + + /* Create 5 packets. */ + for (i = 0; i < 5; i ++) + { + + /* Allocate the packet. */ + status += nx_packet_allocate(&pool_0, &my_packet[i], NX_TCP_PACKET, NX_NO_WAIT); + + /* Check the status. */ + if(status) + error_counter++; + + /* Fill in the packet with data. */ + memcpy(my_packet[i] -> nx_packet_prepend_ptr, &msg[i*(window_size>>2)], (window_size>>2)); + my_packet[i] -> nx_packet_length = (window_size>>2); + my_packet[i] -> nx_packet_append_ptr = my_packet[i] -> nx_packet_prepend_ptr + (window_size>>2); + } + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = client_driver_packet_process; + drop_packet = my_packet[0]; + + /* Disable preemption. */ + tx_thread_preemption_change(&thread_0, 0, &old_threshold); + + /* Loop to send packets. */ + for (i = 0; i < 5; i ++) + { + + /* Send the packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet[i], NX_IP_PERIODIC_RATE); + + /* Check the status. */ + if(status) + { + error_counter++; + } + } + + /* Restore preemption. */ + tx_thread_preemption_change(&thread_0, old_threshold, &old_threshold); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + { + error_counter++; + } +} + +static char rcv_buffer[3000]; +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Check the data length. */ + if(recv_length != (window_size + (window_size>>2))) + error_counter++; + + /* Check the data. */ + if(memcmp(rcv_buffer, msg, recv_length)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + tx_thread_relinquish(); + + /* Determine if the test was successful. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + if (packet_ptr == drop_packet) + { + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + drop_packet = NX_NULL; + } + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_new_reno_algorithm_test5_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP New Reno Algorithm Test5..............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_not_enabled_test.c b/test/regression/netxduo_test/netx_tcp_not_enabled_test.c new file mode 100644 index 00000000..b2bbccd6 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_not_enabled_test.c @@ -0,0 +1,289 @@ +/* This NetX test concentrates TCP connections when it is not enabled. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_not_enabled_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for IP 0 only. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP not Enabled Test......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Before enable TCP for IP 1, try connect. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + error_counter++; + + /* Enable TCP processing for IP 1. */ + status = nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Resume thread 1. */ + tx_thread_resume(&thread_1); + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_not_enabled_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP not Enabled Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_nxe_api_test.c b/test/regression/netxduo_test/netx_tcp_nxe_api_test.c new file mode 100644 index 00000000..c1e6281a --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_nxe_api_test.c @@ -0,0 +1,2298 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "nx_tcp.h" +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_packet.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +#ifdef __PRODUCT_NETXDUO__ +static NX_PACKET_POOL invalid_pool; +#endif /* __PRODUCT_NETXDUO__ */ +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP invalid_ip; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET invalid_socket; + +/* Define the counters used in the demo application... */ +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void tcp_receive_notify(NX_TCP_SOCKET *socket_ptr); +#if defined(NX_ENABLE_TCP_QUEUE_DEPTH_UPDATE_NOTIFY) && defined(__PRODUCT_NETXDUO__) +static void tcp_socket_queue_depth_notify(NX_TCP_SOCKET *socket_ptr); +#endif +#ifdef __PRODUCT_NETXDUO__ +static void window_update_notify(NX_TCP_SOCKET *socket_ptr); +#endif /* __PRODUCT_NETXDUO__ */ +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet; +NX_PACKET *unknow_packet; +#ifdef __PRODUCT_NETXDUO__ +NX_PACKET invalid_packet; +NX_PACKET *invalid_packet_2; +#endif /* __PRODUCT_NETXDUO__ */ +#ifdef FEATURE_NX_IPV6 +NXD_ADDRESS ip_address; +NXD_ADDRESS nxd_ip_address; +#endif +UINT port; +UINT free_port; +ULONG mss, peer_mss, peer_ip_address, peer_port, bytes_available; +ULONG tcp_packets_sent, tcp_bytes_sent, tcp_packets_received, tcp_bytes_received, tcp_invalid_packets, tcp_receive_packets_dropped, tcp_checksum_errors, tcp_connections, tcp_disconnections, tcp_connections_dropped, tcp_retransmit_packets; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window; + + /* Print out some test information banners. */ + printf("NetX Test: TCP NXE API Test.........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_enable api */ + /************************************************/ + + /* Enable the TCP feature for invalid IP instance. */ + status = nx_tcp_enable(&invalid_ip); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the TCP feature for valid IP instance. */ + status = nx_tcp_enable(&ip_0); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the TCP feature for valid IP instance. */ + status = nx_tcp_enable(&ip_1); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable the TCP feature again. */ + status = nx_tcp_enable(&ip_0); + + /* Check for error. */ + if (status != NX_ALREADY_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_socket_create api */ + /************************************************/ + + /* Create the TCP socket for invalid IP instance. */ + status = nx_tcp_socket_create(NX_NULL, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the TCP socket for invalid IP instance. */ + status = nx_tcp_socket_create(&invalid_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the TCP socket for invalid socket. */ + status = nx_tcp_socket_create(&ip_0, NX_NULL, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the invalid IP instance parameter. */ + invalid_ip.nx_ip_id = NX_IP_ID; + + /* Create the TCP socket with invalid structure size. */ + status = _nxe_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL, sizeof(NX_TCP_SOCKET) + 1); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the TCP socket for IP instance with socket. */ + status = nx_tcp_socket_create(&invalid_ip, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the TCP socket with invalid type of service. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + 0xFFFFFFFF, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the TCP socket with invalid type of fragment. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, 0xFFFFFFFF, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the TCP socket with invalid time of live. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_DONT_FRAGMENT, 0xFFFFFFFF, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the TCP socket with invalid window size. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 0, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + + /* Create the TCP socket with invalid window size. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, (1 << 30), + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Create the TCP socket with valid parameters. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the TCP socket with valid parameters. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create the same Client socket again. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_free_port_find api */ + /************************************************/ + + /* Find the free port with invalid IP instance. */ + status = nx_tcp_free_port_find(NX_NULL, 80, &free_port); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the invalid IP instance ID. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Find the free port with invalid IP instance ID. */ + status = nx_tcp_free_port_find(&invalid_ip, 80, &free_port); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the free port with invalid free port pointer. */ + status = nx_tcp_free_port_find(&ip_0, 80, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the invalid IP instance ID. */ + invalid_ip.nx_ip_id = NX_IP_ID; + + /* Find the free port when disable the TCP feature. */ + status = nx_tcp_free_port_find(&invalid_ip, 80, &free_port); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Find the free port with invalid port. */ + status = nx_tcp_free_port_find(&ip_0, 0xFFFFFFFF, &free_port); + + /* Check for error. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_info_get api */ + /************************************************/ + + /* Get the TCP information with invalid IP instance. */ + status = nx_tcp_info_get(NX_NULL, &tcp_packets_sent, &tcp_bytes_sent, &tcp_packets_received, &tcp_bytes_received, + &tcp_invalid_packets, &tcp_receive_packets_dropped, &tcp_checksum_errors, &tcp_connections, + &tcp_disconnections, &tcp_connections_dropped, &tcp_retransmit_packets); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the invalid IP instance ID. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Get the TCP information with invalid IP instance ID. */ + status = nx_tcp_info_get(&invalid_ip, &tcp_packets_sent, &tcp_bytes_sent, &tcp_packets_received, &tcp_bytes_received, + &tcp_invalid_packets, &tcp_receive_packets_dropped, &tcp_checksum_errors, &tcp_connections, + &tcp_disconnections, &tcp_connections_dropped, &tcp_retransmit_packets); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the invalid IP instance ID. */ + invalid_ip.nx_ip_id = NX_IP_ID; + + /* Get the TCP information when disable the TCP feature. */ + status = nx_tcp_info_get(&invalid_ip, &tcp_packets_sent, &tcp_bytes_sent, &tcp_packets_received, &tcp_bytes_received, + &tcp_invalid_packets, &tcp_receive_packets_dropped, &tcp_checksum_errors, &tcp_connections, + &tcp_disconnections, &tcp_connections_dropped, &tcp_retransmit_packets); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /************************************************/ + /* Tested the nxe_tcp_client_socket_bind api */ + /************************************************/ + + /* Bind the port with invalid socket. */ + status = nx_tcp_client_socket_bind(NX_NULL, 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Bind the port with invalid socket ID. */ + status = nx_tcp_client_socket_bind(&invalid_socket, 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Bind the port when disable TCP feature. */ + status = nx_tcp_client_socket_bind(&invalid_socket, 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the port with invalid prot. */ + status = nx_tcp_client_socket_bind(&client_socket, 0xFFFFFFFF, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /************************************************/ + /* Tested the nxe_tcp_client_socket_connect api */ + /************************************************/ + + /* Connect the TCP with invalid socket. */ + status = nx_tcp_client_socket_connect(NX_NULL, IP_ADDRESS(1, 2, 3, 5), 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Connect the TCP with invalid socket ID. */ + status = nx_tcp_client_socket_connect(&invalid_socket, IP_ADDRESS(1, 2, 3, 5), 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Connect the TCP when disable the TCP feature. */ + status = nx_tcp_client_socket_connect(&invalid_socket, IP_ADDRESS(1, 2, 3, 5), 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Connect the TCP with invalid IP address. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(0, 0, 0, 0), 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ +#ifdef __PRODUCT_NETXDUO__ + if (status != NX_IP_ADDRESS_ERROR) +#else + if (status != NX_NOT_BOUND) +#endif + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Connect the TCP with invalid IP address. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(255, 255, 255, 255), 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Connect the TCP with invalid port. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 0xFFFFFFFF, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /*************************************************/ + /* Tested the nxde_tcp_client_socket_connect api */ + /*************************************************/ + + /* Set the IP address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Connect the TCP with invalid socket. */ + status = nxd_tcp_client_socket_connect(NX_NULL, &ip_address, 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Connect the TCP with invalid socket ID. */ + status = nxd_tcp_client_socket_connect(&invalid_socket, &ip_address, 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Connect the TCP when disable the TCP feature. */ + status = nxd_tcp_client_socket_connect(&invalid_socket, &ip_address, 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Connect the TCP with invalid IP address. */ + status = nxd_tcp_client_socket_connect(&client_socket, NX_NULL, 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address as invalid version. */ + ip_address.nxd_ip_version = 0x80; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + + /* Connect the TCP with invalid IP address. */ + status = nxd_tcp_client_socket_connect(&client_socket, &ip_address, 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address as invalid address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(255, 255, 255, 255); + + /* Connect the TCP with invalid IP address. */ + status = nxd_tcp_client_socket_connect(&client_socket, &ip_address, 80, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address as invalid address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(128, 0, 0, 1); + + /* Connect the TCP with valid IP address and invalid port. */ + status = nxd_tcp_client_socket_connect(&client_socket, &ip_address, 0xFFFFFFFF, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP address as valid address. */ + ip_address.nxd_ip_version = NX_IP_VERSION_V4; + ip_address.nxd_ip_address.v4 = IP_ADDRESS(192, 0, 0, 1); + + /* Connect the TCP with invalid port. */ + status = nxd_tcp_client_socket_connect(&client_socket, &ip_address, 0xFFFFFFFF, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /************************************************/ + /* Tested the nxe_tcp_client_socket_port_get api*/ + /************************************************/ + + /* Get the Client socket port with invalid socket. */ + status = nx_tcp_client_socket_port_get(NX_NULL, &port); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Get the Client socket port with invalid socket ID. */ + status = nx_tcp_client_socket_port_get(&invalid_socket, &port); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the Client socket port with invalid port pointer. */ + status = nx_tcp_client_socket_port_get(&client_socket, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Get the Client socket port when disable TCP feature. */ + status = nx_tcp_client_socket_port_get(&invalid_socket, &port); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_client_socket_unbind api */ + /************************************************/ + + /* Unbind the Client socket with invalid socket. */ + status = nx_tcp_client_socket_unbind(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Unbind the Client socket with invalid socket ID. */ + status = nx_tcp_client_socket_unbind(&invalid_socket); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Unbind the Client socket when disable the TCP feature. */ + status = nx_tcp_client_socket_unbind(&invalid_socket); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_server_socket_accept api */ + /************************************************/ + + /* Accept the Server socket with invalid socket. */ + status = nx_tcp_server_socket_accept(NX_NULL, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Accept the Server socket with invalid socket ID. */ + status = nx_tcp_server_socket_accept(&invalid_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Accept the Server socket when disable TCP feature. */ + status = nx_tcp_server_socket_accept(&invalid_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_server_socket_listen api */ + /************************************************/ + + /* Listen the Server socket with invalid IP instance. */ + status = nx_tcp_server_socket_listen(NX_NULL, 8080, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the IP instance ID. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Listen the Server socket with invalid IP instance ID. */ + status = nx_tcp_server_socket_listen(&invalid_ip, 8080, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Listen the Server socket with invalid socket. */ + status = nx_tcp_server_socket_listen(&ip_1, 8080, NX_NULL, 5, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Listen the Server socket with invalid socket ID. */ + status = nx_tcp_server_socket_listen(&ip_1, 8080, &invalid_socket, 5, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP instance ID. */ + invalid_ip.nx_ip_id = NX_IP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_ip.nx_ip_tcp_packet_receive = NX_NULL; + + /* Listen the Server socket when disable the TCP feature. */ + status = nx_tcp_server_socket_listen(&invalid_ip, 8080, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Listen the Server socket with invalid port. */ + status = nx_tcp_server_socket_listen(&ip_1, 0, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Listen the Server socket with invalid port. */ + status = nx_tcp_server_socket_listen(&ip_1, 0xFFFFFFFF, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_server_socket_relisten api*/ + /************************************************/ + + /* Relisten the Server socket with invalid IP instance. */ + status = nx_tcp_server_socket_relisten(NX_NULL, 8080, &server_socket); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the IP instance ID. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Relisten the Server socket with invalid IP instance ID. */ + status = nx_tcp_server_socket_relisten(&invalid_ip, 8080, &server_socket); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Relisten the Server socket with invalid socket. */ + status = nx_tcp_server_socket_relisten(&ip_1, 8080, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Relisten the Server socket with invalid socket ID. */ + status = nx_tcp_server_socket_relisten(&ip_1, 8080, &invalid_socket); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP instance ID. */ + invalid_ip.nx_ip_id = NX_IP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_ip.nx_ip_tcp_packet_receive = NX_NULL; + + /* Relisten the Server socket when disable the TCP feature. */ + status = nx_tcp_server_socket_relisten(&invalid_ip, 8080, &server_socket); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Relisten the Server socket with invalid port. */ + status = nx_tcp_server_socket_relisten(&ip_1, 0, &server_socket); + + /* Check for error. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Relisten the Server socket with invalid port. */ + status = nx_tcp_server_socket_relisten(&ip_1, 0xFFFFFFFF, &server_socket); + + /* Check for error. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_server_socket_unaccept api*/ + /************************************************/ + + /* Unaccept the Server socket with invalid socket. */ + status = nx_tcp_server_socket_unaccept(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Unaccept the Server socket with invalid socket ID. */ + status = nx_tcp_server_socket_unaccept(&invalid_socket); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Unaccept the Server socket when disable TCP feature. */ + status = nx_tcp_server_socket_unaccept(&invalid_socket); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_server_socket_unlisten api*/ + /************************************************/ + + /* Unlisten the Server socket with invalid IP instance. */ + status = nx_tcp_server_socket_unlisten(NX_NULL, 8080); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the IP instance ID. */ + invalid_ip.nx_ip_id = NX_NULL; + + /* Unlisten the Server socket with invalid IP instance ID. */ + status = nx_tcp_server_socket_unlisten(&invalid_ip, 8080); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the IP instance ID. */ + invalid_ip.nx_ip_id = NX_IP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_ip.nx_ip_tcp_packet_receive = NX_NULL; + + /* Unlisten the Server socket when disable the TCP feature. */ + status = nx_tcp_server_socket_unlisten(&invalid_ip, 8080); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten the Server socket with invalid port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 0); + + /* Check for error. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unlisten the Server socket with invalid port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 0xFFFFFFFF); + + /* Check for error. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_socket_bytes_available api*/ + /************************************************/ + + /* Get the Server socket available bytes with invalid socket. */ + status = nx_tcp_socket_bytes_available(NX_NULL, &bytes_available); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Get the Server socket available bytes with invalid socket ID. */ + status = nx_tcp_socket_bytes_available(&invalid_socket, &bytes_available); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the Server socket available bytes with invalid bytes available pointer. */ + status = nx_tcp_socket_bytes_available(&server_socket, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Get the Server socket available bytes when disable the TCP feature. */ + status = nx_tcp_socket_bytes_available(&invalid_socket, &bytes_available); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_socket_disconnect api */ + /************************************************/ + + /* Disconnect the TCP with invalid socket. */ + status = nx_tcp_socket_disconnect(NX_NULL, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Disconnect the TCP with invalid socket ID. */ + status = nx_tcp_socket_disconnect(&invalid_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Disconnect the TCP when disable TCP feature. */ + status = nx_tcp_socket_disconnect(&invalid_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_socket_info_get api */ + /************************************************/ + + /* Get the TCP socket information with invalid socket. */ + status = nx_tcp_socket_info_get(NX_NULL, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Get the TCP socket information with invalid socket ID. */ + status = nx_tcp_socket_info_get(&invalid_socket, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Get the TCP socket information when disable TCP feature. */ + status = nx_tcp_socket_info_get(&invalid_socket, &packets_sent, &bytes_sent, + &packets_received, &bytes_received, + &retransmit_packets, &packets_queued, + &checksum_errors, &socket_state, + &transmit_queue_depth, &transmit_window, + &receive_window); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_socket_mss_get api */ + /************************************************/ + + /* Get the socket mss with invalid socket. */ + status = nx_tcp_socket_mss_get(NX_NULL, &mss); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Get the socket mss with invalid socket. */ + status = nx_tcp_socket_mss_get(&invalid_socket, &mss); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the socket mss with invalid mss pointer. */ + status = nx_tcp_socket_mss_get(&client_socket, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Get the socket mss when disable TCP feature. */ + status = nx_tcp_socket_mss_get(&invalid_socket, &mss); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_socket_mss_peer_get api */ + /************************************************/ + + /* Get the peer socket mss with invalid socket. */ + status = nx_tcp_socket_mss_peer_get(NX_NULL, &peer_mss); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Get the peer socket mss with invalid socket. */ + status = nx_tcp_socket_mss_peer_get(&invalid_socket, &peer_mss); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the peer socket mss with invalid mss pointer. */ + status = nx_tcp_socket_mss_peer_get(&client_socket, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Get the peer socket mss when disable TCP feature. */ + status = nx_tcp_socket_mss_peer_get(&invalid_socket, &peer_mss); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_socket_mss_set api */ + /************************************************/ + + /* Set the socket mss with invalid socket. */ + status = nx_tcp_socket_mss_set(NX_NULL, 512); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Set the socket mss with invalid socket. */ + status = nx_tcp_socket_mss_set(&invalid_socket, 512); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Set the socket mss when disable TCP feature. */ + status = nx_tcp_socket_mss_set(&invalid_socket, 512); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_socket_peer_info_get api */ + /************************************************/ + + /* Get peer socket information with invalid socket. */ + status = nx_tcp_socket_peer_info_get(NX_NULL, &peer_ip_address, &peer_port); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Get peer socket information with invalid socket ID. */ + status = nx_tcp_socket_peer_info_get(&invalid_socket, &peer_ip_address, &peer_port); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get peer socket information with invalid peer IP address pointer. */ + status = nx_tcp_socket_peer_info_get(&client_socket, NX_NULL, &peer_port); + + /* Check for error. */ +#ifdef __PRODUCT_NETXDUO__ + if (status != NX_PTR_ERROR) +#else + if (status != NX_NOT_CONNECTED) +#endif + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get peer socket information with invalid peer port pointer. */ + status = nx_tcp_socket_peer_info_get(&client_socket, &peer_ip_address, NX_NULL); + + /* Check for error. */ +#ifdef __PRODUCT_NETXDUO__ + if (status != NX_PTR_ERROR) +#else + if (status != NX_NOT_CONNECTED) +#endif + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Get peer socket information when disable TCP feature. */ + status = nx_tcp_socket_peer_info_get(&invalid_socket, &peer_ip_address, &peer_port); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + +#ifdef FEATURE_NX_IPV6 + /************************************************/ + /* Tested the nxde_tcp_socket_peer_info_get api */ + /************************************************/ + + /* Get peer socket information with invalid socket. */ + status = nxd_tcp_socket_peer_info_get(NX_NULL, &nxd_ip_address, &peer_port); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Get peer socket information with invalid socket ID. */ + status = nxd_tcp_socket_peer_info_get(&invalid_socket, &nxd_ip_address, &peer_port); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get peer socket information with invalid peer IP address pointer. */ + status = nxd_tcp_socket_peer_info_get(&client_socket, NX_NULL, &peer_port); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get peer socket information with invalid peer port pointer. */ + status = nxd_tcp_socket_peer_info_get(&client_socket, &nxd_ip_address, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Get peer socket information when disable TCP feature. */ + status = nxd_tcp_socket_peer_info_get(&invalid_socket, &nxd_ip_address, &peer_port); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + +#if defined(NX_ENABLE_TCP_QUEUE_DEPTH_UPDATE_NOTIFY) && defined(__PRODUCT_NETXDUO__) + /*******************************************************/ + /* Tested the nxe_tcp_socket_queue_depth_notify_set api*/ + /*******************************************************/ + + /* Set the queue depth notify function with invalid socket. */ + status = nx_tcp_socket_queue_depth_notify_set(NX_NULL, tcp_socket_queue_depth_notify); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Set the queue depth notify function with invalid socket ID. */ + status = nx_tcp_socket_queue_depth_notify_set(&invalid_socket, tcp_socket_queue_depth_notify); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the queue depth notify function with invalid callback pointer. */ + status = nx_tcp_socket_queue_depth_notify_set(&client_socket, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Set the queue depth notify function when disable TCP feature. */ + status = nx_tcp_socket_queue_depth_notify_set(&invalid_socket, tcp_socket_queue_depth_notify); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /************************************************/ + /* Tested the nxe_tcp_socket_receive api */ + /************************************************/ + + /* Receive a TCP message with invalid socket. */ + status = nx_tcp_socket_receive(NX_NULL, &packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Receive a TCP message with invalid socket ID. */ + status = nx_tcp_socket_receive(&invalid_socket, &packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a TCP message with invalid packet pointer. */ + status = nx_tcp_socket_receive(&server_socket, NX_NULL, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Receive a TCP message with invalid packet pointer. */ + status = nx_tcp_socket_receive(&invalid_socket, &packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_socket_receive_notify api */ + /************************************************/ + + /* Set the socket receive notify function with invalid socket. */ + status = nx_tcp_socket_receive_notify(NX_NULL, tcp_receive_notify); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Set the socket receive notify function with invalid socket. */ + status = nx_tcp_socket_receive_notify(&invalid_socket, tcp_receive_notify); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Clear socket receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Set the socket receive notify function when disable TCP feature. */ + status = nx_tcp_socket_receive_notify(&invalid_socket, tcp_receive_notify); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ + + /************************************************/ + /* Tested the nxe_tcp_socket_send api */ + /************************************************/ + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the packet with invalid socket. */ + status = nx_tcp_socket_send(NX_NULL, packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Send the packet with invalid socket. */ + status = nx_tcp_socket_send(&invalid_socket, packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the packet with invalid packet. */ + unknow_packet = NX_NULL; + status = nx_tcp_socket_send(&client_socket, unknow_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_PACKET) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Send the packet with freed packet. */ + packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_FREE; + status = nx_tcp_socket_send(&client_socket, packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_INVALID_PACKET) + { + + printf("ERROR!\n"); + test_control_return(1); + } + packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; +#endif + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Send the packet when disable TCP feature. */ + status = nx_tcp_socket_send(&invalid_socket, packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Set the socket ID, tcp_packet_receive and connect IP address. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + invalid_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_NULL; + + /* Send the packet with invalid connect IP address. */ + status = nx_tcp_socket_send(&invalid_socket, packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_CONNECTED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID, tcp_packet_receive and connect IP address. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + invalid_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + + /* Send the invalid packet that prepend pointer is less than data start. */ + invalid_packet_2 = (NX_PACKET *) &invalid_packet; + invalid_packet_2 -> nx_packet_pool_owner = (NX_PACKET_POOL *) &invalid_pool; + invalid_packet_2 -> nx_packet_pool_owner -> nx_packet_pool_id = NX_PACKET_POOL_ID; + invalid_packet_2 -> nx_packet_data_start = (UCHAR *)0x20; + invalid_packet_2 -> nx_packet_prepend_ptr = (UCHAR *)0x10; + invalid_packet_2 -> nx_packet_append_ptr = (UCHAR *)0x30; + invalid_packet_2 -> nx_packet_data_end = (UCHAR *)0x40; + invalid_packet_2 -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *) NX_PACKET_ALLOCATED; + status = nx_tcp_socket_send(&invalid_socket, invalid_packet_2, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_UNDERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append packet with invalid packet that prepend pointer is less than data start. */ + invalid_packet_2 = (NX_PACKET *) &invalid_packet; + invalid_packet_2 -> nx_packet_pool_owner = (NX_PACKET_POOL *) &invalid_pool; + invalid_packet_2 -> nx_packet_pool_owner -> nx_packet_pool_id = NX_PACKET_POOL_ID; + invalid_packet_2 -> nx_packet_data_start = (UCHAR *)0x10; + invalid_packet_2 -> nx_packet_prepend_ptr = (UCHAR *)0x40; + invalid_packet_2 -> nx_packet_append_ptr = (UCHAR *)0x80; + invalid_packet_2 -> nx_packet_data_end = (UCHAR *)0x60; + invalid_packet_2 -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *) NX_PACKET_ALLOCATED; + status = nx_tcp_socket_send(&invalid_socket, invalid_packet_2, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_OVERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet*/ + status = nx_packet_release(packet); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ + + /************************************************/ + /* Tested the nxe_tcp_socket_state_wait api */ + /************************************************/ + + /* Wait for state with invalid socket. */ + status = nx_tcp_socket_state_wait(NX_NULL, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Wait for state with invalid socket ID. */ + status = nx_tcp_socket_state_wait(&invalid_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Wait for state when disable TCP feature. */ + status = nx_tcp_socket_state_wait(&invalid_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for state with invalid desired state. */ + status = nx_tcp_socket_state_wait(&client_socket, 0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for state with invalid desired state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_LAST_ACK + 1, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /***************************************************/ + /* Tested the nxe_tcp_socket_transmit_configure api*/ + /***************************************************/ + + /* Configure the socket further with invalid socket. */ + status = nx_tcp_socket_transmit_configure(NX_NULL, 10, 300, 10, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Configure the socket further with invalid socket ID. */ + status = nx_tcp_socket_transmit_configure(&invalid_socket, 10, 300, 10, 0); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Configure the socket further with invalid max queue depth. */ + status = nx_tcp_socket_transmit_configure(&server_socket, 0, 300, 10, 0); + + /* Check for error. */ + if (status != NX_OPTION_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Configure the socket further when disable TCP feature. */ + status = nx_tcp_socket_transmit_configure(&invalid_socket, 10, 300, 10, 0); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /*********************************************************/ + /* Tested the nxe_tcp_socket_window_update_notify_set api*/ + /*********************************************************/ + + /* Set the queue depth notify function with invalid socket. */ + status = nx_tcp_socket_window_update_notify_set(NX_NULL, window_update_notify); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Set the queue depth notify function with invalid socket. */ + status = nx_tcp_socket_window_update_notify_set(&invalid_socket, window_update_notify); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the queue depth notify function with invalid notify function. */ + status = nx_tcp_socket_window_update_notify_set(&client_socket, NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Set the queue depth notify function when disable TCP feature. */ + status = nx_tcp_socket_window_update_notify_set(&invalid_socket, window_update_notify); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /************************************************/ + /* Tested the nxe_tcp_socket_delete api */ + /************************************************/ + + /* Delete the TCP socket with invalid socket. */ + status = nx_tcp_socket_delete(NX_NULL); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Delete the TCP socket with invalid socket ID. */ + status = nx_tcp_socket_delete(&invalid_socket); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Disable the TCP feature for invalid IP instance. */ + invalid_socket.nx_tcp_socket_ip_ptr = (NX_IP *)&invalid_ip; + invalid_socket.nx_tcp_socket_ip_ptr -> nx_ip_tcp_packet_receive = NX_NULL; + + /* Delete the TCP socket when disable TCP feature. */ + status = nx_tcp_socket_delete(&invalid_socket); + + /* Check for error. */ + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef NX_ENABLE_LOW_WATERMARK + /* Clear the socket ID. */ + invalid_socket.nx_tcp_socket_id = NX_NULL; + + /* Set receive queue to invalid socket. */ + status = nx_tcp_socket_receive_queue_max_set(&invalid_socket, 10); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_ENABLE_LOW_WATERMARK */ +#endif /* __PRODUCT_NETXDUO__ */ + + printf("SUCCESS!\n"); + test_control_return(0); +} + +#if defined(NX_ENABLE_TCP_QUEUE_DEPTH_UPDATE_NOTIFY) && defined(__PRODUCT_NETXDUO__) +static void tcp_socket_queue_depth_notify(NX_TCP_SOCKET *socket_ptr) +{ +} +#endif +#ifdef __PRODUCT_NETXDUO__ +static void window_update_notify(NX_TCP_SOCKET *socket_ptr) +{ +} +#endif /* __PRODUCT_NETXDUO__ */ +static void tcp_receive_notify(NX_TCP_SOCKET *socket_ptr) +{ +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP NXE API Test..........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_odd_window_test.c b/test/regression/netxduo_test/netx_tcp_odd_window_test.c new file mode 100644 index 00000000..563a39ac --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_odd_window_test.c @@ -0,0 +1,314 @@ +/* This NetX test concentrates on the odd window of TCP transmission. */ +/* Window size is 800 bytes. Payload size of pool is 512. + * 1. Host A sends 1 byte. So the remaining window is 799. + * 2. Host A sends 1499 bytes. */ + +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static UCHAR send_buff[1500]; +static UCHAR recv_buff[1500]; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_odd_window_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; +UINT i; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + for (i = 0; i < sizeof(send_buff); i++) + { + send_buff[i] = i & 0xFF; + recv_buff[i] = 0xFF - (i & 0xFF); + } + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 10240); + pointer = pointer + 10240; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Odd Window Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, 1, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff + 1, sizeof(send_buff) - 1, + &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG total_length = 0; +ULONG bytes_copied; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 800, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 3 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + /* Retrieve data. */ + nx_packet_data_retrieve(packet_ptr, recv_buff + total_length, &bytes_copied); + total_length += bytes_copied; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Check received data. */ + if (total_length != sizeof(send_buff)) + error_counter++; + else if (memcmp(send_buff, recv_buff, sizeof(send_buff)) != 0) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_odd_window_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Odd Window Test.......................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_out_of_order_ack_test.c b/test/regression/netxduo_test/netx_tcp_out_of_order_ack_test.c new file mode 100644 index 00000000..ff3c7bdf --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_out_of_order_ack_test.c @@ -0,0 +1,2801 @@ +/* This case tests the get content length task which should allow zero or more white + spaces between field name (Content-Length) and value. +*/ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT); + +#if (NX_TCP_MAX_OUT_OF_ORDER_PACKETS == 8) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +/* Set up the HTTP client global variables. */ + +#define CLIENT_PACKET_SIZE (1536 + sizeof(NX_PACKET)) +#define CLIENT_POOL_SIZE (CLIENT_PACKET_SIZE * 30) + +static TX_THREAD client_thread; +static TX_THREAD server_thread; +static NX_PACKET_POOL client_pool; +static NX_TCP_SOCKET client_socket; +static NX_IP client_ip; +static UINT error_counter; +static UINT tcp_connected = NX_FALSE; +static UINT packet_received_counter = 0; +static UINT packet_response_sent= NX_FALSE; +static UINT test_done = NX_FALSE; +static UINT received_data_size = 0; +static ULONG pool_stack[CLIENT_POOL_SIZE / sizeof(ULONG)]; + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void test_initialize(); +static VOID response_packet_inject(UCHAR *data_ptr, UINT data_size); + +#define CLIENT_ADDRESS IP_ADDRESS(192,168,2,3) +#define SERVER_ADDRESS IP_ADDRESS(152,199,19,161) +#define GATEWAY_ADDRESS IP_ADDRESS(192,168,2,1) + +#define RESPONSE_COUNT 14 + +typedef struct RESPONSE_STRUCT +{ + char *response_pkt_data; + int response_pkt_size; +} RESPONSE; + +static RESPONSE response[RESPONSE_COUNT]; + +/* Frame (58 bytes) */ +static const unsigned char pkt2[58] = { +0x02, 0x00, 0x00, 0x70, 0xca, 0x04, 0x5e, 0xe9, /* ...p..^. */ +0x1e, 0xa6, 0x21, 0x64, 0x08, 0x00, 0x45, 0x00, /* ..!d..E. */ +0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x33, 0x06, /* .,....3. */ +0x18, 0xb9, 0x98, 0xc7, 0x13, 0xa1, 0xc0, 0xa8, /* ........ */ +0x02, 0x03, 0x00, 0x50, 0xc9, 0xc1, 0xb1, 0x64, /* ...P...d */ +0xb8, 0x70, 0xfa, 0xdf, 0xde, 0x78, 0x60, 0x12, /* .p...x`. */ +0xff, 0xff, 0x1b, 0xc3, 0x00, 0x00, 0x02, 0x04, /* ........ */ +0x05, 0xb4 /* .. */ +}; + +/* Frame (54 bytes) */ +static const unsigned char pkt5[54] = { +0x02, 0x00, 0x00, 0x70, 0xca, 0x04, 0x5e, 0xe9, /* ...p..^. */ +0x1e, 0xa6, 0x21, 0x64, 0x08, 0x00, 0x45, 0x00, /* ..!d..E. */ +0x00, 0x28, 0xe7, 0xc9, 0x00, 0x00, 0x33, 0x06, /* .(....3. */ +0x30, 0xf3, 0x98, 0xc7, 0x13, 0xa1, 0xc0, 0xa8, /* 0....... */ +0x02, 0x03, 0x00, 0x50, 0xc9, 0xc1, 0xb1, 0x64, /* ...P...d */ +0xb8, 0x71, 0xfa, 0xdf, 0xdf, 0x46, 0x50, 0x10, /* .q...FP. */ +0xff, 0xff, 0x32, 0xb2, 0x00, 0x00 /* ..2... */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt6[1514] = { +0x02, 0x00, 0x00, 0x70, 0xca, 0x04, 0x5e, 0xe9, /* ...p..^. */ +0x1e, 0xa6, 0x21, 0x64, 0x08, 0x00, 0x45, 0x00, /* ..!d..E. */ +0x05, 0xdc, 0xe7, 0xca, 0x00, 0x00, 0x33, 0x06, /* ......3. */ +0x2b, 0x3e, 0x98, 0xc7, 0x13, 0xa1, 0xc0, 0xa8, /* +>...... */ +0x02, 0x03, 0x00, 0x50, 0xc9, 0xc1, 0xb1, 0x64, /* ...P...d */ +0xb8, 0x71, 0xfa, 0xdf, 0xdf, 0x46, 0x50, 0x10, /* .q...FP. */ +0xff, 0xff, 0xd4, 0x09, 0x00, 0x00, 0x48, 0x54, /* ......HT */ +0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x32, /* TP/1.1 2 */ +0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d, 0x0a, 0x41, /* 00 OK..A */ +0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x52, 0x61, /* ccept-Ra */ +0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20, 0x62, 0x79, /* nges: by */ +0x74, 0x65, 0x73, 0x0d, 0x0a, 0x41, 0x67, 0x65, /* tes..Age */ +0x3a, 0x20, 0x36, 0x36, 0x39, 0x36, 0x30, 0x36, /* : 669606 */ +0x0d, 0x0a, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, /* ..Cache- */ +0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, /* Control: */ +0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2c, /* public, */ +0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, 0x3d, /* max-age= */ +0x31, 0x37, 0x32, 0x38, 0x30, 0x30, 0x30, 0x30, /* 17280000 */ +0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, /* ..Conten */ +0x74, 0x2d, 0x44, 0x69, 0x73, 0x70, 0x6f, 0x73, /* t-Dispos */ +0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, /* ition: a */ +0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, /* ttachmen */ +0x74, 0x3b, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x6e, /* t; filen */ +0x61, 0x6d, 0x65, 0x3d, 0x70, 0x6f, 0x63, 0x5f, /* ame=poc_ */ +0x61, 0x69, 0x5f, 0x31, 0x2e, 0x30, 0x2e, 0x37, /* ai_1.0.7 */ +0x2e, 0x62, 0x69, 0x6e, 0x3b, 0x20, 0x66, 0x69, /* .bin; fi */ +0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x2a, 0x3d, /* lename*= */ +0x75, 0x74, 0x66, 0x2d, 0x38, 0x27, 0x27, 0x70, /* utf-8''p */ +0x6f, 0x63, 0x5f, 0x61, 0x69, 0x5f, 0x31, 0x2e, /* oc_ai_1. */ +0x30, 0x2e, 0x37, 0x2e, 0x62, 0x69, 0x6e, 0x0d, /* 0.7.bin. */ +0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, /* .Content */ +0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, /* -Type: a */ +0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, /* pplicati */ +0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, /* on/octet */ +0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x0d, /* -stream. */ +0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46, /* .Date: F */ +0x72, 0x69, 0x2c, 0x20, 0x30, 0x39, 0x20, 0x4a, /* ri, 09 J */ +0x75, 0x6e, 0x20, 0x32, 0x30, 0x32, 0x33, 0x20, /* un 2023 */ +0x30, 0x37, 0x3a, 0x30, 0x39, 0x3a, 0x32, 0x35, /* 07:09:25 */ +0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x45, 0x74, /* GMT..Et */ +0x61, 0x67, 0x3a, 0x20, 0x22, 0x61, 0x68, 0x78, /* ag: "ahx */ +0x6b, 0x4a, 0x33, 0x59, 0x78, 0x36, 0x37, 0x63, /* kJ3Yx67c */ +0x70, 0x6c, 0x57, 0x2b, 0x7a, 0x55, 0x55, 0x7a, /* plW+zUUz */ +0x6a, 0x73, 0x55, 0x59, 0x75, 0x69, 0x76, 0x45, /* jsUYuivE */ +0x6e, 0x47, 0x66, 0x72, 0x6b, 0x4b, 0x74, 0x6e, /* nGfrkKtn */ +0x58, 0x50, 0x76, 0x41, 0x36, 0x4c, 0x71, 0x77, /* XPvA6Lqw */ +0x3d, 0x22, 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, /* ="..Last */ +0x2d, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, /* -Modifie */ +0x64, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, /* d: Thu, */ +0x30, 0x31, 0x20, 0x4a, 0x75, 0x6e, 0x20, 0x32, /* 01 Jun 2 */ +0x30, 0x32, 0x33, 0x20, 0x31, 0x33, 0x3a, 0x30, /* 023 13:0 */ +0x36, 0x3a, 0x33, 0x32, 0x20, 0x47, 0x4d, 0x54, /* 6:32 GMT */ +0x0d, 0x0a, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, /* ..Server */ +0x3a, 0x20, 0x45, 0x43, 0x41, 0x63, 0x63, 0x20, /* : ECAcc */ +0x28, 0x70, 0x61, 0x61, 0x2f, 0x36, 0x46, 0x34, /* (paa/6F4 */ +0x32, 0x29, 0x0d, 0x0a, 0x74, 0x72, 0x61, 0x63, /* 2)..trac */ +0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3a, /* eparent: */ +0x20, 0x30, 0x30, 0x2d, 0x35, 0x37, 0x62, 0x35, /* 00-57b5 */ +0x62, 0x31, 0x66, 0x33, 0x66, 0x61, 0x32, 0x34, /* b1f3fa24 */ +0x32, 0x36, 0x62, 0x65, 0x36, 0x65, 0x65, 0x32, /* 26be6ee2 */ +0x38, 0x34, 0x32, 0x66, 0x31, 0x38, 0x30, 0x66, /* 842f180f */ +0x61, 0x31, 0x66, 0x32, 0x2d, 0x39, 0x35, 0x30, /* a1f2-950 */ +0x66, 0x30, 0x33, 0x37, 0x32, 0x32, 0x64, 0x30, /* f03722d0 */ +0x32, 0x63, 0x65, 0x39, 0x66, 0x2d, 0x30, 0x30, /* 2ce9f-00 */ +0x0d, 0x0a, 0x58, 0x2d, 0x41, 0x7a, 0x75, 0x72, /* ..X-Azur */ +0x65, 0x2d, 0x52, 0x65, 0x66, 0x2d, 0x4f, 0x72, /* e-Ref-Or */ +0x69, 0x67, 0x69, 0x6e, 0x53, 0x68, 0x69, 0x65, /* iginShie */ +0x6c, 0x64, 0x3a, 0x20, 0x52, 0x65, 0x66, 0x20, /* ld: Ref */ +0x41, 0x3a, 0x20, 0x37, 0x34, 0x46, 0x36, 0x38, /* A: 74F68 */ +0x42, 0x37, 0x44, 0x34, 0x37, 0x39, 0x37, 0x34, /* B7D47974 */ +0x30, 0x34, 0x38, 0x38, 0x44, 0x34, 0x36, 0x42, /* 0488D46B */ +0x35, 0x46, 0x31, 0x38, 0x39, 0x39, 0x36, 0x43, /* 5F18996C */ +0x42, 0x31, 0x37, 0x20, 0x52, 0x65, 0x66, 0x20, /* B17 Ref */ +0x42, 0x3a, 0x20, 0x41, 0x4d, 0x53, 0x32, 0x33, /* B: AMS23 */ +0x31, 0x30, 0x32, 0x31, 0x30, 0x31, 0x34, 0x30, /* 10210140 */ +0x31, 0x39, 0x20, 0x52, 0x65, 0x66, 0x20, 0x43, /* 19 Ref C */ +0x3a, 0x20, 0x32, 0x30, 0x32, 0x33, 0x2d, 0x30, /* : 2023-0 */ +0x36, 0x2d, 0x30, 0x31, 0x54, 0x31, 0x33, 0x3a, /* 6-01T13: */ +0x30, 0x39, 0x3a, 0x31, 0x39, 0x5a, 0x0d, 0x0a, /* 09:19Z.. */ +0x58, 0x2d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x3a, /* X-Cache: */ +0x20, 0x48, 0x49, 0x54, 0x0d, 0x0a, 0x58, 0x2d, /* HIT..X- */ +0x43, 0x43, 0x43, 0x3a, 0x20, 0x46, 0x52, 0x0d, /* CCC: FR. */ +0x0a, 0x58, 0x2d, 0x43, 0x49, 0x44, 0x3a, 0x20, /* .X-CID: */ +0x31, 0x31, 0x0d, 0x0a, 0x58, 0x2d, 0x44, 0x43, /* 11..X-DC */ +0x53, 0x4f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x2d, /* SOrigin- */ +0x52, 0x65, 0x66, 0x3a, 0x20, 0x77, 0x65, 0x73, /* Ref: wes */ +0x74, 0x65, 0x75, 0x72, 0x6f, 0x70, 0x65, 0x0d, /* teurope. */ +0x0a, 0x58, 0x2d, 0x4d, 0x53, 0x45, 0x64, 0x67, /* .X-MSEdg */ +0x65, 0x2d, 0x52, 0x65, 0x66, 0x3a, 0x20, 0x52, /* e-Ref: R */ +0x65, 0x66, 0x20, 0x41, 0x3a, 0x20, 0x30, 0x32, /* ef A: 02 */ +0x41, 0x31, 0x41, 0x46, 0x32, 0x43, 0x34, 0x42, /* A1AF2C4B */ +0x31, 0x35, 0x34, 0x33, 0x43, 0x30, 0x39, 0x36, /* 1543C096 */ +0x31, 0x36, 0x36, 0x31, 0x41, 0x35, 0x42, 0x38, /* 1661A5B8 */ +0x39, 0x45, 0x39, 0x31, 0x30, 0x32, 0x20, 0x52, /* 9E9102 R */ +0x65, 0x66, 0x20, 0x42, 0x3a, 0x20, 0x4d, 0x49, /* ef B: MI */ +0x4c, 0x33, 0x30, 0x45, 0x44, 0x47, 0x45, 0x31, /* L30EDGE1 */ +0x33, 0x30, 0x37, 0x20, 0x52, 0x65, 0x66, 0x20, /* 307 Ref */ +0x43, 0x3a, 0x20, 0x32, 0x30, 0x32, 0x33, 0x2d, /* C: 2023- */ +0x30, 0x36, 0x2d, 0x30, 0x31, 0x54, 0x31, 0x33, /* 06-01T13 */ +0x3a, 0x30, 0x39, 0x3a, 0x31, 0x39, 0x5a, 0x0d, /* :09:19Z. */ +0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, /* .Content */ +0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, /* -Length: */ +0x20, 0x31, 0x31, 0x35, 0x38, 0x32, 0x38, 0x0d, /* 115828. */ +0x0a, 0x0d, 0x0a, 0x3d, 0xb8, 0xf3, 0x96, 0x00, /* ...=.... */ +0xc0, 0x06, 0x0c, 0x20, 0x00, 0x6c, 0x00, 0xa0, /* ... .l.. */ +0xc2, 0x01, 0x00, 0x04, 0x01, 0x00, 0x00, 0x02, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0xbd, 0x7a, 0xc1, 0x28, 0x96, /* ....z.(. */ +0x4a, 0xc6, 0x2a, 0x59, 0x4e, 0xb4, 0x0c, 0xfc, /* J.*YN... */ +0xfb, 0x4d, 0x63, 0xa7, 0x2f, 0x4c, 0x9d, 0xf4, /* .Mc./L.. */ +0x3e, 0xb3, 0xa4, 0xc8, 0xb0, 0x7e, 0x3e, 0x65, /* >....~>e */ +0xdc, 0x62, 0xbf, 0x76, 0x13, 0x85, 0x9a, 0xc6, /* .b.v.... */ +0xe6, 0x18, 0xad, 0xf1, 0xc0, 0x84, 0xf7, 0xc3, /* ........ */ +0xbe, 0x1f, 0xd3, 0x09, 0x03, 0xfd, 0x19, 0x9c, /* ........ */ +0x04, 0xdd, 0x91, 0x5f, 0x1e, 0x87, 0x93, 0x6a, /* ..._...j */ +0x48, 0xca, 0xc4, 0xb1, 0xb9, 0x90, 0xd3, 0x28, /* H......( */ +0xe9, 0x0b, 0x9c, 0x7c, 0x6f, 0x0c, 0x25, 0xba, /* ...|o.%. */ +0xed, 0xb9, 0xf5, 0x14, 0x27, 0x09, 0x15, 0x10, /* ....'... */ +0x24, 0xfd, 0x6d, 0x3f, 0xdb, 0xb5, 0x1a, 0x96, /* $.m?.... */ +0xd4, 0x45, 0xeb, 0x21, 0xcd, 0x86, 0x9f, 0x95, /* .E.!.... */ +0x47, 0xee, 0x24, 0x5e, 0x04, 0xbd, 0x22, 0xe5, /* G.$^..". */ +0x94, 0x02, 0x3d, 0x43, 0x51, 0x9c, 0x6b, 0xb1, /* ..=CQ.k. */ +0x40, 0x1f, 0x37, 0x37, 0xd2, 0x93, 0x8f, 0x75, /* @.77...u */ +0x9c, 0xc3, 0xd8, 0x8e, 0x30, 0x2a, 0x2c, 0xf9, /* ....0*,. */ +0xf7, 0xdf, 0x4b, 0x86, 0x03, 0xbd, 0x03, 0x5c, /* ..K....\ */ +0x73, 0x62, 0x7a, 0x82, 0x5e, 0x4f, 0x5f, 0x1d, /* sbz.^O_. */ +0x4e, 0x67, 0x3e, 0xa0, 0xc6, 0x60, 0xfe, 0x06, /* Ng>..`.. */ +0xa7, 0xef, 0xd4, 0x59, 0x0b, 0x26, 0xa0, 0x37, /* ...Y.&.7 */ +0xcb, 0x42, 0x4a, 0x03, 0x09, 0xf0, 0x44, 0x33, /* .BJ...D3 */ +0x8a, 0x91, 0x21, 0x06, 0xa3, 0x14, 0x4b, 0xa3, /* ..!...K. */ +0xf7, 0xb2, 0xde, 0x28, 0x7c, 0x4f, 0x6f, 0x55, /* ...(|OoU */ +0x10, 0x75, 0xa7, 0xb1, 0x8c, 0x7f, 0x99, 0x9b, /* .u...... */ +0x61, 0x89, 0xdd, 0x22, 0xf8, 0xfb, 0x4f, 0x8d, /* a.."..O. */ +0x5c, 0x5d, 0x0b, 0x0e, 0x76, 0x6e, 0xcf, 0xf2, /* \]..vn.. */ +0x09, 0x1b, 0x9d, 0xaf, 0xe2, 0x17, 0x2c, 0x23, /* ......,# */ +0x77, 0xcf, 0xe2, 0xe1, 0xf9, 0xa9, 0xf0, 0x4e, /* w......N */ +0x50, 0xe6, 0x8f, 0xa1, 0x64, 0x16, 0x20, 0x2f, /* P...d. / */ +0x53, 0x09, 0xed, 0xf4, 0x0d, 0x71, 0x8b, 0x2e, /* S....q.. */ +0x50, 0x1b, 0xe5, 0x0f, 0x12, 0x92, 0xc0, 0xb6, /* P....... */ +0xa3, 0x8c, 0x82, 0x58, 0x57, 0x6e, 0xeb, 0xf6, /* ...XWn.. */ +0xc3, 0x76, 0xb0, 0x90, 0x68, 0xde, 0xa7, 0x11, /* .v..h... */ +0xb9, 0xb9, 0x97, 0x56, 0xea, 0x6f, 0xd0, 0x41, /* ...V.o.A */ +0xd0, 0xa1, 0xb3, 0xb3, 0x26, 0x81, 0x29, 0x34, /* ....&.)4 */ +0xe1, 0x4f, 0x52, 0x10, 0x0e, 0x40, 0xa4, 0x5b, /* .OR..@.[ */ +0x95, 0x61, 0x41, 0x66, 0xd1, 0x3c, 0x81, 0x36, /* .aAf.<.6 */ +0x8d, 0x6d, 0x89, 0xa1, 0x18, 0xa5, 0x98, 0x5c, /* .m.....\ */ +0x13, 0x29, 0x1e, 0x77, 0xb5, 0xa3, 0xd1, 0x5f, /* .).w..._ */ +0x64, 0xb8, 0x03, 0x6c, 0x02, 0x78, 0x43, 0x1f, /* d..l.xC. */ +0xa8, 0xbe, 0x6b, 0xc2, 0xfe, 0xb2, 0x12, 0xee, /* ..k..... */ +0xeb, 0x2a, 0xe5, 0x13, 0x2f, 0x40, 0x29, 0x81, /* .*../@). */ +0x7e, 0x1a, 0x1b, 0x2f, 0xaf, 0x94, 0x79, 0x4a, /* ~../..yJ */ +0x63, 0x18, 0xdf, 0x76, 0x59, 0x18, 0x48, 0x02, /* c..vY.H. */ +0x9e, 0xa5, 0x80, 0xd3, 0x7d, 0xd2, 0xbd, 0x34, /* ....}..4 */ +0x43, 0x2f, 0xbd, 0x95, 0x55, 0xaf, 0x60, 0x1f, /* C/..U.`. */ +0x52, 0xe9, 0x17, 0x3e, 0x34, 0x3d, 0x0d, 0x15, /* R..>4=.. */ +0xb5, 0x2c, 0xd2, 0xcf, 0x97, 0x3b, 0xbf, 0xb2, /* .,...;.. */ +0x2d, 0xa1, 0x06, 0x09, 0xfc, 0xeb, 0xa0, 0xca, /* -....... */ +0x49, 0xd5, 0xf6, 0xdc, 0x84, 0xa0, 0xe2, 0x88, /* I....... */ +0xbc, 0x81, 0xb7, 0x50, 0x9e, 0xab, 0x6b, 0x2f, /* ...P..k/ */ +0x84, 0xe7, 0xe2, 0x15, 0x8d, 0xf2, 0x18, 0x97, /* ........ */ +0xd4, 0x8e, 0xea, 0x79, 0x08, 0x76, 0x76, 0xf7, /* ...y.vv. */ +0x04, 0xf3, 0x04, 0x19, 0x10, 0xdb, 0x6c, 0x95, /* ......l. */ +0xb7, 0x5f, 0x9d, 0x81, 0x48, 0xa8, 0x1f, 0x1b, /* ._..H... */ +0x19, 0x9f, 0x99, 0xb2, 0xd7, 0x13, 0x49, 0x97, /* ......I. */ +0x33, 0x8a, 0x41, 0x0c, 0x37, 0x76, 0xca, 0x14, /* 3.A.7v.. */ +0x14, 0x8b, 0x9a, 0x15, 0x49, 0x6f, 0x79, 0x5b, /* ....Ioy[ */ +0x46, 0xd1, 0x15, 0xb6, 0x20, 0x3a, 0xf0, 0xed, /* F... :.. */ +0xa8, 0x4f, 0x8b, 0xf2, 0xb9, 0x14, 0xfc, 0xa9, /* .O...... */ +0xca, 0x25, 0x4b, 0xfc, 0x20, 0x72, 0xe9, 0x3a, /* .%K. r.: */ +0xa7, 0x37, 0xfe, 0x0f, 0x29, 0xbe, 0xc2, 0xc3, /* .7..)... */ +0x3a, 0xaa, 0xe1, 0xd5, 0x2f, 0x03, 0xd0, 0xa0, /* :.../... */ +0x85, 0x35, 0x65, 0xb4, 0x3a, 0x16, 0x0c, 0x67, /* .5e.:..g */ +0xac, 0x37, 0xdc, 0x6d, 0xe4, 0xc2, 0x69, 0x09, /* .7.m..i. */ +0x42, 0x32, 0x38, 0x1b, 0xb7, 0x52, 0xa9, 0x88, /* B28..R.. */ +0x0d, 0x27, 0x6d, 0x12, 0x21, 0xf1, 0xba, 0x84, /* .'m.!... */ +0xb6, 0x93, 0x7c, 0x8c, 0x19, 0xe0, 0x6f, 0x1e, /* ..|...o. */ +0x2b, 0xa0, 0xc8, 0x27, 0x49, 0xc7, 0xe8, 0xe6, /* +..'I... */ +0x5e, 0x8e, 0x43, 0xb8, 0xda, 0x2a, 0x8c, 0x33, /* ^.C..*.3 */ +0xf4, 0x3c, 0xd8, 0x4f, 0x77, 0x5e, 0xe6, 0x84, /* .<.Ow^.. */ +0x80, 0x52, 0xbe, 0x20, 0x30, 0x04, 0x06, 0x1f, /* .R. 0... */ +0x9a, 0x6f, 0x2f, 0xd5, 0xc6, 0x2a, 0x56, 0x03, /* .o/..*V. */ +0x0a, 0x0a, 0x0c, 0xd8, 0x88, 0x37, 0x08, 0xa1, /* .....7.. */ +0x10, 0x68, 0x9f, 0x77, 0x0e, 0x9e, 0xaf, 0xb6, /* .h.w.... */ +0x7e, 0xf0, 0x74, 0x6c, 0x5a, 0x87, 0x11, 0xeb, /* ~.tlZ... */ +0x06, 0x4e, 0x8d, 0x53, 0x8d, 0xc1, 0x56, 0xa0, /* .N.S..V. */ +0xe8, 0x31, 0x49, 0xb7, 0x7f, 0xfb, 0xe7, 0xbf, /* .1I..... */ +0x5e, 0x57, 0xc1, 0x45, 0xbc, 0xcd, 0x08, 0xbf, /* ^W.E.... */ +0x9c, 0x72, 0x47, 0x67, 0xd0, 0xbc, 0xe4, 0x6a, /* .rGg...j */ +0x5b, 0x6b, 0xfd, 0x18, 0x66, 0xdd, 0x20, 0x0b, /* [k..f. . */ +0x7e, 0xa5 /* ~. */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt7[1514] = { +0x02, 0x00, 0x00, 0x70, 0xca, 0x04, 0x5e, 0xe9, /* ...p..^. */ +0x1e, 0xa6, 0x21, 0x64, 0x08, 0x00, 0x45, 0x00, /* ..!d..E. */ +0x05, 0xdc, 0xe7, 0xcb, 0x00, 0x00, 0x33, 0x06, /* ......3. */ +0x2b, 0x3d, 0x98, 0xc7, 0x13, 0xa1, 0xc0, 0xa8, /* +=...... */ +0x02, 0x03, 0x00, 0x50, 0xc9, 0xc1, 0xb1, 0x64, /* ...P...d */ +0xbe, 0x25, 0xfa, 0xdf, 0xdf, 0x46, 0x50, 0x18, /* .%...FP. */ +0xff, 0xff, 0x67, 0x02, 0x00, 0x00, 0x74, 0x8f, /* ..g...t. */ +0x9c, 0xfb, 0x61, 0x7e, 0xa5, 0x92, 0x95, 0x81, /* ..a~.... */ +0x31, 0x47, 0xa7, 0xd7, 0xf9, 0x57, 0xe7, 0xd0, /* 1G...W.. */ +0xb9, 0x60, 0x59, 0x14, 0x03, 0x27, 0x2c, 0xd9, /* .`Y..',. */ +0x2e, 0x16, 0x09, 0xfd, 0x81, 0x7a, 0x46, 0xe9, /* .....zF. */ +0xa5, 0x94, 0x49, 0x58, 0x85, 0xd5, 0xc9, 0xc0, /* ..IX.... */ +0x9e, 0x05, 0x8b, 0x14, 0x4d, 0x46, 0xa8, 0x02, /* ....MF.. */ +0xb0, 0x9f, 0xbf, 0xd2, 0xc1, 0x36, 0x36, 0x72, /* .....66r */ +0x96, 0x63, 0x8a, 0xb6, 0x55, 0x29, 0xa3, 0xfa, /* .c..U).. */ +0x0b, 0xb6, 0xfe, 0xbb, 0x7a, 0x51, 0xed, 0x85, /* ....zQ.. */ +0xef, 0x9d, 0xf6, 0x25, 0x80, 0x38, 0x75, 0x20, /* ...%.8u */ +0x2d, 0x02, 0x1e, 0x1e, 0x8e, 0x30, 0xf3, 0x10, /* -....0.. */ +0x24, 0xe2, 0x86, 0x50, 0xd5, 0x19, 0x47, 0x4b, /* $..P..GK */ +0xd8, 0x42, 0x78, 0x09, 0x0f, 0xaa, 0x67, 0x0c, /* .Bx...g. */ +0x72, 0xc0, 0xfa, 0x7f, 0x97, 0x54, 0xd6, 0x78, /* r....T.x */ +0xec, 0xb2, 0xe0, 0x5b, 0xaf, 0x75, 0xcc, 0x39, /* ...[.u.9 */ +0x85, 0x4e, 0xa0, 0x0b, 0x3a, 0x7b, 0xa4, 0xb8, /* .N..:{.. */ +0xde, 0xc7, 0xe0, 0xf9, 0x62, 0x88, 0xdd, 0xfd, /* ....b... */ +0x09, 0x74, 0xf0, 0x31, 0x05, 0xa5, 0x23, 0xa2, /* .t.1..#. */ +0x38, 0xa3, 0x58, 0x87, 0xcb, 0x00, 0xab, 0xf9, /* 8.X..... */ +0x80, 0x46, 0xfb, 0xb9, 0xcf, 0x0a, 0x6d, 0xfe, /* .F....m. */ +0xce, 0xa9, 0xa4, 0xef, 0xb6, 0x03, 0xa4, 0xc9, /* ........ */ +0xc5, 0x50, 0xfa, 0x45, 0xb7, 0xa1, 0x44, 0xc7, /* .P.E..D. */ +0xc8, 0x80, 0x7b, 0x60, 0x40, 0x74, 0xbf, 0xe4, /* ..{`@t.. */ +0xf1, 0xa5, 0xbe, 0x1f, 0xb0, 0xdc, 0x68, 0x03, /* ......h. */ +0x13, 0x57, 0x20, 0x0b, 0x80, 0x23, 0x92, 0xa8, /* .W ..#.. */ +0x85, 0x95, 0x04, 0x3f, 0x99, 0xc7, 0xdb, 0xa6, /* ...?.... */ +0x4c, 0x34, 0xa7, 0xe2, 0xa1, 0xdd, 0x7b, 0x6e, /* L4....{n */ +0xca, 0xda, 0x38, 0xf7, 0x44, 0xef, 0xa4, 0x87, /* ..8.D... */ +0x66, 0x14, 0x1a, 0x91, 0x7f, 0xfe, 0x15, 0x47, /* f......G */ +0x99, 0x21, 0x72, 0x3e, 0x82, 0x30, 0x32, 0xf7, /* .!r>.02. */ +0xab, 0x99, 0x9d, 0xd2, 0x93, 0x7b, 0x14, 0x95, /* .....{.. */ +0x2f, 0x02, 0x3f, 0x94, 0xf5, 0x9e, 0xe2, 0x67, /* /.?....g */ +0xeb, 0xb5, 0x12, 0xff, 0x6e, 0x19, 0xb3, 0x76, /* ....n..v */ +0x5e, 0xf3, 0x4b, 0x26, 0xa1, 0xbc, 0xb3, 0xf4, /* ^.K&.... */ +0x78, 0x0f, 0xf7, 0x24, 0x47, 0x70, 0xe0, 0x45, /* x..$Gp.E */ +0xfd, 0xf0, 0xa5, 0xb7, 0x3c, 0xd0, 0xd4, 0x02, /* ....<... */ +0x94, 0xff, 0x7d, 0x5c, 0xf4, 0xd4, 0x34, 0x4d, /* ..}\..4M */ +0x3c, 0x4f, 0x0a, 0x29, 0xc4, 0x90, 0xd8, 0x28, /* b.. */ +0xed, 0x65, 0x4f, 0x6d, 0x94, 0xa3, 0x0a, 0x77, /* .eOm...w */ +0xb1, 0xf3, 0x87, 0xe2, 0xb7, 0x03, 0x6e, 0x00, /* ......n. */ +0x1a, 0x5b, 0xdb, 0x11, 0xb5, 0x78, 0xaf, 0x74, /* .[...x.t */ +0x8d, 0x06, 0xc9, 0x15, 0xbd, 0xbb, 0xca, 0x53, /* .......S */ +0x68, 0x81, 0x7e, 0xf6, 0x20, 0x4f, 0x80, 0xfd, /* h.~. O.. */ +0x12, 0x28, 0xa4, 0xb5, 0x4d, 0x98, 0x3b, 0xad, /* .(..M.;. */ +0x81, 0x1b, 0x45, 0xe3, 0x50, 0x96, 0x85, 0xb7, /* ..E.P... */ +0x7b, 0x9c, 0xfd, 0xc9, 0x83, 0x47, 0xad, 0x93, /* {....G.. */ +0x7d, 0xee, 0xd8, 0x20, 0x8e, 0x11, 0x8f, 0xab, /* }.. .... */ +0x18, 0x99, 0x8a, 0x64, 0xd2, 0xf0, 0xe1, 0x07, /* ...d.... */ +0x35, 0xec, 0x6c, 0x0e, 0x4c, 0xb8, 0xbb, 0x54, /* 5.l.L..T */ +0xa4, 0x82, 0x53, 0x4a, 0x3e, 0x9a, 0x9f, 0x7c, /* ..SJ>..| */ +0x19, 0x65, 0xda, 0x76, 0xfa, 0x9b, 0x7f, 0x6c, /* .e.v...l */ +0x32, 0x45, 0xd1, 0x0a, 0xce, 0x22, 0xcd, 0x53, /* 2E...".S */ +0x0a, 0x28, 0x4a, 0xf4, 0xf1, 0xdc, 0xb2, 0x06, /* .(J..... */ +0xf8, 0xcb, 0x91, 0x4d, 0x39, 0xc0, 0x0f, 0x65, /* ...M9..e */ +0xe5, 0x78, 0x23, 0xdb, 0x37, 0x59, 0xba, 0x68, /* .x#.7Y.h */ +0x28, 0xd5, 0x91, 0xe3, 0xb2, 0x07, 0x20, 0x63, /* (..... c */ +0xe2, 0x8a, 0x9d, 0x8c, 0xbd, 0x5e, 0x2a, 0x2a, /* .....^** */ +0x87, 0xb2, 0xaa, 0xef, 0xdc, 0xc6, 0x6e, 0xd8, /* ......n. */ +0x81, 0xe2, 0xc0, 0x6f, 0x31, 0x7f, 0x23, 0xd5, /* ...o1.#. */ +0x30, 0x85, 0x2a, 0x91, 0xaf, 0xab, 0xa7, 0xc8, /* 0.*..... */ +0x5c, 0xc6, 0x73, 0xf2, 0x40, 0x97, 0xd7, 0xfb, /* \.s.@... */ +0xb2, 0x7a, 0x4a, 0x66, 0x51, 0xec, 0x41, 0x42, /* .zJfQ.AB */ +0xb1, 0x06, 0x1f, 0x95, 0xfd, 0x6f, 0x82, 0x97, /* .....o.. */ +0x88, 0xbc, 0x01, 0x8f, 0xfd, 0x61, 0xa6, 0x83, /* .....a.. */ +0x69, 0x3d, 0x70, 0xa5, 0xfb, 0xf6, 0xec, 0x61, /* i=p....a */ +0xf0, 0x7a, 0xe4, 0x21, 0x85, 0x38, 0xd5, 0x76, /* .z.!.8.v */ +0x03, 0xc9, 0x3b, 0x5a, 0x62, 0x9e, 0xfa, 0x51, /* ..;Zb..Q */ +0x84, 0x54, 0x12, 0x96, 0x9c, 0x35, 0xf2, 0x25, /* .T...5.% */ +0x70, 0x66, 0x49, 0x22, 0x3e, 0xab, 0xc4, 0x7f, /* pfI">... */ +0x60, 0x3d, 0x47, 0x49, 0x8c, 0x16, 0x33, 0x4a, /* `=GI..3J */ +0x98, 0xa5, 0x91, 0x4a, 0x80, 0x59, 0x76, 0x0f, /* ...J.Yv. */ +0xd7, 0xcc, 0xfb, 0x95, 0x95, 0x7b, 0x0e, 0x6d, /* .....{.m */ +0xff, 0x17, 0x3d, 0x72, 0xf9, 0xf3, 0xc5, 0xb8, /* ..=r.... */ +0x17, 0xca, 0xdd, 0xff, 0xfb, 0x0e, 0x3c, 0xfe, /* ......<. */ +0x9f, 0x1c, 0xac, 0xe8, 0x77, 0x2c, 0x86, 0xd5, /* ....w,.. */ +0xb6, 0x80, 0xaa, 0x26, 0xe0, 0x28, 0x44, 0x71, /* ...&.(Dq */ +0x96, 0x6d, 0x22, 0x24, 0x2d, 0xd8, 0xf4, 0x81, /* .m"$-... */ +0x08, 0x56, 0xf2, 0x18, 0xd5, 0xdb, 0x13, 0x06, /* .V...... */ +0x61, 0x54, 0xdc, 0x41, 0xbb, 0xb7, 0x69, 0x31, /* aT.A..i1 */ +0xc4, 0x73, 0x4d, 0x84, 0xa0, 0x36, 0xef, 0x95, /* .sM..6.. */ +0x6f, 0xc6, 0x9f, 0xa9, 0x45, 0x41, 0xed, 0xd6, /* o...EA.. */ +0x0d, 0x0b, 0x5e, 0x68, 0xd5, 0x35, 0xe7, 0x76, /* ..^h.5.v */ +0xb2, 0x71, 0x62, 0xed, 0x10, 0xfc, 0x0f, 0x78, /* .qb....x */ +0x1a, 0x48, 0x57, 0x03, 0x8b, 0xd8, 0x05, 0x07, /* .HW..... */ +0x5a, 0x34, 0xa5, 0xcd, 0xef, 0x4f, 0x0f, 0xf3, /* Z4...O.. */ +0xbe, 0xf9, 0x98, 0xce, 0x74, 0x2e, 0x4a, 0x9c, /* ....t.J. */ +0x0c, 0x84, 0x39, 0xf5, 0x9d, 0xa0, 0x47, 0xf9, /* ..9...G. */ +0xde, 0x90, 0xf2, 0x7d, 0x0f, 0xa2, 0x25, 0xe4, /* ...}..%. */ +0x36, 0x5b, 0x97, 0xd6, 0xfd, 0x7d, 0xe1, 0xf7, /* 6[...}.. */ +0x8a, 0x5b, 0x4d, 0xc5, 0x89, 0x43, 0xc0, 0x11, /* .[M..C.. */ +0x90, 0xe9, 0x79, 0xba, 0x01, 0x6c, 0x9e, 0x34, /* ..y..l.4 */ +0x89, 0x6c, 0xcc, 0x7c, 0x65, 0x86, 0xbe, 0x46, /* .l.|e..F */ +0x1f, 0x2f, 0xb2, 0x32, 0x1c, 0x3f, 0x2c, 0xdf, /* ./.2.?,. */ +0x24, 0xeb, 0x5b, 0xba, 0xd9, 0x9b, 0x8d, 0x54, /* $.[....T */ +0x17, 0x8e, 0x92, 0x1a, 0x69, 0xbc, 0x56, 0x61, /* ....i.Va */ +0x89, 0x3c, 0xec, 0xf6, 0xcd, 0xaa, 0x9b, 0xfa, /* .<...... */ +0x6a, 0xb8, 0x0a, 0x42, 0x68, 0x76, 0xd8, 0x10, /* j..Bhv.. */ +0x5f, 0x74, 0x89, 0x9a, 0x82, 0xbc, 0x4a, 0xdb, /* _t....J. */ +0x0d, 0x89, 0x73, 0x94, 0x13, 0x77, 0x4b, 0xac, /* ..s..wK. */ +0xa2, 0xf8, 0xad, 0xe8, 0xc2, 0xd7, 0x9b, 0xb8, /* ........ */ +0xeb, 0xf2, 0xf7, 0x33, 0xcc, 0x12, 0x4f, 0x65, /* ...3..Oe */ +0xda, 0x9e, 0xe7, 0xa8, 0x60, 0x55, 0xde, 0x13, /* ....`U.. */ +0x10, 0x8a, 0xa4, 0x0a, 0x0e, 0x5d, 0xfe, 0xcb, /* .....].. */ +0xf3, 0x7f, 0x9d, 0x08, 0x48, 0xba, 0xfe, 0x14, /* ....H... */ +0x48, 0xb4, 0xa3, 0x6c, 0x7a, 0xae, 0xcb, 0xb7, /* H..lz... */ +0xf8, 0x80, 0xe2, 0xfa, 0xd2, 0xdf, 0xac, 0x19, /* ........ */ +0x1c, 0xd8, 0xc7, 0x3f, 0x30, 0xd4, 0x1f, 0x7a, /* ...?0..z */ +0x8d, 0x78, 0xc9, 0xed, 0xb8, 0xe8, 0xfb, 0xd5, /* .x...... */ +0xa2, 0xab, 0x5a, 0x28, 0x4a, 0xfe, 0xc4, 0xcc, /* ..Z(J... */ +0x85, 0xab, 0x88, 0xc5, 0x38, 0x05, 0xe0, 0xbb, /* ....8... */ +0xed, 0x41, 0xe0, 0x73, 0xcc, 0xb4, 0x65, 0xfa, /* .A.s..e. */ +0x55, 0x62, 0xab, 0xf1, 0x12, 0x57, 0x33, 0x49, /* Ub...W3I */ +0xd5, 0x41, 0x02, 0xaa, 0x7a, 0x17, 0x8e, 0xd7, /* .A..z... */ +0xe1, 0xd0, 0x4e, 0xae, 0x6c, 0xb2, 0x0a, 0x4c, /* ..N.l..L */ +0x3b, 0x1c, 0x8c, 0x63, 0x74, 0x3f, 0xbd, 0x19, /* ;..ct?.. */ +0xc5, 0xdb, 0x24, 0x1a, 0x2d, 0x0c, 0xb0, 0xfa, /* ..$.-... */ +0x72, 0x43, 0xe4, 0x8c, 0x9f, 0x10, 0xda, 0x5e, /* rC.....^ */ +0x89, 0xa9, 0xd5, 0x47, 0x04, 0x12, 0x87, 0x62, /* ...G...b */ +0x90, 0x96, 0x19, 0x88, 0xc9, 0xe2, 0xba, 0x56, /* .......V */ +0x3a, 0x37, 0xcf, 0xbc, 0x77, 0x7e, 0x09, 0x1f, /* :7..w~.. */ +0x52, 0xee, 0x8e, 0xf2, 0x82, 0x05, 0xb7, 0x2c, /* R......, */ +0x18, 0x27, 0xfd, 0xa4, 0xf7, 0xff, 0x61, 0x2b, /* .'....a+ */ +0x42, 0xe7, 0x12, 0xc0, 0xc3, 0xee, 0xd9, 0x4a, /* B......J */ +0x0f, 0x6c, 0x5e, 0x31, 0xa6, 0x13, 0xcd, 0x91, /* .l^1.... */ +0x05, 0x84, 0x7c, 0x4e, 0xe7, 0x7b, 0xc1, 0xe7, /* ..|N.{.. */ +0x4b, 0xdf, 0xfc, 0x12, 0x80, 0x11, 0xca, 0x93, /* K....... */ +0xcc, 0x4d, 0x05, 0xbe, 0xaf, 0xd3, 0xa7, 0xcb, /* .M...... */ +0x96, 0x36, 0x5c, 0x67, 0xf0, 0x34, 0x95, 0x5c, /* .6\g.4.\ */ +0x44, 0x3c, 0x2a, 0x7c, 0xde, 0xc0, 0x8b, 0x6d, /* D<*|...m */ +0x32, 0xdc, 0xa0, 0x00, 0xb4, 0xa1, 0x81, 0xf2, /* 2....... */ +0x93, 0xf5, 0x3e, 0x0f, 0xd0, 0x43, 0x31, 0x14, /* ..>..C1. */ +0xa6, 0xa5, 0xa8, 0xf0, 0x38, 0xa9, 0xfb, 0x15, /* ....8... */ +0x3f, 0xba, 0x01, 0x9e, 0x73, 0xc8, 0xe1, 0xe2, /* ?...s... */ +0xdb, 0x95, 0xa8, 0x80, 0x00, 0xb1, 0x13, 0xb9, /* ........ */ +0xb1, 0xb6, 0x23, 0x2a, 0xf6, 0x34, 0xcf, 0x01, /* ..#*.4.. */ +0x12, 0x4e, 0x97, 0x9a, 0x61, 0x3e, 0x9a, 0x11, /* .N..a>.. */ +0xb5, 0x43, 0x27, 0x35, 0x86, 0x57, 0x40, 0xb8, /* .C'5.W@. */ +0x7a, 0x9c, 0x2c, 0xd5, 0x83, 0x0f, 0xb6, 0x1b, /* z.,..... */ +0x40, 0xf8, 0xaf, 0xa1, 0xb7, 0x3a, 0x05, 0xad, /* @....:.. */ +0x7d, 0xba, 0x69, 0x10, 0xca, 0x6f, 0xcb, 0xf0, /* }.i..o.. */ +0xd6, 0xe4, 0x64, 0xf1, 0xd9, 0x93, 0x7d, 0xb5, /* ..d...}. */ +0x20, 0x57, 0xb7, 0x44, 0xa1, 0x6b, 0x8f, 0xb7, /* W.D.k.. */ +0x6c, 0x2f, 0xdc, 0xe7, 0x6a, 0xb8, 0x06, 0x0a, /* l/..j... */ +0xdf, 0xd5, 0x1e, 0x16, 0xd6, 0xf4, 0xc2, 0x9b, /* ........ */ +0x41, 0x78, 0x61, 0xa7, 0x5a, 0xcf, 0x0f, 0x41, /* Axa.Z..A */ +0x61, 0xd2, 0x28, 0xfc, 0x97, 0xc5, 0x94, 0xb2, /* a.(..... */ +0x75, 0x50, 0xb0, 0x5a, 0x8b, 0xea, 0x8f, 0x6e, /* uP.Z...n */ +0x53, 0x56, 0x3c, 0xf6, 0x60, 0xd0, 0x85, 0xe8, /* SV<.`... */ +0xd8, 0xf4, 0x87, 0xd0, 0xf1, 0x19, 0x53, 0x57, /* ......SW */ +0x08, 0x65, 0x89, 0x41, 0x36, 0x7d, 0xb2, 0x73, /* .e.A6}.s */ +0xcf, 0x29, 0x5b, 0xcb, 0x9c, 0x70, 0x47, 0x3a, /* .)[..pG: */ +0x66, 0xc4, 0x6a, 0x5c, 0x9b, 0x41, 0xf6, 0x9f, /* f.j\.A.. */ +0xcf, 0x64, 0xd5, 0xa3, 0xc4, 0x48, 0xee, 0x37, /* .d...H.7 */ +0x16, 0xac, 0x06, 0xb8, 0x32, 0xb4, 0x72, 0x44, /* ....2.rD */ +0x73, 0x54, 0x7a, 0xb0, 0x76, 0x1a, 0xb7, 0xb4, /* sTz.v... */ +0x04, 0x00, 0xf4, 0x4a, 0xdc, 0xb9, 0x58, 0x1f, /* ...J..X. */ +0x34, 0x43, 0xd9, 0xee, 0x02, 0x54, 0x88, 0x7e, /* 4C...T.~ */ +0x49, 0x88, 0x09, 0x68, 0xdd, 0x58, 0x1e, 0x37, /* I..h.X.7 */ +0x61, 0x95, 0xb8, 0xb6, 0x89, 0xf4, 0xf8, 0xa4, /* a....... */ +0x36, 0x05, 0x45, 0x4f, 0x0e, 0x57, 0xab, 0xd6, /* 6.EO.W.. */ +0xdd, 0x85, 0x27, 0xf4, 0xce, 0xd4, 0x3b, 0x39, /* ..'...;9 */ +0x87, 0xa3, 0x35, 0x00, 0x11, 0x53, 0xb2, 0x80, /* ..5..S.. */ +0x60, 0xe7, 0x9e, 0x1b, 0x24, 0x60, 0x65, 0xf6, /* `...$`e. */ +0x35, 0x96, 0x2a, 0x87, 0x87, 0xa6, 0xb8, 0x79, /* 5.*....y */ +0xf5, 0xed, 0x1c, 0xdb, 0x96, 0x9e, 0x08, 0x2f, /* ......./ */ +0xb8, 0x0d, 0x40, 0xe7, 0xa4, 0xb8, 0xe3, 0xf7, /* ..@..... */ +0x49, 0xc4, 0x9d, 0xec, 0x50, 0xf3, 0x8f, 0x00, /* I...P... */ +0x33, 0x1a, 0xc9, 0x3c, 0x14, 0x0e, 0x18, 0xd1, /* 3..<.... */ +0xd8, 0xae /* .. */ +}; + +/* Frame (719 bytes) */ +static const unsigned char pkt8[719] = { +0x02, 0x00, 0x00, 0x70, 0xca, 0x04, 0x5e, 0xe9, /* ...p..^. */ +0x1e, 0xa6, 0x21, 0x64, 0x08, 0x00, 0x45, 0x00, /* ..!d..E. */ +0x02, 0xc1, 0xe7, 0xd3, 0x00, 0x00, 0x33, 0x06, /* ......3. */ +0x2e, 0x50, 0x98, 0xc7, 0x13, 0xa1, 0xc0, 0xa8, /* .P...... */ +0x02, 0x03, 0x00, 0x50, 0xc9, 0xc1, 0xb1, 0x64, /* ...P...d */ +0xeb, 0xc5, 0xfa, 0xdf, 0xdf, 0x46, 0x50, 0x18, /* .....FP. */ +0xff, 0xff, 0x44, 0x4b, 0x00, 0x00, 0x8d, 0x68, /* ..DK...h */ +0x62, 0x45, 0x47, 0x5a, 0xe3, 0xab, 0x32, 0xbc, /* bEGZ..2. */ +0x5e, 0x31, 0xb1, 0x90, 0x55, 0x75, 0xf3, 0x0f, /* ^1..Uu.. */ +0x83, 0xa4, 0x38, 0x84, 0x00, 0xcf, 0xa4, 0x0b, /* ..8..... */ +0xb3, 0x41, 0xdc, 0x6d, 0x48, 0xb2, 0xbc, 0x5c, /* .A.mH..\ */ +0x26, 0x8f, 0x12, 0x7b, 0xf3, 0xdd, 0xda, 0xb4, /* &..{.... */ +0xb7, 0x68, 0xc7, 0x1b, 0x42, 0x2b, 0x51, 0x90, /* .h..B+Q. */ +0x5b, 0xab, 0x3d, 0x7e, 0x4a, 0xb9, 0x55, 0x9b, /* [.=~J.U. */ +0xd4, 0x80, 0x1d, 0x7f, 0x81, 0xa4, 0xff, 0x54, /* .......T */ +0xa9, 0x61, 0xb9, 0xad, 0x51, 0x29, 0x08, 0x36, /* .a..Q).6 */ +0x57, 0xeb, 0xdd, 0x29, 0x26, 0xcc, 0xd5, 0x95, /* W..)&... */ +0x70, 0x6f, 0xee, 0xcb, 0xd9, 0x14, 0xe2, 0xb5, /* po...... */ +0xd9, 0xbd, 0x0f, 0xb1, 0x90, 0x2a, 0x6b, 0xb7, /* .....*k. */ +0x62, 0x5d, 0x7e, 0x89, 0xee, 0x0f, 0xfd, 0xb1, /* b]~..... */ +0x5a, 0xb1, 0xf6, 0xe7, 0x9c, 0xcb, 0xd1, 0xd7, /* Z....... */ +0x75, 0x4c, 0xc0, 0xb1, 0xe9, 0xb4, 0x87, 0xd9, /* uL...... */ +0x4e, 0x12, 0x62, 0xc4, 0xda, 0xeb, 0x3c, 0xb4, /* N.b...<. */ +0x4f, 0xf1, 0x38, 0xa4, 0xe3, 0x83, 0x3d, 0xd7, /* O.8...=. */ +0x2c, 0x6a, 0x20, 0xde, 0x7d, 0xf1, 0x05, 0xb0, /* ,j .}... */ +0xbb, 0xe9, 0x1b, 0x00, 0xed, 0xd2, 0x1f, 0x6a, /* .......j */ +0xd3, 0xad, 0x87, 0x8c, 0xc1, 0x1e, 0xf1, 0x22, /* ......." */ +0x34, 0x59, 0x91, 0xf8, 0xfa, 0xe7, 0x18, 0xd6, /* 4Y...... */ +0x41, 0x5e, 0x58, 0xdb, 0x19, 0x84, 0x1a, 0xa3, /* A^X..... */ +0x79, 0xb7, 0x91, 0x92, 0x13, 0x6a, 0xba, 0xde, /* y....j.. */ +0x63, 0x00, 0x3c, 0xe9, 0xfa, 0x66, 0x70, 0x46, /* c.<..fpF */ +0x7e, 0xc3, 0x21, 0x6f, 0xda, 0x38, 0x00, 0x55, /* ~.!o.8.U */ +0x19, 0x8c, 0x80, 0x4b, 0x74, 0xa1, 0xab, 0x65, /* ...Kt..e */ +0x75, 0xc7, 0x75, 0xf1, 0xb2, 0xf8, 0xb6, 0x57, /* u.u....W */ +0xe4, 0xdb, 0xc5, 0xe5, 0x19, 0xf3, 0xc0, 0xea, /* ........ */ +0x49, 0x0d, 0xff, 0xb1, 0xe1, 0xbc, 0x3c, 0xee, /* I.....<. */ +0xc7, 0x71, 0x4e, 0x3d, 0xc9, 0xe4, 0x63, 0x20, /* .qN=..c */ +0xd1, 0x8b, 0xab, 0x1c, 0x65, 0xe8, 0x22, 0x37, /* ....e."7 */ +0x72, 0xff, 0x12, 0x3b, 0xb3, 0x32, 0x76, 0x3f, /* r..;.2v? */ +0xfa, 0x02, 0x7d, 0x4a, 0x1b, 0x6e, 0xd1, 0x94, /* ..}J.n.. */ +0xff, 0xee, 0xe5, 0xa3, 0x8c, 0x1c, 0xc6, 0x73, /* .......s */ +0xaf, 0x77, 0x34, 0xdb, 0x4e, 0x76, 0x3b, 0x30, /* .w4.Nv;0 */ +0x8d, 0x08, 0xf7, 0xcf, 0xbc, 0x45, 0x7c, 0xfc, /* .....E|. */ +0xdb, 0xcc, 0xbd, 0x62, 0xc6, 0x81, 0x8c, 0x48, /* ...b...H */ +0x08, 0x97, 0xc1, 0x5e, 0x34, 0xa9, 0x6f, 0xe5, /* ...^4.o. */ +0xc4, 0xda, 0x1a, 0x5f, 0x11, 0x6b, 0xaa, 0x37, /* ..._.k.7 */ +0x39, 0xbf, 0x4b, 0x74, 0x22, 0x57, 0xfc, 0xa4, /* 9.Kt"W.. */ +0x5b, 0xd8, 0x77, 0xe3, 0x20, 0x23, 0x10, 0xbc, /* [.w. #.. */ +0xd7, 0x69, 0xe9, 0x75, 0xb6, 0x76, 0x24, 0xda, /* .i.u.v$. */ +0xb5, 0x0a, 0x51, 0x66, 0xc4, 0x66, 0x0b, 0x7e, /* ..Qf.f.~ */ +0x46, 0xa7, 0x60, 0xa7, 0x78, 0x82, 0x74, 0x36, /* F.`.x.t6 */ +0xfc, 0xb8, 0xbd, 0x1b, 0x5c, 0x85, 0xe3, 0xd9, /* ....\... */ +0x60, 0x10, 0x68, 0x89, 0x28, 0x36, 0x49, 0xa5, /* `.h.(6I. */ +0x83, 0xbf, 0xb2, 0x8a, 0x2b, 0x16, 0x42, 0x98, /* ....+.B. */ +0x76, 0xf1, 0x7e, 0x96, 0xb2, 0xea, 0x62, 0xbf, /* v.~...b. */ +0xc1, 0x61, 0xd6, 0x79, 0xb2, 0x03, 0x04, 0x99, /* .a.y.... */ +0x0e, 0xdc, 0x31, 0xb5, 0xc5, 0x31, 0x3e, 0x98, /* ..1..1>. */ +0x7c, 0x54, 0x92, 0xbf, 0x71, 0x76, 0x4e, 0xfe, /* |T..qvN. */ +0x6c, 0x13, 0x7a, 0xa7, 0xb5, 0xe9, 0x44, 0x34, /* l.z...D4 */ +0x77, 0x70, 0x71, 0x1c, 0xbd, 0x2b, 0x1e, 0x28, /* wpq..+.( */ +0x98, 0x75, 0xfd, 0xc9, 0xb2, 0x51, 0xef, 0x8f, /* .u...Q.. */ +0xbc, 0x6a, 0x7e, 0x85, 0xb5, 0xfa, 0xe6, 0x7c, /* .j~....| */ +0x6a, 0xd2, 0xae, 0x68, 0xbb, 0x24, 0xb9, 0x9b, /* j..h.$.. */ +0x30, 0xf1, 0x7e, 0xa6, 0xe3, 0x0c, 0x0b, 0xac, /* 0.~..... */ +0x85, 0x20, 0x2b, 0x2d, 0x8f, 0x84, 0x8c, 0x56, /* . +-...V */ +0xec, 0xac, 0x18, 0x53, 0x8d, 0x52, 0x11, 0xd1, /* ...S.R.. */ +0xe1, 0x50, 0xae, 0xdd, 0x88, 0x84, 0xb6, 0x61, /* .P.....a */ +0xb1, 0x96, 0x4f, 0x72, 0x58, 0x11, 0x4d, 0xa5, /* ..OrX.M. */ +0x1c, 0xc9, 0x89, 0x44, 0x8e, 0x69, 0x2b, 0x44, /* ...D.i+D */ +0x85, 0x90, 0xc6, 0x92, 0xbc, 0xe5, 0x99, 0x51, /* .......Q */ +0xe0, 0xae, 0x45, 0xf9, 0x32, 0xf1, 0x46, 0x98, /* ..E.2.F. */ +0xbe, 0x68, 0xd4, 0x48, 0x92, 0x87, 0x60, 0x40, /* .h.H..`@ */ +0xd6, 0xf6, 0x69, 0xc3, 0x5c, 0x64, 0x3b, 0x8f, /* ..i.\d;. */ +0x66, 0x4c, 0x14, 0xe5, 0x5f, 0x7f, 0x28, 0x1b, /* fL.._.(. */ +0x9e, 0x05, 0x7e, 0x39, 0xb8, 0xe5, 0xe7, 0x3c, /* ..~9...< */ +0x79, 0xb8, 0xc0, 0x42, 0x76, 0x2a, 0xf4, 0xf6, /* y..Bv*.. */ +0xd7, 0x11, 0xc9, 0xe8, 0x44, 0xee, 0xce, 0x8f, /* ....D... */ +0x6c, 0x67, 0xba, 0x8b, 0x59, 0x36, 0x38, 0x43, /* lg..Y68C */ +0xb5, 0x08, 0x43, 0x36, 0xe0, 0xb1, 0xdd, 0xc6, /* ..C6.... */ +0x89, 0x38, 0xf3, 0x86, 0x90, 0x27, 0xb9, 0x1a, /* .8...'.. */ +0xf3, 0xa0, 0xb0, 0x02, 0xb1, 0x13, 0xed, 0xb7, /* ........ */ +0x9a, 0x21, 0xad, 0x0f, 0xbd, 0xd6, 0x35, 0xff, /* .!....5. */ +0xe2, 0x24, 0xb4, 0x95, 0x52, 0xcb, 0xe0, 0x09, /* .$..R... */ +0xa4, 0x70, 0xfe, 0x7f, 0x95, 0x08, 0x11, 0xa4, /* .p...... */ +0x70, 0x9f, 0xf7, 0x43, 0x6d, 0x24, 0x46, 0x12, /* p..Cm$F. */ +0x2c, 0x52, 0x9b, 0xf0, 0x4b, 0xfb, 0x89, 0x9e, /* ,R..K... */ +0x9e, 0xf1, 0xb6, 0x21, 0x95, 0xc1, 0x8a, 0x16, /* ...!.... */ +0xc3, 0xd6, 0xa6, 0xf4, 0xd7, 0x0f, 0x87, 0x15, /* ........ */ +0x16, 0x14, 0x71, 0x85, 0x8b, 0x10, 0x8a, 0x7a, /* ..q....z */ +0x95, 0x59, 0x92, 0x1f, 0x5a, 0x01, 0x97 /* .Y..Z.. */ +}; + +/* Frame (1173 bytes) */ +static const unsigned char pkt9[1173] = { +0x02, 0x00, 0x00, 0x70, 0xca, 0x04, 0x5e, 0xe9, /* ...p..^. */ +0x1e, 0xa6, 0x21, 0x64, 0x08, 0x00, 0x45, 0x00, /* ..!d..E. */ +0x04, 0x87, 0xe7, 0xd5, 0x00, 0x00, 0x33, 0x06, /* ......3. */ +0x2c, 0x88, 0x98, 0xc7, 0x13, 0xa1, 0xc0, 0xa8, /* ,....... */ +0x02, 0x03, 0x00, 0x50, 0xc9, 0xc1, 0xb1, 0x64, /* ...P...d */ +0xf4, 0x12, 0xfa, 0xdf, 0xdf, 0x46, 0x50, 0x18, /* .....FP. */ +0xff, 0xff, 0x7a, 0x92, 0x00, 0x00, 0x30, 0x9a, /* ..z...0. */ +0xd0, 0x8e, 0x56, 0x52, 0x40, 0x81, 0x0c, 0xd4, /* ..VR@... */ +0x37, 0x25, 0xce, 0xcd, 0x3c, 0x3c, 0x56, 0xca, /* 7%..<.;..V */ +0x7a, 0xa0, 0x1e, 0x6a, 0x87, 0x5e, 0xc5, 0x01, /* z..j.^.. */ +0x5c, 0x13, 0xc0, 0x30, 0x8a, 0x0a, 0x29, 0x09, /* \..0..). */ +0xce, 0x57, 0xdf, 0xd0, 0x04, 0x89, 0x63, 0xbc, /* .W....c. */ +0xde, 0x2f, 0xf1, 0x4e, 0xcb, 0xe6, 0x15, 0xf9, /* ./.N.... */ +0x80, 0xd8, 0x36, 0xf0, 0x7f, 0xdc, 0xde, 0x8b, /* ..6..... */ +0x94, 0xa5, 0xce, 0x27, 0xd7, 0x7d, 0x35, 0x80, /* ...'.}5. */ +0x6e, 0xd9, 0x78, 0x10, 0xdb, 0x67, 0xab, 0xc2, /* n.x..g.. */ +0xa8, 0x6b, 0x3f, 0x4e, 0xbd, 0x68, 0x6e, 0x48, /* .k?N.hnH */ +0x30, 0x24, 0xeb, 0xef, 0x94, 0x40, 0xf3, 0xa1, /* 0$...@.. */ +0x3f, 0xe7, 0x88, 0x2e, 0x38, 0x5f, 0xf3, 0x31, /* ?...8_.1 */ +0x88, 0x92, 0xe4, 0xa7, 0x23, 0xc6, 0xfb, 0x17, /* ....#... */ +0x60, 0xfc, 0x6a, 0xae, 0xa6, 0xe8, 0xd5, 0xa6, /* `.j..... */ +0xad, 0x4b, 0x65, 0x3d, 0x56, 0x08, 0xc6, 0xae, /* .Ke=V... */ +0x54, 0x07, 0xc1, 0xa5, 0xb0, 0x38, 0x8e, 0xb0, /* T....8.. */ +0xf6, 0x12, 0x3d, 0x24, 0x59, 0x41, 0xc2, 0xe9, /* ..=$YA.. */ +0x08, 0x56, 0x14, 0xbe, 0x4f, 0x83, 0x0b, 0x09, /* .V..O... */ +0x08, 0x1a, 0x02, 0xe3, 0xcb, 0xcc, 0x84, 0x70, /* .......p */ +0x4e, 0x3f, 0xa1, 0xdc, 0xee, 0x78, 0x30, 0x27, /* N?...x0' */ +0xb0, 0x1f, 0x01, 0xae, 0xbf, 0x34, 0x49, 0x1b, /* .....4I. */ +0xab, 0x88, 0x5d, 0x4d, 0x6d, 0xff, 0xc2, 0x01, /* ..]Mm... */ +0x73, 0xc2, 0x70, 0x25, 0x98, 0x93, 0x51, 0xc4, /* s.p%..Q. */ +0xfb, 0x56, 0x70, 0xa1, 0xfb, 0x45, 0xf5, 0xe8, /* .Vp..E.. */ +0x41, 0x7c, 0x58, 0x8d, 0x63, 0x95, 0x46, 0x5b, /* A|X.c.F[ */ +0x03, 0x7e, 0xda, 0x2a, 0x7e, 0x90, 0xf3, 0x64, /* .~.*~..d */ +0x8e, 0x95, 0x74, 0xe3, 0x30, 0x2c, 0x3a, 0xbe, /* ..t.0,:. */ +0xe3, 0x25, 0xa0, 0xb7, 0x25, 0xb5, 0xfe, 0xc0, /* .%..%... */ +0x53, 0xb5, 0xcc, 0xcb, 0x44, 0x56, 0xc5, 0xc3, /* S...DV.. */ +0xd2, 0xa6, 0xaf, 0x24, 0x8d, 0x73, 0x07, 0x13, /* ...$.s.. */ +0x04, 0x7b, 0xbf, 0x1f, 0x87, 0x7c, 0xe5, 0x52, /* .{...|.R */ +0xce, 0x4e, 0x7d, 0x36, 0x56, 0x13, 0x85, 0x6b, /* .N}6V..k */ +0x7e, 0xd7, 0x04, 0x44, 0xb1, 0x06, 0x06, 0xb8, /* ~..D.... */ +0x7b, 0x58, 0x65, 0x62, 0x33, 0x8b, 0x5d, 0xb2, /* {Xeb3.]. */ +0x53, 0x46, 0x34, 0x3a, 0x18, 0x18, 0x45, 0x4b, /* SF4:..EK */ +0x89, 0x9e, 0x1b, 0xc5, 0xfa, 0x6d, 0xf9, 0xb1, /* .....m.. */ +0x3d, 0x0b, 0x56, 0x75, 0x37, 0x72, 0x4b, 0x89, /* =.Vu7rK. */ +0xea, 0x15, 0x7c, 0x57, 0xce, 0x29, 0xd1, 0xbd, /* ..|W.).. */ +0x08, 0x22, 0x08, 0x05, 0x99, 0x03, 0x2a, 0xcf, /* ."....*. */ +0x2b, 0xc4, 0xb4, 0xef, 0x04, 0x91, 0x8b, 0xd0, /* +....... */ +0xc8, 0xfc, 0x4a, 0x32, 0x50, 0x84, 0x5d, 0x41, /* ..J2P.]A */ +0xd9, 0x35, 0x85, 0x86, 0x11, 0x4a, 0x5f, 0x09, /* .5...J_. */ +0x67, 0x94, 0x96, 0xd3, 0xe0, 0x76, 0xf8, 0x41, /* g....v.A */ +0x9d, 0x95, 0x88, 0x9d, 0x19, 0x91, 0x74, 0x36, /* ......t6 */ +0x2c, 0x17, 0xaa, 0x7e, 0x8b, 0x0f, 0x8e, 0x2e, /* ,..~.... */ +0x1d, 0xa3, 0x24, 0xc4, 0xc7, 0x16, 0xbc, 0x31, /* ..$....1 */ +0xdb, 0xcf, 0x4f, 0xab, 0x66, 0x17, 0xf4, 0xdc, /* ..O.f... */ +0x66, 0x67, 0x16, 0x95, 0xab, 0x88, 0x53, 0xad, /* fg....S. */ +0x02, 0x1e, 0x10, 0x14, 0x09, 0x1d, 0xd0, 0x04, /* ........ */ +0xd6, 0x2e, 0x3d, 0x65, 0x9c, 0xe0, 0x32, 0x47, /* ..=e..2G */ +0x0f, 0xfa, 0x49, 0x63, 0xfa, 0x1b, 0xf1, 0xf8, /* ..Ic.... */ +0x80, 0x73, 0x38, 0x42, 0x6d, 0x46, 0x30, 0x9c, /* .s8BmF0. */ +0x83, 0x05, 0x63, 0xd6, 0xd7, 0x5b, 0x27, 0x3d, /* ..c..['= */ +0x0b, 0xa1, 0xde, 0xd5, 0xf0, 0xed, 0xd1, 0xdb, /* ........ */ +0x5f, 0x4b, 0x9c, 0xa1, 0x87, 0xa3, 0xf8, 0x37, /* _K.....7 */ +0x10, 0xff, 0x16, 0x93, 0x5d, 0x6c, 0xa8, 0xcb, /* ....]l.. */ +0x85, 0xb5, 0xb0, 0x78, 0x30, 0x26, 0x19, 0xfc, /* ...x0&.. */ +0xce, 0xbd, 0xc3, 0x7d, 0x04, 0x46, 0xf8, 0xdc, /* ...}.F.. */ +0xdc, 0x12, 0xe6, 0xc7, 0x8e, 0x53, 0xdf, 0xd7, /* .....S.. */ +0xd9, 0xe9, 0x71, 0x04, 0xfc, 0x16, 0x63, 0x72, /* ..q...cr */ +0x04, 0xf4, 0x03, 0xe7, 0xde, 0xa3, 0xee, 0x04, /* ........ */ +0x7f, 0xb2, 0x2f, 0x4a, 0xc5, 0x6f, 0x0b, 0x09, /* ../J.o.. */ +0xc6, 0xde, 0x8f, 0x86, 0xfd, 0x5b, 0x26, 0x49, /* .....[&I */ +0x3a, 0x6f, 0xbd, 0x36, 0xe9, 0x7a, 0x5a, 0x1c, /* :o.6.zZ. */ +0x72, 0x81, 0xb2, 0x20, 0x6b, 0xe6, 0xb9, 0x29, /* r.. k..) */ +0x8f, 0x5d, 0x8d, 0xff, 0x10, 0xc5, 0xaa, 0x68, /* .].....h */ +0x9b, 0xbf, 0xd3, 0x66, 0x70, 0xe8, 0x93, 0xcb, /* ...fp... */ +0xad, 0xee, 0x44, 0xbf, 0x26, 0xdb, 0xef, 0x1d, /* ..D.&... */ +0xbd, 0x7c, 0x52, 0x6b, 0xdf, 0x1c, 0xef, 0x65, /* .|Rk...e */ +0xa4, 0xc2, 0x04, 0x95, 0xd7, 0xfe, 0x6f, 0xe8, /* ......o. */ +0xe1, 0xe0, 0x2d, 0xe5, 0xc1, 0xbd, 0x50, 0x9f, /* ..-...P. */ +0x44, 0x46, 0x17, 0xeb, 0xf0, 0x85, 0xfa, 0xd2, /* DF...... */ +0xa0, 0x0d, 0x2f, 0xcc, 0xfb, 0x3c, 0x9f, 0x79, /* ../..<.y */ +0x18, 0xf7, 0x11, 0x29, 0xb5, 0x84, 0xee, 0xbe, /* ...).... */ +0xa6, 0xcb, 0xb7, 0xce, 0x67, 0x9e, 0x8f, 0x3f, /* ....g..? */ +0x93, 0xba, 0x19, 0xb2, 0x9e, 0xe5, 0xe8, 0xe4, /* ........ */ +0xde, 0x9b, 0xae, 0x12, 0xde, 0x83, 0x7c, 0xfe, /* ......|. */ +0xf4, 0x04, 0xb2, 0x34, 0x37, 0xfc, 0xdb, 0xf0, /* ...47... */ +0x02, 0xfb, 0xfd, 0x83, 0x2f, 0x1a, 0x76, 0xc5, /* ..../.v. */ +0xa3, 0xd8, 0xd6, 0xc5, 0xb3, 0x30, 0x00, 0x77, /* .....0.w */ +0xe9, 0x1b, 0x2d, 0xa0, 0x9e, 0xe0, 0x1e, 0x76, /* ..-....v */ +0xf0, 0xfd, 0x20, 0x63, 0x86, 0xbc, 0xd3, 0x51, /* .. c...Q */ +0x27, 0x00, 0xbe, 0xca, 0xdf, 0x6d, 0xa6, 0xa9, /* '....m.. */ +0xc8, 0x15, 0xb8, 0x31, 0x70, 0x90, 0xa1, 0x45, /* ...1p..E */ +0xba, 0xa3, 0x66, 0xdf, 0x5b, 0x0b, 0x3b, 0xff, /* ..f.[.;. */ +0x2f, 0x4f, 0xae, 0x66, 0x08, 0x8f, 0xd9, 0x8a, /* /O.f.... */ +0x37, 0x55, 0xed, 0x03, 0x9b, 0xf9, 0x1f, 0x4e, /* 7U.....N */ +0x37, 0x40, 0xaa, 0x78, 0x6a, 0x33, 0x28, 0x5b, /* 7@.xj3([ */ +0xf1, 0x86, 0x42, 0x87, 0xcb, 0x20, 0xe9, 0xe4, /* ..B.. .. */ +0xf2, 0xb2, 0xb3, 0xcb, 0x1c, 0x68, 0xb3, 0xf2, /* .....h.. */ +0x37, 0xf2, 0x0b, 0xa4, 0xcc, 0x6c, 0xb7, 0xa6, /* 7....l.. */ +0x14, 0xf2, 0x8c, 0x8c, 0x9c, 0x28, 0x66, 0x45, /* .....(fE */ +0x0d, 0xed, 0x5b, 0xd5, 0xa7, 0x54, 0x73, 0x80, /* ..[..Ts. */ +0x18, 0x11, 0xb8, 0x61, 0xb0, 0x43, 0xf2, 0xcc, /* ...a.C.. */ +0x65, 0x46, 0xef, 0x9a, 0xb2, 0x5d, 0x66, 0x30, /* eF...]f0 */ +0x7a, 0xd0, 0xeb, 0x9c, 0xa7, 0x05, 0xfd, 0xfc, /* z....... */ +0x6e, 0xd4, 0x9e, 0x09, 0x35, 0x27, 0x21, 0x69, /* n...5'!i */ +0xa1, 0xa2, 0x79, 0xa2, 0xb1, 0x60, 0xfc, 0xe0, /* ..y..`.. */ +0x88, 0x3e, 0x6b, 0x5e, 0x27, 0x3b, 0xfc, 0xf2, /* .>k^';.. */ +0x32, 0x38, 0x10, 0xdc, 0xfe, 0x02, 0x44, 0xd1, /* 28....D. */ +0x1e, 0x09, 0x58, 0x9f, 0xfc, 0xd7, 0xba, 0xe8, /* ..X..... */ +0xb7, 0x4b, 0x3f, 0x15, 0x13, 0x0a, 0x73, 0x2d, /* .K?...s- */ +0xdb, 0x5a, 0x9b, 0x22, 0x31, 0x14, 0x9e, 0xf4, /* .Z."1... */ +0x79, 0xda, 0x87, 0x38, 0x13, 0x36, 0xba, 0x89, /* y..8.6.. */ +0xf6, 0x1f, 0xfb, 0xb4, 0x94, 0x13, 0x75, 0x6e, /* ......un */ +0xd7, 0x09, 0x47, 0x17, 0xaa, 0x02, 0x01, 0x09, /* ..G..... */ +0xa5, 0xb1, 0x16, 0x87, 0x27, 0x15, 0x39, 0x98, /* ....'.9. */ +0xcc, 0x20, 0x59, 0xe1, 0xea, 0xbb, 0xbc, 0x45, /* . Y....E */ +0xfa, 0x07, 0xe8, 0x43, 0x6c, 0x9d, 0x93, 0xb0, /* ...Cl... */ +0x17, 0xd2, 0xb3, 0xb6, 0x8f, 0xb0, 0x88, 0x8c, /* ........ */ +0x11, 0x39, 0x3e, 0x61, 0x27, 0x5c, 0x26, 0x8f, /* .9>a'\&. */ +0x14, 0x70, 0x8d, 0x2c, 0x78, 0xd0, 0x4d, 0x21, /* .p.,x.M! */ +0x7e, 0xb5, 0x28, 0x3c, 0x52, 0x8a, 0xb9, 0x8f, /* ~.(. */ +0x1b, 0x51, 0xac, 0xe1, 0xe7, 0xfa, 0x87, 0x8b, /* .Q...... */ +0xc3, 0x9f, 0x1b, 0xe7, 0x75, 0x1e, 0x3f, 0xbb, /* ....u.?. */ +0x3c, 0x57, 0x23, 0xdc, 0x55, 0x49, 0xd8, 0x0f, /* ...?T */ +0xa1, 0xc4, 0x28, 0xbb, 0x0b, 0x2e, 0xd9, 0x0b, /* ..(..... */ +0xd7, 0xb6, 0xee, 0x3c, 0xed, 0x53, 0xa0, 0x07, /* ...<.S.. */ +0x7a, 0x85, 0x46, 0x28, 0x25, 0xcd, 0x90, 0x53, /* z.F(%..S */ +0x30, 0x92, 0x70, 0x0b, 0x2a, 0x86, 0x4e, 0x82, /* 0.p.*.N. */ +0x4e, 0x68, 0xeb, 0x0b, 0x0d, 0xf4, 0x1f, 0x69, /* Nh.....i */ +0xc8, 0x44, 0xd0, 0xd9, 0xd9, 0x32, 0x02, 0xc9, /* .D...2.. */ +0x01, 0x85, 0x6a, 0x9e, 0x2a, 0x5a, 0x8d, 0xce, /* ..j.*Z.. */ +0x5f, 0xba, 0x2b, 0x8a, 0x7b, 0xaa, 0x6e, 0xf9, /* _.+.{.n. */ +0xf3, 0x53, 0x4c, 0xd5, 0x80, 0x3d, 0xcd, 0x18, /* .SL..=.. */ +0x91, 0x7f, 0x7d, 0x59, 0x8c, 0x3b, 0x10, 0xaa, /* ..}Y.;.. */ +0xda, 0x73, 0x56, 0x85, 0x3c, 0xf7, 0xfc, 0xc6, /* .sV.<... */ +0x6d, 0x2c, 0x3d, 0xd3, 0x92, 0x38, 0x1a, 0xac, /* m,=..8.. */ +0xd9, 0x92, 0xc1, 0x75, 0x89, 0x47, 0x5e, 0xc2, /* ...u.G^. */ +0x46, 0x60, 0x70, 0x73, 0xf0, 0xcc, 0x4b, 0xa9, /* F`ps..K. */ +0x72, 0x88, 0xd9, 0xa8, 0xff, 0x9c, 0xb7, 0x5b, /* r......[ */ +0xb0, 0x90, 0x7f, 0x5d, 0xa8, 0x35, 0x0c, 0x50, /* ...].5.P */ +0x1f, 0xad, 0xfa, 0x19, 0x64, 0x36, 0x6a, 0x83, /* ....d6j. */ +0x30, 0x05, 0x2a, 0x9a, 0xd5, 0x78, 0xf3, 0x93, /* 0.*..x.. */ +0xd2, 0x8c, 0x77, 0x6b, 0xdb, 0x2c, 0x60, 0x51, /* ..wk.,`Q */ +0xa0, 0x5f, 0xfd, 0x3d, 0x95, 0x8b, 0xb9, 0xfb, /* ._.=.... */ +0x72, 0x93, 0x5c, 0xf0, 0x0f, 0x74, 0xfe, 0x50, /* r.\..t.P */ +0x8a, 0x24, 0xdb, 0x81, 0x6a, 0x97, 0x33, 0x61, /* .$..j.3a */ +0x46, 0xe9, 0xaf, 0x68, 0x05, 0x22, 0x48, 0x9c, /* F..h."H. */ +0x6b, 0x62, 0x64, 0xa6, 0x0a, 0x42, 0x07, 0x9d, /* kbd..B.. */ +0x11, 0x4c, 0x68, 0x3a, 0x05, 0xc0, 0x26, 0xdb, /* .Lh:..&. */ +0xe2, 0xa8, 0x03, 0xd1, 0xd8, 0x44, 0x5c, 0xbe, /* .....D\. */ +0x24, 0x14, 0x3c, 0x68, 0x5b, 0xa2, 0xc3, 0xfc, /* $.6yj$ */ +0x62, 0x3c, 0x92, 0x5b, 0x19, 0x42, 0x24, 0xa2, /* b<.[.B$. */ +0x51, 0x1f, 0x21, 0x7a, 0x8c, 0x19, 0xb4, 0x00, /* Q.!z.... */ +0xa3, 0x36, 0x5f, 0x93, 0x51, 0x7a, 0x3c, 0x2d, /* .6_.Qz<- */ +0x3a, 0x84, 0x08, 0x41, 0x76, 0x3c, 0xe2, 0x4b, /* :..Av<.K */ +0x55, 0xbb, 0xcb, 0xbc, 0xb5, 0xf7, 0x8c, 0xd1, /* U....... */ +0x5c, 0xa8, 0x8d, 0x81, 0xbe, 0xf6, 0x34, 0x21, /* \.....4! */ +0xec, 0xec, 0x61, 0x97, 0xbe, 0x2c, 0x93, 0xd8, /* ..a..,.. */ +0xc9, 0x6a, 0x39, 0x8a, 0xc8, 0x0d, 0x58, 0xc9, /* .j9...X. */ +0xb0, 0x1c, 0x5c, 0x98, 0x86, 0x8f, 0x39, 0x98, /* ..\...9. */ +0xaa, 0xd1, 0xbb, 0x53, 0x21, 0xab, 0x4c, 0x33, /* ...S!.L3 */ +0xcb, 0xff, 0x95, 0x1a, 0x83, 0x45, 0x82, 0xcf, /* .....E.. */ +0x04, 0x4e, 0xac, 0x23, 0xad, 0x93, 0xe5, 0x1f, /* .N.#.... */ +0xcb, 0x63, 0x8f, 0xde, 0x94, 0x3e, 0x5f, 0xab, /* .c...>_. */ +0xe9, 0x2d, 0x2b, 0x23, 0x69, 0xbb, 0x38, 0xd2, /* .-+#i.8. */ +0x74, 0x7d, 0x2f, 0x2e, 0xc3, 0x43, 0x38, 0xb0, /* t}/..C8. */ +0xd2, 0xe5, 0xef, 0x5b, 0x3f, 0x67, 0x1d, 0xb3, /* ...[?g.. */ +0x1b, 0xfe, 0x71, 0xc6, 0x6e, 0x2b, 0x00, 0x64, /* ..q.n+.d */ +0x07, 0xcd, 0x61, 0x2c, 0x97, 0x52, 0x7f, 0x77, /* ..a,.R.w */ +0xf4, 0xef, 0x66, 0xe8, 0x9e, 0x8c, 0x3c, 0x60, /* ..f...<` */ +0x81, 0x9c, 0xe5, 0x41, 0x30, 0x72, 0xcf, 0x9c, /* ...A0r.. */ +0x75, 0xf4, 0xff, 0x5e, 0x85, 0x9a, 0x26, 0xe4, /* u..^..&. */ +0x61, 0xfe, 0x8b, 0x66, 0x4c, 0x53, 0xf4, 0xd6, /* a..fLS.. */ +0xb6, 0x84, 0xc0, 0x4a, 0xd8, 0xb6, 0xa7, 0xa9, /* ...J.... */ +0x9f, 0xf0, 0x2e, 0x40, 0xf0, 0x75, 0x5b, 0x3d, /* ...@.u[= */ +0x80, 0xac, 0x8b, 0xf7, 0xdf, 0x51, 0xef, 0xfa, /* .....Q.. */ +0xf4, 0xf4, 0x36, 0x79, 0x94, 0x9f, 0x65, 0xd2, /* ..6y..e. */ +0xdc, 0xb5, 0x19, 0xc3, 0x5d, 0x32, 0xda, 0x27, /* ....]2.' */ +0x68, 0xfd, 0x87, 0xcd, 0x80, 0x8b, 0x40, 0x6e, /* h.....@n */ +0x5c, 0x94, 0xbf, 0x02, 0x89, 0x05, 0x48, 0x01, /* \.....H. */ +0x99, 0x99, 0xe3, 0x87, 0x9c, 0x59, 0xdb, 0xac, /* .....Y.. */ +0x3a, 0x2c, 0x58, 0x15, 0x4d, 0xff, 0x31, 0xf5, /* :,X.M.1. */ +0x74, 0x36, 0x93, 0x96, 0xf4, 0x26, 0x25, 0xfa, /* t6...&%. */ +0x5c, 0x2f, 0x09, 0x47, 0xc7, 0xf9, 0xe7, 0x72, /* \/.G...r */ +0x69, 0xda, 0xe2, 0x00, 0xcc, 0x6c, 0xc9, 0xdd, /* i....l.. */ +0x5a, 0x73, 0x61, 0x1d, 0xf0, 0x01, 0x94, 0x66, /* Zsa....f */ +0x46, 0xed, 0xf5, 0x41, 0x28, 0xa8, 0xa8, 0x54, /* F..A(..T */ +0xab, 0x49, 0x1a, 0x98, 0xb2, 0x02, 0xd6, 0xb1, /* .I...... */ +0x82, 0x02, 0x85, 0xbf, 0x9c, 0x46, 0x85, 0x7f, /* .....F.. */ +0x4e, 0x1e, 0x4b, 0x64, 0xa3, 0x75, 0xf5, 0xc1, /* N.Kd.u.. */ +0xc4, 0x15, 0xc5, 0x1a, 0x01, 0xf6, 0xc8, 0xf0, /* ........ */ +0x66, 0x21, 0x50, 0x62, 0xf3, 0x23, 0xa4, 0xb7, /* f!Pb.#.. */ +0xa4, 0x49, 0x8c, 0x70, 0x91, 0x46, 0x95, 0x70, /* .I.p.F.p */ +0xdf, 0x4c, 0x3e, 0x9c, 0xf5, 0xaf, 0x61, 0x07, /* .L>...a. */ +0x3d, 0x46, 0xfc, 0xdf, 0xe7, 0x13, 0x11, 0x24, /* =F.....$ */ +0xcb, 0x0f, 0xcd, 0x17, 0x83, 0x2d, 0xef, 0xd2, /* .....-.. */ +0x06, 0x4b, 0x8f, 0x47, 0x78, 0xa4, 0xf6, 0x29, /* .K.Gx..) */ +0x73, 0xf3, 0x89, 0xad, 0xcc, 0xe6, 0x4b, 0x2f, /* s.....K/ */ +0x79, 0xab, 0x9c, 0x20, 0x1d, 0xd1, 0x79, 0x30, /* y.. ..y0 */ +0x2f, 0x1c, 0x8f, 0x6b, 0xcf, 0x0d, 0x76, 0xe6, /* /..k..v. */ +0x97, 0xc6, 0x09, 0xcb, 0xf4, 0xa4, 0x58, 0x6f, /* ......Xo */ +0x7d, 0xef, 0x82, 0x67, 0xd7, 0x73, 0xd0, 0x76, /* }..g.s.v */ +0xa8, 0x4b, 0x16, 0xda, 0x3c, 0x9e, 0x84, 0x29, /* .K..<..) */ +0x28, 0x77, 0xc0, 0x90, 0x50, 0x23, 0x63, 0x2e, /* (w..P#c. */ +0xaa, 0xaf, 0xf5, 0xaf, 0x68, 0xa0, 0x04, 0x73, /* ....h..s */ +0x44, 0x94, 0xf3, 0xf6, 0xac, 0x05, 0x8b, 0x68, /* D......h */ +0xfc, 0x4a, 0xe0, 0xa6, 0xca, 0xbf, 0x03, 0x2e, /* .J...... */ +0x49, 0xfd, 0xa7, 0xc7, 0xd4, 0xea, 0x0a, 0xcf, /* I....... */ +0xb6, 0xf8, 0x7d, 0xf1, 0xa4, 0x54, 0xe9, 0x8a, /* ..}..T.. */ +0xd5, 0x57, 0x8f, 0x5d, 0xf0, 0x0e, 0xf2, 0x2d, /* .W.]...- */ +0x5e, 0x1e, 0x01, 0x27, 0xf3, 0xd2, 0x79, 0x3c, /* ^..'..y< */ +0x3a, 0x7a, 0x61, 0x13, 0xc1, 0x16, 0xac, 0x89, /* :za..... */ +0xc1, 0x08, 0x04, 0xe9, 0xbe, 0x74, 0xf9, 0x00, /* .....t.. */ +0x16, 0xb6, 0x38, 0x49, 0x26, 0x1a, 0x17, 0xe6, /* ..8I&... */ +0xe5, 0x11, 0xb2, 0x59, 0x63, 0x1d, 0xbc, 0x38, /* ...Yc..8 */ +0xab, 0xbe, 0x81, 0x90, 0xc8, 0xf7, 0x9e, 0xf9, /* ........ */ +0xd8, 0xa9, 0x5e, 0x59, 0xcd, 0x03, 0xcb, 0x20, /* ..^Y... */ +0xcd, 0x33, 0xcc, 0xaa, 0x8f, 0x14, 0xe8, 0xaa, /* .3...... */ +0xa0, 0xb3, 0x21, 0xc9, 0x94, 0xeb, 0x69, 0x31, /* ..!...i1 */ +0x7c, 0x3d, 0x33, 0xff, 0xaa, 0x18, 0xe9, 0xe3, /* |=3..... */ +0x8b, 0x18, 0x32, 0x0b, 0xde, 0x61, 0xcf, 0xc8, /* ..2..a.. */ +0x77, 0x86, 0x92, 0x22, 0x27, 0x1b, 0xb5, 0x05, /* w.."'... */ +0x3e, 0x19, 0xd4, 0xe4, 0xb5, 0x33, 0xbc, 0x41, /* >....3.A */ +0x5d, 0x4e, 0x65, 0x71, 0xb9, 0x1b, 0x32, 0x2e, /* ]Neq..2. */ +0xd0, 0xe7, 0x24, 0xe2, 0x51, 0x5c, 0x45, 0xfa, /* ..$.Q\E. */ +0x41, 0xd9, 0xd4, 0x57, 0xe1, 0x82, 0xc0, 0x9c, /* A..W.... */ +0x78, 0xd5, 0x0d, 0x60, 0x62, 0x63, 0xe5, 0x01, /* x..`bc.. */ +0xa0, 0xff, 0x1b, 0x99, 0x77, 0x5c, 0xf8, 0x17, /* ....w\.. */ +0x5a, 0xf6, 0xee, 0x5c, 0x18, 0x15, 0xbc, 0xe9, /* Z..\.... */ +0x6c, 0x29, 0x4d, 0x1b, 0xb9, 0xd3, 0xb1, 0x74, /* l)M....t */ +0x3b, 0xb0, 0x17, 0xa0, 0x45, 0xac, 0xd2, 0x98, /* ;...E... */ +0xfe, 0xa8, 0xf9, 0x31, 0x0e, 0x09, 0x02, 0xff, /* ...1.... */ +0xf4, 0xd0, 0xb1, 0x8a, 0x3c, 0x67, 0x6f, 0x3d, /* .....Qv; */ +0x73, 0x46, 0xce, 0x4e, 0x83, 0x5d, 0xe0, 0x02, /* sF.N.].. */ +0x9c, 0xec, 0xf2, 0x8c, 0xd2, 0x5d, 0x3f, 0x59, /* .....]?Y */ +0x4a, 0xbd, 0x14, 0x59, 0x79, 0x23, 0x53, 0xae, /* J..Yy#S. */ +0x37, 0x68, 0x18, 0xfe, 0x3a, 0x1a, 0xa3, 0x62, /* 7h..:..b */ +0xdc, 0xcf, 0x3a, 0x89, 0x1c, 0x4b, 0xed, 0xe8, /* ..:..K.. */ +0x00, 0x34, 0x46, 0xbd, 0xbe, 0x1a, 0x2d, 0xb5, /* .4F...-. */ +0x30, 0x90, 0x44, 0x5d, 0x87, 0x37, 0x8e, 0x02, /* 0.D].7.. */ +0xd2, 0xa1, 0xaf, 0xb5, 0xff, 0x90, 0x8e, 0x56, /* .......V */ +0x0d, 0xe6, 0xc8, 0x31, 0xb1, 0x3b, 0x03, 0xdf, /* ...1.;.. */ +0xfb, 0x9c, 0x6a, 0x7d, 0x80, 0x2b, 0x9c, 0x35, /* ..j}.+.5 */ +0x96, 0xf9, 0xb6, 0x1d, 0xd7, 0x37, 0xaf, 0x3c, /* .....7.< */ +0x14, 0x07, 0xdf, 0xad, 0x8c, 0x91, 0x80, 0x4c, /* .......L */ +0x7f, 0x76, 0x58, 0x32, 0x56, 0x4d, 0xb4, 0xe6, /* .vX2VM.. */ +0x17, 0xd2, 0x01, 0xac, 0xe8, 0x34, 0x20, 0x31, /* .....4 1 */ +0xd9, 0x6e, 0xa4, 0x7e, 0x6f, 0x19, 0xe3, 0xec, /* .n.~o... */ +0x83, 0xf1, 0xdb, 0x7e, 0x27, 0x93, 0x96, 0x25, /* ...~'..% */ +0xf4, 0x37, 0x97, 0xbe, 0x60, 0xf2, 0x52, 0x20, /* .7..`.R */ +0x82, 0x3f, 0x6f, 0x3a, 0x82, 0x48, 0xee, 0xb1, /* .?o:.H.. */ +0x2d, 0x6a, 0x9e, 0xfb, 0x83, 0x6e, 0x15, 0x8f, /* -j...n.. */ +0x1a, 0x6c, 0x66, 0x56, 0x6e, 0x4d, 0x06, 0xa0, /* .lfVnM.. */ +0xcd, 0xc8, 0x51, 0x94, 0x65, 0xb1, 0x19, 0x5b, /* ..Q.e..[ */ +0x34, 0x8d, 0xc8, 0x1b, 0x76, 0x0e, 0x90, 0x16, /* 4...v... */ +0x6d, 0x2e, 0x4c, 0xa3, 0xf3, 0xb2, 0xb3, 0x48, /* m.L....H */ +0xd8, 0x96, 0xff, 0x79, 0xd4, 0xec, 0x15, 0x7b, /* ...y...{ */ +0x1d, 0x9b, 0xc1, 0xd5, 0x00, 0xf3, 0x6d, 0xae, /* ......m. */ +0x65, 0x1c, 0xbe, 0xab, 0xcb, 0x29, 0x28, 0x84, /* e....)(. */ +0xa3, 0x25, 0x8c, 0xd7, 0x37, 0xfe, 0x5b, 0x6e, /* .%..7.[n */ +0x98, 0x7a, 0xd7, 0x6a, 0x41, 0x12, 0x0f, 0x44, /* .z.jA..D */ +0xe3, 0xc7, 0x4a, 0x74, 0x5e, 0x83, 0xc5, 0x6c, /* ..Jt^..l */ +0x6b, 0x48, 0x58, 0x2e, 0xcf, 0x41, 0xff, 0x32, /* kHX..A.2 */ +0x33, 0x13, 0x1e, 0x28, 0xa7, 0xf7, 0x64, 0x96, /* 3..(..d. */ +0x51, 0xb1, 0xf6, 0xad, 0xeb, 0xb4, 0x7a, 0xc9, /* Q.....z. */ +0x0e, 0x00, 0xae, 0x00, 0x94, 0xfc, 0x37, 0x31, /* ......71 */ +0x6b, 0x0e, 0x7d, 0x40, 0x30, 0x10, 0xf6, 0xcc, /* k.}@0... */ +0x27, 0xa5, 0x37, 0xda, 0x4e, 0x35, 0xb7, 0xcb, /* '.7.N5.. */ +0xf1, 0xb9, 0x5f, 0xb7, 0x2f, 0x2d, 0xbd, 0x5f, /* .._./-._ */ +0x3d, 0x3c, 0x4d, 0x78, 0x63, 0x37, 0x77, 0x84, /* =>E. */ +0x8c, 0x39, 0x07, 0xa7, 0xc7, 0x88, 0x76, 0x36, /* .9....v6 */ +0x19, 0x61, 0x50, 0x1c, 0xf9, 0x91, 0x28, 0x9c, /* .aP...(. */ +0xb8, 0x22, 0x05, 0x31, 0x4b, 0xc8, 0x44, 0xbf, /* .".1K.D. */ +0x9c, 0x91, 0x8c, 0xea, 0x4c, 0x6d, 0x8b, 0x73, /* ....Lm.s */ +0xd7, 0xd9, 0x51, 0x03, 0x86, 0x77, 0xbb, 0x5f, /* ..Q..w._ */ +0xd1, 0xaa, 0x4d, 0x37, 0xaf, 0xff, 0x1b, 0x4f, /* ..M7...O */ +0x4d, 0xbe, 0x81, 0x15, 0x5e, 0x9f, 0x27, 0x87, /* M...^.'. */ +0x86, 0x46, 0xad, 0x10, 0x4e, 0x38, 0x32, 0x8c, /* .F..N82. */ +0x49, 0x5c, 0xa4, 0x33, 0x7c, 0xd4, 0xdd, 0xdd, /* I\.3|... */ +0x71, 0x03, 0x0d, 0xca, 0x96, 0x85, 0x1e, 0xa8, /* q....... */ +0x9a, 0xac, 0x8d, 0x60, 0x16, 0xd1, 0x65, 0xea, /* ...`..e. */ +0xeb, 0x3b, 0xa7, 0xc1, 0x02, 0x78, 0xe8, 0xd9, /* .;...x.. */ +0xb6, 0xd7, 0xc8, 0x87, 0xf9, 0xe2, 0x37, 0x30, /* ......70 */ +0x8d, 0x59, 0xcf, 0xba, 0x66, 0x5b, 0x00, 0xe9, /* .Y..f[.. */ +0xc3, 0x8b, 0xe6, 0xb6, 0xa0, 0xdc, 0x7b, 0x54, /* ......{T */ +0xa4, 0x9e, 0x91, 0x35, 0xc5, 0x68, 0x2a, 0x6e, /* ...5.h*n */ +0xc2, 0xef, 0xdb, 0x33, 0xdb, 0x4e, 0x44, 0x4f, /* ...3.NDO */ +0xec, 0x32, 0x0b, 0x86, 0x57, 0x33, 0xc6, 0xc1, /* .2..W3.. */ +0xa7, 0x3b, 0xd1, 0x11, 0x75, 0x51, 0x95, 0x0e, /* .;..uQ.. */ +0x38, 0x11, 0xfb, 0xd6, 0xa6, 0xd4, 0xbc, 0xe9, /* 8....... */ +0x1a, 0xdd, 0xa4, 0x7e, 0xe7, 0xe7, 0xbd, 0x7f, /* ...~.... */ +0x7e, 0x97, 0xf1, 0xcc, 0x5c, 0x08, 0xb1, 0x51, /* ~...\..Q */ +0x93, 0x6e, 0x63, 0x9f, 0xe9, 0x73, 0xd5, 0x34, /* .nc..s.4 */ +0x8a, 0x22, 0x0c, 0x11, 0x91, 0x6b, 0x27, 0x28, /* ."...k'( */ +0x4d, 0x88, 0xe5, 0x0b, 0x89, 0x29, 0x49, 0xaf, /* M....)I. */ +0x95, 0x1e, 0x9c, 0xb6, 0xe8, 0xb1, 0x2c, 0xba, /* ......,. */ +0xb8, 0x19, 0xef, 0x02, 0xc4, 0x6e, 0x69, 0x61, /* .....nia */ +0xce, 0x5c, 0x6c, 0x37, 0x7e, 0x56, 0xde, 0xc3, /* .\l7~V.. */ +0x7b, 0x71, 0xd8, 0x66, 0x97, 0x7e, 0xfa, 0x0d, /* {q.f.~.. */ +0x2a, 0x7c, 0x80, 0xce, 0xf7, 0x4f, 0x42, 0xd1, /* *|...OB. */ +0x13, 0x73, 0x3a, 0x7f, 0x23, 0x5a, 0x68, 0x8e, /* .s:.#Zh. */ +0xd7, 0x23, 0xbb, 0x52, 0xe7, 0x7c, 0xcf, 0x40, /* .#.R.|.@ */ +0x3d, 0xb6, 0x70, 0x3c, 0x7c, 0x07, 0x56, 0xb4, /* =.p<|.V. */ +0xae, 0xcd, 0x44, 0x30, 0x24, 0xc4, 0x45, 0x83, /* ..D0$.E. */ +0x53, 0x3c, 0x5f, 0x42, 0x93, 0x95, 0xc2, 0x06, /* S<_B.... */ +0xe3, 0x6d, 0x80, 0x53, 0xb0, 0x4f, 0xe7, 0x4c, /* .m.S.O.L */ +0x97, 0xb1, 0x27, 0x6e, 0x72, 0x7f, 0x86, 0xc5, /* ..'nr... */ +0xdb, 0xf1, 0xe8, 0xb8, 0x35, 0x67, 0x62, 0xbe, /* ....5gb. */ +0x23, 0x43, 0xd2, 0xb3, 0x15, 0xd5, 0x67, 0xfd, /* #C....g. */ +0x79, 0xf9, 0xe3, 0xed, 0x51, 0x20, 0xbb, 0xbb, /* y...Q .. */ +0x95, 0x84, 0xf7, 0x75, 0x95, 0x9b, 0xd7, 0xb3, /* ...u.... */ +0x44, 0xe6, 0x52, 0x80, 0x77, 0x50, 0xbc, 0xf9, /* D.R.wP.. */ +0xc9, 0xc4, 0xcf, 0x79, 0xd4, 0xba, 0x9b, 0xc6, /* ...y.... */ +0xeb, 0xed, 0x21, 0x16, 0xa0, 0x17, 0x9f, 0x9e, /* ..!..... */ +0x79, 0xdf, 0x4a, 0xa5, 0x7b, 0x9e, 0x7f, 0xb8, /* y.J.{... */ +0xf4, 0x06, 0xec, 0x46, 0xe4, 0x6e, 0xd0, 0x7b, /* ...F.n.{ */ +0x20, 0x22, 0xeb, 0xe0, 0xfc, 0x21, 0x8b, 0x67, /* "...!.g */ +0x2b, 0xbb, 0x12, 0x74, 0x56, 0xe3, 0x0b, 0xe1, /* +..tV... */ +0xff, 0x21, 0x82, 0x91, 0xbf, 0x9d, 0x94, 0xbf, /* .!...... */ +0x2e, 0x44, 0x6d, 0x9b, 0xb9, 0xa3, 0x98, 0x7a, /* .Dm....z */ +0xaf, 0x08, 0x8e, 0x3d, 0x18, 0x7b, 0xa4, 0x45, /* ...=.{.E */ +0xd3, 0xd5, 0xba, 0xbc, 0xac, 0x61, 0x08, 0x41, /* .....a.A */ +0x28, 0x9a, 0xfb, 0x76, 0x33, 0x4a, 0xb7, 0x3e, /* (..v3J.> */ +0xf9, 0x8b, 0xbe, 0x2a, 0xb3, 0x04, 0x44, 0x50, /* ...*..DP */ +0x97, 0x12, 0x4c, 0x8a, 0x98, 0xb5, 0xcc, 0xac, /* ..L..... */ +0x8d, 0xd8, 0x97, 0xf5, 0xcf, 0x59, 0x80, 0x4f, /* .....Y.O */ +0xb5, 0xfe, 0xcd, 0x4e, 0x0a, 0x64, 0x40, 0xc4, /* ...N.d@. */ +0x43, 0xbf, 0xfe, 0x87, 0x5a, 0x05, 0x96, 0xca, /* C...Z... */ +0x58, 0xa3, 0x3d, 0xd9, 0xd7, 0xbd, 0x97, 0x56, /* X.=....V */ +0x5c, 0x46, 0xb4, 0xcc, 0x30, 0x2a, 0xcd, 0x5b, /* \F..0*.[ */ +0xfc, 0x9e, 0xbf, 0x79, 0xfb, 0xbb, 0xf3, 0xe9, /* ...y.... */ +0x0f, 0xd1, 0x64, 0x82, 0x91, 0x90, 0x75, 0xfa, /* ..d...u. */ +0x85, 0xec, 0x61, 0xf7, 0x6b, 0x3d, 0xa0, 0x04, /* ..a.k=.. */ +0xb1, 0xc5, 0xe0, 0xad, 0xa8, 0x45, 0x6f, 0x20, /* .....Eo */ +0x36, 0x25, 0x5a, 0x0d, 0xf3, 0xc6, 0x58, 0xe4, /* 6%Z...X. */ +0x2d, 0xde, 0xdf, 0x58, 0xba, 0xda, 0x46, 0xe1, /* -..X..F. */ +0xce, 0xdd, 0x8a, 0x0e, 0x91, 0x27, 0xe7, 0xff, /* .....'.. */ +0xd8, 0xef, 0x0c, 0xbb, 0x1a, 0x11, 0x62, 0x97, /* ......b. */ +0x8a, 0xaf, 0xa3, 0x7b, 0x89, 0xb5, 0x97, 0x51, /* ...{...Q */ +0xea, 0x02, 0xba, 0xcf, 0xaf, 0x97, 0x4a, 0x17, /* ......J. */ +0x55, 0xcb, 0x2d, 0x0f, 0x75, 0x44, 0x9d, 0xe0, /* U.-.uD.. */ +0xb0, 0xd7, 0x7c, 0x92, 0x6f, 0x2a, 0x14, 0x41, /* ..|.o*.A */ +0xdb, 0x54, 0xab, 0x45, 0xf4, 0xb4, 0x13, 0xb5, /* .T.E.... */ +0x58, 0xd1, 0x58, 0x6e, 0xfa, 0x28, 0xb2, 0x02, /* X.Xn.(.. */ +0x27, 0x7e, 0xb6, 0xae, 0xc3, 0x9f, 0xd2, 0x94, /* '~...... */ +0x02, 0x12, 0xb9, 0x6f, 0xc3, 0x4f, 0xef, 0x03, /* ...o.O.. */ +0x0f, 0x1e, 0xab, 0xff, 0xb1, 0xac, 0x74, 0x96, /* ......t. */ +0xb7, 0xa7, 0x1d, 0x8e, 0xc5, 0xaa, 0x06, 0x03, /* ........ */ +0x02, 0x9d, 0x02, 0x03, 0x00, 0xeb, 0x40, 0xb3, /* ......@. */ +0xc1, 0x6c, 0xc5, 0x38, 0xd2, 0xa7, 0x40, 0x3f, /* .l.8..@? */ +0x43, 0xd8, 0x1a, 0x75, 0x1d, 0x98, 0xcf, 0x85, /* C..u.... */ +0xa4, 0x28, 0xc4, 0xed, 0xc3, 0x81, 0x9d, 0x91, /* .(...... */ +0xe3, 0xc7, 0xa3, 0x55, 0xd6, 0xa4, 0x0d, 0x8d, /* ...U.... */ +0x8a, 0xf0, 0x21, 0x16, 0x2c, 0x09, 0x26, 0x0e, /* ..!.,.&. */ +0xe6, 0x3c, 0x3f, 0x6d, 0x0a, 0x6f, 0xff, 0x4a, /* ...E. */ +0xb3, 0xb4, 0xcb, 0xa4, 0xba, 0x64, 0x0c, 0x7f, /* .....d.. */ +0xe7, 0x2c, 0x53, 0x12, 0x51, 0x92, 0x91, 0xcd, /* .,S.Q... */ +0x18, 0xa5, 0xc4, 0x01, 0x4e, 0x41, 0x95, 0xda, /* ....NA.. */ +0x6a, 0xc8, 0xc8, 0xf6, 0xab, 0x60, 0x81, 0x4f, /* j....`.O */ +0xb8, 0x0f, 0xfd, 0x95, 0x92, 0xca, 0xcc, 0x11, /* ........ */ +0x01, 0x36, 0x4d, 0xef, 0x9a, 0x19, 0x4d, 0x5a, /* .6M...MZ */ +0x61, 0x1c, 0xdf, 0x11, 0x9f, 0x48, 0x48, 0x7a, /* a....HHz */ +0x90, 0x0d, 0xa8, 0x27, 0xdb, 0xb2, 0x7e, 0x5d, /* ...'..~] */ +0x18, 0x59, 0x36, 0x6e, 0xb9, 0xde, 0x73, 0xf4, /* .Y6n..s. */ +0x70, 0x24, 0x42, 0xba, 0xc1, 0x0b, 0x14, 0x9b, /* p$B..... */ +0x95, 0x95, 0xe1, 0x67, 0xda, 0x50, 0x36, 0x60, /* ...g.P6` */ +0xa9, 0xc2, 0x55, 0xa6, 0xc8, 0x69, 0xed, 0xb3, /* ..U..i.. */ +0x19, 0xa1, 0xb9, 0xc3, 0x42, 0x74, 0x6a, 0xb3, /* ....Btj. */ +0xd6, 0x83, 0xe4, 0xf7, 0x61, 0x9f, 0x3d, 0xe9, /* ....a.=. */ +0x5f, 0xcd, 0x77, 0xc9, 0x69, 0xe4, 0xe7, 0x5d, /* _.w.i..] */ +0xae, 0x62, 0x4e, 0xa9, 0x02, 0xaa, 0xed, 0xc4, /* .bN..... */ +0xb4, 0x69, 0x0e, 0x61, 0x77, 0x1a, 0x63, 0xe2, /* .i.aw.c. */ +0xd6, 0x1b, 0x61, 0xa0, 0xaf, 0xfd, 0xce, 0x7d, /* ..a....} */ +0xe6, 0xc4, 0xf8, 0xfb, 0x7e, 0x9c, 0x8d, 0x46, /* ....~..F */ +0xf0, 0xbc, 0xd3, 0x51, 0x0e, 0xd9, 0x69, 0x8a, /* ...Q..i. */ +0xee, 0xd2, 0x89, 0xa0, 0x14, 0x62, 0x15, 0xc4, /* .....b.. */ +0xed, 0xc6, 0x95, 0x64, 0xfd, 0xf8, 0xb5, 0x90, /* ...d.... */ +0xa0, 0x96, 0x0c, 0x5c, 0x27, 0xf3, 0x60, 0x9d, /* ...\'.`. */ +0x70, 0xf7, 0x45, 0x22, 0x36, 0x53, 0x87, 0x5a, /* p.E"6S.Z */ +0x2e, 0xda, 0xe6, 0xd0, 0xa0, 0x85, 0x28, 0x89, /* ......(. */ +0xc9, 0x77, 0x08, 0xaa, 0x04, 0xf4, 0xf9, 0x51, /* .w.....Q */ +0x29, 0xc1, 0x55, 0x3e, 0xac, 0x14, 0xa8, 0x32, /* ).U>...2 */ +0x4c, 0x52, 0xff, 0xd5, 0x4e, 0x63, 0x7e, 0x08, /* LR..Nc~. */ +0x04, 0xda, 0x1a, 0x37, 0xa0, 0x36, 0xb9, 0x62, /* ...7.6.b */ +0x04, 0xbb, 0x78, 0x6a, 0xc8, 0xbd, 0xc6, 0xa1, /* ..xj.... */ +0x6b, 0x01, 0x5e, 0x4d, 0xd2, 0xf9, 0x94, 0xf8, /* k.^M.... */ +0x04, 0xe5, 0x07, 0x8f, 0xc8, 0x15, 0xe6, 0x93, /* ........ */ +0xd4, 0x6f, 0xb6, 0x60, 0x04, 0x0d, 0x55, 0xea, /* .o.`..U. */ +0x52, 0xa4, 0x05, 0xbb, 0xf8, 0x3b, 0xc9, 0xaf, /* R....;.. */ +0x67, 0x49, 0xc0, 0x16, 0x7e, 0x0f, 0x9b, 0x4d, /* gI..~..M */ +0x34, 0xb6, 0xef, 0x26, 0xaa, 0xa7, 0xfe, 0x67, /* 4..&...g */ +0x77, 0xe1, 0x1b, 0x45, 0x21, 0xd7, 0xda, 0xf4, /* w..E!... */ +0x7a, 0xae, 0xb2, 0xd3, 0xad, 0x5c, 0xc4, 0x9d, /* z....\.. */ +0x5c, 0xaf, 0x20, 0x8f, 0xcf, 0xa8, 0x2a, 0x2e, /* \. ...*. */ +0xa3, 0xc0, 0x0b, 0xbd, 0xf5, 0x3d, 0x0f, 0xd0, /* .....=.. */ +0x0d, 0x23 /* .# */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt15[1514] = { +0x02, 0x00, 0x00, 0x70, 0xca, 0x04, 0x5e, 0xe9, /* ...p..^. */ +0x1e, 0xa6, 0x21, 0x64, 0x08, 0x00, 0x45, 0x00, /* ..!d..E. */ +0x05, 0xdc, 0xe7, 0xcf, 0x00, 0x00, 0x33, 0x06, /* ......3. */ +0x2b, 0x39, 0x98, 0xc7, 0x13, 0xa1, 0xc0, 0xa8, /* +9...... */ +0x02, 0x03, 0x00, 0x50, 0xc9, 0xc1, 0xb1, 0x64, /* ...P...d */ +0xd4, 0xf5, 0xfa, 0xdf, 0xdf, 0x46, 0x50, 0x18, /* .....FP. */ +0xff, 0xff, 0xae, 0x36, 0x00, 0x00, 0x9f, 0x98, /* ...6.... */ +0x12, 0xcc, 0x36, 0xc2, 0x98, 0xa8, 0x63, 0xff, /* ..6...c. */ +0xb0, 0x3d, 0x53, 0x91, 0xb3, 0xfa, 0x2a, 0xca, /* .=S...*. */ +0x80, 0x76, 0xff, 0x03, 0x13, 0x3c, 0xe9, 0x13, /* .v...<.. */ +0x9b, 0x7a, 0x3c, 0xc4, 0x80, 0x55, 0x67, 0x91, /* .z<..Ug. */ +0xe2, 0x5f, 0x96, 0x6c, 0x2c, 0xe4, 0x94, 0xf5, /* ._.l,... */ +0x26, 0xaf, 0x10, 0x9d, 0x41, 0x87, 0xc5, 0xd2, /* &...A... */ +0x00, 0xbf, 0x63, 0x0b, 0x89, 0x4c, 0x63, 0x2c, /* ..c..Lc, */ +0x14, 0xef, 0x05, 0x02, 0x0f, 0x99, 0x4e, 0xa8, /* ......N. */ +0x57, 0x83, 0x07, 0x04, 0x3c, 0xd8, 0x2b, 0xcb, /* W...<.+. */ +0x98, 0x34, 0x8f, 0xdd, 0x5a, 0xf7, 0xf3, 0x51, /* .4..Z..Q */ +0x25, 0xd8, 0x3c, 0xef, 0x2b, 0xdc, 0xd0, 0xa2, /* %.<.+... */ +0xec, 0xb1, 0xe7, 0xb7, 0xbd, 0x6d, 0x31, 0x90, /* .....m1. */ +0x25, 0x65, 0x7e, 0x6c, 0xbe, 0xf0, 0xe8, 0x78, /* %e~l...x */ +0x41, 0x04, 0x6c, 0x5e, 0xc8, 0x7f, 0x9b, 0x2f, /* A.l^.../ */ +0x20, 0x9e, 0xd3, 0xdf, 0x9b, 0x94, 0x47, 0x6f, /* .....Go */ +0x6e, 0x0a, 0xfe, 0xe3, 0xc8, 0x44, 0x2f, 0x72, /* n....D/r */ +0x9d, 0xec, 0x0c, 0xa7, 0xeb, 0x6e, 0xab, 0x6b, /* .....n.k */ +0xe7, 0x0b, 0x51, 0x54, 0xac, 0xb4, 0x14, 0x18, /* ..QT.... */ +0x21, 0xce, 0x4b, 0x2a, 0x88, 0x6a, 0x8f, 0x4a, /* !.K*.j.J */ +0x8c, 0xbd, 0xea, 0xaa, 0x14, 0x23, 0x23, 0x8d, /* .....##. */ +0x6b, 0xae, 0xb7, 0xb1, 0x67, 0xbc, 0xce, 0xf7, /* k...g... */ +0x0a, 0xc0, 0x7a, 0x42, 0xdd, 0x5a, 0xc5, 0x3a, /* ..zB.Z.: */ +0x58, 0x2a, 0xd4, 0x00, 0x83, 0x76, 0x66, 0x90, /* X*...vf. */ +0x9b, 0xa9, 0x39, 0xe4, 0xa2, 0xe6, 0xc9, 0xa6, /* ..9..... */ +0x5a, 0x86, 0xb3, 0x0b, 0x29, 0xa2, 0x21, 0xc0, /* Z...).!. */ +0x56, 0x99, 0x53, 0xae, 0xb9, 0x4a, 0x44, 0x4a, /* V.S..JDJ */ +0xb0, 0x10, 0x6a, 0x82, 0x70, 0xe8, 0x53, 0xa0, /* ..j.p.S. */ +0xae, 0xb0, 0xf3, 0x83, 0x63, 0x89, 0x9e, 0x9a, /* ....c... */ +0x40, 0x6f, 0xad, 0x94, 0xd6, 0x7d, 0x63, 0x77, /* @o...}cw */ +0x77, 0x5d, 0x5d, 0xb9, 0x7b, 0x53, 0x69, 0x01, /* w]].{Si. */ +0x41, 0xf6, 0x9a, 0x53, 0x5a, 0x6b, 0xf2, 0x06, /* A..SZk.. */ +0xb3, 0x4e, 0x4f, 0xa4, 0x66, 0x4c, 0x6f, 0x39, /* .NO.fLo9 */ +0xff, 0x0e, 0x23, 0xa3, 0x1e, 0x58, 0x03, 0xdd, /* ..#..X.. */ +0x2a, 0x1c, 0xad, 0x1f, 0x21, 0xc0, 0x5e, 0x48, /* *...!.^H */ +0x7c, 0x45, 0x02, 0xd5, 0x03, 0x5f, 0xe2, 0x1c, /* |E..._.. */ +0x4f, 0xfa, 0x64, 0x2f, 0xb0, 0x42, 0xff, 0x41, /* O.d/.B.A */ +0xef, 0x1d, 0x92, 0x2b, 0xe6, 0x38, 0xdc, 0x8d, /* ...+.8.. */ +0xf2, 0xbb, 0x25, 0x91, 0xbf, 0x06, 0x80, 0xa7, /* ..%..... */ +0xb8, 0xa0, 0xa7, 0x53, 0x8e, 0x82, 0x1e, 0x6c, /* ...S...l */ +0xa0, 0xcf, 0x9e, 0x4d, 0xb9, 0x7c, 0x45, 0x9e, /* ...M.|E. */ +0x68, 0xeb, 0x5f, 0x6a, 0xb3, 0xe5, 0xcd, 0xc5, /* h._j.... */ +0xdf, 0xdd, 0x78, 0x9c, 0x83, 0xe6, 0x76, 0x28, /* ..x...v( */ +0x2b, 0xa0, 0x7f, 0x78, 0x12, 0x30, 0x95, 0xe6, /* +..x.0.. */ +0xc6, 0xa5, 0x09, 0x64, 0x31, 0x95, 0xdd, 0xc2, /* ...d1... */ +0x50, 0x2b, 0x91, 0x52, 0x77, 0x2f, 0x5a, 0x7d, /* P+.Rw/Z} */ +0x26, 0x55, 0x67, 0x7b, 0xcd, 0xf4, 0x3d, 0xcc, /* &Ug{..=. */ +0x85, 0x1e, 0x3b, 0x93, 0x3f, 0x61, 0x16, 0xc3, /* ..;.?a.. */ +0x4b, 0x5e, 0xd2, 0xb1, 0xa0, 0x05, 0x0d, 0x01, /* K^...... */ +0xc8, 0xf2, 0x51, 0x64, 0xbd, 0x8f, 0xa9, 0x82, /* ..Qd.... */ +0xad, 0x38, 0xc3, 0x4a, 0x0d, 0xef, 0x3e, 0x5b, /* .8.J..>[ */ +0x01, 0xb0, 0x0b, 0x4d, 0x1d, 0x95, 0x6f, 0x0b, /* ...M..o. */ +0xdc, 0xf7, 0x80, 0x56, 0xf5, 0xc5, 0x48, 0x74, /* ...V..Ht */ +0xf0, 0xad, 0xd9, 0xab, 0x6d, 0x3a, 0x42, 0xe4, /* ....m:B. */ +0xe2, 0xa4, 0x75, 0xf5, 0xeb, 0x31, 0x92, 0x39, /* ..u..1.9 */ +0xd2, 0xc7, 0x70, 0xaa, 0x77, 0xed, 0xaf, 0xd8, /* ..p.w... */ +0x27, 0x61, 0x5c, 0x40, 0x07, 0xa2, 0x0c, 0x2e, /* 'a\@.... */ +0x63, 0x62, 0x30, 0xbb, 0x8b, 0x0d, 0xf7, 0xf5, /* cb0..... */ +0xba, 0x67, 0x80, 0xb9, 0x71, 0x05, 0x20, 0x47, /* .g..q. G */ +0xd1, 0xbe, 0x91, 0xec, 0xbd, 0xcd, 0x98, 0x0f, /* ........ */ +0x6f, 0xb5, 0x69, 0xba, 0x24, 0x14, 0xdb, 0x18, /* o.i.$... */ +0xd0, 0x04, 0xfc, 0x57, 0x2a, 0xd0, 0xb1, 0x4f, /* ...W*..O */ +0x0e, 0x71, 0x33, 0xce, 0xba, 0x38, 0xec, 0xec, /* .q3..8.. */ +0x3e, 0x79, 0x7a, 0x55, 0x99, 0xec, 0x85, 0xc6, /* >yzU.... */ +0xfa, 0x24, 0x6a, 0x51, 0xe3, 0x7a, 0x6d, 0xe6, /* .$jQ.zm. */ +0x42, 0x29, 0x0c, 0x09, 0xa6, 0x42, 0x88, 0x00, /* B)...B.. */ +0x0e, 0xe8, 0x1b, 0x99, 0xf6, 0x2f, 0xdd, 0xb4, /* ...../.. */ +0x79, 0x9c, 0x02, 0xa5, 0xba, 0x4b, 0x40, 0x06, /* y....K@. */ +0xc0, 0x33, 0x3f, 0xcc, 0xcc, 0x9e, 0x4d, 0x02, /* .3?...M. */ +0xb0, 0x2b, 0x92, 0x9c, 0x92, 0x8c, 0x48, 0xc1, /* .+....H. */ +0x20, 0x21, 0xa2, 0x4e, 0xcc, 0xa6, 0x5a, 0x35, /* !.N..Z5 */ +0xb0, 0x33, 0x4e, 0x5d, 0xe8, 0xe8, 0xda, 0xab, /* .3N].... */ +0xa3, 0xf6, 0xb0, 0x97, 0x24, 0xd1, 0x16, 0x92, /* ....$... */ +0xb6, 0x47, 0x0e, 0xb4, 0x4d, 0x1d, 0x98, 0x0e, /* .G..M... */ +0xf3, 0x24, 0x62, 0xa9, 0xb3, 0x2d, 0x8c, 0x63, /* .$b..-.c */ +0x27, 0x8c, 0xd7, 0xf6, 0x1c, 0x8c, 0x4e, 0xa1, /* '.....N. */ +0x52, 0xa7, 0x46, 0x38, 0x87, 0x34, 0x31, 0x06, /* R.F8.41. */ +0x58, 0x10, 0x30, 0x27, 0xae, 0x36, 0x8b, 0x05, /* X.0'.6.. */ +0x9f, 0xf9, 0xe9, 0x63, 0xda, 0x4d, 0xf0, 0x9a, /* ...c.M.. */ +0xb3, 0xca, 0x38, 0x15, 0xd1, 0xe5, 0x00, 0xed, /* ..8..... */ +0xf1, 0x25, 0x64, 0xc2, 0xeb, 0x18, 0xe2, 0xeb, /* .%d..... */ +0x38, 0xc8, 0xb2, 0xb8, 0x79, 0x38, 0x0b, 0xf0, /* 8...y8.. */ +0x8a, 0xec, 0x70, 0x31, 0xef, 0x99, 0x86, 0x87, /* ..p1.... */ +0xd0, 0x5f, 0x06, 0xe4, 0xb3, 0xc2, 0x10, 0x35, /* ._.....5 */ +0x78, 0xfd, 0xe4, 0xee, 0x31, 0x73, 0x07, 0xe4, /* x...1s.. */ +0x2a, 0x10, 0x1f, 0xa3, 0x17, 0x66, 0x5d, 0xe5, /* *....f]. */ +0x1f, 0x36, 0xf4, 0x47, 0x6b, 0xdb, 0x3a, 0x34, /* .6.Gk.:4 */ +0xa4, 0x39, 0x89, 0x6e, 0x0e, 0xf3, 0xb4, 0xff, /* .9.n.... */ +0x54, 0x06, 0x13, 0xcb, 0x99, 0xcb, 0xe8, 0xa1, /* T....... */ +0xc1, 0x13, 0x0b, 0xf6, 0xe3, 0x8e, 0x30, 0xeb, /* ......0. */ +0x42, 0x91, 0x0f, 0x8e, 0x66, 0x12, 0xf7, 0xc8, /* B...f... */ +0xcc, 0xc4, 0xb7, 0x84, 0x26, 0x9c, 0xa3, 0x94, /* ....&... */ +0x15, 0x43, 0x60, 0x82, 0x5f, 0xa9, 0xce, 0x98, /* .C`._... */ +0x94, 0x76, 0x9a, 0x21, 0xca, 0x25, 0x25, 0xa6, /* .v.!.%%. */ +0x83, 0x07, 0x91, 0xeb, 0xe5, 0xed, 0x87, 0x8a, /* ........ */ +0x45, 0x17, 0xb9, 0xc1, 0x92, 0xdb, 0xba, 0xd0, /* E....... */ +0xf8, 0x88, 0x79, 0x27, 0xe1, 0x38, 0x22, 0xe9, /* ..y'.8". */ +0x45, 0x4e, 0xce, 0x5b, 0x86, 0x6c, 0x2a, 0xb4, /* EN.[.l*. */ +0x03, 0xfe, 0x1c, 0xfa, 0x5c, 0x3a, 0x47, 0x96, /* ....\:G. */ +0x3a, 0xa4, 0xa9, 0x62, 0xce, 0xe0, 0x42, 0x33, /* :..b..B3 */ +0xf4, 0xad, 0x32, 0x0d, 0x97, 0xc9, 0xd6, 0xae, /* ..2..... */ +0x5b, 0xe7, 0x45, 0x2e, 0xf5, 0x76, 0x5d, 0xf9, /* [.E..v]. */ +0x1e, 0x6c, 0xeb, 0x0e, 0xab, 0x6e, 0x10, 0x6a, /* .l...n.j */ +0x19, 0x85, 0xff, 0x61, 0x73, 0xba, 0x89, 0x3b, /* ...as..; */ +0xad, 0x07, 0x28, 0x83, 0x39, 0xfa, 0x1b, 0x1a, /* ..(.9... */ +0xfb, 0x7e, 0x35, 0x68, 0xd1, 0xa0, 0x9e, 0x17, /* .~5h.... */ +0x93, 0x7b, 0xe2, 0xd5, 0x3e, 0xb2, 0x4c, 0x9b, /* .{..>.L. */ +0xf1, 0xa9, 0x1a, 0x74, 0xe6, 0x7d, 0x9d, 0x78, /* ...t.}.x */ +0x56, 0xdd, 0xd7, 0xd3, 0x37, 0x37, 0x45, 0x70, /* V...77Ep */ +0x0f, 0xa8, 0xcd, 0x5b, 0x41, 0xec, 0x6b, 0xb1, /* ...[A.k. */ +0x08, 0xbd, 0x6e, 0x48, 0xad, 0x96, 0x50, 0x4c, /* ..nH..PL */ +0x7f, 0xa2, 0xbb, 0x43, 0x25, 0x47, 0xb2, 0x41, /* ...C%G.A */ +0x7e, 0x0a, 0x7a, 0x26, 0x2c, 0x8b, 0x0e, 0x30, /* ~.z&,..0 */ +0x16, 0xbd, 0x7d, 0xb2, 0xd3, 0x54, 0xed, 0xfd, /* ..}..T.. */ +0x87, 0x3e, 0x56, 0x94, 0x83, 0x23, 0xd3, 0x05, /* .>V..#.. */ +0xe6, 0x16, 0x4e, 0xef, 0x3f, 0x7d, 0x9b, 0x90, /* ..N.?}.. */ +0x2d, 0x20, 0x0e, 0x81, 0xa3, 0x35, 0xe6, 0xe1, /* - ...5.. */ +0x8e, 0x34, 0xa4, 0xc3, 0x62, 0xc5, 0xd8, 0xc7, /* .4..b... */ +0x34, 0x48, 0x12, 0x7f, 0xad, 0xd0, 0x07, 0x51, /* 4H.....Q */ +0x8e, 0xfe, 0xa7, 0xc2, 0x36, 0x68, 0x56, 0xf8, /* ....6hV. */ +0x28, 0x55, 0x1a, 0x04, 0x16, 0xb7, 0xb5, 0x1c, /* (U...... */ +0x0e, 0x6b, 0xb6, 0x5b, 0xf9, 0x64, 0x56, 0x1c, /* .k.[.dV. */ +0x1f, 0x9e, 0x5a, 0xc6, 0x55, 0x7a, 0x6c, 0x45, /* ..Z.UzlE */ +0xd6, 0xd1, 0xc6, 0x52, 0x8a, 0x0f, 0x99, 0x23, /* ...R...# */ +0x37, 0x96, 0xf4, 0x2e, 0x5f, 0x21, 0x77, 0x46, /* 7..._!wF */ +0x78, 0x30, 0xa9, 0x9e, 0x91, 0xce, 0xd1, 0x3a, /* x0.....: */ +0xf6, 0x54, 0xa1, 0x87, 0x0a, 0x85, 0xdd, 0xb3, /* .T...... */ +0xe9, 0x66, 0xaf, 0x6e, 0x07, 0xfb, 0xc3, 0x92, /* .f.n.... */ +0xfa, 0x55, 0xa9, 0x14, 0x42, 0xbd, 0x14, 0x72, /* .U..B..r */ +0x48, 0x5c, 0x1d, 0xd2, 0x56, 0x95, 0x7a, 0x01, /* H\..V.z. */ +0xcb, 0x9e, 0x6b, 0xa0, 0x7c, 0x9e, 0xf5, 0x05, /* ..k.|... */ +0x94, 0xe1, 0x39, 0x5c, 0x9f, 0xc4, 0xf7, 0xb8, /* ..9\.... */ +0x16, 0xab, 0x76, 0x68, 0xef, 0x67, 0x3f, 0x3e, /* ..vh.g?> */ +0x15, 0x12, 0x94, 0x5d, 0x80, 0xcb, 0x14, 0x3e, /* ...]...> */ +0x9d, 0xa3, 0xe3, 0xa6, 0x83, 0xb6, 0xa2, 0x06, /* ........ */ +0x7c, 0x62, 0xfd, 0xe5, 0x19, 0x1e, 0xed, 0x8a, /* |b...... */ +0x73, 0x88, 0x9b, 0xf6, 0xeb, 0xe8, 0x18, 0x80, /* s....... */ +0x3b, 0xe9, 0xeb, 0x9e, 0xf7, 0x3c, 0x91, 0x5b, /* ;....<.[ */ +0xeb, 0xf7, 0x4b, 0xc1, 0x80, 0x55, 0x19, 0x8c, /* ..K..U.. */ +0x8e, 0x70, 0x27, 0xd4, 0xaa, 0x7c, 0xf3, 0xc3, /* .p'..|.. */ +0xbf, 0x62, 0x11, 0x92, 0x8e, 0x20, 0x94, 0x66, /* .b... .f */ +0x26, 0x79, 0xc4, 0x0b, 0x1c, 0xae, 0x2a, 0x13, /* &y....*. */ +0x53, 0xb4, 0x76, 0xe9, 0xd1, 0x70, 0x86, 0xd2, /* S.v..p.. */ +0x5b, 0x05, 0xa4, 0x18, 0x22, 0xe9, 0xd9, 0x2c, /* [...".., */ +0x4a, 0xc7, 0xab, 0x37, 0x28, 0x9b, 0xe0, 0xa8, /* J..7(... */ +0xc2, 0x17, 0xed, 0xd4, 0x91, 0x4a, 0x2c, 0x27, /* .....J,' */ +0xac, 0x98, 0xa6, 0xa4, 0x15, 0x34, 0x7b, 0x81, /* .....4{. */ +0x96, 0x6d, 0xe1, 0xe8, 0xfd, 0x28, 0x8b, 0x39, /* .m...(.9 */ +0xe1, 0x51, 0xa5, 0xaf, 0x2c, 0xf9, 0xa7, 0xdc, /* .Q..,... */ +0x6e, 0xd4, 0xf9, 0xcd, 0xa6, 0xb6, 0xb3, 0xff, /* n....... */ +0xfb, 0xe7, 0xa7, 0xea, 0xcb, 0xc5, 0x90, 0x09, /* ........ */ +0x6e, 0x30, 0x2f, 0x40, 0xff, 0x59, 0xbf, 0xc9, /* n0/@.Y.. */ +0x3a, 0x81, 0x61, 0xc8, 0x98, 0xc3, 0xf7, 0x1b, /* :.a..... */ +0x35, 0x03, 0x17, 0x2b, 0xcb, 0xdc, 0x12, 0xfc, /* 5..+.... */ +0x82, 0xc2, 0xd4, 0xa7, 0xb8, 0xd7, 0xf4, 0xf2, /* ........ */ +0xb2, 0xc4, 0x57, 0xab, 0xfb, 0x61, 0xc5, 0xb8, /* ..W..a.. */ +0x01, 0x72, 0xdb, 0xc3, 0xce, 0x86, 0x3a, 0x14, /* .r....:. */ +0x6f, 0x7c, 0xfe, 0xd4, 0x66, 0x4a, 0x4a, 0x7e, /* o|..fJJ~ */ +0xba, 0x75, 0xea, 0xde, 0x1c, 0xd0, 0xf6, 0x5d, /* .u.....] */ +0x9b, 0x54, 0x92, 0x92, 0x18, 0x6d, 0xe6, 0x66, /* .T...m.f */ +0x22, 0xf6, 0xe9, 0xbe, 0xcf, 0x93, 0x51, 0x6d, /* ".....Qm */ +0xee, 0x90, 0x12, 0x66, 0x5a, 0x10, 0xb9, 0x90, /* ...fZ... */ +0x96, 0x5a, 0x8a, 0xb9, 0x1f, 0x40, 0xf5, 0x1c, /* .Z...@.. */ +0xde, 0x11, 0xa6, 0xa7, 0x4b, 0xc7, 0x4e, 0xe3, /* ....K.N. */ +0x88, 0x9c, 0xb0, 0xe0, 0x73, 0x8c, 0x33, 0x99, /* ....s.3. */ +0x1d, 0x3a, 0x58, 0x9e, 0xa9, 0xff, 0x85, 0x5a, /* .:X....Z */ +0x49, 0x48, 0xc8, 0x64, 0x65, 0x0f, 0x05, 0xa5, /* IH.de... */ +0xbc, 0x8d, 0x09, 0x74, 0x21, 0xd8, 0x71, 0x07, /* ...t!.q. */ +0x81, 0xf4, 0x95, 0xdf, 0xbf, 0x55, 0x53, 0x7a, /* .....USz */ +0xa7, 0xf6, 0xb0, 0x47, 0x2f, 0xc1, 0xfc, 0x5d, /* ...G/..] */ +0x4d, 0x2f, 0xcf, 0xfe, 0xac, 0x80, 0x8c, 0xe9, /* M/...... */ +0x83, 0x83, 0x42, 0x98, 0x8f, 0xc9, 0x10, 0x1d, /* ..B..... */ +0x7c, 0x3c, 0xff, 0x54, 0x4a, 0x7c, 0xc9, 0xbc, /* |<.TJ|.. */ +0x97, 0x7a, 0xf2, 0x5d, 0x77, 0x2c, 0xaa, 0x37, /* .z.]w,.7 */ +0x5c, 0x0f, 0x25, 0x10, 0x6b, 0x2f, 0xe3, 0x23, /* \.%.k/.# */ +0x03, 0x0a, 0x5c, 0x83, 0xac, 0x42, 0x35, 0x83, /* ..\..B5. */ +0x76, 0x90, 0x87, 0x67, 0xc8, 0x69, 0x88, 0x0e, /* v..g.i.. */ +0xdc, 0x52, 0xbb, 0x5f, 0xf8, 0xa0, 0xec, 0x63, /* .R._...c */ +0xf1, 0x5f, 0xff, 0x45, 0x65, 0x98, 0x37, 0x85, /* ._.Ee.7. */ +0x1c, 0x37, 0x37, 0xb4, 0xbd, 0xce, 0x24, 0xc9, /* .77...$. */ +0xa6, 0x3d, 0x9e, 0xe8, 0xad, 0x21, 0x0e, 0x87, /* .=...!.. */ +0x42, 0x65, 0xa6, 0x86, 0x99, 0xcf, 0x4e, 0xa6, /* Be....N. */ +0x69, 0x9d, 0xca, 0xe6, 0xb9, 0xef, 0x90, 0xf1, /* i....... */ +0xe4, 0x4e /* .N */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt16[1514] = { +0x02, 0x00, 0x00, 0x70, 0xca, 0x04, 0x5e, 0xe9, /* ...p..^. */ +0x1e, 0xa6, 0x21, 0x64, 0x08, 0x00, 0x45, 0x00, /* ..!d..E. */ +0x05, 0xdc, 0xe7, 0xd0, 0x00, 0x00, 0x33, 0x06, /* ......3. */ +0x2b, 0x38, 0x98, 0xc7, 0x13, 0xa1, 0xc0, 0xa8, /* +8...... */ +0x02, 0x03, 0x00, 0x50, 0xc9, 0xc1, 0xb1, 0x64, /* ...P...d */ +0xda, 0xa9, 0xfa, 0xdf, 0xdf, 0x46, 0x50, 0x10, /* .....FP. */ +0xff, 0xff, 0x14, 0x9b, 0x00, 0x00, 0xc9, 0xa4, /* ........ */ +0x5b, 0x75, 0xc0, 0x09, 0x50, 0x9d, 0x15, 0x10, /* [u..P... */ +0x72, 0x98, 0x3a, 0x18, 0xa1, 0xef, 0x85, 0x44, /* r.:....D */ +0xf6, 0xa8, 0x13, 0xda, 0x86, 0x42, 0x42, 0x9e, /* .....BB. */ +0xff, 0xfb, 0x72, 0x5f, 0x33, 0xeb, 0x08, 0xb0, /* ..r_3... */ +0x19, 0x26, 0x4e, 0x9f, 0x8c, 0xae, 0xbc, 0x4a, /* .&N....J */ +0xf2, 0x8f, 0x4e, 0x77, 0x18, 0xba, 0x51, 0x06, /* ..Nw..Q. */ +0x68, 0x7c, 0x1e, 0x78, 0x29, 0x7a, 0xc7, 0x0d, /* h|.x)z.. */ +0x05, 0xcf, 0x58, 0x2f, 0x38, 0x1e, 0xed, 0x5e, /* ..X/8..^ */ +0x05, 0x79, 0x9c, 0x21, 0xf4, 0xaf, 0x7b, 0x6d, /* .y.!..{m */ +0xf3, 0x4c, 0x9c, 0xd1, 0x0f, 0xf7, 0x91, 0x14, /* .L...... */ +0x20, 0xe6, 0x7a, 0x17, 0xc0, 0x04, 0x1b, 0x8a, /* .z..... */ +0x12, 0xe5, 0x10, 0xf7, 0xfa, 0x27, 0x18, 0x03, /* .....'.. */ +0xfe, 0xd1, 0x49, 0x99, 0xda, 0x8f, 0x79, 0xff, /* ..I...y. */ +0xc3, 0x0f, 0x31, 0x02, 0x2a, 0x9c, 0x59, 0xf7, /* ..1.*.Y. */ +0x3c, 0x08, 0xcf, 0xfd, 0x60, 0x0e, 0x90, 0x9c, /* <...`... */ +0x04, 0x00, 0x93, 0xe7, 0xe7, 0x65, 0xf2, 0x39, /* .....e.9 */ +0x8c, 0xea, 0x36, 0xc4, 0x24, 0x25, 0x09, 0x85, /* ..6.$%.. */ +0x9a, 0x20, 0xc5, 0x30, 0xe8, 0x19, 0x92, 0x58, /* . .0...X */ +0x6e, 0x47, 0xc5, 0xa6, 0x83, 0x0f, 0x23, 0xe6, /* nG....#. */ +0xe7, 0x4e, 0xa7, 0xfd, 0xf9, 0x5d, 0xf7, 0x3f, /* .N...].? */ +0x4e, 0xd4, 0xdd, 0x83, 0xac, 0x54, 0x34, 0x8e, /* N....T4. */ +0xdf, 0x6d, 0x99, 0x69, 0xcd, 0x73, 0x3a, 0x73, /* .m.i.s:s */ +0x18, 0x73, 0xc4, 0x75, 0x22, 0x0d, 0x90, 0x30, /* .s.u"..0 */ +0x5e, 0xa7, 0x7c, 0xf7, 0xe9, 0x2e, 0x09, 0x3f, /* ^.|....? */ +0x0d, 0x55, 0xba, 0x13, 0x7c, 0xd8, 0x46, 0x0e, /* .U..|.F. */ +0xc9, 0x89, 0x08, 0x88, 0x8e, 0xbd, 0x95, 0x58, /* .......X */ +0x36, 0x19, 0x58, 0xd0, 0x43, 0xc5, 0xd3, 0xb1, /* 6.X.C... */ +0x99, 0xc9, 0x19, 0xe7, 0x9d, 0x5e, 0xfe, 0xe5, /* .....^.. */ +0x61, 0xbe, 0xa9, 0x9d, 0xcb, 0x1f, 0xbe, 0xc9, /* a....... */ +0x3a, 0x21, 0xa0, 0x58, 0x21, 0x2e, 0xce, 0x89, /* :!.X!... */ +0x1b, 0xd5, 0x6c, 0x36, 0x87, 0xea, 0x25, 0x56, /* ..l6..%V */ +0xf5, 0x13, 0x79, 0xfd, 0xc5, 0xf1, 0x4a, 0x97, /* ..y...J. */ +0x73, 0x51, 0xc0, 0x6d, 0x8f, 0x35, 0x97, 0x52, /* sQ.m.5.R */ +0x03, 0xb2, 0x48, 0x2d, 0xd9, 0x4e, 0xbb, 0x3f, /* ..H-.N.? */ +0x79, 0xbc, 0x12, 0xeb, 0xa9, 0x56, 0xcf, 0xdb, /* y....V.. */ +0x6b, 0x47, 0x0b, 0x35, 0x98, 0x22, 0x6b, 0x17, /* kG.5."k. */ +0x42, 0x37, 0x89, 0x7b, 0x51, 0x26, 0x10, 0x6c, /* B7.{Q&.l */ +0x2a, 0x9a, 0xbf, 0x6b, 0xf0, 0x20, 0x40, 0xf9, /* *..k. @. */ +0x8c, 0x82, 0xa6, 0x56, 0xd8, 0x85, 0x87, 0xdf, /* ...V.... */ +0x4c, 0xdd, 0xa7, 0xb3, 0x91, 0xf8, 0x0d, 0x6a, /* L......j */ +0xb2, 0x32, 0x96, 0x15, 0x17, 0x2b, 0x0c, 0x0e, /* .2...+.. */ +0xfd, 0x9b, 0x7f, 0x9f, 0x57, 0xcc, 0xe0, 0x2d, /* ....W..- */ +0xd2, 0xe9, 0xbf, 0x41, 0x84, 0xef, 0x23, 0x02, /* ...A..#. */ +0xf4, 0x53, 0xff, 0xdb, 0xb4, 0x08, 0x9a, 0xf7, /* .S...... */ +0xb8, 0xd0, 0x62, 0x4b, 0x49, 0xa3, 0xc6, 0x03, /* ..bKI... */ +0x16, 0x78, 0x5f, 0xdc, 0xe2, 0xe1, 0x2e, 0xdb, /* .x_..... */ +0x63, 0xdc, 0xd9, 0x46, 0x8a, 0x7c, 0xbb, 0xc2, /* c..F.|.. */ +0x30, 0xb3, 0xfb, 0xb3, 0x2e, 0x67, 0x39, 0xc7, /* 0....g9. */ +0x2d, 0x9c, 0xc8, 0x2b, 0xee, 0x1b, 0xea, 0xad, /* -..+.... */ +0x92, 0x0e, 0x94, 0x43, 0xc7, 0xd9, 0x13, 0x24, /* ...C...$ */ +0x6e, 0x97, 0x72, 0xfe, 0x15, 0x8d, 0x52, 0xfb, /* n.r...R. */ +0xe4, 0x80, 0x53, 0xad, 0x25, 0x6c, 0xf0, 0x19, /* ..S.%l.. */ +0xbc, 0x54, 0x55, 0x77, 0x48, 0x3c, 0x36, 0xfc, /* .TUwH<6. */ +0xe1, 0x84, 0x39, 0x00, 0x9b, 0xd0, 0xc6, 0xc8, /* ..9..... */ +0x44, 0xf7, 0xb1, 0x08, 0xc9, 0x51, 0x02, 0x91, /* D....Q.. */ +0x4c, 0xa9, 0x9e, 0x5f, 0x8d, 0xbf, 0x3b, 0x0e, /* L.._..;. */ +0x9e, 0xd6, 0x0d, 0xaf, 0x52, 0xae, 0x01, 0x04, /* ....R... */ +0xcc, 0x3e, 0x28, 0xc8, 0xb9, 0xa8, 0x93, 0xee, /* .>(..... */ +0x78, 0x85, 0x9e, 0x1e, 0x39, 0xef, 0xb2, 0x05, /* x...9... */ +0xd6, 0x06, 0xed, 0x21, 0xbe, 0x0a, 0xe0, 0x44, /* ...!...D */ +0x5d, 0x60, 0xa6, 0x95, 0x48, 0xd5, 0x99, 0x62, /* ]`..H..b */ +0x65, 0x8f, 0xb1, 0x99, 0x2f, 0x76, 0x45, 0xb8, /* e.../vE. */ +0x0c, 0x26, 0x39, 0x4e, 0xd1, 0x16, 0x58, 0x52, /* .&9N..XR */ +0x5d, 0x2a, 0xe2, 0xf7, 0x19, 0xb1, 0xc0, 0x1b, /* ]*...... */ +0x1c, 0x2b, 0xd4, 0x61, 0xaa, 0x66, 0xe1, 0x0d, /* .+.a.f.. */ +0x89, 0x8e, 0xf9, 0x22, 0xec, 0xe9, 0x90, 0x1a, /* ...".... */ +0xcb, 0x6a, 0x53, 0x83, 0xc8, 0xca, 0x2d, 0x85, /* .jS...-. */ +0x17, 0x87, 0xe7, 0x91, 0x44, 0xf9, 0x96, 0x4c, /* ....D..L */ +0x44, 0x93, 0x6e, 0x5c, 0xd5, 0x40, 0x47, 0x65, /* D.n\.@Ge */ +0x62, 0x32, 0x36, 0x33, 0xcf, 0x0f, 0x2d, 0x7b, /* b263..-{ */ +0x40, 0xd5, 0x17, 0x71, 0xc4, 0x82, 0x5a, 0xdf, /* @..q..Z. */ +0x6c, 0x88, 0xfb, 0xf4, 0xb5, 0xe0, 0xf8, 0xde, /* l....... */ +0x0f, 0x5a, 0xfe, 0xed, 0x53, 0x44, 0xf9, 0xc7, /* .Z..SD.. */ +0x53, 0x2f, 0x67, 0x7e, 0xde, 0xd3, 0x0c, 0x5e, /* S/g~...^ */ +0xcf, 0x05, 0xcd, 0x6f, 0xd8, 0x7c, 0xf8, 0x9a, /* ...o.|.. */ +0x68, 0x35, 0xd7, 0x1a, 0x13, 0x2e, 0x08, 0xec, /* h5...... */ +0xc0, 0x63, 0xa3, 0x45, 0xb9, 0x1d, 0xcf, 0x0c, /* .c.E.... */ +0x7e, 0x51, 0xd6, 0xf6, 0x01, 0xa8, 0x9e, 0x39, /* ~Q.....9 */ +0x78, 0xb9, 0xd0, 0x91, 0x91, 0x9b, 0x4a, 0x25, /* x.....J% */ +0x2b, 0x1a, 0x2e, 0x23, 0x9f, 0x69, 0x38, 0x62, /* +..#.i8b */ +0xb7, 0x51, 0x37, 0x2a, 0xda, 0x83, 0x63, 0x6f, /* .Q7*..co */ +0xd1, 0x70, 0xdd, 0xa9, 0x41, 0x9a, 0x2d, 0xfd, /* .p..A.-. */ +0x8c, 0x21, 0x11, 0xfc, 0x1f, 0x86, 0x80, 0xef, /* .!...... */ +0x77, 0xa9, 0x2e, 0xff, 0xf6, 0x83, 0x02, 0xe4, /* w....... */ +0x8e, 0xe1, 0x03, 0x94, 0xe9, 0x42, 0x23, 0x23, /* .....B## */ +0xac, 0xc6, 0x66, 0xcc, 0x8c, 0x90, 0x07, 0x0a, /* ..f..... */ +0x7b, 0xd9, 0x03, 0x9c, 0x09, 0x94, 0x7c, 0x67, /* {.....|g */ +0x62, 0xd5, 0x75, 0x22, 0x1c, 0x80, 0xbe, 0x90, /* b.u".... */ +0xc4, 0x5d, 0x06, 0xf4, 0x33, 0x48, 0xef, 0x0d, /* .]..3H.. */ +0xe3, 0x31, 0x1a, 0x96, 0x08, 0xc0, 0xaa, 0x1b, /* .1...... */ +0xb9, 0x3b, 0xa7, 0xf0, 0xe9, 0x14, 0xf9, 0x0f, /* .;...... */ +0xbe, 0x59, 0x36, 0x93, 0xaf, 0x2f, 0xac, 0x7f, /* .Y6../.. */ +0xee, 0xef, 0xf1, 0xfa, 0xe7, 0x33, 0xd0, 0x5c, /* .....3.\ */ +0x81, 0xf8, 0x05, 0x66, 0xcb, 0x43, 0xc6, 0xf9, /* ...f.C.. */ +0xbe, 0x65, 0x69, 0x91, 0x81, 0x0a, 0xa5, 0xc9, /* .ei..... */ +0x80, 0xe1, 0x6b, 0xf4, 0x25, 0x2e, 0x62, 0xbd, /* ..k.%.b. */ +0xb9, 0xa1, 0xf8, 0x0a, 0x56, 0x76, 0x0e, 0x35, /* ....Vv.5 */ +0xcb, 0xd4, 0x3a, 0x3b, 0x12, 0xb4, 0x7f, 0x34, /* ..:;...4 */ +0xa8, 0x9c, 0x1b, 0x02, 0x00, 0x72, 0xd9, 0x2d, /* .....r.- */ +0x3a, 0xdb, 0x8b, 0xf2, 0xd1, 0xf9, 0x3f, 0x29, /* :.....?) */ +0xa2, 0x01, 0x69, 0xae, 0xd7, 0x9a, 0x36, 0xe6, /* ..i...6. */ +0x8f, 0x3d, 0xe1, 0x8d, 0x5b, 0x02, 0x09, 0x98, /* .=..[... */ +0x50, 0x6e, 0x00, 0xcf, 0x70, 0x45, 0x83, 0x87, /* Pn..pE.. */ +0xa9, 0x28, 0xa4, 0xf8, 0xb2, 0x20, 0x60, 0xd3, /* .(... `. */ +0x2e, 0x84, 0x56, 0x9b, 0x96, 0x15, 0x2c, 0xc7, /* ..V...,. */ +0x0c, 0x3c, 0xb0, 0xf3, 0x96, 0x09, 0x9e, 0xb5, /* .<...... */ +0x74, 0xe7, 0xd1, 0x63, 0xdc, 0xe0, 0xc0, 0x08, /* t..c.... */ +0x13, 0x0c, 0xeb, 0x18, 0xa1, 0x79, 0x1e, 0x0d, /* .....y.. */ +0x54, 0x68, 0x2a, 0x7e, 0x5d, 0x5e, 0xb0, 0x78, /* Th*~]^.x */ +0x65, 0x32, 0x20, 0x0b, 0x20, 0x31, 0xcc, 0x4d, /* e2 . 1.M */ +0xdd, 0xd1, 0xc6, 0xc2, 0x42, 0xe8, 0x88, 0xc4, /* ....B... */ +0xce, 0xe6, 0x31, 0x14, 0x5f, 0x42, 0x20, 0x10, /* ..1._B . */ +0xe3, 0x39, 0x96, 0x8a, 0x8c, 0xb5, 0xc8, 0x0a, /* .9...... */ +0x79, 0xa5, 0xcc, 0x05, 0x8e, 0x4a, 0x92, 0x75, /* y....J.u */ +0x3e, 0xd3, 0x33, 0xf2, 0xee, 0xfe, 0x0b, 0x42, /* >.3....B */ +0x3d, 0x1a, 0x7d, 0xcc, 0x33, 0x4a, 0x9e, 0x55, /* =.}.3J.U */ +0x4a, 0xc4, 0x41, 0x9d, 0xcb, 0xe9, 0xea, 0x4c, /* J.A....L */ +0x88, 0x8b, 0xf0, 0x33, 0xb1, 0xea, 0x72, 0x1f, /* ...3..r. */ +0x01, 0xcf, 0xd5, 0xff, 0x24, 0x9b, 0x6f, 0xf8, /* ....$.o. */ +0x64, 0x1e, 0x60, 0xdd, 0xad, 0x9d, 0xb1, 0xe7, /* d.`..... */ +0x0b, 0xf6, 0x52, 0xa1, 0x55, 0x4e, 0xcb, 0x1e, /* ..R.UN.. */ +0xea, 0x68, 0x27, 0x69, 0xa7, 0xa6, 0xe0, 0x00, /* .h'i.... */ +0xed, 0xa0, 0x79, 0x44, 0x18, 0x04, 0xa4, 0x81, /* ..yD.... */ +0xf9, 0x39, 0x88, 0x7f, 0x2e, 0xed, 0xdf, 0x5f, /* .9....._ */ +0xcd, 0x5f, 0x86, 0xd8, 0xd7, 0x8c, 0x19, 0xa0, /* ._...... */ +0x47, 0x1a, 0x12, 0x9b, 0x26, 0xd6, 0x35, 0x77, /* G...&.5w */ +0x85, 0x1b, 0xc6, 0x1c, 0xcb, 0xf0, 0x73, 0x76, /* ......sv */ +0xea, 0xf9, 0x42, 0x06, 0x60, 0x5c, 0xa5, 0xb1, /* ..B.`\.. */ +0xe6, 0xd9, 0x86, 0xb5, 0x80, 0xee, 0x51, 0x24, /* ......Q$ */ +0x5b, 0x3a, 0xd8, 0x14, 0xaf, 0x5a, 0x8c, 0xa4, /* [:...Z.. */ +0x83, 0xe3, 0x4e, 0x2f, 0xbc, 0x47, 0x3a, 0xe3, /* ..N/.G:. */ +0x06, 0x5e, 0x79, 0xc5, 0xd8, 0xf1, 0x87, 0xef, /* .^y..... */ +0x89, 0x67, 0x6e, 0x9d, 0x56, 0x7d, 0x34, 0x78, /* .gn.V}4x */ +0x67, 0x88, 0xa0, 0xcf, 0x56, 0x15, 0xc2, 0x61, /* g...V..a */ +0x79, 0xe8, 0xfd, 0x9d, 0x6f, 0xd5, 0xc3, 0x38, /* y...o..8 */ +0x95, 0x4b, 0x8d, 0x57, 0xa5, 0x18, 0x44, 0x26, /* .K.W..D& */ +0xdf, 0xcb, 0x9e, 0xbd, 0xa7, 0x2d, 0x18, 0x03, /* .....-.. */ +0x2f, 0x99, 0x2a, 0x82, 0xdc, 0xb1, 0xcc, 0x62, /* /.*....b */ +0x74, 0xdd, 0x02, 0x61, 0x37, 0x72, 0x88, 0x75, /* t..a7r.u */ +0xfe, 0xf7, 0x0d, 0x4a, 0x8f, 0x0d, 0xcc, 0x96, /* ...J.... */ +0x09, 0xe7, 0x11, 0xd1, 0x9b, 0xa6, 0xe9, 0xeb, /* ........ */ +0x2c, 0x91, 0x73, 0x29, 0x77, 0x67, 0x10, 0x64, /* ,.s)wg.d */ +0x8f, 0x6d, 0xc3, 0x64, 0xf7, 0xc2, 0x4b, 0x40, /* .m.d..K@ */ +0x01, 0x67, 0xc9, 0xce, 0x56, 0x5f, 0xe7, 0x57, /* .g..V_.W */ +0xf5, 0xd6, 0xeb, 0x28, 0xe3, 0x64, 0x55, 0x02, /* ...(.dU. */ +0x75, 0x16, 0x5e, 0x8e, 0x1d, 0xb7, 0xb6, 0x3e, /* u.^....> */ +0x7d, 0x17, 0x92, 0xae, 0xe1, 0x01, 0x4d, 0xeb, /* }.....M. */ +0xa5, 0x6e, 0x45, 0x80, 0x83, 0x99, 0x65, 0x7e, /* .nE...e~ */ +0xb9, 0x69, 0x24, 0x0b, 0x53, 0x8f, 0x47, 0x89, /* .i$.S.G. */ +0x5b, 0x48, 0x80, 0x79, 0x75, 0x3b, 0xe6, 0xe8, /* [H.yu;.. */ +0xd7, 0x8b, 0x31, 0xdb, 0x11, 0x6d, 0xea, 0xc1, /* ..1..m.. */ +0x33, 0xe1, 0xc9, 0x19, 0x07, 0xb8, 0xa1, 0x62, /* 3......b */ +0xfc, 0x23, 0x1d, 0x5a, 0x89, 0x24, 0x32, 0x33, /* .#.Z.$23 */ +0x96, 0x8b, 0xe1, 0x9d, 0x8a, 0x98, 0x04, 0xf1, /* ........ */ +0x32, 0x2b, 0xe1, 0xe0, 0xee, 0x8a, 0x80, 0xc7, /* 2+...... */ +0x7b, 0xc3, 0x82, 0x99, 0x7e, 0x75, 0x46, 0xbd, /* {...~uF. */ +0xbd, 0x8c, 0x1b, 0x49, 0x83, 0xe6, 0xb3, 0x65, /* ...I...e */ +0x2e, 0x4c, 0x14, 0x32, 0xbc, 0x1c, 0xd5, 0xa3, /* .L.2.... */ +0x6a, 0xc3, 0x2e, 0xb8, 0xdf, 0xe5, 0x15, 0x23, /* j......# */ +0xbc, 0xa6, 0xf4, 0x73, 0xa8, 0x74, 0xff, 0xbc, /* ...s.t.. */ +0x8b, 0x98, 0xa6, 0x6a, 0x9c, 0x90, 0x98, 0x38, /* ...j...8 */ +0x4f, 0x27, 0xb1, 0x6c, 0xd4, 0xde, 0x19, 0xe8, /* O'.l.... */ +0xa6, 0x62, 0x2e, 0x77, 0x70, 0x37, 0x57, 0x01, /* .b.wp7W. */ +0x3c, 0xd2, 0x35, 0xd8, 0x1b, 0x28, 0x2c, 0x64, /* <.5..(,d */ +0x16, 0x9c, 0x66, 0xd1, 0x57, 0xa6, 0x70, 0xf5, /* ..f.W.p. */ +0x10, 0x4f, 0xf2, 0x1e, 0xe6, 0x4c, 0x05, 0x15, /* .O...L.. */ +0x6d, 0xb5, 0x0d, 0x5e, 0x5b, 0x4e, 0xbb, 0xdd, /* m..^[N.. */ +0x5d, 0x81, 0xdf, 0xc5, 0x31, 0x47, 0xea, 0xa2, /* ]...1G.. */ +0x7a, 0x6c, 0xa9, 0xac, 0x5d, 0x26, 0x5d, 0xa1, /* zl..]&]. */ +0x87, 0x3e, 0xbf, 0x62, 0x7e, 0xa8, 0x16, 0x81, /* .>.b~... */ +0x30, 0x76, 0xad, 0x36, 0x22, 0xa9, 0x83, 0xc8, /* 0v.6"... */ +0xba, 0x16, 0x7c, 0x00, 0x09, 0x7e, 0x23, 0x99, /* ..|..~#. */ +0xaa, 0x66, 0xfa, 0x97, 0xa0, 0x65, 0xad, 0x56, /* .f...e.V */ +0x95, 0x23, 0x8d, 0xde, 0x9f, 0x8d, 0xa8, 0x5a, /* .#.....Z */ +0x9c, 0x32, 0xd4, 0x4b, 0xaf, 0xd3, 0x86, 0x38, /* .2.K...8 */ +0x60, 0x55, 0x3c, 0x44, 0x41, 0xe8, 0xa7, 0x9e, /* `U. */ +0x1c, 0xe0, 0x74, 0x31, 0x27, 0xd0, 0xe1, 0xa5, /* ..t1'... */ +0x74, 0x8f, 0x82, 0x07, 0x6f, 0x41, 0x2c, 0xf1, /* t...oA,. */ +0x4f, 0x72, 0x51, 0xb8, 0x1b, 0xb7, 0xb7, 0x44, /* OrQ....D */ +0xfc, 0x63, 0xe1, 0xbb, 0x7a, 0xbc, 0x6a, 0xf6, /* .c..z.j. */ +0x27, 0xd4, 0xfe, 0x0a, 0xbe, 0xcd, 0x0b, 0x8d, /* '....... */ +0x54, 0x51, 0xcb, 0xbc, 0x1a, 0xb6, 0xa6, 0x6f, /* TQ.....o */ +0x65, 0xa6, 0x99, 0xfc, 0x17, 0xb2, 0x6f, 0x88, /* e.....o. */ +0x4e, 0x5c, 0x87, 0x94, 0xb7, 0x14, 0x67, 0xf6, /* N\....g. */ +0x59, 0xf2, 0xe0, 0x84, 0x60, 0x63, 0x41, 0x3c, /* Y...`cA< */ +0x50, 0x12, 0xaf, 0x2b, 0x2f, 0xc2, 0x1a, 0x67, /* P..+/..g */ +0x7f, 0xe7, 0xe6, 0xbf, 0xb3, 0xd7, 0x3d, 0xea, /* ......=. */ +0x1e, 0x8b, 0x6d, 0x20, 0xe3, 0x30, 0x48, 0xd2, /* ..m .0H. */ +0xd2, 0x1f, 0x39, 0x77, 0x57, 0x19, 0xdd, 0xbe, /* ..9wW... */ +0x24, 0x1e, 0x5f, 0x6e, 0x1f, 0x54, 0xfa, 0x89, /* $._n.T.. */ +0xc6, 0x7d, 0xab, 0x8c, 0xed, 0x1a, 0x7c, 0x11, /* .}....|. */ +0x2d, 0xcb, 0xfb, 0xbe, 0xb1, 0x86, 0xa8, 0xb0, /* -....... */ +0xc5, 0x37, 0x55, 0xb1, 0xd7, 0x8e, 0xc9, 0xb7, /* .7U..... */ +0x19, 0xdd, 0xe5, 0x03, 0xa1, 0xbb, 0xea, 0x20, /* ....... */ +0x1d, 0x93, 0x0d, 0xa5, 0x98, 0x18, 0x1a, 0xae, /* ........ */ +0x9d, 0x70, 0xc6, 0x6a, 0x73, 0x2f, 0x1b, 0xec, /* .p.js/.. */ +0x6c, 0xfe, 0xa3, 0x01, 0xcf, 0xf1, 0x56, 0x68, /* l.....Vh */ +0xa5, 0x4d, 0xea, 0x7b, 0xda, 0xe5, 0xc8, 0x4a, /* .M.{...J */ +0x1b, 0x8e, 0x20, 0xb7, 0x4a, 0x93, 0xb9, 0xb1, /* .. .J... */ +0xb2, 0xf1, 0x53, 0x86, 0x6f, 0xe9, 0xa2, 0x36, /* ..S.o..6 */ +0x7f, 0x35, 0x19, 0x59, 0x7d, 0x2f, 0xb1, 0xd2, /* .5.Y}/.. */ +0x53, 0xf8, 0x6c, 0xf6, 0x14, 0x6e, 0xac, 0xc9, /* S.l..n.. */ +0x3c, 0xbe, 0x0f, 0x95, 0x08, 0x0e, 0xd3, 0x28, /* <......( */ +0x84, 0x02, 0x80, 0x9e, 0xaf, 0xa6, 0x2a, 0xe7, /* ......*. */ +0xa8, 0x2f, 0xac, 0x15, 0x04, 0xfc, 0x5e, 0x2c, /* ./....^, */ +0xce, 0x5a, 0x20, 0x68, 0xd4, 0x89, 0x15, 0xc3, /* .Z h.... */ +0xa2, 0x28, 0xcc, 0x8a, 0xdf, 0xf4, 0xc0, 0x56, /* .(.....V */ +0x4b, 0x8c, 0xba, 0xe5, 0xa9, 0x13, 0x5d, 0xbb, /* K.....]. */ +0xd3, 0x53, 0xd6, 0x23, 0x71, 0xe6, 0xfa, 0xe1, /* .S.#q... */ +0x2a, 0xd6, 0x91, 0x98, 0x4a, 0xb8, 0x21, 0x1a, /* *...J.!. */ +0xad, 0xfc, 0x56, 0x35, 0x61, 0x26, 0xe8, 0xad, /* ..V5a&.. */ +0x22, 0x9d, 0xe8, 0x1c, 0x57, 0xe3, 0xd2, 0xbf, /* "...W... */ +0x6a, 0xb6, 0xc3, 0x9e, 0x7d, 0xe7, 0x18, 0xca, /* j...}... */ +0x63, 0xf8, 0x4b, 0xeb, 0x74, 0x48, 0x49, 0xb6, /* c.K.tHI. */ +0x2e, 0x6d, 0x98, 0x1f, 0x48, 0x77, 0xa0, 0x59, /* .m..Hw.Y */ +0xae, 0xcd, 0xc9, 0xd1, 0xe0, 0x2e, 0x03, 0xa0, /* ........ */ +0xb9, 0x0f, 0x5d, 0xea, 0x88, 0x6b, 0x5a, 0x6a, /* ..]..kZj */ +0xac, 0x77, 0x2e, 0xac, 0xb6, 0x8e, 0x1f, 0xa3, /* .w...... */ +0xc3, 0x44, 0x55, 0xd3, 0x85, 0x18, 0x56, 0x29, /* .DU...V) */ +0x41, 0xf6, 0x9f, 0x59, 0xba, 0x7f, 0x58, 0xda, /* A..Y..X. */ +0x03, 0x6d, 0x57, 0xb2, 0x49, 0xf4, 0x1b, 0x95, /* .mW.I... */ +0x76, 0x4a, 0x94, 0x29, 0xd9, 0x81, 0x16, 0x99, /* vJ.).... */ +0xa2, 0xa4, 0xbc, 0x17, 0x2c, 0xe5, 0xbb, 0x6d, /* ....,..m */ +0xdf, 0xfc, 0x79, 0xf8, 0xa4, 0x28, 0xad, 0xe3, /* ..y..(.. */ +0xbc, 0xb9, 0xb8, 0x6d, 0x8c, 0xb9, 0x72, 0x42, /* ...m..rB */ +0xc4, 0xb0, 0x37, 0x55, 0x2c, 0x75, 0x0d, 0xa5, /* ..7U,u.. */ +0xc6, 0x78, 0x35, 0x79, 0xf4, 0x74, 0x1d, 0x26, /* .x5y.t.& */ +0x23, 0x9e, 0x76, 0x3b, 0xd2, 0x6b, 0xff, 0x7b, /* #.v;.k.{ */ +0xe1, 0x29, 0x7a, 0xb8, 0x79, 0x49, 0x48, 0x33, /* .)z.yIH3 */ +0xf0, 0xb4, 0x29, 0xaf, 0x2f, 0x7d, 0xbc, 0x26, /* ..)./}.& */ +0x52, 0xff, 0xae, 0x91, 0x7b, 0x12, 0x59, 0xa1, /* R...{.Y. */ +0xa2, 0x56, 0x0c, 0x3e, 0x57, 0x57, 0x98, 0x8c, /* .V.>WW.. */ +0xa7, 0x6f, 0x7f, 0x4c, 0x5d, 0xd3, 0x36, 0x8b, /* .o.L].6. */ +0xbc, 0x65, 0x61, 0xbb, 0x34, 0x7b, 0xcd, 0x59, /* .ea.4{.Y */ +0xfe, 0xba, 0x16, 0x9d, 0xff, 0x08, 0x7a, 0x5b, /* ......z[ */ +0xd5, 0x3e, 0x7d, 0x49, 0x11, 0x8f, 0x88, 0x36, /* .>}I...6 */ +0x16, 0x41, 0x79, 0xef, 0x73, 0x9f, 0x2d, 0x42, /* .Ay.s.-B */ +0xcf, 0x1f, 0x5e, 0xeb, 0xa9, 0x8a, 0x15, 0x06, /* ..^..... */ +0xa2, 0x8e, 0x5a, 0x42, 0xa5, 0x30, 0xb4, 0xe5, /* ..ZB.0.. */ +0x56, 0xe1, 0x87, 0x1f, 0x55, 0xa1, 0x35, 0x6a, /* V...U.5j */ +0xe7, 0xae, 0x1d, 0x6d, 0x45, 0xde, 0x7f, 0x8a, /* ...mE... */ +0x81, 0x8b, 0xf8, 0x63, 0x8e, 0xa9, 0x9c, 0x11, /* ...c.... */ +0x10, 0x23, 0xad, 0xc0, 0x7e, 0x6c, 0xd8, 0xb1, /* .#..~l.. */ +0x6f, 0x5d, 0x6d, 0xaa, 0x5b, 0x30, 0x5e, 0x3e, /* o]m.[0^> */ +0x0a, 0x14, 0x7d, 0xc2, 0x63, 0x8f, 0xee, 0xd8, /* ..}.c... */ +0x98, 0x44, 0x28, 0x86, 0x9f, 0x26, 0xfe, 0xa8, /* .D(..&.. */ +0xc5, 0x14, 0x8f, 0xdc, 0x0f, 0x2a, 0x84, 0x3c, /* .....*.< */ +0xd4, 0x7c, 0xec, 0x76, 0x09, 0x96, 0x8d, 0x0d, /* .|.v.... */ +0x15, 0x58, 0xdb, 0x07, 0x4e, 0x9d, 0xff, 0xdc, /* .X..N... */ +0x48, 0x81, 0xb0, 0x13, 0xc3, 0xf9, 0x00, 0xf7, /* H....... */ +0x26, 0x1d, 0x6e, 0xaa, 0xf4, 0x12, 0xe0, 0x27, /* &.n....' */ +0x67, 0x27, 0x6d, 0x7a, 0xd9, 0xde, 0x09, 0xe3, /* g'mz.... */ +0xdd, 0x2f, 0xc5, 0x77, 0x0d, 0x67, 0x85, 0x3a, /* ./.w.g.: */ +0x91, 0xbc, 0xf4, 0x88, 0x2e, 0xd3, 0xab, 0x44, /* .......D */ +0x54, 0x1b, 0xbe, 0xdf, 0x4d, 0x51, 0xa4, 0x83, /* T...MQ.. */ +0xe3, 0x23, 0xba, 0x94, 0x66, 0x99, 0x4b, 0xb3, /* .#..f.K. */ +0xe6, 0x36, 0xb7, 0x37, 0x2e, 0xfc, 0x42, 0x2c, /* .6.7..B, */ +0x8c, 0xf7, 0x71, 0x2e, 0x79, 0xf8, 0xa8, 0x88, /* ..q.y... */ +0xcc, 0x7e, 0x80, 0x15, 0x8f, 0xf1, 0x50, 0x97, /* .~....P. */ +0xcb, 0xce, 0xe0, 0x97, 0xae, 0x42, 0x67, 0xc2, /* .....Bg. */ +0x99, 0x56, 0x47, 0x26, 0xf1, 0xeb, 0xb8, 0x45, /* .VG&...E */ +0xc9, 0xf6, 0x32, 0x86, 0x3e, 0x4d, 0x7e, 0x77, /* ..2.>M~w */ +0x93, 0x18, 0x2e, 0xa2, 0xed, 0xf4, 0x69, 0x6b, /* ......ik */ +0x57, 0x11, 0xa0, 0x9d, 0x22, 0x91, 0x31, 0xbe, /* W...".1. */ +0xfc, 0x05, 0x70, 0xed, 0x5f, 0xd7, 0xa4, 0x37, /* ..p._..7 */ +0x4c, 0x0b, 0xa6, 0xc6, 0x38, 0xa7, 0x11, 0x1c, /* L...8... */ +0x56, 0xbb, 0xdd, 0x7d, 0xa4, 0x03, 0x41, 0xc6, /* V..}..A. */ +0xe5, 0x81, 0x52, 0x91, 0xb8, 0xdb, 0xc2, 0x72, /* ..R....r */ +0x58, 0x45, 0x00, 0x29, 0xc7, 0x34, 0x33, 0x27, /* XE.).43' */ +0x25, 0x4f, 0x79, 0x0c, 0x73, 0xb1, 0xba, 0x50, /* %Oy.s..P */ +0x29, 0xf9, 0x90, 0x8b, 0xe8, 0xe5, 0x71, 0xf4, /* ).....q. */ +0x28, 0x34, 0x0c, 0xb4, 0x6a, 0x1b, 0x54, 0xc3, /* (4..j.T. */ +0xad, 0x6a, 0x30, 0x58, 0xb8, 0xba, 0x3e, 0x6c, /* .j0X..>l */ +0x88, 0xc5, 0xf5, 0x85, 0x46, 0x6a, 0x4f, 0x75, /* ....FjOu */ +0x6c, 0x29, 0xf2, 0x20, 0x29, 0xf3, 0xf4, 0xd0, /* l). )... */ +0x93, 0x57, 0x2f, 0x93, 0xe6, 0x8f, 0x7b, 0x17, /* .W/...{. */ +0x3f, 0x5a, 0xca, 0x75, 0x07, 0xa6, 0x78, 0x82, /* ?Z.u..x. */ +0x11, 0xbc, 0x02, 0xe4, 0x7f, 0x33, 0xce, 0x37, /* .....3.7 */ +0x9d, 0x29, 0x38, 0xa5, 0x99, 0x75, 0x23, 0x0d, /* .)8..u#. */ +0x4f, 0x6e, 0x34, 0x90, 0x8d, 0xd1, 0xde, 0xd7, /* On4..... */ +0x45, 0x3e, 0x5c, 0x84, 0xaa, 0xb5, 0x43, 0x86, /* E>\...C. */ +0xa0, 0x38, 0x04, 0x77, 0xcd, 0xee, 0x65, 0x98, /* .8.w..e. */ +0xaf, 0x91, 0x91, 0xf4, 0x6d, 0x84, 0xae, 0x5c, /* ....m..\ */ +0xe2, 0x14, 0xed, 0x89, 0x92, 0xbf, 0x21, 0x4e, /* ......!N */ +0xbb, 0xe0, 0x72, 0x37, 0x77, 0xf7, 0x76, 0x57, /* ..r7w.vW */ +0x73, 0xca, 0x5c, 0x65, 0x0f, 0x11, 0x6e, 0xe4, /* s.\e..n. */ +0x93, 0x53, 0x7d, 0x1e, 0x03, 0x13, 0xc7, 0x84, /* .S}..... */ +0x3c, 0xe8, 0x6a, 0xa2, 0x5f, 0xb8, 0xd4, 0x2d, /* <.j._..- */ +0x7f, 0xe5, 0xd2, 0xb6, 0xbd, 0xb0, 0x7c, 0xf4, /* ......|. */ +0x0b, 0xe0, 0xf6, 0xc8, 0x13, 0x71, 0xa0, 0x1e, /* .....q.. */ +0xef, 0x24, 0x88, 0x1e, 0xdc, 0x37, 0x57, 0xe1, /* .$...7W. */ +0xc6, 0x23, 0xea, 0x89, 0xc8, 0x5c, 0x09, 0x7c, /* .#...\.| */ +0x40, 0xd8, 0x57, 0x7a, 0x5b, 0x94, 0x53, 0xea, /* @.Wz[.S. */ +0xdf, 0x38, 0x52, 0x73, 0xf3, 0xfc, 0xa0, 0x39, /* .8Rs...9 */ +0xcc, 0xf6, 0xfb, 0x31, 0x89, 0x7b, 0x20, 0xc9, /* ...1.{ . */ +0x6a, 0xf5, 0xba, 0x8a, 0x67, 0xab, 0xc4, 0xad, /* j...g... */ +0x88, 0x29, 0x3b, 0xd5, 0x4b, 0xb6, 0x91, 0x5f, /* .);.K.._ */ +0x51, 0x62, 0xf2, 0x8d, 0xa0, 0x60, 0x3d, 0x4a, /* Qb...`=J */ +0x4b, 0x03, 0x16, 0x00, 0x77, 0x55, 0x2a, 0x1e, /* K...wU*. */ +0xde, 0x16, 0x0d, 0x18, 0x18, 0xc5, 0x1c, 0x27, /* .......' */ +0x6c, 0x5c, 0xf0, 0x7e, 0x72, 0x51, 0xed, 0x86, /* l\.~rQ.. */ +0xcf, 0xf2, 0xfc, 0x65, 0x1e, 0xcf, 0x6f, 0x7b, /* ...e..o{ */ +0xe7, 0x1f, 0xcc, 0x15, 0x5d, 0xb8, 0x93, 0x52, /* ....]..R */ +0x87, 0x5c, 0xc4, 0xba, 0x6b, 0xb5, 0xdc, 0xfa, /* .\..k... */ +0xd9, 0xf1, 0x8c, 0x36, 0x41, 0x3a, 0x66, 0x93, /* ...6A:f. */ +0x3a, 0xdd, 0xf8, 0x6d, 0x77, 0x59, 0xb8, 0x0b, /* :..mwY.. */ +0x19, 0x06, 0x1e, 0x79, 0x76, 0xfa, 0xab, 0x25, /* ...yv..% */ +0xbb, 0xf6, 0x78, 0x7f, 0x79, 0x2c, 0x68, 0xb0, /* ..x.y,h. */ +0x96, 0x93, 0xcb, 0xaf, 0x3b, 0x93, 0xd6, 0x6f, /* ....;..o */ +0xe8, 0x72, 0x00, 0x32, 0xf3, 0x2b, 0xe7, 0x15, /* .r.2.+.. */ +0x1c, 0x44, 0xbf, 0xfa, 0x9d, 0xc7, 0xb0, 0x32, /* .D.....2 */ +0x29, 0x3b, 0x4e, 0x27, 0xfe, 0x51, 0x30, 0x28, /* );N'.Q0( */ +0x6b, 0x4b, 0x91, 0x42, 0x49, 0x11, 0x80, 0x6b, /* kK.BI..k */ +0x75, 0x05, 0x42, 0x25, 0x6f, 0x18, 0x77, 0x66, /* u.B%o.wf */ +0x0b, 0xf6, 0x9e, 0xf6, 0xcc, 0xed, 0xfe, 0x62, /* .......b */ +0x0a, 0x37, 0x85, 0x9f, 0x5d, 0xe4, 0xf5, 0xc1, /* .7..]... */ +0x84, 0xa6, 0xb3, 0x5d, 0x90, 0xdb, 0x05, 0x9a, /* ...].... */ +0xa3, 0x33, 0x9e, 0x9d, 0x13, 0xc6, 0x0e, 0xe6, /* .3...... */ +0x3c, 0x40, 0x1d, 0x44, 0x43, 0x72, 0xa9, 0x40, /* <@.DCr.@ */ +0x71, 0x4b, 0x2a, 0xe8, 0x4e, 0x0c, 0xba, 0x77, /* qK*.N..w */ +0x9b, 0xa8, 0xd7, 0x98, 0xc2, 0x33, 0xba, 0x7c, /* .....3.| */ +0xa5, 0xbe, 0x86, 0x4b, 0x9e, 0x64, 0x60, 0x87, /* ...K.d`. */ +0x3a, 0x5f, 0x8e, 0xc0, 0x8b, 0xf2, 0xd0, 0x2d, /* :_.....- */ +0x75, 0xf5, 0xe5, 0xac, 0x0c, 0x46, 0xfc, 0x8a, /* u....F.. */ +0xe8, 0x1e, 0xac, 0xdb, 0xd2, 0x8e, 0x9d, 0xff, /* ........ */ +0x12, 0xbd, 0x87, 0x3a, 0x45, 0x07, 0x3c, 0xf2, /* ...:E.<. */ +0x38, 0xd0, 0x20, 0x29, 0x33, 0x05, 0x92, 0x64, /* 8. )3..d */ +0x50, 0x02, 0x35, 0xcf, 0x48, 0x08, 0x9a, 0x4f, /* P.5.H..O */ +0xf2, 0xb4, 0xb3, 0x44, 0xb8, 0xcf, 0x56, 0x7c, /* ...D..V| */ +0xb6, 0x93, 0x01, 0xcb, 0x44, 0xc8, 0x51, 0x8d, /* ....D.Q. */ +0x28, 0x03, 0x72, 0x06, 0x32, 0xc7, 0x19, 0xe8, /* (.r.2... */ +0xa0, 0x7a, 0x6e, 0x20, 0xbe, 0x96, 0x92, 0xd5, /* .zn .... */ +0x41, 0x56, 0x8e, 0x30, 0xdf, 0x22, 0x1f, 0xeb, /* AV.0.".. */ +0xf6, 0x5b, 0x76, 0x22, 0x1e, 0x0c, 0x77, 0x05, /* .[v"..w. */ +0x62, 0xb4, 0x70, 0x92, 0x97, 0xd6, 0xf9, 0xa8, /* b.p..... */ +0x71, 0x44, 0xa6, 0xa4, 0x0f, 0xac, 0x06, 0x2a, /* qD.....* */ +0xf3, 0x45, 0x11, 0x08, 0x88, 0xd3, 0x40, 0x7a, /* .E....@z */ +0x43, 0x15, 0x38, 0x2a, 0x95, 0xab, 0x35, 0x94, /* C.8*..5. */ +0x21, 0x7a, 0xa8, 0xe4, 0x70, 0x3e, 0x6f, 0xaa, /* !z..p>o. */ +0x4c, 0x66, 0xad, 0x2c, 0xc8, 0x94, 0x86, 0xeb, /* Lf.,.... */ +0xc0, 0x4e, 0x7c, 0x79, 0x5c, 0x3a, 0x33, 0x64, /* .N|y\:3d */ +0x14, 0xc7 /* .. */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt18[1514] = { +0x02, 0x00, 0x00, 0x70, 0xca, 0x04, 0x5e, 0xe9, /* ...p..^. */ +0x1e, 0xa6, 0x21, 0x64, 0x08, 0x00, 0x45, 0x00, /* ..!d..E. */ +0x05, 0xdc, 0xe7, 0xd2, 0x00, 0x00, 0x33, 0x06, /* ......3. */ +0x2b, 0x36, 0x98, 0xc7, 0x13, 0xa1, 0xc0, 0xa8, /* +6...... */ +0x02, 0x03, 0x00, 0x50, 0xc9, 0xc1, 0xb1, 0x64, /* ...P...d */ +0xe6, 0x11, 0xfa, 0xdf, 0xdf, 0x46, 0x50, 0x10, /* .....FP. */ +0xff, 0xff, 0xe6, 0x3d, 0x00, 0x00, 0x10, 0x5c, /* ...=...\ */ +0xb3, 0x88, 0x07, 0xfb, 0x38, 0x31, 0xbc, 0x7e, /* ....81.~ */ +0x9f, 0x3a, 0x50, 0x15, 0xa4, 0x74, 0x03, 0x07, /* .:P..t.. */ +0x21, 0xa9, 0x03, 0xcb, 0x4b, 0xe4, 0x07, 0xff, /* !...K... */ +0x9d, 0x89, 0x95, 0xb2, 0x37, 0x85, 0x6a, 0x43, /* ....7.jC */ +0xc7, 0x52, 0x41, 0xe2, 0x3c, 0xed, 0x78, 0x06, /* .RA.<.x. */ +0x96, 0x3f, 0x03, 0x87, 0xd4, 0xc6, 0x0a, 0x96, /* .?...... */ +0x5e, 0x42, 0xec, 0x05, 0xd7, 0xc8, 0x76, 0xbb, /* ^B....v. */ +0xb9, 0x07, 0x0a, 0xc6, 0x7e, 0x6d, 0xe8, 0x35, /* ....~m.5 */ +0x9f, 0xd5, 0x4d, 0x80, 0x61, 0x0a, 0xc5, 0x3e, /* ..M.a..> */ +0xb4, 0x41, 0x8a, 0x65, 0x17, 0xcf, 0xd6, 0x5e, /* .A.e...^ */ +0x32, 0x7e, 0xfd, 0x03, 0x2e, 0x90, 0x36, 0xff, /* 2~....6. */ +0x2c, 0xf5, 0xb6, 0xa7, 0x13, 0x46, 0x10, 0x59, /* ,....F.Y */ +0x4b, 0x03, 0xf8, 0x0d, 0x74, 0xe7, 0x8e, 0x12, /* K...t... */ +0x00, 0x2d, 0xa5, 0xc1, 0x0b, 0xef, 0x94, 0x62, /* .-.....b */ +0x1b, 0x5a, 0x44, 0x2f, 0xbb, 0xb4, 0x89, 0xce, /* .ZD/.... */ +0xc1, 0xcb, 0xb1, 0x8e, 0x74, 0xdf, 0xc8, 0x9b, /* ....t... */ +0x68, 0xdf, 0xda, 0x88, 0x6c, 0x6e, 0x48, 0x68, /* h...lnHh */ +0xe9, 0x82, 0xcb, 0x61, 0xde, 0xa5, 0xb4, 0xa0, /* ...a.... */ +0x06, 0xb8, 0x43, 0x9d, 0x3e, 0xdd, 0x5d, 0x50, /* ..C.>.]P */ +0x51, 0xed, 0x1a, 0xb9, 0x01, 0xba, 0x66, 0xd1, /* Q.....f. */ +0x88, 0x98, 0xca, 0x0f, 0xc1, 0x75, 0xd6, 0x06, /* .....u.. */ +0x35, 0x3d, 0x3c, 0x83, 0x41, 0x4b, 0xe7, 0x25, /* 5=<.AK.% */ +0xdb, 0x64, 0xd6, 0xee, 0x85, 0xc3, 0x66, 0x83, /* .d....f. */ +0xec, 0x4d, 0xdd, 0x07, 0x3d, 0x13, 0xd1, 0x34, /* .M..=..4 */ +0x7f, 0x2c, 0x16, 0x7e, 0xed, 0x3e, 0xea, 0x88, /* .,.~.>.. */ +0x3b, 0x5e, 0x1d, 0x72, 0x97, 0x1f, 0x61, 0x8a, /* ;^.r..a. */ +0x55, 0xc4, 0xb7, 0x12, 0x01, 0x14, 0x90, 0xbf, /* U....... */ +0x42, 0x5d, 0x0b, 0x27, 0x0b, 0x53, 0x45, 0x12, /* B].'.SE. */ +0x69, 0x49, 0x6e, 0xf0, 0x36, 0xae, 0x7c, 0xd0, /* iIn.6.|. */ +0x3b, 0xee, 0xa9, 0xb5, 0xc3, 0x90, 0xf6, 0x7c, /* ;......| */ +0xd8, 0x5a, 0x8f, 0xe1, 0x30, 0xde, 0x0c, 0x79, /* .Z..0..y */ +0x21, 0x99, 0x63, 0x49, 0x64, 0xdd, 0xb3, 0xca, /* !.cId... */ +0x58, 0x35, 0x32, 0x0d, 0xd1, 0x21, 0x2d, 0x8c, /* X52..!-. */ +0xaa, 0xf4, 0x6a, 0x04, 0x81, 0x7b, 0x00, 0x2d, /* ..j..{.- */ +0xa4, 0x23, 0xcd, 0x86, 0x64, 0x2f, 0xe1, 0x38, /* .#..d/.8 */ +0xbb, 0x30, 0x18, 0x3b, 0x0f, 0x97, 0xc9, 0xfa, /* .0.;.... */ +0x8f, 0xd1, 0x2f, 0xa2, 0xdc, 0xb3, 0x7b, 0x13, /* ../...{. */ +0x7a, 0xd2, 0x1b, 0xd0, 0x7f, 0x4a, 0xd1, 0xc9, /* z....J.. */ +0x55, 0xb9, 0xbd, 0xd7, 0x3b, 0xfd, 0xc4, 0xf9, /* U...;... */ +0x4e, 0xd8, 0x6b, 0x65, 0xf5, 0x20, 0x0f, 0x84, /* N.ke. .. */ +0xe5, 0xef, 0xa1, 0x49, 0x33, 0x22, 0xa6, 0x5f, /* ...I3"._ */ +0xe8, 0xdf, 0x11, 0x61, 0x64, 0x85, 0x2c, 0x25, /* ...ad.,% */ +0x9f, 0x80, 0xfd, 0x3d, 0x2e, 0x5b, 0x7a, 0xc7, /* ...=.[z. */ +0xb9, 0xbc, 0x60, 0x63, 0xa3, 0x24, 0x0b, 0x31, /* ..`c.$.1 */ +0x91, 0xa4, 0x54, 0x0c, 0xc2, 0x92, 0x8a, 0xdb, /* ..T..... */ +0xf8, 0xfa, 0x7a, 0x6b, 0x33, 0x98, 0x88, 0x69, /* ..zk3..i */ +0x6d, 0xe3, 0x16, 0x7e, 0xbe, 0x0f, 0x4f, 0x30, /* m..~..O0 */ +0x60, 0xf8, 0x4b, 0x6e, 0xe8, 0xc3, 0x81, 0xce, /* `.Kn.... */ +0x88, 0xfc, 0xd6, 0x21, 0xa6, 0xf4, 0xf0, 0xd4, /* ...!.... */ +0xaa, 0x6f, 0x20, 0xda, 0xb9, 0x2e, 0x36, 0xfb, /* .o ...6. */ +0xe4, 0x7a, 0x48, 0xae, 0x36, 0x4f, 0x4c, 0x9c, /* .zH.6OL. */ +0xba, 0x01, 0x74, 0x57, 0x35, 0x40, 0xc3, 0x3e, /* ..tW5@.> */ +0xf2, 0x62, 0x2e, 0xe5, 0x7a, 0xea, 0xa9, 0x30, /* .b..z..0 */ +0x6d, 0x72, 0x6a, 0x6a, 0x2a, 0xac, 0xea, 0x4d, /* mrjj*..M */ +0xdb, 0xf9, 0x8f, 0x3a, 0xa0, 0x67, 0xd5, 0x88, /* ...:.g.. */ +0x6f, 0x1d, 0xa6, 0xf2, 0x44, 0xf8, 0x8e, 0xb4, /* o...D... */ +0xdd, 0x9f, 0xbc, 0xc5, 0xdb, 0x0d, 0xea, 0xfb, /* ........ */ +0xbc, 0x7c, 0xb7, 0x5a, 0x11, 0x55, 0x16, 0x34, /* .|.Z.U.4 */ +0xb4, 0xf4, 0x78, 0x70, 0xb4, 0xaf, 0x73, 0x5a, /* ..xp..sZ */ +0x18, 0x70, 0x21, 0xde, 0x7a, 0xf6, 0x34, 0x03, /* .p!.z.4. */ +0x33, 0x76, 0x67, 0xc0, 0xc7, 0xec, 0x5a, 0x12, /* 3vg...Z. */ +0xcc, 0x5e, 0xde, 0x82, 0xaa, 0xf3, 0x4b, 0xb5, /* .^....K. */ +0x13, 0xf1, 0x24, 0xde, 0x39, 0x9d, 0x88, 0xbe, /* ..$.9... */ +0xe3, 0x5e, 0xe1, 0x60, 0xe4, 0x18, 0x09, 0xe0, /* .^.`.... */ +0x28, 0x25, 0x73, 0x38, 0x09, 0x13, 0xd9, 0x8a, /* (%s8.... */ +0xc1, 0x7c, 0xf4, 0xe1, 0xa9, 0x48, 0x0b, 0x94, /* .|...H.. */ +0xb7, 0xa7, 0x81, 0xe1, 0x3f, 0xd1, 0x9a, 0x7e, /* ....?..~ */ +0xcb, 0x48, 0xab, 0xbf, 0x85, 0x5f, 0x8c, 0x51, /* .H..._.Q */ +0xfe, 0xf4, 0xdc, 0x50, 0x76, 0x1d, 0xc1, 0x8c, /* ...Pv... */ +0xf0, 0xdd, 0x84, 0x7f, 0x39, 0xb3, 0x99, 0x51, /* ....9..Q */ +0xe8, 0x3f, 0x3c, 0xf3, 0xa3, 0x0e, 0x6d, 0x62, /* .?<...mb */ +0x0c, 0xc7, 0x86, 0x4d, 0xd2, 0xc2, 0x0b, 0xba, /* ...M.... */ +0x93, 0x85, 0xcd, 0x39, 0x04, 0x29, 0x85, 0x68, /* ...9.).h */ +0x66, 0xd7, 0x84, 0x1c, 0x80, 0x72, 0x2f, 0xc3, /* f....r/. */ +0x49, 0x10, 0x45, 0x28, 0xcf, 0x21, 0x94, 0x29, /* I.E(.!.) */ +0xfb, 0x58, 0xcc, 0xa4, 0x37, 0x01, 0x03, 0xa3, /* .X..7... */ +0x59, 0x1c, 0x51, 0x29, 0xd3, 0x19, 0xd0, 0x0e, /* Y.Q).... */ +0xdf, 0x76, 0x24, 0x74, 0xde, 0xa1, 0xe5, 0xae, /* .v$t.... */ +0xb8, 0x50, 0xdd, 0xb8, 0x7c, 0x0c, 0xba, 0x0f, /* .P..|... */ +0x23, 0xbe, 0x9d, 0x09, 0x91, 0x86, 0x54, 0x74, /* #.....Tt */ +0x09, 0xf5, 0x2a, 0x9b, 0x10, 0x5a, 0x11, 0xff, /* ..*..Z.. */ +0x37, 0xe1, 0x60, 0x50, 0x28, 0x4f, 0xdf, 0x5e, /* 7.`P(O.^ */ +0x5c, 0x53, 0x3d, 0x90, 0x3b, 0xfa, 0x00, 0x09, /* \S=.;... */ +0x06, 0xf3, 0x14, 0x30, 0xb4, 0x67, 0x6b, 0xb4, /* ...0.gk. */ +0x7a, 0xf8, 0x22, 0xa8, 0x93, 0xe3, 0xcf, 0x12, /* z."..... */ +0x2d, 0x70, 0xa2, 0xa2, 0x96, 0xae, 0x11, 0xde, /* -p...... */ +0xb7, 0x0a, 0x82, 0xd7, 0x72, 0x46, 0xce, 0xe5, /* ....rF.. */ +0xfe, 0x2f, 0xac, 0xda, 0x27, 0x1f, 0xc5, 0x1a, /* ./..'... */ +0x78, 0x79, 0x4d, 0x27, 0x4c, 0x07, 0x62, 0xed, /* xyM'L.b. */ +0x18, 0xa6, 0xac, 0xdd, 0xa3, 0xde, 0x15, 0x6c, /* .......l */ +0x9c, 0x98, 0x08, 0x42, 0xf4, 0xc5, 0x26, 0x0f, /* ...B..&. */ +0x45, 0x2c, 0x6c, 0xd6, 0x97, 0x5f, 0xf9, 0x22, /* E,l.._." */ +0xec, 0x98, 0xbc, 0x61, 0xdd, 0xe3, 0x45, 0x37, /* ...a..E7 */ +0xd1, 0xc5, 0x70, 0x1b, 0x0c, 0x45, 0xb3, 0xb8, /* ..p..E.. */ +0x59, 0xf6, 0x89, 0xce, 0xa5, 0x10, 0xed, 0x05, /* Y....... */ +0x30, 0x65, 0xa7, 0x29, 0x30, 0x4d, 0xa3, 0x24, /* 0e.)0M.$ */ +0xd5, 0xb8, 0x76, 0x4e, 0xef, 0xb8, 0x59, 0x07, /* ..vN..Y. */ +0x70, 0xb6, 0xf1, 0x52, 0x8a, 0x08, 0x67, 0xca, /* p..R..g. */ +0x04, 0x05, 0x03, 0x91, 0x51, 0xa1, 0x08, 0x88, /* ....Q... */ +0x98, 0x6c, 0x8c, 0xbe, 0x13, 0xa5, 0xcf, 0xba, /* .l...... */ +0x4d, 0x11, 0x12, 0x84, 0xfd, 0x38, 0xd0, 0xd4, /* M....8.. */ +0xe2, 0x31, 0x1e, 0xa0, 0xf4, 0x33, 0x84, 0x5a, /* .1...3.Z */ +0x06, 0xed, 0xaa, 0x85, 0xc4, 0xb6, 0x6d, 0x26, /* ......m& */ +0x10, 0x24, 0x5e, 0x53, 0x86, 0xd5, 0xc9, 0x9e, /* .$^S.... */ +0xae, 0xb9, 0xec, 0x43, 0x6d, 0x6c, 0xce, 0xe3, /* ...Cml.. */ +0x49, 0x62, 0x66, 0xf9, 0x0e, 0xb8, 0xf9, 0x0f, /* Ibf..... */ +0xd5, 0xac, 0x5b, 0xfc, 0x32, 0xa8, 0xf5, 0x77, /* ..[.2..w */ +0xfc, 0x7a, 0xfa, 0xf2, 0xf5, 0x8f, 0x36, 0x9f, /* .z....6. */ +0x23, 0x50, 0xbb, 0x4a, 0x8e, 0x2f, 0xe0, 0x5b, /* #P.J./.[ */ +0xf7, 0x38, 0xa8, 0xb3, 0x57, 0x03, 0x15, 0xc5, /* .8..W... */ +0x05, 0x24, 0x6b, 0x1d, 0xc7, 0x53, 0x92, 0x33, /* .$k..S.3 */ +0x15, 0x1d, 0x23, 0xb7, 0x4d, 0xf9, 0x95, 0xf3, /* ..#.M... */ +0x33, 0xf0, 0xac, 0xc2, 0x75, 0x51, 0xc0, 0xa6, /* 3...uQ.. */ +0x0a, 0x40, 0x4d, 0x38, 0x19, 0xfd, 0x5a, 0xd4, /* .@M8..Z. */ +0xd7, 0xd6, 0xc1, 0x9d, 0x0d, 0x5b, 0x02, 0x70, /* .....[.p */ +0xf4, 0x61, 0x5c, 0xc6, 0xe8, 0xff, 0xa7, 0x20, /* .a\.... */ +0x04, 0x8b, 0x00, 0xaf, 0x77, 0x38, 0x9e, 0x6c, /* ....w8.l */ +0x8a, 0x69, 0x2c, 0xc5, 0xc2, 0x5f, 0x15, 0xf6, /* .i,.._.. */ +0x8b, 0x42, 0x0b, 0xcd, 0xc1, 0x11, 0x9f, 0x15, /* .B...... */ +0xe3, 0xdf, 0x78, 0x3c, 0x87, 0x88, 0x5c, 0xdb, /* ..x<..\. */ +0xeb, 0x92, 0x14, 0x6e, 0x5f, 0x41, 0x46, 0xce, /* ...n_AF. */ +0x33, 0x87, 0xaa, 0x3b, 0xa9, 0x8a, 0xa0, 0x80, /* 3..;.... */ +0xb3, 0x96, 0x36, 0x53, 0x72, 0x73, 0x35, 0xec, /* ..6Srs5. */ +0x1d, 0xc4, 0xb1, 0x9e, 0x0e, 0x3a, 0x7d, 0xb4, /* .....:}. */ +0x2d, 0xa8, 0xe6, 0x30, 0xd5, 0x58, 0xb3, 0x34, /* -..0.X.4 */ +0x77, 0x4d, 0x9c, 0x15, 0x07, 0x53, 0x1e, 0x19, /* wM...S.. */ +0x9b, 0xa0, 0xb5, 0xf6, 0x5b, 0xba, 0xed, 0x98, /* ....[... */ +0xa8, 0x80, 0x41, 0x24, 0xec, 0xdd, 0x8d, 0xde, /* ..A$.... */ +0xbc, 0xda, 0x6c, 0x9a, 0xee, 0x3b, 0x8d, 0x3c, /* ..l..;.< */ +0x19, 0x26, 0x8a, 0xab, 0xfd, 0x0d, 0x28, 0xe7, /* .&....(. */ +0xbe, 0xe1, 0x0c, 0xa4, 0xa0, 0x0b, 0x24, 0xb2, /* ......$. */ +0x71, 0x28, 0x77, 0x49, 0x2e, 0xef, 0x2e, 0x19, /* q(wI.... */ +0xc7, 0xd6, 0xc7, 0x47, 0xf2, 0x23, 0x6b, 0x5c, /* ...G.#k\ */ +0xc8, 0x84, 0x6d, 0xbd, 0xe9, 0x75, 0xdb, 0x4e, /* ..m..u.N */ +0xdb, 0x42, 0x69, 0x9f, 0x4b, 0x10, 0xd7, 0xec, /* .Bi.K... */ +0x46, 0x9d, 0x26, 0xcb, 0x23, 0x24, 0x83, 0x7c, /* F.&.#$.| */ +0xff, 0x2d, 0xc5, 0xe5, 0x14, 0x40, 0xea, 0x4e, /* .-...@.N */ +0xc9, 0x22, 0x1d, 0xd1, 0xe4, 0x20, 0xc0, 0x1f, /* ."... .. */ +0x6f, 0xa5, 0xc1, 0x25, 0xbf, 0x26, 0x3b, 0xb8, /* o..%.&;. */ +0x6a, 0x1f, 0xc0, 0x29, 0xa1, 0x3c, 0x05, 0x79, /* j..).<.y */ +0xea, 0x22, 0xb4, 0xd3, 0xc2, 0xe8, 0xa8, 0x6d, /* .".....m */ +0x42, 0x29, 0x6a, 0xba, 0xa0, 0x70, 0x3a, 0x6c, /* B)j..p:l */ +0x84, 0xee, 0xcf, 0x35, 0x9b, 0xfe, 0x1c, 0x0c, /* ...5.... */ +0xcc, 0xfe, 0x5c, 0x75, 0x37, 0xd3, 0x2b, 0x78, /* ..\u7.+x */ +0x47, 0x72, 0x3a, 0x12, 0x03, 0xe3, 0xc1, 0xfb, /* Gr:..... */ +0xb3, 0x98, 0x68, 0xca, 0xd6, 0xd6, 0xc0, 0xbb, /* ..h..... */ +0x02, 0xc9, 0x56, 0xec, 0x40, 0x09, 0x48, 0xca, /* ..V.@.H. */ +0xa2, 0x46, 0xfe, 0x6c, 0x86, 0xb9, 0x7a, 0x7c, /* .F.l..z| */ +0xfb, 0x66, 0x4a, 0x4d, 0xe7, 0xed, 0x9e, 0xde, /* .fJM.... */ +0xe9, 0xf8, 0x21, 0x1d, 0xc9, 0x7f, 0xce, 0xe1, /* ..!..... */ +0x7c, 0x7c, 0x94, 0x7c, 0xfb, 0x57, 0x79, 0x9c, /* ||.|.Wy. */ +0x0f, 0xd4, 0xc0, 0x2d, 0x83, 0x7c, 0xf0, 0xed, /* ...-.|.. */ +0x04, 0x72, 0xc5, 0x33, 0x79, 0xc2, 0x47, 0x02, /* .r.3y.G. */ +0x94, 0xda, 0x85, 0xdf, 0x13, 0x4d, 0xf8, 0x10, /* .....M.. */ +0xe0, 0x96, 0x79, 0x44, 0xf0, 0xd2, 0xef, 0x10, /* ..yD.... */ +0xc7, 0xd7, 0xe3, 0xc0, 0xd1, 0x8d, 0xd3, 0x81, /* ........ */ +0xb3, 0xde, 0xeb, 0x04, 0x4a, 0x50, 0x1c, 0xf7, /* ....JP.. */ +0xb3, 0xc2, 0xf5, 0x57, 0x55, 0x41, 0x07, 0x08, /* ...WUA.. */ +0x74, 0x91, 0x15, 0x8c, 0x98, 0xc2, 0x1a, 0xe5, /* t....... */ +0x34, 0xf4, 0x00, 0xea, 0xb9, 0x61, 0xc9, 0xe7, /* 4....a.. */ +0x31, 0x97, 0x31, 0x18, 0x85, 0xab, 0x60, 0x8a, /* 1.1...`. */ +0x28, 0x5f, 0xf3, 0xfd, 0x23, 0x25, 0x11, 0x17, /* (_..#%.. */ +0xe8, 0x9a, 0xec, 0x2b, 0x69, 0xb6, 0x14, 0x39, /* ...+i..9 */ +0x02, 0x63, 0xb7, 0x04, 0x16, 0x48, 0xd5, 0x0f, /* .c...H.. */ +0x8c, 0x75, 0xd1, 0x70, 0x7e, 0x77, 0xf6, 0x7a, /* .u.p~w.z */ +0x13, 0xf5, 0x14, 0x87, 0x20, 0xc5, 0x12, 0x8d, /* .... ... */ +0x69, 0xdb, 0x5b, 0x71, 0xa2, 0x02, 0x8a, 0xd6, /* i.[q.... */ +0x3d, 0x41, 0x90, 0x5a, 0xdd, 0x93, 0x69, 0x19, /* =A.Z..i. */ +0x7f, 0x2d, 0xe6, 0x71, 0xc4, 0x8b, 0xd3, 0xdc, /* .-.q.... */ +0x30, 0x4e, 0x8d, 0x42, 0x12, 0x27, 0x0f, 0x43, /* 0N.B.'.C */ +0xc2, 0x72, 0x21, 0x51, 0xe3, 0x3c, 0xde, 0x63, /* .r!Q.<.c */ +0x42, 0xe0, 0xbd, 0x25, 0x55, 0xf2, 0x1e, 0x66, /* B..%U..f */ +0x8a, 0x0a, 0xb3, 0xaf, 0xc3, 0xf5, 0xfb, 0xcc, /* ........ */ +0x4a, 0x20, 0x77, 0xfe, 0x59, 0x62, 0xf1, 0xe9, /* J w.Yb.. */ +0x6a, 0xba, 0x7d, 0x53, 0xe7, 0x33, 0xe3, 0xb5, /* j.}S.3.. */ +0x48, 0x3d, 0xbc, 0xb3, 0x9c, 0xc1, 0x77, 0xcf, /* H=....w. */ +0xff, 0x04, 0xd4, 0xe3, 0x86, 0x61, 0x2f, 0xc9, /* .....a/. */ +0xa1, 0x71, 0x09, 0xcd, 0x64, 0xe5, 0x43, 0x59, /* .q..d.CY */ +0xb4, 0x0f, 0x4c, 0xd3, 0xa5, 0x1a, 0x0e, 0x81, /* ..L..... */ +0xed, 0xf1, 0xa4, 0xd3, 0x2c, 0xcb, 0x02, 0xfc, /* ....,... */ +0x0f, 0xa7, 0x82, 0xa0, 0xa3, 0xea, 0x23, 0xb6, /* ......#. */ +0xa4, 0x78, 0xc5, 0x68, 0xeb, 0x45, 0x40, 0xab, /* .x.h.E@. */ +0x76, 0x97 /* v. */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt19[1514] = { +0x02, 0x00, 0x00, 0x70, 0xca, 0x04, 0x5e, 0xe9, /* ...p..^. */ +0x1e, 0xa6, 0x21, 0x64, 0x08, 0x00, 0x45, 0x00, /* ..!d..E. */ +0x05, 0xdc, 0xe7, 0xd4, 0x00, 0x00, 0x33, 0x06, /* ......3. */ +0x2b, 0x34, 0x98, 0xc7, 0x13, 0xa1, 0xc0, 0xa8, /* +4...... */ +0x02, 0x03, 0x00, 0x50, 0xc9, 0xc1, 0xb1, 0x64, /* ...P...d */ +0xee, 0x5e, 0xfa, 0xdf, 0xdf, 0x46, 0x50, 0x10, /* .^...FP. */ +0xff, 0xff, 0x2c, 0x82, 0x00, 0x00, 0xeb, 0x18, /* ..,..... */ +0x04, 0x87, 0x03, 0xc6, 0x8c, 0xb0, 0x78, 0x0a, /* ......x. */ +0xd2, 0x6a, 0xee, 0x03, 0x13, 0x3a, 0x49, 0xb1, /* .j...:I. */ +0x34, 0x07, 0x72, 0x5d, 0x1b, 0x11, 0xda, 0xf6, /* 4.r].... */ +0xd1, 0xe1, 0xe7, 0xff, 0xd8, 0x85, 0xd8, 0xbf, /* ........ */ +0x0a, 0xd1, 0x54, 0x5d, 0xd2, 0x0f, 0x7d, 0x6b, /* ..T]..}k */ +0xd7, 0x08, 0x02, 0xe8, 0x5f, 0x6c, 0x3b, 0x55, /* ...._l;U */ +0x68, 0x91, 0x60, 0xc9, 0x3b, 0xcb, 0x11, 0xbb, /* h.`.;... */ +0x14, 0x66, 0x59, 0x84, 0x24, 0x8c, 0x7e, 0x15, /* .fY.$.~. */ +0x19, 0x58, 0xa2, 0x43, 0x6d, 0xd4, 0x6c, 0xc0, /* .X.Cm.l. */ +0x2d, 0x20, 0xf6, 0x65, 0x8e, 0x18, 0x91, 0x68, /* - .e...h */ +0xad, 0xd8, 0x9b, 0x54, 0xe4, 0x28, 0xca, 0xdf, /* ...T.(.. */ +0xc2, 0xbd, 0x4d, 0xbc, 0xbe, 0xde, 0xc3, 0x4c, /* ..M....L */ +0x6f, 0x6a, 0x20, 0xe6, 0x2c, 0x8d, 0xc0, 0x1d, /* oj .,... */ +0xfc, 0xc5, 0xcf, 0x1f, 0x39, 0x38, 0xd2, 0x24, /* ....98.$ */ +0xff, 0x4d, 0x33, 0xa5, 0xfb, 0x30, 0x59, 0xce, /* .M3..0Y. */ +0xf8, 0x04, 0x37, 0xf3, 0x3f, 0x3e, 0xb8, 0xf1, /* ..7.?>.. */ +0x88, 0x09, 0xbe, 0xef, 0x32, 0x5f, 0x8b, 0x9a, /* ....2_.. */ +0xf7, 0xc3, 0xd4, 0x8a, 0x04, 0x59, 0xbe, 0xeb, /* .....Y.. */ +0x20, 0x52, 0x7c, 0x6b, 0xd6, 0xbb, 0x5d, 0xd4, /* R|k..]. */ +0x6e, 0x9e, 0xdc, 0xba, 0x06, 0xae, 0x2e, 0x38, /* n......8 */ +0x09, 0xc9, 0x36, 0x64, 0xd9, 0x78, 0xc7, 0x84, /* ..6d.x.. */ +0x84, 0x34, 0xb7, 0x89, 0x09, 0x76, 0x7a, 0xf3, /* .4...vz. */ +0xb1, 0xd9, 0x3f, 0x95, 0xe8, 0xb7, 0x7c, 0x7a, /* ..?...|z */ +0xec, 0x1c, 0xdf, 0x39, 0x46, 0x81, 0x42, 0x99, /* ...9F.B. */ +0x4a, 0x84, 0x28, 0x31, 0xa4, 0x4d, 0xd9, 0x12, /* J.(1.M.. */ +0xcb, 0xdb, 0xc2, 0x96, 0xc3, 0x1e, 0x0b, 0x84, /* ........ */ +0xd0, 0x6e, 0xbc, 0x62, 0xc3, 0xcc, 0xd8, 0xd0, /* .n.b.... */ +0xd0, 0x99, 0x8d, 0xf4, 0x62, 0xc2, 0x89, 0xdd, /* ....b... */ +0xfd, 0x58, 0xa0, 0x91, 0xf3, 0x62, 0x7b, 0xe3, /* .X...b{. */ +0x91, 0x5f, 0xad, 0x24, 0x8a, 0xc6, 0xa3, 0x8d, /* ._.$.... */ +0x9a, 0xd8, 0xf8, 0x60, 0x03, 0x90, 0xf0, 0x96, /* ...`.... */ +0x40, 0xc8, 0x25, 0xb2, 0x5b, 0xa5, 0x24, 0x8e, /* @.%.[.$. */ +0xa3, 0x73, 0xde, 0x2c, 0x5e, 0x87, 0xfc, 0x72, /* .s.,^..r */ +0x0b, 0x0c, 0x31, 0xc8, 0xf4, 0x76, 0xa8, 0xba, /* ..1..v.. */ +0x7c, 0x55, 0xb3, 0x2e, 0x3a, 0xfa, 0xea, 0x6b, /* |U..:..k */ +0xb3, 0xff, 0x86, 0xbd, 0x24, 0xd1, 0x97, 0xd9, /* ....$... */ +0x60, 0x57, 0xea, 0xc3, 0x2e, 0xa5, 0x3d, 0x88, /* `W....=. */ +0x8f, 0xe6, 0xaa, 0x50, 0xb4, 0x62, 0xb2, 0x33, /* ...P.b.3 */ +0x85, 0xa4, 0x4d, 0xae, 0x92, 0xea, 0x32, 0x7a, /* ..M...2z */ +0xea, 0x6b, 0xae, 0x5a, 0xba, 0x3c, 0xd7, 0xbf, /* .k.Z.<.. */ +0xd7, 0x67, 0xa4, 0x30, 0x1f, 0x7b, 0x19, 0x89, /* .g.0.{.. */ +0x75, 0x4b, 0xd9, 0x28, 0xee, 0x7b, 0x46, 0xda, /* uK.(.{F. */ +0xcf, 0xb1, 0x3f, 0xf1, 0xbc, 0x40, 0x82, 0x61, /* ..?..@.a */ +0x57, 0x35, 0x33, 0xb7, 0x5e, 0x0e, 0xd7, 0xf4, /* W53.^... */ +0x5f, 0x63, 0xb4, 0x85, 0x2e, 0x35, 0xc1, 0x8e, /* _c...5.. */ +0x31, 0xd8, 0xd8, 0xd1, 0x36, 0x5d, 0x96, 0x72, /* 1...6].r */ +0x7a, 0x62, 0xf3, 0x2c, 0x38, 0x20, 0x01, 0x0e, /* zb.,8 .. */ +0x9f, 0x29, 0x15, 0x3e, 0xea, 0xad, 0x6c, 0x3f, /* .).>..l? */ +0xd2, 0x8f, 0xa4, 0x1a, 0x3d, 0xd8, 0xb2, 0x18, /* ....=... */ +0xcc, 0x76, 0x9f, 0xa7, 0xc7, 0x0f, 0x5f, 0xc1, /* .v...._. */ +0xe2, 0x59, 0xea, 0x10, 0xb3, 0x9f, 0xb5, 0x29, /* .Y.....) */ +0x32, 0xd9, 0x95, 0x00, 0x85, 0x23, 0x3e, 0x5f, /* 2....#>_ */ +0x45, 0xaa, 0x0d, 0xd2, 0xdc, 0x3c, 0xd0, 0x5c, /* E....<.\ */ +0xdc, 0x11, 0x76, 0x9c, 0x33, 0x52, 0x44, 0x5b, /* ..v.3RD[ */ +0xc1, 0x13, 0xda, 0x6e, 0xf5, 0x37, 0xa3, 0x32, /* ...n.7.2 */ +0xcc, 0xcb, 0x38, 0x30, 0xa7, 0xdf, 0x04, 0x63, /* ..80...c */ +0xa2, 0xae, 0x9d, 0x1c, 0x02, 0x95, 0x90, 0x4f, /* .......O */ +0x34, 0x57, 0x22, 0x6f, 0xc7, 0xf9, 0x31, 0x12, /* 4W"o..1. */ +0x34, 0xef, 0x60, 0xf3, 0x90, 0x47, 0x9f, 0xb2, /* 4.`..G.. */ +0x0d, 0xda, 0x2e, 0xd0, 0x3d, 0x6e, 0x01, 0xd5, /* ....=n.. */ +0xad, 0x88, 0x1a, 0x85, 0xe7, 0x8b, 0x7e, 0x71, /* ......~q */ +0x21, 0x45, 0x07, 0x2a, 0x39, 0xdb, 0x38, 0xcf, /* !E.*9.8. */ +0xcd, 0x82, 0x60, 0x04, 0xf7, 0x03, 0xf7, 0xa1, /* ..`..... */ +0x51, 0xbd, 0x1c, 0x5a, 0x7b, 0xd0, 0x18, 0x3f, /* Q..Z{..? */ +0x0a, 0x49, 0xcb, 0x03, 0x68, 0xa9, 0xbd, 0xb5, /* .I..h... */ +0x34, 0x31, 0xdf, 0x2d, 0x1f, 0x43, 0xc4, 0x7e, /* 41.-.C.~ */ +0x6c, 0xc7, 0x67, 0xc9, 0x43, 0x99, 0x89, 0x89, /* l.g.C... */ +0xcc, 0x58, 0xce, 0x15, 0x6d, 0x95, 0x5c, 0x0e, /* .X..m.\. */ +0x52, 0xae, 0x25, 0x20, 0xf3, 0x9b, 0xba, 0xf2, /* R.% .... */ +0x32, 0x5f, 0xf3, 0xe3, 0x6a, 0x97, 0x59, 0x7d, /* 2_..j.Y} */ +0x31, 0x3b, 0x38, 0x37, 0x88, 0xe0, 0xd6, 0x4f, /* 1;87...O */ +0x30, 0x35, 0x2f, 0xc2, 0x8f, 0x03, 0xc2, 0xbf, /* 05/..... */ +0x5b, 0x64, 0xba, 0x7b, 0xa3, 0x54, 0xce, 0x28, /* [d.{.T.( */ +0x41, 0xad, 0x7a, 0x34, 0xcf, 0xf8, 0xe8, 0x25, /* A.z4...% */ +0xe7, 0x3c, 0x23, 0xba, 0x4b, 0xbc, 0x42, 0x15, /* .<#.K.B. */ +0x3f, 0xce, 0x04, 0x7a, 0x2e, 0xdc, 0xb8, 0x61, /* ?..z...a */ +0x24, 0x1a, 0x43, 0x47, 0x33, 0xf5, 0xc4, 0x4a, /* $.CG3..J */ +0xab, 0x2d, 0x4a, 0x6a, 0x38, 0xfa, 0x7d, 0xe6, /* .-Jj8.}. */ +0x4d, 0xb8, 0xf0, 0xb5, 0x3b, 0x6a, 0x66, 0x53, /* M...;jfS */ +0x21, 0x4c, 0x34, 0x04, 0x19, 0xf2, 0xd3, 0x7b, /* !L4....{ */ +0xaf, 0x4d, 0xa6, 0x37, 0x92, 0x27, 0x65, 0x54, /* .M.7.'eT */ +0xdc, 0x8c, 0x9b, 0x28, 0xc7, 0xc4, 0x75, 0x28, /* ...(..u( */ +0x4a, 0x38, 0x6c, 0xec, 0xfd, 0x06, 0x99, 0x74, /* J8l....t */ +0xf5, 0x49, 0x7b, 0x46, 0x69, 0xd6, 0x9b, 0xa4, /* .I{Fi... */ +0x52, 0xff, 0xf3, 0x92, 0x19, 0x7b, 0xbb, 0x30, /* R....{.0 */ +0x58, 0xb3, 0x94, 0x41, 0x09, 0x7a, 0x85, 0xd3, /* X..A.z.. */ +0x84, 0xfc, 0x98, 0x43, 0x04, 0xe2, 0x12, 0x15, /* ...C.... */ +0xd5, 0x25, 0xf7, 0xb7, 0x19, 0x56, 0x25, 0xa0, /* .%...V%. */ +0x2f, 0x8e, 0xb3, 0xf9, 0x06, 0x84, 0xac, 0x90, /* /....... */ +0x0a, 0x12, 0xee, 0xa0, 0x74, 0xb1, 0x5d, 0x29, /* ....t.]) */ +0xac, 0x2a, 0xbb, 0x4a, 0x22, 0x8f, 0x48, 0x12, /* .*.J".H. */ +0x1a, 0xd0, 0x8a, 0x10, 0x95, 0x48, 0xea, 0x5e, /* .....H.^ */ +0xee, 0x4b, 0xc6, 0xb6, 0x35, 0xa5, 0xe6, 0x6c, /* .K..5..l */ +0xaa, 0x88, 0xb5, 0x78, 0x29, 0xc1, 0x97, 0x00, /* ...x)... */ +0xa0, 0x53, 0x54, 0x7b, 0x20, 0x20, 0xce, 0x4c, /* .ST{ .L */ +0xa3, 0x59, 0x04, 0xbd, 0xf9, 0xd5, 0xd4, 0x10, /* .Y...... */ +0xbc, 0x62, 0x85, 0xc1, 0xf1, 0x27, 0x88, 0x93, /* .b...'.. */ +0xd6, 0xc2, 0x03, 0xae, 0xe8, 0x9e, 0xa5, 0x62, /* .......b */ +0xf6, 0x45, 0x34, 0x6d, 0x1e, 0xf0, 0xd1, 0x2d, /* .E4m...- */ +0x86, 0xb2, 0xa4, 0x3c, 0x48, 0x74, 0x26, 0xf1, /* ....... */ +0x2e, 0x13, 0xce, 0x67, 0x9f, 0xe7, 0x29, 0x5e, /* ...g..)^ */ +0xb6, 0x32, 0xfe, 0xd7, 0x9a, 0x86, 0xae, 0x61, /* .2.....a */ +0x9e, 0x33, 0x01, 0x93, 0x0e, 0x97, 0x99, 0x29, /* .3.....) */ +0x47, 0x99, 0x85, 0x70, 0x68, 0x60, 0x8b, 0x3d, /* G..ph`.= */ +0x8d, 0x38, 0x9c, 0x78, 0x98, 0xef, 0xaf, 0x22, /* .8.x..." */ +0x97, 0x01, 0xba, 0x73, 0x15, 0x89, 0x97, 0x5c, /* ...s...\ */ +0xce, 0x92, 0xe5, 0xbd, 0x7b, 0xe6, 0xcd, 0xe6, /* ....{... */ +0xc1, 0x4e, 0x4a, 0x25, 0xe6, 0x88, 0xc0, 0xb7, /* .NJ%.... */ +0xce, 0x0a, 0x92, 0x2b, 0x20, 0x73, 0x7e, 0x67, /* ...+ s~g */ +0xa9, 0x28, 0x13, 0xfb, 0x38, 0x27, 0x7b, 0x87, /* .(..8'{. */ +0xbc, 0xf0, 0xb1, 0x31, 0x07, 0x1d, 0x21, 0x45, /* ...1..!E */ +0x09, 0x01, 0x26, 0x5b, 0x5f, 0x5b, 0x48, 0x7a, /* ..&[_[Hz */ +0x6f, 0xe3, 0xb3, 0x93, 0x6d, 0x57, 0x61, 0xbe, /* o...mWa. */ +0x9d, 0xf8, 0xca, 0xe2, 0x5f, 0x6c, 0x70, 0x8b, /* ...._lp. */ +0xe4, 0x26, 0xb5, 0x1f, 0xaf, 0xff, 0xe0, 0xfe, /* .&...... */ +0x89, 0x2d, 0xe5, 0xd3, 0xd5, 0x44, 0xee, 0x28, /* .-...D.( */ +0x0c, 0xd2, 0x18, 0x16, 0xbd, 0x6d, 0xed, 0xc7, /* .....m.. */ +0x1a, 0x8d, 0x2b, 0x90, 0x3f, 0x1f, 0x5f, 0xa4, /* ..+.?._. */ +0x20, 0x2d, 0xfa, 0x5b, 0xd8, 0x3a, 0x03, 0xa0, /* -.[.:.. */ +0xe9, 0xc9, 0xcd, 0x20, 0xf9, 0xbc, 0xce, 0xb0, /* ... .... */ +0x7b, 0xb9, 0x9a, 0x0b, 0xc1, 0x28, 0x4a, 0xd8, /* {....(J. */ +0xb9, 0xc2, 0xef, 0x2b, 0xed, 0xb7, 0x3b, 0x82, /* ...+..;. */ +0x2f, 0x9d, 0xeb, 0xa2, 0xd2, 0xa2, 0xd3, 0x1a, /* /....... */ +0xfe, 0xe6, 0xa0, 0x63, 0x4b, 0x04, 0x23, 0xda, /* ...cK.#. */ +0xdc, 0x6e, 0xbe, 0x56, 0x2b, 0x9a, 0x19, 0x70, /* .n.V+..p */ +0x6f, 0xc0, 0xb7, 0xf1, 0x9e, 0xe9, 0xe9, 0xc8, /* o....... */ +0xda, 0x27, 0x6a, 0x7e, 0xce, 0xf6, 0xcf, 0x9f, /* .'j~.... */ +0x0d, 0x51, 0x78, 0x6b, 0x21, 0x71, 0x18, 0x43, /* .Qxk!q.C */ +0x3e, 0xdc, 0xbd, 0xfc, 0xe7, 0xba, 0x2d, 0xbe, /* >.....-. */ +0xe1, 0xff, 0x0c, 0x58, 0x81, 0xce, 0x8a, 0x83, /* ...X.... */ +0x51, 0xca, 0x79, 0x4d, 0xa1, 0x76, 0x0e, 0x9b, /* Q.yM.v.. */ +0xcd, 0xc2, 0x88, 0x2d, 0xe5, 0x8f, 0x58, 0x5b, /* ...-..X[ */ +0x7f, 0xf4, 0xce, 0xc3, 0xc5, 0x9d, 0x04, 0xf6, /* ........ */ +0x89, 0x02, 0x36, 0x38, 0x51, 0x36, 0x54, 0x33, /* ..68Q6T3 */ +0x37, 0xb4, 0x0f, 0x9e, 0x47, 0x2c, 0xaf, 0xa9, /* 7...G,.. */ +0xaa, 0xcf, 0x2d, 0x06, 0xfe, 0x3a, 0xb7, 0x88, /* ..-..:.. */ +0xc0, 0xd2, 0x3d, 0x7c, 0x9c, 0x62, 0xc6, 0xb9, /* ..=|.b.. */ +0x17, 0x71, 0x6f, 0x16, 0x6d, 0xca, 0x56, 0x90, /* .qo.m.V. */ +0xfd, 0x34, 0x57, 0xcf, 0xe6, 0x66, 0x2d, 0x1d, /* .4W..f-. */ +0xa6, 0x22, 0x67, 0xa6, 0xa8, 0x92, 0x5a, 0xf2, /* ."g...Z. */ +0x99, 0x9d, 0x34, 0xdb, 0x1c, 0x99, 0x6c, 0x8f, /* ..4...l. */ +0x54, 0xb8, 0xce, 0x77, 0x0a, 0xe8, 0x44, 0xcb, /* T..w..D. */ +0x67, 0xd1, 0x2d, 0xd3, 0xfa, 0x18, 0xe6, 0x29, /* g.-....) */ +0x65, 0xc5, 0x25, 0x9d, 0xf1, 0x00, 0xc5, 0x41, /* e.%....A */ +0xf4, 0xc1, 0x57, 0x35, 0xde, 0xe6, 0x55, 0x48, /* ..W5..UH */ +0xce, 0xc1, 0x56, 0x7f, 0xb4, 0xc0, 0x37, 0x08, /* ..V...7. */ +0x4c, 0x83, 0xb2, 0xcc, 0x9c, 0x15, 0x53, 0xa3, /* L.....S. */ +0x67, 0x1c, 0x17, 0x5d, 0xef, 0xc6, 0x71, 0x50, /* g..]..qP */ +0xd1, 0x76, 0xaf, 0x0a, 0x4e, 0x10, 0x2c, 0x70, /* .v..N.,p */ +0x23, 0x0e, 0x2f, 0xff, 0x72, 0xa5, 0x89, 0x7c, /* #./.r..| */ +0x52, 0xe8, 0xdd, 0xfd, 0x97, 0xa3, 0xca, 0xe9, /* R....... */ +0x2e, 0x05, 0xf5, 0x92, 0xff, 0xa9, 0x56, 0xb6, /* ......V. */ +0x72, 0x7c, 0x0d, 0xd6, 0x30, 0xe4, 0x32, 0x77, /* r|..0.2w */ +0x88, 0xfd, 0x74, 0xe9, 0x72, 0xef, 0x86, 0xb4, /* ..t.r... */ +0x0e, 0xfe, 0xb9, 0x54, 0x14, 0xb5, 0xd8, 0x40, /* ...T...@ */ +0xb7, 0xbf, 0x49, 0xe8, 0xb9, 0x90, 0x29, 0x23, /* ..I...)# */ +0x66, 0x07, 0xf5, 0xe9, 0xc5, 0xee, 0x3a, 0x5f, /* f.....:_ */ +0x47, 0xde, 0x01, 0x33, 0x0a, 0xa5, 0x8c, 0xd4, /* G..3.... */ +0x76, 0x1b, 0x28, 0x81, 0xc0, 0x88, 0x1c, 0xb2, /* v.(..... */ +0x82, 0xbb, 0x21, 0x32, 0xf9, 0x5f, 0x32, 0xd6, /* ..!2._2. */ +0x93, 0x70, 0x12, 0x85, 0x0b, 0x26, 0x74, 0x50, /* .p...&tP */ +0x12, 0xec, 0x43, 0x92, 0x70, 0xc5, 0xee, 0x23, /* ..C.p..# */ +0xc3, 0x87, 0xf3, 0xe9, 0xa1, 0x7e, 0xac, 0x30, /* .....~.0 */ +0x26, 0xe3, 0x9f, 0x79, 0xd9, 0xc1, 0xf9, 0x54, /* &..y...T */ +0x1f, 0x68, 0xf7, 0x6d, 0xa3, 0x6d, 0xdd, 0x0f, /* .h.m.m.. */ +0xe3, 0xca, 0xf5, 0x21, 0xc1, 0xc3, 0x94, 0xce, /* ...!.... */ +0x2c, 0x09, 0x56, 0x62, 0x73, 0x3e, 0xf5, 0xc3, /* ,.Vbs>.. */ +0xce, 0xfe, 0x78, 0x22, 0x2a, 0x1e, 0x30, 0x54, /* ..x"*.0T */ +0xb5, 0x7a, 0xf8, 0xba, 0xf9, 0x77, 0x64, 0x4c, /* .z...wdL */ +0x60, 0x17, 0x18, 0x77, 0xf2, 0x35, 0x9a, 0xc1, /* `..w.5.. */ +0xb0, 0x45, 0xea, 0x35, 0x9e, 0x2c, 0x95, 0xd8, /* .E.5.,.. */ +0x2c, 0xcf, 0xa0, 0xc1, 0x4c, 0xfe, 0x7d, 0x29, /* ,...L.}) */ +0xdc, 0x76, 0x7a, 0xaf, 0x8a, 0xff, 0xb4, 0x35, /* .vz....5 */ +0x7f, 0x87, 0x3d, 0x50, 0x2e, 0x29, 0xfa, 0x53, /* ..=P.).S */ +0x6d, 0xae, 0x23, 0xb9, 0x70, 0xc7, 0x5f, 0x1d, /* m.#.p._. */ +0x7b, 0xe3, 0xe8, 0xd7, 0x32, 0x63, 0x35, 0x9a, /* {...2c5. */ +0xbd, 0x8a, 0xa0, 0xef, 0x8e, 0x60, 0x47, 0x9c, /* .....`G. */ +0xc2, 0x4f, 0xc6, 0xed, 0x09, 0x53, 0xdb, 0x69, /* .O...S.i */ +0x3b, 0x94, 0xb2, 0xad, 0xa5, 0x43, 0x04, 0x4b, /* ;....C.K */ +0x94, 0xb5 /* .. */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt20[1514] = { +0x02, 0x00, 0x00, 0x70, 0xca, 0x04, 0x5e, 0xe9, /* ...p..^. */ +0x1e, 0xa6, 0x21, 0x64, 0x08, 0x00, 0x45, 0x00, /* ..!d..E. */ +0x05, 0xdc, 0xe7, 0xd6, 0x00, 0x00, 0x33, 0x06, /* ......3. */ +0x2b, 0x32, 0x98, 0xc7, 0x13, 0xa1, 0xc0, 0xa8, /* +2...... */ +0x02, 0x03, 0x00, 0x50, 0xc9, 0xc1, 0xb1, 0x64, /* ...P...d */ +0xf8, 0x71, 0xfa, 0xdf, 0xdf, 0x46, 0x50, 0x10, /* .q...FP. */ +0xff, 0xff, 0xdc, 0xbe, 0x00, 0x00, 0xd6, 0x74, /* .......t */ +0xfa, 0xa6, 0x49, 0x1b, 0xbf, 0x68, 0x24, 0x74, /* ..I..h$t */ +0xfd, 0x96, 0x20, 0x2c, 0xbf, 0x7e, 0x6b, 0x71, /* .. ,.~kq */ +0x7b, 0x61, 0x02, 0x12, 0x4c, 0xc9, 0x71, 0x5d, /* {a..L.q] */ +0x14, 0x71, 0xdf, 0x6a, 0xd0, 0x9b, 0x72, 0x4d, /* .q.j..rM */ +0x8c, 0xaf, 0x91, 0x58, 0xda, 0xf1, 0x77, 0x59, /* ...X..wY */ +0xf4, 0xd9, 0x21, 0xa7, 0xe0, 0xe1, 0x20, 0xe3, /* ..!... . */ +0xc5, 0x47, 0x11, 0x1a, 0x56, 0x32, 0x06, 0x01, /* .G..V2.. */ +0x9a, 0x4c, 0xb8, 0x6b, 0xe9, 0x8c, 0x8d, 0x87, /* .L.k.... */ +0x92, 0x79, 0x4c, 0x37, 0xc3, 0x25, 0xc7, 0xab, /* .yL7.%.. */ +0x58, 0x29, 0x09, 0xcf, 0x63, 0xf3, 0x21, 0x59, /* X)..c.!Y */ +0x16, 0x6d, 0xaa, 0x59, 0x63, 0x80, 0x1a, 0x7f, /* .m.Yc... */ +0x60, 0x04, 0x01, 0x7a, 0xa3, 0x06, 0xcc, 0x36, /* `..z...6 */ +0xc7, 0xa1, 0xa5, 0xe7, 0x6b, 0x90, 0xe2, 0xdc, /* ....k... */ +0xdc, 0x0b, 0x0c, 0xe8, 0xad, 0x5a, 0xa4, 0x88, /* .....Z.. */ +0x26, 0x19, 0x32, 0x67, 0x0a, 0xff, 0xfe, 0x42, /* &.2g...B */ +0xda, 0x9e, 0x60, 0x21, 0xe2, 0xbf, 0x01, 0x6b, /* ..`!...k */ +0x65, 0xac, 0x3d, 0xe0, 0xe5, 0x71, 0x9e, 0x3d, /* e.=..q.= */ +0x60, 0x60, 0xe4, 0xd8, 0x89, 0x84, 0x1b, 0x3f, /* ``.....? */ +0xaa, 0xa2, 0x0a, 0x1e, 0xe5, 0x5a, 0x91, 0x13, /* .....Z.. */ +0xb3, 0x77, 0x3e, 0x5a, 0x87, 0xc3, 0xd9, 0x60, /* .w>Z...` */ +0xa0, 0x0a, 0x8c, 0xcc, 0xd0, 0x59, 0x8a, 0x43, /* .....Y.C */ +0x6f, 0x28, 0x5b, 0x6e, 0xa2, 0x58, 0xdc, 0x23, /* o([n.X.# */ +0xa9, 0x9e, 0x82, 0x76, 0x79, 0xfe, 0xf0, 0x5e, /* ...vy..^ */ +0x94, 0x65, 0x71, 0x83, 0x12, 0xd5, 0xcf, 0xa7, /* .eq..... */ +0x91, 0x33, 0xd4, 0x92, 0x9b, 0x8f, 0x51, 0x45, /* .3....QE */ +0x87, 0xe9, 0xdf, 0xde, 0xaf, 0xba, 0xbd, 0xa4, /* ........ */ +0x46, 0x13, 0x92, 0xd2, 0x9c, 0x80, 0x6b, 0xeb, /* F.....k. */ +0x1f, 0x68, 0x41, 0xa9, 0x51, 0x10, 0x5f, 0xf5, /* .hA.Q._. */ +0x9b, 0xdc, 0x44, 0xf5, 0xf4, 0x44, 0xd4, 0x5a, /* ..D..D.Z */ +0xe2, 0x15, 0xb9, 0x12, 0xf2, 0x17, 0xae, 0x0c, /* ........ */ +0x96, 0x35, 0x20, 0x1e, 0x5c, 0x86, 0xb8, 0x80, /* .5 .\... */ +0x48, 0xe0, 0x51, 0x6b, 0x84, 0x5c, 0x9d, 0x60, /* H.Qk.\.` */ +0x7b, 0x10, 0xe1, 0x0c, 0x73, 0x38, 0x7a, 0x27, /* {...s8z' */ +0x88, 0xbf, 0x1c, 0x96, 0x34, 0xd7, 0x79, 0x80, /* ....4.y. */ +0x10, 0xb3, 0x14, 0x11, 0x3a, 0x4c, 0xba, 0xb6, /* ....:L.. */ +0x31, 0x82, 0xea, 0xa1, 0xb9, 0x33, 0x02, 0x73, /* 1....3.s */ +0x7d, 0x88, 0xdb, 0xe2, 0xfb, 0xf3, 0x2d, 0x2a, /* }.....-* */ +0xd9, 0x5e, 0xf7, 0x6e, 0xac, 0xc2, 0xa0, 0x59, /* .^.n...Y */ +0x64, 0x8e, 0x46, 0x37, 0x0f, 0x6c, 0x7a, 0x52, /* d.F7.lzR */ +0x42, 0x21, 0x03, 0x38, 0x1b, 0xb7, 0xd7, 0x2b, /* B!.8...+ */ +0x2a, 0x88, 0x5a, 0x3c, 0xc8, 0xc4, 0xad, 0x52, /* *.Z<...R */ +0x44, 0xbb, 0x15, 0x1f, 0x0a, 0x46, 0xee, 0x6b, /* D....F.k */ +0xeb, 0xdd, 0xaa, 0x73, 0xc4, 0xbc, 0x0c, 0x10, /* ...s.... */ +0xc2, 0x44, 0x2c, 0x35, 0x61, 0xa5, 0x46, 0x85, /* .D,5a.F. */ +0x79, 0xa8, 0xa0, 0xb3, 0x82, 0x6f, 0x54, 0x2f, /* y....oT/ */ +0x25, 0xd0, 0xae, 0x33, 0x47, 0x9c, 0xae, 0xf6, /* %..3G... */ +0x9f, 0xba, 0x11, 0x78, 0x98, 0x52, 0x3c, 0x74, /* ...x.R nx_packet_append_ptr - received_packet -> nx_packet_prepend_ptr); + + /* Release the packet. */ + nx_packet_release(received_packet); + } + + while(packet_response_sent != NX_TRUE) + { + tx_thread_sleep(1); + } + + /* Receive response data from the server. Loop until all data is received. */ + while (1) + { + + /* Recieve the packet. */ + status = nx_tcp_socket_receive(&client_socket, &received_packet, NX_NO_WAIT); + + /* Check for error. */ + if (status == NX_SUCCESS) + { + packet_received_counter++; + + /* Calculate the data size in current packet. */ + received_data_size += (UINT)(received_packet -> nx_packet_append_ptr - received_packet -> nx_packet_prepend_ptr); + + /* Release the packet. */ + nx_packet_release(received_packet); + } + else + { + break; + } + } + + /* Check the data size and ack number. */ + if ((received_data_size != 17844) || (packet_received_counter != 13)) + { + error_counter++; + } + + test_done = NX_TRUE; +} + + +/* Define the helper HTTP server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT i = 0; + + /* Print out test information banner. */ + printf("NetX Test: TCP Out Of Order Ack Test................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Initialize the test data. */ + test_initialize(); + + /* Wait for tcp connection. */ + while(tcp_connected != NX_TRUE) + { + tx_thread_sleep(1); + } + + /* Start to send response. */ + while (i < RESPONSE_COUNT) + { + response_packet_inject((UCHAR *)response[i].response_pkt_data, response[i].response_pkt_size); + i++; + + /* Send reaming packet after HTTP client receives first packet. */ + if (i == 5) + { + while(packet_received_counter == 0) + { + tx_thread_sleep(1); + } + } + } + + packet_response_sent = NX_TRUE; + + /* Wait for test done. */ + while (test_done != NX_TRUE) + { + tx_thread_sleep(1); + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void test_initialize() +{ + + response[0].response_pkt_data = (char *)&pkt5[0]; + response[0].response_pkt_size = sizeof(pkt5); + + response[1].response_pkt_data = (char *)&pkt6[0]; + response[1].response_pkt_size = sizeof(pkt6); + + response[2].response_pkt_data = (char *)&pkt7[0]; + response[2].response_pkt_size = sizeof(pkt7); + + response[3].response_pkt_data = (char *)&pkt8[0]; + response[3].response_pkt_size = sizeof(pkt8); + + response[4].response_pkt_data = (char *)&pkt9[0]; + response[4].response_pkt_size = sizeof(pkt9); + + response[5].response_pkt_data = (char *)&pkt12[0]; + response[5].response_pkt_size = sizeof(pkt12); + + response[6].response_pkt_data = (char *)&pkt13[0]; + response[6].response_pkt_size = sizeof(pkt13); + + response[7].response_pkt_data = (char *)&pkt14[0]; + response[7].response_pkt_size = sizeof(pkt14); + + response[8].response_pkt_data = (char *)&pkt15[0]; + response[8].response_pkt_size = sizeof(pkt15); + + response[9].response_pkt_data = (char *)&pkt16[0]; + response[9].response_pkt_size = sizeof(pkt16); + + response[10].response_pkt_data = (char *)&pkt17[0]; + response[10].response_pkt_size = sizeof(pkt17); + + response[11].response_pkt_data = (char *)&pkt18[0]; + response[11].response_pkt_size = sizeof(pkt18); + + response[12].response_pkt_data = (char *)&pkt19[0]; + response[12].response_pkt_size = sizeof(pkt19); + + response[13].response_pkt_data = (char *)&pkt20[0]; + response[13].response_pkt_size = sizeof(pkt20); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *header_ptr; +ULONG tcp_header_word_3; + + /* Do not process packets that are not TCP. */ + if ((packet_ptr -> nx_packet_length < 40) || (ip_ptr != &client_ip)) + return NX_TRUE; + + /* Get TCP header. */ + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + tcp_header_word_3 = header_ptr -> nx_tcp_header_word_3; + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check whether it is a SYN packet. */ + if ((tcp_header_word_3 & NX_TCP_CONTROL_MASK) == NX_TCP_SYN_BIT) + { + + /* Update the sequence number. */ + client_socket.nx_tcp_socket_tx_sequence = 4208975480; + + /* SYN packet, inject SYN + ACK. */ + response_packet_inject((UCHAR *)pkt2, sizeof(pkt2)); + } + + return NX_TRUE; +} + +static VOID response_packet_inject(UCHAR *data_ptr, UINT data_size) +{ +UINT status; +NX_PACKET *my_packet; + + status = nx_packet_allocate(&client_pool, &my_packet, NX_RECEIVE_PACKET, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Make sure IP header is 4-byte aligned. */ + my_packet -> nx_packet_prepend_ptr += 2; + my_packet -> nx_packet_append_ptr += 2; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(my_packet, data_ptr, data_size, &client_pool, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Skip the MAC header. */ + my_packet -> nx_packet_length -= 14; + my_packet -> nx_packet_prepend_ptr += 14; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&client_ip, my_packet); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_out_of_order_ack_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Out Of Order Ack Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_out_of_order_packet_max_test.c b/test/regression/netxduo_test/netx_tcp_out_of_order_packet_max_test.c new file mode 100644 index 00000000..3857f355 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_out_of_order_packet_max_test.c @@ -0,0 +1,319 @@ +/* This NetX test concentrates on out of order TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#define DEMO_STACK_SIZE 2048 + +#if defined(NX_TCP_MAX_OUT_OF_ORDER_PACKETS) && !defined(NX_DISABLE_IPV4) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static NX_PACKET *operation_packet; +static CHAR *test_buffer = "ABCDEFGH"; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_out_of_order_packet_max_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; +ULONG pool_size; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + operation_packet = NX_NULL; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + pool_size = (sizeof(NX_PACKET) + 256) * 16; + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, pool_size); + pointer = pointer + pool_size; + + if (status) + error_counter++; + + /* Create a packet pool. */ + pool_size = (sizeof(NX_PACKET) + 256) * (NX_TCP_MAX_OUT_OF_ORDER_PACKETS + 1); + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 256, pointer, pool_size); + pointer = pointer + pool_size; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet[8]; +UINT i; + + + + /* Print out test information banner. */ + printf("NetX Test: TCP Out of Order Packet Max Test.........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup callback function to drop packets. */ + advanced_packet_process_callback = my_packet_process; + + for(i = 0; i < sizeof(my_packet) / sizeof(NX_PACKET *); i++) + { + nx_packet_allocate(&pool_0, &my_packet[i], NX_TCP_PACKET, NX_WAIT_FOREVER); + nx_packet_data_append(my_packet[i], test_buffer + i, 1, &pool_0, NX_WAIT_FOREVER); + + /* Drop the first two packets. */ + if(i < 2) + { + operation_packet = my_packet[i]; + } + + nx_tcp_socket_send(&client_socket, my_packet[i], NX_WAIT_FOREVER); + } + + nx_tcp_socket_disconnect(&client_socket, NX_WAIT_FOREVER); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +UCHAR recv_buffer[10]; +ULONG recv_len; +ULONG total_len = 0; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive until no data. */ + while(nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + nx_packet_data_retrieve(packet_ptr, recv_buffer + total_len, &recv_len); + nx_packet_release(packet_ptr); + total_len += recv_len; + } + + nx_tcp_socket_disconnect(&server_socket, NX_WAIT_FOREVER); + + /* Check received data. */ + if(total_len != strlen(test_buffer)) + { + error_counter++; + } + else if(memcmp(test_buffer, recv_buffer, total_len)) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + if(packet_ptr == operation_packet) + { + operation_packet = NX_NULL; + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_out_of_order_packet_max_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Out of Order Packet Max Test..........................N/A\n"); + test_control_return(2); +} +#endif /* NX_TCP_MAX_OUT_OF_ORDER_PACKETS */ diff --git a/test/regression/netxduo_test/netx_tcp_out_of_order_packet_test.c b/test/regression/netxduo_test/netx_tcp_out_of_order_packet_test.c new file mode 100644 index 00000000..1cb6c2c1 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_out_of_order_packet_test.c @@ -0,0 +1,493 @@ +/* This NetX test concentrates on out of order TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; + + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_out_of_order_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + + /* Print out test information banner. */ + printf("NetX Test: TCP Out of Order Packet Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + tx_thread_relinquish(); + + /* Loop to repeat things over and over again! */ + thread_0_counter = 0; + while ((thread_0_counter < 2000) && (!error_counter)) + { + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Set the gather flag to instruct the test driver to save the packets and reverse the order. */ + packet_gather = 1; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_suspend(&thread_0); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Determine if the test was successful. */ + if ((error_counter) || (thread_0_counter != 2000) || (thread_1_counter != 2000)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG sequence_increment = 1; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Supsend thread 0. */ + tx_thread_suspend(&thread_0); + nx_tcp_socket_state_wait(&server_socket, NX_TCP_ESTABLISHED, 2 * NX_IP_PERIODIC_RATE); + tx_thread_resume(&thread_0); + + /* Set all the sequence numbers the way we want them for our test. */ + client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00; + client_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00; + client_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00; + server_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00; + server_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00; + server_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00; + + /* Loop to create and establish server connections. */ + thread_1_counter = 0; + while ((thread_1_counter < 2000) && (!error_counter)) + { + + /* Increment thread 1's counter. */ + thread_1_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive a TCP message from the socket. */ + server_socket.nx_tcp_socket_rx_window_last_sent = 0; /* Force an ACK out! */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Set all the sequence numbers the way we want them for our test. */ + if ((server_socket.nx_tcp_socket_rx_sequence < 0xFFFFFF00) && + (server_socket.nx_tcp_socket_rx_sequence > 0x100)) + { + client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + client_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + client_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00 + (sequence_increment & 0xFF); + server_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + server_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + server_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00 + (sequence_increment++ & 0xFF); + } + + /* Resume thread 0. */ + tx_thread_resume(&thread_0); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_out_of_order_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Out of Order Packet Test..............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_out_of_window_control_packet_test.c b/test/regression/netxduo_test/netx_tcp_out_of_window_control_packet_test.c new file mode 100644 index 00000000..70a1f6d5 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_out_of_window_control_packet_test.c @@ -0,0 +1,334 @@ +/* This NetX test concentrates on processing out of window RST, URG, ACK packet when receive window is zero. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define WINDOW_SIZE 128 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static CHAR send_buff[WINDOW_SIZE]; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static ULONG ack_received = 0; +static ULONG urg_received = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static VOID tcp_urgent_data_callback(NX_TCP_SOCKET *socket_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_out_of_window_control_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + ack_received = 0; + urg_received = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Out of Window Control Packet Test....................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, WINDOW_SIZE, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write send_buff into the packet payload! */ + status = nx_packet_data_append(my_packet, send_buff, WINDOW_SIZE, &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Sleep one second to make sure server has replied ACK. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Setup the TCP packet process function pointer. */ + ip_0.nx_ip_tcp_packet_receive = tcp_packet_receive; + + /* Send out of window URG packet. */ + _nx_tcp_packet_send_control(&client_socket, NX_TCP_URG_BIT, client_socket.nx_tcp_socket_tx_sequence + WINDOW_SIZE, + client_socket.nx_tcp_socket_rx_sequence, 0, 0, NX_NULL); + + /* Sleep one second. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure server is still in established state. */ + if (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send out of window ACK packet. */ + _nx_tcp_packet_send_control(&client_socket, NX_TCP_ACK_BIT, client_socket.nx_tcp_socket_tx_sequence + WINDOW_SIZE, + client_socket.nx_tcp_socket_rx_sequence, 0, 0, NX_NULL); + + /* Sleep one second. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure server is still in established state. */ + if (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send out of window RST packet. */ + _nx_tcp_packet_send_control(&client_socket, NX_TCP_RST_BIT, client_socket.nx_tcp_socket_tx_sequence + WINDOW_SIZE, + client_socket.nx_tcp_socket_rx_sequence, 0, 0, NX_NULL); + + /* Sleep one second. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure server is closed. */ + if (server_socket.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if (error_counter || ack_received || (urg_received != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, WINDOW_SIZE, + tcp_urgent_data_callback, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static VOID tcp_urgent_data_callback(NX_TCP_SOCKET *socket_ptr) +{ + urg_received++; +} + + +static VOID tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; + + /* Get TCP header. */ + tcp_header_ptr = (NX_TCP_HEADER *) packet_ptr -> nx_packet_prepend_ptr; + + /* Swap word 3. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Whether it is an ACK packet. */ + if (tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + ack_received++; + } + + /* Swap word 3. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_out_of_window_control_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Out of Window Control Packet Test.....................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test.c new file mode 100644 index 00000000..7345ddad --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test.c @@ -0,0 +1,362 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +NX_PACKET *my_packet4; +NX_PACKET *my_packet23; +char *msg = MSG; +ULONG seq1, seq2; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 1............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet23, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 37 + Packet 2 contains bytes 38 - 75 + Packet 3 contains bytes 76 - 113 + Packet 4 contains bytes 76 - 85 + packet 23 contains bytes 38 - 113 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 38); + my_packet1 -> nx_packet_length = 38; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 38; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[38], 38); + my_packet2 -> nx_packet_length = 38; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 38; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[76], 38); + my_packet3 -> nx_packet_length = 38; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 38; + + memcpy(my_packet4 -> nx_packet_prepend_ptr, &msg[76], 10); + my_packet4 -> nx_packet_length = 10; + my_packet4 -> nx_packet_append_ptr = my_packet4 -> nx_packet_prepend_ptr + 10; + + memcpy(my_packet23 -> nx_packet_prepend_ptr, &msg[38], 76); + my_packet23 -> nx_packet_length = 76; + my_packet23 -> nx_packet_append_ptr = my_packet23 -> nx_packet_prepend_ptr + 76; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Update the seq number and send the 3rd one. */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + client_socket.nx_tcp_socket_tx_sequence += 38; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + seq2 = client_socket.nx_tcp_socket_tx_sequence; + + /* Update the seq number and send the 4th one. */ + client_socket.nx_tcp_socket_tx_sequence = seq1 + 38; + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + + /* Restore the Seq number for packet 2. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Restore the seq number for packet 23 */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + +#ifdef __PRODUCT_NETXDUO__ + /* Also reduce the outstanding byte count. */ + client_socket.nx_tcp_socket_tx_outstanding_bytes -= my_packet23 -> nx_packet_length; +#endif + status += nx_tcp_socket_send(&client_socket, my_packet23, NX_IP_PERIODIC_RATE); + + if (status) + { + error_counter++; + } + + if(client_socket.nx_tcp_socket_tx_sequence != seq2) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 114) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + +#ifndef NX_DISABLE_PACKET_INFO + /* Check packet pool state. */ + if(pool_0.nx_packet_pool_invalid_releases) + error_counter++; +#endif + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 1.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_10.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_10.c new file mode 100644 index 00000000..8364d98b --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_10.c @@ -0,0 +1,319 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_10_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *my_packet1; + NX_PACKET *my_packet2; + NX_PACKET *my_packet3; + NX_PACKET *my_packet4; + char *msg = MSG; + ULONG seq1; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 10............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 19 + Packet 2 contains bytes 60 - 79 + Packet 3 contains bytes 40 - 59 + packet 4 contains bytes 20 - 45 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[60], 20); + my_packet2 -> nx_packet_length = 20; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet3 -> nx_packet_length = 20; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet4 -> nx_packet_prepend_ptr, &msg[20], 26); + my_packet4 -> nx_packet_length = 26; + my_packet4 -> nx_packet_append_ptr = my_packet4 -> nx_packet_prepend_ptr + 26; + + /* Send the 1st one. */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Update the seq number and send the 3rd one. */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + client_socket.nx_tcp_socket_tx_sequence += 20; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Send the 2nd one. */ + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Send the 4th one. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + + if(status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 80) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + server_socket.nx_tcp_socket_rx_sequence = client_socket.nx_tcp_socket_tx_sequence; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_10_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 10............................N/A\n"); + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_11.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_11.c new file mode 100644 index 00000000..aa0831ad --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_11.c @@ -0,0 +1,335 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_11_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +NX_PACKET *my_packet4; +CHAR *msg = MSG; +ULONG seq1, seq2; +ULONG bytes_available; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 11............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + + /* Packet 1 contains bytes 60 - 79 + Packet 2 contains bytes 20 - 39 + Packet 3 contains bytes 40 - 59 + packet 4 contains bytes 0 - 29 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[60], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[20], 20); + my_packet2 -> nx_packet_length = 20; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet3 -> nx_packet_length = 20; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet4 -> nx_packet_prepend_ptr, &msg[0], 30); + my_packet4 -> nx_packet_length = 30; + my_packet4 -> nx_packet_append_ptr = my_packet4 -> nx_packet_prepend_ptr + 30; + + /* Send the 1st one. */ + client_socket.nx_tcp_socket_tx_sequence += 60; + seq1 = client_socket.nx_tcp_socket_tx_sequence; + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + seq2 = client_socket.nx_tcp_socket_tx_sequence; + + /* Get the socket bytes available. */ + status = nx_tcp_socket_bytes_available(&server_socket, &bytes_available); + if (status || (bytes_available != 0)) + error_counter++; + + /* Update the seq number and send the 2th one. */ + client_socket.nx_tcp_socket_tx_sequence = seq1 - 40; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Restore the Seq number for packet 3. */ + client_socket.nx_tcp_socket_tx_sequence = seq1 - 20; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Restore the seq number for packet 4. */ + client_socket.nx_tcp_socket_tx_sequence = seq1 - 60; + +#ifdef __PRODUCT_NETXDUO__ + /* Also reduce the outstanding byte count. */ + client_socket.nx_tcp_socket_tx_outstanding_bytes = 0; +#endif + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + client_socket.nx_tcp_socket_tx_sequence = seq1 + 20; + + if(status) + { + error_counter++; + } + + if(client_socket.nx_tcp_socket_tx_sequence != seq2) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* let thread0 run, so thread0 can send out out-of-order packets. */ + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 80) + error_counter++; + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_11_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 11............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_12.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_12.c new file mode 100644 index 00000000..26339452 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_12.c @@ -0,0 +1,347 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_12_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet1; + NX_PACKET *my_packet2; + NX_PACKET *my_packet3; + NX_PACKET *my_packet4; + char *msg = MSG; + ULONG seq1; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 12............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 19 + Packet 2 contains bytes 20 - 39 + Packet 3 contains bytes 40 - 59 + packet 4 contains bytes 30 - 49 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[20], 20); + my_packet2 -> nx_packet_length = 20; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet3 -> nx_packet_length = 20; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet4 -> nx_packet_prepend_ptr, &msg[30], 20); + my_packet4 -> nx_packet_length = 20; + my_packet4 -> nx_packet_append_ptr = my_packet4 -> nx_packet_prepend_ptr + 20; + + /* To avoid ACK loop. Drop the ACK from client to server. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_server; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Send the 2nd one */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Send the 3rd one */ + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Send the 4th one */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + client_socket.nx_tcp_socket_tx_sequence += 10; + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + + if(status) + { + error_counter++; + } + +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 60) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + server_socket.nx_tcp_socket_rx_sequence = client_socket.nx_tcp_socket_tx_sequence; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check whether server receives an ACK packet in establish state. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && + (server_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) && + (packet_ptr -> nx_packet_length == 20)) + { + nx_packet_release(packet_ptr); + return; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_12_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 12............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_13.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_13.c new file mode 100644 index 00000000..66c22476 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_13.c @@ -0,0 +1,332 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_13_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet1; + NX_PACKET *my_packet2; + NX_PACKET *my_packet3; + NX_PACKET *my_packet4; + NX_PACKET *my_packet5; + char *msg = MSG; + ULONG seq1; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 13............................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create 5 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet5, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 19 + Packet 2 contains bytes 40 - 59 + Packet 3 contains bytes 80 - 99 + packet 4 contains bytes 45 - 79 + packet 5 contains bytes 20 - 44 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet2 -> nx_packet_length = 20; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[80], 20); + my_packet3 -> nx_packet_length = 20; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet4 -> nx_packet_prepend_ptr, &msg[45], 35); + my_packet4 -> nx_packet_length = 35; + my_packet4 -> nx_packet_append_ptr = my_packet4 -> nx_packet_prepend_ptr + 35; + + memcpy(my_packet5 -> nx_packet_prepend_ptr, &msg[20], 25); + my_packet5 -> nx_packet_length = 25; + my_packet5 -> nx_packet_append_ptr = my_packet5 -> nx_packet_prepend_ptr + 25; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Send the 2nd one */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + client_socket.nx_tcp_socket_tx_sequence += 20; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Send the 3rd one */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + client_socket.nx_tcp_socket_tx_sequence += 60; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Send the 4th one */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + client_socket.nx_tcp_socket_tx_sequence += 25; + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + + /* Send the 5th one */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + status += nx_tcp_socket_send(&client_socket, my_packet5, NX_IP_PERIODIC_RATE); + client_socket.nx_tcp_socket_tx_sequence += 55; + + if(status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 100) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_13_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 13............................N/A\n"); + test_control_return(3); +} +#endif + diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_14.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_14.c new file mode 100644 index 00000000..6591bdf5 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_14.c @@ -0,0 +1,326 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "11122222333333344444444" + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_14_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +char *msg = MSG; +ULONG seq1, seq2; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 14............................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Fill in the packet with data. */ + /* The full message to send is: 11122222333333344444444 + Packet 1 sends: 111 + Packet 2 sends: 111222223333333 + Packet 3 sends: 22222333333344444444 */ + + status = nx_packet_data_append(my_packet1, &msg[0], 3, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet2, &msg[0], 15, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet3, &msg[3], 20, &pool_0, TX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Store tx_seq before sending packet1. */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Store tx_seq after sending packet1. */ + seq2 = client_socket.nx_tcp_socket_tx_sequence; + + /* Sleep 3 seconds to let remote send ACK. */ + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq1 to send packet2 with duplicate data. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq2 to send packet3. */ + client_socket.nx_tcp_socket_tx_sequence = seq2; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + if (status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(2); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != strlen(MSG)) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_14_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 14............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_15.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_15.c new file mode 100644 index 00000000..0556c80f --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_15.c @@ -0,0 +1,350 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "11122222333333344444444555" + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_15_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +NX_PACKET *my_packet4; +NX_PACKET *my_packet5; +char *msg = MSG; +ULONG seq1; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 15............................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet5, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Fill in the packet with data. */ + /* The full message to send is: 11122222333333344444444555 + Packet 1 sends: 111 + Packet 2 sends: 555 + Packet 3 sends: 111222223333333 + Packet 4 sends: 4444 + Packet 5 sends: 33444444 + */ + + status = nx_packet_data_append(my_packet1, &msg[0], 3, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet2, &msg[23], 3, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet3, &msg[0], 15, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet4, &msg[19], 4, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet5, &msg[13], 8, &pool_0, TX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Store tx_seq before sending packet1. */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Sleep 1 second to let remote send ACK. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq1+23 to send packet2 that is out of order. */ + client_socket.nx_tcp_socket_tx_sequence = seq1 + 23; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq1 to send packet3. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq1+19 to send packet4 that is out of order. */ + client_socket.nx_tcp_socket_tx_sequence = seq1 + 19; + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq1+13 to send packet5 that is out of order. */ + client_socket.nx_tcp_socket_tx_sequence = seq1 + 13; + status += nx_tcp_socket_send(&client_socket, my_packet5, NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq1+26 to fix tx_seq. */ + client_socket.nx_tcp_socket_tx_sequence = seq1 + 26; + + if (status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +ULONG recv_length = 0; +ULONG total_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(2); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while(1) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + break; + else + { + status = nx_packet_data_retrieve(packet_ptr, &rcv_buffer[total_length], &recv_length); + total_length += recv_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + tx_thread_relinquish(); + } + + if(total_length != strlen(MSG)) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, total_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_15_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 15............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_16.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_16.c new file mode 100644 index 00000000..feb3a93c --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_16.c @@ -0,0 +1,340 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG_LENGTH 1024 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG long_msg[MSG_LENGTH >> 2]; + + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_16_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status, i; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +ULONG seq1, seq2; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 16............................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 3000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Init long_msg. */ + for (i = 1; i <= (MSG_LENGTH >> 2); i++) + { + long_msg[i - 1] = i; + } + + /* Fill in the packet with data. */ + /* The full message to send is: 0x0100000002000000......00010000 + Packet 1 sends: 0x0100000002000000......40000000 + Packet 2 sends: 0x0100000002000000......C0000000 + Packet 3 sends: 0x4100000042000000......00010000 */ + + status = nx_packet_data_append(my_packet1, (VOID *)(&long_msg[0]), 0x100, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet2, (VOID *)(&long_msg[0]), 0x300, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet3, (VOID *)(&long_msg[64]), 0x300, &pool_0, TX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Store tx_seq before sending packet1. */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Sleep 3 seconds to let remote send ACK. */ + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + /* Store tx_seq after sending packet1. */ + seq2 = client_socket.nx_tcp_socket_tx_sequence; + + /* Set the tx_seq to seq1 to send packet2 that is duplicated. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq2 to send packet3. */ + client_socket.nx_tcp_socket_tx_sequence = seq2; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + if (status) + { + error_counter++; + } +} + +static char rcv_buffer[MSG_LENGTH]; +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +ULONG recv_length = 0; +ULONG total_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(2); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 2000, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while(1) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + break; + else + { + status = nx_packet_data_retrieve(packet_ptr, &rcv_buffer[total_length], &recv_length); + total_length += recv_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + } + + if(total_length != MSG_LENGTH) + error_counter++; + + if(memcmp(rcv_buffer, (void*)long_msg, total_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_16_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Overlapping Packet Test 16............................N/A\n"); + + test_control_return(3); + +} + +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_17.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_17.c new file mode 100644 index 00000000..82fed792 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_17.c @@ -0,0 +1,341 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define MSG_LENGTH 1024 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG long_msg[MSG_LENGTH >> 2]; + + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_17_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status, i; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +ULONG seq1; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 17............................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 3000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Init long_msg. */ + for (i = 1; i <= (MSG_LENGTH >> 2); i++) + { + long_msg[i - 1] = i; + } + + /* Fill in the packet with data. */ + /* The full message to send is: 0x0100000002000000......00010000 + Packet 1 sends: 0x0100000002000000......40000000 + Packet 2 sends: 0xC1000000C2000000......00010000 + Packet 3 sends: 0x0100000002000000......C0000000 */ + + status = nx_packet_data_append(my_packet1, (VOID *)(&long_msg[0]), 0x100, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet2, (VOID *)(&long_msg[192]), 0x100, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet3, (VOID *)(&long_msg[0]), 0x300, &pool_0, TX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Store tx_seq before sending packet1. */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Sleep 3 seconds to let remote send ACK. */ + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq1+0x300 to send packet2 that is out of order. */ + client_socket.nx_tcp_socket_tx_sequence = seq1 + 0x300; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq1 to send packet3. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq1+0x0400 to fix tx_seq. */ + client_socket.nx_tcp_socket_tx_sequence = seq1 + 0x0400; + + if (status) + { + error_counter++; + } +} + +static char rcv_buffer[MSG_LENGTH]; +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +ULONG recv_length = 0; +ULONG total_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(2); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 2000, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while(1) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + break; + else + { + status = nx_packet_data_retrieve(packet_ptr, &rcv_buffer[total_length], &recv_length); + total_length += recv_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + } + + if(total_length != MSG_LENGTH) + error_counter++; + + if(memcmp(rcv_buffer, (void*)long_msg, total_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_17_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Overlapping Packet Test 17............................N/A\n"); + + test_control_return(3); + +} + +#endif + diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_18.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_18.c new file mode 100644 index 00000000..04be4126 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_18.c @@ -0,0 +1,334 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "11122222333333344444444" + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_18_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +char *msg = MSG; +ULONG seq1, seq2; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 18............................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Fill in the packet with data. */ + /* The full message to send is: 11122222333333344444444 + Packet 1 sends: 111 + Packet 2 sends: 111222223333333 + Packet 3 sends: 22222333333344444444 */ + + status = nx_packet_data_append(my_packet1, &msg[0], 3, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet2, &msg[0], 15, &pool_0, TX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet3, &msg[3], 20, &pool_0, TX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Store tx_seq before sending packet1. */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Store tx_seq after sending packet1. */ + seq2 = client_socket.nx_tcp_socket_tx_sequence; + + /* Set the tx_seq to seq1 to send packet2 with duplicate data. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Set the tx_seq to seq2 to send packet3. */ + client_socket.nx_tcp_socket_tx_sequence = seq2; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + if (status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + +UINT status, actual_status; +NX_PACKET *packet_ptr; +ULONG recv_length = 0; +ULONG total_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, (ULONG *)&actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(2); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while(1) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + break; + else + { + status = nx_packet_data_retrieve(packet_ptr, &rcv_buffer[total_length], &recv_length); + total_length += recv_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + } + + if(total_length != strlen(MSG)) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, total_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_18_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Overlapping Packet Test 18............................N/A\n"); + + test_control_return(3); + +} + +#endif + diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_2.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_2.c new file mode 100644 index 00000000..0291eb91 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_2.c @@ -0,0 +1,339 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_2_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *my_packet1; + NX_PACKET *my_packet2; + NX_PACKET *my_packet3; + NX_PACKET *my_packet23; + char *msg = MSG; + ULONG seq1, seq2; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 2............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet23, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 37 + Packet 2 contains bytes 38 - 75 + Packet 3 contains bytes 76 - 113 + packet 23 contains bytes 37 - 112 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 38); + my_packet1 -> nx_packet_length = 38; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 38; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[38], 38); + my_packet2 -> nx_packet_length = 38; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 38; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[76], 38); + my_packet3 -> nx_packet_length = 38; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 38; + + memcpy(my_packet23 -> nx_packet_prepend_ptr, &msg[37], 76); + my_packet23 -> nx_packet_length = 76; + my_packet23 -> nx_packet_append_ptr = my_packet23 -> nx_packet_prepend_ptr + 76; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Update the seq number and send the 3rd one. */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + client_socket.nx_tcp_socket_tx_sequence += 38; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + seq2 = client_socket.nx_tcp_socket_tx_sequence; + + /* Restore the Seq num for packet 2. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Restore the seq num for packet 23 */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + + status += nx_tcp_socket_send(&client_socket, my_packet23, NX_IP_PERIODIC_RATE); + + if (status) + { + error_counter++; + } + + if(client_socket.nx_tcp_socket_tx_sequence != (seq2)) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 114) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_2_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 2.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_3.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_3.c new file mode 100644 index 00000000..a9e3d780 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_3.c @@ -0,0 +1,348 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_3_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *my_packet1; + NX_PACKET *my_packet2; + NX_PACKET *my_packet3; + NX_PACKET *my_packet23; + char *msg = MSG; + ULONG seq1, seq2; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 3............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet23, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 37 + Packet 2 contains bytes 38 - 75 + Packet 3 contains bytes 76 - 113 + packet 23 contains bytes 37 - 113 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 38); + my_packet1 -> nx_packet_length = 38; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 38; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[38], 38); + my_packet2 -> nx_packet_length = 38; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 38; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[76], 38); + my_packet3 -> nx_packet_length = 38; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 38; + + memcpy(my_packet23 -> nx_packet_prepend_ptr, &msg[37], 77); + my_packet23 -> nx_packet_length = 76; + my_packet23 -> nx_packet_append_ptr = my_packet23 -> nx_packet_prepend_ptr + 76; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Update the seq number and send the 3rd one. */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + client_socket.nx_tcp_socket_tx_sequence += 38; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + seq2 = client_socket.nx_tcp_socket_tx_sequence; + + /* Restore the Seq number for packet 2. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Restore the seq number for packet 23 */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + +#ifdef __PRODUCT_NETXDUO__ + /* Also reduce the outstanding byte count. */ + client_socket.nx_tcp_socket_tx_outstanding_bytes -= my_packet23 -> nx_packet_length; +#endif + status += nx_tcp_socket_send(&client_socket, my_packet23, NX_IP_PERIODIC_RATE); + + if (status) + { + error_counter++; + } + + if(client_socket.nx_tcp_socket_tx_sequence != seq2) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + /* let thread0 run, so thread0 can send out out-of-order packets. */ +#if 0 + tx_thread_relinquish(); +#endif + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if (recv_length != 114) + error_counter++; + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_3_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 3.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_4.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_4.c new file mode 100644 index 00000000..8279c702 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_4.c @@ -0,0 +1,360 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_4_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet1; + NX_PACKET *my_packet2; + NX_PACKET *my_packet3; + NX_PACKET *my_packet4; + char *msg = MSG; + ULONG seq1, seq2; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 4............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 19 + Packet 2 contains bytes 20 - 39 + Packet 3 contains bytes 40 - 59 + packet 4 contains bytes 20 - 39 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[20], 20); + my_packet2 -> nx_packet_length = 20; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet3 -> nx_packet_length = 20; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet4 -> nx_packet_prepend_ptr, &msg[20], 20); + my_packet4 -> nx_packet_length = 20; + my_packet4 -> nx_packet_append_ptr = my_packet4 -> nx_packet_prepend_ptr + 20; + + /* To avoid ACK loop. Drop the ACK from client to server. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_server; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + seq1 = client_socket.nx_tcp_socket_tx_sequence; + + /* Send the packet2 */ + status = nx_tcp_socket_send(&client_socket,my_packet2, NX_IP_PERIODIC_RATE); + seq2 = client_socket.nx_tcp_socket_tx_sequence; + + /* Send the packet3 */ + status = nx_tcp_socket_send(&client_socket,my_packet3, NX_IP_PERIODIC_RATE); + + /* Restore the Seq number for packet 4 */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + +#ifdef __PRODUCT_NETXDUO__ + if(client_socket.nx_tcp_socket_tx_outstanding_bytes > my_packet4 -> nx_packet_length) + { + /* Also reduce the outstanding byte count. */ + client_socket.nx_tcp_socket_tx_outstanding_bytes -= my_packet4 -> nx_packet_length; + } +#endif + /* Send the packet4 */ + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + + if(status) + { +#if 0 + printf("thread_0: tcp_socket_send error, 0x%x\n", status); +#endif + error_counter++; + } + + if(client_socket.nx_tcp_socket_tx_sequence != seq2) + { +#if 0 + printf("thread_0: tcp_tx_seq != seq2 error\n"); +#endif + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 60) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check whether server receives an ACK packet in establish state. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && + (server_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) && + (packet_ptr -> nx_packet_length == 20)) + { + nx_packet_release(packet_ptr); + return; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_4_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 4.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_5.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_5.c new file mode 100644 index 00000000..09fda62c --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_5.c @@ -0,0 +1,348 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_5_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet1; + NX_PACKET *my_packet2; + NX_PACKET *my_packet3; + NX_PACKET *my_packet123; + NX_PACKET *my_packet23; + char *msg = MSG; + ULONG seq1; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 5............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create 5 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet123, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet23, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 19 + Packet 2 contains bytes 40 - 59 + Packet 3 contains bytes 80 - 99 + packet 123 contains bytes 20 - 59 + packet 23 contains bytes 60 - 89 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet2 -> nx_packet_length = 20; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[80], 20); + my_packet3 -> nx_packet_length = 20; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet123 -> nx_packet_prepend_ptr, &msg[20], 40); + my_packet123 -> nx_packet_length = 40; + my_packet123 -> nx_packet_append_ptr = my_packet123 -> nx_packet_prepend_ptr + 40; + + memcpy(my_packet23 -> nx_packet_prepend_ptr, &msg[60], 30); + my_packet23 -> nx_packet_length = 30; + my_packet23 -> nx_packet_append_ptr = my_packet23 -> nx_packet_prepend_ptr + 30; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Update the seq number and send the 3rd one. */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + client_socket.nx_tcp_socket_tx_sequence += 60; + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Restore the Seq number for packet 2. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + client_socket.nx_tcp_socket_tx_sequence += 20; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Restore the seq number for packet 123 */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + + /* Also reduce the outstanding byte count. */ + client_socket.nx_tcp_socket_tx_outstanding_bytes -= 20; + status += nx_tcp_socket_send(&client_socket, my_packet123, NX_IP_PERIODIC_RATE); + + /* Restore the seq number for packet 23 */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + client_socket.nx_tcp_socket_tx_sequence += 40; + +#ifdef __PRODUCT_NETXDUO__ + /* Also reduce the outstanding byte count. */ + client_socket.nx_tcp_socket_tx_outstanding_bytes -= 10; +#endif + status += nx_tcp_socket_send(&client_socket, my_packet23, NX_IP_PERIODIC_RATE); + client_socket.nx_tcp_socket_tx_sequence += 10; + + if (status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 100) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_5_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 5.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_6.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_6.c new file mode 100644 index 00000000..db57b018 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_6.c @@ -0,0 +1,328 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_6_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet1; + NX_PACKET *my_packet2; + NX_PACKET *my_packet3; + NX_PACKET *my_packet4; + char *msg = MSG; + ULONG seq1, seq2; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 6............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create 4 packets */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if (status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 19 + Packet 2 contains bytes 20 - 39 + Packet 3 contains bytes 40 - 59 + packet 4 contains bytes 40 - 59 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[20], 20); + my_packet2 -> nx_packet_length = 20; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet3 -> nx_packet_length = 20; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet4 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet4 -> nx_packet_length = 20; + my_packet4 -> nx_packet_append_ptr = my_packet4 -> nx_packet_prepend_ptr + 20; + + /* Send the 1st one */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Send the packet2 */ + status = nx_tcp_socket_send(&client_socket,my_packet2, NX_IP_PERIODIC_RATE); + seq1 = client_socket.nx_tcp_socket_tx_sequence; + + /* Send the packet3 */ + status = nx_tcp_socket_send(&client_socket,my_packet3, NX_IP_PERIODIC_RATE); + seq2 = client_socket.nx_tcp_socket_tx_sequence; + + /* Restore the Seq num for packet 4 */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + +#ifdef __PRODUCT_NETXDUO__ + if(client_socket.nx_tcp_socket_tx_outstanding_bytes > my_packet4 -> nx_packet_length) + { + /* Also reduce the outstanding byte count. */ + client_socket.nx_tcp_socket_tx_outstanding_bytes -= my_packet4 -> nx_packet_length; + } +#endif + + /* Send the packet4 */ + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + + if(status) + { + error_counter++; + } + + if(client_socket.nx_tcp_socket_tx_sequence != seq2) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 60) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_6_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 6.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_7.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_7.c new file mode 100644 index 00000000..5d70c601 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_7.c @@ -0,0 +1,328 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "----------abcdefgh20----------ABCDEFGH40----------klmnopqr60----------KLMNOPQR80----------" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +extern ULONG packet_gather; + +/* Define thread prototypes. */ +extern void (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_7_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet1; +NX_PACKET *my_packet2; +NX_PACKET *my_packet3; +NX_PACKET *my_packet4; +NX_PACKET *my_packet0; +char *msg = MSG; +ULONG seq1; +UINT old_threshold; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 7............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create 5 packets */ + status = nx_packet_allocate(&pool_0, &my_packet0, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 0 contains bytes 0 - 19 + Packet 1 contains bytes 20 - 39 + Packet 2 contains bytes 40 - 59 + Packet 3 contains bytes 60 - 79 + Packet 4 contains bytes 0 - 19 */ + + memcpy(my_packet0 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet0 -> nx_packet_length = 20; + my_packet0 -> nx_packet_append_ptr = my_packet0 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[20], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet2 -> nx_packet_length = 20; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[60], 20); + my_packet3 -> nx_packet_length = 20; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet4 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet4 -> nx_packet_length = 20; + my_packet4 -> nx_packet_append_ptr = my_packet4 -> nx_packet_prepend_ptr + 20; + + /* Disable thread switch by IP thread. */ + tx_thread_preemption_change(tx_thread_identify(), 0, &old_threshold); + + seq1 = client_socket.nx_tcp_socket_tx_sequence; + + /* Send the my_packet0 */ + status = nx_tcp_socket_send(&client_socket, my_packet0, NX_IP_PERIODIC_RATE); + + /* send the my_packet2. */ + client_socket.nx_tcp_socket_tx_sequence += 20; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Restore the Seq number for my_packet3. */ + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* send the my_packet1. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + client_socket.nx_tcp_socket_tx_sequence += 20; + status += nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Restore the seq number for packet 4 */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + +#ifdef __PRODUCT_NETXDUO__ + /* Also reduce the outstanding byte count. */ + client_socket.nx_tcp_socket_tx_outstanding_bytes -= 20; +#endif + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + + if(status) + { + error_counter++; + } + + /* Restore the transmit sequence. */ + client_socket.nx_tcp_socket_tx_sequence += 60; + + /* Restore priority. */ + tx_thread_preemption_change(tx_thread_identify(), old_threshold, &old_threshold); +} + +static char rcv_buffer[200]; + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +ULONG recv_length = 0; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 80) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_7_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 7.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_8.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_8.c new file mode 100644 index 00000000..59fed687 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_8.c @@ -0,0 +1,319 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "1---------abcdefgh203---------ABCDEFGH405---------klmnopqr607---------KLMNOPQR809---------" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +extern ULONG packet_gather; + +/* Define thread prototypes. */ +extern void (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_8_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet1; + NX_PACKET *my_packet2; + NX_PACKET *my_packet3; + NX_PACKET *my_packet4; + char *msg = MSG; + ULONG seq1; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 8............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create 4 packets, packet 1-3 contains 3 segments of the outgoing message. Packet 4 contains a retran overlapping 1-3. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 19 + Packet 2 contains bytes 20 - 39 + Packet 3 contains bytes 40 - 59 + packet 4 contains bytes 0 - 59 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[20], 20); + my_packet2 -> nx_packet_length = 20; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet3 -> nx_packet_length = 20; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet4 -> nx_packet_prepend_ptr, &msg[0], 60); + my_packet4 -> nx_packet_length = 60; + my_packet4 -> nx_packet_append_ptr = my_packet4 -> nx_packet_prepend_ptr + 60; + + /* Send the my_packet3 */ + seq1 = client_socket.nx_tcp_socket_tx_sequence; + client_socket.nx_tcp_socket_tx_sequence += 40; + status = nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Update the seq number and send the my_packet1. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + status += nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Restore the Seq number for packet 2. */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + client_socket.nx_tcp_socket_tx_sequence += 20; + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Restore the seq number for packet 4 */ + client_socket.nx_tcp_socket_tx_sequence = seq1; + +#ifdef __PRODUCT_NETXDUO__ + /* Also reduce the outstanding byte count. */ + client_socket.nx_tcp_socket_tx_outstanding_bytes -= my_packet4 -> nx_packet_length; +#endif + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + + if(status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; + +static void thread_1_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 60) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_8_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 8.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_9.c b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_9.c new file mode 100644 index 00000000..7cd1e271 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_overlapping_packet_test_9.c @@ -0,0 +1,337 @@ +/* This NetX test concentrates on overlapping TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_TCP_ACK_EVERY_N_PACKETS) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +extern ULONG packet_gather; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_9_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + NX_PACKET *my_packet1; + NX_PACKET *my_packet2; + NX_PACKET *my_packet3; + NX_PACKET *my_packet4; + char *msg = MSG; + + /* Print out test information banner. */ + printf("NetX Test: TCP Overlapping Packet Test 9............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Create 4 packets, packet 1-3 contains 3 segments of the outgoing message. Packet 4 contains a retran overlapping 2. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet3, NX_TCP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_allocate(&pool_0, &my_packet4, NX_TCP_PACKET, NX_WAIT_FOREVER); + + if(status) + error_counter++; + + /* Fill in the packet with data. */ + /* Packet 1 contains bytes 0 - 19 + Packet 2 contains bytes 20 - 39 + Packet 3 contains bytes 40 - 59 + packet 4 contains bytes 25 - 30 */ + + memcpy(my_packet1 -> nx_packet_prepend_ptr, &msg[0], 20); + my_packet1 -> nx_packet_length = 20; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet2 -> nx_packet_prepend_ptr, &msg[20], 20); + my_packet2 -> nx_packet_length = 20; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet3 -> nx_packet_prepend_ptr, &msg[40], 20); + my_packet3 -> nx_packet_length = 20; + my_packet3 -> nx_packet_append_ptr = my_packet3 -> nx_packet_prepend_ptr + 20; + + memcpy(my_packet4 -> nx_packet_prepend_ptr, &msg[25], 6); + my_packet4 -> nx_packet_length = 6; + my_packet4 -> nx_packet_append_ptr = my_packet4 -> nx_packet_prepend_ptr + 6; + + /* To avoid ACK loop. Drop the ACK from client to server. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive_server; + + /* Send the 1st one. */ + status = nx_tcp_socket_send(&client_socket, my_packet1, NX_IP_PERIODIC_RATE); + + /* Send the 2nd one. */ + status += nx_tcp_socket_send(&client_socket, my_packet2, NX_IP_PERIODIC_RATE); + + /* Send the 3rd one. */ + status += nx_tcp_socket_send(&client_socket, my_packet3, NX_IP_PERIODIC_RATE); + + /* Update the seq number and send the 4th one. */ + client_socket.nx_tcp_socket_tx_sequence -= 35; + + /* Send the 4th one. */ + status += nx_tcp_socket_send(&client_socket, my_packet4, NX_IP_PERIODIC_RATE); + + if(status) + { + error_counter++; + } +} + +static char rcv_buffer[200]; +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + ULONG recv_length = 0; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 60) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void my_tcp_packet_receive_server(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + NX_TCP_HEADER *header_ptr; + + header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + + /* Check whether server receives an ACK packet in establish state. */ + if((header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) && + (server_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) && + (packet_ptr -> nx_packet_length == 20)) + { + nx_packet_release(packet_ptr); + return; + } + + NX_CHANGE_ULONG_ENDIAN(header_ptr -> nx_tcp_header_word_3); + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_overlapping_packet_test_9_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Overlapping Packet Test 9.............................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_packet_leak_test.c b/test/regression/netxduo_test/netx_tcp_packet_leak_test.c new file mode 100644 index 00000000..bd147ccb --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_packet_leak_test.c @@ -0,0 +1,345 @@ +/* This NetX test concentrates no packet leak after socket is deleted. */ + +#include "nx_api.h" +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_packet_leak_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 4096); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFF0000UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 2); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Packet Leak Test......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create the client socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Connect to server. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Prepare a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check for error */ + if (status) + { + error_counter++; + } + + status = nx_packet_data_append(packet_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + nx_packet_release(packet_ptr); + error_counter++; + } + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Disconnect from server. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unbind the client socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Delete the client socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Verify no packet leak. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + error_counter++; + } + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Create the server socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Listen the socket. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Accept connection from client. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Prepare a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check for error */ + if (status) + { + error_counter++; + } + + status = nx_packet_data_append(packet_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + nx_packet_release(packet_ptr); + error_counter++; + } + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for error */ + if (status) + { + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Disconnect from client. */ + status = nx_tcp_socket_disconnect(&server_socket, 5); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Delete the client socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error */ + if (status) + { + error_counter++; + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_packet_leak_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Packet Leak Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_packet_receive_function_test.c b/test/regression/netxduo_test/netx_tcp_packet_receive_function_test.c new file mode 100644 index 00000000..1a4d5814 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_packet_receive_function_test.c @@ -0,0 +1,451 @@ +/* This NetX test case test _nx_tcp_packet_receive function with non standard operation . */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UINT packet_count = 0; + +static NX_PACKET *my_packet1; +static NX_PACKET *my_packet2; +static NX_PACKET *copy_packet_1; +static NX_PACKET *copy_packet_2; +static NX_PACKET *copy_packet_3; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +static void packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_packet_receive_function_test_application_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = _nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += _nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Packet Receive Function Test.........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 600, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + /* Determine if the timeout error occurred. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1,2,3,5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet1, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check for error. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + memcpy(my_packet1 -> nx_packet_prepend_ptr,"ABCDEFGHIJKLMNOPQRSTUVWXYZ12", 28); + my_packet1 -> nx_packet_length = 28; + my_packet1 -> nx_packet_append_ptr = my_packet1 -> nx_packet_prepend_ptr + 28; + + /* Send the packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet1, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Point to new receive function */ + ip_1.nx_ip_tcp_packet_receive = packet_receive; + + /* Allocate a new packet. */ + status = nx_packet_allocate(&pool_0, &my_packet2, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check for error. */ + if((status != NX_SUCCESS)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + memcpy(my_packet2 -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ12", 28); + my_packet2 -> nx_packet_length = 28; + my_packet2 -> nx_packet_append_ptr = my_packet2 -> nx_packet_prepend_ptr + 28; + + /* Send the packet. */ + status = nx_tcp_socket_send(&client_socket, my_packet2, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; +ULONG actual_status; +NX_PACKET *packet_ptr; +#ifndef NX_DISABLE_RX_SIZE_CHECKING +NX_PACKET *invalid_packet; +#endif + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status != NX_SUCCESS) + { + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 650, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + if(status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + +#ifndef NX_DISABLE_RX_SIZE_CHECKING + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &invalid_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check for error. */ + if((status != NX_SUCCESS)) + { + error_counter++; + } + + /* Set the packet length with invalid value. */ + memcpy(invalid_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ12", 28); + invalid_packet -> nx_packet_length = sizeof(NX_TCP_HEADER) - 1; + invalid_packet -> nx_packet_append_ptr = invalid_packet -> nx_packet_prepend_ptr + invalid_packet -> nx_packet_length; + + /* Directly call _nx_tcp_packet_receive invalid packet. */ + _nx_tcp_packet_receive(&ip_1, invalid_packet); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status == NX_SUCCESS) + { + error_counter++; + } +#endif + + /* Obtain the IP internal mutex before processing the IP event. */ + tx_mutex_get(&(ip_1.nx_ip_protection), TX_WAIT_FOREVER); + + /* Directly call _nx_tcp_packet_receive valid packet. */ + _nx_tcp_packet_receive(&ip_1, copy_packet_1); + + /* Directly call _nx_tcp_packet_receive valid packet. */ + _nx_tcp_packet_receive(&ip_1, copy_packet_2); + + /* Directly call _nx_tcp_packet_receive to receive packet with incorrect checksum. */ + _nx_tcp_packet_receive(&ip_1, copy_packet_3); + + /* Release the IP internal mutex. */ + tx_mutex_put(&(ip_1.nx_ip_protection)); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if(socket != &server_socket) + error_counter++; +} + +static void packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + UINT status; + + /* Only store the packet one time. */ + if (packet_count == 0) + { + + /* Update the packet prepend and length to include the IP header. */ + packet_ptr -> nx_packet_prepend_ptr -= 20; + packet_ptr -> nx_packet_length += 20; + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_1, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet prepend and length. */ + copy_packet_1 -> nx_packet_prepend_ptr += 20; + copy_packet_1 -> nx_packet_length -= 20; + } + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_2, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet prepend and length. */ + copy_packet_2 -> nx_packet_prepend_ptr += 20; + copy_packet_2 -> nx_packet_length -= 20; + } + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet_3, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet prepend and length. */ + copy_packet_3 -> nx_packet_prepend_ptr += 20; + copy_packet_3 -> nx_packet_length -= 20; + + /* Clear the checksum field. */ + *(copy_packet_3 -> nx_packet_prepend_ptr + 16) = 0; + *(copy_packet_3 -> nx_packet_prepend_ptr + 17) = 0; + } + + /* Update the packet count. */ + packet_count ++; + } + + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Stop the process. */ + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_packet_receive_function_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Packet Receive Function Test..........................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_queue_depth_notify_test.c b/test/regression/netxduo_test/netx_tcp_queue_depth_notify_test.c new file mode 100644 index 00000000..03397fa8 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_queue_depth_notify_test.c @@ -0,0 +1,359 @@ +/* This test cases verify that tcp queue depth nofity works. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_ENABLE_TCP_QUEUE_DEPTH_UPDATE_NOTIFY) || !defined(__PRODUCT_NETXDUO__) || defined(NX_DISABLE_IPV4) +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_queue_depth_nofity_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP queue depth notify test...............................N/A\n"); + test_control_return(3); +} +#else +#define DEMO_STACK_SIZE 2048 + +#define MSG "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UINT op; +static UCHAR queue_depth_notify_called; +static TX_SEMAPHORE sema_0; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void my_queue_depth_notify(NX_TCP_SOCKET *socket_ptr); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_queue_depth_nofity_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + op = NX_RAMDRIVER_OP_BYPASS; + queue_depth_notify_called = NX_FALSE; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + + /* Create semaphore. */ + status = tx_semaphore_create(&sema_0, "Semaphore 0", 0); +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status, i; +ULONG actual_status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: TCP queue depth notify test..............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Configure max_queue_depth to 2. */ + nx_tcp_socket_transmit_configure(&server_socket, 2, _nx_tcp_transmit_timer_rate, NX_TCP_MAXIMUM_RETRIES, NX_TCP_RETRY_SHIFT); + + /* Set callback function. */ + status = nx_tcp_socket_queue_depth_notify_set(&server_socket, my_queue_depth_notify); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_socket_queue_depth_notify_set(&server_socket, my_queue_depth_notify); + + /* Check for error. */ + if(status) + error_counter++; + + advanced_packet_process_callback = my_packet_process; + + for(i = 0; i < 3; i++) + { + if(i == 0) + { + + /* Drop the first packet. */ + op = NX_RAMDRIVER_OP_DROP; + } + else + { + + /* Bypass the following packts. */ + op = NX_RAMDRIVER_OP_BYPASS; + } + + /* Allocate packets */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + status = nx_packet_data_append(my_packet, MSG, 20, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Send the packet. */ + status = nx_tcp_socket_send(&server_socket, my_packet, 0); + + /* Check status. */ + if(status) + { + + /* Error on send! */ + if (status == NX_TX_QUEUE_DEPTH) + { + if(tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE)) + error_counter++; + else + i--; + } + else + error_counter++; + + nx_packet_release(my_packet); + } + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unaccepted the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check for error. */ + if(status) + error_counter++; +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + while(!nx_tcp_socket_receive(&client_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE)) + nx_packet_release(my_packet); + + /* Call disconnect to send a FIN. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if(status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if(status) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter || (queue_depth_notify_called == NX_FALSE)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + *operation_ptr = op; + + return NX_TRUE; +} + +VOID my_queue_depth_notify(NX_TCP_SOCKET *socket_ptr) +{ + queue_depth_notify_called = NX_TRUE; + tx_semaphore_put(&sema_0); + return; +} + +#endif diff --git a/test/regression/netxduo_test/netx_tcp_race_condition_test.c b/test/regression/netxduo_test/netx_tcp_race_condition_test.c new file mode 100644 index 00000000..a90d2121 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_race_condition_test.c @@ -0,0 +1,304 @@ +/* This NetX test concentrates when thread is suspended on send, the disconnect call will resume the sending thread. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "tx_thread.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_ENABLE_PACKET_DEBUG_INFO) && !defined(NX_ENABLE_INTERFACE_CAPABILITY) && !defined(NX_IPSEC_ENABLE) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_test; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static UCHAR send_buffer[20]; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_test_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static UINT send_flag = NX_FALSE; + +TX_THREAD *_tx_thread_identify(VOID) +{ + +TX_THREAD *thread_ptr; + +TX_INTERRUPT_SAVE_AREA + + + /* Disable interrupts to put the timer on the created list. */ + TX_DISABLE + + /* Log this kernel call. */ + TX_EL_THREAD_IDENTIFY_INSERT + + /* Pickup thread pointer. */ + TX_THREAD_GET_CURRENT(thread_ptr); + + /* Restore interrupts. */ + TX_RESTORE + + if (thread_ptr == &thread_0) + { + + if (send_flag) + { + send_flag = NX_FALSE; + tx_thread_resume(&thread_test); + } + } + + /* Return the current thread pointer. */ + return(thread_ptr); +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_race_condition_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_test, "thread test", thread_test_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 15360); + pointer = pointer + 15360; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + +/* Define the test threads. */ +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Race Condition Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buffer, sizeof(send_buffer), &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + send_flag = NX_TRUE; + status = nx_tcp_socket_send(&client_socket, my_packet, NX_NO_WAIT); + if (status != NX_SUCCESS) + { + nx_packet_release(my_packet); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the test threads. */ +static void thread_test_entry(ULONG thread_input) +{ + nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect the server socket. */ + nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_race_condition_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Race Condition Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_race_condition_test2.c b/test/regression/netxduo_test/netx_tcp_race_condition_test2.c new file mode 100644 index 00000000..945b280e --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_race_condition_test2.c @@ -0,0 +1,383 @@ +/* This NetX test concentrates when one thread is sending data, another thread disconnect the socket. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "tx_thread.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_test; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static UCHAR send_buffer[200]; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_test_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static NX_PACKET *test_packet[20]; +static UINT test_packet_count; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_race_condition_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_test, "thread test", thread_test_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 15360); + pointer = pointer + 15360; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + +/* Define the test threads. */ +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Race Condition Test 2................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buffer, 200, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + for (test_packet_count = 0; test_packet_count < 20; test_packet_count++) + { + status = nx_packet_allocate(&pool_0, &test_packet[test_packet_count], NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + if (status) + { + break; + } + } + + /* Cover nx_tcp_socket_send_internal.c + [+ -] line 837 if (preempted == NX_TRUE) */ + tx_thread_resume(&thread_test); + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + nx_packet_release(my_packet); + } + else + { + error_counter++; + } + + tx_thread_resume(&thread_1); + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buffer, 100, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Window will be zero. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buffer, 20, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + status = nx_tcp_socket_send(&client_socket, my_packet, NX_NO_WAIT); + if (status == NX_SUCCESS) + { + error_counter++; + } + + /* Cover nx_tcp_socket_send_internal.c + [+ -] line 1072 if (socket_ptr -> nx_tcp_socket_zero_window_probe_has_data == NX_FALSE) */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_NO_WAIT); + if (status == NX_SUCCESS) + { + error_counter++; + } + + /* Cover nx_tcp_socket_send_internal.c + [+ -] line 846 if (send_packet != packet_ptr) */ + tx_thread_resume(&thread_test); + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + nx_packet_release(my_packet); + } + else + { + error_counter++; + } + + tx_thread_resume(&thread_1); + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the test threads. */ +static void thread_test_entry(ULONG thread_input) +{ +UINT i; +UINT status; +NX_PACKET *packet_ptr; + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + for (i = 0; i < test_packet_count; i++) + { + nx_packet_release(test_packet[i]); + } + + test_packet_count = 0; + + nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + tx_thread_suspend(&thread_test); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + } + else + { + nx_packet_release(packet_ptr); + } + + nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +UINT i; + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + for (i = 0 ; i < 2; i++) + { + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + tx_thread_suspend(&thread_1); + + /* Disconnect the server socket. */ + nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + } + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_race_condition_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Race Condition Test 2.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_receive_cleanup_test.c b/test/regression/netxduo_test/netx_tcp_receive_cleanup_test.c new file mode 100644 index 00000000..15c4180f --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_receive_cleanup_test.c @@ -0,0 +1,261 @@ +/* This NetX test concentrates on the TCP Socket Receive Cleanup operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_receive_cleanup_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Recieve Cleanup Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the client_socket port to 12. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_NO_WAIT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket.nx_tcp_socket_receive_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (server_socket.nx_tcp_socket_receive_suspended_count != 1) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NO_PACKET) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket.nx_tcp_socket_receive_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (server_socket.nx_tcp_socket_receive_suspended_count != 0) + error_counter++; + + /* Check the error counter. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket.nx_tcp_socket_receive_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (server_socket.nx_tcp_socket_receive_suspended_count != 0) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NO_PACKET) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket.nx_tcp_socket_receive_suspended_count != 0) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (server_socket.nx_tcp_socket_receive_suspended_count != 1) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_receive_cleanup_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Recieve Cleanup Test..................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_receive_under_interface_detach_test.c b/test/regression/netxduo_test/netx_tcp_receive_under_interface_detach_test.c new file mode 100644 index 00000000..2d2246c6 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_receive_under_interface_detach_test.c @@ -0,0 +1,265 @@ +/* This NetX test concentrates on the TCP Socket connect reset operation under interface deatch(tested receive suspension list). */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static TX_THREAD ntest_2; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ntest_2_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_2_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_receive_under_interface_detach_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_2, "thread 2", ntest_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Set the second interface. */ + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1, "Second Interface", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, _nx_ram_network_driver_256); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Receive Under Interface Detach Test..................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the client_socket port to 12. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_NO_WAIT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(2, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Check the error counter. */ + if ((error_counter) || (ntest_2_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Resume the thread 2. */ + tx_thread_resume(&ntest_2); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status == NX_SUCCESS) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_2_entry(ULONG thread_input) +{ + +UINT status; + + /* Update the ntest_2_counter. */ + ntest_2_counter++; + + /* Check the TCP socket receive suspended count. */ + if (server_socket.nx_tcp_socket_receive_suspension_list == NX_NULL) + error_counter++; + + /* Detach the second interface for IP instance 2. */ + status = nx_ip_interface_detach(&ip_1, 1); + + /* Check the status. */ + if (status) + error_counter++; + + /* Check the TCP socket receive suspended count. */ + if (server_socket.nx_tcp_socket_receive_suspension_list != NX_NULL) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_receive_under_interface_detach_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Receive Under Interface Detach Test...................N/A\n"); + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_receive_under_interface_detach_test2.c b/test/regression/netxduo_test/netx_tcp_receive_under_interface_detach_test2.c new file mode 100644 index 00000000..c918ab62 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_receive_under_interface_detach_test2.c @@ -0,0 +1,281 @@ +/* This NetX test concentrates on the TCP Socket connect reset operation under interface deatch(tested receive queue count). */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static TX_THREAD ntest_2; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ntest_2_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_2_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_receive_under_interface_detach_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_2, "thread 2", ntest_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Set the second interface. */ + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1, "Second Interface", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, _nx_ram_network_driver_256); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Receive Under Interface Detach Test2.................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the client_socket port to 12. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_NO_WAIT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(2, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Resume the thread 2. */ + tx_thread_resume(&ntest_2); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! This packe should not be sent. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + } + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Check the error counter. */ + if ((error_counter) || (ntest_2_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_2_entry(ULONG thread_input) +{ + +UINT status; + + /* Update the ntest_2_counter. */ + ntest_2_counter++; + + /* Check the TCP socket receive queue count. */ + if (server_socket.nx_tcp_socket_receive_queue_count != 1) + error_counter++; + + /* Detach the second interface for IP instance 2. */ + status = nx_ip_interface_detach(&ip_1, 1); + + /* Check the status. */ + if (status) + error_counter++; + + /* Check the TCP socket receive queue count. */ + if (server_socket.nx_tcp_socket_receive_queue_count != 1) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_receive_under_interface_detach_test2_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Receive Under Interface Detach Test2..................N/A\n"); + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_reset_during_send_test.c b/test/regression/netxduo_test/netx_tcp_reset_during_send_test.c new file mode 100644 index 00000000..c1e5aef4 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_reset_during_send_test.c @@ -0,0 +1,275 @@ +/* This NetX test concentrates on sending TCP packets while socket is reset by peer. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_RESET_DISCONNECT) &&!defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +static UCHAR pool_area_0[20480]; +static UCHAR pool_area_1[20480]; + +static CHAR send_buff[3000]; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_reset_during_send_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create two packet pools. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pool_area_0, sizeof(pool_area_0)); + status += nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 256, pool_area_1, sizeof(pool_area_1)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Reset During Send Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE << 1); + if (status != NX_NOT_CONNECTED) + { + error_counter++; + nx_packet_release(my_packet); + } + else if (my_packet -> nx_packet_length == sizeof(send_buff)) + { + + /* Partial data should be sent but not. */ + error_counter++; + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Sleep one second. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE); + + if (status != NX_SUCCESS) + error_counter++; + else + nx_packet_release(packet_ptr); + + /* Reset the connection. */ + nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_reset_during_send_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Multiple Send Test....................................N/A\n"); + + test_control_return(3); + +} +#endif /* FEATURE_NX_IPV6 */ diff --git a/test/regression/netxduo_test/netx_tcp_retransmit_test.c b/test/regression/netxduo_test/netx_tcp_retransmit_test.c new file mode 100644 index 00000000..ccba24f4 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_retransmit_test.c @@ -0,0 +1,334 @@ +/* This case tests two TCP segments are sent but the first one is dropped. The peer can receive all segments. */ + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#ifdef __PRODUCT_NETXDUO__ +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static ULONG drop_packet; +static UCHAR pool_area[20480]; +static UCHAR send_buffer[3000]; +static UCHAR recv_buffer[3000]; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +#endif /* FEATURE_NX_IPV6 */ + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_retransmit_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + drop_packet = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pool_area, sizeof(pool_area)); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + +#ifndef NX_DISABLE_IPV4 + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; +#endif + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + if(status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: TCP Retransmit Test......................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Initialize the buffer. */ + for (i = 0; i < sizeof(send_buffer); i++) + { + send_buffer[i] = i & 0xFF; + } + memset(recv_buffer, 0, sizeof(recv_buffer)); + + /* Let server thread listen first. */ + tx_thread_relinquish(); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Connect to server. */ +#ifdef FEATURE_NX_IPV6 + status = nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_2, 12, 5 * NX_IP_PERIODIC_RATE); +#else + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Check the connection status. */ + if(status != NX_SUCCESS) + error_counter++; + + /* The callback function is used to drop the first data packet to trigger retransmission. */ + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + else + { + status = nx_packet_data_append(packet_ptr, send_buffer, client_socket.nx_tcp_socket_connect_mss * 2, + &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + } + + /* The packet will be fragmented into 2 TCP packets. Drop 1 packet. */ + drop_packet = 1; + + /* Send the pacekt. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +ULONG length; +ULONG total_length = 0; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Loop to receive the packet. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + nx_packet_data_retrieve(packet_ptr, &recv_buffer[total_length], &length); + total_length += length; + nx_packet_release(packet_ptr); + } + + /* Check data. */ + if ((total_length != client_socket.nx_tcp_socket_connect_mss * 2) || + (memcmp(send_buffer, recv_buffer, total_length))) + { + error_counter++; + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Skip packets from IP1*/ + if (ip_ptr != &ip_0) + { + return NX_TRUE; + } + + /* Skip none TCP packets. */ +#ifdef FEATURE_NX_IPV6 + if (packet_ptr -> nx_packet_length < 60) +#else + if (packet_ptr -> nx_packet_length < 40) +#endif + { + return NX_TRUE; + } + + if (drop_packet != 0) + { + + /* This packet should be dropped. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + drop_packet--; + } + + return NX_TRUE; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_retransmit_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Retransmit Test.......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_retransmit_test_1.c b/test/regression/netxduo_test/netx_tcp_retransmit_test_1.c new file mode 100644 index 00000000..84d23948 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_retransmit_test_1.c @@ -0,0 +1,465 @@ +/* This case tests whether ACK number and window size is updated in retransmitted packet. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#ifdef __PRODUCT_NETXDUO__ +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static ULONG drop_packet; +static NX_PACKET *retransmission_packet; +static ULONG window_size; +static ULONG ack_number; +static ULONG retransmission_window_size; +static ULONG retransmission_ack_number; +static UCHAR pool_area[20480]; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +#endif /* FEATURE_NX_IPV6 */ + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static VOID test_cleanup(VOID); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_retransmit_test_1_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + drop_packet = 0; + retransmission_packet = NX_NULL; + window_size = 0; + ack_number = 0; + retransmission_window_size = 0; + retransmission_ack_number = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pool_area, sizeof(pool_area)); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + +#ifndef NX_DISABLE_IPV4 + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; +#endif + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + if(status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ +} + +/* Define the test threads. */ +static UCHAR send_buffer[3000]; + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +UINT old_threshold; +UINT i; + + /* Print out test information banner. */ + printf("NetX Test: TCP Retransmit Test 1....................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let server thread listen first. */ + tx_thread_relinquish(); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Connect to server. */ +#ifdef FEATURE_NX_IPV6 + status = nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_2, 12, 5 * NX_IP_PERIODIC_RATE); +#else + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Check the connection status. */ + if(status != NX_SUCCESS) + error_counter++; + + /* The callback function is used to drop the first data packet to trigger retransmission. */ + advanced_packet_process_callback = my_packet_process; + + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + else + { + status = nx_packet_data_append(packet_ptr, send_buffer, client_socket.nx_tcp_socket_tx_window_congestion, + &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + } + + /* The packet will be fragmented into 4 TCP packet. Drop 4 packets. */ + drop_packet = 4; + + /* Send the pacekt. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_NO_WAIT); + if(status != NX_SUCCESS) + error_counter++; + + /* Disable preemption. */ + tx_thread_priority_change(tx_thread_identify(), 0, &old_threshold); + for (i = 0; i < 3; i++) + { + + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + else + { + + status = nx_packet_data_append(packet_ptr, send_buffer, 100, + &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + } + + /* Send another pacekt. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + nx_packet_release(packet_ptr); + } + } + + /* Restore preemption. */ + tx_thread_priority_change(tx_thread_identify(), old_threshold, &old_threshold); + + /* Check ACK number and window size. */ + if ((window_size == retransmission_window_size) || + (ack_number == retransmission_ack_number)) + { + + /* Window size or ACK number is not updated. */ + error_counter++; + } + else if ((retransmission_ack_number != client_socket.nx_tcp_socket_rx_sequence) || +#ifdef NX_ENABLE_TCP_WINDOW_SCALING + (retransmission_window_size != (client_socket.nx_tcp_socket_rx_window_current << client_socket.nx_tcp_snd_win_scale_value))) +#else + (retransmission_window_size != client_socket.nx_tcp_socket_rx_window_current)) +#endif + { + + /* Window size or ACK number is not updated to current value of socket. */ + error_counter++; + } + + /* Coverage test for function _nx_tcp_cleanup_deferred. */ + test_cleanup(); + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1170, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + else + { + status = nx_packet_data_append(packet_ptr, send_buffer, 100, &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + } + + /* Send the pacekt. */ + status = nx_tcp_socket_send(&server_socket, packet_ptr, NX_NO_WAIT); + if(status != NX_SUCCESS) + error_counter++; + + /* Make sure thread 0 is the first thread waiting for NX_IP_TCP_CLEANUP_DEFERRED event. */ + tx_thread_suspend(&ntest_1); + nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE); +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_TCP_HEADER *header_ptr; + + /* Skip packets from IP1*/ + if (ip_ptr != &ip_0) + { + return NX_TRUE; + } + + /* Skip none TCP packets. */ +#ifdef FEATURE_NX_IPV6 + if (packet_ptr -> nx_packet_length < 60) +#else + if (packet_ptr -> nx_packet_length < 40) +#endif + { + return NX_TRUE; + } + + if (drop_packet != 0) + { + + /* This packet should be dropped. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + + if (drop_packet == 4) + { + retransmission_packet = packet_ptr; + + /* Get TCP header. */ +#ifdef FEATURE_NX_IPV6 + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 40); +#else + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); +#endif + + /* Get window size and ACK number. */ + ack_number = header_ptr -> nx_tcp_acknowledgment_number; + window_size = header_ptr -> nx_tcp_header_word_3; + NX_CHANGE_ULONG_ENDIAN(ack_number); + NX_CHANGE_ULONG_ENDIAN(window_size); + window_size = window_size & NX_LOWER_16_MASK; + } + + drop_packet--; + } + else if (packet_ptr == retransmission_packet) + { + + /* Get TCP header. */ +#ifdef FEATURE_NX_IPV6 + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 40); +#else + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); +#endif + + /* Get window size and ACK number. */ + retransmission_ack_number = header_ptr -> nx_tcp_acknowledgment_number; + retransmission_window_size = header_ptr -> nx_tcp_header_word_3; + NX_CHANGE_ULONG_ENDIAN(retransmission_ack_number); + NX_CHANGE_ULONG_ENDIAN(retransmission_window_size); + retransmission_window_size = retransmission_window_size & NX_LOWER_16_MASK; + + retransmission_packet = NX_NULL; + } + + return NX_TRUE; +} + + +static VOID test_cleanup(VOID) +{ +UINT old_threshold; +ULONG ip_events; + + /* Disable preemption. */ + tx_thread_priority_change(tx_thread_identify(), 0, &old_threshold); + + /* Wakeup thread 1. */ + tx_thread_resume(&ntest_1); + + /* Get NX_IP_TCP_CLEANUP_DEFERRED event. */ + tx_event_flags_get(&ip_1.nx_ip_events, NX_IP_TCP_CLEANUP_DEFERRED, TX_OR_CLEAR, &ip_events, TX_WAIT_FOREVER); + + /* Make sure _nx_tcp_cleanup_deferred is set. */ + if (ntest_1.tx_thread_suspend_cleanup != _nx_tcp_cleanup_deferred) + { + error_counter++; + } + + /* Delete IP_1 so IP thread is terminated. */ + tx_thread_terminate(&ntest_1); + + /* Restore preemption. */ + tx_thread_priority_change(tx_thread_identify(), old_threshold, &old_threshold); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_retransmit_test_1_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Retransmit Test 1.....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_send_disconnect_test.c b/test/regression/netxduo_test/netx_tcp_send_disconnect_test.c new file mode 100644 index 00000000..bdbc2590 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_send_disconnect_test.c @@ -0,0 +1,267 @@ +/* This NetX test concentrates when thread is suspended on send, the disconnect call will resume the sending thread. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static UCHAR send_buffer[1024]; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_send_disconnect_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 15360); + pointer = pointer + 15360; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Send Disconnect Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buffer, sizeof(send_buffer), &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + /* Since packet is larger than peer's window size and peer doesn't receive any data, the send will fail. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status == NX_SUCCESS) + { + error_counter++; + } + else + { + nx_packet_release(my_packet); + } + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Sleep one second and let client thread send the packet first. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect the client socket while it is transmitting. */ + nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + /* Disconnect the server socket. */ + nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_send_disconnect_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Send Disconnect Test..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_send_fail_test.c b/test/regression/netxduo_test/netx_tcp_send_fail_test.c new file mode 100644 index 00000000..a2b93749 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_send_fail_test.c @@ -0,0 +1,466 @@ +/* This case tests TCP send fails. */ + +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET fake_socket; +static UCHAR send_buffer[1024]; +static UCHAR recv_buffer[1024]; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void window_update_notify(NX_TCP_SOCKET *client_socket); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_send_fail_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create two packet pools. */ + status = nx_packet_pool_create(&pool_0, "Packet Pool 0", 1536, pointer, 8192); + pointer = pointer + 8192; + status += nx_packet_pool_create(&pool_1, "Packet Pool 1", 1536, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_256, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Send Fail Test........................................"); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a fake socket. */ + status = nx_tcp_socket_create(&ip_0, &fake_socket, "Fake Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup fake socket. */ + fake_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + fake_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + fake_socket.nx_tcp_socket_connect_interface = &ip_0.nx_ip_interface[0]; + fake_socket.nx_tcp_socket_next_hop_address = IP_ADDRESS(1, 2, 3, 5); + fake_socket.nx_tcp_socket_port = 12; + fake_socket.nx_tcp_socket_connect_port = 12; + fake_socket.nx_tcp_socket_rx_window_current = 128; +#ifdef NX_IPSEC_ENABLE + fake_socket.nx_tcp_socket_egress_sa = NX_NULL; +#endif /* NX_IPSEC_ENABLE */ + + /* Send a fake packet with no control bits set. */ + _nx_tcp_packet_send_control(&fake_socket, 0, 0, 0, 0, 0, NX_NULL); + +#ifndef NX_DISABLE_TCP_INFO + if (ip_1.nx_ip_tcp_receive_packets_dropped == 0) + error_counter++; +#endif /* NX_DISABLE_TCP_INFO */ + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup a receive notify function. */ + status = nx_tcp_socket_window_update_notify_set(&client_socket, window_update_notify); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Connect to server. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check the connection status. */ + if(status != NX_SUCCESS) + error_counter++; + + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + if(status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(packet_ptr, send_buffer, sizeof(send_buffer), &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + /* Let thread 1 consume all packets and then send the pacekt. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE << 2); + if(status != NX_NO_PACKET) + { + error_counter++; + } + else + { + nx_packet_release(packet_ptr); + } + + tx_thread_resume(&ntest_1); + +#ifndef NX_DISABLE_PACKET_CHAIN + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + if(status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(packet_ptr, send_buffer, server_socket.nx_tcp_socket_rx_window_default, &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + /* Break the length of packet. */ + packet_ptr -> nx_packet_length += 65535; + + /* Send the pacekt. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE); + if(status != NX_INVALID_PACKET) + { + error_counter++; + } + else + { + nx_packet_release(packet_ptr); + } +#endif /* NX_DISABLE_PACKET_CHAIN */ + + + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + if(status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(packet_ptr, send_buffer, server_socket.nx_tcp_socket_rx_window_default, &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + /* Break the length of packet. */ + packet_ptr -> nx_packet_length += client_socket.nx_tcp_socket_connect_mss + 10; + + /* Send the pacekt. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE); + if(status != NX_INVALID_PACKET) + { + error_counter++; + } + else + { + nx_packet_release(packet_ptr); + } + + + /* Send one byte then send packet larger than window size. */ + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + if(status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(packet_ptr, send_buffer, 1, &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + /* Send the pacekt. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Init send buffer. */ + memset(send_buffer, 0xF0, sizeof(send_buffer)); + memset(recv_buffer, 0x00, sizeof(recv_buffer)); + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + if(status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(packet_ptr, send_buffer, sizeof(send_buffer), &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + /* Send the pacekt. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + { + error_counter++; + nx_packet_release(packet_ptr); + } + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +NX_PACKET *consume_pkt[10]; +ULONG consumed = 0; +UINT count; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 196, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* Sleep one second so client socket will waiting for window update to send the second packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Release packet. */ + nx_packet_release(packet_ptr); + + /* Allocate all packets until pool_0 is empty. */ + while (nx_packet_allocate(&pool_0, &consume_pkt[consumed], 0, NX_IP_PERIODIC_RATE) == NX_SUCCESS) + consumed++; + + /* Wait until thread 0 timeout. */ + tx_thread_suspend(&ntest_1); + + /* Release all packets. */ + while (consumed--) + { + nx_packet_release(consume_pkt[consumed]); + } + +#ifndef NX_DISABLE_PACKET_CHAIN + tx_thread_sleep(NX_IP_PERIODIC_RATE >> 1); + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Release packet. */ + nx_packet_release(packet_ptr); +#endif /* NX_DISABLE_PACKET_CHAIN */ + + tx_thread_sleep(NX_IP_PERIODIC_RATE >> 1); + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Release packet. */ + nx_packet_release(packet_ptr); + + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_WAIT_FOREVER); + + /* Check for error. */ + if(status) + error_counter++; + + /* Release packet. */ + nx_packet_release(packet_ptr); + + count = 0; + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + /* Copy data to recv_buffer. */ + memcpy(recv_buffer + count, packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + count += packet_ptr -> nx_packet_length; + + /* Release packet. */ + nx_packet_release(packet_ptr); + } + + /* Check data in received packet. */ + if (count != sizeof(send_buffer)) + error_counter++; + else if (memcmp(recv_buffer, send_buffer, sizeof(send_buffer))) + error_counter++; + +} + +static void window_update_notify(NX_TCP_SOCKET *client_socket) +{ +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_send_fail_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Send Fail Test........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_send_fail_test2.c b/test/regression/netxduo_test/netx_tcp_send_fail_test2.c new file mode 100644 index 00000000..2aab6bad --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_send_fail_test2.c @@ -0,0 +1,323 @@ +/* This NetX test concentrates on sending partial TCP data due to pool empty. + * The payload size of packet pool is 512. + * The window size is 800. + * Size of transmitting data is 1800. + * The transmitting data are placed in 4 packets, the packet pool has only one packet available. + * While the payload size of packet is smaller than the window size, TCP won't send all data until packet is available. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +#ifndef NX_PACKET_ALIGNMENT +#define NX_PACKET_ALIGNMENT sizeof(ULONG) +#endif /* NX_PACKET_ALIGNMENT */ + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + +static CHAR send_buff[1800]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_send_fail_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool with 5 packets. */ + pointer = (CHAR *)(((ALIGN_TYPE)pointer + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)); + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, + ((512 + sizeof(NX_PACKET) + NX_PACKET_ALIGNMENT - 1) & ~(NX_PACKET_ALIGNMENT - 1)) * 6); + pointer = pointer + (512 + NX_PACKET_ALIGNMENT + sizeof(NX_PACKET)) * 6; + + /* Create another packet pool. */ + status += nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 1536, pointer, 10240); + pointer = pointer + 10240; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Send Fail Test 2......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Verify only one packet available. */ + if (pool_0.nx_packet_pool_available != 2) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE << 1); + if (status != NX_NO_PACKET) + error_counter++; + + /* Verify partial data are sent. */ + if (my_packet -> nx_packet_length == sizeof(send_buff)) + error_counter++; + + nx_packet_release(my_packet); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +NX_PACKET *waste_ptr; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 800, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Sleep one second. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + + /* Verify only partial data are received. */ + if(packet_ptr -> nx_packet_length != server_socket.nx_tcp_socket_rx_window_default) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Waste a packet from pool 0. */ + status = nx_packet_allocate(&pool_0, &waste_ptr, NX_TCP_PACKET, NX_NO_WAIT); + if (status) + error_counter++; + + /* Verify only one packet available. */ + if (pool_0.nx_packet_pool_available != 1) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_send_fail_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Send Fail Test 2......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_send_fail_test3.c b/test/regression/netxduo_test/netx_tcp_send_fail_test3.c new file mode 100644 index 00000000..441e6719 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_send_fail_test3.c @@ -0,0 +1,277 @@ +/* This NetX test concentrates on sending partial TCP data due to window size. The length of packet is verified after send. + * The payload size of packet pool is 1516. + * The MSS and window is 1460. + * Size of transmitting data is 1500. + * The transmitting data are received by peer. TCP won't send all data. */ + +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETX__) && !defined(NX_DISABLE_PACKET_CHAIN) +#define DEMO_STACK_SIZE 2048 + +#ifndef NX_PACKET_ALIGNMENT +#define NX_PACKET_ALIGNMENT sizeof(ULONG) +#endif /* NX_PACKET_ALIGNMENT */ + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + +static CHAR send_buff[1500]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_send_fail_test3_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 10240); + pointer = pointer + 10240; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Send Fail Test 3......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_NO_WAIT); + if (status != NX_WINDOW_OVERFLOW) + error_counter++; + + /* Verify partial data are sent. */ + if (my_packet -> nx_packet_length != sizeof(send_buff) - 1460) + error_counter++; + + nx_packet_release(my_packet); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1460, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Sleep one second. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_send_fail_test3_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Send Fail Test 3......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_server_socket_accept_test.c b/test/regression/netxduo_test/netx_tcp_server_socket_accept_test.c new file mode 100644 index 00000000..f063ab8e --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_server_socket_accept_test.c @@ -0,0 +1,275 @@ +/* This NetX test concentrates on the TCP Server Socket accept operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket_0; +static NX_TCP_SOCKET server_socket_0; + +/* The 2 ports will hashed to the same index. */ +#define SERVER_PORT_0 0x00000100 +#define SERVER_PORT_1 0x00008100 + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_server_socket_accept_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT client_port; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Server Socket Accept Test............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_0, "Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket_0, client_port, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket_0, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_0, "Server Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept the server socket before listen. */ + status = nx_tcp_server_socket_accept(&server_socket_0, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_NOT_LISTEN_STATE) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT_0, &server_socket_0, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket_0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept the server socket again. */ + status = nx_tcp_server_socket_accept(&server_socket_0, NX_NO_WAIT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_server_socket_accept_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Server Socket Accept Test.............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_simultaneous_test.c b/test/regression/netxduo_test/netx_tcp_simultaneous_test.c new file mode 100644 index 00000000..dc4f5eb4 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_simultaneous_test.c @@ -0,0 +1,348 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static UINT driver_packet_process_delay(NX_IP *ip_ptr, NX_PACKET *packet_ptr, + UINT *operation_ptr, UINT *delay_ptr); +static UINT driver_packet_process_drop_always(NX_IP *ip_ptr, NX_PACKET *packet_ptr, + UINT *operation_ptr, UINT *delay_ptr); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, + UINT *operation_ptr, UINT *delay_ptr); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_simultaneous_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Simultaneous Test....................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + if (status != NX_NOT_CONNECTED) + error_counter++; + + /* Verify server socket is in SYN RECEIVED state. */ + if (server_socket.nx_tcp_socket_state != NX_TCP_SYN_RECEIVED) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *packet_ptr; + ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Delay the SYN packets to simulate simultaneous open. */ + advanced_packet_process_callback = driver_packet_process_delay; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&server_socket, 12, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&server_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + error_counter++; + + nx_packet_release(packet_ptr); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Drop the SYN packet from server socket always. */ + advanced_packet_process_callback = driver_packet_process_drop_always; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&server_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE); + if (status != NX_NOT_CONNECTED) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&server_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + + +static UINT driver_packet_process_delay(NX_IP *ip_ptr, NX_PACKET *packet_ptr, + UINT *operation_ptr, UINT *delay_ptr) +{ + + if ((ip_ptr == &ip_1) && + (packet_ptr -> nx_packet_length > 40)) + { + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = 10; + } + + if ((ip_ptr == &ip_0) && + (packet_ptr -> nx_packet_length > 40)) + { + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = 10; + + /* Clear the callback function. */ + advanced_packet_process_callback = NX_NULL; + } + + return NX_TRUE; +} + + +static UINT driver_packet_process_drop_always(NX_IP *ip_ptr, NX_PACKET *packet_ptr, + UINT *operation_ptr, UINT *delay_ptr) +{ + + if ((ip_ptr == &ip_1) && + (packet_ptr -> nx_packet_length > 40)) + { + + /* Drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_simultaneous_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Simultaneous Test.....................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_small_packet_test.c b/test/regression/netxduo_test/netx_tcp_small_packet_test.c new file mode 100644 index 00000000..8716ba44 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_small_packet_test.c @@ -0,0 +1,159 @@ +/* This NetX test concentrates on TCP data packets. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#ifndef NX_DISABLE_IPV4 + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static ULONG syn_packet_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_small_packet_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_IP_PACKET, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: TCP Small Packet Test....................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + advanced_packet_process_callback = my_packet_process; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status == NX_SUCCESS) || (syn_packet_counter != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + syn_packet_counter++; + + return NX_TRUE; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_small_packet_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Small Packet Test.....................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_small_window_preempt_test.c b/test/regression/netxduo_test/netx_tcp_small_window_preempt_test.c new file mode 100644 index 00000000..6a78ece4 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_small_window_preempt_test.c @@ -0,0 +1,474 @@ +/* This NetX test concentrates on the small window TCP operation. This is the same + as the small window test... but instead the receiver keeps the receive queue empty + so the immediate ACK must come back from the socket data receive function. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_small_window_preempt_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG start_time; +ULONG end_time; + + + /* Print out test information banner. */ + printf("NetX Test: TCP Small Window Size Preemption Test....................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 128, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 132); + + /* Check for error. */ + if (status) + error_counter++; + + /* Send 5 packets... the 5th packet should block because of the window size. */ + + /* Allocate a 1st packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a 2nd packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a 3rd packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a 4th packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a 5th packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Remember the starting time. */ + start_time = tx_time_get(); + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Get the end time. */ + end_time = tx_time_get(); + + /* Determine if the status is valid. */ + if ((status) || (end_time > (start_time+NX_IP_PERIODIC_RATE/10))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 132, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Receive five TCP messages from the socket - 1st packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive five TCP messages from the socket - 2nd packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive five TCP messages from the socket - 3rd packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive five TCP messages from the socket - 4th packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive five TCP messages from the socket - 5th packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_small_window_preempt_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Small Window Size Preemption Test.....................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_small_window_test.c b/test/regression/netxduo_test/netx_tcp_small_window_test.c new file mode 100644 index 00000000..a04c6566 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_small_window_test.c @@ -0,0 +1,546 @@ +/* This NetX test concentrates on the small window TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) +static UCHAR message[280]; +#endif /* NX_DISABLE_PACKET_CHAIN */ + + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void ntest_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +#endif + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_small_window_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG start_time; +ULONG end_time; + + + /* Let the other thread run first. */ + tx_thread_relinquish(); + + /* Print out test information banner. */ + printf("NetX Test: TCP Small Window Size Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 128, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + tx_thread_relinquish(); + +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write data that is larger than window size. */ + status = nx_packet_data_append(my_packet, message, sizeof(message), &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Delay the packet sent out. */ + advanced_packet_process_callback = my_packet_process; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 1); + + advanced_packet_process_callback = NX_NULL; + + /* The timeout is one tick only, so only part of whole packet can be sent. */ + if (status) + { + nx_packet_release(my_packet); + } + else + { + error_counter++; + } + + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write data that is larger than window size. */ + status = nx_packet_data_append(my_packet, message, sizeof(message), &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } +#endif /* NX_DISABLE_PACKET_CHAIN */ + + /* Send 5 packets... the 5th packet should block because of the window size. */ + /* Allocate a 1st packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 10); + + /* Determine if the status is valid. */ + if (status) + { + nx_packet_release(my_packet); + } + + /* Allocate a 2nd packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a 3rd packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a 4th packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a 5th packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Remember the starting time. */ + start_time = tx_time_get(); + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Get the end time. */ + end_time = tx_time_get(); + + /* Determine if the status is valid. */ + if ((status) || (end_time > (start_time+NX_IP_PERIODIC_RATE/10))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG expected_length; +ULONG loop; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 132, + NX_NULL, ntest_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, ntest_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) + + /* Receive five TCP messages from the socket - 1st packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + else + nx_packet_release(packet_ptr); + + expected_length = sizeof(message); + loop = 6; +#else + expected_length = 28; + loop = 5; +#endif /* NX_DISABLE_PACKET_CHAIN */ + while(loop > 0) + { + + /* Receive five TCP messages from the socket - 1st packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + { + expected_length -= packet_ptr -> nx_packet_length; + if(expected_length == 0) + { + expected_length = 28; + loop--; + } + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void ntest_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void ntest_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + + +#if !defined(NX_DISABLE_PACKET_CHAIN) && defined(__PRODUCT_NETXDUO__) +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Skip packet that is not TCP. */ + if(packet_ptr -> nx_packet_length < 40) + return NX_TRUE; + + /* Let driver drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + return NX_TRUE; +} +#endif +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_small_window_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Small Window Size Test................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_socket_available_bytes_test.c b/test/regression/netxduo_test/netx_tcp_socket_available_bytes_test.c new file mode 100644 index 00000000..bc28590b --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_available_bytes_test.c @@ -0,0 +1,320 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_available_bytes_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +ULONG bytes_available; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket available bytes Test..........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Get the socket bytes available. */ + status = nx_tcp_socket_bytes_available(&client_socket, &bytes_available); + if (status != NX_NOT_CONNECTED) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, 2 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + for (i = 0; i < 2; i++) + { + + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_resume(&thread_1); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG bytes_available; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Get the socket bytes available. */ + status = nx_tcp_socket_bytes_available(&server_socket, &bytes_available); + if (status != NX_NOT_CONNECTED) + error_counter++; + + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + tx_thread_suspend(&thread_1); + + /* Get the socket bytes available. */ + status = nx_tcp_socket_bytes_available(&server_socket, &bytes_available); + if (status || (bytes_available != 28)) + error_counter++; + + tx_thread_suspend(&thread_1); + + /* Get the socket bytes available. */ + status = nx_tcp_socket_bytes_available(&server_socket, &bytes_available); + if (status || (bytes_available != 28 * 2)) + error_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get the socket bytes available. */ + status = nx_tcp_socket_bytes_available(&server_socket, &bytes_available); + if (status != NX_NOT_CONNECTED) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_available_bytes_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Socket available bytes Test...........................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_socket_delete_test.c b/test/regression/netxduo_test/netx_tcp_socket_delete_test.c new file mode 100644 index 00000000..7de56bdf --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_delete_test.c @@ -0,0 +1,184 @@ +/* This NetX test concentrates on the TCP Socket unaccept operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_delete_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable TCP processing for IP instance. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Delete Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a client socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete this socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a client socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the port. */ + status = nx_tcp_client_socket_bind(&client_socket, 80, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete this socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status != NX_STILL_BOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the port. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete this socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_socket_listen_queue_test.c b/test/regression/netxduo_test/netx_tcp_socket_listen_queue_test.c new file mode 100644 index 00000000..4f1b2055 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_listen_queue_test.c @@ -0,0 +1,876 @@ +/* This NetX test concentrates on the TCP Socket unaccept operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_IPV4) + +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket_0; +static NX_TCP_SOCKET client_socket_1; +static NX_TCP_SOCKET server_socket_0; +static NX_TCP_SOCKET server_socket_1; + +/* The 2 ports will hashed to the same index. */ +#define SERVER_PORT_0 0x00000100 +#define SERVER_PORT_1 0x00008100 + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT v4_syn_counter = 0; +static UINT v6_syn_counter = 0; +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +static NX_PACKET *v4_syn_packet; +static NX_PACKET *v4_rst_packet; +static NX_PACKET *v6_syn_packet; +static NX_PACKET *v6_rst_packet; +static NX_PACKET *copy_packet[20]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void tcp_checksum_compute(NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_listen_queue_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT client_port; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Listen Queue Test.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_0, "Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket_0, client_port, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to send a SYN */ + status = nxd_tcp_client_socket_connect(&client_socket_0, &ipv6_address_2, SERVER_PORT_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_1, "Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket_1, client_port, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + + /* Call connect to send a SYN with IPv6 address. */ + status = nxd_tcp_client_socket_connect(&client_socket_1, &ipv6_address_2, SERVER_PORT_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Call connect to send a SYN with IPv4 address. */ + nx_tcp_client_socket_connect(&client_socket_1, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT_1, NX_NO_WAIT); + + /* Sleep 500 ticks, Server socket receive packet. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +UINT i; +NX_IPV6_HEADER *ip_header_ptr; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_0, "Server Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT_0, &server_socket_0, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_relisten(&ip_1, SERVER_PORT_0, &server_socket_0); + + /* Check for error. */ + if (status != NX_NOT_CLOSED) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_1, "Server Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT_1, &server_socket_1, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket_1); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the socket state. */ + if (server_socket_1.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Check the TCP port table. */ + if ((ip_1.nx_ip_tcp_port_table[1] != &server_socket_0) || (ip_1.nx_ip_tcp_port_table[1] -> nx_tcp_socket_bound_next != &server_socket_0)) + error_counter++; + + /* Sleep 0.5 second to receive the IPV4 SYN packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE/2); + + /* Copy the IP header. */ + v4_syn_packet -> nx_packet_prepend_ptr -= 20; + v4_syn_packet -> nx_packet_length += 20; + + /* Copy the packet. */ + status = nx_packet_copy(v4_syn_packet, ©_packet[0], &pool_0, NX_NO_WAIT); + + /* Check status . */ + if (status) + { + error_counter ++; + } + else + { + + /* Update the packet IP header. */ + copy_packet[0] -> nx_packet_ip_header = copy_packet[0] -> nx_packet_prepend_ptr; + + /* Update the copy packet pointer. */ + copy_packet[0] -> nx_packet_prepend_ptr += 20; + copy_packet[0] -> nx_packet_length -= 20; + + tcp_checksum_compute(copy_packet[0]); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(&ip_1, copy_packet[0]); + } + + /* Check the listen queue current count. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_next -> nx_tcp_listen_queue_current != 1) + error_counter ++; + + /* Copy the IP header. */ + v4_rst_packet -> nx_packet_prepend_ptr -= 20; + v4_rst_packet -> nx_packet_length += 20; + + /* Copy the packet. */ + status = nx_packet_copy(v4_rst_packet, ©_packet[1], &pool_0, NX_NO_WAIT); + + /* Check status . */ + if (status) + { + error_counter ++; + } + else + { + + /* Update the packet IP header. */ + copy_packet[1] -> nx_packet_ip_header = copy_packet[1] -> nx_packet_prepend_ptr; + + /* Update the copy packet pointer. */ + copy_packet[1] -> nx_packet_prepend_ptr += 20; + copy_packet[1] -> nx_packet_length -= 20; + + tcp_checksum_compute(copy_packet[1]); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(&ip_1, copy_packet[1]); + } + + /* Check the listen queue current count. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_next -> nx_tcp_listen_queue_current != 0) + error_counter ++; + + /* Copy the IP header. */ + v6_syn_packet -> nx_packet_prepend_ptr -= 40; + v6_syn_packet -> nx_packet_length += 40; + + /* Copy the packet. */ + status = nx_packet_copy(v6_syn_packet, ©_packet[2], &pool_0, NX_NO_WAIT); + + /* Check status . */ + if (status) + { + error_counter ++; + } + else + { + + /* Update the packet IP header. */ + copy_packet[2] -> nx_packet_ip_header = copy_packet[2] -> nx_packet_prepend_ptr; + + /* Update the copy packet pointer. */ + copy_packet[2] -> nx_packet_prepend_ptr += 40; + copy_packet[2] -> nx_packet_length -= 40; + + tcp_checksum_compute(copy_packet[2]); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(&ip_1, copy_packet[2]); + } + + /* Check the listen queue current count. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_next -> nx_tcp_listen_queue_current != 1) + error_counter ++; + + /* Copy the IP header. */ + v6_rst_packet -> nx_packet_prepend_ptr -= 40; + v6_rst_packet -> nx_packet_length += 40; + + /* Copy the packet. */ + status = nx_packet_copy(v6_rst_packet, ©_packet[3], &pool_0, NX_NO_WAIT); + + /* Check status . */ + if (status) + { + error_counter ++; + } + else + { + + /* Update the packet IP header. */ + copy_packet[3] -> nx_packet_ip_header = copy_packet[3] -> nx_packet_prepend_ptr; + + /* Update the copy packet pointer. */ + copy_packet[3] -> nx_packet_prepend_ptr += 40; + copy_packet[3] -> nx_packet_length -= 40; + + tcp_checksum_compute(copy_packet[3]); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(&ip_1, copy_packet[3]); + } + + /* Check the listen queue current count. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_next -> nx_tcp_listen_queue_current != 0) + error_counter ++; + + /* Loop to recieve the SYN packet with different source address. */ + for (i = 4; i< 15; i++) + { + + /* Copy the packet. */ + status = nx_packet_copy(v6_syn_packet, ©_packet[i], &pool_0, NX_NO_WAIT); + + /* Check status . */ + if (status) + { + error_counter ++; + } + else + { + + /* Update the packet IP header. */ + copy_packet[i] -> nx_packet_ip_header = copy_packet[i] -> nx_packet_prepend_ptr; + + /* Update the source IP address. */ + if (i >= 6) + { + + /* Points to the base of IPv6 header. */ + ip_header_ptr = (NX_IPV6_HEADER*)copy_packet[i] -> nx_packet_prepend_ptr; + + /* Update the address. */ + ip_header_ptr -> nx_ip_header_source_ip[3] += i; + } + + /* Update the copy packet pointer. */ + copy_packet[i] -> nx_packet_prepend_ptr += 40; + copy_packet[i] -> nx_packet_length -= 40; + + tcp_checksum_compute(copy_packet[i]); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(&ip_1, copy_packet[i]); + } + } + + /* Check the listen queue current count. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_next -> nx_tcp_listen_queue_current != 5) + error_counter ++; + + /* Loop to recieve the RST packet with different source address. */ + for (i = 14; i >= 4; i--) + { + + /* Copy the packet. */ + status = nx_packet_copy(v6_rst_packet, ©_packet[i], &pool_0, NX_NO_WAIT); + + /* Check status . */ + if (status) + { + error_counter ++; + } + else + { + + /* Update the packet IP header. */ + copy_packet[i] -> nx_packet_ip_header = copy_packet[i] -> nx_packet_prepend_ptr; + + /* Update the source IP address. */ + if (i >= 6) + { + + /* Points to the base of IPv6 header. */ + ip_header_ptr = (NX_IPV6_HEADER*)copy_packet[i] -> nx_packet_prepend_ptr; + + /* Update the address. */ + ip_header_ptr -> nx_ip_header_source_ip[3] += i; + } + + /* Update the copy packet pointer. */ + copy_packet[i] -> nx_packet_prepend_ptr += 40; + copy_packet[i] -> nx_packet_length -= 40; + + tcp_checksum_compute(copy_packet[i]); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(&ip_1, copy_packet[i]); + } + } + + /* Check the listen queue current count. */ + if (ip_1.nx_ip_tcp_active_listen_requests -> nx_tcp_listen_next -> nx_tcp_listen_queue_current != 0) + error_counter ++; +} + +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +UINT status; +NX_TCP_HEADER *tcp_header_ptr; +ULONG tcp_header_word_3; + + + /* Check the packet version. */ + if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) + { + + /* Get the TCP header. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + /* Get the word. */ + tcp_header_word_3 = tcp_header_ptr -> nx_tcp_header_word_3; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_word_3); + + /* Check if the packet is an SYN packet. */ + if (tcp_header_word_3 & NX_TCP_SYN_BIT) + { + + /* Update the counter. */ + v4_syn_counter ++; + + /* Check the counter. */ + if (v4_syn_counter == 1) + { + + /* Update the packet prepend and length to include the IPv4 header. */ + packet_ptr -> nx_packet_prepend_ptr -= 20; + packet_ptr -> nx_packet_length += 20; + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, &v4_syn_packet, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet IP header. */ + v4_syn_packet -> nx_packet_ip_header = v4_syn_packet -> nx_packet_prepend_ptr; + + /* Update the packet prepend and length. */ + v4_syn_packet -> nx_packet_prepend_ptr += 20; + v4_syn_packet -> nx_packet_length -= 20; + } + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, &v4_rst_packet, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet IP header. */ + v4_rst_packet -> nx_packet_ip_header = v4_rst_packet -> nx_packet_prepend_ptr; + + /* Update the packet prepend and length. */ + v4_rst_packet -> nx_packet_prepend_ptr += 20; + v4_rst_packet -> nx_packet_length -= 20; + + /* Get the TCP header. */ + tcp_header_ptr = (NX_TCP_HEADER *)v4_rst_packet -> nx_packet_prepend_ptr; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Clear the SYN bit and set the RST bit. */ + tcp_header_ptr -> nx_tcp_header_word_3 = (tcp_header_ptr -> nx_tcp_header_word_3 & (~NX_TCP_SYN_BIT)) | NX_TCP_RST_BIT; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Update the packet prepend and length to include the IPv4 header. */ + packet_ptr -> nx_packet_prepend_ptr += 20; + packet_ptr -> nx_packet_length -= 20; + } + } + } + else if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) + { + + /* Get the TCP header. */ + tcp_header_ptr = (NX_TCP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + + /* Get the word. */ + tcp_header_word_3 = tcp_header_ptr -> nx_tcp_header_word_3; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_word_3); + + /* Check if the packet is an SYN packet. */ + if (tcp_header_word_3 & NX_TCP_SYN_BIT) + { + + /* Update the counter. */ + v6_syn_counter ++; + + /* Check the counter. */ + if (v6_syn_counter == 1) + { + + /* Update the packet prepend and length to include the IPv6 header. */ + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, &v6_syn_packet, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet IP header. */ + v6_syn_packet -> nx_packet_ip_header = v6_syn_packet -> nx_packet_prepend_ptr; + + /* Update the packet prepend and length. */ + v6_syn_packet -> nx_packet_prepend_ptr += 40; + v6_syn_packet -> nx_packet_length -= 40; + } + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, &v6_rst_packet, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet IP header. */ + v6_rst_packet -> nx_packet_ip_header = v6_rst_packet -> nx_packet_prepend_ptr; + + /* Update the packet prepend and length. */ + v6_rst_packet -> nx_packet_prepend_ptr += 40; + v6_rst_packet -> nx_packet_length -= 40; + + + /* Get the TCP header. */ + tcp_header_ptr = (NX_TCP_HEADER *)v6_rst_packet -> nx_packet_prepend_ptr; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Clear the SYN bit and set the RST bit. */ + tcp_header_ptr -> nx_tcp_header_word_3 = (tcp_header_ptr -> nx_tcp_header_word_3 & (~NX_TCP_SYN_BIT)) | NX_TCP_RST_BIT; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + } + + /* Update the packet prepend and length to include the IPv6 header. */ + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + } + } + } + + tcp_checksum_compute(packet_ptr); + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + + +#if defined(__PRODUCT_NETXDUO__) +static void tcp_checksum_compute(NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG *source_ip, *dest_ip; +ULONG checksum; + + if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) + { + + /* Get IPv4 addresses. */ + source_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 8); + dest_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 4); + } + else + { + + /* Get IPv6 addresses. */ + source_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 32); + dest_ip = (ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 16); + } + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + /* Calculate the checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); +} +#else +static void tcp_checksum_compute(PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG source_ip, dest_ip; +ULONG checksum; + + /* Get IPv4 addresses. */ + source_ip = *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 8); + dest_ip = *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr - 4); + + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + + /* Calculate the TCP checksum. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + /* Calculate the checksum. */ + checksum = _nx_tcp_checksum(packet_ptr, source_ip, dest_ip); + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); +} +#endif /* __PRODUCT_NETXDUO__ */ + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_listen_queue_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Listen Queue Test..............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_socket_listen_test.c b/test/regression/netxduo_test/netx_tcp_socket_listen_test.c new file mode 100644 index 00000000..414e997d --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_listen_test.c @@ -0,0 +1,161 @@ +/* This NetX test concentrates on the TCP Socket unaccept operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET server_socket[NX_MAX_LISTEN_REQUESTS + 1]; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_listen_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable TCP processing for IP instance. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +UINT server_port; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Listen Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Initialize the server port. */ + server_port = 80; + + /* Loop to create the server socket. */ + for (i = 0; i < NX_MAX_LISTEN_REQUESTS; i++, server_port++) + { + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, server_port, &server_socket[i], 5, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket[i], "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup this socket to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, server_port, &server_socket[i], 5, NX_NULL); + + /* Check for error. */ + if (status != NX_MAX_LISTEN) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_socket_mss_test.c b/test/regression/netxduo_test/netx_tcp_socket_mss_test.c new file mode 100644 index 00000000..717a7697 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_mss_test.c @@ -0,0 +1,361 @@ +/* This NetX test concentrates on the TCP Socket MSS set and get operation. */ + +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +#define CLIENT_MSS 1280 +#define SERVER_MSS 640 +#define LARGE_MSS 2000 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +#define CLIENT_PORT 0x88 +#define SERVER_PORT 0x89 + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_mss_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + /* Check the status. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check the status. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG mss; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket MSS Set Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, CLIENT_PORT, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_tcp_socket_mss_get(&client_socket, &mss); + + /* Check for error. */ + if (status || (mss != NX_TCP_MSS_SIZE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set MSS smaller than the interface MSS. */ + status = nx_tcp_socket_mss_set(&client_socket, CLIENT_MSS); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_tcp_socket_mss_get(&client_socket, &mss); + + /* Check for error. */ + if (status || (mss != CLIENT_MSS)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set MSS larger than the interface MSS. */ + status = nx_tcp_socket_mss_set(&client_socket, LARGE_MSS); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_tcp_socket_mss_get(&client_socket, &mss); + + /* Check for error. */ + if (status || (mss != SERVER_MSS)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; +ULONG mss; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + status = nx_tcp_socket_mss_get(&server_socket, &mss); + + /* Check for error. */ + if (status || (mss != CLIENT_MSS)) + error_counter++; + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, SERVER_PORT, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Set MSS. */ + status = nx_tcp_socket_mss_set(&server_socket, SERVER_MSS); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + status = nx_tcp_socket_mss_peer_get(&server_socket, &mss); + + /* Check for error. */ + if (status || (mss != 1460)) + error_counter++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_mss_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket MSS Set Test...................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_socket_receive_rst_test.c b/test/regression/netxduo_test/netx_tcp_socket_receive_rst_test.c new file mode 100644 index 00000000..8069ac6b --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_receive_rst_test.c @@ -0,0 +1,289 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_receive_rst_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +ULONG bytes_received = 0; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Receive RST Test..............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, 2 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + for (i = 0; i < 2; i++) + { + status = nx_tcp_socket_receive(&client_socket, &my_packet, NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + } + else + { + bytes_received += my_packet -> nx_packet_length; + } + } + + /* Check received data. */ + if (bytes_received != 56) + { + error_counter++; + } + + /* Disconnect the server socket. */ + nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); + + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *packet_ptr; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + for (i = 0; i < 2; i++) + { + + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(packet_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&server_socket, packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(packet_ptr); + } + } + + /* Send RST. */ + nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unlisten on the server port. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_receive_rst_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Socket Receive RST Test...............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_socket_relisten_test.c b/test/regression/netxduo_test/netx_tcp_socket_relisten_test.c new file mode 100644 index 00000000..1bec5e8e --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_relisten_test.c @@ -0,0 +1,484 @@ +/* This NetX test concentrates on the IPv4 TCP Socket relisten operation. */ + +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket_0; +static NX_TCP_SOCKET client_socket_1; +static NX_TCP_SOCKET server_socket_0; +static NX_TCP_SOCKET server_socket_1; + +/* The 2 ports will hashed to the same index. */ +#define SERVER_PORT_0 0x00000100 +#define SERVER_PORT_1 0x00008100 + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT syn_counter = 0; +static NX_PACKET *copy_packet; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_relisten_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT client_port; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Relisten Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_0, "Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket_0, client_port, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Should return some error message. */ + status = nx_tcp_server_socket_relisten(&ip_0, 12, &client_socket_0); + if (status != NX_ALREADY_BOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_socket_0, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_1, "Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket_1, client_port, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + + /* Call connect to send a SYN */ + status = nx_tcp_client_socket_connect(&client_socket_1, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_0, "Server Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT_0, &server_socket_0, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_relisten(&ip_1, SERVER_PORT_0, &server_socket_0); + + /* Check for error. */ + if (status != NX_NOT_CLOSED) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_1, "Server Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT_1, &server_socket_1, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket_1); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the socket state. */ + if (server_socket_1.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Check the TCP port table. */ + if ((ip_1.nx_ip_tcp_port_table[1] != &server_socket_0) || (ip_1.nx_ip_tcp_port_table[1] -> nx_tcp_socket_bound_next != &server_socket_0)) + error_counter++; + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(&ip_1, copy_packet); + + /* Relisten. */ + status = nx_tcp_server_socket_relisten(&ip_1, SERVER_PORT_1, &server_socket_1); + + /* Check for error. */ + if (status != NX_CONNECTION_PENDING) + error_counter++; + + /* Check the socket state. */ + if (server_socket_1.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* Check the mss value. */ + if (server_socket_1.nx_tcp_socket_peer_mss != 536) + error_counter++; + + /* Check the TCP port table. */ + if ((ip_1.nx_ip_tcp_port_table[1] != &server_socket_0) || (ip_1.nx_ip_tcp_port_table[1] -> nx_tcp_socket_bound_next != &server_socket_1)) + error_counter++; +} + +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +UINT status; +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG checksum; +ULONG old_m; +ULONG new_m; + + /* Update the counter. */ + syn_counter ++; + + /* Check the counter. */ + if (syn_counter == 1) + { + + /* Update the packet prepend and length to include the IPv4 header. */ + packet_ptr -> nx_packet_prepend_ptr -= 20; + packet_ptr -> nx_packet_length += 20; + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + +#ifdef __PRODUCT_NETXDUO__ + /* Update the packet IP header. */ + copy_packet -> nx_packet_ip_header = copy_packet -> nx_packet_prepend_ptr; +#endif /* __PRODUCT_NETXDUO__ */ + + /* Update the packet prepend and length. */ + copy_packet -> nx_packet_prepend_ptr += 20; + copy_packet -> nx_packet_length -= 20; + + /* Update the packet prepend and length to include the IPv4 header. */ + packet_ptr -> nx_packet_prepend_ptr += 20; + packet_ptr -> nx_packet_length -= 20; + + /* Get the TCP header pointer. */ + tcp_header_ptr = (NX_TCP_HEADER *) copy_packet -> nx_packet_prepend_ptr; + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + /* Get the old checksum (HC) in header. */ + checksum = tcp_header_ptr -> nx_tcp_header_word_4 >> 16; + + /* Get the old mss. */ + old_m = *option_word_1 & 0x0000FFFF;; + + /* Set the new TTL as 1. */ + new_m = 0; + + /* Update the mss value as zero. */ + *option_word_1 = NX_TCP_MSS_OPTION | new_m; + + /* Update the checksum, get the new checksum(HC'), + The new_m is ULONG value, so need get the lower value after invert. */ + checksum = ((~checksum) & 0xFFFF) + ((~old_m) & 0xFFFF) + new_m; + + /* Fold a 4-byte value into a two byte value */ + checksum = (checksum >> 16) + (checksum & 0xFFFF); + + /* Do it again in case previous operation generates an overflow */ + checksum = (checksum >> 16) + (checksum & 0xFFFF); + + /* Now store the new checksum in the IP header. */ + tcp_header_ptr -> nx_tcp_header_word_4 = ((tcp_header_ptr -> nx_tcp_header_word_4 & 0x0000FFFF) | ((~checksum) << 16)); + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + } + } + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_relisten_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Socket Relisten Test..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_socket_relisten_test2.c b/test/regression/netxduo_test/netx_tcp_socket_relisten_test2.c new file mode 100644 index 00000000..38c573ac --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_relisten_test2.c @@ -0,0 +1,503 @@ +/* This NetX test concentrates on the IPv6 TCP Socket relisten operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#ifdef FEATURE_NX_IPV6 + +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket_0; +static NX_TCP_SOCKET client_socket_1; +static NX_TCP_SOCKET server_socket_0; +static NX_TCP_SOCKET server_socket_1; + +/* The 2 ports will hashed to the same index. */ +#define SERVER_PORT_0 0x00000100 +#define SERVER_PORT_1 0x00008100 + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT syn_counter = 0; +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +static NX_PACKET *copy_packet; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_relisten_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check IPv6 enable status. */ + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ICMP enable status. */ + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT client_port; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Relisten Test 2................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_0, "Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket_0, client_port, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Should return some error message. */ + status = nx_tcp_server_socket_relisten(&ip_0, 12, &client_socket_0); + if (status != NX_ALREADY_BOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to send a SYN */ + status = nxd_tcp_client_socket_connect(&client_socket_0, &ipv6_address_2, SERVER_PORT_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_1, "Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket_1, client_port, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + + /* Call connect to send a SYN */ + status = nxd_tcp_client_socket_connect(&client_socket_1, &ipv6_address_2, SERVER_PORT_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_0, "Server Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT_0, &server_socket_0, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_relisten(&ip_1, SERVER_PORT_0, &server_socket_0); + + /* Check for error. */ + if (status != NX_NOT_CLOSED) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_1, "Server Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT_1, &server_socket_1, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket_1); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the socket state. */ + if (server_socket_1.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Check the TCP port table. */ + if ((ip_1.nx_ip_tcp_port_table[1] != &server_socket_0) || (ip_1.nx_ip_tcp_port_table[1] -> nx_tcp_socket_bound_next != &server_socket_0)) + error_counter++; + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(&ip_1, copy_packet); + + /* Relisten. */ + status = nx_tcp_server_socket_relisten(&ip_1, SERVER_PORT_1, &server_socket_1); + + /* Check for error. */ + if (status != NX_CONNECTION_PENDING) + error_counter++; + + /* Check the socket state. */ + if (server_socket_1.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* Check the mss value. */ + if (server_socket_1.nx_tcp_socket_peer_mss != 1220) + error_counter++; + + /* Check the TCP port table. */ + if ((ip_1.nx_ip_tcp_port_table[1] != &server_socket_0) || (ip_1.nx_ip_tcp_port_table[1] -> nx_tcp_socket_bound_next != &server_socket_1)) + error_counter++; +} + +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +UINT status; +NX_TCP_HEADER *tcp_header_ptr; +ULONG *option_word_1; +ULONG checksum; +ULONG old_m; +ULONG new_m; + + /* Update the counter. */ + syn_counter ++; + + /* Check the counter. */ + if (syn_counter == 1) + { + + /* Update the packet prepend and length to include the IPv6 header. */ + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + /* Store the packet. */ + status = nx_packet_copy(packet_ptr, ©_packet, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + error_counter++; + } + else + { + + /* Update the packet IP header. */ + copy_packet -> nx_packet_ip_header = copy_packet -> nx_packet_prepend_ptr; + + /* Update the packet prepend and length. */ + copy_packet -> nx_packet_prepend_ptr += 40; + copy_packet -> nx_packet_length -= 40; + + /* Update the packet prepend and length to include the IPv6 header. */ + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get the TCP header pointer. */ + tcp_header_ptr = (NX_TCP_HEADER *) copy_packet -> nx_packet_prepend_ptr; + option_word_1 = (ULONG *)(tcp_header_ptr + 1); + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + + /* Get the old checksum (HC) in header. */ + checksum = tcp_header_ptr -> nx_tcp_header_word_4 >> 16; + + /* Get the old mss. */ + old_m = *option_word_1 & 0x0000FFFF;; + + /* Set the new TTL as 1. */ + new_m = 0; + + /* Update the mss value as zero. */ + *option_word_1 = NX_TCP_MSS_OPTION | new_m; + + /* Update the checksum, get the new checksum(HC'), + The new_m is ULONG value, so need get the lower value after invert. */ + checksum = ((~checksum) & 0xFFFF) + ((~old_m) & 0xFFFF) + new_m; + + /* Fold a 4-byte value into a two byte value */ + checksum = (checksum >> 16) + (checksum & 0xFFFF); + + /* Do it again in case previous operation generates an overflow */ + checksum = (checksum >> 16) + (checksum & 0xFFFF); + + /* Now store the new checksum in the IP header. */ + tcp_header_ptr -> nx_tcp_header_word_4 = ((tcp_header_ptr -> nx_tcp_header_word_4 & 0x0000FFFF) | ((~checksum) << 16)); + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(*option_word_1); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + } + } + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_relisten_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Relisten Test 2................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_socket_send_internal_test.c b/test/regression/netxduo_test/netx_tcp_socket_send_internal_test.c new file mode 100644 index 00000000..5121b2f5 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_send_internal_test.c @@ -0,0 +1,213 @@ +/* This NetX test concentrates on the branches coverage for _nx_tcp_socket_send_internal functions, + 697 [ + - ]: 1 : if (preempted == NX_TRUE) + + 706 [ + - ]: 1 : if (send_packet != packet_ptr) +*/ + +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET tcp_socket; +static UCHAR pool_area[8192]; +static UCHAR send_buffer[3000]; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static UINT thread1_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_send_internal_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + thread1_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pool_area, sizeof(pool_area)); + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Socket Send Internal Test............................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &tcp_socket, "TCP Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + + /* Set TCP socket as establish. */ + tcp_socket.nx_tcp_socket_state = NX_TCP_ESTABLISHED; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_version = NX_IP_VERSION_V4; + tcp_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4 = IP_ADDRESS(1, 2, 3, 5); + tcp_socket.nx_tcp_socket_connect_interface = &ip_0.nx_ip_interface[0]; + tcp_socket.nx_tcp_socket_bound_next = &tcp_socket; + tcp_socket.nx_tcp_socket_tx_window_advertised = 65535; + tcp_socket.nx_tcp_socket_tx_window_congestion = 65535; + tcp_socket.nx_tcp_socket_tx_outstanding_bytes = 0; + tcp_socket.nx_tcp_socket_mss = 216; + tcp_socket.nx_tcp_socket_transmit_sent_head = NX_NULL; + + + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append data. */ + status = nx_packet_data_append(packet_ptr, send_buffer, 100, &pool_0, NX_NO_WAIT); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let thread1 to check the state. */ + tx_thread_relinquish(); + + /* Send packet, get the mutex after check the socket state, . */ + status = _nx_tcp_socket_send_internal(&tcp_socket, packet_ptr, 2 * NX_IP_PERIODIC_RATE); + + if(status != NX_NOT_CONNECTED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Determine if the test was successful. */ + if ((thread1_counter != 1) || (error_counter)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ + + /* Update the counter. */ + thread1_counter ++; + + /* Place protection while we check the sequence number for the new TCP packet. */ + tx_mutex_get(&(ip_0.nx_ip_protection), TX_WAIT_FOREVER); + + /* Sleep one second. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Change the state. */ + tcp_socket.nx_tcp_socket_state = NX_TCP_CLOSED; + + /* Release the mutex before a blocking call. */ + tx_mutex_put(&(ip_0.nx_ip_protection)); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_send_internal_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Socket Send Internal Test.............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_socket_state_wait_test.c b/test/regression/netxduo_test/netx_tcp_socket_state_wait_test.c new file mode 100644 index 00000000..e758a973 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_state_wait_test.c @@ -0,0 +1,305 @@ +/* This NetX test concentrates on the TCP Socket state wait operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_state_wait_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT client_port; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket State Wait Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Clear the socket ID. */ + client_socket.nx_tcp_socket_id = NX_NULL; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, NX_NO_WAIT); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the socket ID. */ + client_socket.nx_tcp_socket_id = NX_TCP_ID; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_NOT_SUCCESSFUL) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete server socket*/ + nx_tcp_socket_disconnect(&server_socket, 0); + nx_tcp_server_socket_unaccept(&server_socket); + nx_tcp_server_socket_unlisten(&ip_1, 12); + nx_tcp_socket_delete(&server_socket); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Create the TCP socket server in 500 ticks. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&server_socket, NX_TCP_SYN_SENT, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status != NX_PTR_ERROR) + { + error_counter++; + } + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_state_wait_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Socket State Wait Test................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_socket_unaccept_test.c b/test/regression/netxduo_test/netx_tcp_socket_unaccept_test.c new file mode 100644 index 00000000..a24a66bc --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_unaccept_test.c @@ -0,0 +1,360 @@ +/* This NetX test concentrates on the TCP Socket unaccept operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket_0; +static NX_TCP_SOCKET client_socket_1; +static NX_TCP_SOCKET server_socket_0; +static NX_TCP_SOCKET server_socket_1; + +/* The 2 ports will hashed to the same index. */ +#define SERVER_PORT_0 0x00000100 +#define SERVER_PORT_1 0x00008100 + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_unaccept_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT client_port; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Unaccept Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_0, "Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket_0, client_port, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket_0, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT_0, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_1, "Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket_1, client_port, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket_1, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&client_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_0, "Server Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT_0, &server_socket_0, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the socket state. */ + if (server_socket_0.nx_tcp_socket_state != NX_TCP_LISTEN_STATE) + error_counter++; + + /* Unaccept server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket_0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check the socket state. */ + if (server_socket_0.nx_tcp_socket_state != NX_TCP_CLOSED) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_relisten(&ip_1, SERVER_PORT_0, &server_socket_0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket_0, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket_1, "Server Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT_1, &server_socket_1, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket_1, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket_1); + + /* Check for error. */ + if (status) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_unaccept_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Socket Unaccept Test..................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_socket_unbind_test.c b/test/regression/netxduo_test/netx_tcp_socket_unbind_test.c new file mode 100644 index 00000000..30174838 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_unbind_test.c @@ -0,0 +1,273 @@ +/* This NetX test concentrates on the TCP Socket Unbind operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket_0; +static NX_TCP_SOCKET client_socket_1; +static NX_TCP_SOCKET client_socket_2; +static NX_TCP_SOCKET client_socket_3; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + +/* The 2 ports will hashed to the same index. */ +#define CLIENT_PORT_1 0x00000100 +#define CLIENT_PORT_2 0x00008100 + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_unbind_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Unbind Cleanup Test 1.........................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket 0. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_0, "Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create a socket 1. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_1, "Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket 0. */ + status = nx_tcp_client_socket_bind(&client_socket_0, CLIENT_PORT_1, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket 1. */ + status = nx_tcp_client_socket_bind(&client_socket_1, CLIENT_PORT_2, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Let socket 2 bind to CLIENT_PORT_1. */ + tx_thread_relinquish(); + + /* Unbind the socket 0. */ + status = nx_tcp_client_socket_unbind(&client_socket_0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket 1. */ + status = nx_tcp_client_socket_unbind(&client_socket_1); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket 0. */ + status = nx_tcp_socket_delete(&client_socket_0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket 0. */ + status = nx_tcp_socket_delete(&client_socket_1); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Let thread 1 finish jobs */ + tx_thread_relinquish(); + + /* Check status. */ + if ((error_counter)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket 2. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_2, "Client Socket 2", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Bind the socket 2 to the port socket 0 has bound to */ + status = nx_tcp_client_socket_bind(&client_socket_2, CLIENT_PORT_1, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket 2. */ + status = nx_tcp_client_socket_unbind(&client_socket_2); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket 1. */ + status = nx_tcp_socket_delete(&client_socket_2); + + /* Check for error. */ + if (status) + error_counter++; + + +} + +static void thread_2_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket 3. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_3, "Client Socket 3", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket 3 to the port socket 0 has bound to */ + status = nx_tcp_client_socket_bind(&client_socket_3, CLIENT_PORT_1, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket 3. */ + status = nx_tcp_client_socket_unbind(&client_socket_3); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket 3. */ + status = nx_tcp_socket_delete(&client_socket_3); + + /* Check for error. */ + if (status) + error_counter++; + +} diff --git a/test/regression/netxduo_test/netx_tcp_socket_unbind_test2.c b/test/regression/netxduo_test/netx_tcp_socket_unbind_test2.c new file mode 100644 index 00000000..16ddbfd5 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_unbind_test2.c @@ -0,0 +1,192 @@ +/* This NetX test concentrates on the TCP Socket Unbind operation. */ + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET client_socket_0; +static NX_TCP_SOCKET client_socket_1; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + +/* The 2 ports will hashed to the same index. */ +#define CLIENT_PORT_1 0x00000100 +#define CLIENT_PORT_2 0x00008100 + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_unbind_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Unbind Cleanup Test 2.........................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket 0. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_0, "Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket 0. */ + status = nx_tcp_client_socket_bind(&client_socket_0, CLIENT_PORT_1, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Let socket 1 bind to CLIENT_PORT_1. */ + tx_thread_relinquish(); + + /* Unbind the socket 0. */ + status = nx_tcp_client_socket_unbind(&client_socket_0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket 0. */ + status = nx_tcp_socket_delete(&client_socket_0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Check status. */ + if ((error_counter)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket 2. */ + status = nx_tcp_socket_create(&ip_0, &client_socket_1, "Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Bind the socket 1 to the port socket 0 has bound to */ + status = nx_tcp_client_socket_bind(&client_socket_1, CLIENT_PORT_2, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unbind the socket 1. */ + status = nx_tcp_client_socket_unbind(&client_socket_1); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket 1. */ + status = nx_tcp_socket_delete(&client_socket_1); + + /* Check for error. */ + if (status) + error_counter++; + +} + diff --git a/test/regression/netxduo_test/netx_tcp_socket_unlisten_test.c b/test/regression/netxduo_test/netx_tcp_socket_unlisten_test.c new file mode 100644 index 00000000..c6791e53 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_socket_unlisten_test.c @@ -0,0 +1,184 @@ +/* This NetX test concentrates on the TCP Socket unaccept operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET server_socket[2]; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_socket_unlisten_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable TCP processing for IP instance. */ + status = nx_tcp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Socket Unlisten Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket[0], "Server Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 0x80, &server_socket[0], 5, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &server_socket[1], "Server Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_0, 0x81, &server_socket[1], 5, NX_NULL); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 0x82); + + /* Check for error. */ + if (status != NX_ENTRY_NOT_FOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 0x80); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_unlisten(&ip_0, 0x81); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_time_wait_to_close_test.c b/test/regression/netxduo_test/netx_tcp_time_wait_to_close_test.c new file mode 100644 index 00000000..3c747219 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_time_wait_to_close_test.c @@ -0,0 +1,242 @@ +/* This NetX test concentrates on TCP state change from TIME-WAIT to CLOSE. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_time_wait_to_close_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TCP TIME-WAIT to CLOSE Test..............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let server listen first. */ + tx_thread_relinquish(); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Check server state. */ + if (client_socket.nx_tcp_socket_state != NX_TCP_TIMED_WAIT) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for 2MSL. */ + tx_thread_sleep(_nx_tcp_2MSL_timer_rate + NX_IP_PERIODIC_RATE); + + /* Check server state. */ + if (client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + { + error_counter++; + } + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Let client disconnect first. */ + tx_thread_relinquish(); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_time_wait_to_close_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: TCP TIME-WAIT to CLOSE Test...............................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_tcp_transmit_cleanup_test.c b/test/regression/netxduo_test/netx_tcp_transmit_cleanup_test.c new file mode 100644 index 00000000..3417ceab --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_transmit_cleanup_test.c @@ -0,0 +1,427 @@ +/* This NetX test concentrates on the basic TCP operation. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +static void thread_3_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket); +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_transmit_cleanup_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_3, "thread 3", thread_3_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT compare_port; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Transmit Cleanup Test................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup a receive notify function. */ + status = nx_tcp_socket_receive_notify(&client_socket, thread_0_receive_notify); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Pickup the port for the client socket. */ + status = nx_tcp_client_socket_port_get(&client_socket, &compare_port); + + /* Check for error. */ + if ((status) || (client_port != compare_port)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. 220bytes. */ + my_packet -> nx_packet_length = 220; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 220; + + /* Check the TCP socket bind suspended count. */ + if (client_socket.nx_tcp_socket_transmit_suspended_count != 0) + error_counter++; + + /* Send the packet out, the window size of server socket is 100! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_WINDOW_OVERFLOW) + error_counter++; + + /* Check the TCP socket bind suspended count. */ + if (client_socket.nx_tcp_socket_transmit_suspended_count != 0) + error_counter++; + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. 220bytes. */ + my_packet -> nx_packet_length = 220; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 220; + + /* Check the TCP socket bind suspended count. */ + if (client_socket.nx_tcp_socket_transmit_suspended_count != 1) + error_counter++; + + /* Send the packet out, the window size of server socket is 100! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + +#ifdef __PRODUCT_NETXDUO__ + /* Check status. */ + if (status != NX_WINDOW_OVERFLOW) + error_counter++; +#else + if (status != NX_ALREADY_SUSPENDED) + error_counter++; +#endif + + /* Check the TCP socket transmit suspended count. */ + if (client_socket.nx_tcp_socket_transmit_suspended_count != 1) + error_counter++; +} + +static void thread_2_entry(ULONG thread_input) +{ + + +#ifdef __PRODUCT_NETXDUO__ + /* Check the TCP socket transmit suspended count. */ + if (client_socket.nx_tcp_socket_transmit_suspended_count != 2) + error_counter++; +#else + if (client_socket.nx_tcp_socket_transmit_suspended_count != 1) + error_counter++; +#endif +} + +static void thread_3_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket(window size = 100). */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup a receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, thread_1_receive_notify); + + /* Check for error. */ + if (status) + error_counter++; + + /* Configure the socket further. */ + status = nx_tcp_socket_transmit_configure(&server_socket, 10, 300, 10, 0); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Resume the test thread. */ + tx_thread_resume(&thread_1); + tx_thread_resume(&thread_2); +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; + else + connections++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket) +{ + + client_receives++; +} + + +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket) +{ + + server_receives++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_transmit_cleanup_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Transmit Cleanup Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_transmit_not_done_test.c b/test/regression/netxduo_test/netx_tcp_transmit_not_done_test.c new file mode 100644 index 00000000..f459b44d --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_transmit_not_done_test.c @@ -0,0 +1,299 @@ +/* This NetX test concentrates on the TCP transmitting packet is not done by driver before + * the socket is going to close. */ + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_transmit_not_done_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Transmit Not Done Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Let driver delay the packet for 1 second. */ + advanced_packet_process_callback = packet_process; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Verify the packet is queued in the TX queue. */ + if (client_socket.nx_tcp_socket_transmit_sent_count != 1) + { + error_counter++; + } + + /* Wakeup server thread. */ + tx_thread_resume(&thread_1); + + /* Disconnect this socket without waiting. */ + nx_tcp_socket_disconnect(&client_socket, NX_NO_WAIT); + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Wait 2 seconds and driver will release the transmitting packet. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Verify all packets are released. */ + if (pool_0.nx_packet_pool_available != pool_0.nx_packet_pool_total) + { + error_counter++; + } + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Let client thread run first. */ + tx_thread_suspend(&thread_1); + + /* Disconnect the server socket without waiting. */ + nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Delay 1 second. */ + *operation_ptr = NX_RAMDRIVER_OP_DELAY; + *delay_ptr = NX_IP_PERIODIC_RATE; + + advanced_packet_process_callback = NX_NULL; + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_transmit_not_done_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Transmit Not Done Test................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_transmit_under_interface_detach_test.c b/test/regression/netxduo_test/netx_tcp_transmit_under_interface_detach_test.c new file mode 100644 index 00000000..1e46c34b --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_transmit_under_interface_detach_test.c @@ -0,0 +1,288 @@ +/* This NetX test concentrates on the TCP Socket connect reset operation under interface deatch(tested transmit queue count and transmit suspension list). */ + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static TX_THREAD ntest_2; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static NX_TCP_SOCKET test_socket; + + +/* Define the counters used in the test application... */ + +static ULONG error_counter; +static ULONG ntest_2_counter; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_2_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_transmit_under_interface_detach_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_2, "thread 2", ntest_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Set the second interface. */ + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2, 2, 3, 4), 0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1, "Second Interface", IP_ADDRESS(2, 2, 3, 5), 0xFFFFFF00UL, _nx_ram_network_driver_256); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Transmit Under Interface Detach Test.................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 20, + NX_NULL, NX_NULL); + + /* Create a temp socket checked during interface detach. */ + status += nx_tcp_socket_create(&ip_0, &test_socket, "Test Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 20, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the client_socket port to 12. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_NO_WAIT); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(2, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Resume the thread 2. */ + tx_thread_resume(&ntest_2); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! This packe should not be sent. */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status == NX_SUCCESS) + { + error_counter++; + } + + /* Check the error counter. */ + if ((error_counter) || (ntest_2_counter != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* Define the test threads. */ + +static void ntest_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 20, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 2 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void ntest_2_entry(ULONG thread_input) +{ + +UINT status; + + /* Update the ntest_2_counter. */ + ntest_2_counter++; + + /* Check the TCP socket transmit suspended count. */ + if (client_socket.nx_tcp_socket_transmit_sent_count != 1) + error_counter++; + if (client_socket.nx_tcp_socket_transmit_suspension_list == NX_NULL) + error_counter++; + + /* Detach the second interface for IP instance 2. */ + status = nx_ip_interface_detach(&ip_0, 1); + + /* Check the status. */ + if (status) + error_counter++; + + /* Check the TCP socket transmit suspended count. */ + if (client_socket.nx_tcp_socket_transmit_sent_count != 0) + error_counter++; + if (client_socket.nx_tcp_socket_transmit_suspension_list != NX_NULL) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_transmit_under_interface_detach_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: TCP Transmit Under Interface Detach Test..................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv4_basic_test.c b/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv4_basic_test.c new file mode 100644 index 00000000..18502231 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv4_basic_test.c @@ -0,0 +1,466 @@ +/* This NetX IPsec basic test using AES. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if defined(NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_tunnel.h" +#define DEMO_STACK_SIZE 4096 + +#define MSG "abcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; +static CHAR rcv_buffer[200]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket); +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv4_ipv4_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_1500); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_1500); + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR *msg = MSG; + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV4_4 Basic Processing Test......."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020304; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020305; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V4,address_selector_0); + + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &msg[0], 26); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 26; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 26; + + /* Suspend thread1 */ + tx_thread_suspend(&thread_1); + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_resume(&thread_1); + + tx_thread_relinquish(); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG recv_length = 0; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020305; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020304; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V6,address_selector_1); + + if (status) + error_counter++; + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Suspend thread 0. */ + tx_thread_suspend(&thread_0); + + /* Receive a TCP message from the socket. */ + if(server_socket.nx_tcp_socket_receive_queue_head) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length = packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + } + + if(recv_length != 26) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; + else + connections++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; + else + disconnections++; +} + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket) +{ + + client_receives++; +} + + +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket) +{ + + server_receives++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv4_ipv4_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV4_4 Basic Processing Test...................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_address_test.c b/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_address_test.c new file mode 100644 index 00000000..b2e7aadd --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_address_test.c @@ -0,0 +1,419 @@ +/* This NetX IPsec basic test using AES. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_ipv6.h" + +#include "nx_tunnel.h" +#define DEMO_STACK_SIZE 4096 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; +NXD_ADDRESS ipv6_address_5; + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; +static CHAR rcv_buffer[200]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket); +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv4_ipv6_address_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_1500); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_1500); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + ipv6_address_5.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_5.nxd_ip_address.v6[0] = 0x40010000; + ipv6_address_5.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_5.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_5.nxd_ip_address.v6[3] = 0x20000005; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV4_6 ADDRESS Processing Test....."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* Add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address = ipv6_address_3; + address_selector_0.nx_selector_dst_tunnel_address = ipv6_address_5; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V6,address_selector_0); + + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + tx_thread_resume(&thread_1); + + tx_thread_relinquish(); + +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address = ipv6_address_5; + address_selector_1.nx_selector_dst_tunnel_address = ipv6_address_3; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V6,address_selector_1); + + if (status) + error_counter++; + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Suspend thread 0. */ + tx_thread_suspend(&thread_0); + + if ((client_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED) || (server_socket.nx_tcp_socket_state == NX_TCP_ESTABLISHED)) + { + error_counter++; + } + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; + else + connections++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; + else + disconnections++; +} + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket) +{ + + client_receives++; +} + + +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket) +{ + + server_receives++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv4_ipv6_address_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV4_6 ADDRESS Processing Test.................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_basic_test.c b/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_basic_test.c new file mode 100644 index 00000000..58d66aff --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_basic_test.c @@ -0,0 +1,502 @@ +/* This NetX IPsec basic test using AES. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_ipv6.h" +#include "nx_tunnel.h" +#define DEMO_STACK_SIZE 4096 + +#define MSG "abcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; +static CHAR rcv_buffer[200]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket); +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv4_ipv6_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_1500); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_1500); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR *msg = MSG; + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV4_6 Basic Processing Test......."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address = ipv6_address_3; + address_selector_0.nx_selector_dst_tunnel_address = ipv6_address_4; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V6,address_selector_0); + + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &msg[0], 26); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 26; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 26; + + /* Suspend thread1 */ + tx_thread_suspend(&thread_1); + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_resume(&thread_1); + + tx_thread_relinquish(); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG recv_length = 0; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address = ipv6_address_4; + address_selector_1.nx_selector_dst_tunnel_address = ipv6_address_3; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V6,address_selector_1); + + if (status) + error_counter++; + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Suspend thread 0. */ + tx_thread_suspend(&thread_0); + + /* Receive a TCP message from the socket. */ + if(server_socket.nx_tcp_socket_receive_queue_head) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length = packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + } + + if(recv_length != 26) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; + else + connections++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; + else + disconnections++; +} + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket) +{ + + client_receives++; +} + + +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket) +{ + + server_receives++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv4_ipv6_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV4_6 Basic Processing Test...................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_big_packet_test.c b/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_big_packet_test.c new file mode 100644 index 00000000..5d155bff --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_big_packet_test.c @@ -0,0 +1,515 @@ +/* This NetX IPsec basic test using AES. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_ipv6.h" +#include "nx_tunnel.h" +#define DEMO_STACK_SIZE 4096 + +#define MSG "abcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; +static CHAR rcv_buffer[2000]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket); +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv4_ipv6_big_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1660, pointer, 10248); + pointer = pointer + 8192; + + if (status) + error_counter++; + + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_1500); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_1500); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR *msg = MSG; + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV4_6 Big Packet Test............."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address = ipv6_address_3; + address_selector_0.nx_selector_dst_tunnel_address = ipv6_address_4; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V6,address_selector_0); + + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 2000, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &msg[0], 1460); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 1460; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 1460; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG recv_length = 0; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address = ipv6_address_4; + address_selector_1.nx_selector_dst_tunnel_address = ipv6_address_3; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V6,address_selector_1); + + if (status) + error_counter++; + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 2000, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Suspend thread 0. */ + tx_thread_suspend(&thread_0); + + /* Receive a TCP message from the socket. */ + if(server_socket.nx_tcp_socket_receive_queue_head) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + } + + /* Receive a TCP message from the socket. */ + if(server_socket.nx_tcp_socket_receive_queue_head) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length += packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + } + + if(recv_length != 1460) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; + else + connections++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; + else + disconnections++; +} + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket) +{ + + client_receives++; +} + + +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket) +{ + + server_receives++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv4_ipv6_big_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV4_6 Big Packet Test.........................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_small_windows_test.c b/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_small_windows_test.c new file mode 100644 index 00000000..7b52e94a --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_tunnel_ipv4_ipv6_small_windows_test.c @@ -0,0 +1,626 @@ +/* This NetX IPsec basic test using AES. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_ipv6.h" +#include "nx_tunnel.h" +#define DEMO_STACK_SIZE 4096 + +#define MSG "abcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; +static CHAR rcv_buffer[200]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket); +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv4_ipv6_samll_windows_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_256); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR *msg = MSG; +ULONG start_time; +ULONG end_time; + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV4_6 Small Windows Test.........."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address = ipv6_address_3; + address_selector_0.nx_selector_dst_tunnel_address = ipv6_address_4; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V6,address_selector_0); + + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 128, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Send 5 packets... the 5th packet should block because of the window size. */ + + /* Allocate a 1st packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a 2nd packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a 3rd packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a 4th packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a 5th packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Remember the starting time. */ + start_time = tx_time_get(); + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Get the end time. */ + end_time = tx_time_get(); + + /* Determine if the status is valid. */ + if ((status) || (end_time > (start_time+4))) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_resume(&thread_1); + + tx_thread_relinquish(); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG recv_length = 0; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address = ipv6_address_4; + address_selector_1.nx_selector_dst_tunnel_address = ipv6_address_3; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V6,address_selector_1); + + if (status) + error_counter++; + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 128, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Suspend thread 0. */ + tx_thread_suspend(&thread_0); + + /* Receive five TCP messages from the socket - 1st packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive five TCP messages from the socket - 2nd packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive five TCP messages from the socket - 3rd packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive five TCP messages from the socket - 4th packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive five TCP messages from the socket - 5th packet. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if ((status) || (packet_ptr -> nx_packet_length != 28)) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; + else + connections++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; + else + disconnections++; +} + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket) +{ + client_receives++; +} + + +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket) +{ + + server_receives++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv4_ipv6_samll_windows_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV4_6 Small Windows Test......................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_tunnel_ipv6_ipv4_basic_test.c b/test/regression/netxduo_test/netx_tcp_tunnel_ipv6_ipv4_basic_test.c new file mode 100644 index 00000000..d8d008c6 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_tunnel_ipv6_ipv4_basic_test.c @@ -0,0 +1,521 @@ +/* This NetX IPsec basic test using AES. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_ipv6.h" +#include "nx_tunnel.h" +#define DEMO_STACK_SIZE 4096 + +#define MSG "abcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; +static CHAR rcv_buffer[200]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket); +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv6_ipv4_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_1500); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_1500); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR *msg = MSG; + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV6_4 Basic Processing Test......."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020304; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020305; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V4,address_selector_0); + + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &msg[0], 26); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 26; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 26; + + /* Suspend thread1 */ + tx_thread_suspend(&thread_1); + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 4 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_resume(&thread_1); + + tx_thread_relinquish(); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG recv_length = 0; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020305; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020304; + + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V4,address_selector_1); + + if (status) + error_counter++; + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Supsend thread 0. */ + tx_thread_suspend(&thread_0); + + /* Receive a TCP message from the socket. */ + if(server_socket.nx_tcp_socket_receive_queue_head) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length = packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + } + + if(recv_length != 26) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + tx_thread_resume(&thread_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; + else + connections++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; + else + disconnections++; +} + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket) +{ + + client_receives++; +} + + +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket) +{ + + server_receives++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv6_ipv4_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV6_4 Basic Processing Test...................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_tunnel_ipv6_ipv6_basic_test.c b/test/regression/netxduo_test/netx_tcp_tunnel_ipv6_ipv6_basic_test.c new file mode 100644 index 00000000..1643ce13 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_tunnel_ipv6_ipv6_basic_test.c @@ -0,0 +1,517 @@ +/* This NetX IPsec basic test using AES. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) +#include "nx_ipv6.h" +#include "nx_tunnel.h" +#define DEMO_STACK_SIZE 4096 + +#define MSG "abcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static ULONG connections = 0; +static ULONG disconnections = 0; +static ULONG client_receives = 0; +static ULONG server_receives = 0; +static UINT client_port; +static CHAR rcv_buffer[200]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket); +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv6_ipv6_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + connections = 0; + disconnections = 0; + client_receives = 0; + server_receives = 0; + client_port = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_1500); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_1500); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR *msg = MSG; + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV6_6 Basic Processing Test......."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address = ipv6_address_3; + address_selector_0.nx_selector_dst_tunnel_address = ipv6_address_4; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V6,address_selector_0); + + if (status) + error_counter++; + + /* Get a free port for the client's use. */ + status = nx_tcp_free_port_find(&ip_0, 1, &client_port); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, client_port, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + + status = nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_2, 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Wait for established state. */ + status = nx_tcp_socket_state_wait(&client_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &msg[0], 26); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 26; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 26; + + /* Suspend thread1 */ + tx_thread_suspend(&thread_1); + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 4 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_resume(&thread_1); + + tx_thread_relinquish(); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG recv_length = 0; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address = ipv6_address_4; + address_selector_1.nx_selector_dst_tunnel_address = ipv6_address_3; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V6,address_selector_1); + + if (status) + error_counter++; + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Supsend thread 0. */ + tx_thread_suspend(&thread_0); + + /* Receive a TCP message from the socket. */ + if(server_socket.nx_tcp_socket_receive_queue_head) + { + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length = packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + } + + if(recv_length != 26) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + tx_thread_resume(&thread_0); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; + else + connections++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; + else + disconnections++; +} + +static void thread_0_receive_notify(NX_TCP_SOCKET *client_socket) +{ + + client_receives++; +} + + +static void thread_1_receive_notify(NX_TCP_SOCKET *server_socket) +{ + + server_receives++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tunnel_ipv6_ipv6_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL TCP IPV6_6 Basic Processing Test...................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_tx_queue_exceed_test.c b/test/regression/netxduo_test/netx_tcp_tx_queue_exceed_test.c new file mode 100644 index 00000000..748862d4 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_tx_queue_exceed_test.c @@ -0,0 +1,316 @@ +/* This NetX test concentrates on the TCP TX queue exceed. */ + +#include "nx_api.h" +#include "nx_tcp.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + +static UCHAR pool_area[1024 * 1024]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tx_queue_exceed_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pool_area, sizeof(pool_area)); + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: TCP TX Queue Exceed Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Drop ACK from server to client. */ + ip_0.nx_ip_tcp_packet_receive = tcp_packet_receive; + + for (i = 0; i < NX_TCP_MAXIMUM_TX_QUEUE + 2; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_NO_WAIT); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "A", 1, &pool_0, 2 * NX_NO_WAIT); + if(status) + error_counter++; + + /* Send the packet out! */ + if (i == (NX_TCP_MAXIMUM_TX_QUEUE + 1)) + { + status = nx_tcp_socket_send(&client_socket, my_packet, NX_NO_WAIT); + } + else + { + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + } + + if (i < NX_TCP_MAXIMUM_TX_QUEUE) + { + + /* For first NX_TCP_MAXIMUM_TX_QUEUE packets, send should be always success. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + else + { + + /* Queue depth exceeded. */ + if (status != NX_TX_QUEUE_DEPTH) + { + error_counter++; + } + else + { + nx_packet_release(my_packet); + } + } + } + + /* Recover TCP packet process from server to client. */ + ip_0.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Wakeup server thread. */ + tx_thread_resume(&thread_1); + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Wait until client thread finishes testing. */ + tx_thread_suspend(&thread_1); + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + + +static VOID tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + /* Drop packet from server to client. */ + nx_packet_release(packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_tx_queue_exceed_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP TX Queue Exceed Test..................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_udp_random_port_test.c b/test/regression/netxduo_test/netx_tcp_udp_random_port_test.c new file mode 100644 index 00000000..aa1c97a3 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_udp_random_port_test.c @@ -0,0 +1,215 @@ +/* This NetX test concentrates on the TCP and UDP free port find. + * The port is random but not incremental. Follow section 3.3.1, RFC 6056. */ + + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_LOOP 100 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_TCP_SOCKET tcp_socket[2]; +static NX_UDP_SOCKET udp_socket[2]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void test_control_return(UINT status); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_udp_random_port_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&ip_0); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UCHAR not_incremental; +UINT status; +UINT previous_port; +UINT port; +UINT i; + + + /* Print out some test information banners. */ + printf("NetX Test: TCP UDP Random Port Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket. */ + nx_tcp_socket_create(&ip_0, &tcp_socket[0], "TCP Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + nx_tcp_socket_create(&ip_0, &tcp_socket[1], "TCP Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + status = nx_tcp_client_socket_bind(&tcp_socket[1], NX_ANY_PORT, NX_WAIT_FOREVER); + if (status != NX_SUCCESS) + error_counter++; + + /* TCP random port test. */ + not_incremental = NX_FALSE; + nx_tcp_client_socket_port_get(&tcp_socket[1], &previous_port); + + for (i = 0; i < TEST_LOOP; i++) + { + + previous_port++; + if (previous_port == NX_MAX_PORT) + { + previous_port = 1; + } + status = nx_tcp_client_socket_bind(&tcp_socket[i & 1], NX_ANY_PORT, NX_WAIT_FOREVER); + if (status != NX_SUCCESS) + error_counter++; + + nx_tcp_client_socket_port_get(&tcp_socket[i & 1], &port); + + /* Check whether free_port is increased by one of previous_port. */ + if (port != previous_port) + { + not_incremental = NX_TRUE; + } + + nx_tcp_client_socket_unbind(&tcp_socket[1 - (i & 1)]); + + previous_port = port; + } + + if (not_incremental == NX_FALSE) + { + error_counter++; + } + + /* Create a UDP socket. */ + nx_udp_socket_create(&ip_0, &udp_socket[0], "UDP Socket 0", NX_IP_NORMAL, + NX_FRAGMENT_OKAY, 0x80, 5); + nx_udp_socket_create(&ip_0, &udp_socket[1], "UDP Socket 1", NX_IP_NORMAL, + NX_FRAGMENT_OKAY, 0x80, 5); + + status = nx_udp_socket_bind(&udp_socket[1], NX_ANY_PORT, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + error_counter++; + + /* UDP random port test. */ + not_incremental = NX_FALSE; + nx_udp_socket_port_get(&udp_socket[1], &previous_port); + + for (i = 0; i < TEST_LOOP; i++) + { + + previous_port++; + if (previous_port == NX_MAX_PORT) + { + previous_port = 1; + } + status = nx_udp_socket_bind(&udp_socket[i & 1], NX_ANY_PORT, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + error_counter++; + + nx_udp_socket_port_get(&udp_socket[i & 1], &port); + + /* Check whether free_port is increased by one of previous_port. */ + if (port != previous_port) + { + not_incremental = NX_TRUE; + } + + nx_udp_socket_unbind(&udp_socket[1 - (i & 1)]); + + previous_port = port; + } + + if (not_incremental == NX_FALSE) + { + error_counter++; + } + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} diff --git a/test/regression/netxduo_test/netx_tcp_urgent_packet_test.c b/test/regression/netxduo_test/netx_tcp_urgent_packet_test.c new file mode 100644 index 00000000..f1ba24da --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_urgent_packet_test.c @@ -0,0 +1,337 @@ +/* This NetX test concentrates on the TCP urgent packet operation. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#include "nx_tcp.h" +#include "nx_ip.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +#define CLIENT_PORT 0x88 +#define SERVER_PORT 0x89 + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT urg_received = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static VOID tcp_urgent_data_callback(NX_TCP_SOCKET *socket_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_urgent_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + /* Check the status. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check the status. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Urgent Packet Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, CLIENT_PORT, NX_NO_WAIT); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Call connect to establish connection. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), SERVER_PORT, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check the client and server socket state. */ + if ((client_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED) || (server_socket.nx_tcp_socket_state != NX_TCP_ESTABLISHED)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write send_buff into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ12", 28, &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set the callback function. */ + ip_1.nx_ip_tcp_packet_receive = my_tcp_packet_receive; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check status. */ + if ((error_counter) || (urg_received != 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_status; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100, + tcp_urgent_data_callback, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; +} + +static VOID tcp_urgent_data_callback(NX_TCP_SOCKET *socket_ptr) +{ + urg_received++; +} + +static void my_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_TCP_HEADER *tcp_header_ptr; +ULONG checksum; +ULONG *source_ip, *dest_ip; + + /* Check if it is a data packet (TCP(20) + DATA(28)). */ + if (packet_ptr ->nx_packet_length == 48) + { + + /* Set the tcp header pointer. */ + tcp_header_ptr = (NX_TCP_HEADER *) packet_ptr ->nx_packet_prepend_ptr; + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Set the URG bit. */ + tcp_header_ptr -> nx_tcp_header_word_3 = (tcp_header_ptr -> nx_tcp_header_word_3 | NX_TCP_URG_BIT); + + /* Swap the endianess. */ + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr ->nx_tcp_header_word_3); + + /* Clear the checksum field. */ + tcp_header_ptr -> nx_tcp_header_word_4 = 0; + + /* Calculate the checksum . */ + dest_ip = &client_socket.nx_tcp_socket_connect_ip.nxd_ip_address.v4; + source_ip = &client_socket.nx_tcp_socket_connect_interface -> nx_interface_ip_address; + checksum = _nx_ip_checksum_compute(packet_ptr, NX_PROTOCOL_TCP, + packet_ptr -> nx_packet_length, + source_ip, dest_ip); + checksum = ~checksum & NX_LOWER_16_MASK; + tcp_header_ptr -> nx_tcp_header_word_4 = (checksum << NX_SHIFT_BY_16); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_4); + } + + /* Clear the callback function. */ + ip_1.nx_ip_tcp_packet_receive = _nx_tcp_packet_receive; + + /* Let server receive the packet. */ + _nx_tcp_packet_receive(ip_ptr, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_urgent_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Urgent Packet Test....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_window_update_test.c b/test/regression/netxduo_test/netx_tcp_window_update_test.c new file mode 100644 index 00000000..23ea06f5 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_window_update_test.c @@ -0,0 +1,314 @@ +/* If the ACK is a duplicate, the window size can be ignored. Page 72, Section 3.9, RFC 793. */ + +/* Procedure +1. Client socket connects to server socket. +2. Client sends five packets to server. The size of each packet is 1/5 of window size. Then the send window should be zero. +3. Drop the second packet from client to server. +4. Try to send 1/5 of window size from client to server without wait. It should fail since send window is zero. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static NX_PACKET *drop_packet = NX_NULL; + +/* Define the counters used in the test application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_window_update_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_512, + pointer, 2048, 2); + pointer = pointer + 2048; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if(status) + error_counter++; +} + +/* Define the test threads. */ +static UCHAR send_buffer[200]; + +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +UINT i; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: TCP Window Update Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_relinquish(); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, 1 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; + + /* The callback function is used to drop the second data packet. */ + advanced_packet_process_callback = my_packet_process; + + /* Connect to server. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 1 * NX_IP_PERIODIC_RATE); + + /* Check the connection status. */ + if(status != NX_SUCCESS) + error_counter++; + + /* Send two packets. */ + for(i = 0; i < 2; i++) + { + + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + else + { + status = nx_packet_data_append(packet_ptr, send_buffer, sizeof(send_buffer), &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + } + + /* Send the pacekt. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, 0); + if(status != NX_SUCCESS) + error_counter++; + } + + /* Wait ACK packet. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + else + { + status = nx_packet_data_append(packet_ptr, send_buffer, sizeof(send_buffer), &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + } + + /* Drop the packet. */ + drop_packet = packet_ptr; + + /* Send the pacekt. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, 0); + if(status != NX_SUCCESS) + error_counter++; + + /* Send two packets. */ + for(i = 0; i < 2; i++) + { + + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + else + { + status = nx_packet_data_append(packet_ptr, send_buffer, sizeof(send_buffer), &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + } + + /* Send the pacekt. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, 0); + if(status != NX_SUCCESS) + error_counter++; + } + + /* Allocate a packet and fill data. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + else + { + status = nx_packet_data_append(packet_ptr, send_buffer, sizeof(send_buffer), &pool_0, 1 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + } + + /* Send the pacekt. Since window is full, send call should not be successful. */ + status = nx_tcp_socket_send(&client_socket, packet_ptr, 0); + if(status == NX_SUCCESS) + error_counter++; + + /* Determine if the test was successful. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static void ntest_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, sizeof(send_buffer) * 5, + NX_NULL, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if(status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if(status) + error_counter++; +} + +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + if(packet_ptr == drop_packet) + { + + /* This packet should be dropped. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + drop_packet = NX_NULL; + return NX_TRUE; + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_window_update_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Window Update Test....................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test.c b/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test.c new file mode 100644 index 00000000..b9677612 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test.c @@ -0,0 +1,488 @@ +/* This NetX test concentrates on the wrapping of RX and TX sequence numbers. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_1_connect_received(NX_TCP_SOCKET *server_socket, UINT port); +static void thread_1_disconnect_received(NX_TCP_SOCKET *server_socket); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_wrapping_sequence_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + + /* Print out test information banner. */ + printf("NetX Test: TCP Wrapping RX/TX Sequence Test.........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + tx_thread_relinquish(); + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + tx_thread_relinquish(); + + /* Loop to repeat things over and over again! */ + thread_0_counter = 0; + while ((thread_0_counter < 2000) && (!error_counter)) + { + + /* Increment thread 0's counter. */ + thread_0_counter++; + + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_suspend(&thread_0); + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Determine if the test was successful. */ + if ((error_counter) || (thread_0_counter != 2000) || (thread_1_counter != 2000)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +ULONG sequence_increment = 1; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + + /* Check status... */ + if (status != NX_SUCCESS) + { + + error_counter++; + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, + NX_NULL, thread_1_disconnect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, thread_1_connect_received); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Supsend thread 0. */ + tx_thread_suspend(&thread_0); + nx_tcp_socket_state_wait(&server_socket, NX_TCP_ESTABLISHED, 2 * NX_IP_PERIODIC_RATE); + tx_thread_resume(&thread_0); + + /* Set all the sequence numbers the way we want them for our test. */ + client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00; + client_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00; + client_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00; + server_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00; + server_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00; + server_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00; + + /* Loop to create and establish server connections. */ + thread_1_counter = 0; + while ((thread_1_counter < 2000) && (!error_counter)) + { + + /* Increment thread 1's counter. */ + thread_1_counter++; + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Receive a TCP message from the socket. */ + server_socket.nx_tcp_socket_rx_window_last_sent = 0; /* Force an ACK out! */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + else + /* Release the packet. */ + nx_packet_release(packet_ptr); + + /* Set all the sequence numbers the way we want them for our test. */ + if ((server_socket.nx_tcp_socket_rx_sequence < 0xFFFFFF00) && + (server_socket.nx_tcp_socket_rx_sequence > 0x100)) + { + client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + client_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + client_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00 + (sequence_increment & 0xFF); + server_socket.nx_tcp_socket_tx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + server_socket.nx_tcp_socket_rx_sequence = 0xFFFFFF00 + (sequence_increment & 0xFF); + server_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFF00 + (sequence_increment++ & 0xFF); + } + + /* Resume thread 0. */ + tx_thread_resume(&thread_0); + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup server socket for listening again. */ + status = nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + + /* Check for error. */ + if (status) + error_counter++; +} + + +static void thread_1_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port) +{ + + /* Check for the proper socket and port. */ + if ((socket_ptr != &server_socket) || (port != 12)) + error_counter++; +} + + +static void thread_1_disconnect_received(NX_TCP_SOCKET *socket) +{ + + /* Check for proper disconnected socket. */ + if (socket != &server_socket) + error_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_wrapping_sequence_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Wrapping RX/TX Sequence Test..........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test2.c b/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test2.c new file mode 100644 index 00000000..8b16494e --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test2.c @@ -0,0 +1,324 @@ +/* This NetX test concentrates on the wrapping of TX sequence numbers. */ +/* Client sends two packets with sequences: + * 0xFFFFFFEF ~ 0xFFFFFFFE, length is 16, + * 0xFFFFFFFF ~ 0x0000000E, length is 16. + * The seconds packet is dropped. + * Server will ACK 0xFFFFFFFF. + * + * Packets like following. + * + * | | | + * ---- -------- ---- + * ^ + * | + * ACK + */ + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_wrapping_sequence_test2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Wrapping Sequence Test 2.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Set all the sequence numbers the way we want them for our test. */ + client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFFEF; + server_socket.nx_tcp_socket_rx_sequence = 0xFFFFFFEF; + server_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFFEF; + + for (i = 0; i < 2; i++) + { + + if (i == 1) + { + + /* Set driver filter to drop the second packet. */ + advanced_packet_process_callback = packet_process; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOP", 16, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +UINT i; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + for (i = 0; i < 2; i++) + { + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOP", 16)) + error_counter++; + + nx_packet_release(packet_ptr); + } + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Simply drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + advanced_packet_process_callback = NX_NULL; + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_wrapping_sequence_test2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Wrapping Sequence Test 2..............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test3.c b/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test3.c new file mode 100644 index 00000000..f6526a57 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test3.c @@ -0,0 +1,324 @@ +/* This NetX test concentrates on the wrapping of TX sequence numbers. */ +/* Client sends two packets with sequences: + * 0xFFFFFFFF ~ 0x0000000E, length is 16, + * 0x0000000F ~ 0x0000001E, length is 16. + * The seconds packet is dropped. + * Server will ACK 0x0000000F. + * + * Packets like following. + * + * | | | + * ---- -------- ---- + * ^ + * | + * ACK + */ + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_wrapping_sequence_test3_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Wrapping Sequence Test 3.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Set all the sequence numbers the way we want them for our test. */ + client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFFFF; + server_socket.nx_tcp_socket_rx_sequence = 0xFFFFFFFF; + server_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFFFF; + + for (i = 0; i < 2; i++) + { + + if (i == 1) + { + + /* Set driver filter to drop the second packet. */ + advanced_packet_process_callback = packet_process; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOP", 16, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +UINT i; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + for (i = 0; i < 2; i++) + { + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOP", 16)) + error_counter++; + + nx_packet_release(packet_ptr); + } + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Simply drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + advanced_packet_process_callback = NX_NULL; + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_wrapping_sequence_test3_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Wrapping Sequence Test 3..............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test4.c b/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test4.c new file mode 100644 index 00000000..042a6ade --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_wrapping_sequence_test4.c @@ -0,0 +1,325 @@ +/* This NetX test concentrates on the wrapping of TX sequence numbers. */ +/* Client sends three packets with sequences: + * 0xFFFFFFDF ~ 0xFFFFFFEE, length is 16, + * 0xFFFFFFEF ~ 0xFFFFFFFE, length is 16. + * 0xFFFFFFFF ~ 0x0000000E, length is 16. + * The seconds packet is dropped. + * Server will ACK 0xFFFFFFF0. + * + * Packets like following. + * + * | | | | + * ---- -------- -------- ---- + * ^ + * | + * ACK + */ + +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_wrapping_sequence_test4_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Wrapping Sequence Test 4.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 0x88, NX_WAIT_FOREVER); + if (status) + error_counter++; + + /* Attempt to connect the socket. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Set all the sequence numbers the way we want them for our test. */ + client_socket.nx_tcp_socket_tx_sequence = 0xFFFFFFDF; + server_socket.nx_tcp_socket_rx_sequence = 0xFFFFFFDF; + server_socket.nx_tcp_socket_rx_sequence_acked = 0xFFFFFFDF; + + for (i = 0; i < 3; i++) + { + + if (i == 1) + { + + /* Set driver filter to drop the second packet. */ + advanced_packet_process_callback = packet_process; + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + if (status) + error_counter++; + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOP", 16, &pool_0, 2 * NX_IP_PERIODIC_RATE); + if(status) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + } + + /* Disconnect this socket. */ + status = nx_tcp_socket_disconnect(&client_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unbind the socket. */ + status = nx_tcp_client_socket_unbind(&client_socket); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&client_socket); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG actual_status; +UINT i; + + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 65535, + NX_NULL, NX_NULL); + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + for (i = 0; i < 3; i++) + { + + /* Receive a TCP message from the socket. */ + status = nx_tcp_socket_receive(&server_socket, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + if(memcmp(packet_ptr -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOP", 16)) + error_counter++; + + nx_packet_release(packet_ptr); + } + } + + /* Disconnect the server socket. */ + status = nx_tcp_socket_disconnect(&server_socket, 5 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Unaccept the server socket. */ + status = nx_tcp_server_socket_unaccept(&server_socket); + if (status) + error_counter++; + + /* Unlisten on the server port 12. */ + status = nx_tcp_server_socket_unlisten(&ip_1, 12); + if (status) + error_counter++; + + /* Delete the socket. */ + status = nx_tcp_socket_delete(&server_socket); + if (status) + error_counter++; + +} + + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Simply drop the packet. */ + *operation_ptr = NX_RAMDRIVER_OP_DROP; + advanced_packet_process_callback = NX_NULL; + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_wrapping_sequence_test4_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Wrapping Sequence Test 4..............................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_tcp_zero_window_probe_2_test.c b/test/regression/netxduo_test/netx_tcp_zero_window_probe_2_test.c new file mode 100644 index 00000000..1d1e9eb0 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_zero_window_probe_2_test.c @@ -0,0 +1,357 @@ +/* This case verifies bug reported by trac #138. + * https://192.168.100.2/trac/netx/ticket/138 */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define WINDOW_SIZE 200 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static UCHAR send_buff[WINDOW_SIZE << 1]; +static UCHAR recv_buff[WINDOW_SIZE << 1]; +static UCHAR zero_window_probe = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static ULONG packet_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_zero_window_probe_test_2_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Zero Window Probe Test 2.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Generate the data for send_buff. */ + for (i = 0; i < sizeof(send_buff); i++) + { + send_buff[i] = i & 0xFF; + recv_buff[i] = 0; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, WINDOW_SIZE, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Establish the connection. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = client_driver_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write send_buff into the packet payload! */ + status = nx_packet_data_append(my_packet, send_buff, WINDOW_SIZE, &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write send_buff into the packet payload! */ + status = nx_packet_data_append(my_packet, send_buff + WINDOW_SIZE, WINDOW_SIZE, &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE * 5); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Check status. */ + if ((error_counter) || (zero_window_probe == NX_FALSE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +UINT total = 0; +ULONG bytes_copied; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, WINDOW_SIZE, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Sleep three seconds. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE * 3); + + /* Receive all data. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + /* Retrieve data. */ + nx_packet_data_retrieve(packet_ptr, recv_buff + total, &bytes_copied); + total += bytes_copied; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if (total != sizeof(send_buff)) + { + error_counter++; + } + else if (memcmp(send_buff, recv_buff, total) != 0) + { + error_counter++; + } +} + +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Ignore the server packet. */ + if (ip_ptr != &ip_0) + return NX_TRUE; + + /* Update the packet counter. */ + packet_counter ++; + + /* Check the packet information. */ + if (packet_counter == 1) + { + + /* Check the packet length. */ + if (packet_ptr -> nx_packet_length != (WINDOW_SIZE + 40)) + error_counter ++; + } + + /* Check the packet information. */ + else if (packet_counter == 2) + { + + /* Check the packet length. */ + if ((packet_ptr -> nx_packet_length == (1 + 40)) && + (*(packet_ptr -> nx_packet_append_ptr - 1) == send_buff[WINDOW_SIZE])) + { + zero_window_probe = NX_TRUE; + + /* Increase the receive window by one byte. */ + server_socket.nx_tcp_socket_rx_window_current++; + } + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_zero_window_probe_test_2_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Zero Window Probe Test 2..............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_zero_window_probe_3_test.c b/test/regression/netxduo_test/netx_tcp_zero_window_probe_3_test.c new file mode 100644 index 00000000..6ed6e39b --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_zero_window_probe_3_test.c @@ -0,0 +1,396 @@ +/* This case verifies bug reported by work item #2252. + https://expresslogic.visualstudio.com/X-Ware/_workitems/edit/2252/ +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define WINDOW_SIZE 200 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static UCHAR send_buff[WINDOW_SIZE << 1]; +static UCHAR recv_buff[WINDOW_SIZE << 1]; +static UCHAR zero_window_probe = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static ULONG client_packet_counter = 0; +static ULONG server_packet_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_zero_window_probe_test_3_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Zero Window Probe Test 3.............................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Generate the data for send_buff. */ + for (i = 0; i < sizeof(send_buff); i++) + { + send_buff[i] = i & 0xFF; + recv_buff[i] = 0; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, WINDOW_SIZE, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Establish the connection. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = client_driver_packet_process; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write send_buff into the packet payload! */ + status = nx_packet_data_append(my_packet, send_buff, WINDOW_SIZE, &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write send_buff into the packet payload! */ + status = nx_packet_data_append(my_packet, send_buff + WINDOW_SIZE, WINDOW_SIZE, &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE * 5); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +UINT total = 0; +ULONG bytes_copied; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, WINDOW_SIZE, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Sleep three seconds. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE * 3); + + /* Receive all data. */ + while (nx_tcp_socket_receive(&server_socket, &packet_ptr, NX_IP_PERIODIC_RATE) == NX_SUCCESS) + { + + /* Retrieve data. */ + nx_packet_data_retrieve(packet_ptr, recv_buff + total, &bytes_copied); + total += bytes_copied; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if (total != sizeof(send_buff)) + { + error_counter++; + } + else if (memcmp(send_buff, recv_buff, total) != 0) + { + error_counter++; + } + + /* Check status. */ + if ((error_counter) || (zero_window_probe == NX_FALSE) || (client_packet_counter != 4) +#ifndef NX_ENABLE_TCP_KEEPALIVE + || (server_packet_counter != 7) +#endif + ) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +//#define TEST_INFO + +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +#ifdef TEST_INFO +NX_TCP_HEADER *header_ptr; +ULONG seq_number, ack_number, window_size; + + /* Get TCP header. */ +#ifdef FEATURE_NX_IPV6 + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 40); +#else + header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr + 20); +#endif + + /* Get window size and ACK number. */ + seq_number = header_ptr -> nx_tcp_sequence_number; + ack_number = header_ptr -> nx_tcp_acknowledgment_number; + window_size = header_ptr -> nx_tcp_header_word_3; + NX_CHANGE_ULONG_ENDIAN(seq_number); + NX_CHANGE_ULONG_ENDIAN(ack_number); + NX_CHANGE_ULONG_ENDIAN(window_size); + window_size = window_size & NX_LOWER_16_MASK; +#endif + + /* Ignore the server packet. */ + if (ip_ptr != &ip_0) + { + + server_packet_counter++; +#ifdef TEST_INFO + printf("\nserver %d seq: %d, ack: %d, window: %d, length: %d\n", server_packet_counter, seq_number, ack_number, window_size, packet_ptr -> nx_packet_length); +#endif + return NX_TRUE; + } + + /* Update the packet counter. */ + client_packet_counter++; +#ifdef TEST_INFO + printf("\nclient %d seq: %d, ack: %d, window: %d, length: %d", client_packet_counter, seq_number, ack_number, window_size, packet_ptr -> nx_packet_length); +#endif + + /* Check the packet information. */ + if (client_packet_counter == 1) + { + + /* Check the packet length. */ + if (packet_ptr -> nx_packet_length != (WINDOW_SIZE + 40)) + error_counter ++; + } + + /* Check the packet information. */ + else if (client_packet_counter == 2) + { + + /* Check the packet length. */ + if ((packet_ptr -> nx_packet_length == (1 + 40)) && + (*(packet_ptr -> nx_packet_append_ptr - 1) == send_buff[WINDOW_SIZE])) + { + + zero_window_probe = NX_TRUE; + + /* Increase the receive window by one byte. */ + server_socket.nx_tcp_socket_rx_window_current += WINDOW_SIZE; + } + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_zero_window_probe_test_3_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Zero Window Probe Test 3..............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_zero_window_probe_test.c b/test/regression/netxduo_test/netx_tcp_zero_window_probe_test.c new file mode 100644 index 00000000..7c602256 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_zero_window_probe_test.c @@ -0,0 +1,359 @@ +/* This case tests zero window probe is implemented. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define WINDOW_SIZE 200 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static UCHAR send_buff[WINDOW_SIZE]; +static UCHAR zero_window_probe = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static ULONG packet_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_zero_window_probe_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create a packet pool with payload not four bytes aligned. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + /* Print out some test information banners. */ + printf("NetX Test: TCP Zero Window Probe Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Generate the data for send_buff. */ + for (i = 0; i < sizeof(send_buff); i++) + send_buff[i] = (CHAR)rand(); + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, WINDOW_SIZE, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Establish the connection. */ + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_IP_PERIODIC_RATE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Deal the packet with my routing. */ + advanced_packet_process_callback = client_driver_packet_process; + + /* Deal the packet with my routing. */ + ip_0.nx_ip_tcp_packet_receive = client_tcp_packet_receive; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write send_buff into the packet payload! */ + status = nx_packet_data_append(my_packet, send_buff, WINDOW_SIZE/2, &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write send_buff into the packet payload! */ + status = nx_packet_data_append(my_packet, &send_buff[WINDOW_SIZE/2], WINDOW_SIZE/2, &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Modify the advertised window to zero to act as that received the ACK with zero window.*/ + client_socket.nx_tcp_socket_tx_window_advertised = 0; + + /* Sleep two seconds. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((error_counter) || (zero_window_probe == NX_FALSE)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, WINDOW_SIZE, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; +} + +static UINT client_driver_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Ingore the server packet. */ + if (ip_ptr != &ip_0) + return NX_TRUE; + + /* Update the packet counter. */ + packet_counter ++; + + /* Check the packet information. */ + if (packet_counter == 1) + { + + /* Check the packet length. */ + if (packet_ptr -> nx_packet_length != (WINDOW_SIZE/2 + 40)) + error_counter ++; + } + + /* Check the packet information. */ + else if (packet_counter == 2) + { + + /* Check the packet length. */ + if (packet_ptr -> nx_packet_length != (WINDOW_SIZE/2 + 40)) + error_counter ++; + } + + /* Check the packet information. */ + else if (packet_counter == 3) + { + + /* Check the packet length. */ + if ((packet_ptr -> nx_packet_length == (1 + 40)) && + (*(packet_ptr -> nx_packet_append_ptr - 1) == send_buff[0])) + { + zero_window_probe = NX_TRUE; + } + } + + return NX_TRUE; +} + +static void client_tcp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +NX_TCP_HEADER *tcp_header_ptr; + + /* Set the header. */ + tcp_header_ptr = (NX_TCP_HEADER *)(packet_ptr -> nx_packet_prepend_ptr); + NX_CHANGE_ULONG_ENDIAN(tcp_header_ptr -> nx_tcp_header_word_3); + + /* Check if the packet is an ACK packet. */ + if(tcp_header_ptr -> nx_tcp_header_word_3 & NX_TCP_ACK_BIT) + { + + /* Release the ACK to let client socket timeout. */ + nx_packet_release(packet_ptr); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_zero_window_probe_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Zero Window Probe Test................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_tcp_zero_window_test.c b/test/regression/netxduo_test/netx_tcp_zero_window_test.c new file mode 100644 index 00000000..c3462200 --- /dev/null +++ b/test/regression/netxduo_test/netx_tcp_zero_window_test.c @@ -0,0 +1,564 @@ +/* This case tests zero window probe is implemented. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_tcp.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define WINDOW_SIZE 128 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_TCP_SOCKET client_socket; +static NX_TCP_SOCKET server_socket; +static UCHAR send_buff[WINDOW_SIZE]; +static UCHAR recv_buff[WINDOW_SIZE]; +static UCHAR zero_window_probe; +static UCHAR zero_window_probe_ack; +#ifdef NX_ENABLE_DUAL_PACKET_POOL +static NX_PACKET_POOL my_auxiliary_pool; +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ +static NX_PACKET_POOL no_packet_pool; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +#endif /* FEATURE_NX_IPV6 */ + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT advanced_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_zero_window_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; +NX_PACKET *pkt_ptr; +UINT header_size = sizeof(NX_PACKET); + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + +#ifdef NX_PACKET_ALIGNMENT + pointer = (CHAR *)(((ALIGN_TYPE)pointer + NX_PACKET_ALIGNMENT - 1) / NX_PACKET_ALIGNMENT * NX_PACKET_ALIGNMENT); + header_size = (header_size + NX_PACKET_ALIGNMENT - 1) / NX_PACKET_ALIGNMENT * NX_PACKET_ALIGNMENT; +#endif /* NX_PACKET_ALIGNMENT */ + +#ifdef NX_ENABLE_DUAL_PACKET_POOL + /* Create an auxiliary packet pool. */ + status = nx_packet_pool_create(&my_auxiliary_pool, "NetX Auxiliary Packet Pool", 256, pointer, (256 + header_size)); + pointer = pointer + 256 + header_size; + + if (status) + error_counter++; +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ + + /* Create a packet pool with no packet. */ + status = nx_packet_pool_create(&no_packet_pool, "NetX No Packet Pool", 256, pointer, (256 + header_size)); + pointer = pointer + 256 + header_size; + + if (status) + error_counter++; + + /* Allocate the only one packet from pool. */ + nx_packet_allocate(&no_packet_pool, &pkt_ptr, NX_TCP_PACKET, NX_NO_WAIT); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create a packet pool with payload not four bytes aligned. */ + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable TCP processing for both IP instances. */ + status = nx_tcp_enable(&ip_0); + status += nx_tcp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + if(status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + if(status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ + +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; +ULONG tcp_transmit_window; +#ifdef NX_ENABLE_DUAL_PACKET_POOL +NX_PACKET *waste_packet; +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ + + /* Print out some test information banners. */ + printf("NetX Test: TCP Zero Window Test......................................"); + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds for DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + for (i = 0; i < sizeof(send_buff); i++) + { + send_buff[i] = 0x01; + recv_buff[i] = 0x00; + } + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_0, &client_socket, "Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, WINDOW_SIZE, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Bind the socket. */ + status = nx_tcp_client_socket_bind(&client_socket, 12, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + for (i = 0; i < 4; i++) +#else + for (i = 0; i < 2; i++) +#endif /* FEATURE_NX_IPV6 */ + { + + zero_window_probe = 0; + zero_window_probe_ack = 0; + + /* Attempt to connect the socket. */ +#ifdef FEATURE_NX_IPV6 + if (i > 1) + { + status = nxd_tcp_client_socket_connect(&client_socket, &ipv6_address_2, 12, 5 * NX_IP_PERIODIC_RATE); + } + else +#endif /* FEATURE_NX_IPV6 */ + { + + status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 5), 12, 5 * NX_IP_PERIODIC_RATE); + } + + /* Check for error. */ + if (status) + error_counter++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write send_buff into the packet payload! */ + status = nx_packet_data_append(my_packet, send_buff, WINDOW_SIZE, &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Send the packet out! */ + status = nx_tcp_socket_send(&client_socket, my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Get TCP transmit window size. */ + status = nx_tcp_socket_info_get(&client_socket, NX_NULL, NX_NULL, + NX_NULL, NX_NULL, + NX_NULL, NX_NULL, + NX_NULL, NX_NULL, + NX_NULL, &tcp_transmit_window, + NX_NULL); + + /* Check for error */ + if (status) + { + error_counter++; + } + + /* Check transmit window. */ + if (tcp_transmit_window != 0) + { + error_counter++; + } + + /* Sleep one second to make sure ACK is received. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write send_buff into the packet payload! */ + status = nx_packet_data_append(my_packet, "ABC", 3, &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + if (i & 1) + { + + /* Set both pools with no packets. */ + ip_0.nx_ip_default_packet_pool = &no_packet_pool; +#ifdef NX_ENABLE_DUAL_PACKET_POOL + ip_0.nx_ip_auxiliary_packet_pool = &my_auxiliary_pool; +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + /* Disable all interface capability. */ + nx_ip_interface_capability_set(&ip_0, 0, 0); +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + } +#ifdef NX_ENABLE_DUAL_PACKET_POOL + else + { + + /* Set the same pool with no packets. */ + ip_0.nx_ip_default_packet_pool = &my_auxiliary_pool; + ip_0.nx_ip_auxiliary_packet_pool = &my_auxiliary_pool; + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + /* Enable all TX checksum capability. */ + nx_ip_interface_capability_set(&ip_0, 0, NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM | + NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM); +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + } + + /* Allocate all packets from auxiliary pool. */ + status = nx_packet_allocate(&my_auxiliary_pool, &waste_packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ + + /* Send the packet out! */ + /* Window is full, so it can't be sent. */ + status = nx_tcp_socket_send(&client_socket, my_packet, NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status == NX_SUCCESS) + { + + /* Packet should not be sent. */ + error_counter++; + } + +#ifdef NX_ENABLE_DUAL_PACKET_POOL + /* Release wasted packet. */ + nx_packet_release(waste_packet); +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ + + /* Use auxiliary packet pool and default pool together. */ + ip_0.nx_ip_default_packet_pool = &pool_0; +#ifdef NX_ENABLE_DUAL_PACKET_POOL + ip_0.nx_ip_auxiliary_packet_pool = &my_auxiliary_pool; +#endif /* NX_ENABLE_DUAL_PACKET_POOL */ + + /* Window is full, so it can't be sent until timeout. */ + status = nx_tcp_socket_send(&client_socket, my_packet, + (client_socket.nx_tcp_socket_timeout_max_retries + 2) * NX_IP_PERIODIC_RATE); + + /* Determine if the status is valid. */ + if (status) + { + nx_packet_release(my_packet); + } + else + { + + /* Packet should not be sent. */ + error_counter++; + } + + /* Whether socket is still established. */ + if (client_socket.nx_tcp_socket_state == NX_TCP_CLOSED) + { + + /* Connection is closed. */ + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set callback function to drop all zero window probe ACK. */ + advanced_packet_process_callback = advanced_packet_process; + tx_thread_sleep((client_socket.nx_tcp_socket_timeout_max_retries + 2) * NX_IP_PERIODIC_RATE); + + /* Whether socket is still established. */ + if (client_socket.nx_tcp_socket_state != NX_TCP_CLOSED) + { + error_counter++; + } + + /* Check zero window probe received. */ + if ((zero_window_probe != client_socket.nx_tcp_socket_timeout_max_retries) || + (zero_window_probe_ack != client_socket.nx_tcp_socket_timeout_max_retries)) + { + error_counter++; + } + + /* Clear callback function. */ + advanced_packet_process_callback = NX_NULL; + + /* Wakeup server thread. */ + tx_thread_resume(&thread_1); + } + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +UINT i; + + /* Create a socket. */ + status = nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, WINDOW_SIZE, + NX_NULL, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + + /* Setup this thread to listen. */ + status = nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL); + + /* Check for error. */ + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + for (i = 0; i < 4; i++) +#else + for (i = 0; i < 2; i++) +#endif /* FEATURE_NX_IPV6 */ + { + + /* Accept a client socket connection. */ + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + + /* Suspend server thread. */ + tx_thread_suspend(&thread_1); + + /* Reset connection. */ + nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + nx_tcp_server_socket_unaccept(&server_socket); + nx_tcp_server_socket_relisten(&ip_1, 12, &server_socket); + } +} + +static UINT advanced_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Drop zero window probe from ip_0. */ + if (ip_ptr == &ip_0) + { + + /* Is the length match TCP zero window probe packet? */ + if ((packet_ptr -> nx_packet_length == 41) || + (packet_ptr -> nx_packet_length == 61)) + { + + /* Yes it is. */ + /* Check one byte data. */ + if (*(packet_ptr -> nx_packet_append_ptr - 1) == 'A') + { + + /* It's zero window probe packet. */ + zero_window_probe++; + } + } + return NX_TRUE; + } + + /* Is the length match TCP ACK packet? */ + if ((packet_ptr -> nx_packet_length == 40) || (packet_ptr -> nx_packet_length == 60)) + { + + /* Yes it is. Drop it. */ + zero_window_probe_ack++; + *operation_ptr = NX_RAMDRIVER_OP_DROP; + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tcp_zero_window_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: TCP Zero Window Test......................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_udp_basic_processing_test.c b/test/regression/netxduo_test/netx_udp_basic_processing_test.c new file mode 100644 index 00000000..2a34cda7 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_basic_processing_test.c @@ -0,0 +1,699 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_udp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_0; +static NXD_ADDRESS address_1; +#endif /* FEATURE_NX_IPV6 */ + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; +static ULONG notify_calls = 0; +static ULONG total_packets = 2000; +static ULONG modify_packets = 0; +static ULONG invalid_packets; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +#ifdef FEATURE_NX_IPV6 +static UINT my_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +#endif /* FEATURE_NX_IPV6 */ +static VOID udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_basic_processing_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + notify_calls = 0; + invalid_packets = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check enable status. */ + if (status) + error_counter++; + + /* Set source and destination address with global address. */ + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0x20010DB8; + address_0.nxd_ip_address.v6[1] = 0x00010001; + address_0.nxd_ip_address.v6[2] = 0x021122FF; + address_0.nxd_ip_address.v6[3] = 0xFE334456; + + address_1.nxd_ip_version = NX_IP_VERSION_V6; + address_1.nxd_ip_address.v6[0] = 0x20010DB8; + address_1.nxd_ip_address.v6[1] = 0x00010001; + address_1.nxd_ip_address.v6[2] = 0x021122FF; + address_1.nxd_ip_address.v6[3] = 0xFE334499; + + status = nxd_ipv6_address_set(&ip_0, 0, &address_0, 64, NX_NULL); + status = nxd_ipv6_address_set(&ip_1, 0, &address_1, 64, NX_NULL); + + total_packets = 4000; + packet_process_callback = NX_NULL; +#endif /* FEATURE_NX_IPV6 */ + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Basic Processing Test................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Filter UDP packet. */ + ip_1.nx_ip_udp_packet_receive = udp_packet_receive; + + /* Let the IP threads and thread 1 execute. */ + tx_thread_relinquish(); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Pickup the first free port for 0x88. */ + status = nx_udp_free_port_find(&ip_0, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(31); + } + + /* Disable checksum logic for this socket. */ + status = nx_udp_socket_checksum_disable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup the ARP entry for the UDP send. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0, 0); + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Send 1000 ipv4 packets without checksum. */ + thread_0_counter = 0; + while ((thread_0_counter < 1000) && (error_counter == 0)) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Relinquish to thread 1 so it can pickup the message. */ + tx_thread_relinquish(); + } + + /* Now, enable the checksum. */ + status = nx_udp_socket_checksum_enable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send another 1000 ipv4 packets with checksum enabled. */ + while ((thread_0_counter < 2000) && (error_counter == 0)) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Relinquish to thread 1 so it can pickup the message. */ + tx_thread_relinquish(); + } + + /* Now, disable the checksum. */ + status = nx_udp_socket_checksum_disable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + packet_process_callback = my_packet_process; + + /* Send another 1000 ipv6 packets without checksum enabled. */ + while ((thread_0_counter < 3000) && (error_counter == 0)) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Relinquish to thread 1 so it can pickup the message. */ + tx_thread_relinquish(); + } + + /* Now, enable the checksum. */ + status = nx_udp_socket_checksum_enable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send another 1000 ipv6 packets with checksum enabled. */ + while ((thread_0_counter < 4000) && (error_counter == 0)) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Relinquish to thread 1 so it can pickup the message. */ + tx_thread_relinquish(); + } +#endif /* FEATURE_NX_IPV6 */ + + /* Get nothing from UDP socket. */ + status = nx_udp_socket_info_get(&socket_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP socket information. */ + status = nx_udp_socket_info_get(&socket_0, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_UDP_INFO + + if ((packets_sent != total_packets) || (bytes_sent != total_packets*28)) + { + error_counter++; + } +#endif + +#if defined(NX_DISABLE_UDP_RX_CHECKSUM) + /* Modified packets are processed as normal packets. */ + modify_packets = 0; +#elif defined(NX_ENABLE_INTERFACE_CAPABILITY) + /* Packets with checksum error are dropped by driver directly. */ + if(ip_0.nx_ip_interface[0].nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_UDP_RX_CHECKSUM) + notify_calls += modify_packets; +#endif /* NX_ENABLE_INTERFACE_CAPABILITY */ + + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != total_packets) || (thread_1_counter != total_packets - modify_packets) || + (packets_received) || (bytes_received) || (packets_queued) || (receive_packets_dropped) || (checksum_errors) || (notify_calls != total_packets)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_IP_INFO + if (invalid_packets != ip_0.nx_ip_invalid_transmit_packets) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_IP_INFO */ + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&socket_1, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Get 4000 packets. */ + thread_1_counter = 0; + while (1) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Increment thread 1's counter. */ + thread_1_counter++; + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &socket_1) + notify_calls++; +} + + +#ifdef FEATURE_NX_IPV6 +static UINT my_packet_process(NX_IP * ip_ptr,NX_PACKET * packet_ptr) +{ + + /* Check if it is a UDP packet with IPv6 header. */ + if ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) && + (*(packet_ptr -> nx_packet_prepend_ptr + 6) == NX_PROTOCOL_UDP)) + { + + /* Yes it is a UDP packet with IPv6 header. */ +#ifndef NX_DISABLE_UDP_RX_CHECKSUM + /* Check if checksum field is 0. */ + if ((*(packet_ptr -> nx_packet_prepend_ptr + 46) == 0) && + (*(packet_ptr -> nx_packet_prepend_ptr + 47) == 0)) + { + + /* The checksum field is 0. */ + error_counter++; + } + else +#endif /* NX_DISABLE_UDP_RX_CHECKSUM */ + { + + /* Modify first 1000 packets. Set checksum field to 0. */ + if (modify_packets < 1000) + { + *(packet_ptr -> nx_packet_prepend_ptr + 46) = 0; + *(packet_ptr -> nx_packet_prepend_ptr + 47) = 0; + modify_packets++; + } + } + } + + return NX_TRUE; +} +#endif /* FEATURE_NX_IPV6 */ + + +static VOID udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_PACKET *invalid_pkt_ptr; + + /* Send a UDP packet with no interface. */ + if (nx_packet_copy(packet_ptr, &invalid_pkt_ptr, &pool_0, NX_NO_WAIT)) + { + error_counter++; + } + else + { + + /* Set interface to NULL. */ +#ifdef __PRODUCT_NETXDUO__ + invalid_pkt_ptr -> nx_packet_address.nx_packet_interface_ptr = NX_NULL; + invalid_packets++; + + /* Send the packet. */ + _nx_ip_packet_send(&ip_0, invalid_pkt_ptr, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL, + 0x80, NX_IP_UDP, NX_FRAGMENT_OKAY, IP_ADDRESS(1, 2, 3, 5)); +#else + invalid_pkt_ptr -> nx_packet_ip_interface = NX_NULL; + invalid_packets++; + + /* Send the packet. */ + _nx_ip_packet_send(&ip_0, invalid_pkt_ptr, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL, + 0x80, NX_IP_UDP, NX_FRAGMENT_OKAY); +#endif + } + + /* Process this packet. */ + _nx_udp_packet_receive(ip_ptr, packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_basic_processing_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: UDP Basic Processing Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_udp_bind_cleanup_test.c b/test/regression/netxduo_test/netx_udp_bind_cleanup_test.c new file mode 100644 index 00000000..5ea6461d --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_bind_cleanup_test.c @@ -0,0 +1,202 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; +static NX_UDP_SOCKET socket_2; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void test_control_return(UINT status); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_bind_cleanup_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT free_port; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Bind Cleanup Test....................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Pickup the first free port for 0x88. */ + status = nx_udp_free_port_find(&ip_0, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + error_counter++; + + /* Bind the UDP socket 0 to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket 1 to the same IP port to trigger the udp_bind_cleanup. */ + status = nx_udp_socket_bind(&socket_1, 0x88, 250); + + /* Check status. */ + if (!status) + error_counter++; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Unbind the UDP socket 1. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status != NX_NOT_BOUND) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if ((status) || (error_counter)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static void thread_1_entry(ULONG thread_input) +{ +UINT status; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_2, "Socket 2", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if(status != NX_SUCCESS) + error_counter++; + + /* Bind the UDP socket 1 to the same IP port to trigger the udp_bind_cleanup. */ + status = nx_udp_socket_bind(&socket_2, 0x88, 2 * NX_IP_PERIODIC_RATE); + if(status == NX_SUCCESS) + error_counter++; + + status = nx_udp_socket_unbind(&socket_2); + if(status != NX_NOT_BOUND) + error_counter++; + + status = nx_udp_socket_delete(&socket_2); + if(status != NX_SUCCESS) + error_counter++; + +} diff --git a/test/regression/netxduo_test/netx_udp_branch_test.c b/test/regression/netxduo_test/netx_udp_branch_test.c new file mode 100644 index 00000000..57cb6310 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_branch_test.c @@ -0,0 +1,477 @@ +/* This NetX test concentrates on the code coverage for UDP functions, + * _nx_udp_receive_cleanup.c + * _nx_udp_socket_unbind.c + * _nx_udp_packet_info_extract.c + */ + +#include "nx_api.h" +#include "tx_thread.h" +#include "nx_udp.h" +#include "nx_ip.h" +#ifdef FEATURE_NX_IPV6 +#include "nx_ipv6.h" +#endif + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_test1; +static TX_THREAD thread_test2; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_UDP_SOCKET socket_0; + + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static CHAR *pointer; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static VOID suspend_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_branch_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +NX_PACKET *my_packet; +NX_UDP_HEADER *udp_header_ptr; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + +#ifndef NX_DISABLE_IPV4 + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; +#endif + + /* Enable UDP processing for IP instance. */ + status = nx_udp_enable(&ip_0); + + /* Check UDP enable status. */ + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + error_counter++; + + /* Test _nx_udp_packet_receive() */ + /* Hit condition: _tx_thread_current_ptr = NX_NULL + [ + - ][ + - ]: if ((_tx_thread_current_ptr) && (_tx_thread_system_state == 0)) line 199 and 263 */ + + /* Allocate the packet. */ + nx_packet_allocate(&pool_0, &my_packet, 0, NX_NO_WAIT); + udp_header_ptr = (NX_UDP_HEADER *)my_packet -> nx_packet_prepend_ptr; + udp_header_ptr -> nx_udp_header_word_0 = 0x24681234; + udp_header_ptr -> nx_udp_header_word_1 = 0x00090000; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 9; + my_packet -> nx_packet_length = 9; + + _nx_udp_packet_receive(&ip_0, my_packet); + + /* Hit condition: _tx_thread_current_ptr = NX_NULL + [ + - ][ + - ]: if ((_tx_thread_current_ptr) && (_tx_thread_system_state == 0)) line 312 */ + _nx_udp_socket_bind(&socket_0, 0x1234, NX_NO_WAIT); + + /* Allocate the packet. */ + nx_packet_allocate(&pool_0, &my_packet, 0, NX_NO_WAIT); + udp_header_ptr = (NX_UDP_HEADER *)my_packet -> nx_packet_prepend_ptr; + udp_header_ptr -> nx_udp_header_word_0 = 0x24681234; + udp_header_ptr -> nx_udp_header_word_1 = 0x00090000; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 9; + my_packet -> nx_packet_length = 9; + + _nx_udp_packet_receive(&ip_0, my_packet); + _nx_udp_socket_unbind(&socket_0); +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG thread_state; +ULONG system_state; +NX_PACKET *my_packet[2]; +NX_UDP_SOCKET *temp_socket; +TX_THREAD *temp_thread; +#ifdef __PRODUCT_NETXDUO__ +ULONG ip_address; +NX_PACKET *receive_packet; +#endif +NX_UDP_HEADER *udp_header_ptr; +#ifdef FEATURE_NX_IPV6 +NX_IPV6_HEADER *ipv6_header_ptr; +#endif + + /* Print out some test information banners. */ + printf("NetX Test: UDP Branch Test..........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + + /* Test _nx_udp_receive_cleanup(). */ + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + socket_0.nx_udp_socket_id = NX_UDP_ID; + _nx_udp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = &socket_0; + socket_0.nx_udp_socket_id = 0; + _nx_udp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + socket_0.nx_udp_socket_id = 0; + _nx_udp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = &socket_0; + socket_0.nx_udp_socket_id = NX_UDP_ID; + _nx_udp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + socket_0.nx_udp_socket_id = NX_UDP_ID; + _nx_udp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = &socket_0; + socket_0.nx_udp_socket_id = 0; + _nx_udp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + socket_0.nx_udp_socket_id = 0; + _nx_udp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = &socket_0; + tx_thread_identify() -> tx_thread_suspended_next = &thread_test1; + tx_thread_identify() -> tx_thread_suspended_previous = &thread_test2; + thread_state = tx_thread_identify() -> tx_thread_state; + socket_0.nx_udp_socket_id = NX_UDP_ID; + socket_0.nx_udp_socket_receive_suspended_count ++; + tx_thread_identify() -> tx_thread_state = 0; + _nx_udp_receive_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + tx_thread_identify() -> tx_thread_state = thread_state; + socket_0.nx_udp_socket_receive_suspension_list = TX_NULL; + + + + /* Test _nx_udp_bind_cleanup */ + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + socket_0.nx_udp_socket_id = NX_UDP_ID; + _nx_udp_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = &socket_0; + socket_0.nx_udp_socket_id = 0; + _nx_udp_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + socket_0.nx_udp_socket_id = 0; + _nx_udp_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = &socket_0; + socket_0.nx_udp_socket_id = NX_UDP_ID; + _nx_udp_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + socket_0.nx_udp_socket_id = NX_UDP_ID; + _nx_udp_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = &socket_0; + socket_0.nx_udp_socket_id = 0; + _nx_udp_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID. */ + tx_thread_identify() -> tx_thread_suspend_cleanup = NX_NULL; + tx_thread_identify() -> tx_thread_suspend_control_block = NX_NULL; + socket_0.nx_udp_socket_id = 0; + _nx_udp_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + + /* Setup tx_thread_suspend_cleanup, socket_ptr, and socket ID to hit false condition of if (thread_ptr -> tx_thread_state == TX_TCP_IP) */ + tx_thread_identify() -> tx_thread_suspend_cleanup = suspend_cleanup; + tx_thread_identify() -> tx_thread_suspend_control_block = &socket_0; + socket_0.nx_udp_socket_id = NX_UDP_ID; + tx_thread_identify() -> tx_thread_suspended_next = tx_thread_identify(); + socket_0.nx_udp_socket_bound_previous = &socket_0; + socket_0.nx_udp_socket_bind_suspended_count ++; + thread_state = tx_thread_identify() -> tx_thread_state; + tx_thread_identify() -> tx_thread_state = 0; + _nx_udp_bind_cleanup(tx_thread_identify() NX_CLEANUP_ARGUMENT); + tx_thread_identify() -> tx_thread_state = thread_state; + + /* Recover. */ + tx_thread_identify() -> tx_thread_suspended_next = TX_NULL; + socket_0.nx_udp_socket_bound_previous = NX_NULL; + + + + /* Test _nx_udp_socket_unbind(). */ + /* Hit [ + + ][ - + ] condition + if ((socket_ptr -> nx_udp_socket_bound_next) || + (socket_ptr -> nx_udp_socket_bind_in_progress)) */ + temp_socket = socket_0.nx_udp_socket_bound_next; + socket_0.nx_udp_socket_bound_next = NX_NULL; + temp_thread = socket_0.nx_udp_socket_bind_in_progress; + socket_0.nx_udp_socket_bind_in_progress = tx_thread_identify(); + nx_udp_socket_bind(&socket_0, 1234, NX_NO_WAIT); + socket_0.nx_udp_socket_bound_next = temp_socket; + socket_0.nx_udp_socket_bind_in_progress = temp_thread; + + + /* Hit true condition of if (socket_ptr -> nx_udp_socket_receive_count)*/ + nx_udp_socket_bind(&socket_0, 1234, NX_NO_WAIT); + + /* Allocate the packet. queue two packet on receive list. */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + nx_packet_allocate(&pool_0, &my_packet[1], 0, NX_NO_WAIT); + socket_0.nx_udp_socket_receive_head = my_packet[0]; + my_packet[0] -> nx_packet_queue_next = my_packet[1]; + my_packet[1] -> nx_packet_queue_next = NX_NULL; + socket_0.nx_udp_socket_receive_tail = my_packet[1]; + socket_0.nx_udp_socket_receive_count = 2; + + /* Recover. Unbind the socket. */ + _nx_udp_socket_unbind(&socket_0); + + + +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) + /* Hit false condition of if (status == NX_SUCCESS) in _nx_udp_packet_info_extract. */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_ip_version = 0; + _nx_udp_packet_info_extract(my_packet[0], &ip_address, NX_NULL, NX_NULL, NX_NULL); + nx_packet_release(my_packet[0]); + + + /* Test _nx_udp_socket_receive() */ + /* Hit condition: + [ + - ][ + + ]: if ((!socket_ptr -> nx_udp_socket_disable_checksum && (*(temp_ptr + 1) & NX_LOWER_16_MASK)) || + [ + + ] ((*packet_ptr) -> nx_packet_ip_version == NX_IP_VERSION_V6)) */ + nx_udp_socket_bind(&socket_0, 1234, NX_NO_WAIT); + /* Allocate the packet. queue one packet on receive list. */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 9; + my_packet[0] -> nx_packet_length = 9; + my_packet[0] -> nx_packet_ip_version = NX_IP_VERSION_V4; + my_packet[0] -> nx_packet_address.nx_packet_interface_ptr = &ip_0.nx_ip_interface[0]; + socket_0.nx_udp_socket_receive_count = 1; + socket_0.nx_udp_socket_receive_head = my_packet[0]; + my_packet[0] -> nx_packet_queue_next = NX_NULL; + socket_0.nx_udp_socket_receive_tail = my_packet[0]; + socket_0.nx_udp_socket_disable_checksum = 1; + _nx_udp_socket_receive(&socket_0, &receive_packet, 0); + nx_packet_release(receive_packet); + + /* Recover. Unbind the socket. */ + socket_0.nx_udp_socket_disable_checksum = 0; + _nx_udp_socket_unbind(&socket_0); +#endif /* __PRODUCT_NETXDUO__ */ + + + + /* Test _nx_udp_packet_receive() */ + /* Hit condition: + [ + - ][ + - ]: if ((_tx_thread_current_ptr) && (_tx_thread_system_state == 0)) line 199 and 263 */ + + /* Allocate the packet. */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + udp_header_ptr = (NX_UDP_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + udp_header_ptr -> nx_udp_header_word_0 = 0x24681234; + udp_header_ptr -> nx_udp_header_word_1 = 0x00090000; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 9; + my_packet[0] -> nx_packet_length = 9; + + system_state = _tx_thread_system_state ; + _tx_thread_system_state = 1; + _nx_udp_packet_receive(&ip_0, my_packet[0]); + _tx_thread_system_state = system_state; + + + /* Hit condition: + [ + - ][ + - ]: if ((_tx_thread_current_ptr) && (_tx_thread_system_state == 0)) line 312 */ + nx_udp_socket_bind(&socket_0, 0x1234, NX_NO_WAIT); + + /* Allocate the packet. */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + udp_header_ptr = (NX_UDP_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + udp_header_ptr -> nx_udp_header_word_0 = 0x24681234; + udp_header_ptr -> nx_udp_header_word_1 = 0x00090000; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 9; + my_packet[0] -> nx_packet_length = 9; + + system_state = _tx_thread_system_state ; + _tx_thread_system_state = 1; + _nx_udp_packet_receive(&ip_0, my_packet[0]); + _tx_thread_system_state = system_state; + _nx_udp_socket_unbind(&socket_0); + + +#ifndef NX_DISABLE_IPV4 +#ifdef __PRODUCT_NETXDUO__ + /* Hit condition: + [ + + ][ + - ]: if ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) && + : (ip_ptr -> nx_ip_icmpv4_packet_process)) line 334 */ + nx_udp_socket_bind(&socket_0, 0x0100, NX_NO_WAIT); + + /* Allocate the packet. */ + nx_packet_allocate(&pool_0, &my_packet[0], 0, NX_NO_WAIT); + udp_header_ptr = (NX_UDP_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + udp_header_ptr -> nx_udp_header_word_0 = 0x24688100; + udp_header_ptr -> nx_udp_header_word_1 = 0x00090000; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 9; + my_packet[0] -> nx_packet_length = 9; + my_packet[0] -> nx_packet_ip_version = 4; + ip_0.nx_ip_icmpv4_packet_process = NX_NULL; + + _nx_udp_packet_receive(&ip_0, my_packet[0]); + _nx_udp_socket_unbind(&socket_0); +#endif +#endif + + +#ifdef FEATURE_NX_IPV6 + /* Hit condition: + [ + - ]: if ((ip_header -> nx_ip_header_destination_ip[0] & (ULONG)0xFF000000) != (ULONG)0xFF000000) line 359 */ + nx_udp_socket_bind(&socket_0, 0x0100, NX_NO_WAIT); + + /* Allocate the packet. */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_IPv6_PACKET, NX_NO_WAIT); + udp_header_ptr = (NX_UDP_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + udp_header_ptr -> nx_udp_header_word_0 = 0x24688100; + udp_header_ptr -> nx_udp_header_word_1 = 0x00090000; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 9; + my_packet[0] -> nx_packet_length = 9; + my_packet[0] -> nx_packet_ip_version = 6; + my_packet[0] -> nx_packet_ip_header = my_packet[0] -> nx_packet_prepend_ptr - 40; + ipv6_header_ptr = (NX_IPV6_HEADER *)my_packet[0] -> nx_packet_ip_header; + ipv6_header_ptr -> nx_ip_header_destination_ip[0] = 0xFF000000; + + _nx_udp_packet_receive(&ip_0, my_packet[0]); + _nx_udp_socket_unbind(&socket_0); +#endif + + /* Test packet_ptr -> nx_packet_length < sizeof(NX_UDP_HEADER) */ + /* Allocate the packet. */ + nx_packet_allocate(&pool_0, &my_packet[0], NX_IP_PACKET, NX_NO_WAIT); + udp_header_ptr = (NX_UDP_HEADER *)my_packet[0] -> nx_packet_prepend_ptr; + udp_header_ptr -> nx_udp_header_word_0 = 0x24688100; + udp_header_ptr -> nx_udp_header_word_1 = 0x00090000; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + my_packet[0] -> nx_packet_append_ptr = my_packet[0] -> nx_packet_prepend_ptr + 8; + + /* Reset the packet length to make sure the packet length is small than NX_UDP_HEADER */ + my_packet[0] -> nx_packet_length = 7; + _nx_udp_packet_receive(&ip_0, my_packet[0]); + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static VOID suspend_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER) +{ +} diff --git a/test/regression/netxduo_test/netx_udp_checksum_zero_test.c b/test/regression/netxduo_test/netx_udp_checksum_zero_test.c new file mode 100644 index 00000000..9ef30abc --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_checksum_zero_test.c @@ -0,0 +1,296 @@ +/* This NetX test concentrates on the calculated UDP checksum is zero. */ + + +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UCHAR msg[] = {0xF6, 0xBC}; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_checksum_zero_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Checksum Zero Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the IP threads and thread 1 execute. */ + tx_thread_relinquish(); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Write data into the packet. */ + status += nx_packet_data_append(my_packet, msg, sizeof(msg), &pool_0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Delete the UDP socket. */ + status += nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Check data. */ + if ((my_packet -> nx_packet_length != sizeof(msg)) || + (memcmp(my_packet -> nx_packet_prepend_ptr, msg, sizeof(msg)) != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_checksum_zero_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: UDP Checksum Zero Test....................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_udp_fragment_test.c b/test/regression/netxduo_test/netx_udp_fragment_test.c new file mode 100644 index 00000000..bcf998a6 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_fragment_test.c @@ -0,0 +1,566 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_0; +static NXD_ADDRESS address_1; +#endif /* FEATURE_NX_IPV6 */ + +static UCHAR send_buff[300]; +static UCHAR recv_buff[300]; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_fragment_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create two packet pools. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 5120); + pointer = pointer + 5120; + status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 256, pointer, 5120); + pointer = pointer + 5120; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Set source and destination address with global address. */ + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0x20010DB8; + address_0.nxd_ip_address.v6[1] = 0x00010001; + address_0.nxd_ip_address.v6[2] = 0x021122FF; + address_0.nxd_ip_address.v6[3] = 0xFE334456; + + address_1.nxd_ip_version = NX_IP_VERSION_V6; + address_1.nxd_ip_address.v6[0] = 0x20010DB8; + address_1.nxd_ip_address.v6[1] = 0x00010001; + address_1.nxd_ip_address.v6[2] = 0x021122FF; + address_1.nxd_ip_address.v6[3] = 0xFE334499; + + status = nxd_ipv6_address_set(&ip_0, 0, &address_0, 64, NX_NULL); + status = nxd_ipv6_address_set(&ip_1, 0, &address_1, 64, NX_NULL); + +#endif /* FEATURE_NX_IPV6 */ + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT i; +UINT status; +NX_PACKET *my_packet; +ULONG data_len; +#if !defined(NX_DISABLE_IP_INFO) && !defined(NX_DISABLE_PACKET_CHAIN) +ULONG fragment_failures = 0; +NX_PACKET *test_packet; +NX_PACKET *last_packet_1 = NX_NULL; +NX_PACKET *last_packet_2 = NX_NULL; +#endif + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Fragment Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + + /* Let thread 1 start to send. */ + tx_thread_resume(&thread_1); + +#ifdef NX_FRAGMENT_IMMEDIATE_ASSEMBLY + /* Receive a packet. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, 3 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + + /* Check whether packet is in sequence. */ + nx_packet_data_retrieve(my_packet, recv_buff, &data_len); + if(data_len != sizeof(send_buff)) + error_counter++; + else if(memcmp(send_buff, recv_buff, data_len)) + error_counter++; + nx_packet_release(my_packet); + } + + /* Receive a packet. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, 3 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + + /* Check whether packet is in sequence. */ + nx_packet_data_retrieve(my_packet, recv_buff, &data_len); + if(data_len != 3) + error_counter++; + else if(memcmp("ABC", recv_buff, data_len)) + error_counter++; + nx_packet_release(my_packet); + } + +#ifdef FEATURE_NX_IPV6 + /* Receive a packet. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, 3 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + + /* Check whether packet is in sequence. */ + nx_packet_data_retrieve(my_packet, recv_buff, &data_len); + if(data_len != sizeof(send_buff)) + error_counter++; + else if(memcmp(send_buff, recv_buff, data_len)) + error_counter++; + nx_packet_release(my_packet); + } + + /* Receive a packet. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, 3 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + else + { + + /* Check whether packet is in sequence. */ + nx_packet_data_retrieve(my_packet, recv_buff, &data_len); + if(data_len != 3) + error_counter++; + else if(memcmp("ABC", recv_buff, data_len)) + error_counter++; + nx_packet_release(my_packet); + } +#endif /* FEATURE_NX_IPV6 */ +#endif /* NX_FRAGMENT_IMMEDIATE_ASSEMBLY */ + + /* Receive packets. */ +#ifdef FEATURE_NX_IPV6 + for(i = 0; i < 2000; i++) +#else + for(i = 0; i < 1000; i++) +#endif /* FEATURE_NX_IPV6 */ + { + status = nx_udp_socket_receive(&socket_0, &my_packet, 3 * NX_IP_PERIODIC_RATE); + if (status) + { + error_counter++; + break; + } + else + { + + /* Check whether packet is in sequence. */ + nx_packet_data_retrieve(my_packet, recv_buff, &data_len); + if(data_len != sizeof(send_buff)) + error_counter++; + else if(memcmp(send_buff, recv_buff, data_len)) + error_counter++; + nx_packet_release(my_packet); + } + } + +#if !defined(NX_DISABLE_IP_INFO) && !defined(NX_DISABLE_PACKET_CHAIN) + + /* Get the original failures. */ + fragment_failures = ip_0.nx_ip_fragment_failures; + + /* Create a packet larger than MTU. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_0, NX_WAIT_FOREVER); + + /* Allocate packet until no packet is available. */ + while (nx_packet_allocate(&pool_0, &test_packet, NX_UDP_PACKET, NX_NO_WAIT) == NX_SUCCESS) + { + last_packet_2 = last_packet_1; + last_packet_1 = test_packet; + } + + /* Make sure no ARP request is needed. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), + ip_1.nx_ip_interface[0].nx_interface_physical_address_msw, + ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw); + + /* Send the UDP packet. */ + status += nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Check whether */ + if (ip_0.nx_ip_fragment_failures != fragment_failures + 1) + { + error_counter++; + } + + /* Release one packet. It should not be able to send since packet is not enough. */ + nx_packet_release(last_packet_1); + + /* Create a packet larger than MTU. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_0, NX_WAIT_FOREVER); + + /* Make sure no ARP request is needed. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), + ip_1.nx_ip_interface[0].nx_interface_physical_address_msw, + ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw); + + /* Send the UDP packet. */ + status += nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Check whether */ + if (ip_0.nx_ip_fragment_failures != fragment_failures + 2) + { + error_counter++; + } + + /* Release the second packet. It should be able to send packet. */ + nx_packet_release(last_packet_2); + + /* Create a packet larger than MTU. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_0, NX_WAIT_FOREVER); + + /* Modify the length of packet and keep append_ptr. The fragment process should discard this packet. */ + my_packet -> nx_packet_length += 256; + + + /* Send the UDP packet. */ + status += nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + /* Check whether */ + if (ip_0.nx_ip_fragment_failures != fragment_failures + 3) + { + error_counter++; + } + +#endif /* !NX_DISABLE_IP_INFO && !NX_DISABLE_PACKET_CHAIN */ + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Delete the UDP socket. */ + status += nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT i; +UINT status; +NX_PACKET *my_packet; + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + + /* Initialize send buffer. */ + for(i = 0; i < sizeof(send_buff); i++) + send_buff[i] = (UCHAR)(i & 0xFF); + +#ifdef NX_FRAGMENT_IMMEDIATE_ASSEMBLY + /* Create a packet larger than MTU. */ + status = nx_packet_allocate(&pool_1, &my_packet, NX_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_1, NX_NO_WAIT); + + /* Send the UDP packet. */ + status += nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(1, 2, 3, 4), 0x88); + + /* Check status. */ + if (status) + error_counter++; + + /* Create a small packet. */ + status = nx_packet_allocate(&pool_1, &my_packet, NX_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, "ABC", 3, &pool_1, NX_NO_WAIT); + + /* Send the UDP packet. */ + status += nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(1, 2, 3, 4), 0x88); + + /* Check status. */ + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Create a packet larger than MTU. */ + status = nx_packet_allocate(&pool_1, &my_packet, NX_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_1, NX_NO_WAIT); + + /* Send the UDP packet. */ + status += nxd_udp_socket_send(&socket_1, my_packet, &address_0, 0x88); + + /* Check status. */ + if (status) + error_counter++; + + /* Create a small packet. */ + status = nx_packet_allocate(&pool_1, &my_packet, NX_UDP_PACKET, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, "ABC", 3, &pool_1, NX_NO_WAIT); + + /* Send the UDP packet. */ + status += nxd_udp_socket_send(&socket_1, my_packet, &address_0, 0x88); + + /* Check status. */ + if (status) + error_counter++; +#endif /* FEATURE_NX_IPV6 */ +#endif /* NX_FRAGMENT_IMMEDIATE_ASSEMBLY */ + /* Send 1000 packets from user specified packet pool. */ + for(i = 0; i < 1000; i++) + { + + /* Create a packet larger than MTU. */ + status = nx_packet_allocate(&pool_1, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_1, NX_WAIT_FOREVER); + + /* Send the UDP packet. */ + status += nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(1, 2, 3, 4), 0x88); + + /* Check status. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + break; + } + tx_thread_relinquish(); + } + +#ifdef FEATURE_NX_IPV6 + /* Send 1000 packets from user specified packet pool. */ + for(i = 0; i < 1000; i++) + { + + /* Create a packet larger than MTU. */ + status = nx_packet_allocate(&pool_1, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + status += nx_packet_data_append(my_packet, send_buff, sizeof(send_buff), &pool_1, NX_WAIT_FOREVER); + + /* Send the UDP packet. */ + status += nxd_udp_socket_send(&socket_1, my_packet, &address_0, 0x88); + + /* Check status. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + break; + } + tx_thread_relinquish(); + } +#endif /* FEATURE_NX_IPV6 */ + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Delete the UDP socket. */ + status += nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_fragment_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: UDP Fragment Test.........................................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_udp_fragmentation_processing_test.c b/test/regression/netxduo_test/netx_udp_fragmentation_processing_test.c new file mode 100644 index 00000000..501826a3 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_fragmentation_processing_test.c @@ -0,0 +1,2309 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_FRAGMENTATION) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_UDP_SOCKET socket_0; + +static UCHAR pool_area[(1536 + sizeof(NX_PACKET)) * 20]; + + +/* Define the packet data. */ +/* Frame (1514 bytes) */ +static const unsigned char pkt1[1514] = { +0x18, 0x03, 0x73, 0x29, 0x5f, 0x66, 0xa4, 0x1f, /* ..s)_f.. */ +0x72, 0x53, 0xa0, 0xf7, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x05, 0xdc, 0x3b, 0xd8, 0x20, 0x00, 0x40, 0x11, /* ..;. .@. */ +0x97, 0x6f, 0xc0, 0xa8, 0x00, 0x13, 0xc0, 0xa8, /* .o...... */ +0x00, 0x66, 0x1f, 0xf5, 0x1f, 0xf5, 0x0f, 0xa8, /* .f...... */ +0x90, 0x4e, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* .Nabcdef */ +0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, /* ghijklmn */ +0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, /* opqrstuv */ +0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, /* wxyz.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00 /* .. */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt2[1514] = { +0x18, 0x03, 0x73, 0x29, 0x5f, 0x66, 0xa4, 0x1f, /* ..s)_f.. */ +0x72, 0x53, 0xa0, 0xf7, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x05, 0xdc, 0x3b, 0xd8, 0x20, 0xb9, 0x40, 0x11, /* ..;. .@. */ +0x96, 0xb6, 0xc0, 0xa8, 0x00, 0x13, 0xc0, 0xa8, /* ........ */ +0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .f...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00 /* .. */ +}; + +/* Frame (1082 bytes) */ +static const unsigned char pkt3[1082] = { +0x18, 0x03, 0x73, 0x29, 0x5f, 0x66, 0xa4, 0x1f, /* ..s)_f.. */ +0x72, 0x53, 0xa0, 0xf7, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x04, 0x2c, 0x3b, 0xd8, 0x01, 0x72, 0x40, 0x11, /* .,;..r@. */ +0xb7, 0xad, 0xc0, 0xa8, 0x00, 0x13, 0xc0, 0xa8, /* ........ */ +0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .f...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00 /* .. */ +}; + +#if 0 +/* Reassembled IPv4 (4008 bytes) */ +static const unsigned char pkt3_1[4008] = { +0x1f, 0xf5, 0x1f, 0xf5, 0x0f, 0xa8, 0x90, 0x4e, /* .......N */ +0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, /* abcdefgh */ +0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* ijklmnop */ +0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* qrstuvwx */ +0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* yz...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ........ */ +}; +#endif + +/* Frame (1514 bytes) */ +static const unsigned char pkt4[1514] = { +0x18, 0x03, 0x73, 0x29, 0x5f, 0x66, 0xa4, 0x1f, /* ..s)_f.. */ +0x72, 0x53, 0xa0, 0xf7, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x05, 0xdc, 0x3b, 0xd9, 0x20, 0x00, 0x40, 0x11, /* ..;. .@. */ +0x97, 0x6e, 0xc0, 0xa8, 0x00, 0x13, 0xc0, 0xa8, /* .n...... */ +0x00, 0x66, 0x1f, 0xf5, 0x1f, 0xf5, 0x0f, 0xa8, /* .f...... */ +0x90, 0x4e, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, /* .Nabcdef */ +0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, /* ghijklmn */ +0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, /* opqrstuv */ +0x77, 0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, /* wxyz.... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00 /* .. */ +}; + +/* Frame (1514 bytes) */ +static const unsigned char pkt5[1514] = { +0x18, 0x03, 0x73, 0x29, 0x5f, 0x66, 0xa4, 0x1f, /* ..s)_f.. */ +0x72, 0x53, 0xa0, 0xf7, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x05, 0xdc, 0x3b, 0xd9, 0x20, 0xb9, 0x40, 0x11, /* ..;. .@. */ +0x96, 0xb5, 0xc0, 0xa8, 0x00, 0x13, 0xc0, 0xa8, /* ........ */ +0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .f...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00 /* .. */ +}; + +/* Frame (1082 bytes) */ +static const unsigned char pkt6[1082] = { +0x18, 0x03, 0x73, 0x29, 0x5f, 0x66, 0xa4, 0x1f, /* ..s)_f.. */ +0x72, 0x53, 0xa0, 0xf7, 0x08, 0x00, 0x45, 0x00, /* rS....E. */ +0x04, 0x2c, 0x3b, 0xd9, 0x01, 0x72, 0x40, 0x11, /* .,;..r@. */ +0xb7, 0xac, 0xc0, 0xa8, 0x00, 0x13, 0xc0, 0xa8, /* ........ */ +0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .f...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00 /* .. */ +}; + +#if 0 +/* Reassembled IPv4 (4008 bytes) */ +static const unsigned char pkt6_1[4008] = { +0x1f, 0xf5, 0x1f, 0xf5, 0x0f, 0xa8, 0x90, 0x4e, /* .......N */ +0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, /* abcdefgh */ +0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* ijklmnop */ +0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* qrstuvwx */ +0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* yz...... */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ........ */ +}; +#endif + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_fragmentation_processing_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 0, 0, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pool_area, sizeof(pool_area)); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(192, 168, 0, 102), 0xFFFFF000UL, + &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(192, 168, 0, 19), 0xFFFFF000UL, + &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + /* Enable IP fragmentation logic on both IP instances. */ + status = nx_ip_fragment_enable(&ip_0); + status += nx_ip_fragment_enable(&ip_1); + + /* Check for IP fragment enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Fragmentation Processing Test........................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 8181, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + + /* Let thread 1 start to run. */ + tx_thread_resume(&thread_1); + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, 1 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + else + nx_packet_release(my_packet); + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, 1 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + error_counter++; + else + nx_packet_release(my_packet); + + /* Check status. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Send the second fragmentation of the frist packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, 0, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, (void*)(pkt2 + 14), sizeof(pkt2) - 14, &pool_0, NX_NO_WAIT); + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Send the first fragmentation of the frist packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, 0, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, (void*)(pkt1 + 14), sizeof(pkt1) - 14, &pool_0, NX_NO_WAIT); + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Send the second fragmentation of the second packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, 0, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, (void*)(pkt5 + 14), sizeof(pkt5) - 14, &pool_0, NX_NO_WAIT); + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Send the first fragmentation of the second packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, 0, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, (void*)(pkt4 + 14), sizeof(pkt4) - 14, &pool_0, NX_NO_WAIT); + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Send the third fragmentation of the first packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, 0, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, (void*)(pkt3 + 14), sizeof(pkt3) - 14, &pool_0, NX_NO_WAIT); + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Send the third fragmentation of the second packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, 0, NX_NO_WAIT); + status += nx_packet_data_append(my_packet, (void*)(pkt6 + 14), sizeof(pkt6) - 14, &pool_0, NX_NO_WAIT); + _nx_ip_packet_deferred_receive(&ip_0, my_packet); + + /* Check status. */ + if (status) + error_counter++; +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_fragmentation_processing_test_application_define(void *first_unused_memory) +#endif +{ + + printf("NetX Test: UDP Fragmentation Processing Test.........................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_FRAGMENTATION */ diff --git a/test/regression/netxduo_test/netx_udp_free_port_find_test.c b/test/regression/netxduo_test/netx_udp_free_port_find_test.c new file mode 100644 index 00000000..b23d3c2e --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_free_port_find_test.c @@ -0,0 +1,218 @@ +/* This NetX test concentrates on the UDP free port find operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET my_socket[NX_MAX_PORT - NX_SEARCH_PORT_START + 1]; +#ifdef __PRODUCT_NETXDUO__ +static NX_UDP_SOCKET my_socket_1; +#endif /* __PRODUCT_NETXDUO__ */ + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* The 2 ports will hashed to the same index. */ +#define CLIENT_PORT_1 0x00000100 +#define CLIENT_PORT_2 0x00008100 + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void test_control_return(UINT status); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_free_port_find_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT free_port; +UINT i; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Free Port Find Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_udp_socket_bind(&socket_0, CLIENT_PORT_1, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + /* CLIENT_PORT_1 has been bound. */ + status = nx_udp_free_port_find(&ip_0, CLIENT_PORT_1, &free_port); + if((status != NX_SUCCESS) && (free_port != CLIENT_PORT_1 + 1)) + error_counter++; + + /* CLIENT_PORT_2 and CLIENT_PORT_1 are mapped to the same index. */ + status = nx_udp_free_port_find(&ip_0, CLIENT_PORT_2, &free_port); + if ((status != NX_SUCCESS) || (free_port != CLIENT_PORT_2)) + error_counter++; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + if (status != NX_SUCCESS) + error_counter++; + + /* Test port wrap around. */ + status = nx_udp_socket_bind(&socket_0, NX_MAX_PORT, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + status = nx_udp_free_port_find(&ip_0, NX_MAX_PORT, &free_port); + if ((status != NX_SUCCESS) || (free_port != NX_SEARCH_PORT_START)) + error_counter++; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + if (status != NX_SUCCESS) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + if (status) + error_counter++; + + for(i = 0; i <= (NX_MAX_PORT - NX_SEARCH_PORT_START); i++) + { + status = nx_udp_socket_create(&ip_0, &my_socket[i], "Socket Array", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&my_socket[i], i + NX_SEARCH_PORT_START, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + status = nx_udp_free_port_find(&ip_0, NX_SEARCH_PORT_START, &free_port); + if(status != NX_NO_FREE_PORTS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Verify the port number ahead of NX_SEARCH_PORT_START. */ + status = nx_udp_socket_create(&ip_0, &my_socket_1, "Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&my_socket_1, (NX_SEARCH_PORT_START - 1), NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_free_port_find(&ip_0, (NX_SEARCH_PORT_START - 1), &free_port); + if(status != NX_NO_FREE_PORTS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + diff --git a/test/regression/netxduo_test/netx_udp_ipv4_interface2_test_1_test.c b/test/regression/netxduo_test/netx_udp_ipv4_interface2_test_1_test.c new file mode 100644 index 00000000..b8d82730 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_ipv4_interface2_test_1_test.c @@ -0,0 +1,511 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; + +static ULONG error_counter; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_ipv4_interface2_test_1_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + notify_calls = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2,2,3,4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + status += nx_ip_interface_attach(&ip_1, "Second Interface", IP_ADDRESS(2,2,3,5), 0xFFFFFF00UL, _nx_ram_network_driver_512); + + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *my_packet; + UINT free_port; + ULONG udp_packets_sent, udp_bytes_sent, udp_packets_received, udp_bytes_received, udp_invalid_packets, udp_receive_packets_dropped, udp_checksum_errors; + ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP IPv4 Interface2 Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the IP threads and thread 1 execute. */ + tx_thread_relinquish(); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Pickup the first free port for 0x88. */ + status = nx_udp_free_port_find(&ip_0, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(31); + } + + /* Disable checksum logic for this socket. */ + status = nx_udp_socket_checksum_disable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Setup the ARP entry for the UDP send. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0, 0); + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Send 1000 packets without checksum. */ + thread_0_counter = 0; + while ((thread_0_counter < 1000) && (error_counter == 0)) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(2, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Relinquish to thread 1 so it can pickup the message. */ + tx_thread_relinquish(); + } + + /* Now, enable the checksum. */ + status = nx_udp_socket_checksum_enable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send another 1000 packets with checksum enabled. */ + while ((thread_0_counter < 2000) && (error_counter == 0)) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(2, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Relinquish to thread 1 so it can pickup the message. */ + tx_thread_relinquish(); + } + + /* Get UDP socket information. */ + status = nx_udp_socket_info_get(&socket_0, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_TCP_INFO + + if ((packets_sent != 2000) || (bytes_sent != 2000*28)) + { + error_counter++; + } +#endif + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != 2000) || (thread_1_counter != 2000) || + (packets_received) || (bytes_received) || (packets_queued) || (receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get nothing from UDP. */ + status = nx_udp_info_get(&ip_0, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP information. */ + status = nx_udp_info_get(&ip_0, &udp_packets_sent, &udp_bytes_sent, &udp_packets_received, &udp_bytes_received, + &udp_invalid_packets, &udp_receive_packets_dropped, &udp_checksum_errors); + +#ifndef NX_DISABLE_TCP_INFO + if ((udp_packets_sent != 2000) || (udp_bytes_sent != 2000*28)) + { + error_counter++; + } +#endif + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != 2000) || (thread_1_counter != 2000) || + (udp_packets_received) || (udp_bytes_received) || (udp_invalid_packets) || (udp_receive_packets_dropped) || (udp_checksum_errors) || (notify_calls != 2000)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + ULONG ip_address; + UINT port; + NX_PACKET *my_packet; + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&socket_1, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Get 1000 packets. */ + thread_1_counter = 0; + while (thread_1_counter < 1000) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Get the source IP and port. */ + status = nx_udp_source_extract(my_packet, &ip_address, &port); + + /* Check status. */ + if ((status) || (ip_address != IP_ADDRESS(2,2,3,4)) || (port != 0x88)) + break; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Increment thread 1's counter. */ + thread_1_counter++; + } + + /* Get another 1000 packets. */ + while (thread_1_counter < 2000) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Increment thread 1's counter. */ + thread_1_counter++; + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &socket_1) + notify_calls++; +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_ipv4_interface2_test_1_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: UDP IPv4 Interface2 Test..................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_udp_ipv6_interface2_test_1_test.c b/test/regression/netxduo_test/netx_udp_ipv6_interface2_test_1_test.c new file mode 100644 index 00000000..acc34429 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_ipv6_interface2_test_1_test.c @@ -0,0 +1,592 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if defined(FEATURE_NX_IPV6) && (NX_MAX_PHYSICAL_INTERFACES > 1) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; + +static ULONG error_counter; +static ULONG notify_calls = 0; + +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; +static NXD_ADDRESS ipv6_address_3; +static NXD_ADDRESS ipv6_address_4; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void _nx_ram_network_driver_512(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); +extern void test_control_return(UINT status); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_ipv6_interface2_test_1_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + notify_calls = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(2,2,3,4), 0xFFFFFF00UL, _nx_ram_network_driver_512); + status += nx_ip_interface_attach(&ip_1, "Second Interface", IP_ADDRESS(2,2,3,5), 0xFFFFFF00UL, _nx_ram_network_driver_512); + + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Enable ICMP for IP Instance 0 and 1. */ + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + + /* Check for errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *my_packet; + UINT free_port; + ULONG udp_packets_sent, udp_bytes_sent, udp_packets_received, udp_bytes_received, udp_invalid_packets, udp_receive_packets_dropped, udp_checksum_errors; + ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP IPv6 Interface2 Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Pickup the first free port for 0x88. */ + status = nx_udp_free_port_find(&ip_0, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Disable checksum logic for this socket. */ + status = nx_udp_socket_checksum_disable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + +#ifndef NX_DISABLE_IPV6_DAD + /* Try to send before DAD done. */ + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nxd_udp_socket_source_send(&socket_0, my_packet, &ipv6_address_4, 0x89, 0); + + if (status != NX_NO_INTERFACE_ADDRESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + nx_packet_release(my_packet); + + + /* Sleep for DAD */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* NX_DISABLE_IPV6_DAD */ + + /* Let other threads run. */ + tx_thread_resume(&thread_1); + tx_thread_relinquish(); + + /* Send 1000 packets without checksum. */ + thread_0_counter = 0; + while ((thread_0_counter < 1000) && (error_counter == 0)) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &ipv6_address_4, 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Relinquish to thread 1 so it can pickup the message. */ + tx_thread_relinquish(); + } + + /* Now, enable the checksum. */ + status = nx_udp_socket_checksum_enable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send another 1000 packets with checksum enabled. */ + while ((thread_0_counter < 2000) && (error_counter == 0)) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &ipv6_address_4, 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Relinquish to thread 1 so it can pickup the message. */ + tx_thread_relinquish(); + } + + /* Get UDP socket information. */ + status = nx_udp_socket_info_get(&socket_0, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_TCP_INFO + + if ((packets_sent != 2000) || (bytes_sent != 2000*28)) + { + error_counter++; + } +#endif + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != 2000) || (thread_1_counter != 2000) || + (packets_received) || (bytes_received) || (packets_queued) || (receive_packets_dropped) || (checksum_errors)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP information. */ + status = nx_udp_info_get(&ip_0, &udp_packets_sent, &udp_bytes_sent, &udp_packets_received, &udp_bytes_received, + &udp_invalid_packets, &udp_receive_packets_dropped, &udp_checksum_errors); + +#ifndef NX_DISABLE_TCP_INFO + if ((udp_packets_sent != 2000) || (udp_bytes_sent != 2000*28)) + { + error_counter++; + } +#endif + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != 2000) || (thread_1_counter != 2000) || + (udp_packets_received) || (udp_bytes_received) || (udp_invalid_packets) || (udp_receive_packets_dropped) || (udp_checksum_errors) || (notify_calls != 2000)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + UINT protocol, port, interface_index; + NX_PACKET *my_packet; + NXD_ADDRESS ipv6_address; + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&socket_1, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Get 1000 packets. */ + thread_1_counter = 0; + while (1) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Get the source IP and port. */ + status = nxd_udp_source_extract(my_packet, &ipv6_address, &port); + + /* Check status. */ + if ((status)|| (port != 0x88) || + (ipv6_address.nxd_ip_version != NX_IP_VERSION_V6)|| + (ipv6_address.nxd_ip_address.v6[0] != ipv6_address_3.nxd_ip_address.v6[0])|| + (ipv6_address.nxd_ip_address.v6[1] != ipv6_address_3.nxd_ip_address.v6[1])|| + (ipv6_address.nxd_ip_address.v6[2] != ipv6_address_3.nxd_ip_address.v6[2])|| + (ipv6_address.nxd_ip_address.v6[3] != ipv6_address_3.nxd_ip_address.v6[3])) + break; + + /* Get the source IP and port. */ + status = nxd_udp_packet_info_extract(my_packet, &ipv6_address, &protocol, &port, &interface_index); + + /* Check status. */ + if ((status)|| (port != 0x88) || (protocol != 0x11) || (interface_index != 1) || + (ipv6_address.nxd_ip_version != NX_IP_VERSION_V6)|| + (ipv6_address.nxd_ip_address.v6[0] != ipv6_address_3.nxd_ip_address.v6[0])|| + (ipv6_address.nxd_ip_address.v6[1] != ipv6_address_3.nxd_ip_address.v6[1])|| + (ipv6_address.nxd_ip_address.v6[2] != ipv6_address_3.nxd_ip_address.v6[2])|| + (ipv6_address.nxd_ip_address.v6[3] != ipv6_address_3.nxd_ip_address.v6[3])) + break; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Increment thread 1's counter. */ + thread_1_counter++; + } + + /* Get another 1000 packets. */ + while (thread_1_counter < 2000) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Increment thread 1's counter. */ + thread_1_counter++; + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &socket_1) + notify_calls++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_ipv6_interface2_test_1_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: UDP IPv6 Interface2 Test..................................N/A\n"); + + test_control_return(3); + +} +#endif diff --git a/test/regression/netxduo_test/netx_udp_loopback_test.c b/test/regression/netxduo_test/netx_udp_loopback_test.c new file mode 100644 index 00000000..91dd1de1 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_loopback_test.c @@ -0,0 +1,358 @@ +/* This NetX test concentrates on the UDP send and recv through loopback interface. */ + + +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_LOOPBACK_INTERFACE) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +static NXD_ADDRESS address_lo; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_0; +#endif /* FEATURE_NX_IPV6 */ + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UCHAR recv_buf[28]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_loopback_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the client thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status += nxd_ipv6_enable(&ip_0); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Set global address. */ + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0x20010DB8; + address_0.nxd_ip_address.v6[1] = 0x00010001; + address_0.nxd_ip_address.v6[2] = 0x021122FF; + address_0.nxd_ip_address.v6[3] = 0xFE334456; + + status = nxd_ipv6_address_set(&ip_0, 0, &address_0, 64, NX_NULL); + +#endif /* FEATURE_NX_IPV6 */ + + /* Check for errors. */ + if (status) + error_counter++; + + /* Set loopback address. */ + address_lo.nxd_ip_version = NX_IP_VERSION_V4; + address_lo.nxd_ip_address.v4 = IP_ADDRESS(127, 0, 0, 1); +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Loopback Test........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + for (i = 0; i < 3; i++) +#else + for (i = 0; i < 2; i++) +#endif + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append data. */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if (i == 0) + { + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(127, 0, 0, 1), 0x89, NX_LOOPBACK_INTERFACE); + } + else if (i == 1) + { + status = nxd_udp_socket_source_send(&socket_0, my_packet, &address_lo, 0x89, NX_LOOPBACK_INTERFACE); + } +#ifdef FEATURE_NX_IPV6 + else + { + status = nxd_udp_socket_source_send(&socket_0, my_packet, &address_0, 0x89, 0); + } +#endif /* FEATURE_NX_IPV6 */ + + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG bytes_copied; +UINT i; + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + for (i = 0; i < 3; i++) +#else + for (i = 0; i < 2; i++) +#endif + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_extract_offset(my_packet, 0, recv_buf, 28, &bytes_copied); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(memcmp(recv_buf, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28) || (bytes_copied != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_loopback_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: UDP Loopback Test.........................................N/A\n"); + test_control_return(3); +} +#endif /* NX_DISABLE_LOOPBACK_INTERFACE */ diff --git a/test/regression/netxduo_test/netx_udp_multiple_ports_test.c b/test/regression/netxduo_test/netx_udp_multiple_ports_test.c new file mode 100644 index 00000000..ae6f061f --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_multiple_ports_test.c @@ -0,0 +1,617 @@ +/* This NetX test concentrates on sending to and receiving from multiple UDP ports. */ + + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; +static NX_UDP_SOCKET socket_2; +static NX_UDP_SOCKET socket_3; +static NX_UDP_SOCKET socket_4; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG error_counter; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_multiple_ports_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + notify_calls = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +ULONG udp_packets_sent, udp_bytes_sent, udp_packets_received, udp_bytes_received, udp_invalid_packets, udp_receive_packets_dropped, udp_checksum_errors; +ULONG packets_sent, bytes_sent, packets_received, bytes_received, packets_queued, receive_packets_dropped, checksum_errors; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Multiple Ports Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the IP threads and thread 1 execute. */ + tx_thread_relinquish(); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Pickup the first free port for 0x88. */ + status = nx_udp_free_port_find(&ip_0, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(31); + } + + /* Setup the ARP entry for the UDP send. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0, 0); + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Send 1000 packets to four ports. */ + thread_0_counter = 0; + while ((thread_0_counter < 1000) && (error_counter == 0)) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0xE9); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0xC9); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0xA9); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + + /* Relinquish to thread 1 so it can pickup the message. */ + tx_thread_relinquish(); + } + + /* Get UDP socket information. */ + status = nx_udp_socket_info_get(&socket_0, &packets_sent, &bytes_sent, &packets_received, &bytes_received, + &packets_queued, &receive_packets_dropped, &checksum_errors); + +#ifndef NX_DISABLE_TCP_INFO + if ((packets_sent != 1000*4) || (bytes_sent != 1000*4*28)) + { + error_counter++; + } +#endif + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != 1000) || (thread_1_counter != 1000) || + (packets_received) || (bytes_received) || (packets_queued) || (receive_packets_dropped) || (checksum_errors)) + { + + error_counter++; + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get UDP information. */ + status = nx_udp_info_get(&ip_0, &udp_packets_sent, &udp_bytes_sent, &udp_packets_received, &udp_bytes_received, + &udp_invalid_packets, &udp_receive_packets_dropped, &udp_checksum_errors); + +#ifndef NX_DISABLE_TCP_INFO + if ((udp_packets_sent != 1000*4) || (udp_bytes_sent != 1000*4*28)) + { + error_counter++; + } +#endif + /* Check status. */ + if ((error_counter) || (status) || (thread_0_counter != 1000) || (thread_1_counter != 1000) || + (udp_packets_received) || (udp_bytes_received) || (udp_invalid_packets) || (udp_receive_packets_dropped) || (udp_checksum_errors) || (notify_calls != 1000)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_address; +UINT port; +NX_PACKET *my_packet; + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&socket_1, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Create another UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_2, "Socket 2", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_2, 0xA9, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Create another UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_3, "Socket 3", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_3, 0xC9, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Create another UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_4, "Socket 4", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_4, 0xE9, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Get 1000 packets for each socket. */ + thread_1_counter = 0; + while (thread_1_counter < 1000) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_4, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Get the source IP and port. */ + status = nx_udp_source_extract(my_packet, &ip_address, &port); + + /* Check status. */ + if ((status) || (ip_address != IP_ADDRESS(1,2,3,4)) || (port != 0x88)) + break; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Receive another UDP packet. */ + status = nx_udp_socket_receive(&socket_3, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Get the source IP and port. */ + status = nx_udp_source_extract(my_packet, &ip_address, &port); + + /* Check status. */ + if ((status) || (ip_address != IP_ADDRESS(1,2,3,4)) || (port != 0x88)) + break; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Receive another UDP packet. */ + status = nx_udp_socket_receive(&socket_2, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Get the source IP and port. */ + status = nx_udp_source_extract(my_packet, &ip_address, &port); + + /* Check status. */ + if ((status) || (ip_address != IP_ADDRESS(1,2,3,4)) || (port != 0x88)) + break; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Receive another UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Get the source IP and port. */ + status = nx_udp_source_extract(my_packet, &ip_address, &port); + + /* Check status. */ + if ((status) || (ip_address != IP_ADDRESS(1,2,3,4)) || (port != 0x88)) + break; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + break; + + /* Increment thread 1's counter. */ + thread_1_counter++; + } + + /* Unbind the UDP sockets. */ + status = nx_udp_socket_unbind(&socket_1); + status += nx_udp_socket_unbind(&socket_2); + status += nx_udp_socket_unbind(&socket_3); + status += nx_udp_socket_unbind(&socket_4); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &socket_1) + notify_calls++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_multiple_ports_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: UDP Multiple Ports Test...................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_udp_nxe_api_test.c b/test/regression/netxduo_test/netx_udp_nxe_api_test.c new file mode 100644 index 00000000..7bb74767 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_nxe_api_test.c @@ -0,0 +1,1353 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "nx_udp.h" +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_packet.h" + +#ifdef FEATURE_NX_IPV6 +#include "nx_ipv6.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP invalid_ip; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_0; +static NXD_ADDRESS address_1; +static NXD_ADDRESS invalid_address; +#endif /* FEATURE_NX_IPV6 */ + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&ip_0); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Set source and destination address with global address. */ + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0x20010DB8; + address_0.nxd_ip_address.v6[1] = 0x00010001; + address_0.nxd_ip_address.v6[2] = 0x021122FF; + address_0.nxd_ip_address.v6[3] = 0xFE334456; + + /* Set the destination address. */ + address_1.nxd_ip_version = NX_IP_VERSION_V6; + address_1.nxd_ip_address.v6[0] = 0x20010DB8; + address_1.nxd_ip_address.v6[1] = 0x00010001; + address_1.nxd_ip_address.v6[2] = 0x021122FF; + address_1.nxd_ip_address.v6[3] = 0xFE334458; + + /* Set the IPv6 address. */ + status += nxd_ipv6_address_set(&ip_0, 0, &address_0, 64, NX_NULL); + + /* Check for status. */ + if (status) + error_counter++; + +#endif /* FEATURE_NX_IPV6 */ +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT socket_id; +NX_PACKET *my_packet; +NX_PACKET *unkown_packet = NX_NULL; +UINT free_port; +UINT port; +UINT protocol; +UINT if_index; +ULONG udp_packets_sent, udp_bytes_sent, udp_packets_received, udp_bytes_received, + udp_invalid_packets, udp_receive_packets_dropped, udp_checksum_errors, udp_packet_quiequed; +#ifdef FEATURE_NX_IPV6 +NXD_ADDRESS my_address; +NX_PACKET *my_packet_2; +#endif +ULONG my_address_2; +ULONG bytes_avalable; +#ifdef __PRODUCT_NETXDUO__ +UCHAR temp_interface_valid; +UCHAR *temp; +NX_PACKET *invalid_packet; +#endif /* __PRODUCT_NETXDUO__ */ +NX_UDP_SOCKET * temp_socket; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP NXE API Test.........................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Create udp socket without ip instance. */ + status = nx_udp_socket_create(NX_NULL, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create udp socket with invalid ip instance. */ + invalid_ip.nx_ip_id = 0; + status = nx_udp_socket_create(&invalid_ip, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create udp socket with NULL pointer. */ + status = nx_udp_socket_create(&ip_0, NX_NULL, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + /* Create udp socket with wrong size. */ + status = _nxe_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5, 0); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* NX_DISABLE_ERROR_CHECKING */ + + /* Create udp socket with invalid service type. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", 0xFFFFFFFF, NX_FRAGMENT_OKAY, 0x80, 5); + if(status != NX_OPTION_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create udp socket with invalid fragment option. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, 11111, 0x80, 5); + if(status != NX_OPTION_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create udp socket with invalid time to live option. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE_MASK+1, 5); + if(status != NX_OPTION_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create again. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup the first free port for 0x88. */ + status = nx_udp_free_port_find(&ip_0, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_delete(&socket_0); + if(status != NX_STILL_BOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&socket_0, 0xFFFFFFFF, NX_IP_PERIODIC_RATE/10); + if(status != NX_INVALID_PORT) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the packet. */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the the packet with null socket. */ + status = nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + + /* Send the the packet with null socket. */ + status = nxd_udp_socket_send(NX_NULL, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the the packet with null packet. */ + status = nxd_udp_socket_send(&socket_0, unkown_packet, &address_1, 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the null packet with null socket. */ + status = nxd_udp_socket_send(NX_NULL, unkown_packet, &address_1, 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the the packet with null address. */ + status = nxd_udp_socket_send(&socket_0, my_packet, 0, 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the the packet with error socket ID. */ + socket_0.nx_udp_socket_id = 0; + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_id = NX_UDP_ID; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet_2, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append the packet. */ + status = nx_packet_data_append(my_packet_2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the packet whose IP vesion is IPv6. */ + my_packet_2 -> nx_packet_ip_version = NX_IP_VERSION_V6; + status = nx_udp_socket_send(&socket_0, my_packet_2, IP_ADDRESS(1, 2, 3, 5), 0x89); +#endif + + /* Send the the packet with unkown packet. */ + status = nx_udp_socket_send(&socket_0, unkown_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Send the packet with freed packet. */ + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_FREE; + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; +#endif + + /* Send the packet with unbound socket. */ + temp_socket = socket_0.nx_udp_socket_bound_next; + socket_0.nx_udp_socket_bound_next = NX_NULL; + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_NOT_BOUND) + { + + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_bound_next = temp_socket; + +#ifdef FEATURE_NX_IPV6 + /* Send the the packet with null socket. */ + status = nxd_udp_socket_send(&socket_0, unkown_packet, &address_1, 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Send the the packet with invalid address. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(0, 0, 0, 0), 0x89); + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Send the the packet with invalid address. */ + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(0, 0, 0 ,0), 0x89, 0); + if (status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_source_send(NX_NULL, my_packet, IP_ADDRESS(1, 2, 3 ,5), 0x89, 0); + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ + +#ifdef FEATURE_NX_IPV6 + /* Send the the packet with null socket. */ + status = nxd_udp_socket_send(&socket_0, my_packet, NX_NULL, 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the the packet with invalid socket id. */ + socket_0.nx_udp_socket_id = 0; + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_id = NX_UDP_ID; + + /* Send the the packet with freed packet. */ + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_FREE; + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; + + /* Fake one invalid address. */ + invalid_address.nxd_ip_version = 0x5; + invalid_address.nxd_ip_address.v4= 0; + + /* Send the the packet with null socket. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &invalid_address, 0x89); + + /* Check status. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the packet with invalid destination IP address. */ + status = nxd_udp_socket_source_send(&socket_0, my_packet, &invalid_address, 0x89, 0); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Fake one invalid address. */ + invalid_address.nxd_ip_version = NX_IP_VERSION_V4; + invalid_address.nxd_ip_address.v4= 0; + + /* Send the the packet with invalid IP address. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &invalid_address, 0x89); + + /* Check status. */ + if (status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the null packet. */ + status = nxd_udp_socket_source_send(&socket_0, unkown_packet, &address_1, 0x89, 0) ; + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the packet to null address. */ + status = nxd_udp_socket_source_send(&socket_0, my_packet, NX_NULL, 0x89, 0) ; + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the packet from an invalid interface index. */ + status = nxd_udp_socket_source_send(&socket_0, my_packet, &invalid_address, 0x89, 123) ; + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the packet with invalid destination IP address. */ + status = nxd_udp_socket_source_send(&socket_0, my_packet, &invalid_address, 0x89, 0); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Fake one invalid address. */ + invalid_address.nxd_ip_version = NX_IP_VERSION_V6; + invalid_address.nxd_ip_address.v6[0]= 0; + invalid_address.nxd_ip_address.v6[1]= 0; + invalid_address.nxd_ip_address.v6[2]= 0; + invalid_address.nxd_ip_address.v6[3]= 0; + + /* Send the the packet with null socket. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &invalid_address, 0x89); + + /* Check status. */ + if (status != NX_IP_ADDRESS_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Send the packet with invalid destination IP address. */ + status = nxd_udp_socket_source_send(&socket_0, my_packet, &invalid_address, 0x89, 0); + if(status != NX_IP_ADDRESS_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the packet from an invalid interface index. */ + status = nxd_udp_socket_source_send(&socket_0, my_packet, &address_1, 0x89, 123) ; + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#endif + +#ifdef __PRODUCT_NETXDUO__ + /* Send the packet from an invalid interface index. */ + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89, NX_MAX_PHYSICAL_INTERFACES+1) ; + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } + + temp_interface_valid = ip_0.nx_ip_interface[NX_MAX_PHYSICAL_INTERFACES - 1].nx_interface_valid; + ip_0.nx_ip_interface[NX_MAX_PHYSICAL_INTERFACES - 1].nx_interface_valid = NX_FALSE; + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89, NX_MAX_PHYSICAL_INTERFACES-1) ; + if(status != NX_INVALID_INTERFACE) + { + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ip_interface[NX_MAX_PHYSICAL_INTERFACES - 1].nx_interface_valid = temp_interface_valid; +#endif /* __PRODUCT_NETXDUO__ */ + + + /* Send the the packet with big number port. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0xFFFFFFFF); + + /* Check status. */ + if (status != NX_INVALID_PORT) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Send the the packet with invalid port. */ + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0xFFFFFFFF, 0); + if(status != NX_INVALID_PORT) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ + +#ifdef FEATURE_NX_IPV6 + /* Send the the packet with invalid port. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0xFFFFFFFF); + + /* Check status. */ + if (status != NX_INVALID_PORT) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send the the packet with invalid port. */ + status = nxd_udp_socket_source_send(&socket_0, my_packet, &address_1, 0xFFFFFFFF, 0); + if(status != NX_INVALID_PORT) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#endif + + /* Send the the packet when udp disable. */ + ip_0.nx_ip_udp_packet_receive = NX_NULL; + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + if (status != NX_NOT_ENABLED) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup free port with null IP instance. */ + status = nx_udp_free_port_find(NX_NULL, 0, NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup free port with invalid IP instance. */ + ip_0.nx_ip_id = 0; + status = nx_udp_free_port_find(&ip_0, 0, NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + ip_0.nx_ip_id = NX_IP_ID; + + /* Pickup free port with UDP disabled. */ + status = nx_udp_free_port_find(&ip_0, 0x123, &free_port); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + status = nx_udp_info_get(NX_NULL, &udp_packets_sent, &udp_bytes_sent, + &udp_packets_received, &udp_bytes_received, &udp_invalid_packets, + &udp_receive_packets_dropped, &udp_checksum_errors); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + invalid_ip.nx_ip_id = 0; + status = nx_udp_info_get(&invalid_ip, &udp_packets_sent, &udp_bytes_sent, + &udp_packets_received, &udp_bytes_received, &udp_invalid_packets, + &udp_receive_packets_dropped, &udp_checksum_errors); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_info_get(&ip_0, &udp_packets_sent, &udp_bytes_sent, + &udp_packets_received, &udp_bytes_received, &udp_invalid_packets, + &udp_receive_packets_dropped, &udp_checksum_errors); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&socket_0, 0x123, 10); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bytes_available(&socket_0, NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + socket_0.nx_udp_socket_id = 0; + status = nx_udp_socket_bytes_available(&socket_0, &bytes_avalable); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_id = NX_UDP_ID; + + status = nx_udp_socket_bytes_available(&socket_0, &bytes_avalable); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_checksum_disable(&socket_0); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_checksum_enable(&socket_0); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_delete(&socket_0); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_info_get(&socket_0, &udp_packets_sent, &udp_bytes_sent, + &udp_packets_received, &udp_bytes_received, &udp_packet_quiequed, + &udp_receive_packets_dropped, &udp_checksum_errors); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + status = nx_udp_socket_port_get(&socket_0, &port); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + socket_0.nx_udp_socket_id = 0; + status = nx_udp_socket_port_get(&socket_0, &port); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_id = NX_UDP_ID; + + status = nx_udp_socket_port_get(&socket_0, NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_receive(&socket_0, &my_packet, NX_IP_PERIODIC_RATE); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + socket_0.nx_udp_socket_id = 0; + status = nx_udp_socket_receive(&socket_0, &my_packet, NX_IP_PERIODIC_RATE); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_id = NX_UDP_ID; + + status = nx_udp_socket_receive(&socket_0, NX_NULL, NX_IP_PERIODIC_RATE); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3 ,5), 0x89, 0); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* __PRODUCT_NETXDUO__ */ + + status = nx_udp_socket_unbind(&socket_0); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + +#ifdef FEATURE_NX_IPV6 + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_udp_socket_source_send(&socket_0, my_packet, &address_1, 0x89, 0); + if(status != NX_NOT_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + /* Enable UDP traffic again. */ + status = nx_udp_enable(&ip_0); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable UDP again. */ + status = nx_udp_enable(&ip_0); + if(status != NX_ALREADY_ENABLED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_enable(NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + invalid_ip.nx_ip_id = 0; + status = nx_udp_enable(&invalid_ip); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Send the the packet with invalid packet structure. */ + my_packet -> nx_packet_prepend_ptr = my_packet -> nx_packet_data_start; + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_UNDERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Test packet with underflow pointer. */ + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89, 0); + if (status != NX_UNDERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + status = nxd_udp_socket_source_send(&socket_0, my_packet, &address_1, 0x89, 0); + if (status != NX_UNDERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* FEATURE_NX_IPV6 */ +#endif /* __PRODUCT_NETXDUO__ */ + + status = nx_udp_source_extract(my_packet, &my_address_2, &port); + if(status != NX_INVALID_PACKET) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Send the the packet with null socket. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status != NX_UNDERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } +#endif /* FEATURE_NX_IPV6 */ + + /* Send the the packet with invalid packet. */ + my_packet -> nx_packet_prepend_ptr = my_packet -> nx_packet_data_start + NX_UDP_PACKET; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_data_end + 1; + + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + if (status != NX_OVERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + /* Test packet with overflow packet. */ + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89, 0); + if (status != NX_OVERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + status = nxd_udp_socket_source_send(&socket_0, my_packet, &address_1, 0x89, 0); + if (status != NX_OVERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif +#endif /* __PRODUCT_NETXDUO__ */ + + +#ifdef FEATURE_NX_IPV6 + /* Send the the packet with null socket. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status != NX_OVERFLOW) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + +#ifdef FEATURE_NX_IPV6 + status = nxd_udp_source_extract(my_packet, &address_1, NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_udp_source_extract(my_packet, NX_NULL, &port); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + temp = my_packet -> nx_packet_ip_header; + my_packet -> nx_packet_ip_header = NX_NULL; + /* Extract info from an invalid packet. */ + status = nxd_udp_source_extract(my_packet, &address_1, &port); + if(status != NX_INVALID_PACKET) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Restore the packet. */ + my_packet -> nx_packet_ip_header = temp; + + /* Extract info from a NULL packet. */ + status = nxd_udp_packet_info_extract(NX_NULL, &my_address, &protocol, &port, &if_index); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#endif + /* Pickup free port from an invalid port. */ + status = nx_udp_free_port_find(&ip_0, 0, &free_port); + if(status != NX_INVALID_PORT) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup free port from an invalid port. */ + status = nx_udp_free_port_find(&ip_0, (NX_MAX_PORT + 1), &free_port); + if(status != NX_INVALID_PORT) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Pickup free port from with invalid pointer. */ + status = nx_udp_free_port_find(&ip_0, 0, NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_packet_info_extract(NX_NULL, &my_address_2, &protocol, &port, &if_index); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bytes_available(NX_NULL, &bytes_avalable); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_checksum_disable(NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + socket_1.nx_udp_socket_id = 0; + status = nx_udp_socket_checksum_disable(&socket_1); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_checksum_enable(&socket_1); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + socket_1.nx_udp_socket_id = NX_UDP_ID; + + status = nx_udp_socket_checksum_enable(NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_delete(NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the socket with invalid ID. */ + socket_0.nx_udp_socket_id = 0; + status = nx_udp_socket_delete(&socket_0); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_id = NX_UDP_ID; + + status = nx_udp_socket_info_get(NX_NULL, &udp_packets_sent, &udp_bytes_sent, + &udp_packets_received, &udp_bytes_received, &udp_packet_quiequed, + &udp_receive_packets_dropped, &udp_checksum_errors); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + socket_1.nx_udp_socket_id = 0; + status = nx_udp_socket_info_get(&socket_1, &udp_packets_sent, &udp_bytes_sent, + &udp_packets_received, &udp_bytes_received, &udp_packet_quiequed, + &udp_receive_packets_dropped, &udp_checksum_errors); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + socket_1.nx_udp_socket_id = NX_UDP_ID; + + status = nx_udp_socket_port_get(NX_NULL, &port); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_receive(NX_NULL, &my_packet, NX_IP_PERIODIC_RATE/10); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_receive_notify(NX_NULL, NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + socket_id = socket_0.nx_udp_socket_id; + socket_0.nx_udp_socket_id = 0; + status = nx_udp_socket_receive_notify(&socket_0, NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + socket_0.nx_udp_socket_id = NX_UDP_ID; + status = nx_udp_socket_receive_notify(&socket_0, NX_NULL); + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_id = socket_id; + +#ifdef __PRODUCT_NETXDUO__ + status = nx_udp_socket_source_send(NX_NULL, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89, 0); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + invalid_packet = NX_NULL; + status = nx_udp_socket_source_send(&socket_0, invalid_packet, IP_ADDRESS(1, 2, 3, 5), 0x89, 0); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_data_end; + socket_0.nx_udp_socket_bound_next = NX_NULL; + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89, 0); + if(status != NX_NOT_BOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_bound_next = &socket_0; + +#ifdef __PRODUCT_NETXDUO__ + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_FREE; +#else + my_packet -> nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_FREE; +#endif + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89, 0); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } +#ifdef __PRODUCT_NETXDUO__ + my_packet -> nx_packet_union_next.nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; +#else + my_packet -> nx_packet_tcp_queue_next = (NX_PACKET *)NX_PACKET_ALLOCATED; +#endif + + socket_0.nx_udp_socket_ip_ptr = NX_NULL; + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89, 0); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_ip_ptr = &ip_0; + + socket_0.nx_udp_socket_ip_ptr -> nx_ip_id = 0; + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89, 0); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_ip_ptr -> nx_ip_id = NX_IP_ID; +#endif /* __PRODUCT_NETXDUO__ */ + + status = nx_udp_socket_unbind(NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind with socket id mismatch. */ + socket_0.nx_udp_socket_id = 0; + status = nx_udp_socket_unbind(&socket_0); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + socket_0.nx_udp_socket_id = NX_UDP_ID; + + status = nx_udp_source_extract(NX_NULL, &my_address_2, &port); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_source_extract(my_packet, NX_NULL, &port); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_source_extract(my_packet, &my_address_2, NX_NULL); + if(status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef __PRODUCT_NETXDUO__ + temp = my_packet -> nx_packet_ip_header; + my_packet -> nx_packet_ip_header = NX_NULL; + status = nx_udp_source_extract(my_packet, &my_address_2, &port); + if(status != NX_INVALID_PACKET) + { + printf("ERROR!\n"); + test_control_return(1); + } + my_packet -> nx_packet_ip_header = temp; + +#ifdef FEATURE_NX_IPV6 + temp = my_packet -> nx_packet_data_start; + my_packet -> nx_packet_ip_version = NX_IP_VERSION_V6; + + /* Adjust the data start. */ + my_packet -> nx_packet_data_start = my_packet -> nx_packet_prepend_ptr - (sizeof(NX_UDP_HEADER) + sizeof(NX_IPV6_HEADER) - 1); + status = nx_udp_source_extract(my_packet, &my_address_2, &port); + if(status != NX_INVALID_PACKET) + { + printf("ERROR!\n"); + test_control_return(1); + } + my_packet -> nx_packet_ip_version = NX_IP_VERSION_V4; + my_packet -> nx_packet_data_start = temp; +#endif + +#endif /* __PRODUCT_NETXDUO__ */ + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_nxe_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: UDP NXE API Test..........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_udp_packet_receive_test.c b/test/regression/netxduo_test/netx_udp_packet_receive_test.c new file mode 100644 index 00000000..eade5c54 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_packet_receive_test.c @@ -0,0 +1,670 @@ +/* Here are the test points. + * socket's port is not equal to the source port + * multi threads suspend for the packet + * udp queue is full + * */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_0; +static NXD_ADDRESS address_1; +#endif /* FEATURE_NX_IPV6 */ + +UINT packet_count; + +/* The 2 ports will hashed to the same index. */ +#define PORT_1 0x00000100 +#define PORT_2 0x00008100 + +#define QUEUE_SIZE 5 + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_packet_receive_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + packet_count = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 256*20); + pointer = pointer + 256*20; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Set source and destination address with global address. */ + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0x20010DB8; + address_0.nxd_ip_address.v6[1] = 0x00010001; + address_0.nxd_ip_address.v6[2] = 0x021122FF; + address_0.nxd_ip_address.v6[3] = 0xFE334456; + + address_1.nxd_ip_version = NX_IP_VERSION_V6; + address_1.nxd_ip_address.v6[0] = 0x20010DB8; + address_1.nxd_ip_address.v6[1] = 0x00010001; + address_1.nxd_ip_address.v6[2] = 0x021122FF; + address_1.nxd_ip_address.v6[3] = 0xFE334499; + + status += nxd_ipv6_address_set(&ip_0, 0, &address_0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &address_1, 64, NX_NULL); + +#endif /* FEATURE_NX_IPV6 */ + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; +UINT port; +INT i; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Packet Receive Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#else + tx_thread_sleep(NX_IP_PERIODIC_RATE); +#endif + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Pickup the first free port for 0x88. */ + status = nx_udp_free_port_find(&ip_0, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test checksum enable/disable before bind. */ + + status = nx_udp_socket_checksum_disable(&socket_0); + if(status != NX_NOT_BOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_checksum_enable(&socket_0); + if(status != NX_NOT_BOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get socket port before bind. */ + status = nx_udp_socket_port_get(&socket_0, &port); + if(status != NX_NOT_BOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Receive packet before bind. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, NX_IP_PERIODIC_RATE/10); + if(status != NX_NOT_BOUND) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(31); + } + + /* Setup the ARP entry for the UDP send. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0, 0); + + +#ifdef FEATURE_NX_IPV6 + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_udp_socket_source_send(&socket_0, my_packet, &address_1, PORT_1, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Send packet to an invalid port (PORT_2) which is mapped to the same index with PORT_1. */ + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_udp_socket_source_send(&socket_0, my_packet, &address_1, PORT_2, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_suspend(&thread_0); +#endif + + + tx_thread_resume(&thread_1); + i = -2; + while(i < QUEUE_SIZE) + { + i++; + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), PORT_1, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + tx_thread_suspend(&thread_0); + + + /* Send a packet whose udp_header_word_1 will be modified. */ + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), PORT_1, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), PORT_1, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_resume(&thread_1); + /* Suspend to trigger _nx_udp_receive_cleanup. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 2 * NX_IP_PERIODIC_RATE); + tx_thread_suspend(&thread_0); + + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +#ifdef FEATURE_NX_IPV6 +ULONG src_address; +UINT src_port; +#endif +UINT i; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, QUEUE_SIZE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, PORT_1, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 7 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + status = nx_udp_packet_info_extract(my_packet, &src_address, NX_NULL, &src_port, NX_NULL); + if(status != NX_INVALID_PACKET) + { + printf("ERROR!\n"); + test_control_return(1); + + } + + if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + tx_thread_suspend(&thread_1); + i = 0; + while(i < QUEUE_SIZE) + { + i++; + + status = nx_udp_socket_receive(&socket_1, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + } + + /* Queue is empty, no more packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_NO_PACKET) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_resume(&thread_0); + + /* Change udp receive function to my routine. */ + ip_1.nx_ip_udp_packet_receive = my_udp_packet_receive; + + tx_thread_suspend(&thread_1); + + /* Suspend to trigger _nx_udp_receive_cleanup. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_resume(&thread_0); + + +} + +static void thread_2_entry(ULONG thread_input) +{ + +#ifdef FEATURE_NX_IPV6 +UINT status; +NX_PACKET *my_packet; + + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 7 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_NO_PACKET) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_resume(&thread_0); + +#endif + +} + +static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; + + if(packet_count == 0) + { + udp_header_ptr = (NX_UDP_HEADER *)packet_ptr -> nx_packet_prepend_ptr; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + /* Change the udp packet length to maximum.*/ + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | 0xFFFF0000; + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + _nx_udp_packet_receive(ip_ptr, packet_ptr); + packet_count++; + } + else + { + socket_1.nx_udp_socket_id = 1234; + _nx_udp_packet_receive(ip_ptr, packet_ptr); + socket_1.nx_udp_socket_id = NX_UDP_ID; + ip_1.nx_ip_udp_packet_receive = _nx_udp_packet_receive; + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_packet_receive_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: UDP Packet Receive Test...................................N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/netxduo_test/netx_udp_packet_type_test.c b/test/regression/netxduo_test/netx_udp_packet_type_test.c new file mode 100644 index 00000000..196927d6 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_packet_type_test.c @@ -0,0 +1,663 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_udp.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_0; +static NXD_ADDRESS address_1; +#endif /* FEATURE_NX_IPV6 */ + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_packet_type_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + +#ifndef NX_DISABLE_IPV4 + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; +#endif + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check enable status. */ + if (status) + error_counter++; + + /* Set source and destination address with global address. */ + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0x20010DB8; + address_0.nxd_ip_address.v6[1] = 0x00010001; + address_0.nxd_ip_address.v6[2] = 0x021122FF; + address_0.nxd_ip_address.v6[3] = 0xFE334456; + + address_1.nxd_ip_version = NX_IP_VERSION_V6; + address_1.nxd_ip_address.v6[0] = 0x20010DB8; + address_1.nxd_ip_address.v6[1] = 0x00010001; + address_1.nxd_ip_address.v6[2] = 0x021122FF; + address_1.nxd_ip_address.v6[3] = 0xFE334499; + + status = nxd_ipv6_address_set(&ip_0, 0, &address_0, 64, NX_NULL); + status = nxd_ipv6_address_set(&ip_1, 0, &address_1, 64, NX_NULL); +#endif /* FEATURE_NX_IPV6 */ + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Packet Type Test......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_IPV4 + /**************************/ + /* Test IPv4 packet */ + /**************************/ + + /* Allocate a packet that can fill the UDP header, IPv4 header and physical header. */ + status = nx_packet_allocate(&pool_0, &my_packet, 8 + 20 + 16, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet that can fill the UDP header and IPv4 header, can not fill physical header. */ + status = nx_packet_allocate(&pool_0, &my_packet, 8 + 20, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait until thread 1 finished. */ + tx_thread_suspend(&thread_0); +#ifdef __PRODUCT_NETXDUO__ +#ifndef NX_DISABLE_ERROR_CHECKING + /* Allocate a packet that can fill the UDP header, can not fill IPv4 header and physical header. */ + status = nx_packet_allocate(&pool_0, &my_packet, 8, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + nx_packet_release(my_packet); + + /* Allocate a packet that can not fill the UDP header, IPv4 header and physical header. */ + status = nx_packet_allocate(&pool_0, &my_packet, 0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait until thread 1 finished. */ + tx_thread_suspend(&thread_0); +#endif /* NX_DISABLE_ERROR_CHECKING */ +#endif /* __PRODUCT_NETXDUO__ */ +#endif /* NX_DISABLE_IPV4 */ + +#ifdef FEATURE_NX_IPV6 + + /**************************/ + /* Test IPv6 packet */ + /**************************/ + + /* Allocate a packet that can fill the UDP header, IPv6 header and physical header. */ + status = nx_packet_allocate(&pool_0, &my_packet, 8 + 40 + 16, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + + /* Allocate a packet that can fill the UDP header and IPv6 header, can not fill physical header. */ + status = nx_packet_allocate(&pool_0, &my_packet, 8 + 40, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Sleep 2 second to wait socket_1 receive the packet. */ + tx_thread_sleep(2 * NX_IP_PERIODIC_RATE); + + /* Allocate a packet that can fill the UDP header, can not fill IPv6 header and physical header. */ + status = nx_packet_allocate(&pool_0, &my_packet, 8, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet that can not fill the UDP header, IPv6 header and physical header. */ + status = nx_packet_allocate(&pool_0, &my_packet, 0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 28; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28; + + /* Send the UDP packet. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &address_1, 0x89); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait until thread 1 finished. */ + tx_thread_suspend(&thread_0); +#endif /* NX_DISABLE_ERROR_CHECKING */ + +#endif /* FEATURE_NX_IPV6 */ + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let thread 0 run. */ + tx_thread_resume(&thread_0); + +#ifndef NX_DISABLE_IPV4 + /**************************/ + /* Test IPv4 packet */ + /**************************/ + + /* Try to receive the first UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Try to receive the second UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let thread 0 run. */ + tx_thread_resume(&thread_0); + +#ifdef __PRODUCT_NETXDUO__ +#ifndef NX_DISABLE_ERROR_CHECKING + /* Try to receive the third UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Try to receive the forth UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let thread 0 run. */ + tx_thread_resume(&thread_0); +#endif /* NX_DISABLE_ERROR_CHECKING */ +#endif /* __PRODUCT_NETXDUO__ */ +#endif /* NX_DISABLE_IPV4 */ + +#ifdef FEATURE_NX_IPV6 + /**************************/ + /* Test IPv6 packet */ + /**************************/ + + /* Try to receive the first UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifndef NX_DISABLE_ERROR_CHECKING + /* Try to receive the second UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Try to receive the third UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Try to receive the forth UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 1 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status == NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let thread 0 run. */ + tx_thread_resume(&thread_0); +#endif +#endif + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} diff --git a/test/regression/netxduo_test/netx_udp_port_table_udpate_test.c b/test/regression/netxduo_test/netx_udp_port_table_udpate_test.c new file mode 100644 index 00000000..212f55d1 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_port_table_udpate_test.c @@ -0,0 +1,347 @@ +/* This NetX test concentrates on the UDP port table is updated + * when the receiving socket is not the header of port table. */ + + +#include "nx_api.h" +#include "nx_ip.h" +#include "nx_ram_network_driver_test_1500.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; +static NX_UDP_SOCKET socket_2; + +static NX_PACKET *packet_copy; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT advanced_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_port_table_update_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the client thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the server thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable UDP traffic. */ + status += nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Enable ICMP. */ + status += nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check for errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Port Table Update Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append data. */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set driver callback function. */ + advanced_packet_process_callback = advanced_packet_process; + + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x8089); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT index = ((0x89 + (0x89 >> 8)) & NX_UDP_PORT_TABLE_MASK); + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + status += nx_udp_socket_create(&ip_1, &socket_2, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. The socket_1 and socket_2 is in the same port table. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + status += nx_udp_socket_bind(&socket_2, 0x8089, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Make sure the header of port table is socket_1. */ + if (ip_1.nx_ip_udp_port_table[index] != &socket_1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Suspend thread until socket_0 sends a UDP packet. */ + tx_thread_suspend(&thread_1); + + /* Inject the packet without IP thread. */ + _nx_ip_packet_receive(&ip_1, packet_copy); + + /* Verify the header of port table is updated to socket_2. */ + if (ip_1.nx_ip_udp_port_table[index] != &socket_2) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_2, &my_packet, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + status += nx_udp_socket_unbind(&socket_2); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + status += nx_udp_socket_delete(&socket_2); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +static UINT advanced_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ + + /* Is this the UDP packet? */ + if (packet_ptr -> nx_packet_length == 56) + { + + /* Yes it is. Copy and drop it. */ + nx_packet_copy(packet_ptr, &packet_copy, &pool_0, NX_WAIT_FOREVER); + packet_copy -> nx_packet_ip_interface = &(ip_1.nx_ip_interface[0]); + *operation_ptr = NX_RAMDRIVER_OP_DROP; + advanced_packet_process_callback = NX_NULL; + + /* Resume thread 1. */ + tx_thread_resume(&thread_1); + } + + return NX_TRUE; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_port_table_update_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: UDP Port Table Update Test................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_udp_port_unreachable_test.c b/test/regression/netxduo_test/netx_udp_port_unreachable_test.c new file mode 100644 index 00000000..edf5c7ea --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_port_unreachable_test.c @@ -0,0 +1,296 @@ +/* This NetX test concentrates on the UDP port unreachable. */ + + +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_ICMPV4_ERROR_MESSAGE) && !defined(NX_DISABLE_ICMP_INFO) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_port_unreachable_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the client thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create an IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable UDP traffic. */ + status += nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Enable ICMP. */ + status += nx_icmp_enable(&ip_0); + status += nx_icmp_enable(&ip_1); + + /* Check for errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Port Unreachable Test................................."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append data. */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Verify the ICMPv4 error message is received. */ + if (ip_0.nx_ip_icmp_unhandled_messages != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Now create socket 1 and bind to port 0x8089. The hash value of 0x8089 is the same as 0x89. */ + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x8089, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Append data. */ + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Verify the ICMPv4 error message is received. */ + if (ip_0.nx_ip_icmp_unhandled_messages != 2) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_port_unreachable_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: UDP Port Unreachable Test.................................N/A\n"); + test_control_return(3); +} +#endif diff --git a/test/regression/netxduo_test/netx_udp_socket_bind_test.c b/test/regression/netxduo_test/netx_udp_socket_bind_test.c new file mode 100644 index 00000000..60d0afd4 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_socket_bind_test.c @@ -0,0 +1,170 @@ +/* This NetX test concentrates on the UDP free port find operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET my_socket[NX_MAX_PORT]; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void test_control_return(UINT status); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_socket_bind_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Socket Bind Test......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_udp_socket_bind(&socket_0, 1234, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_SUCCESS) + error_counter++; + + /* Bind again. */ + status = nx_udp_socket_bind(&socket_0, 1234, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_ALREADY_BOUND) + error_counter++; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + if (status != NX_SUCCESS) + error_counter++; + + /* Use up the ports. */ + for(i = 0; i < NX_MAX_PORT; i++) + { + status = nx_udp_socket_create(&ip_0, &my_socket[i], "Socket Array", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&my_socket[i], i+1, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + /* Bind to any port. */ + status = nx_udp_socket_bind(&socket_0, NX_ANY_PORT, 2 * NX_IP_PERIODIC_RATE); + if(status != NX_NO_FREE_PORTS) + error_counter++; + + /* Bind to 1234. */ + status = nx_udp_socket_bind(&socket_0, 1234, NX_NO_WAIT); + if(status != NX_PORT_UNAVAILABLE) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + if (status) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + diff --git a/test/regression/netxduo_test/netx_udp_socket_delete_test.c b/test/regression/netxduo_test/netx_udp_socket_delete_test.c new file mode 100644 index 00000000..8597d57e --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_socket_delete_test.c @@ -0,0 +1,139 @@ +/* This NetX test concentrates on the UDP Socket Delete operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static NX_UDP_SOCKET socket_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +extern void test_control_return(UINT status); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_socket_delete_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Socket Delete Test...................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + error_counter++; + + status = nx_udp_socket_bind(&socket_0, 1234, NX_NO_WAIT); + if(status != NX_SUCCESS) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + if (status != NX_STILL_BOUND) + error_counter++; + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + diff --git a/test/regression/netxduo_test/netx_udp_socket_unbind_receive_test.c b/test/regression/netxduo_test/netx_udp_socket_unbind_receive_test.c new file mode 100644 index 00000000..00fcb95e --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_socket_unbind_receive_test.c @@ -0,0 +1,143 @@ +/* This NetX test concentrates on the UDP socket unbind operation when other thread call receive. */ + + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static NX_UDP_SOCKET socket_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_socket_unbind_receive_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: UDP Socket Unbind Receive Test............................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x80, NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Let thread_1 to call socket receive. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Unbind the socket 0, thread 1 is receiving packet. */ + status = nx_udp_socket_unbind(&socket_0); + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + if (status) + error_counter++; + + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; + + /* Receive a UDP packet. */ + nx_udp_socket_receive(&socket_0, &my_packet, 2 * NX_IP_PERIODIC_RATE); +} diff --git a/test/regression/netxduo_test/netx_udp_socket_unbind_test.c b/test/regression/netxduo_test/netx_udp_socket_unbind_test.c new file mode 100644 index 00000000..a85e2667 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_socket_unbind_test.c @@ -0,0 +1,232 @@ +/* This NetX test concentrates on the UDP socket unbind operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; +static NX_UDP_SOCKET socket_2; +static NX_UDP_SOCKET socket_3; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +/* The 2 ports will hashed to the same index. */ +#define CLIENT_PORT_1 0x00000100 +#define CLIENT_PORT_2 0x00008100 + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void thread_2_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_socket_unbind_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + /* Print out some test information banners. */ + printf("NetX Test: UDP Socket Unbind Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_3, "Socket 3", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, CLIENT_PORT_1, 2 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port which is mapped to the same index with CLIENT_PORT_1. */ + status = nx_udp_socket_bind(&socket_3, CLIENT_PORT_2, 2 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + /* Let socket 1 bind to CLIENT_PORT_1 that socket 0 has bound to . */ + tx_thread_suspend(&thread_0); + + /* Unbind the socket 1, socket_1 is in bound process now. */ + status = nx_udp_socket_unbind(&socket_1); + if (status) + error_counter++; + + /* Let socket 1 and socket 2 bind to CLIENT_PORT_1 that socket 0 has bound to again. */ + tx_thread_resume(&thread_2); + tx_thread_suspend(&thread_0); + + /* Unbind the UDP socket. thread_1 and thread_2 is suspended for CLIENT_PORT_1 now, and */ + /* socket_3 is bound to the port which has the same hash index with CLIENT_PORT_1. */ + status = nx_udp_socket_unbind(&socket_0); + if (status) + error_counter++; + + status = nx_udp_socket_unbind(&socket_3); + status = nx_udp_socket_delete(&socket_3); + + /* Let thread 1 and thread 2 finish the job. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + status = nx_udp_socket_bind(&socket_0, CLIENT_PORT_1, 2 * NX_IP_PERIODIC_RATE); + if (status) + error_counter++; + + tx_thread_resume(&thread_2); + tx_thread_sleep(NX_IP_PERIODIC_RATE/2); + + status = nx_udp_socket_unbind(&socket_0); + if (status) + error_counter++; + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + if (status) + error_counter++; + + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status) + error_counter++; + + /* Bind the UDP socket to CLIENT_PORT_1 that socket_0 has bound to. */ + status = nx_udp_socket_bind(&socket_1, CLIENT_PORT_1, 5 * NX_IP_PERIODIC_RATE); + if (status != NX_PORT_UNAVAILABLE) + error_counter++; + + tx_thread_resume(&thread_0); + /* Bind the UDP socket to CLIENT_PORT_1 that socket_0 has bound to. */ + status = nx_udp_socket_bind(&socket_1, CLIENT_PORT_1, 5 * NX_IP_PERIODIC_RATE); + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); +} + +static void thread_2_entry(ULONG thread_input) +{ +UINT status; + + /* Suspend this thread, resume thread_0. */ + tx_thread_resume(&thread_0); + tx_thread_suspend(&thread_2); + + status = nx_udp_socket_create(&ip_0, &socket_2, "Socket 2", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if(status) + error_counter++; + + /* Bind the socket to CLIENT_PORT_1 that socket_0 has bound to. */ + status = nx_udp_socket_bind(&socket_2, CLIENT_PORT_1, 5 * NX_IP_PERIODIC_RATE); + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_2); + + tx_thread_suspend(&thread_2); + status = nx_udp_socket_bind(&socket_2, CLIENT_PORT_1, 5 * NX_IP_PERIODIC_RATE); +} diff --git a/test/regression/netxduo_test/netx_udp_source_send_test.c b/test/regression/netxduo_test/netx_udp_source_send_test.c new file mode 100644 index 00000000..082315f9 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_source_send_test.c @@ -0,0 +1,545 @@ +/* This NetX test concentrates on the basic UDP operation. */ + + +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); +#if defined(__PRODUCT_NETXDUO__) && (NX_MAX_PHYSICAL_INTERFACES > 1) && !defined(NX_DISABLE_IPV4) +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; + + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_0; +static NXD_ADDRESS address_1; +#endif /* FEATURE_NX_IPV6 */ + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static UCHAR recv_buf[28]; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_source_send_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* . */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFF000UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Set the second interface. */ + status += nx_ip_interface_attach(&ip_0, "Second Interface", IP_ADDRESS(1, 2, 4, 4), 0xFFFF0000UL, _nx_ram_network_driver_256); + status += nx_ip_interface_attach(&ip_1, "Second Interface", IP_ADDRESS(1, 2, 4, 5), 0xFFFF0000UL, _nx_ram_network_driver_256); + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status += nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check TCP enable status. */ + if (status) + error_counter++; + + /* Set source and destination address with global address. */ + address_0.nxd_ip_version = NX_IP_VERSION_V6; + address_0.nxd_ip_address.v6[0] = 0x20010DB8; + address_0.nxd_ip_address.v6[1] = 0x00010001; + address_0.nxd_ip_address.v6[2] = 0x021122FF; + address_0.nxd_ip_address.v6[3] = 0xFE334456; + + address_1.nxd_ip_version = NX_IP_VERSION_V6; + address_1.nxd_ip_address.v6[0] = 0x20010DB8; + address_1.nxd_ip_address.v6[1] = 0x00010001; + address_1.nxd_ip_address.v6[2] = 0x021122FF; + address_1.nxd_ip_address.v6[3] = 0xFE334499; + + status += nxd_ipv6_address_set(&ip_0, 0, &address_0, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &address_1, 64, NX_NULL); + +#endif /* FEATURE_NX_IPV6 */ + + /* Check for UDP enable errors. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT free_port; + + + /* Print out some test information banners. */ + printf("NetX Test: UDP Source Send Test......................................"); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Pickup the first free port for 0x88. */ + status = nx_udp_free_port_find(&ip_0, 0x88, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(31); + } + + /* Setup the ARP entry for the UDP send. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(1, 2, 3, 5), 0, 0); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set static route. */ + nx_ip_static_route_add(&ip_0, IP_ADDRESS(1, 2, 0, 0), 0xFFFF0000, IP_ADDRESS(1, 2, 3, 5)); + + status = nx_udp_socket_source_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89, 1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + +#ifdef FEATURE_NX_IPV6 + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_udp_socket_source_send(&socket_0, my_packet, &address_1, 0x89, 0); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +#endif + + tx_thread_resume(&thread_1); + + status = nx_packet_pool_delete(&pool_0); + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_0); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +ULONG bytes_copied; +ULONG src_address; +UINT src_port; +ULONG bytes_available; +UINT i; +UINT protocol; +UINT if_index; +NXD_ADDRESS nxd_src_address; + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Socket is not bound, should return an error message. */ + status = nx_udp_socket_bytes_available(&socket_1, &bytes_available); + if(status != NX_NOT_SUCCESSFUL) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + tx_thread_suspend(&thread_1); + + status = nx_udp_socket_bytes_available(&socket_1, &bytes_available); +#ifdef FEATURE_NX_IPV6 + if(status || bytes_available != 56) + error_counter++; +#else + if(status || bytes_available != 28) + error_counter++; +#endif + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Get source address and port. */ + status = nx_udp_packet_info_extract(my_packet, &src_address, NX_NULL, &src_port, NX_NULL); + if(status || (src_address != IP_ADDRESS(1, 2, 4, 4)) || src_port != 0x88) + { + printf("ERROR!\n"); + test_control_return(1); + + } + + status = nx_packet_data_extract_offset(my_packet, 0, recv_buf, 28, &bytes_copied); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + else if(memcmp(recv_buf, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28) || (bytes_copied != 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test function _nxd_udp_packet_info_extract . */ + my_packet -> nx_packet_address.nx_packet_interface_ptr = NX_NULL; + status = nxd_udp_packet_info_extract(my_packet, NX_NULL, &protocol, &src_port, &if_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + my_packet -> nx_packet_ip_version = 1; + status = nxd_udp_packet_info_extract(my_packet, NX_NULL, &protocol, &src_port, &if_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nxd_udp_packet_info_extract(my_packet, &nxd_src_address, &protocol, &src_port, &if_index); + if(status != NX_INVALID_PACKET) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 2 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_packet_info_extract(my_packet, &src_address, NX_NULL, &src_port, NX_NULL); + if(status != NX_INVALID_PACKET) + { + printf("ERROR!\n"); + test_control_return(1); + + } + + if(memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test function nxd_udp_packet_info_extract. */ + my_packet -> nx_packet_address.nx_packet_ipv6_address_ptr = NX_NULL; + status = nxd_udp_packet_info_extract(my_packet, &nxd_src_address, &protocol, &src_port, &if_index); + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#endif + + /* Use up the packet pool. */ + i = 0; + while(i < pool_0.nx_packet_pool_total) + { + i++; + nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 2 * NX_IP_PERIODIC_RATE); + } + + /* No packet, suspend the thread. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, 5 * NX_IP_PERIODIC_RATE); + if(status != NX_POOL_DELETED) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete the UDP socket. */ + status = nx_udp_socket_delete(&socket_1); + + /* Check status. */ + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_source_send_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: UDP Source Send Test......................................N/A\n"); + test_control_return(3); +} +#endif /* __PRODUCT_NETXDUO__ */ diff --git a/test/regression/netxduo_test/netx_udp_tunnel_ipv4_ipv4_basic_test.c b/test/regression/netxduo_test/netx_udp_tunnel_ipv4_ipv4_basic_test.c new file mode 100644 index 00000000..fc6bd5d1 --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_tunnel_ipv4_ipv4_basic_test.c @@ -0,0 +1,405 @@ +/* This NetX IPsec basic test using AES. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined( NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_tunnel.h" +#define DEMO_STACK_SIZE 4096 + +#define MSG "abcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +static ULONG notify_calls = 0; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static CHAR rcv_buffer[200]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_tunnel_ipv4_ipv4_basic_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_1500); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_1500); + + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *my_packet; + CHAR *msg = MSG; + UINT free_port; + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL UDP IPV4_4 Basic Processing Test......."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020304; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020305; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V4,address_selector_0); + + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(31); + } + + /* Disable checksum logic for this socket. */ + status = nx_udp_socket_checksum_disable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + /* Check for error. */ + if (status) + error_counter++; + + /* Setup the ARP entry for the UDP send. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0, 0); + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &msg[0], 26); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 26; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 26; + + /* Suspend thread1 */ + tx_thread_suspend(&thread_1); + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_resume(&thread_1); + + tx_thread_relinquish(); + +} + + +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *packet_ptr; + ULONG recv_length = 0; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020305; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020304; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V6,address_selector_1); + + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&socket_1, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Supsend thread 0. */ + tx_thread_resume(&thread_0); + + tx_thread_relinquish(); + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &packet_ptr, TX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length = packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 26) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &socket_1) + notify_calls++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_tunnel_ipv4_ipv4_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL UDP IPV4_4 Basic Processing Test...................N/A\n"); + + test_control_return(3); + +} +#endif /* NX_TUNNEL_ENABLE */ \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_udp_tunnel_ipv4_ipv6_basic_test.c b/test/regression/netxduo_test/netx_udp_tunnel_ipv4_ipv6_basic_test.c new file mode 100644 index 00000000..63a8ef4f --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_tunnel_ipv4_ipv6_basic_test.c @@ -0,0 +1,429 @@ +/* This NetX IPsec basic test using AES. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_ipv6.h" +#include "nx_tunnel.h" +#define DEMO_STACK_SIZE 4096 + +#define MSG "abcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +static ULONG notify_calls = 0; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static CHAR rcv_buffer[200]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_tunnel_ipv4_ipv6_basic_test_application_define(void *first_unused_memory) +#endif +{ + + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_1500); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_1500); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *my_packet; + CHAR *msg = MSG; + UINT free_port; + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL UDP IPV4_6 Basic Processing Test......."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address = ipv6_address_3; + address_selector_0.nx_selector_dst_tunnel_address = ipv6_address_4; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V6,address_selector_0); + + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(31); + } + + /* Disable checksum logic for this socket. */ + status = nx_udp_socket_checksum_disable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + /* Check for error. */ + if (status) + error_counter++; + + /* Setup the ARP entry for the UDP send. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0, 0); + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &msg[0], 26); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 26; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 26; + + /* Suspend thread1 */ + tx_thread_suspend(&thread_1); + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_resume(&thread_1); + + tx_thread_relinquish(); + +} + + +static void thread_1_entry(ULONG thread_input) +{ + + UINT status; + NX_PACKET *packet_ptr; + ULONG recv_length = 0; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v4 = 0x02000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v4 = 0x01000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v4 = 0x02000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address = ipv6_address_4; + address_selector_1.nx_selector_dst_tunnel_address = ipv6_address_3; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V6,address_selector_1); + + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&socket_1, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Supsend thread 0. */ + tx_thread_resume(&thread_0); + + tx_thread_relinquish(); + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &packet_ptr, TX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length = packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 26) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &socket_1) + notify_calls++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_tunnel_ipv4_ipv6_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL UDP IPV4_6 Basic Processing Test...................N/A\n"); + + test_control_return(3); + +} +#endif /* NX_TUNNEL_ENABLE */ \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_udp_tunnel_ipv6_ipv4_basic_test.c b/test/regression/netxduo_test/netx_udp_tunnel_ipv6_ipv4_basic_test.c new file mode 100644 index 00000000..a006afcd --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_tunnel_ipv6_ipv4_basic_test.c @@ -0,0 +1,446 @@ +/* This NetX IPsec basic test using AES. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) && !defined(NX_DISABLE_IPV4) +#include "nx_ipv6.h" +#include "nx_tunnel.h" +#define DEMO_STACK_SIZE 4096 + +#define MSG "abcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +static ULONG notify_calls = 0; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static CHAR rcv_buffer[200]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_tunnel_ipv6_ipv4_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_1500); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_1500); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if (status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR *msg = MSG; +UINT free_port; + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL UDP IPV6_4 Basic Processing Test......."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020304; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_0.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020305; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V4,address_selector_0); + + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(31); + } + + /* Disable checksum logic for this socket. */ + status = nx_udp_socket_checksum_disable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + /* Check for error. */ + if (status) + error_counter++; + + /* Setup the ARP entry for the UDP send. */ + nx_arp_dynamic_entry_set(&ip_0, IP_ADDRESS(2, 2, 3, 5), 0, 0); + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &msg[0], 26); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 26; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 26; + + /* Suspend thread1 */ + tx_thread_suspend(&thread_1); + + /* Send the UDP packet. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &ipv6_address_2, 0x89); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_resume(&thread_1); + + tx_thread_relinquish(); + +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG recv_length = 0; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_src_tunnel_address.nxd_ip_address.v4 = 0x02020304; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_version = NX_IP_VERSION_V4; + address_selector_1.nx_selector_dst_tunnel_address.nxd_ip_address.v4 = 0x02020305; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V4,address_selector_1); + + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&socket_1, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Supsend thread 0. */ + tx_thread_resume(&thread_0); + + tx_thread_relinquish(); + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &packet_ptr, TX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length = packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 26) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &socket_1) + notify_calls++; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_tunnel_ipv6_ipv4_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL UDP IPV6_4 Basic Processing Test...................N/A\n"); + + test_control_return(3); + +} +#endif /* NX_TUNNEL_ENABLE */ \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_udp_tunnel_ipv6_ipv6_basic_test.c b/test/regression/netxduo_test/netx_udp_tunnel_ipv6_ipv6_basic_test.c new file mode 100644 index 00000000..fba76a4d --- /dev/null +++ b/test/regression/netxduo_test/netx_udp_tunnel_ipv6_ipv6_basic_test.c @@ -0,0 +1,444 @@ +/* This NetX IPsec basic test using AES. */ + +#include "tx_api.h" +#include "nx_api.h" +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && defined(NX_TUNNEL_ENABLE) +#include "nx_ipv6.h" +#include "nx_tunnel.h" +#define DEMO_STACK_SIZE 4096 + +#define MSG "abcdefghijklmnopqrstuvwxyz" + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + +static ULONG notify_calls = 0; + +NXD_ADDRESS ipv6_address_1; +NXD_ADDRESS ipv6_address_2; +NXD_ADDRESS ipv6_address_3; +NXD_ADDRESS ipv6_address_4; + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG error_counter = 0; +static CHAR rcv_buffer[200]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +static NX_ADDRESS_SELECTOR address_selector_0; +static NX_ADDRESS_SELECTOR address_selector_1; +static NX_TUNNEL tunnel_0; +static NX_TUNNEL tunnel_1; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_tunnel_ipv6_ipv6_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + thread_0_counter = 0; + thread_1_counter = 0; + error_counter = 0; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192); + pointer = pointer + 8192; + + if (status) + error_counter++; + + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + status += nx_ip_interface_attach(&ip_0,"Second Interface",IP_ADDRESS(2,2,3,4),0xFFFFFF00UL, _nx_ram_network_driver_1500); + status += nx_ip_interface_attach(&ip_1,"Second Interface",IP_ADDRESS(2,2,3,5),0xFFFFFF00UL, _nx_ram_network_driver_1500); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[3] = 0x10000001; + + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x20010000; + ipv6_address_2.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_2.nxd_ip_address.v6[3] = 0x10000002; + + ipv6_address_3.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_3.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_3.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_3.nxd_ip_address.v6[3] = 0x20000003; + + ipv6_address_4.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_4.nxd_ip_address.v6[0] = 0x30010000; + ipv6_address_4.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[2] = 0x00000000; + ipv6_address_4.nxd_ip_address.v6[3] = 0x20000004; + + /* Set interfaces' address */ + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_2, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_0, 1, &ipv6_address_3, 64, NX_NULL); + status += nxd_ipv6_address_set(&ip_1, 1, &ipv6_address_4, 64, NX_NULL); + + if (status) + error_counter++; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + status = nxd_ipv6_enable(&ip_1); + + /* Check IPv6 enable status. */ + if (status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + status = nxd_icmp_enable(&ip_1); + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check for UDP enable errors. */ + if (status) + error_counter++; + + status = nx_tunnel_enable(&ip_0); + status += nx_tunnel_enable(&ip_1); + + /* Check Tunnel enable status. */ + if (status) + error_counter++; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +CHAR *msg = MSG; +UINT free_port; + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL UDP IPV6_6 Basic Processing Test......."); + + /* Check for earlier error. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create TUNNEL. */ + address_selector_0.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_0.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_0.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_0.nx_selector_src_tunnel_address = ipv6_address_3; + address_selector_0.nx_selector_dst_tunnel_address = ipv6_address_4; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_0, &tunnel_0,NX_IP_VERSION_V6,address_selector_0); + + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Get the port that is actually bound to this socket. */ + status = nx_udp_socket_port_get(&socket_0, &free_port); + + /* Check status. */ + if ((status) || (free_port != 0x88)) + { + + printf("ERROR!\n"); + test_control_return(31); + } + + /* Disable checksum logic for this socket. */ + status = nx_udp_socket_checksum_disable(&socket_0); + + /* Check status. */ + if (status) + { + + printf("ERROR!\n"); + test_control_return(1); + } + /* Check for error. */ + if (status) + error_counter++; + + /* Let other threads run again. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + memcpy(my_packet -> nx_packet_prepend_ptr, &msg[0], 26); + + /* Adjust the write pointer. */ + my_packet -> nx_packet_length = 26; + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 26; + + /* Suspend thread1 */ + tx_thread_suspend(&thread_1); + + /* Send the UDP packet. */ + status = nxd_udp_socket_send(&socket_0, my_packet, &ipv6_address_2, 0x89); + + /* Determine if the status is valid. */ + if (status) + { + error_counter++; + nx_packet_release(my_packet); + } + + tx_thread_resume(&thread_1); + + tx_thread_relinquish(); + +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +ULONG recv_length = 0; + + /* Create TUNNEL. */ + address_selector_1.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_src_address_end.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x20000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + + address_selector_1.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[0] = 0x30000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[1] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0x00000000; + address_selector_1.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0x00000000; + + /* add tunnel address. */ + address_selector_1.nx_selector_src_tunnel_address = ipv6_address_4; + address_selector_1.nx_selector_dst_tunnel_address = ipv6_address_3; + + /* Set up TUNNEL */ + status = nx_tunnel_create(&ip_1, &tunnel_1,NX_IP_VERSION_V6,address_selector_1); + + if (status) + error_counter++; + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Register the receive notify function. */ + status = nx_udp_socket_receive_notify(&socket_1, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Supsend thread 0. */ + tx_thread_resume(&thread_0); + + tx_thread_relinquish(); + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &packet_ptr, TX_WAIT_FOREVER); + + /* Check for error. */ + if (status) + error_counter++; + else + { + if(packet_ptr -> nx_packet_length == 0) + error_counter++; + + memcpy(&rcv_buffer[recv_length], packet_ptr -> nx_packet_prepend_ptr, packet_ptr -> nx_packet_length); + recv_length = packet_ptr -> nx_packet_length; + + /* Release the packet. */ + nx_packet_release(packet_ptr); + } + + if(recv_length != 26) + error_counter++; + + if(memcmp(rcv_buffer, (void*)MSG, recv_length)) + error_counter++; + + /* Determine if the test was successful. */ + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + + +} + +static void receive_packet_function(NX_UDP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &socket_1) + notify_calls++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_udp_tunnel_ipv6_ipv6_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out some test information banners. */ + printf("NetX Test: TUNNEL UDP IPV6_6 Basic Processing Test...................N/A\n"); + + test_control_return(3); + +} +#endif /* NX_TUNNEL_ENABLE */ \ No newline at end of file diff --git a/test/regression/netxduo_test/netx_utility_test.c b/test/regression/netxduo_test/netx_utility_test.c new file mode 100644 index 00000000..d5a1bc5c --- /dev/null +++ b/test/regression/netxduo_test/netx_utility_test.c @@ -0,0 +1,688 @@ +/* This NetX test concentrates on the utility functions. */ + +#include "nx_md5.h" +#include "tx_api.h" +#include "nx_api.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_utility_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); +} + + +/* Define the test threads. */ + +static void ntest_0_entry(ULONG thread_input) +{ + +UINT status; +UINT string_length; +UINT number; +UCHAR input_buffer[256] = {0}; +UCHAR out_buffer[256] = {0}; +UINT bytes_copied; +UINT i; +UINT size; +NX_MD5 context; + + /* Print out test information banner. */ + printf("NetX Test: Utility Test.............................................."); + + /* Null string pointer. */ + status = _nx_utility_string_length_check(NX_NULL, &string_length, 10); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* The length of string is less than max length. */ + status = _nx_utility_string_length_check("test string", &string_length, sizeof("test string")); + + /* Check status. */ + if ((status != NX_SUCCESS) || (string_length != sizeof("test string") - 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* The length of string is equal to max length. */ + status = _nx_utility_string_length_check("test string", &string_length, sizeof("test string") - 1); + + /* Check status. */ + if ((status != NX_SUCCESS) || (string_length != sizeof("test string") - 1)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* The length of string is equal to max length. */ + status = _nx_utility_string_length_check("test string", &string_length, sizeof("test string") - 2); + + /* Check status. */ + if (status == NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Verify _nx_utility_string_to_uint(). */ + + /* Null string pointer. */ + status = _nx_utility_string_to_uint(NX_NULL, sizeof("4294967295") -1, &number); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Null string pointer. */ + status = _nx_utility_string_to_uint("4294967295", sizeof("4294967295") -1, NX_NULL); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Invalid string length. */ + status = _nx_utility_string_to_uint("4294967295", 0, &number); + + /* Check status. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Verify string "1234". */ + status = _nx_utility_string_to_uint("1234", sizeof("1234") -1, &number); + + /* Check status. */ + if ((status) || (number != 1234)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Verify max value number(Hex:FFFFFFFF, Decimal:4294967295). */ + status = _nx_utility_string_to_uint("4294967295", sizeof("4294967295") -1, &number); + + /* Check status. */ + if ((status) || (number != 4294967295)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test invalid string "4294967296". */ + status = _nx_utility_string_to_uint("4294967296", sizeof("4294967296") -1, &number); + + /* Check status. */ + if (status != NX_OVERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test invalid string "4294967300". */ + status = _nx_utility_string_to_uint("4294967300", sizeof("4294967300") -1, &number); + + /* Check status. */ + if (status != NX_OVERFLOW) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test invalid string. */ + status = _nx_utility_string_to_uint("123+", sizeof("123+") -1, &number); + + /* Check status. */ + if (status != NX_INVALID_PARAMETERS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test invalid string. */ + status = _nx_utility_string_to_uint("123A", sizeof("123A") -1, &number); + + /* Check status. */ + if (status != NX_INVALID_PARAMETERS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Base64 encode test. */ + + /* Null name pointer. */ + status = _nx_utility_base64_encode(NX_NULL, sizeof("name:password") -1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* 0 name size. */ + status = _nx_utility_base64_encode("name:password", 0, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* NULL buffer pointer. */ + status = _nx_utility_base64_encode("name:password", sizeof("name:password") -1, NX_NULL, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* 0 buffer size. */ + status = _nx_utility_base64_encode("name:password", sizeof("name:password") -1, out_buffer, 0, &bytes_copied); + + /* Check status. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* NULL bytes copied pointer. */ + status = _nx_utility_base64_encode("name:password", sizeof("name:password") -1, out_buffer, sizeof(out_buffer), NX_NULL); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Encode name with small buffer. */ + status = _nx_utility_base64_encode("name:password", sizeof("name:password") -1, out_buffer, 20, &bytes_copied); + + /* Check status. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Encode name successfully. */ + status = _nx_utility_base64_encode("name:password", sizeof("name:password") -1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || + (bytes_copied != 20) || + (memcmp(out_buffer, "bmFtZTpwYXNzd29yZA==", 20) != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Encode special character. */ + input_buffer[0] = 0x80; + input_buffer[1] = 0; + status = _nx_utility_base64_encode(input_buffer, 1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || + (bytes_copied != 4) || + (memcmp(out_buffer, "gA==", 4) != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Encode 1 character. */ + input_buffer[0] = 'a'; + input_buffer[1] = 0; + status = _nx_utility_base64_encode(input_buffer, 1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || + (bytes_copied != 4) || + (memcmp(out_buffer, "YQ==", 4) != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test array without null terminator. */ + input_buffer[0] = 'a'; + input_buffer[1] = 0xff; + status = _nx_utility_base64_encode(input_buffer, 1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || + (bytes_copied != 4) || + (memcmp(out_buffer, "YQ==", 4) != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Encode 2 characters. */ + input_buffer[0] = 'a'; + input_buffer[1] = 'b'; + input_buffer[2] = 0; + status = _nx_utility_base64_encode(input_buffer, 2, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || + (bytes_copied != 4) || + (memcmp(out_buffer, "YWI=", 4) != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Test array without null terminator. */ + input_buffer[0] = 'a'; + input_buffer[1] = 'b'; + input_buffer[2] = 0xff; + status = _nx_utility_base64_encode(input_buffer, 2, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || + (bytes_copied != 4) || + (memcmp(out_buffer, "YWI=", 4) != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Crash test. */ + for (i = 1; i <= 0xFF; i++) + { + input_buffer[0] = i; + input_buffer[1] = i; + input_buffer[2] = i; + input_buffer[3] = 0; + _nx_utility_base64_encode(input_buffer, 3, out_buffer, sizeof(out_buffer), &bytes_copied); + } + + /* Base64 decode test. */ + + /* Null name pointer. */ + status = _nx_utility_base64_decode(NX_NULL, sizeof("bmFtZTpwYXNzd29yZA==") -1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* 0 name size. */ + status = _nx_utility_base64_decode("bmFtZTpwYXNzd29yZA==", 0, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* NULL buffer pointer. */ + status = _nx_utility_base64_decode("bmFtZTpwYXNzd29yZA==", sizeof("bmFtZTpwYXNzd29yZA==") -1, NX_NULL, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* 0 buffer size. */ + status = _nx_utility_base64_decode("bmFtZTpwYXNzd29yZA==", sizeof("bmFtZTpwYXNzd29yZA==") -1, out_buffer, 0, &bytes_copied); + + /* Check status. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* NULL bytes copied pointer. */ + status = _nx_utility_base64_decode("bmFtZTpwYXNzd29yZA==", sizeof("bmFtZTpwYXNzd29yZA==") -1, out_buffer, sizeof(out_buffer), NX_NULL); + + /* Check status. */ + if (status != NX_PTR_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Encode name with small buffer. */ + status = _nx_utility_base64_decode("bmFtZTpwYXNzd29yZA==", sizeof("bmFtZTpwYXNzd29yZA==") -1, out_buffer, 13, &bytes_copied); + + /* Check status. */ + if (status != NX_SIZE_ERROR) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Encode name successfully. */ + status = _nx_utility_base64_decode("bmFtZTpwYXNzd29yZA==", sizeof("bmFtZTpwYXNzd29yZA==") -1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || + (bytes_copied != 13) || + (memcmp(out_buffer, "name:password", 13) != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Encode special character. */ + status = _nx_utility_base64_decode("gA==", sizeof("gA==") - 1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || + (bytes_copied != 1) || + (out_buffer[0] != 0x80)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Decode cut string. */ + status = _nx_utility_base64_decode("bmFt=TpwYXNzd29yZA==", sizeof("bmFt=TpwYXNzd29yZA==") -1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || + (bytes_copied != 3) || + (memcmp(out_buffer, "nam", 3) != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Decode cut string. */ + status = _nx_utility_base64_decode("bmFt\0TpwYXNzd29yZA==", sizeof("bmFt\0TpwYXNzd29yZA==") -1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if ((status != NX_SUCCESS) || + (bytes_copied != 3) || + (memcmp(out_buffer, "nam", 3) != 0)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Crash test. */ + for (i = 1; i <= 0xFF; i++) + { + input_buffer[0] = i; + input_buffer[1] = i; + input_buffer[2] = i; + input_buffer[3] = 0; + _nx_utility_base64_decode(input_buffer, 3, out_buffer, sizeof(out_buffer), &bytes_copied); + } + + /* Read overflow test. */ + input_buffer[0] = '='; + input_buffer[1] = '='; + input_buffer[2] = 0; + status = _nx_utility_base64_decode(&input_buffer[1], 1, out_buffer, 0xffffffff, &bytes_copied); + + /* Check status. */ + if (status || bytes_copied != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = _nx_utility_base64_decode("==", sizeof("==") - 1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if (status || bytes_copied != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = _nx_utility_base64_decode("T", sizeof("T") - 1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if (status || bytes_copied != 0) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = _nx_utility_base64_decode("TQ", sizeof("TQ") - 1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if (status || bytes_copied != 1 || out_buffer[0] != 'M') + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = _nx_utility_base64_decode("TQ=", sizeof("TQ=") - 1, out_buffer, sizeof(out_buffer), &bytes_copied); + + /* Check status. */ + if (status || bytes_copied != 1 || out_buffer[0] != 'M') + { + + printf("ERROR!\n"); + test_control_return(1); + } + + number = 0x1234; + size = _nx_utility_uint_to_string(number, 10, out_buffer, sizeof(out_buffer)); + if ((size != 4) || (memcmp(out_buffer, "4660", size) != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + size = _nx_utility_uint_to_string(number, 16, out_buffer, sizeof(out_buffer)); + if ((size != 4) || (memcmp(out_buffer, "1234", size) != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + size = _nx_utility_uint_to_string(number, 8, out_buffer, sizeof(out_buffer)); + if ((size != 5) || (memcmp(out_buffer, "11064", size) != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + number = 0xffffffff; + size = _nx_utility_uint_to_string(number, 10, out_buffer, sizeof(out_buffer)); + if ((size != 10) || (memcmp(out_buffer, "4294967295", size) != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + size = _nx_utility_uint_to_string(number, 16, out_buffer, sizeof(out_buffer)); + if ((size != 8) || (memcmp(out_buffer, "ffffffff", size) != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + size = _nx_utility_uint_to_string(number, 8, out_buffer, sizeof(out_buffer)); + if ((size != 11) || (memcmp(out_buffer, "37777777777", size) != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + number = 0; + size = _nx_utility_uint_to_string(number, 10, out_buffer, sizeof(out_buffer)); + if ((size != 1) || (memcmp(out_buffer, "0", size) != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + size = _nx_utility_uint_to_string(number, 16, out_buffer, sizeof(out_buffer)); + if ((size != 1) || (memcmp(out_buffer, "0", size) != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + size = _nx_utility_uint_to_string(number, 8, out_buffer, sizeof(out_buffer)); + if ((size != 1) || (memcmp(out_buffer, "0", size) != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + number = 0xffffffff; + size = _nx_utility_uint_to_string(number, 16, out_buffer, 8); + if (size != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + size = _nx_utility_uint_to_string(number, 10, NX_NULL, 8); + if (size != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + size = _nx_utility_uint_to_string(number, 10, out_buffer, 0); + if (size != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + size = _nx_utility_uint_to_string(number, 0, out_buffer, sizeof(out_buffer)); + if (size != 0) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = _nx_md5_initialize(NX_NULL); + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = _nx_md5_update(NX_NULL, input_buffer, 1); + if (status != NX_PTR_ERROR) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = _nx_md5_update(&context, input_buffer, 0); + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + _nx_md5_initialize(&context); + context.nx_md5_bit_count[0] = 0xffffffff; + + status = _nx_md5_update(&context, input_buffer, 1); + if (status || context.nx_md5_bit_count[1] != 1) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + diff --git a/test/regression/pop3_test/netx_pop3_abnormal_packet_test.c b/test/regression/pop3_test/netx_pop3_abnormal_packet_test.c new file mode 100644 index 00000000..aa9e990e --- /dev/null +++ b/test/regression/pop3_test/netx_pop3_abnormal_packet_test.c @@ -0,0 +1,157 @@ +/* + This tests POP3 client process abnormal packet. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_pop3_client.h" +#else +#include "nx_pop3_client.h" +#endif +extern void test_control_return(UINT); +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +static UINT error_counter = 0; + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +/* Set up Client thread entry point. */ +static void client_thread_entry(ULONG info); + + +/* Set up the POP3 Client and POP3 server socket. */ + +static TX_THREAD client_thread; +static NX_POP3_CLIENT pop3_client; +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; + +/* Use the maximum size payload to insure no packets are dropped. */ +#define PAYLOAD_SIZE 1514 + +static char abnormal_packet[] = {0x0A}; + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pop3_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + + /* Setup the working pointer. */ + free_memory_pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create a client thread. */ + tx_thread_create(&client_thread, "Client", client_thread_entry, 0, + free_memory_pointer, DEMO_STACK_SIZE, 1, 1, + TX_NO_TIME_SLICE, TX_AUTO_START); + + free_memory_pointer = free_memory_pointer + DEMO_STACK_SIZE; + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + + /* Create Client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "POP3 Client Packet Pool", + PAYLOAD_SIZE, free_memory_pointer, (PAYLOAD_SIZE * 10)); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + (PAYLOAD_SIZE * 10); + + /* Create IP instance for demo Client */ + status = nx_ip_create(&client_ip, "POP3 Client IP Instance", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, + &client_packet_pool, _nx_ram_network_driver_1024, free_memory_pointer, + 2048, 1); + + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 2048; + + /* Enable ARP and supply ARP cache memory. */ + nx_arp_enable(&client_ip, (void *) free_memory_pointer, 1024); + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 1024; + + /* Enable TCP and ICMP for Client IP. */ + nx_tcp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; +} + +/* Define the application thread entry function. */ + +void client_thread_entry(ULONG info) +{ + +UINT status; +UCHAR *buffer_ptr; +UINT buffer_length; +CHAR test_buffer[11] = {0}; +CHAR *argument; + + NX_PARAMETER_NOT_USED(info); + + /* Print out test information banner. */ + printf("NetX Test: POP3 Abnormal Packet Test................................."); + + buffer_ptr = abnormal_packet; + buffer_length = sizeof(abnormal_packet); + test_buffer[0] = 0x0D; + argument = test_buffer + 1; + _nx_pop3_parse_response(buffer_ptr, 1, buffer_length, argument, 10, NX_FALSE, NX_FALSE); + + if (test_buffer[0] != 0x0D) + { + error_counter++; + } + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + }; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pop3_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: POP3 Abnormal Packet Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/pop3_test/netx_pop3_mail_receive_test.c b/test/regression/pop3_test/netx_pop3_mail_receive_test.c new file mode 100644 index 00000000..6e23d0da --- /dev/null +++ b/test/regression/pop3_test/netx_pop3_mail_receive_test.c @@ -0,0 +1,612 @@ +/* + This is a small demo of POP3 Client on the high-performance NetX TCP/IP stack. + This demo relies on Thread, NetX and POP3 Client API to conduct + a POP3 mail session. + + The POP3 'server' is a TCP socket that sends responses and downloads a mail item + of three packets. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_pop3_client.h" +#else +#include "nx_pop3_client.h" +#endif +extern void test_control_return(UINT); +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define SERVER_PORT 110 + +static UINT error_counter = 0; +static UINT client_running = NX_TRUE; + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static UINT nx_pop3_response_packet_send(NX_TCP_SOCKET *server_socket_ptr, INT packet_number); +static UINT pop3_initialize_responses(); + +/* Set up Client thread entry point. */ +static void client_thread_entry(ULONG info); +/* Set up Server thread entry point. */ +static void server_thread_entry(ULONG info); + + +/* Set up the POP3 Client and POP3 server socket. */ + +static TX_THREAD client_thread; +static NX_POP3_CLIENT pop3_client; +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD server_thread; +static NX_TCP_SOCKET server_socket; +static NX_PACKET_POOL server_packet_pool; +static NX_IP server_ip; + +/* Use the maximum size payload to insure no packets are dropped. */ +#define PAYLOAD_SIZE 1514 + +/* Shared secret is the same as password. */ + +#define LOCALHOST "recipient@domain.com" +#define LOCALHOST_PASSWORD "testpwd" + +typedef struct POP3_RESPONSE_STRUCT +{ + char *pop3_response_pkt_data; + int pop3_response_pkt_size; +} POP3_RESPONSE; + +#define NUM_RESPONSES 10 +static POP3_RESPONSE pop3_response[NUM_RESPONSES]; + + +static char greeting[115] = { +0x2b, 0x4f, /* ..\...+O */ +0x4b, 0x20, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x65, /* K mail.e */ +0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, 0x6f, /* xpresslo */ +0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x20, /* gic.com */ +0x50, 0x4f, 0x50, 0x33, 0x20, 0x4d, 0x44, 0x61, /* POP3 MDa */ +0x65, 0x6d, 0x6f, 0x6e, 0x20, 0x31, 0x35, 0x2e, /* emon 15. */ +0x35, 0x2e, 0x33, 0x20, 0x72, 0x65, 0x61, 0x64, /* 5.3 read */ +0x79, 0x20, 0x3c, 0x4d, 0x44, 0x41, 0x45, 0x4d, /* y . */ +0x0a /* . */ +}; + +static int greeting_size = 115; + +static char user_ok[47] = { +0x2b, 0x4f, /* ...c..+O */ +0x4b, 0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, /* K testre */ +0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, /* cipient@ */ +0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, /* expressl */ +0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, /* ogic.com */ +0x2e, 0x2e, 0x2e, 0x20, 0x55, 0x73, 0x65, 0x72, /* ... User */ +0x20, 0x6f, 0x6b, 0x0d, 0x0a /* ok.. */ +}; + +static int user_ok_size = 47; + +static char password_ok[83] = { +0x2b, 0x4f, /* ...p..+O */ +0x4b, 0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, /* K testre */ +0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, /* cipient@ */ +0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, /* expressl */ +0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, /* ogic.com */ +0x27, 0x73, 0x20, 0x6d, 0x61, 0x69, 0x6c, 0x62, /* 's mailb */ +0x6f, 0x78, 0x20, 0x68, 0x61, 0x73, 0x20, 0x31, /* ox has 1 */ +0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x20, 0x6d, /* total m */ +0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x20, /* essages */ +0x28, 0x31, 0x38, 0x37, 0x34, 0x30, 0x32, 0x20, /* (187402 */ +0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x29, 0x0d, /* octets). */ +0x0a /* . */ +}; + +static int password_ok_size = 83; + +static char stat_ok[14] = { +0x2b, 0x4f, /* ..}...+O */ +0x4b, 0x20, 0x31, 0x20, 0x31, 0x38, 0x37, 0x34, /* K 1 1874 */ +0x30, 0x32, 0x0d, 0x0a /* 02.. */ +}; + +static int stat_ok_size = 14; + +static char retr_ok[19] = { +0x2b, 0x4f, /* ..Tv..+O */ +0x4b, 0x20, 0x31, 0x38, 0x37, 0x34, 0x30, 0x32, /* K 187402 */ +0x20, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x0d, /* octets. */ +0x0a /* . */ +}; + +static int retr_ok_size = 19; + + +static char first_data_packet[82] = { +0x52, 0x65, /* ..G...Re */ +0x74, 0x75, 0x72, 0x6e, 0x2d, 0x70, 0x61, 0x74, /* turn-pat */ +0x68, 0x3a, 0x20, 0x3c, 0x74, 0x65, 0x73, 0x74, /* h: ..Authe */ +0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, /* nticatio */ +0x6e, 0x2d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, /* n-Result */ +0x73, 0x3a, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, /* s: expre */ +0x73, 0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e +}; + +static int first_data_packet_size = 82; + +static char second_data_packet[82] = { +0x65, 0x64, /* ......ed */ +0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, /* ;.. */ +0x20, 0x20, 0x20, 0x64, 0x3d, 0x67, 0x6d, 0x61, /* d=gma */ +0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x3b, 0x20, /* il.com; */ +0x73, 0x3d, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, /* s=201201 */ +0x31, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, /* 13;.. */ +0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x3d, 0x63, /* h=c */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, /* ontent-t */ +0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, /* ransfer- */ +0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, /* encoding */ +0x3a, 0x66, 0x72, 0x6f, 0x6d, 0x3a, 0x6d, 0x69 +}; + +static int second_data_packet_size = 82; + +static char last_data_packet[82] = { +0x65, 0x64, /* ......ed */ +0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, /* ;.. */ +0x20, 0x20, 0x20, 0x64, 0x3d, 0x67, 0x6d, 0x61, /* d=gma */ +0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x3b, 0x20, /* il.com; */ +0x73, 0x3d, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, /* s=201201 */ +0x31, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, /* 13;.. */ +0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x3d, 0x63, /* h=c */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, /* ontent-t */ +0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, /* ransfer- */ +0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, /* encoding */ +0x3a, 0x66, 0x72, 0x0d, 0x0a, 0x2e, 0x0d, 0x0a +}; + +static int last_data_packet_size = 82; + +static char dele_ok[23] = { +0x2b, 0x4f, /* ......+O */ +0x4b, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, /* K messag */ +0x65, 0x20, 0x31, 0x20, 0x64, 0x65, 0x6c, 0x65, /* e 1 dele */ +0x74, 0x65, 0x64, 0x0d, 0x0a /* ted.. */ +}; + + +static int dele_ok_size = 23; + +static char quit_ok[93] = { +0x2b, 0x4f, /* ......+O */ +0x4b, 0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, /* K testre */ +0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, /* cipient@ */ +0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, /* expressl */ +0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, /* ogic.com */ +0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, /* express */ +0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, /* logic.co */ +0x6d, 0x20, 0x50, 0x4f, 0x50, 0x33, 0x20, 0x53, /* m POP3 S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, /* erver si */ +0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, /* gning of */ +0x66, 0x20, 0x28, 0x6d, 0x61, 0x69, 0x6c, 0x62, /* f (mailb */ +0x6f, 0x78, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, /* ox empty */ +0x29, 0x0d, 0x0a /* ).. */ +}; + +static int quit_ok_size = 93; + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pop3_mail_receive_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + + /* Setup the working pointer. */ + free_memory_pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the Server thread. */ + status = tx_thread_create(&server_thread, "Server thread ", server_thread_entry, 0, + free_memory_pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + free_memory_pointer = free_memory_pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "Server Packet Pool", PAYLOAD_SIZE, free_memory_pointer , PAYLOAD_SIZE*10); + + free_memory_pointer = free_memory_pointer + PAYLOAD_SIZE*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(1,2,3,4), + 0xFFFFFF00UL, + &server_packet_pool, _nx_ram_network_driver_1024, + free_memory_pointer, DEMO_STACK_SIZE, 1); + + free_memory_pointer = free_memory_pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory. */ + nx_arp_enable(&server_ip, (void *) free_memory_pointer, 1024); + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 1024; + + /* Enable TCP and ICMP for Server IP. */ + nx_tcp_enable(&server_ip); + nx_icmp_enable(&server_ip); + + /* Create a client thread. */ + tx_thread_create(&client_thread, "Client", client_thread_entry, 0, + free_memory_pointer, DEMO_STACK_SIZE, 1, 1, + TX_NO_TIME_SLICE, TX_AUTO_START); + + free_memory_pointer = free_memory_pointer + DEMO_STACK_SIZE; + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + + /* Create Client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "POP3 Client Packet Pool", + PAYLOAD_SIZE, free_memory_pointer, (PAYLOAD_SIZE * 10)); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + (PAYLOAD_SIZE * 10); + + /* Create IP instance for demo Client */ + status = nx_ip_create(&client_ip, "POP3 Client IP Instance", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, + &client_packet_pool, _nx_ram_network_driver_1024, free_memory_pointer, + 2048, 1); + + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 2048; + + /* Enable ARP and supply ARP cache memory. */ + nx_arp_enable(&client_ip, (void *) free_memory_pointer, 1024); + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 1024; + + /* Enable TCP and ICMP for Client IP. */ + nx_tcp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; +} + +/* Define the server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT i =0; + + /* Print out test information banner. */ + printf("NetX Test: POP3 Mail Receive Test...................................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + error_counter++; + } + + /* Create a socket as the server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + pop3_initialize_responses(); + + /* Bind the TCP socket to the POP3 port. */ + status = nx_tcp_server_socket_listen(&server_ip, 110, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for Client requests */ + while ( i < NUM_RESPONSES ) + { + + status = nx_pop3_response_packet_send(&server_socket, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* If this is the QUIT response, we're done */ + if (i == 9) + break; + + if ((i <4) || (i > 6)) + { + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Advance the index for the next response. */ + i++; + } + + /* Wait for the client to terminate the connection. */ + while(client_running == NX_TRUE) + tx_thread_sleep(20); + + /* Delete the TCP socket. */ + nx_tcp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +/* Define the application thread entry function. */ + +void client_thread_entry(ULONG info) +{ + +UINT status; +UINT mail_item, number_mail_items; +UINT bytes_downloaded = 0; +UINT final_packet = NX_FALSE; +ULONG total_size, mail_item_size, bytes_retrieved; +NX_PACKET *packet_ptr; + + NX_PARAMETER_NOT_USED(info); + + /* Let the IP instance get initialized with driver parameters. */ + tx_thread_sleep(10); + + /* Create a NetX POP3 Client instance with no byte or block memory pools. + Note that it uses its password for its APOP shared secret. */ + status = nx_pop3_client_create(&pop3_client, + NX_FALSE /* if true, enables Client to send APOP command to authenticate */, + &client_ip, &client_packet_pool, IP_ADDRESS(1,2,3,4), 110, + LOCALHOST, LOCALHOST_PASSWORD); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Find out how many items are in our mailbox. */ + status = nx_pop3_client_mail_items_get(&pop3_client, &number_mail_items, &total_size); + + /* If nothing in the mailbox, disconnect. */ + if (number_mail_items == 0) + { + error_counter++; + } + + /* Download all mail items. */ + mail_item = 1; + + while (mail_item <= number_mail_items) + { + + /* This submits a RETR request and gets the mail message size. */ + status = nx_pop3_client_mail_item_get(&pop3_client, mail_item, &mail_item_size); + + /* Loop to get the next mail message packet until the last mail item + packet is downloaded. */ + do + { + + status = nx_pop3_client_mail_item_message_get(&pop3_client, &packet_ptr, + &bytes_retrieved, + &final_packet); + + if (status != NX_SUCCESS) + { + break; + } + + nx_packet_release(packet_ptr); + + /* Determine if this is the last data packet. */ + if (final_packet) + { + /* It is. Let the server know it can delete this mail item. */ + status = nx_pop3_client_mail_item_delete(&pop3_client, mail_item); + + if (status != NX_SUCCESS) + { + break; + } + } + + /* Keep track of how much mail message data is left. */ + bytes_downloaded += bytes_retrieved; + + } while (final_packet == NX_FALSE); + + /* Get the next mail item. */ + mail_item++; + + tx_thread_sleep(10); + } + + /* Disconnect from the POP3 server. */ + status = nx_pop3_client_quit(&pop3_client); + + client_running = NX_FALSE; + + if (status != NX_SUCCESS) + error_counter++; + + /* Delete the POP3 Client. */ + status = nx_pop3_client_delete(&pop3_client); + + if (status != NX_SUCCESS) + error_counter++; + +} + +static UINT nx_pop3_response_packet_send(NX_TCP_SOCKET *server_socket_ptr, INT packet_number) +{ + +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, pop3_response[packet_number].pop3_response_pkt_data, + pop3_response[packet_number].pop3_response_pkt_size); + + response_packet -> nx_packet_length = pop3_response[packet_number].pop3_response_pkt_size; + + /* Adjust the write pointer. */ + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ + status = nx_tcp_socket_send(server_socket_ptr, response_packet, 100); + + /* Check the status. */ + if (status) + { + + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static UINT pop3_initialize_responses() +{ + + pop3_response[0].pop3_response_pkt_data = &greeting[0]; + pop3_response[0].pop3_response_pkt_size = greeting_size ; + + pop3_response[1].pop3_response_pkt_data = &user_ok[0]; + pop3_response[1].pop3_response_pkt_size = user_ok_size ; + + pop3_response[2].pop3_response_pkt_data = &password_ok[0]; + pop3_response[2].pop3_response_pkt_size = password_ok_size ; + + pop3_response[3].pop3_response_pkt_data = &stat_ok[0]; + pop3_response[3].pop3_response_pkt_size = stat_ok_size ; + + pop3_response[4].pop3_response_pkt_data = &retr_ok[0]; + pop3_response[4].pop3_response_pkt_size = retr_ok_size ; + + pop3_response[5].pop3_response_pkt_data = &first_data_packet[0]; + pop3_response[5].pop3_response_pkt_size = first_data_packet_size ; + + pop3_response[6].pop3_response_pkt_data = &second_data_packet[0]; + pop3_response[6].pop3_response_pkt_size = second_data_packet_size ; + + pop3_response[7].pop3_response_pkt_data = &last_data_packet[0]; + pop3_response[7].pop3_response_pkt_size = last_data_packet_size ; + + pop3_response[8].pop3_response_pkt_data = &dele_ok[0]; + pop3_response[8].pop3_response_pkt_size = dele_ok_size ; + + pop3_response[9].pop3_response_pkt_data = &quit_ok[0]; + pop3_response[9].pop3_response_pkt_size = quit_ok_size ; + + return NX_SUCCESS; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pop3_mail_receive_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: POP3 Mail Receive Test....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/pop3_test/netx_pop3_packet_with_endmarker_test.c b/test/regression/pop3_test/netx_pop3_packet_with_endmarker_test.c new file mode 100644 index 00000000..ad1f8268 --- /dev/null +++ b/test/regression/pop3_test/netx_pop3_packet_with_endmarker_test.c @@ -0,0 +1,727 @@ +/* + This is a small demo of POP3 Client on the high-performance NetX TCP/IP stack. + This demo relies on Thread, NetX and POP3 Client API to conduct + a POP3 mail session. + + The POP3 'server' is a TCP socket that sends responses and downloads a mail item + of three packets. The third packet of the second mail item only contains the POP# + end marker so the bytes_received should be zero. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_pop3_client.h" +#else +#include "nx_pop3_client.h" +#endif +extern void test_control_return(UINT); +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define SERVER_PORT 110 + +static UINT error_counter = 0; +static UINT client_running = NX_TRUE; + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static UINT nx_pop3_response_packet_send(NX_TCP_SOCKET *server_socket_ptr, INT packet_number); +static UINT pop3_initialize_responses(); + +/* Set up Client thread entry point. */ +static void client_thread_entry(ULONG info); +/* Set up Server thread entry point. */ +static void server_thread_entry(ULONG info); + + +/* Set up the POP3 Client and POP3 server socket. */ + +static TX_THREAD client_thread; +static NX_POP3_CLIENT pop3_client; +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD server_thread; +static NX_TCP_SOCKET server_socket; +static NX_PACKET_POOL server_packet_pool; +static NX_IP server_ip; + +/* Use the maximum size payload to insure no packets are dropped. */ +#define PAYLOAD_SIZE 1514 + +/* Shared secret is the same as password. */ + +#define LOCALHOST "recipient@domain.com" +#define LOCALHOST_PASSWORD "testpwd" + +typedef struct POP3_RESPONSE_STRUCT +{ + char *pop3_response_pkt_data; + int pop3_response_pkt_size; +} POP3_RESPONSE; + +#define NUM_RESPONSES 15 +static POP3_RESPONSE pop3_response[NUM_RESPONSES]; + + +static char greeting[115] = { +0x2b, 0x4f, /* ..\...+O */ +0x4b, 0x20, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x65, /* K mail.e */ +0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, 0x6f, /* xpresslo */ +0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x20, /* gic.com */ +0x50, 0x4f, 0x50, 0x33, 0x20, 0x4d, 0x44, 0x61, /* POP3 MDa */ +0x65, 0x6d, 0x6f, 0x6e, 0x20, 0x31, 0x35, 0x2e, /* emon 15. */ +0x35, 0x2e, 0x33, 0x20, 0x72, 0x65, 0x61, 0x64, /* 5.3 read */ +0x79, 0x20, 0x3c, 0x4d, 0x44, 0x41, 0x45, 0x4d, /* y . */ +0x0a /* . */ +}; + +static int greeting_size = 115; + +static char user_ok[47] = { +0x2b, 0x4f, /* ...c..+O */ +0x4b, 0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, /* K testre */ +0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, /* cipient@ */ +0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, /* expressl */ +0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, /* ogic.com */ +0x2e, 0x2e, 0x2e, 0x20, 0x55, 0x73, 0x65, 0x72, /* ... User */ +0x20, 0x6f, 0x6b, 0x0d, 0x0a /* ok.. */ +}; + +static int user_ok_size = 47; + +static char password_ok[83] = { +0x2b, 0x4f, /* ...p..+O */ +0x4b, 0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, /* K testre */ +0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, /* cipient@ */ +0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, /* expressl */ +0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, /* ogic.com */ +0x27, 0x73, 0x20, 0x6d, 0x61, 0x69, 0x6c, 0x62, /* 's mailb */ +0x6f, 0x78, 0x20, 0x68, 0x61, 0x73, 0x20, 0x31, /* ox has 1 */ +0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x20, 0x6d, /* total m */ +0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x20, /* essages */ +0x28, 0x31, 0x38, 0x37, 0x34, 0x30, 0x32, 0x20, /* (187402 */ +0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x29, 0x0d, /* octets). */ +0x0a /* . */ +}; + +static int password_ok_size = 83; + +static char stat_ok[14] = { +0x2b, 0x4f, /* ..}...+O */ +0x4b, 0x20, 0x32, 0x20, 0x31, 0x38, 0x37, 0x34, /* K 2 1874 */ +0x30, 0x32, 0x0d, 0x0a /* 02.. */ +}; + +static int stat_ok_size = 14; + +static char retr_ok[19] = { +0x2b, 0x4f, /* ..Tv..+O */ +0x4b, 0x20, 0x31, 0x38, 0x37, 0x34, 0x30, 0x32, /* K 187402 */ +0x20, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x0d, /* octets. */ +0x0a /* . */ +}; + +static int retr_ok_size = 19; + + +static char first_data_packet[82] = { +0x52, 0x65, /* ..G...Re */ +0x74, 0x75, 0x72, 0x6e, 0x2d, 0x70, 0x61, 0x74, /* turn-pat */ +0x68, 0x3a, 0x20, 0x3c, 0x74, 0x65, 0x73, 0x74, /* h: ..Authe */ +0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, /* nticatio */ +0x6e, 0x2d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, /* n-Result */ +0x73, 0x3a, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, /* s: expre */ +0x73, 0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e +}; + +static int first_data_packet_size = 82; + +static char second_data_packet[82] = { +0x65, 0x64, /* ......ed */ +0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, /* ;.. */ +0x20, 0x20, 0x20, 0x64, 0x3d, 0x67, 0x6d, 0x61, /* d=gma */ +0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x3b, 0x20, /* il.com; */ +0x73, 0x3d, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, /* s=201201 */ +0x31, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, /* 13;.. */ +0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x3d, 0x63, /* h=c */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, /* ontent-t */ +0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, /* ransfer- */ +0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, /* encoding */ +0x3a, 0x66, 0x72, 0x6f, 0x6d, 0x3a, 0x6d, 0x69 +}; + +static int second_data_packet_size = 82; + +static char last_data_packet[82] = { +0x65, 0x64, /* ......ed */ +0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, /* ;.. */ +0x20, 0x20, 0x20, 0x64, 0x3d, 0x67, 0x6d, 0x61, /* d=gma */ +0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x3b, 0x20, /* il.com; */ +0x73, 0x3d, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, /* s=201201 */ +0x31, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, /* 13;.. */ +0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x3d, 0x63, /* h=c */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, /* ontent-t */ +0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, /* ransfer- */ +0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, /* encoding */ +0x3a, 0x66, 0x72, 0x0d, 0x0a, 0x2e, 0x0d, 0x0a +}; + +static int last_data_packet_size = 82; + +static char dele_ok[23] = { +0x2b, 0x4f, /* ......+O */ +0x4b, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, /* K messag */ +0x65, 0x20, 0x31, 0x20, 0x64, 0x65, 0x6c, 0x65, /* e 1 dele */ +0x74, 0x65, 0x64, 0x0d, 0x0a /* ted.. */ +}; + + +static int dele_ok_size = 23; + + +static char retr_ok2[19] = { +0x2b, 0x4f, /* ..Tv..+O */ +0x4b, 0x20, 0x31, 0x38, 0x37, 0x34, 0x30, 0x32, /* K 187402 */ +0x20, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x0d, /* octets. */ +0x0a /* . */ +}; + +static int retr_ok2_size = 19; + + +static char first_data_packet2[82] = { +0x52, 0x65, /* ..G...Re */ +0x74, 0x75, 0x72, 0x6e, 0x2d, 0x70, 0x61, 0x74, /* turn-pat */ +0x68, 0x3a, 0x20, 0x3c, 0x74, 0x65, 0x73, 0x74, /* h: ..Authe */ +0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, /* nticatio */ +0x6e, 0x2d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, /* n-Result */ +0x73, 0x3a, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, /* s: expre */ +0x73, 0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e +}; + +static int first_data_packet2_size = 82; + +static char second_data_packet2[82] = { +0x65, 0x64, /* ......ed */ +0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, /* ;.. */ +0x20, 0x20, 0x20, 0x64, 0x3d, 0x67, 0x6d, 0x61, /* d=gma */ +0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x3b, 0x20, /* il.com; */ +0x73, 0x3d, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, /* s=201201 */ +0x31, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, /* 13;.. */ +0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x3d, 0x63, /* h=c */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, /* ontent-t */ +0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, /* ransfer- */ +0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, /* encoding */ +0x3a, 0x66, 0x72, 0x6f, 0x6d, 0x3a, 0x6d, 0x69 +}; + +static int second_data_packet2_size = 82; + +static char last_data_packet2[5] = { + 0x0d, 0x0a, 0x2e, 0x0d, 0x0a +}; + +static int last_data_packet2_size = 5; + +static char dele_ok2[23] = { +0x2b, 0x4f, /* ......+O */ +0x4b, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, /* K messag */ +0x65, 0x20, 0x31, 0x20, 0x64, 0x65, 0x6c, 0x65, /* e 1 dele */ +0x74, 0x65, 0x64, 0x0d, 0x0a /* ted.. */ +}; + + +static int dele_ok2_size = 23; + + + +static char quit_ok[93] = { +0x2b, 0x4f, /* ......+O */ +0x4b, 0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, /* K testre */ +0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, /* cipient@ */ +0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, /* expressl */ +0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, /* ogic.com */ +0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, /* express */ +0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, /* logic.co */ +0x6d, 0x20, 0x50, 0x4f, 0x50, 0x33, 0x20, 0x53, /* m POP3 S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, /* erver si */ +0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, /* gning of */ +0x66, 0x20, 0x28, 0x6d, 0x61, 0x69, 0x6c, 0x62, /* f (mailb */ +0x6f, 0x78, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, /* ox empty */ +0x29, 0x0d, 0x0a /* ).. */ +}; + +static int quit_ok_size = 93; + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pop3_packet_with_endmarker_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + + /* Setup the working pointer. */ + free_memory_pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the Server thread. */ + status = tx_thread_create(&server_thread, "Server thread ", server_thread_entry, 0, + free_memory_pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + free_memory_pointer = free_memory_pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "Server Packet Pool", PAYLOAD_SIZE, free_memory_pointer , PAYLOAD_SIZE*10); + + free_memory_pointer = free_memory_pointer + PAYLOAD_SIZE*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(1,2,3,4), + 0xFFFFFF00UL, + &server_packet_pool, _nx_ram_network_driver_1024, + free_memory_pointer, DEMO_STACK_SIZE, 1); + + free_memory_pointer = free_memory_pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory. */ + nx_arp_enable(&server_ip, (void *) free_memory_pointer, 1024); + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 1024; + + /* Enable TCP and ICMP for Server IP. */ + nx_tcp_enable(&server_ip); + nx_icmp_enable(&server_ip); + + /* Create a client thread. */ + tx_thread_create(&client_thread, "Client", client_thread_entry, 0, + free_memory_pointer, DEMO_STACK_SIZE, 1, 1, + TX_NO_TIME_SLICE, TX_AUTO_START); + + free_memory_pointer = free_memory_pointer + DEMO_STACK_SIZE; + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + + /* Create Client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "POP3 Client Packet Pool", + PAYLOAD_SIZE, free_memory_pointer, (PAYLOAD_SIZE * 10)); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + (PAYLOAD_SIZE * 10); + + /* Create IP instance for demo Client */ + status = nx_ip_create(&client_ip, "POP3 Client IP Instance", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, + &client_packet_pool, _nx_ram_network_driver_1024, free_memory_pointer, + 2048, 1); + + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 2048; + + /* Enable ARP and supply ARP cache memory. */ + nx_arp_enable(&client_ip, (void *) free_memory_pointer, 1024); + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 1024; + + /* Enable TCP and ICMP for Client IP. */ + nx_tcp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; +} + +/* Define the server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT receive_packet; +UINT i =0; + + /* Print out test information banner. */ + printf("NetX Test: POP3_Packet_With_Endmarker_Test..........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + error_counter++; + } + + /* Create a socket as the server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + pop3_initialize_responses(); + + /* Bind the TCP socket to the POP3 port. */ + status = nx_tcp_server_socket_listen(&server_ip, 110, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for Client requests */ + while ( i < NUM_RESPONSES ) + { + + /* Default TCP server not to send a packet. */ + receive_packet = NX_TRUE; + + status = nx_pop3_response_packet_send(&server_socket, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* If this is the QUIT response, we're done */ + if (i == 14) + { + break; + } + + /* In these iterations, the server sends a packet without expecting a + response. */ + if ( + (i == 4) || + (i == 5) || + (i == 6) || + (i == 9) || + (i == 10) || + (i == 11) + ) + { + + /* Set the flag not to receive a packet. */ + receive_packet = NX_FALSE; + } + + /* TCP server expects to receive a packet. */ + if (receive_packet) + { + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + nx_packet_release(my_packet); + } + } + + /* Advance the index for the next response. */ + i++; + } + + /* Wait for the client to terminate the connection. */ + while(client_running == NX_TRUE) + tx_thread_sleep(20); + + /* Delete the TCP socket. */ + nx_tcp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +/* Define the application thread entry function. */ + +void client_thread_entry(ULONG info) +{ + +UINT status; +UINT mail_item, number_mail_items; +UINT bytes_downloaded = 0; +UINT final_packet = NX_FALSE; +ULONG total_size, mail_item_size, bytes_retrieved; +NX_PACKET *packet_ptr; + + NX_PARAMETER_NOT_USED(info); + + /* Let the IP instance get initialized with driver parameters. */ + tx_thread_sleep(10); + + /* Create a NetX POP3 Client instance with no byte or block memory pools. + Note that it uses its password for its APOP shared secret. */ + status = nx_pop3_client_create(&pop3_client, + NX_FALSE /* if true, enables Client to send APOP command to authenticate */, + &client_ip, &client_packet_pool, IP_ADDRESS(1,2,3,4), 110, + LOCALHOST, LOCALHOST_PASSWORD); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Find out how many items are in our mailbox. */ + status = nx_pop3_client_mail_items_get(&pop3_client, &number_mail_items, &total_size); + + /* If nothing in the mailbox, disconnect. */ + if (number_mail_items == 0) + { + error_counter++; + } + + /* Download all mail items. */ + mail_item = 1; + + while (mail_item <= number_mail_items) + { + + /* This submits a RETR request and gets the mail message size. */ + status = nx_pop3_client_mail_item_get(&pop3_client, mail_item, &mail_item_size); + + /* Loop to get the next mail message packet until the last mail item + packet is downloaded. */ + do + { + + status = nx_pop3_client_mail_item_message_get(&pop3_client, &packet_ptr, + &bytes_retrieved, + &final_packet); + + if (status != NX_SUCCESS) + { + break; + } + + nx_packet_release(packet_ptr); + + /* Determine if this is the last data packet. */ + if (final_packet) + { + /* It is. If it is the second mail item verify that no data is reported in the packet. */ + if ((mail_item == 2) && (bytes_retrieved != 0)) + { + + error_counter++; + } + + /* Let the server know it can delete this mail item. */ + status = nx_pop3_client_mail_item_delete(&pop3_client, mail_item); + + if (status != NX_SUCCESS) + { + break; + } + } + + /* Keep track of how much mail message data is left. */ + bytes_downloaded += bytes_retrieved; + + } while (final_packet == NX_FALSE); + + bytes_downloaded = 0; + + /* Get the next mail item. */ + mail_item++; + + tx_thread_sleep(10); + } + + /* Disconnect from the POP3 server. */ + status = nx_pop3_client_quit(&pop3_client); + + client_running = NX_FALSE; + + if (status != NX_SUCCESS) + error_counter++; + + /* Delete the POP3 Client. */ + status = nx_pop3_client_delete(&pop3_client); + + if (status != NX_SUCCESS) + error_counter++; + +} + +static UINT nx_pop3_response_packet_send(NX_TCP_SOCKET *server_socket_ptr, INT packet_number) +{ + +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, pop3_response[packet_number].pop3_response_pkt_data, + pop3_response[packet_number].pop3_response_pkt_size); + + response_packet -> nx_packet_length = pop3_response[packet_number].pop3_response_pkt_size; + + /* Adjust the write pointer. */ + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ + status = nx_tcp_socket_send(server_socket_ptr, response_packet, 100); + + /* Check the status. */ + if (status) + { + + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static UINT pop3_initialize_responses() +{ + + pop3_response[0].pop3_response_pkt_data = &greeting[0]; + pop3_response[0].pop3_response_pkt_size = greeting_size ; + + pop3_response[1].pop3_response_pkt_data = &user_ok[0]; + pop3_response[1].pop3_response_pkt_size = user_ok_size ; + + pop3_response[2].pop3_response_pkt_data = &password_ok[0]; + pop3_response[2].pop3_response_pkt_size = password_ok_size ; + + pop3_response[3].pop3_response_pkt_data = &stat_ok[0]; + pop3_response[3].pop3_response_pkt_size = stat_ok_size ; + + pop3_response[4].pop3_response_pkt_data = &retr_ok[0]; + pop3_response[4].pop3_response_pkt_size = retr_ok_size ; + + pop3_response[5].pop3_response_pkt_data = &first_data_packet[0]; + pop3_response[5].pop3_response_pkt_size = first_data_packet_size ; + + pop3_response[6].pop3_response_pkt_data = &second_data_packet[0]; + pop3_response[6].pop3_response_pkt_size = second_data_packet_size ; + + pop3_response[7].pop3_response_pkt_data = &last_data_packet[0]; + pop3_response[7].pop3_response_pkt_size = last_data_packet_size ; + + pop3_response[8].pop3_response_pkt_data = &dele_ok[0]; + pop3_response[8].pop3_response_pkt_size = dele_ok_size ; + + + pop3_response[9].pop3_response_pkt_data = &retr_ok2[0]; + pop3_response[9].pop3_response_pkt_size = retr_ok2_size ; + + pop3_response[10].pop3_response_pkt_data = &first_data_packet2[0]; + pop3_response[10].pop3_response_pkt_size = first_data_packet2_size ; + + pop3_response[11].pop3_response_pkt_data = &second_data_packet2[0]; + pop3_response[11].pop3_response_pkt_size = second_data_packet2_size ; + + pop3_response[12].pop3_response_pkt_data = &last_data_packet2[0]; + pop3_response[12].pop3_response_pkt_size = last_data_packet2_size ; + + pop3_response[13].pop3_response_pkt_data = &dele_ok2[0]; + pop3_response[13].pop3_response_pkt_size = dele_ok2_size ; + + + pop3_response[14].pop3_response_pkt_data = &quit_ok[0]; + pop3_response[14].pop3_response_pkt_size = quit_ok_size ; + + return NX_SUCCESS; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pop3_packet_with_endmarker_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: POP3_Packet_With_Endmarker_Test...........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/pop3_test/netx_pop3_two_mails_received_test.c b/test/regression/pop3_test/netx_pop3_two_mails_received_test.c new file mode 100644 index 00000000..41f2ae31 --- /dev/null +++ b/test/regression/pop3_test/netx_pop3_two_mails_received_test.c @@ -0,0 +1,732 @@ +/* + This is a small demo of POP3 Client on the high-performance NetX TCP/IP stack. + This demo relies on Thread, NetX and POP3 Client API to conduct + a POP3 mail session. + + The POP3 'server' is a TCP socket that sends responses and downloads 2 mail items + of three packets each. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ram_network_driver_test_1500.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_pop3_client.h" +#else +#include "nx_pop3_client.h" +#endif +extern void test_control_return(UINT); +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 +#define SERVER_PORT 110 + +static UINT error_counter = 0; +static UINT client_running = NX_TRUE; + +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); +static UINT nx_pop3_response_packet_send(NX_TCP_SOCKET *server_socket_ptr, INT packet_number); +static UINT pop3_initialize_responses(); + +/* Set up Client thread entry point. */ +static void client_thread_entry(ULONG info); +/* Set up Server thread entry point. */ +static void server_thread_entry(ULONG info); + + +/* Set up the POP3 Client and POP3 server socket. */ + +static TX_THREAD client_thread; +static NX_POP3_CLIENT pop3_client; +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD server_thread; +static NX_TCP_SOCKET server_socket; +static NX_PACKET_POOL server_packet_pool; +static NX_IP server_ip; + +/* Use the maximum size payload to insure no packets are dropped. */ +#define PAYLOAD_SIZE 1514 + +/* Shared secret is the same as password. */ + +#define LOCALHOST "recipient@domain.com" +#define LOCALHOST_PASSWORD "testpwd" + +typedef struct POP3_RESPONSE_STRUCT +{ + char *pop3_response_pkt_data; + int pop3_response_pkt_size; +} POP3_RESPONSE; + +#define NUM_RESPONSES 15 +static POP3_RESPONSE pop3_response[NUM_RESPONSES]; + + +static char greeting[115] = { +0x2b, 0x4f, /* ..\...+O */ +0x4b, 0x20, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x65, /* K mail.e */ +0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, 0x6f, /* xpresslo */ +0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x20, /* gic.com */ +0x50, 0x4f, 0x50, 0x33, 0x20, 0x4d, 0x44, 0x61, /* POP3 MDa */ +0x65, 0x6d, 0x6f, 0x6e, 0x20, 0x31, 0x35, 0x2e, /* emon 15. */ +0x35, 0x2e, 0x33, 0x20, 0x72, 0x65, 0x61, 0x64, /* 5.3 read */ +0x79, 0x20, 0x3c, 0x4d, 0x44, 0x41, 0x45, 0x4d, /* y . */ +0x0a /* . */ +}; + +static int greeting_size = 115; + +static char user_ok[47] = { +0x2b, 0x4f, /* ...c..+O */ +0x4b, 0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, /* K testre */ +0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, /* cipient@ */ +0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, /* expressl */ +0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, /* ogic.com */ +0x2e, 0x2e, 0x2e, 0x20, 0x55, 0x73, 0x65, 0x72, /* ... User */ +0x20, 0x6f, 0x6b, 0x0d, 0x0a /* ok.. */ +}; + +static int user_ok_size = 47; + +static char password_ok[83] = { +0x2b, 0x4f, /* ...p..+O */ +0x4b, 0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, /* K testre */ +0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, /* cipient@ */ +0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, /* expressl */ +0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, /* ogic.com */ +0x27, 0x73, 0x20, 0x6d, 0x61, 0x69, 0x6c, 0x62, /* 's mailb */ +0x6f, 0x78, 0x20, 0x68, 0x61, 0x73, 0x20, 0x31, /* ox has 1 */ +0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x20, 0x6d, /* total m */ +0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x20, /* essages */ +0x28, 0x31, 0x38, 0x37, 0x34, 0x30, 0x32, 0x20, /* (187402 */ +0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x29, 0x0d, /* octets). */ +0x0a /* . */ +}; + +static int password_ok_size = 83; + +static char stat_ok[14] = { +0x2b, 0x4f, /* ..}...+O */ +0x4b, 0x20, 0x32, 0x20, 0x31, 0x38, 0x37, 0x34, /* K 2 1874 */ +0x30, 0x32, 0x0d, 0x0a /* 02.. */ +}; + +static int stat_ok_size = 14; + +static char retr_ok[19] = { +0x2b, 0x4f, /* ..Tv..+O */ +0x4b, 0x20, 0x31, 0x38, 0x37, 0x34, 0x30, 0x32, /* K 187402 */ +0x20, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x0d, /* octets. */ +0x0a /* . */ +}; + +static int retr_ok_size = 19; + + +static char first_data_packet[82] = { +0x52, 0x65, /* ..G...Re */ +0x74, 0x75, 0x72, 0x6e, 0x2d, 0x70, 0x61, 0x74, /* turn-pat */ +0x68, 0x3a, 0x20, 0x3c, 0x74, 0x65, 0x73, 0x74, /* h: ..Authe */ +0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, /* nticatio */ +0x6e, 0x2d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, /* n-Result */ +0x73, 0x3a, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, /* s: expre */ +0x73, 0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e +}; + +static int first_data_packet_size = 82; + +static char second_data_packet[82] = { +0x65, 0x64, /* ......ed */ +0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, /* ;.. */ +0x20, 0x20, 0x20, 0x64, 0x3d, 0x67, 0x6d, 0x61, /* d=gma */ +0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x3b, 0x20, /* il.com; */ +0x73, 0x3d, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, /* s=201201 */ +0x31, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, /* 13;.. */ +0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x3d, 0x63, /* h=c */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, /* ontent-t */ +0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, /* ransfer- */ +0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, /* encoding */ +0x3a, 0x66, 0x72, 0x6f, 0x6d, 0x3a, 0x6d, 0x69 +}; + +static int second_data_packet_size = 82; + +static char last_data_packet[82] = { +0x65, 0x64, /* ......ed */ +0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, /* ;.. */ +0x20, 0x20, 0x20, 0x64, 0x3d, 0x67, 0x6d, 0x61, /* d=gma */ +0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x3b, 0x20, /* il.com; */ +0x73, 0x3d, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, /* s=201201 */ +0x31, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, /* 13;.. */ +0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x3d, 0x63, /* h=c */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, /* ontent-t */ +0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, /* ransfer- */ +0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, /* encoding */ +0x3a, 0x66, 0x72, 0x0d, 0x0a, 0x2e, 0x0d, 0x0a +}; + +static int last_data_packet_size = 82; + +static char dele_ok[23] = { +0x2b, 0x4f, /* ......+O */ +0x4b, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, /* K messag */ +0x65, 0x20, 0x31, 0x20, 0x64, 0x65, 0x6c, 0x65, /* e 1 dele */ +0x74, 0x65, 0x64, 0x0d, 0x0a /* ted.. */ +}; + + +static int dele_ok_size = 23; + + +static char retr_ok2[19] = { +0x2b, 0x4f, /* ..Tv..+O */ +0x4b, 0x20, 0x31, 0x38, 0x37, 0x34, 0x30, 0x32, /* K 187402 */ +0x20, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x73, 0x0d, /* octets. */ +0x0a /* . */ +}; + +static int retr_ok2_size = 19; + + +static char first_data_packet2[82] = { +0x52, 0x65, /* ..G...Re */ +0x74, 0x75, 0x72, 0x6e, 0x2d, 0x70, 0x61, 0x74, /* turn-pat */ +0x68, 0x3a, 0x20, 0x3c, 0x74, 0x65, 0x73, 0x74, /* h: ..Authe */ +0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, /* nticatio */ +0x6e, 0x2d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, /* n-Result */ +0x73, 0x3a, 0x20, 0x65, 0x78, 0x70, 0x72, 0x65, /* s: expre */ +0x73, 0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e +}; + +static int first_data_packet2_size = 82; + +static char second_data_packet2[82] = { +0x65, 0x64, /* ......ed */ +0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, /* ;.. */ +0x20, 0x20, 0x20, 0x64, 0x3d, 0x67, 0x6d, 0x61, /* d=gma */ +0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x3b, 0x20, /* il.com; */ +0x73, 0x3d, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, /* s=201201 */ +0x31, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, /* 13;.. */ +0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x3d, 0x63, /* h=c */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, /* ontent-t */ +0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, /* ransfer- */ +0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, /* encoding */ +0x3a, 0x66, 0x72, 0x6f, 0x6d, 0x3a, 0x6d, 0x69 +}; + +static int second_data_packet2_size = 82; + +static char last_data_packet2[82] = { +0x65, 0x64, /* ......ed */ +0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, /* ;.. */ +0x20, 0x20, 0x20, 0x64, 0x3d, 0x67, 0x6d, 0x61, /* d=gma */ +0x69, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x3b, 0x20, /* il.com; */ +0x73, 0x3d, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, /* s=201201 */ +0x31, 0x33, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, /* 13;.. */ +0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x3d, 0x63, /* h=c */ +0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, /* ontent-t */ +0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, /* ransfer- */ +0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, /* encoding */ +0x3a, 0x66, 0x72, 0x0d, 0x0a, 0x2e, 0x0d, 0x0a +}; + +static int last_data_packet2_size = 82; + +static char dele_ok2[23] = { +0x2b, 0x4f, /* ......+O */ +0x4b, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, /* K messag */ +0x65, 0x20, 0x31, 0x20, 0x64, 0x65, 0x6c, 0x65, /* e 1 dele */ +0x74, 0x65, 0x64, 0x0d, 0x0a /* ted.. */ +}; + + +static int dele_ok2_size = 23; + + + +static char quit_ok[93] = { +0x2b, 0x4f, /* ......+O */ +0x4b, 0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, /* K testre */ +0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, /* cipient@ */ +0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, /* expressl */ +0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, /* ogic.com */ +0x20, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, /* express */ +0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, /* logic.co */ +0x6d, 0x20, 0x50, 0x4f, 0x50, 0x33, 0x20, 0x53, /* m POP3 S */ +0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, /* erver si */ +0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x6f, 0x66, /* gning of */ +0x66, 0x20, 0x28, 0x6d, 0x61, 0x69, 0x6c, 0x62, /* f (mailb */ +0x6f, 0x78, 0x20, 0x65, 0x6d, 0x70, 0x74, 0x79, /* ox empty */ +0x29, 0x0d, 0x0a /* ).. */ +}; + +static int quit_ok_size = 93; + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pop3_two_mails_received_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + + /* Setup the working pointer. */ + free_memory_pointer = (UCHAR *) first_unused_memory; + + /* Initialize NetX. */ + nx_system_initialize(); + + /* Create the Server thread. */ + status = tx_thread_create(&server_thread, "Server thread ", server_thread_entry, 0, + free_memory_pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + + free_memory_pointer = free_memory_pointer + DEMO_STACK_SIZE ; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "Server Packet Pool", PAYLOAD_SIZE, free_memory_pointer , PAYLOAD_SIZE*10); + + free_memory_pointer = free_memory_pointer + PAYLOAD_SIZE*10; + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, + "Server IP", + IP_ADDRESS(1,2,3,4), + 0xFFFFFF00UL, + &server_packet_pool, _nx_ram_network_driver_1024, + free_memory_pointer, DEMO_STACK_SIZE, 1); + + free_memory_pointer = free_memory_pointer + DEMO_STACK_SIZE; + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory. */ + nx_arp_enable(&server_ip, (void *) free_memory_pointer, 1024); + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 1024; + + /* Enable TCP and ICMP for Server IP. */ + nx_tcp_enable(&server_ip); + nx_icmp_enable(&server_ip); + + /* Create a client thread. */ + tx_thread_create(&client_thread, "Client", client_thread_entry, 0, + free_memory_pointer, DEMO_STACK_SIZE, 1, 1, + TX_NO_TIME_SLICE, TX_AUTO_START); + + free_memory_pointer = free_memory_pointer + DEMO_STACK_SIZE; + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + + /* Create Client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "POP3 Client Packet Pool", + PAYLOAD_SIZE, free_memory_pointer, (PAYLOAD_SIZE * 10)); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + (PAYLOAD_SIZE * 10); + + /* Create IP instance for demo Client */ + status = nx_ip_create(&client_ip, "POP3 Client IP Instance", IP_ADDRESS(1,2,3,5), 0xFFFFFF00UL, + &client_packet_pool, _nx_ram_network_driver_1024, free_memory_pointer, + 2048, 1); + + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 2048; + + /* Enable ARP and supply ARP cache memory. */ + nx_arp_enable(&client_ip, (void *) free_memory_pointer, 1024); + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 1024; + + /* Enable TCP and ICMP for Client IP. */ + nx_tcp_enable(&client_ip); + nx_icmp_enable(&client_ip); + + return; +} + +/* Define the server thread. */ +void server_thread_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *my_packet; +UINT receive_packet; +UINT i =0; + + /* Print out test information banner. */ + printf("NetX Test: POP3 Two Mail Items Received Test........................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + error_counter++; + } + + /* Create a socket as the server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket Server", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 2048, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Load up the server 'responses'. */ + pop3_initialize_responses(); + + /* Bind the TCP socket to the POP3 port. */ + status = nx_tcp_server_socket_listen(&server_ip, 110, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for a connection request. */ + status = nx_tcp_server_socket_accept(&server_socket, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Wait for Client requests */ + while ( i < NUM_RESPONSES ) + { + + /* Default TCP server not to send a packet. */ + receive_packet = NX_TRUE; + + status = nx_pop3_response_packet_send(&server_socket, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* If this is the QUIT response, we're done */ + if (i == 14) + { + break; + } + + + /* In these iterations, the server sends a packet without expecting a + response. */ + if ( + (i == 4) || + (i == 5) || + (i == 6) || + (i == 9) || + (i == 10) || + (i == 11) + ) + { + + /* Set the flag not to receive a packet. */ + receive_packet = NX_FALSE; + } + + /* TCP server expects to receive a packet. */ + if (receive_packet) + { + + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + } + else + { + nx_packet_release(my_packet); + } + } + + /* Advance the index for the next response. */ + i++; + } + + /* Wait for the client to terminate the connection. */ + while(client_running == NX_TRUE) + tx_thread_sleep(20); + + /* Delete the TCP socket. */ + nx_tcp_socket_delete(&server_socket); + + if(error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + }; +} + + +/* Define the application thread entry function. */ + +void client_thread_entry(ULONG info) +{ + +UINT status; +UINT mail_item, number_mail_items; +UINT bytes_downloaded = 0; +UINT final_packet = NX_FALSE; +ULONG total_size, mail_item_size, bytes_retrieved; +NX_PACKET *packet_ptr; + + NX_PARAMETER_NOT_USED(info); + + /* Let the IP instance get initialized with driver parameters. */ + tx_thread_sleep(10); + + /* Create a NetX POP3 Client instance with no byte or block memory pools. + Note that it uses its password for its APOP shared secret. */ + status = nx_pop3_client_create(&pop3_client, + NX_FALSE /* if true, enables Client to send APOP command to authenticate */, + &client_ip, &client_packet_pool, IP_ADDRESS(1,2,3,4), 110, + LOCALHOST, LOCALHOST_PASSWORD); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Find out how many items are in our mailbox. */ + status = nx_pop3_client_mail_items_get(&pop3_client, &number_mail_items, &total_size); + + /* If nothing in the mailbox, disconnect. */ + if (number_mail_items == 0) + { + error_counter++; + } + + /* Download all mail items. */ + mail_item = 1; + + while (mail_item <= number_mail_items) + { + + /* This submits a RETR request and gets the mail message size. */ + status = nx_pop3_client_mail_item_get(&pop3_client, mail_item, &mail_item_size); + + /* Loop to get the next mail message packet until the last mail item + packet is downloaded. */ + do + { + + status = nx_pop3_client_mail_item_message_get(&pop3_client, &packet_ptr, + &bytes_retrieved, + &final_packet); + + if (status != NX_SUCCESS) + { + break; + } + + nx_packet_release(packet_ptr); + + /* Determine if this is the last data packet. */ + if (final_packet) + { + /* It is. Let the server know it can delete this mail item. */ + status = nx_pop3_client_mail_item_delete(&pop3_client, mail_item); + + if (status != NX_SUCCESS) + { + break; + } + } + + /* Keep track of how much mail message data is left. */ + bytes_downloaded += bytes_retrieved; + + } while (final_packet == NX_FALSE); + + /* Get the next mail item. */ + mail_item++; + + /* Clear the download size before downloading the next mail item. */ + bytes_downloaded = 0; + + tx_thread_sleep(10); + } + + /* Tell the POP3 server we're leaving the session. This sends the QUIT command. */ + status = nx_pop3_client_quit(&pop3_client); + + if (status) + { + error_counter++; + } + + client_running = NX_FALSE; + + /* Disconnect and delete the POP3 Client. */ + nx_pop3_client_delete(&pop3_client); + +} + +static UINT nx_pop3_response_packet_send(NX_TCP_SOCKET *server_socket_ptr, INT packet_number) +{ + +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Write the response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, pop3_response[packet_number].pop3_response_pkt_data, + pop3_response[packet_number].pop3_response_pkt_size); + + response_packet -> nx_packet_length = pop3_response[packet_number].pop3_response_pkt_size; + + /* Adjust the write pointer. */ + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the packet with the correct port. */ + status = nx_tcp_socket_send(server_socket_ptr, response_packet, 100); + + /* Check the status. */ + if (status) + { + + error_counter++; + } + + return status; +} + +static UINT pop3_initialize_responses() +{ + + pop3_response[0].pop3_response_pkt_data = &greeting[0]; + pop3_response[0].pop3_response_pkt_size = greeting_size ; + + pop3_response[1].pop3_response_pkt_data = &user_ok[0]; + pop3_response[1].pop3_response_pkt_size = user_ok_size ; + + pop3_response[2].pop3_response_pkt_data = &password_ok[0]; + pop3_response[2].pop3_response_pkt_size = password_ok_size ; + + pop3_response[3].pop3_response_pkt_data = &stat_ok[0]; + pop3_response[3].pop3_response_pkt_size = stat_ok_size ; + + pop3_response[4].pop3_response_pkt_data = &retr_ok[0]; + pop3_response[4].pop3_response_pkt_size = retr_ok_size ; + + pop3_response[5].pop3_response_pkt_data = &first_data_packet[0]; + pop3_response[5].pop3_response_pkt_size = first_data_packet_size ; + + pop3_response[6].pop3_response_pkt_data = &second_data_packet[0]; + pop3_response[6].pop3_response_pkt_size = second_data_packet_size ; + + pop3_response[7].pop3_response_pkt_data = &last_data_packet[0]; + pop3_response[7].pop3_response_pkt_size = last_data_packet_size ; + + pop3_response[8].pop3_response_pkt_data = &dele_ok[0]; + pop3_response[8].pop3_response_pkt_size = dele_ok_size ; + + + pop3_response[9].pop3_response_pkt_data = &retr_ok2[0]; + pop3_response[9].pop3_response_pkt_size = retr_ok2_size ; + + pop3_response[10].pop3_response_pkt_data = &first_data_packet2[0]; + pop3_response[10].pop3_response_pkt_size = first_data_packet2_size ; + + pop3_response[11].pop3_response_pkt_data = &second_data_packet2[0]; + pop3_response[11].pop3_response_pkt_size = second_data_packet2_size ; + + pop3_response[12].pop3_response_pkt_data = &last_data_packet2[0]; + pop3_response[12].pop3_response_pkt_size = last_data_packet2_size ; + + pop3_response[13].pop3_response_pkt_data = &dele_ok2[0]; + pop3_response[13].pop3_response_pkt_size = dele_ok2_size ; + + + pop3_response[14].pop3_response_pkt_data = &quit_ok[0]; + pop3_response[14].pop3_response_pkt_size = quit_ok_size ; + + return NX_SUCCESS; +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pop3_two_mails_received_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: POP3 Two Mail Items Received Test.........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ppp_test/netx_ppp_IPCP_abnormal_packet_test.c b/test/regression/ppp_test/netx_ppp_IPCP_abnormal_packet_test.c new file mode 100644 index 00000000..6490641b --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_IPCP_abnormal_packet_test.c @@ -0,0 +1,279 @@ +/* This demo tests the abnormal IPCP packet. + +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_check; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_PPP ppp_0; +static NX_PPP ppp_1; +static UINT checkpoint; + + +/* Define the counters used in the demo application... */ + +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG error_counter = 0; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_check_entry(ULONG thread_input); +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static void ppp_0_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_IPCP_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the check thread. */ + tx_thread_create(&thread_check, "thread check", thread_check_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, + &pool_0, nx_ppp_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); +} + +static char ipcp_data_0[] = { +0x80, 0x21, 0x01, 0x07, 0x00, 0x16, +0x81, 0x06, 0x00, 0x00, 0x00, 0x00, +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, +0x83, 0x06, 0x00, 0x00, 0x00, 0x00 +}; + +static char ipcp_data_1[] = { +0x80, 0x21, 0x01, 0x07, 0x00, 0x4C, +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, +0x03, 0x06, 0x00, 0x00, 0x00, 0x00, +0x81, 0x06, 0x00, 0x00, 0x00, 0x00, +0x83, 0x06, 0x00, 0x00, 0x00, 0x00 +}; + +extern void _nx_ppp_receive_packet_process(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr); + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *packet_ptr; +UINT i = 0; +UCHAR *data_ptr; +UINT data_size; + + + /* Print out test information banner. */ + printf("NetX Test: PPP IPCP Abnormal Packet Test............................."); + + if (error_counter) + { + printf("ERROR\n"); + test_control_return(1); + } + + checkpoint = NX_FALSE; + tx_thread_resume(&thread_check); + + for (i = 0; i < 2; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &packet_ptr, 0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + if (i == 0) + { + + /* NX_PPP_DNS_SERVER_OPTION before NX_PPP_IP_ADDRESS_OPTION. */ + data_ptr = ipcp_data_0; + data_size = sizeof(ipcp_data_0); + } + else + { + + /* Option length exceed the NX_PPP_OPTION_MESSAGE_LENGTH. */ + data_ptr = ipcp_data_1; + data_size = sizeof(ipcp_data_1); + } + + /* Write IPCP data into the packet payload. */ + nx_packet_data_append(packet_ptr, data_ptr, data_size, &pool_0, TX_WAIT_FOREVER); + + ppp_0.nx_ppp_ipcp_state = NX_PPP_IPCP_CONFIGURE_REQUEST_ACKED_STATE; + + /* Call PPP packet process function. */ + _nx_ppp_receive_packet_process(&ppp_0, packet_ptr); + + if ((i == 0) && (ppp_0.nx_ppp_peer_naked_list[0] != 18)) + { + error_counter++; + } + } + + checkpoint = NX_TRUE; + nx_ppp_delete(&ppp_0); +} + + +static void thread_check_entry(ULONG thread_input) +{ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((checkpoint != NX_TRUE) || error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + + error_counter++; + nx_packet_release(packet_ptr); +} + + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + ppp_0_link_up_counter++; +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + ppp_0_link_down_counter++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_IPCP_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP IPCP Abnormal Packet Test........................................N/A\n"); + + test_control_return(3); +} +#endif + + + diff --git a/test/regression/ppp_test/netx_ppp_IPCP_nak_test.c b/test/regression/ppp_test/netx_ppp_IPCP_nak_test.c new file mode 100644 index 00000000..bc6a4aff --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_IPCP_nak_test.c @@ -0,0 +1,490 @@ +/* This tests that in NX_PPP_IPCP_CONFIGURE_REQUEST_ACKED_STATE state, we can send the correct NAK. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 +#define DEMO_DATA "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; + +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_PPP ppp_0; +static NX_PPP ppp_1; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_up_counter; +static ULONG ppp_1_link_down_counter; +static UINT error_counter = 0; +static UINT thread_1_alive = NX_TRUE; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static UINT generate_login(CHAR *name, CHAR *password); +static UINT verify_login(CHAR *name, CHAR *password); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_IPCP_nak_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP 0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_pap_enable(&ppp_0, NX_NULL, verify_login); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP 1", &ip_1, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_1, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the since it generates the name and password for the peer. */ + status = nx_ppp_pap_enable(&ppp_1, generate_login, NX_NULL); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); + nx_udp_enable(&ip_1); +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: PPP IPCP NAK Test........................................."); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the link to come up. */ + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 30 * NX_IP_PERIODIC_RATE); + + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Disable checksum logic for this socket. */ + nx_udp_socket_checksum_disable(&socket_0); + + /* Let receiver thread run. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + nx_packet_data_append(my_packet, DEMO_DATA, sizeof(DEMO_DATA), &pool_0, TX_WAIT_FOREVER); + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + while(thread_1_alive) + tx_thread_sleep(50); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; + + /* Wait for the link to come up. */ + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 30 * NX_IP_PERIODIC_RATE); + + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + thread_1_alive = NX_FALSE; + + return; +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ +static UCHAR temp_data[8] = {0}; +static UCHAR temp_index = 0; +static UINT i = 0; +static UINT packet_drop = NX_FALSE; + +static UCHAR configure_request[] = {0x7E, 0xFF, 0x7D, 0x23, 0x80, 0x21, 0x7D, 0x21}; + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Discard IPCP Configure Request before NX_PPP_IPCP_CONFIGURE_REQUEST_ACKED_STATE. */ + if (ppp_0.nx_ppp_ipcp_state > NX_PPP_IPCP_INITIAL_STATE && + ppp_0.nx_ppp_ipcp_state < NX_PPP_IPCP_CONFIGURE_REQUEST_ACKED_STATE) + { + + if (byte == 0x7e) + { + + if (temp_index == 0) + { + packet_drop = NX_TRUE; + i = 0; + } + else + { + temp_index = 0; + } + } + + if (temp_index < 8) + { + temp_data[temp_index++] = byte; + } + else if (memcmp(temp_data, configure_request, 8) != 0) + { + packet_drop = NX_FALSE; + } + + if (packet_drop) + { + return; + } + else + { + for (;i < temp_index; i++) + { + nx_ppp_byte_receive(&ppp_0, temp_data[i]); + } + } + } + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} + + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_up_counter++; + else + ppp_1_link_up_counter++; +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_down_counter++; + else + ppp_1_link_down_counter++; + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); +} + + +static UINT generate_login(CHAR *name, CHAR *password) +{ + + /* Make a name and password, called "myname" and "mypassword". */ + name[0] = 'm'; + name[1] = 'y'; + name[2] = 'n'; + name[3] = 'a'; + name[4] = 'm'; + name[5] = 'e'; + name[6] = (CHAR) 0; + + password[0] = 'm'; + password[1] = 'y'; + password[2] = 'p'; + password[3] = 'a'; + password[4] = 's'; + password[5] = 's'; + password[6] = 'w'; + password[7] = 'o'; + password[8] = 'r'; + password[9] = 'd'; + password[10] = (CHAR) 0; + + return(NX_SUCCESS); +} + + +static UINT verify_login(CHAR *name, CHAR *password) +{ + +if ((name[0] == 'm') && + (name[1] == 'y') && + (name[2] == 'n') && + (name[3] == 'a') && + (name[4] == 'm') && + (name[5] == 'e') && + (name[6] == (CHAR) 0) && + (password[0] == 'm') && + (password[1] == 'y') && + (password[2] == 'p') && + (password[3] == 'a') && + (password[4] == 's') && + (password[5] == 's') && + (password[6] == 'w') && + (password[7] == 'o') && + (password[8] == 'r') && + (password[9] == 'd') && + (password[10] == (CHAR) 0)) + return(NX_SUCCESS); + else + return(NX_PPP_ERROR); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_IPCP_nak_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP IPCP NAK Test.........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ppp_test/netx_ppp_IPCP_retransmit_test.c b/test/regression/ppp_test/netx_ppp_IPCP_retransmit_test.c new file mode 100644 index 00000000..7d5edb19 --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_IPCP_retransmit_test.c @@ -0,0 +1,425 @@ +/* This tests that in NX_PPP_IPCP_CONFIGURE_REQUEST_ACKED_STATE state, we can send the correct NAK. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 +#define DEMO_DATA "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; + +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_PPP ppp_0; +static NX_PPP ppp_1; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_up_counter; +static ULONG ppp_1_link_down_counter; +static UINT error_counter = 0; +static UINT thread_1_alive = NX_TRUE; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_IPCP_retransmit_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP 0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP 1", &ip_1, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_1, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); + nx_udp_enable(&ip_1); +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; + + /* Print out test information banner. */ + printf("NetX Test: PPP IPCP Retransmit Test.................................."); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the link to come up. */ + status = nx_ip_status_check(&ip_0, NX_IP_ADDRESS_RESOLVED, &ip_status, 30 * NX_IP_PERIODIC_RATE); + + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Disable checksum logic for this socket. */ + nx_udp_socket_checksum_disable(&socket_0); + + /* Let receiver thread run. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Write ABCs into the packet payload! */ + nx_packet_data_append(my_packet, DEMO_DATA, sizeof(DEMO_DATA), &pool_0, TX_WAIT_FOREVER); + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + while(thread_1_alive) + tx_thread_sleep(50); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; + + /* Wait for the link to come up. */ + status = nx_ip_status_check(&ip_1, NX_IP_ADDRESS_RESOLVED, &ip_status, 30 * NX_IP_PERIODIC_RATE); + + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + thread_1_alive = NX_FALSE; + + return; +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ +static UCHAR temp_data[8] = {0}; +static UCHAR temp_index = 0; +static UINT i = 0; +static UINT packet_drop = NX_FALSE; +static UINT packet_end = NX_FALSE; + +static UCHAR configure_request_ack[] = {0x7E, 0xFF, 0x7D, 0x23, 0xc0, 0x21, 0x7D, 0x22}; + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Discard LCP Configure Request ACK before NX_PPP_IPCP_CONFIGURE_REQUEST_SENT_STATE. */ + if (ppp_0.nx_ppp_ipcp_state < NX_PPP_IPCP_CONFIGURE_REQUEST_SENT_STATE) + { + + if (byte == 0x7e) + { + + if (temp_index == 0) + { + packet_drop = NX_TRUE; + packet_end = NX_FALSE; + i = 0; + } + else + { + packet_end = NX_TRUE; + } + } + + if (temp_index < 8) + { + temp_data[temp_index++] = byte; + } + else if (memcmp(temp_data, configure_request_ack, 8) != 0) + { + packet_drop = NX_FALSE; + } + + if (packet_drop) + { + if (packet_end) + temp_index = 0; + return; + } + else + { + for (;i < temp_index; i++) + { + nx_ppp_byte_receive(&ppp_1, temp_data[i]); + } + + if (packet_end) + temp_index = 0; + } + } + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} + + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_up_counter++; + else + ppp_1_link_up_counter++; +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_down_counter++; + else + ppp_1_link_down_counter++; + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_IPCP_retransmit_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP IPCP retransmit Test..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ppp_test/netx_ppp_IPCP_timeout.c b/test/regression/ppp_test/netx_ppp_IPCP_timeout.c new file mode 100644 index 00000000..2c0a6d7e --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_IPCP_timeout.c @@ -0,0 +1,362 @@ +/* This demo tests the nx_ppp_restart() function. To simulate a link down in the middle of the IPCP + negotiation, the thread_0/PPP_0 promotes the PPP 1 instance to LCP complete, and its IPCP state to STARTED. + Then the PPP0 instance is suspended as part of simulating link down. + + PPP_1 should go into a FAILED state after the max number of retries, and call the link down callback. + NetX PPP has a restart function which reinitializes the PPP instance so it can restart the PPP + protocol using nx_ppp_restart(). + + The process is started again, PPP 0 is resumed, and thread 0 promotes the PPP 1 instance ahead + to the LCP complete state, and ICP start state. After the second link down event, the test is complete. + + This test verifies that the NetX PPP properly clears and restarts a PPP instance, including resetting + the PPP state to restart the IPCP negotiation. +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; + +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_PPP ppp_0; +static NX_PPP ppp_1; + + +/* Define the counters used in the demo application... */ + +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_up_counter; +static ULONG ppp_1_link_down_counter; +static ULONG error_counter = 0; +static UINT suspend_thread = NX_TRUE; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_IPCP_timeout_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pointer, 8192); + pointer = pointer + 8192; + status += nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 4096); + pointer = pointer + 4096; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define the IP addresses. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP1", &ip_1, pointer, 2048, 1, &pool_1, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_1, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_1, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); + nx_udp_enable(&ip_1); + + /* Enable ICMP traffic. */ + nx_icmp_enable(&ip_0); + nx_icmp_enable(&ip_1); + +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + /* Print out test information banner. */ + printf("NetX Test: PPP IPCP Timeout/Restart Test............................."); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + do + { + + if (suspend_thread) + { + + if (ppp_1.nx_ppp_lcp_state >= 2) + { + + suspend_thread = NX_FALSE; + + /* PPP_1 is in the LCP completed state. Suspend PPP_0 thread so PPP_1 will not be able + to complete the IPCP protocol. */ + tx_thread_suspend(&(ppp_0.nx_ppp_thread)); + + ppp_1.nx_ppp_timeout = NX_PPP_PROTOCOL_TIMEOUT; + ppp_1.nx_ppp_lcp_state = NX_PPP_LCP_COMPLETED_STATE; + ppp_1.nx_ppp_ipcp_state = NX_PPP_IPCP_START_STATE; + + } + + } + + /* Determine if the two or more restarts have occurred */ + if (ppp_1_link_down_counter >= 2) + { + break; + } + + /* Wait for the link to come up (this should not happen if we are + testing the link down callback. */ + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, NX_IP_PERIODIC_RATE/2); + + } while (status != NX_SUCCESS) ; + + /* Determine if the test completed successfully. */ + if ((error_counter == 0) && (ppp_0_link_down_counter == 0) && (ppp_1_link_down_counter >= 2)) + { + printf("SUCCESS!\n"); + test_control_return(0); + } + else + { + printf("ERROR!\n"); + test_control_return(1); + } + +} + + +static void thread_1_entry(ULONG thread_input) +{ + + +UINT status; +ULONG ip_status; + + tx_thread_sleep(20); + do + { + + /* If this is the second restart, the test is complete. */ + if (ppp_1_link_down_counter > 1) + { + + return; + } + + /* Wait for the link to come up. */ + status = nx_ip_status_check(&ip_1, NX_IP_LINK_ENABLED, &ip_status, NX_IP_PERIODIC_RATE/2); + + } while (status != NX_SUCCESS); + +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + + error_counter++; + nx_packet_release(packet_ptr); +} + + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_up_counter++; + else + ppp_1_link_up_counter++; +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_down_counter++; + else + ppp_1_link_down_counter++; + + if (ppp_ptr -> nx_ppp_ipcp_state != NX_PPP_IPCP_FAILED_STATE) + { + /* Error test should only restart from the IPCP FAILED state */ + error_counter++; + return; + } + + /* If this is the second restart, the test is complete. */ + if (ppp_1_link_down_counter > 1) + { + /* Success. Restart test is complete */ + return; + } + + /* Restart PPP 1. */ + nx_ppp_restart(ppp_ptr); + + if (ppp_1_link_down_counter == 1) + { + /* First restart. Wait for second restart to verify first restart succeeds */ + suspend_thread = NX_TRUE; + } + + return; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_IPCP_timeout_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP IPCP Timeout/Restart Test.............................N/A\n"); + + test_control_return(3); +} +#endif + + diff --git a/test/regression/ppp_test/netx_ppp_LCP_invalid_packet_test.c b/test/regression/ppp_test/netx_ppp_LCP_invalid_packet_test.c new file mode 100644 index 00000000..13581c2a --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_LCP_invalid_packet_test.c @@ -0,0 +1,238 @@ +/* This demo tests the invalid LCP packet. + +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_PPP ppp_0; +static NX_PPP ppp_1; + + +/* Define the counters used in the demo application... */ + +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG error_counter = 0; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static void ppp_0_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_LCP_invalid_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, + &pool_0, nx_ppp_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); +} + +static char invalid_lcp_data_0[] = {0xc0, 0x21, 0x01, 0x1e, 0x00, 0x00}; +static char invalid_lcp_data_1[] = {0xc0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x02, 0x16}; +extern void _nx_ppp_receive_packet_process(NX_PPP *ppp_ptr, NX_PACKET *packet_ptr); + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_PACKET *invalid_packet; +UINT i = 0; +UCHAR *data_ptr; +UINT data_size; + + + /* Print out test information banner. */ + printf("NetX Test: PPP LCP Invalid Packet Test..............................."); + + if (error_counter) + { + printf("ERROR\n"); + test_control_return(1); + } + + for (i = 0; i < 2; i++) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &invalid_packet, NX_IP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + error_counter++; + + if (i == 0) + { + + /* Invalid NX_PPP_LCP_CONFIGURE_REQUEST. */ + data_ptr = invalid_lcp_data_0; + data_size = sizeof(invalid_lcp_data_0); + } + else + { + + /* Invalid unsupported code ID. */ + data_ptr = invalid_lcp_data_1; + data_size = sizeof(invalid_lcp_data_1); + } + + /* Write invalid data into the packet payload. */ + nx_packet_data_append(invalid_packet, data_ptr, data_size, &pool_0, TX_WAIT_FOREVER); + + /* Call PPP packet process function. */ + _nx_ppp_receive_packet_process(&ppp_0, invalid_packet); + } + + if (ppp_0.nx_ppp_lcp_frames_received != 0) + { + error_counter++; + } + + /* Check status. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + nx_ppp_delete(&ppp_0); + test_control_return(0); + +} + + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + + error_counter++; + nx_packet_release(packet_ptr); +} + + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + ppp_0_link_up_counter++; +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + ppp_0_link_down_counter++; + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_LCP_invalid_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP LCP Invalid Packet Test...............................N/A\n"); + + test_control_return(3); +} +#endif + + + diff --git a/test/regression/ppp_test/netx_ppp_LCP_timeout.c b/test/regression/ppp_test/netx_ppp_LCP_timeout.c new file mode 100644 index 00000000..c8f786de --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_LCP_timeout.c @@ -0,0 +1,233 @@ +/* This demo tests the nx_ppp_restart() function. The PPP_1 instance is never started. + So PPP_0 fails to complete the LCP protocol. After so many attempts at the LCP + protocol, the PPP_0 should go into a FAILED state and call the link down callback. + NetX PPP has a restart function which reinitializes the PPP instance so it can + restart the PPP protocol again. + + This test runs until the second link down event occurs. This is considered a successful + outcome because it verifies the NetX PPP properly resets the LCP state, removes packets on + the receive queue, resets the buffer markers, and clears authentication status. + +*/ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_PPP ppp_0; +static NX_PPP ppp_1; + + +/* Define the counters used in the demo application... */ + +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG error_counter = 0; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static void ppp_0_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_LCP_timeout_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, + &pool_0, nx_ppp_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + + /* Print out test information banner. */ + printf("NetX Test: PPP LCP Timeout/Restart Test.............................."); + + if (error_counter) + { + printf("ERROR\n"); + test_control_return(1); + } + + do + { + + /* Wait for the link to come up. */ + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, NX_IP_PERIODIC_RATE); + + if (ppp_0_link_down_counter > 1) + { + /* Deleting the PPP_0 instance. Test is complete. */ + status = NX_SUCCESS; + break; + } + } while (status != NX_SUCCESS); + + + /* Check status. */ + if ((status) || (error_counter) || (ppp_0_link_down_counter != 2)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + printf("SUCCESS!\n"); + nx_ppp_delete(&ppp_0); + test_control_return(0); + +} + + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + + error_counter++; + nx_packet_release(packet_ptr); +} + + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + ppp_0_link_up_counter++; +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + ppp_0_link_down_counter++; + + if (ppp_ptr -> nx_ppp_protocol_retry_counter != NX_PPP_MAX_LCP_PROTOCOL_RETRIES) + { + /* Error with retry counter */ + error_counter++; + } + else if (ppp_ptr -> nx_ppp_lcp_state != NX_PPP_LCP_FAILED_STATE) + { + + /* Error: the PPP is not in the LCP failed state */ + error_counter++; + } + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); + + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_LCP_timeout_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP LCP Timeout/Restart Test..............................N/A\n"); + + test_control_return(3); +} +#endif + + + diff --git a/test/regression/ppp_test/netx_ppp_PAP_bad_password_test.c b/test/regression/ppp_test/netx_ppp_PAP_bad_password_test.c new file mode 100644 index 00000000..a9b426ed --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_PAP_bad_password_test.c @@ -0,0 +1,410 @@ +/* This tests 1) that PPP PAP authentication detects a bad password and handles with the NAK callback, + and 2) that the NAK callback permits the user PPP application to change the password and retry + PAP authentication. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; + +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_PPP ppp_0; +static NX_PPP ppp_1; + + +/* Define the counters used in the demo application... */ + +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_up_counter; +static ULONG ppp_1_link_down_counter; +static UINT login_attempts = 0; +static UINT nak_counter = 0; +static UINT error_counter = 0; +static UINT thread_1_alive = NX_TRUE; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static UINT generate_login(CHAR *name, CHAR *password); +static UINT verify_login(CHAR *name, CHAR *password); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); +static void nak_authentication_notify(void); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_PAP_bad_password_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP 0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_pap_enable(&ppp_0, NX_NULL, verify_login); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + status = nx_ppp_nak_authentication_notify(&ppp_0, nak_authentication_notify); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP 1", &ip_1, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_1, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the since it generates the name and password for the peer. */ + status = nx_ppp_pap_enable(&ppp_1, generate_login, NX_NULL); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + status = nx_ppp_nak_authentication_notify(&ppp_1, nak_authentication_notify); + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); + nx_udp_enable(&ip_1); + +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + /* Print out test information banner. */ + printf("NetX Test: PPP PAP Bad Password Test................................."); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + + /* Check status. */ + if ((status) || (ppp_0.nx_ppp_authenticated == 0) || (ppp_1.nx_ppp_authenticated == 0) || + (nak_counter != 1) || (login_attempts != 2) || + (ppp_0_link_up_counter != 1) || (ppp_1_link_up_counter != 1) || + (ppp_0_link_down_counter != 0) || (ppp_1_link_down_counter != 0) || + (error_counter)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete PPP 0, CHAP complete, we don't need to finish IPCP handshake.. */ + nx_ppp_delete(&ppp_0); + + while(thread_1_alive) + tx_thread_sleep(50); + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + tx_thread_sleep(50); + + thread_1_alive = NX_FALSE; + + return; + +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} + + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_up_counter++; + else + ppp_1_link_up_counter++; +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_down_counter++; + else + ppp_1_link_down_counter++; + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); +} + + +static UINT generate_login(CHAR *name, CHAR *password) +{ + + if (login_attempts == 0) + { + /* Input a name and wrong password, called "myname" and "mypasswordd". */ + name[0] = 'm'; + name[1] = 'y'; + name[2] = 'n'; + name[3] = 'a'; + name[4] = 'm'; + name[5] = 'e'; + name[6] = (CHAR) 0; + + password[0] = 'm'; + password[1] = 'y'; + password[2] = 'p'; + password[3] = 'a'; + password[4] = 's'; + password[5] = 's'; + password[6] = 'w'; + password[7] = 'o'; + password[8] = 'r'; + password[9] = 'd'; + password[10] = 'd'; /* This password will not match the one in verify login; PAP should fail. */ + password[11] = (CHAR) 0; + } + else /* if (login_attempts >= 1) */ + { + + /* Try a corrected password, called "myname" and "mypassword". */ + name[0] = 'm'; + name[1] = 'y'; + name[2] = 'n'; + name[3] = 'a'; + name[4] = 'm'; + name[5] = 'e'; + name[6] = (CHAR) 0; + + password[0] = 'm'; + password[1] = 'y'; + password[2] = 'p'; + password[3] = 'a'; + password[4] = 's'; + password[5] = 's'; + password[6] = 'w'; + password[7] = 'o'; + password[8] = 'r'; + password[9] = 'd'; + password[10] = (CHAR) 0; + } + + login_attempts++; + + return(NX_SUCCESS); +} + + +static UINT verify_login(CHAR *name, CHAR *password) +{ + +if ((name[0] == 'm') && + (name[1] == 'y') && + (name[2] == 'n') && + (name[3] == 'a') && + (name[4] == 'm') && + (name[5] == 'e') && + (name[6] == (CHAR) 0) && + (password[0] == 'm') && + (password[1] == 'y') && + (password[2] == 'p') && + (password[3] == 'a') && + (password[4] == 's') && + (password[5] == 's') && + (password[6] == 'w') && + (password[7] == 'o') && + (password[8] == 'r') && + (password[9] == 'd') && + (password[10] == (CHAR) 0)) + return(NX_SUCCESS); + else + return(NX_PPP_ERROR); +} + +static void nak_authentication_notify(void) +{ + + nak_counter ++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_PAP_bad_password_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP PAP Bad Password Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ppp_test/netx_ppp_PAP_bad_username_test.c b/test/regression/ppp_test/netx_ppp_PAP_bad_username_test.c new file mode 100644 index 00000000..578208a8 --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_PAP_bad_username_test.c @@ -0,0 +1,413 @@ +/* This tests 1) that PPP PAP authentication detects a bad username and handles with the NAK callback, + and 2) that the NAK callback permits the user PPP application to change the username and retry + PAP authentication. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define the PPP_REGRESSION_TEST option to run in regression test environment. */ + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; + +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_PPP ppp_0; +static NX_PPP ppp_1; + + +/* Define the counters used in the demo application... */ + +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_up_counter; +static ULONG ppp_1_link_down_counter; +static UINT login_attempts = 0; +static UINT nak_counter = 0; +static UINT thread_1_alive = NX_TRUE; +static UINT error_counter = 0; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static UINT generate_login(CHAR *name, CHAR *password); +static UINT verify_login(CHAR *name, CHAR *password); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); +static void nak_authentication_notify(void); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_PAP_bad_username_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP 0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_pap_enable(&ppp_0, NX_NULL, verify_login); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + status = nx_ppp_nak_authentication_notify(&ppp_0, nak_authentication_notify); + + if (status) + error_counter++; + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, + &pool_0, nx_ppp_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + error_counter++; + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP 1", &ip_1, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_1, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the since it generates the name and password for the peer. */ + status = nx_ppp_pap_enable(&ppp_1, generate_login, NX_NULL); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + status = nx_ppp_nak_authentication_notify(&ppp_1, nak_authentication_notify); + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, + &pool_0, nx_ppp_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP error */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); + nx_udp_enable(&ip_1); +} + + +/* Define the test threads. */ + +void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + /* Print out test information banner. */ + printf("NetX Test: PPP PAP Bad Username Test................................."); + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + /* Check status. */ + if ((status) || (nak_counter != 1) || (login_attempts != 2) || + (ppp_0_link_up_counter != 1) || (ppp_1_link_up_counter != 1) || + (ppp_0_link_down_counter != 0) || (ppp_1_link_down_counter != 0) || + (error_counter)) + { + printf("ERROR!\n"); + test_control_return(1); + } + while (thread_1_alive) + { + tx_thread_sleep(50); + } + /* Delete PPP 0, PAP failed, we don't need to finish IPCP handshake.. */ + status = nx_ppp_delete(&ppp_0); + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + tx_thread_sleep(20); + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_1, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + tx_thread_sleep(50); + thread_1_alive = NX_FALSE; + + return; + +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} + + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_up_counter++; + else + ppp_1_link_up_counter++; +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_down_counter++; + else + ppp_1_link_down_counter++; + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); +} + + +static UINT generate_login(CHAR *name, CHAR *password) +{ + + if (login_attempts == 0) + { + /* Input a wrong username and good password, called "yname" and "mypassword". */ + name[0] = 'y'; /* This username will not match the one in verify login; PAP should fail. */ + name[1] = 'n'; + name[2] = 'a'; + name[3] = 'm'; + name[4] = 'e'; + name[5] = (CHAR) 0; + + password[0] = 'm'; + password[1] = 'y'; + password[2] = 'p'; + password[3] = 'a'; + password[4] = 's'; + password[5] = 's'; + password[6] = 'w'; + password[7] = 'o'; + password[8] = 'r'; + password[9] = 'd'; + password[10] = 'd'; + password[11] = (CHAR) 0; + } + else /* if (login_attempts >= 1)*/ + { + + /* Try a corrected username, called "myname" and "mypassword". */ + name[0] = 'm'; + name[1] = 'y'; + name[2] = 'n'; + name[3] = 'a'; + name[4] = 'm'; + name[5] = 'e'; + name[6] = (CHAR) 0; + + password[0] = 'm'; + password[1] = 'y'; + password[2] = 'p'; + password[3] = 'a'; + password[4] = 's'; + password[5] = 's'; + password[6] = 'w'; + password[7] = 'o'; + password[8] = 'r'; + password[9] = 'd'; + password[10] = (CHAR) 0; + } + + login_attempts++; + + return(NX_SUCCESS); +} + + +static UINT verify_login(CHAR *name, CHAR *password) +{ + +if ((name[0] == 'm') && + (name[1] == 'y') && + (name[2] == 'n') && + (name[3] == 'a') && + (name[4] == 'm') && + (name[5] == 'e') && + (name[6] == (CHAR) 0) && + (password[0] == 'm') && + (password[1] == 'y') && + (password[2] == 'p') && + (password[3] == 'a') && + (password[4] == 's') && + (password[5] == 's') && + (password[6] == 'w') && + (password[7] == 'o') && + (password[8] == 'r') && + (password[9] == 'd') && + (password[10] == (CHAR) 0)) + return(NX_SUCCESS); + else + return(NX_PPP_ERROR); +} + +static void nak_authentication_notify(void) +{ + nak_counter ++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_PAP_bad_username_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP PAP Bad Username Test.................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/ppp_test/netx_ppp_acfc_option_test.c b/test/regression/ppp_test/netx_ppp_acfc_option_test.c new file mode 100644 index 00000000..ab4abc28 --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_acfc_option_test.c @@ -0,0 +1,431 @@ +/* This tests the processing of compressed Access and Control fields. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_PPP_COMPRESSION_ENABLE) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 +#define DEMO_DATA "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_PPP ppp_0; +static NX_PPP ppp_1; +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT thread_1_alive = NX_TRUE; +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_up_counter; +static ULONG ppp_1_link_down_counter; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static UINT generate_login(CHAR *name, CHAR *password); +static UINT verify_login(CHAR *name, CHAR *password); + +/* UDP packet data with Access and Control fields compressed. +00 21 45 00 00 38 00 21 00 00 80 11 32 a8 01 02 03 05 01 02 03 04 00 89 00 88 00 24 e9 8e 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 20 00 +*/ +static UCHAR udp_data[] = { +0x7e, 0x7d, 0x20, 0x21, 0x45, 0x7d, 0x20, 0x7d, 0x20, 0x38, 0x7d, 0x20, 0x7d, +0x21, 0x7d, 0x20, 0x7d, 0x20, 0x80, 0x7d, 0x31, 0x32, 0xa8, 0x7d, 0x21, 0x7d, 0x22, 0x7d, 0x23, +0x7d, 0x24, 0x7d, 0x21, 0x7d, 0x22, 0x7d, 0x23, 0x7d, 0x25, 0x7d, 0x20, 0x88, 0x7d, 0x20, 0x89, +0x7d, 0x20, 0x24, 0x7d, 0x20, 0x7d, 0x20, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, +0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, +0x5a, 0x20, 0x7d, 0x20, 0x6f, 0x5e, 0x7e, +}; + +static UINT udp_data_send = NX_FALSE; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_acfc_option_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 2 * NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + { + error_counter++; + } + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP 0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + { + error_counter++; + } + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + { + error_counter++; + } + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + { + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + { + error_counter++; + } + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP 1", &ip_1, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + { + error_counter++; + } + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + { + error_counter++; + } + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_1, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + { + error_counter++; + } + + /* Create another IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + if (status) + { + error_counter++; + } +} + + +/* Define the test threads. */ + +void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; + + + printf("NetX Test: PPP ACFC Option Test......................................"); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Disable checksum logic for this socket. */ + nx_udp_socket_checksum_disable(&socket_0); + + /* Let receiver thread run. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Write ABCs into the packet payload! */ + nx_packet_data_append(my_packet, DEMO_DATA, sizeof(DEMO_DATA), &pool_0, NX_WAIT_FOREVER); + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Relinquish to thread 1. */ + tx_thread_relinquish(); + + /* Wait for the other thread to finish. */ + while(thread_1_alive) + { + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; + + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_1, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + thread_1_alive = NX_FALSE; + return; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + thread_1_alive = NX_FALSE; + return; + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + } + + thread_1_alive = NX_FALSE; + + return; + +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ +UINT i; + + if (ppp_0.nx_ppp_ipcp_state < NX_PPP_IPCP_COMPLETED_STATE) + { + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); + } + else if (udp_data_send == NX_FALSE) + { + /* Modify the data to send compressed protocol field. */ + for (i = 0; i < sizeof(udp_data); i++) + { + nx_ppp_byte_receive(&ppp_1, udp_data[i]); + } + + udp_data_send = NX_TRUE; + } +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_up_counter++; + else + ppp_1_link_up_counter++; +} + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_down_counter++; + else + ppp_1_link_down_counter++; + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_acfc_option_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP ACFC Option Test......................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/ppp_test/netx_ppp_chap_bad_secret_failed_retry_test.c b/test/regression/ppp_test/netx_ppp_chap_bad_secret_failed_retry_test.c new file mode 100644 index 00000000..c4fac994 --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_chap_bad_secret_failed_retry_test.c @@ -0,0 +1,430 @@ +/* This is a test of the NetX Duo PPP CHAP authentication protocol. ppp_1 + has a different secret than ppp_0, therefore ppp_1 who is trying + to authenticate itself with ppp_0, needs to handle the NAK authentication failure. + In this test, both PPP instances restart() when notified of NAK/CHAP failure. PPP1 + reloads the responder value with the same secret and should not succeed on the next + CHAP authentication challenges. However it should be able to abort further attempts + after a certain number of retries (2). + */ + +#include "nx_ppp.h" +#include "tx_api.h" +#include "nx_api.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; + +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_PPP ppp_0; +static NX_PPP ppp_1; + +/* Define the counters used in the demo application... */ + +static UINT ppp_0_retry_counter = 0; +static UINT ppp_1_retry_counter = 0; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_down_counter; +static UINT get_values_counter = 0; +static UINT nak_counter = 0; +static UINT nak_authentication_failed = NX_FALSE; +static UINT error_counter = 0; + + +static CHAR name_string[] = "username"; +static CHAR name_string_ppp1[] = "username"; // testing bad chap value; this makes no difference +static CHAR rand_value_string[] = "1234567"; +static CHAR system_string[] = "system"; +static CHAR system_string_ppp1[] = "system"; // testing bad chap value; this makes no difference +static CHAR secret_string[] = "secret"; +static CHAR secret_string_ppp1[] = "secret0"; // testing bad chap value; this mismatch will cause CHAP failure + + + +static UINT get_challenge_values(CHAR *rand_value, CHAR *id, CHAR *name); +static UINT get_responder_values(CHAR *system, CHAR *name, CHAR *secret); +static UINT get_responder_values_ppp1(CHAR *system, CHAR *name, CHAR *secret); +static UINT get_verification_values(CHAR *system, CHAR *name, CHAR *secret); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static void nak_authentication_notify(void); + +/* Define thread prototype. */ +static void thread_0_entry(ULONG thread_input); + +/* Define what the initial system looks like. */ + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_chap_bad_secret_failed_retry_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool for ppp_0. */ + status = nx_packet_pool_create(&pool_0, "Packet Pool 0", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check status. */ + if (status) + error_counter++; + + /* Create a packet pool for ppp_1. */ + status = nx_packet_pool_create(&pool_1, "Packet Pool 1", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check status. */ + if (status) + error_counter++; + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check status. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Setup CHAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_chap_enable(&ppp_0, get_challenge_values, get_responder_values, get_verification_values); + + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + status += nx_ppp_nak_authentication_notify(&ppp_0, nak_authentication_notify); + + /* Check status. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check status. */ + if (status) + error_counter++; + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP1", &ip_1, pointer, 2048, 1, &pool_1, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check status. */ + if (status) + error_counter++; + + /* Setup CHAP, this PPP instance will only respond to CHAP challenges. */ + status = nx_ppp_chap_enable(&ppp_1, NX_NULL, get_responder_values_ppp1, NX_NULL); + + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + status += nx_ppp_nak_authentication_notify(&ppp_1, nak_authentication_notify); + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status += nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check status. */ + if (status) + error_counter++; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check status. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); + nx_udp_enable(&ip_1); + +} + +#define SEND_MESSAGE "1234567890123456789012345678901234567890123456789012345678901234567890ABCDEFGHIJ123456" + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + + /* Print out test information banner. */ + printf("NetX Test: PPP Chap Bad Secret Failed Retry Test....................."); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the link to come up and then realize PAP has failed. */ + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if ((status != NX_NOT_SUCCESSFUL) || (ppp_0.nx_ppp_authenticated == 1) || (ppp_1.nx_ppp_authenticated == 1) || + (nak_authentication_failed != NX_TRUE) || (nak_counter != 2) || + (get_values_counter != 2) || (ppp_0_link_down_counter != 2) || + (ppp_0_retry_counter != 2) || (ppp_1_link_down_counter != 2) || + (ppp_1_retry_counter != 2) || (error_counter)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete PPP 0, CHAP failed, we don't need to finish IPCP handshake.. */ + nx_ppp_delete(&ppp_0); + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + + +/* Define the CHAP enable routines. */ +static UINT get_challenge_values(CHAR *rand_value, CHAR *id, CHAR *name) +{ + +UINT i; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + name[i] = name_string[i]; + } + name[i] = 0; + + *id = '1'; /* One byte */ + + for (i = 0; i< (NX_PPP_VALUE_SIZE-1); i++) + { + rand_value[i] = rand_value_string[i]; + } + rand_value[i] = 0; + + return(NX_SUCCESS); +} + +static UINT get_responder_values(CHAR *system, CHAR *name, CHAR *secret) +{ + +UINT i; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + name[i] = name_string[i]; + } + name[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + system[i] = system_string[i]; + } + system[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + secret[i] = secret_string[i]; + } + secret[i] = 0; + + return(NX_SUCCESS); +} + +/* Get PPP_1's idea of username/secret/system */ +static UINT get_responder_values_ppp1(CHAR *system, CHAR *name, CHAR *secret) +{ + +UINT i; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + name[i] = name_string_ppp1[i]; + } + name[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + system[i] = system_string_ppp1[i]; + } + system[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + + /* Keep setting the bad secret. */ + secret[i] = secret_string_ppp1[i]; + } + + secret[i] = 0; + + get_values_counter++; + + return(NX_SUCCESS); +} + +static UINT get_verification_values(CHAR *system, CHAR *name, CHAR *secret) +{ + +UINT i; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + name[i] = name_string[i]; + } + name[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + system[i] = system_string[i]; + } + system[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + secret[i] = secret_string[i]; + } + secret[i] = 0; + + return(NX_SUCCESS); +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + { + + ppp_0_link_down_counter++; + ppp_0_retry_counter++; + + /* In reality we'd probably try three times */ + if (ppp_0_retry_counter >= 2) + { + /* Error. */ + nak_authentication_failed = NX_TRUE; + } + else + { + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); + } + } + else + { + + ppp_1_link_down_counter++; + ppp_1_retry_counter++; + if (ppp_1_retry_counter >= 2) + { + /* Error. */ + nak_authentication_failed = NX_TRUE; + } + else + { + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); + } + } +} + +static void nak_authentication_notify(void) +{ + + nak_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_chap_bad_secret_failed_retry_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP Chap Bad Secret Failed Retry Test.....................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ppp_test/netx_ppp_chap_bad_secret_passed_on_retry_test.c b/test/regression/ppp_test/netx_ppp_chap_bad_secret_passed_on_retry_test.c new file mode 100644 index 00000000..21b2b79f --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_chap_bad_secret_passed_on_retry_test.c @@ -0,0 +1,474 @@ +/* This is a test of the NetX Duo PPP CHAP authentication protocol. ppp_1 + has a different secret than ppp_0, therefore ppp_1 who is trying + to authenticate itself with ppp_0, needs to handle the NAK authentication failure. + In this test, both PPP instances restart() when notified of NAK/CHAP failure. PPP1 + reloads the responder value with the correct secret and should succeed on the next + CHAP authentication challenge. + */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; + +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_PPP ppp_0; +static NX_PPP ppp_1; + +/* Define the counters used in the demo application... */ + +static UINT ppp_0_retry_counter = 0; +static UINT ppp_1_retry_counter = 0; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_down_counter; +static UINT get_values_counter = 0; +static UINT nak_counter = 0; +static UINT nak_authentication_failed = NX_FALSE; +static UINT error_counter = 0; +static UINT thread_1_alive = NX_TRUE; + + +static CHAR name_string[] = "username"; +static CHAR name_string_ppp1[] = "username"; /* testing bad chap value; this makes no difference */ +static CHAR rand_value_string[] = "1234567"; +static CHAR system_string[] = "system"; +static CHAR system_string_ppp1[] = "system"; /* testing bad chap value; this makes no difference */ +static CHAR secret_string[] = "secret"; +static CHAR secret_string_ppp1[] = "secret0"; /* testing bad chap value; this mismatch will cause CHAP failure */ + + +static UINT get_challenge_values(CHAR *rand_value, CHAR *id, CHAR *name); +static UINT get_responder_values(CHAR *system, CHAR *name, CHAR *secret); +static UINT get_responder_values_ppp1(CHAR *system, CHAR *name, CHAR *secret); +static UINT get_verification_values(CHAR *system, CHAR *name, CHAR *secret); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static void nak_authentication_notify(void); + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_chap_bad_secret_passed_on_retry_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool for ppp_0. */ + status = nx_packet_pool_create(&pool_0, "Packet Pool 0", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create a packet pool for ppp_1. */ + status = nx_packet_pool_create(&pool_1, "Packet Pool 1", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Setup CHAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_chap_enable(&ppp_0, get_challenge_values, get_responder_values, get_verification_values); + + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + status += nx_ppp_nak_authentication_notify(&ppp_0, nak_authentication_notify); + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status += nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP CHAP enable error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check status. */ + if (status) + error_counter++; + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP1", &ip_1, pointer, 2048, 1, &pool_1, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + + /* Setup CHAP, this PPP instance will only respond to CHAP challenges. */ + status = nx_ppp_chap_enable(&ppp_1, NX_NULL, get_responder_values_ppp1, NX_NULL); + + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + status += nx_ppp_nak_authentication_notify(&ppp_1, nak_authentication_notify); + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status += nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Create another IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check status. */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); + nx_udp_enable(&ip_1); + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + /* Print out test information banner. */ + printf("NetX Test: PPP Chap Bad Secret Passed on Retry Test.................."); + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + + /* Check status. */ + if ((status) || (!ppp_0.nx_ppp_authenticated) || (!ppp_1.nx_ppp_authenticated) || + (get_values_counter != 2) || (nak_authentication_failed) || + (nak_counter != 1)|| (ppp_0_link_down_counter != 1) || + (ppp_0_retry_counter != 1) || (ppp_1_link_down_counter != 1) || + (ppp_1_retry_counter != 1) || nak_authentication_failed || (!ppp_1.nx_ppp_authenticated) || + (error_counter)) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + while(thread_1_alive) + tx_thread_sleep(50); + + /* Delete PPP 0, CHAP complete, we don't need to finish IPCP handshake.. */ + nx_ppp_delete(&ppp_0); + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_1, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + + /* Delete PPP 1. CHAP complete, we don't need to finish IPCP handshake.. */ + nx_ppp_delete(&ppp_1); + + thread_1_alive = NX_FALSE; + + return; + +} + +/* Define the CHAP enable routines. */ +static UINT get_challenge_values(CHAR *rand_value, CHAR *id, CHAR *name) +{ + +UINT i; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + name[i] = name_string[i]; + } + name[i] = 0; + + *id = '1'; /* One byte */ + + for (i = 0; i< (NX_PPP_VALUE_SIZE-1); i++) + { + rand_value[i] = rand_value_string[i]; + } + rand_value[i] = 0; + + return(NX_SUCCESS); +} + +static UINT get_responder_values(CHAR *system, CHAR *name, CHAR *secret) +{ + +UINT i; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + name[i] = name_string[i]; + } + name[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + system[i] = system_string[i]; + } + system[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + secret[i] = secret_string[i]; + } + secret[i] = 0; + + return(NX_SUCCESS); +} + +/* Get PPP_1's idea of username/secret/system */ +static UINT get_responder_values_ppp1(CHAR *system, CHAR *name, CHAR *secret) +{ + +UINT i; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + name[i] = name_string_ppp1[i]; + } + name[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + system[i] = system_string_ppp1[i]; + } + system[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + + /* Check if we are being asked for the secret for the first time. */ + if (get_values_counter == 0) + { + + /* Yes, start out with the 'bad' secret (CHAP should fail). */ + secret[i] = secret_string_ppp1[i]; + } + else + { + + /* We are not. Try the good secret now. */ + secret[i] = secret_string[i]; + } + + } + + secret[i] = 0; + + get_values_counter++; + + return(NX_SUCCESS); +} + +static UINT get_verification_values(CHAR *system, CHAR *name, CHAR *secret) +{ + +UINT i; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + name[i] = name_string[i]; + } + name[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + system[i] = system_string[i]; + } + system[i] = 0; + + for (i = 0; i< (NX_PPP_NAME_SIZE-1); i++) + { + secret[i] = secret_string[i]; + } + secret[i] = 0; + + return(NX_SUCCESS); +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + { + + ppp_0_link_down_counter++; + ppp_0_retry_counter++; + + /* We'd probably try three times. */ + if (ppp_0_retry_counter >= 2) + { + /* Error */ + ppp_0_retry_counter = 0; + nak_authentication_failed = NX_TRUE; + } + else + { + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); + } + } + else + { + + ppp_1_link_down_counter++; + ppp_1_retry_counter++; + if (ppp_1_retry_counter >= 2) + { + /* Error. */ + ppp_1_retry_counter = 0; + nak_authentication_failed = NX_TRUE; + } + else + { + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); + } + } +} + +static void nak_authentication_notify(void) +{ + + nak_counter++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_chap_bad_secret_passed_on_retry_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP Chap Bad Secret Passed on Retry Test..................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/ppp_test/netx_ppp_check_boundary_test.c b/test/regression/ppp_test/netx_ppp_check_boundary_test.c new file mode 100644 index 00000000..95aab81a --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_check_boundary_test.c @@ -0,0 +1,426 @@ +/* This test should be done with the PACKET CHAIN option enabled. It tests that the PPP instance can + handle receiving chained packets, including when the data, CRC checksum and PPP frame closing sequence + occur on or around the packet buffer boundary. It should run to completion. + */ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_PACKET_CHAIN) && !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; + +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_PPP ppp_0; +static NX_PPP ppp_1; + +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter = 0; +static ULONG thread_1_counter = 0; +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_up_counter; +static ULONG ppp_1_link_down_counter; +static UINT error_counter = 0; +static UINT ppp_boundary_test_complete = NX_FALSE; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_check_boundary_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1024, pointer, 8192); + pointer = pointer + 8192; + status += nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 500, pointer, 8192); + pointer = pointer + 8192; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define the IP addresses. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP1", &ip_1, pointer, 2048, 1, &pool_1, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_1, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_1, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); + nx_udp_enable(&ip_1); + + /* Enable ICMP traffic. */ + nx_icmp_enable(&ip_0); + nx_icmp_enable(&ip_1); +} + + +UCHAR message[] = +"12345678901234567890123456789012345678901234567890" +"12345678901234567890123456789012345678901234567890" + +"12345678901234567890123456789012345678901234567890" +"12345678901234567890123456789012345678901234567890" + +"12345678901234567890123456789012345678901234567890" +"12345678901234567890123456789012345678901234567890" + +"12345678901234567890123456789012345678901234567890" +"12345678901234567890123456789012345678901234567890" + +"12345678901234567890123456789012345678901234567890" +"12345678901234567890123456789012345678901234567890" + +"12345678901234567890123456789012345678901234567890" +"12345678901234567890123456789012345678901234567890" +; + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; +UINT length; +UINT total; +UINT counter; + + + /* Print out test information banner. */ + printf("NetX Test: PPP Check Packet Boundary Test............................"); + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for address resolved. */ + nx_ip_status_check(&ip_0, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + + /* Disable checksum logic for this socket. */ + nx_udp_socket_checksum_disable(&socket_0); + + /* Set the value. */ + length = 10; + total = strlen((const char *)message); + counter = total - length; + + /* Increase the size of message till we hit a boundary error (e.g. packet payload area exceeded). */ + while(length <= total) + { + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_1, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + break; + } + + /* Write ABCs into the packet payload! */ + status = nx_packet_data_append(my_packet, &message[0], length, &pool_1, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + break; + } + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + break; + } + + /* Increment thread 0's counter. */ + thread_0_counter++; + tx_thread_sleep(NX_IP_PERIODIC_RATE/10); + + length++; + } + + /* Let ppp_1 receive packets. */ + while (ppp_boundary_test_complete == NX_FALSE) + { + tx_thread_sleep(NX_IP_PERIODIC_RATE); + } + + /* Delete ppp_0. */ + nx_ppp_delete(&ppp_0); + + /* Check status. */ + if (error_counter || (thread_0_counter != counter + 1) || (thread_0_counter != thread_1_counter) || (length != total + 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; + + + /* Wait for address resolved. */ + nx_ip_status_check(&ip_1, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + error_counter++; + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + error_counter++; + + while(1) + { + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + break; + } + + thread_1_counter++; + + if (thread_1_counter == 590) + thread_1_counter = 590; + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + nx_ppp_delete(&ppp_1); + ppp_boundary_test_complete = NX_TRUE; + +} + + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} + + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_up_counter++; + else + ppp_1_link_up_counter++; +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_down_counter++; + else + ppp_1_link_down_counter++; + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_check_boundary_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP Check Packet Boundary Test............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ppp_test/netx_ppp_pap_basic_test.c b/test/regression/ppp_test/netx_ppp_pap_basic_test.c new file mode 100644 index 00000000..4c978084 --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_pap_basic_test.c @@ -0,0 +1,511 @@ +/* This tests the basic PPP logic with PAP authentication. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 +#define DEMO_DATA "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_PPP ppp_0; +static NX_PPP ppp_1; +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT thread_1_alive = NX_TRUE; +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_up_counter; +static ULONG ppp_1_link_down_counter; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static UINT generate_login(CHAR *name, CHAR *password); +static UINT verify_login(CHAR *name, CHAR *password); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_pap_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 2 * NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + { + error_counter++; + } + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP 0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + { + error_counter++; + } + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + { + error_counter++; + } + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + { + error_counter++; + } + + /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_pap_enable(&ppp_0, NX_NULL, verify_login); + + /* Check for PPP PAP enable error. */ + if (status) + { + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + { + error_counter++; + } + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP 1", &ip_1, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + { + error_counter++; + } + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + { + error_counter++; + } + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_1, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + { + error_counter++; + } + + /* Setup PAP, this PPP instance is effectively the since it generates the name and password for the peer. */ + status = nx_ppp_pap_enable(&ppp_1, generate_login, NX_NULL); + + /* Check for PPP PAP enable error. */ + if (status) + { + error_counter++; + } + + /* Create another IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + if (status) + { + error_counter++; + } +} + + +/* Define the test threads. */ + +void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; + + + printf("NetX Test: PPP PAP Basic Test........................................"); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Disable checksum logic for this socket. */ + nx_udp_socket_checksum_disable(&socket_0); + + /* Let receiver thread run. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Write ABCs into the packet payload! */ + nx_packet_data_append(my_packet, DEMO_DATA, sizeof(DEMO_DATA), &pool_0, NX_WAIT_FOREVER); + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Relinquish to thread 1. */ + tx_thread_relinquish(); + + /* Wait for the other thread to finish. */ + while(thread_1_alive) + { + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_0, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + + /* Check the echo data. */ + if (memcmp(my_packet -> nx_packet_prepend_ptr, DEMO_DATA, sizeof(DEMO_DATA)) != 0) + { + error_counter++; + } + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; + + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_1, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + thread_1_alive = NX_FALSE; + return; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + thread_1_alive = NX_FALSE; + return; + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + thread_1_alive = NX_FALSE; + return; + } + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_1, my_packet, IP_ADDRESS(1, 2, 3, 4), 0x88); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + thread_1_alive = NX_FALSE; + return; + } + } + + thread_1_alive = NX_FALSE; + + return; + +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_up_counter++; + else + ppp_1_link_up_counter++; +} + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_down_counter++; + else + ppp_1_link_down_counter++; + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); +} + +static UINT generate_login(CHAR *name, CHAR *password) +{ + + /* Make a name and password, called "myname" and "mypassword". */ + name[0] = 'm'; + name[1] = 'y'; + name[2] = 'n'; + name[3] = 'a'; + name[4] = 'm'; + name[5] = 'e'; + name[6] = (CHAR) 0; + + password[0] = 'm'; + password[1] = 'y'; + password[2] = 'p'; + password[3] = 'a'; + password[4] = 's'; + password[5] = 's'; + password[6] = 'w'; + password[7] = 'o'; + password[8] = 'r'; + password[9] = 'd'; + password[10] = (CHAR) 0; + + return(NX_SUCCESS); +} + +static UINT verify_login(CHAR *name, CHAR *password) +{ + +if ((name[0] == 'm') && + (name[1] == 'y') && + (name[2] == 'n') && + (name[3] == 'a') && + (name[4] == 'm') && + (name[5] == 'e') && + (name[6] == (CHAR) 0) && + (password[0] == 'm') && + (password[1] == 'y') && + (password[2] == 'p') && + (password[3] == 'a') && + (password[4] == 's') && + (password[5] == 's') && + (password[6] == 'w') && + (password[7] == 'o') && + (password[8] == 'r') && + (password[9] == 'd') && + (password[10] == (CHAR) 0)) + return(NX_SUCCESS); + else + return(NX_PPP_ERROR); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_pap_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP PAP Basic Test........................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/ppp_test/netx_ppp_pap_null_name_password_test.c b/test/regression/ppp_test/netx_ppp_pap_null_name_password_test.c new file mode 100644 index 00000000..db6e2417 --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_pap_null_name_password_test.c @@ -0,0 +1,340 @@ +/* This tests that PPP PAP authentication with empty username and password. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; + +static NX_IP ip_0; +static NX_IP ip_1; + +static NX_PPP ppp_0; +static NX_PPP ppp_1; + + +/* Define the counters used in the demo application... */ + +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_up_counter; +static ULONG ppp_1_link_down_counter; +static UINT nak_counter = 0; +static UINT error_counter = 0; +static UINT thread_1_done = NX_FALSE; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); + +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static UINT generate_login(CHAR *name, CHAR *password); +static UINT verify_login(CHAR *name, CHAR *password); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); +static void nak_authentication_notify(void); + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_pap_null_name_password_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP 0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_pap_enable(&ppp_0, NX_NULL, verify_login); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + status = nx_ppp_nak_authentication_notify(&ppp_0, nak_authentication_notify); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP 1", &ip_1, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_1, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the since it generates the name and password for the peer. */ + status = nx_ppp_pap_enable(&ppp_1, generate_login, NX_NULL); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + status = nx_ppp_nak_authentication_notify(&ppp_1, nak_authentication_notify); + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, pointer, 2048, 1); + pointer = pointer + 2048; + + if (status) + error_counter++; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + /* Print out test information banner. */ + printf("NetX Test: PPP PAP Null Name Password Test..........................."); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for address resolved. */ + status = nx_ip_status_check(&ip_0, NX_IP_ADDRESS_RESOLVED, &ip_status, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for thread1 finish. */ + while (thread_1_done != NX_TRUE) + { + tx_thread_sleep(1); + } + + /* Check status. */ + if ((status) || + (ppp_0.nx_ppp_authenticated != 1) || (ppp_1.nx_ppp_authenticated != 1) || + (ppp_0_link_up_counter != 1) || (ppp_1_link_up_counter != 1) || + (ppp_0_link_down_counter != 0) || (ppp_1_link_down_counter != 0) || + (error_counter != 0) || (nak_counter != 0)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Delete PPP instances. */ + nx_ppp_delete(&ppp_0); + nx_ppp_delete(&ppp_1); + + /* Output successful. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + /* Wait for address resolved. */ + status = nx_ip_status_check(&ip_1, NX_IP_ADDRESS_RESOLVED, &ip_status, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + error_counter++; + + /* Update the flag. */ + thread_1_done = NX_TRUE; +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} + + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_up_counter++; + else + ppp_1_link_up_counter++; +} + + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_down_counter++; + else + ppp_1_link_down_counter++; + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); +} + + +static UINT generate_login(CHAR *name, CHAR *password) +{ + + /* Input null name and null password. */ + name[0] = (CHAR)0; + password[0] = (CHAR) 0; + + return(NX_SUCCESS); +} + + +static UINT verify_login(CHAR *name, CHAR *password) +{ + + if ((name[0]) || (password[0])) + return(NX_PPP_ERROR); + else + return(NX_SUCCESS); +} + +static void nak_authentication_notify(void) +{ + + nak_counter ++; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_pap_null_name_password_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP PAP Null Name Password Test...........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/ppp_test/netx_ppp_pfc_option_test.c b/test/regression/ppp_test/netx_ppp_pfc_option_test.c new file mode 100644 index 00000000..e1b689c7 --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_pfc_option_test.c @@ -0,0 +1,431 @@ +/* This tests the processing of compressed protocol field. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_PPP_COMPRESSION_ENABLE) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 +#define DEMO_DATA "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_PPP ppp_0; +static NX_PPP ppp_1; +static NX_UDP_SOCKET socket_0; +static NX_UDP_SOCKET socket_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT thread_1_alive = NX_TRUE; +static ULONG ppp_0_link_up_counter; +static ULONG ppp_0_link_down_counter; +static ULONG ppp_1_link_up_counter; +static ULONG ppp_1_link_down_counter; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); +static void link_up_callback(NX_PPP *ppp_ptr); +static void link_down_callback(NX_PPP *ppp_ptr); +static UINT generate_login(CHAR *name, CHAR *password); +static UINT verify_login(CHAR *name, CHAR *password); + +/* UDP packet data with Protocol filed compressed. +00 21 45 00 00 38 21 00 00 80 11 32 a8 01 02 03 04 01 02 03 05 00 88 00 89 00 24 00 00 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 20 00 +*/ +static UCHAR udp_data[] = { +0x7e, 0xff, 0x7d, 0x23, 0x21, 0x45, 0x7d, 0x20, 0x7d, 0x20, 0x38, 0x7d, 0x20, 0x7d, +0x21, 0x7d, 0x20, 0x7d, 0x20, 0x80, 0x7d, 0x31, 0x32, 0xa8, 0x7d, 0x21, 0x7d, 0x22, 0x7d, 0x23, +0x7d, 0x24, 0x7d, 0x21, 0x7d, 0x22, 0x7d, 0x23, 0x7d, 0x25, 0x7d, 0x20, 0x88, 0x7d, 0x20, 0x89, +0x7d, 0x20, 0x24, 0x7d, 0x20, 0x7d, 0x20, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, +0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, +0x5a, 0x20, 0x7d, 0x20, 0x40, 0xc0, 0x7e, +}; + +static UINT udp_data_send = NX_FALSE; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_pfc_option_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 2 * NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + { + error_counter++; + } + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP 0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + { + error_counter++; + } + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + { + error_counter++; + } + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_0, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_0, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + { + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + { + error_counter++; + } + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP 1", &ip_1, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + { + error_counter++; + } + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + { + error_counter++; + } + + /* Register the link up/down callbacks. */ + status = nx_ppp_link_up_notify(&ppp_1, link_up_callback); + status += nx_ppp_link_down_notify(&ppp_1, link_down_callback); + + /* Check for PPP link up/down callback registration error(s). */ + if (status) + { + error_counter++; + } + + /* Create another IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + if (status) + { + error_counter++; + } +} + + +/* Define the test threads. */ + +void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; + + + printf("NetX Test: PPP PFC Option Test......................................."); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 0x88, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Disable checksum logic for this socket. */ + nx_udp_socket_checksum_disable(&socket_0); + + /* Let receiver thread run. */ + tx_thread_relinquish(); + + /* Allocate a packet. */ + status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Write ABCs into the packet payload! */ + nx_packet_data_append(my_packet, DEMO_DATA, sizeof(DEMO_DATA), &pool_0, NX_WAIT_FOREVER); + + /* Send the UDP packet. */ + status = nx_udp_socket_send(&socket_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Relinquish to thread 1. */ + tx_thread_relinquish(); + + /* Wait for the other thread to finish. */ + while(thread_1_alive) + { + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; +NX_PACKET *my_packet; + + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_1, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_1, &socket_1, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + thread_1_alive = NX_FALSE; + return; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_1, 0x89, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + thread_1_alive = NX_FALSE; + return; + } + + /* Receive a UDP packet. */ + status = nx_udp_socket_receive(&socket_1, &my_packet, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + + /* Release the packet. */ + status = nx_packet_release(my_packet); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + } + + thread_1_alive = NX_FALSE; + + return; + +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +static void ppp_0_serial_byte_output(UCHAR byte) +{ +UINT i; + + if (ppp_0.nx_ppp_ipcp_state < NX_PPP_IPCP_COMPLETED_STATE) + { + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); + } + else if (udp_data_send == NX_FALSE) + { + /* Modify the data to send compressed protocol field. */ + for (i = 0; i < sizeof(udp_data); i++) + { + nx_ppp_byte_receive(&ppp_1, udp_data[i]); + } + + udp_data_send = NX_TRUE; + } +} + +static void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + +static void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} + +static void link_up_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link up counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_up_counter++; + else + ppp_1_link_up_counter++; +} + +static void link_down_callback(NX_PPP *ppp_ptr) +{ + + /* Just increment the link down counter. */ + if (ppp_ptr == &ppp_0) + ppp_0_link_down_counter++; + else + ppp_1_link_down_counter++; + + /* Restart the PPP instance. */ + nx_ppp_restart(ppp_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_pfc_option_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP PFC Option Test.......................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/ppp_test/netx_ppp_request_dns_server_test.c b/test/regression/ppp_test/netx_ppp_request_dns_server_test.c new file mode 100644 index 00000000..2494bbe2 --- /dev/null +++ b/test/regression/ppp_test/netx_ppp_request_dns_server_test.c @@ -0,0 +1,289 @@ +/* This tests the use of requesting and processing primary and secondary DNS servers + as part of the IPCP handshake. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define demo stack size. */ + +#define DEMO_STACK_SIZE 2048 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_PPP ppp_0; +static NX_PPP ppp_1; + + +/* Define the counters used in the demo application... */ + +static ULONG error_counter = 0; +static UINT thread_1_alive = NX_TRUE; +static ULONG dns_address = 0 ; +static ULONG secondary_dns_address = 0; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +static void ppp_0_serial_byte_output(UCHAR byte); +static void ppp_1_serial_byte_output(UCHAR byte); +static void invalid_packet_handler(NX_PACKET *packet_ptr); + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_request_dns_server_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the thread 0. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the thread 1. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", NX_PPP_MIN_PACKET_PAYLOAD, pointer, 2048); + pointer = pointer + 2048; + + /* Check for pool creation error. */ + if (status) + { + error_counter++; + } + + /* Create the first PPP instance. */ + status = nx_ppp_create(&ppp_0, "PPP 0", &ip_0, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_0_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + { + error_counter++; + } + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_0, IP_ADDRESS(1, 2, 3, 4), IP_ADDRESS(1, 2, 3, 5)); + + /* Check for PPP IP address assign error. */ + if (status) + { + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + { + error_counter++; + } + + /* Create the next PPP instance. */ + status = nx_ppp_create(&ppp_1, "PPP 1", &ip_1, pointer, 2048, 1, &pool_0, invalid_packet_handler, ppp_1_serial_byte_output); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + { + error_counter++; + } + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_1, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + { + error_counter++; + } + + /* Create another IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFF000UL, &pool_0, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create error. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + nx_udp_enable(&ip_0); + nx_udp_enable(&ip_1); + + /* Set up the PPP0 primary address. */ + status = nx_ppp_dns_address_set(&ppp_0, IP_ADDRESS(1,2,3,89)); + + /* Set the PPP0 secondary DNS server */ + status += nx_ppp_secondary_dns_address_set(&ppp_0, IP_ADDRESS(1,2,3,88)); + + /* Set PP1 primary DNS. Note that PPP_0 will overwrite this with its own primary DNS. */ + status += nx_ppp_dns_address_set(&ppp_1, IP_ADDRESS(1,2,3,79)); + + if (status) + { + error_counter++; + } +} + + +/* Define the test threads. */ + +void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + + + printf("NetX Test: PPP Request DNS Server Test..............................."); + + if (error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_0, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + /* Wait for the other thread to finish. */ + while(thread_1_alive) + { + + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + } + + if (!secondary_dns_address || !dns_address || error_counter) + { + + printf("ERROR!\n"); + test_control_return(1); + + } + + printf("SUCCESS!\n"); + test_control_return(0); + + return; +} + + +void thread_1_entry(ULONG thread_input) +{ + +UINT status; +ULONG ip_status; + + + /* Wait for the link to come up. */ + do + { + + status = nx_ip_status_check(&ip_1, NX_IP_LINK_ENABLED, &ip_status, 20 * NX_IP_PERIODIC_RATE); + }while(status != NX_SUCCESS); + + + status = nx_ppp_dns_address_get(&ppp_1, &dns_address); + if (status != NX_SUCCESS) + { + error_counter++; + } + + status = nx_ppp_secondary_dns_address_get(&ppp_1, &secondary_dns_address); + if (status != NX_SUCCESS) + { + error_counter++; + } + + thread_1_alive = NX_FALSE; + + return; + +} + +/* Define serial output routines. Normally these routines would + map to physical UART routines and the nx_ppp_byte_receive call + would be made from a UART receive interrupt. */ + +void ppp_0_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 1 input routine. */ + nx_ppp_byte_receive(&ppp_1, byte); +} + +void ppp_1_serial_byte_output(UCHAR byte) +{ + + /* Just feed the PPP 0 input routine. */ + nx_ppp_byte_receive(&ppp_0, byte); +} + + +void invalid_packet_handler(NX_PACKET *packet_ptr) +{ + /* Print out the non-PPP byte. In Windows, the string "CLIENT" will + be sent before Windows PPP starts. Once CLIENT is received, we need + to send "CLIENTSERVER" to establish communication. It's also possible + to receive modem commands here that might need some response to + continue. */ + nx_packet_release(packet_ptr); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ppp_request_dns_server_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPP Request DNS Server Test...............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/pppoe_test/netx_pppoe_ac_name_test.c b/test/regression/pppoe_test/netx_pppoe_ac_name_test.c new file mode 100644 index 00000000..0f3873d5 --- /dev/null +++ b/test/regression/pppoe_test/netx_pppoe_ac_name_test.c @@ -0,0 +1,473 @@ +/* This case tests processing AC name. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" +#include "nx_pppoe_server.h" +#include "nx_pppoe_client.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_PPP_PPPOE_ENABLE) && defined(NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE) && defined(NX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE) && (NX_PHYSICAL_HEADER >= 24) && !defined(NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE) + +/* Defined NX_PPP_PPPOE_ENABLE if use Express Logic's PPP, since PPP module has been modified to match PPPoE moduler under this definition. */ + +/* If the driver is not initialized in other module, define NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE to initialize the driver in PPPoE module . + In this demo, the driver has been initialized in IP module. */ + +/* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE: + If defined, enables the feature that controls the PPPoE session. + PPPoE server does not automatically response to the request until application call specific API. */ + +/* Define the block size. */ +#define NX_PACKET_POOL_SIZE ((1536 + sizeof(NX_PACKET)) * 12) +#define DEMO_STACK_SIZE 2048 +#define PPPOE_THREAD_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD thread_server; +static TX_THREAD thread_client; + +/* Define the packet pool and IP instance for normal IP instnace. */ +static NX_PACKET_POOL pool_server; +static NX_IP ip_server; +static NX_PACKET_POOL pool_client; +static NX_IP ip_client; +static CHAR pool_buffer_server[NX_PACKET_POOL_SIZE]; +static CHAR pool_buffer_client[NX_PACKET_POOL_SIZE]; + +/* Define the PPP Server instance. */ +static NX_PPP ppp_server; +static NX_PPP ppp_client; + +/* Define the PPPoE Server instance. */ +static NX_PPPOE_SERVER pppoe_server; +static NX_PPPOE_CLIENT pppoe_client; + +/* Define the counters. */ +static CHAR *pointer; +static ULONG error_counter; + +/* Define thread prototypes. */ +static void thread_server_entry(ULONG thread_input); +static void thread_client_entry(ULONG thread_input); + +/***** Substitute your PPP driver entry function here *********/ +extern void _nx_ppp_driver(NX_IP_DRIVER *driver_req_ptr); + +/***** Substitute your Ethernet driver entry function here *********/ +extern void _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); + +/* Define the callback functions. */ +static void pppoe_server_packet_receive(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id); + +/* Define the porting layer function for Express Logic's PPP. + Functions to be provided by PPP for calling by the PPPoE Stack. */ +static void ppp_server_packet_send(NX_PACKET *packet_ptr); + +/* Define the porting layer function for Express Logic's PPP. + Functions to be provided by PPP for calling by the PPPoE Stack. */ +static void ppp_client_packet_send(NX_PACKET *packet_ptr); +static void pppoe_client_packet_receive(NX_PACKET *packet_ptr); + +#define SERVER_ADDRESS IP_ADDRESS(192, 168, 10, 43) +#define CLIENT_ADDRESS IP_ADDRESS(192, 168, 10, 44) + +static UINT generate_login(CHAR *name, CHAR *password) +{ + + /* Make a name and password, called "myname" and "mypassword". */ + name[0] = 'm'; + name[1] = 'y'; + name[2] = 'n'; + name[3] = 'a'; + name[4] = 'm'; + name[5] = 'e'; + name[6] = (CHAR) 0; + + password[0] = 'm'; + password[1] = 'y'; + password[2] = 'p'; + password[3] = 'a'; + password[4] = 's'; + password[5] = 's'; + password[6] = 'w'; + password[7] = 'o'; + password[8] = 'r'; + password[9] = 'd'; + password[10] = (CHAR) 0; + + return(NX_SUCCESS); +} + +static UINT verify_login(CHAR *name, CHAR *password) +{ + +if ((name[0] == 'm') && + (name[1] == 'y') && + (name[2] == 'n') && + (name[3] == 'a') && + (name[4] == 'm') && + (name[5] == 'e') && + (name[6] == (CHAR) 0) && + (password[0] == 'm') && + (password[1] == 'y') && + (password[2] == 'p') && + (password[3] == 'a') && + (password[4] == 's') && + (password[5] == 's') && + (password[6] == 'w') && + (password[7] == 'o') && + (password[8] == 'r') && + (password[9] == 'd') && + (password[10] == (CHAR) 0)) + return(NX_SUCCESS); + else + return(NX_PPP_ERROR); +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pppoe_ac_name_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool for normal IP instance. */ + status = nx_packet_pool_create(&pool_server, "Server Packet Pool", + (1536 + sizeof(NX_PACKET)), + pool_buffer_server, NX_PACKET_POOL_SIZE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create an normal IP instance. */ + status = nx_ip_create(&ip_server, "Server IP Instance", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_server, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_server, "PPP Server Instance", &ip_server, pointer, 2048, 1, &pool_server, NX_NULL, NX_NULL); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Set the PPP packet send function. */ + status = nx_ppp_packet_send_set(&ppp_server, ppp_server_packet_send); + + /* Check for PPP packet send function set error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_server, SERVER_ADDRESS, CLIENT_ADDRESS); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_pap_enable(&ppp_server, NX_NULL, verify_login); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for Normal IP Instance. */ + status = nx_arp_enable(&ip_server, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP */ + status = nx_icmp_enable(&ip_server); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&thread_server, "thread server", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create a packet pool for normal IP instance. */ + status = nx_packet_pool_create(&pool_client, "Client Packet Pool", + (1536 + sizeof(NX_PACKET)), + pool_buffer_client, NX_PACKET_POOL_SIZE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create an normal IP instance. */ + status = nx_ip_create(&ip_client, "Client IP Instance", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_client, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_client, "PPP Client Instance", &ip_client, pointer, 2048, 1, &pool_client, NX_NULL, NX_NULL); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Set the PPP packet send function. */ + status = nx_ppp_packet_send_set(&ppp_client, ppp_client_packet_send); + + /* Check for PPP packet send function set error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_client, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the since it generates the name and password for the peer.. */ + status = nx_ppp_pap_enable(&ppp_client, generate_login, NX_NULL); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for Normal IP Instance. */ + status = nx_arp_enable(&ip_client, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP */ + status = nx_icmp_enable(&ip_client); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&thread_client, "thread client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + +} + +static UCHAR PADI[] = +{ +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x88, 0x63, +0x11, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x01, 0x00, 0x00, 0x01, 0x03, 0x00, 0x04, 0x64, 0x13, +0x85, 0x18, +}; + +static UCHAR PADR[] = +{ +0x00, 0x11, 0x22, 0x33, 0x44, 0x56, 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x88, 0x63, +0x11, 0x19, 0x00, 0x00, 0x00, 0x14, 0x01, 0x01, 0x00, 0x00, 0x01, 0x03, 0x00, 0x04, 0x64, 0x13, +0x85, 0x18, 0x01, 0x02, 0x00, 0x04, 0x42, 0x52, 0x41, 0x53, +}; + +static void thread_client_entry(ULONG thread_input) +{ +UINT status; +ULONG ip_status; +NX_PACKET *recv_pkt; +ULONG ip_address; +ULONG network_mask; +NX_PACKET *send_packet; + + /* Create the PPPoE instance. */ + status = nx_pppoe_client_create(&pppoe_client, (UCHAR *)"PPPoE Client", &ip_client, 0, &pool_client, pointer, PPPOE_THREAD_SIZE, 4, _nx_ram_network_driver, pppoe_client_packet_receive); + pointer = pointer + PPPOE_THREAD_SIZE; + if (status) + { + error_counter++; + } + + /* Establish PPPoE Client sessione. */ + nx_packet_allocate(&pool_client, &send_packet, NX_PHYSICAL_HEADER, NX_NO_WAIT); + memcpy(send_packet -> nx_packet_prepend_ptr, PADI, sizeof(PADI)); + send_packet -> nx_packet_prepend_ptr += NX_PPPOE_SERVER_ETHER_HEADER_SIZE; + send_packet -> nx_packet_length = sizeof(PADI) - NX_PPPOE_SERVER_ETHER_HEADER_SIZE; + send_packet -> nx_packet_append_ptr = send_packet -> nx_packet_prepend_ptr + send_packet -> nx_packet_length; + _nx_pppoe_server_packet_deferred_receive(send_packet); + nx_packet_allocate(&pool_client, &send_packet, NX_PHYSICAL_HEADER, NX_NO_WAIT); + memcpy(send_packet -> nx_packet_prepend_ptr, PADR, sizeof(PADR)); + send_packet -> nx_packet_prepend_ptr += NX_PPPOE_SERVER_ETHER_HEADER_SIZE; + send_packet -> nx_packet_length = sizeof(PADR) - NX_PPPOE_SERVER_ETHER_HEADER_SIZE; + send_packet -> nx_packet_append_ptr = send_packet -> nx_packet_prepend_ptr + send_packet -> nx_packet_length; + pppoe_client.nx_pppoe_server_session.nx_pppoe_physical_address_msw = 0x11; + pppoe_client.nx_pppoe_server_session.nx_pppoe_physical_address_lsw = 0x22334456; + pppoe_client.nx_pppoe_state = NX_PPPOE_CLIENT_STATE_PADR_SENT; + _nx_pppoe_server_packet_deferred_receive(send_packet); + + /* Wait for the link to come up. */ + status = nx_ip_interface_status_check(&ip_client, 0, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Check client IP address. */ + status = nx_ip_address_get(&ip_client, &ip_address, &network_mask); + if (status || ip_address != CLIENT_ADDRESS) + { + error_counter++; + } + + /* Ping test. */ + status = nx_icmp_ping(&ip_client, SERVER_ADDRESS, "abcd", 4, &recv_pkt, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + else + { + nx_packet_release(recv_pkt); + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* PPPoE Client receive function. */ +static void pppoe_client_packet_receive(NX_PACKET *packet_ptr) +{ + + /* Call PPP Client to receive the PPP data fame. */ + nx_ppp_packet_receive(&ppp_client, packet_ptr); +} + +/* PPP Client send function. */ +static void ppp_client_packet_send(NX_PACKET *packet_ptr) +{ + + /* Directly Call PPPoE send function to send out the data through PPPoE module. */ + nx_pppoe_client_session_packet_send(&pppoe_client, packet_ptr); +} + +/* Define the server threads. */ + +static void thread_server_entry(ULONG thread_input) +{ +UINT status; +ULONG ip_status; +ULONG ip_address; +ULONG network_mask; +UCHAR ac_name[] = "BRAS"; + + /* Print out test information banner. */ + printf("NetX Test: PPPoE AC Name Test........................................"); + + /* Create the PPPoE instance. */ + status = nx_pppoe_server_create(&pppoe_server, (UCHAR *)"PPPoE Server", &ip_server, 0, _nx_ram_network_driver, &pool_server, pointer, PPPOE_THREAD_SIZE, 4); + pointer = pointer + PPPOE_THREAD_SIZE; + if (status) + { + error_counter++; + } + + /* Set AC name. */ + nx_pppoe_server_ac_name_set(&pppoe_server, ac_name, sizeof(ac_name) - 1); + + /* Set the callback notify function. */ + status = nx_pppoe_server_callback_notify_set(&pppoe_server, NX_NULL, NX_NULL, NX_NULL, NX_NULL, pppoe_server_packet_receive, NX_NULL); + if (status) + { + error_counter++; + } + + /* Enable PPPoE Server. */ + status = nx_pppoe_server_enable(&pppoe_server); + if (status) + { + error_counter++; + } + + tx_thread_resume(&thread_client); + + /* Wait for the link to come up. */ + status = nx_ip_interface_status_check(&ip_server, 0, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Check server IP address. */ + status = nx_ip_address_get(&ip_server, &ip_address, &network_mask); + if (status || ip_address != SERVER_ADDRESS) + { + error_counter++; + } +} + +static void pppoe_server_packet_receive(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id) +{ + +NX_PACKET *packet_ptr; + + /* Get the notify that receive the PPPoE Session data. */ + + /* Call PPP Server to receive the PPP data fame. */ + packet_ptr = (NX_PACKET *)(packet_id); + nx_ppp_packet_receive(&ppp_server, packet_ptr); +} + +/* PPP Server send function. */ +static void ppp_server_packet_send(NX_PACKET *packet_ptr) +{ + +/* For Express Logic's PPP test, the session should be the first session, so set interfaceHandle as 0. */ +UINT interfaceHandle = 0; + + /* Directly Call PPPoE send function to send out the data through PPPoE module. */ + nx_pppoe_server_session_packet_send(&pppoe_server, interfaceHandle, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pppoe_ac_name_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPPoE AC Name Test........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/pppoe_test/netx_pppoe_api_extended_test.c b/test/regression/pppoe_test/netx_pppoe_api_extended_test.c new file mode 100644 index 00000000..6467696c --- /dev/null +++ b/test/regression/pppoe_test/netx_pppoe_api_extended_test.c @@ -0,0 +1,470 @@ +/* This case tests the APIs of PPPoE server and client. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" +#include "nx_pppoe_server.h" +#include "nx_pppoe_client.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_PPP_PPPOE_ENABLE) && defined(NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE) && defined(NX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE) && (NX_PHYSICAL_HEADER >= 24) && !defined(NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE) + +/* Define the block size. */ +#define NX_PACKET_POOL_SIZE ((1536 + sizeof(NX_PACKET)) * 12) +#define DEMO_STACK_SIZE 2048 +#define PPPOE_THREAD_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD thread_server; +static TX_THREAD thread_client; + +/* Define the packet pool and IP instance for normal IP instnace. */ +static NX_PACKET_POOL pool_server; +static NX_IP ip_server; +static NX_PACKET_POOL pool_client; +static NX_IP ip_client; +static CHAR pool_buffer_server[NX_PACKET_POOL_SIZE]; +static CHAR pool_buffer_client[NX_PACKET_POOL_SIZE]; + +/* Define the PPP Server instance. */ +static NX_PPP ppp_server; +static NX_PPP ppp_client; + +/* Define the PPPoE Server instance. */ +static NX_PPPOE_SERVER pppoe_server; +static NX_PPPOE_CLIENT pppoe_client; + +/* Define the counters. */ +static CHAR *pointer; +static ULONG error_counter; + +/* Define thread prototypes. */ +static void thread_server_entry(ULONG thread_input); +static void thread_client_entry(ULONG thread_input); + +/***** Substitute your PPP driver entry function here *********/ +extern void _nx_ppp_driver(NX_IP_DRIVER *driver_req_ptr); + +/***** Substitute your Ethernet driver entry function here *********/ +extern void _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); + +/* Define the callback functions. */ +static void pppoe_server_packet_receive(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id); + +/* Define the porting layer function for Express Logic's PPP. + Functions to be provided by PPP for calling by the PPPoE Stack. */ +static void ppp_server_packet_send(NX_PACKET *packet_ptr); + +/* Define the porting layer function for Express Logic's PPP. + Functions to be provided by PPP for calling by the PPPoE Stack. */ +static void ppp_client_packet_send(NX_PACKET *packet_ptr); +static void pppoe_client_packet_receive(NX_PACKET *packet_ptr); + +#define SERVER_ADDRESS IP_ADDRESS(192, 168, 10, 43) +#define CLIENT_ADDRESS IP_ADDRESS(192, 168, 10, 44) + +static UINT generate_login(CHAR *name, CHAR *password) +{ + + /* Make a name and password, called "myname" and "mypassword". */ + name[0] = 'm'; + name[1] = 'y'; + name[2] = 'n'; + name[3] = 'a'; + name[4] = 'm'; + name[5] = 'e'; + name[6] = (CHAR) 0; + + password[0] = 'm'; + password[1] = 'y'; + password[2] = 'p'; + password[3] = 'a'; + password[4] = 's'; + password[5] = 's'; + password[6] = 'w'; + password[7] = 'o'; + password[8] = 'r'; + password[9] = 'd'; + password[10] = (CHAR) 0; + + return(NX_SUCCESS); +} + +static UINT verify_login(CHAR *name, CHAR *password) +{ + +if ((name[0] == 'm') && + (name[1] == 'y') && + (name[2] == 'n') && + (name[3] == 'a') && + (name[4] == 'm') && + (name[5] == 'e') && + (name[6] == (CHAR) 0) && + (password[0] == 'm') && + (password[1] == 'y') && + (password[2] == 'p') && + (password[3] == 'a') && + (password[4] == 's') && + (password[5] == 's') && + (password[6] == 'w') && + (password[7] == 'o') && + (password[8] == 'r') && + (password[9] == 'd') && + (password[10] == (CHAR) 0)) + return(NX_SUCCESS); + else + return(NX_PPP_ERROR); +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pppoe_api_extended_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool for normal IP instance. */ + status = nx_packet_pool_create(&pool_server, "Server Packet Pool", + (1536 + sizeof(NX_PACKET)), + pool_buffer_server, NX_PACKET_POOL_SIZE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create an normal IP instance. */ + status = nx_ip_create(&ip_server, "Server IP Instance", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_server, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_server, "PPP Server Instance", &ip_server, pointer, 2048, 1, &pool_server, NX_NULL, NX_NULL); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Set the PPP packet send function. */ + status = nx_ppp_packet_send_set(&ppp_server, ppp_server_packet_send); + + /* Check for PPP packet send function set error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_server, SERVER_ADDRESS, CLIENT_ADDRESS); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_pap_enable(&ppp_server, NX_NULL, verify_login); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for Normal IP Instance. */ + status = nx_arp_enable(&ip_server, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP */ + status = nx_icmp_enable(&ip_server); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&thread_server, "thread server", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create a packet pool for normal IP instance. */ + status = nx_packet_pool_create(&pool_client, "Client Packet Pool", + (1536 + sizeof(NX_PACKET)), + pool_buffer_client, NX_PACKET_POOL_SIZE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create an normal IP instance. */ + status = nx_ip_create(&ip_client, "Client IP Instance", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_client, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_client, "PPP Client Instance", &ip_client, pointer, 2048, 1, &pool_client, NX_NULL, NX_NULL); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Set the PPP packet send function. */ + status = nx_ppp_packet_send_set(&ppp_client, ppp_client_packet_send); + + /* Check for PPP packet send function set error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_client, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the since it generates the name and password for the peer.. */ + status = nx_ppp_pap_enable(&ppp_client, generate_login, NX_NULL); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for Normal IP Instance. */ + status = nx_arp_enable(&ip_client, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP */ + status = nx_icmp_enable(&ip_client); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&thread_client, "thread client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + +} + +static void thread_client_entry(ULONG thread_input) +{ +UINT status; +ULONG ip_status; +NX_PACKET *recv_pkt; +ULONG ip_address; +ULONG network_mask; + + /* Create the PPPoE instance. */ + status = nx_pppoe_client_create(&pppoe_client, (UCHAR *)"PPPoE Client", &ip_client, 0, &pool_client, pointer, PPPOE_THREAD_SIZE, 4, _nx_ram_network_driver, pppoe_client_packet_receive); + pointer = pointer + PPPOE_THREAD_SIZE; + if (status) + { + error_counter++; + } + + /* Set host unique. */ + status = nx_pppoe_client_host_uniq_set_extended(&pppoe_client, "220000000000000041000000", sizeof("220000000000000041000000") - 1); + if (status) + { + error_counter++; + } + + /* Set service name. */ + status = nx_pppoe_client_service_name_set_extended(&pppoe_client, "BRAS", sizeof("BRAS") - 1); + if (status) + { + error_counter++; + } + + /* Establish PPPoE Client sessione. */ + status = nx_pppoe_client_session_connect(&pppoe_client, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Wait for the link to come up. */ + status = nx_ip_interface_status_check(&ip_client, 0, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Check client IP address. */ + status = nx_ip_address_get(&ip_client, &ip_address, &network_mask); + if (status || ip_address != CLIENT_ADDRESS) + { + error_counter++; + } + + /* Ping test. */ + status = nx_icmp_ping(&ip_client, SERVER_ADDRESS, "abcd", 4, &recv_pkt, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + else + { + nx_packet_release(recv_pkt); + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* PPPoE Client receive function. */ +static void pppoe_client_packet_receive(NX_PACKET *packet_ptr) +{ + + /* Call PPP Client to receive the PPP data fame. */ + nx_ppp_packet_receive(&ppp_client, packet_ptr); +} + +/* PPP Client send function. */ +static void ppp_client_packet_send(NX_PACKET *packet_ptr) +{ + + /* Directly Call PPPoE send function to send out the data through PPPoE module. */ + nx_pppoe_client_session_packet_send(&pppoe_client, packet_ptr); +} + +/* Define the server threads. */ + +static void thread_server_entry(ULONG thread_input) +{ +UINT status; +ULONG ip_status; +UCHAR *nx_pppoe_service_name[] = +{ + "BRAS", + "PRINTER", + NX_NULL +}; +ULONG ip_address; +ULONG network_mask; + + + /* Print out test information banner. */ + printf("NetX Test: PPPoE API Extended Test..................................."); + + /* Create the PPPoE instance. */ + status = nx_pppoe_server_create(&pppoe_server, (UCHAR *)"PPPoE Server", &ip_server, 0, _nx_ram_network_driver, &pool_server, pointer, PPPOE_THREAD_SIZE, 4); + pointer = pointer + PPPOE_THREAD_SIZE; + if (status) + { + error_counter++; + } + + /* Set the callback notify function. */ + status = nx_pppoe_server_callback_notify_set(&pppoe_server, NX_NULL, NX_NULL, NX_NULL, NX_NULL, pppoe_server_packet_receive, NX_NULL); + if (status) + { + error_counter++; + } + + /* Set service name. */ + status = nx_pppoe_server_service_name_set(&pppoe_server, nx_pppoe_service_name, 2); + if (status) + { + error_counter++; + } + + /* Set access concentrator name. */ + status = nx_pppoe_server_ac_name_set(&pppoe_server, (UCHAR *)"PPPoE Server AC", sizeof("PPPoE Server AC") - 1); + if (status) + { + error_counter++; + } + + /* Enable PPPoE Server. */ + status = nx_pppoe_server_enable(&pppoe_server); + if (status) + { + error_counter++; + } + + tx_thread_resume(&thread_client); + + /* Wait for the link to come up. */ + status = nx_ip_interface_status_check(&ip_server, 0, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Check server IP address. */ + status = nx_ip_address_get(&ip_server, &ip_address, &network_mask); + if (status || ip_address != SERVER_ADDRESS) + { + error_counter++; + } +} + +static void pppoe_server_packet_receive(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id) +{ + +NX_PACKET *packet_ptr; + + /* Get the notify that receive the PPPoE Session data. */ + + /* Call PPP Server to receive the PPP data fame. */ + packet_ptr = (NX_PACKET *)(packet_id); + nx_ppp_packet_receive(&ppp_server, packet_ptr); +} + +/* PPP Server send function. */ +static void ppp_server_packet_send(NX_PACKET *packet_ptr) +{ + +/* For Express Logic's PPP test, the session should be the first session, so set interfaceHandle as 0. */ +UINT interfaceHandle = 0; + + /* Directly Call PPPoE send function to send out the data through PPPoE module. */ + nx_pppoe_server_session_packet_send(&pppoe_server, interfaceHandle, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pppoe_api_extended_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPPoE API Extended Test...................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/pppoe_test/netx_pppoe_api_test.c b/test/regression/pppoe_test/netx_pppoe_api_test.c new file mode 100644 index 00000000..b32553ba --- /dev/null +++ b/test/regression/pppoe_test/netx_pppoe_api_test.c @@ -0,0 +1,463 @@ +/* This case tests the APIs of PPPoE server and client. */ + +#include "nx_pppoe_server.h" +#include "nx_pppoe_client.h" +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_PPP_PPPOE_ENABLE) && defined(NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE) && defined(NX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE) && (NX_PHYSICAL_HEADER >= 24) && !defined(NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE) + +/* Define the block size. */ +#define NX_PACKET_POOL_SIZE ((1536 + sizeof(NX_PACKET)) * 12) +#define DEMO_STACK_SIZE 2048 +#define PPPOE_THREAD_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD thread_server; +static TX_THREAD thread_client; + +/* Define the packet pool and IP instance for normal IP instnace. */ +static NX_PACKET_POOL pool_server; +static NX_IP ip_server; +static NX_PACKET_POOL pool_client; +static NX_IP ip_client; +static CHAR pool_buffer_server[NX_PACKET_POOL_SIZE]; +static CHAR pool_buffer_client[NX_PACKET_POOL_SIZE]; + +/* Define the PPP Server instance. */ +static NX_PPP ppp_server; +static NX_PPP ppp_client; + +/* Define the PPPoE Server instance. */ +static NX_PPPOE_SERVER pppoe_server; +static NX_PPPOE_CLIENT pppoe_client; + +/* Define the counters. */ +static CHAR *pointer; +static ULONG error_counter; + +/* Define thread prototypes. */ +static void thread_server_entry(ULONG thread_input); +static void thread_client_entry(ULONG thread_input); + +/***** Substitute your PPP driver entry function here *********/ +extern void _nx_ppp_driver(NX_IP_DRIVER *driver_req_ptr); + +/***** Substitute your Ethernet driver entry function here *********/ +extern void _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); + +/* Define the callback functions. */ +static void pppoe_server_packet_receive(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id); + +/* Define the porting layer function for Express Logic's PPP. + Functions to be provided by PPP for calling by the PPPoE Stack. */ +static void ppp_server_packet_send(NX_PACKET *packet_ptr); + +/* Define the porting layer function for Express Logic's PPP. + Functions to be provided by PPP for calling by the PPPoE Stack. */ +static void ppp_client_packet_send(NX_PACKET *packet_ptr); +static void pppoe_client_packet_receive(NX_PACKET *packet_ptr); + +#define SERVER_ADDRESS IP_ADDRESS(192, 168, 10, 43) +#define CLIENT_ADDRESS IP_ADDRESS(192, 168, 10, 44) + +static UINT generate_login(CHAR *name, CHAR *password) +{ + + /* Make a name and password, called "myname" and "mypassword". */ + name[0] = 'm'; + name[1] = 'y'; + name[2] = 'n'; + name[3] = 'a'; + name[4] = 'm'; + name[5] = 'e'; + name[6] = (CHAR) 0; + + password[0] = 'm'; + password[1] = 'y'; + password[2] = 'p'; + password[3] = 'a'; + password[4] = 's'; + password[5] = 's'; + password[6] = 'w'; + password[7] = 'o'; + password[8] = 'r'; + password[9] = 'd'; + password[10] = (CHAR) 0; + + return(NX_SUCCESS); +} + +static UINT verify_login(CHAR *name, CHAR *password) +{ + +if ((name[0] == 'm') && + (name[1] == 'y') && + (name[2] == 'n') && + (name[3] == 'a') && + (name[4] == 'm') && + (name[5] == 'e') && + (name[6] == (CHAR) 0) && + (password[0] == 'm') && + (password[1] == 'y') && + (password[2] == 'p') && + (password[3] == 'a') && + (password[4] == 's') && + (password[5] == 's') && + (password[6] == 'w') && + (password[7] == 'o') && + (password[8] == 'r') && + (password[9] == 'd') && + (password[10] == (CHAR) 0)) + return(NX_SUCCESS); + else + return(NX_PPP_ERROR); +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pppoe_api_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool for normal IP instance. */ + status = nx_packet_pool_create(&pool_server, "Server Packet Pool", + (1536 + sizeof(NX_PACKET)), + pool_buffer_server, NX_PACKET_POOL_SIZE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create an normal IP instance. */ + status = nx_ip_create(&ip_server, "Server IP Instance", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_server, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_server, "PPP Server Instance", &ip_server, pointer, 2048, 1, &pool_server, NX_NULL, NX_NULL); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Set the PPP packet send function. */ + status = nx_ppp_packet_send_set(&ppp_server, ppp_server_packet_send); + + /* Check for PPP packet send function set error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_server, SERVER_ADDRESS, CLIENT_ADDRESS); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_pap_enable(&ppp_server, NX_NULL, verify_login); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for Normal IP Instance. */ + status = nx_arp_enable(&ip_server, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP */ + status = nx_icmp_enable(&ip_server); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&thread_server, "thread server", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create a packet pool for normal IP instance. */ + status = nx_packet_pool_create(&pool_client, "Client Packet Pool", + (1536 + sizeof(NX_PACKET)), + pool_buffer_client, NX_PACKET_POOL_SIZE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create an normal IP instance. */ + status = nx_ip_create(&ip_client, "Client IP Instance", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_client, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_client, "PPP Client Instance", &ip_client, pointer, 2048, 1, &pool_client, NX_NULL, NX_NULL); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Set the PPP packet send function. */ + status = nx_ppp_packet_send_set(&ppp_client, ppp_client_packet_send); + + /* Check for PPP packet send function set error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_client, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the since it generates the name and password for the peer.. */ + status = nx_ppp_pap_enable(&ppp_client, generate_login, NX_NULL); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for Normal IP Instance. */ + status = nx_arp_enable(&ip_client, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP */ + status = nx_icmp_enable(&ip_client); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&thread_client, "thread client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + +} + +static void thread_client_entry(ULONG thread_input) +{ +UINT status; +ULONG ip_status; +NX_PACKET *recv_pkt; +ULONG ip_address; +ULONG network_mask; + + /* Create the PPPoE instance. */ + status = nx_pppoe_client_create(&pppoe_client, (UCHAR *)"PPPoE Client", &ip_client, 0, &pool_client, pointer, PPPOE_THREAD_SIZE, 4, _nx_ram_network_driver, pppoe_client_packet_receive); + pointer = pointer + PPPOE_THREAD_SIZE; + if (status) + { + error_counter++; + } + + /* Set host unique. */ + status = nx_pppoe_client_host_uniq_set(&pppoe_client, "220000000000000041000000"); + if (status) + { + error_counter++; + } + + /* Set service name. */ + status = nx_pppoe_client_service_name_set(&pppoe_client, "BRAS"); + if (status) + { + error_counter++; + } + + /* Establish PPPoE Client sessione. */ + status = nx_pppoe_client_session_connect(&pppoe_client, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Wait for the link to come up. */ + status = nx_ip_interface_status_check(&ip_client, 0, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Check client IP address. */ + status = nx_ip_address_get(&ip_client, &ip_address, &network_mask); + if (status || ip_address != CLIENT_ADDRESS) + { + error_counter++; + } + + /* Ping test. */ + status = nx_icmp_ping(&ip_client, SERVER_ADDRESS, "abcd", 4, &recv_pkt, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + else + { + nx_packet_release(recv_pkt); + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* PPPoE Client receive function. */ +static void pppoe_client_packet_receive(NX_PACKET *packet_ptr) +{ + + /* Call PPP Client to receive the PPP data fame. */ + nx_ppp_packet_receive(&ppp_client, packet_ptr); +} + +/* PPP Client send function. */ +static void ppp_client_packet_send(NX_PACKET *packet_ptr) +{ + + /* Directly Call PPPoE send function to send out the data through PPPoE module. */ + nx_pppoe_client_session_packet_send(&pppoe_client, packet_ptr); +} + +/* Define the server threads. */ + +static void thread_server_entry(ULONG thread_input) +{ +UINT status; +ULONG ip_status; +UCHAR *nx_pppoe_service_name[] = +{ + "BRAS", + "PRINTER", + NX_NULL +}; +ULONG ip_address; +ULONG network_mask; + + + /* Print out test information banner. */ + printf("NetX Test: PPPoE API Test............................................"); + + /* Create the PPPoE instance. */ + status = nx_pppoe_server_create(&pppoe_server, (UCHAR *)"PPPoE Server", &ip_server, 0, _nx_ram_network_driver, &pool_server, pointer, PPPOE_THREAD_SIZE, 4); + pointer = pointer + PPPOE_THREAD_SIZE; + if (status) + { + error_counter++; + } + + /* Set the callback notify function. */ + status = nx_pppoe_server_callback_notify_set(&pppoe_server, NX_NULL, NX_NULL, NX_NULL, NX_NULL, pppoe_server_packet_receive, NX_NULL); + if (status) + { + error_counter++; + } + + /* Set service name. */ + status = nx_pppoe_server_service_name_set(&pppoe_server, nx_pppoe_service_name, 2); + if (status) + { + error_counter++; + } + + /* Enable PPPoE Server. */ + status = nx_pppoe_server_enable(&pppoe_server); + if (status) + { + error_counter++; + } + + tx_thread_resume(&thread_client); + + /* Wait for the link to come up. */ + status = nx_ip_interface_status_check(&ip_server, 0, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Check server IP address. */ + status = nx_ip_address_get(&ip_server, &ip_address, &network_mask); + if (status || ip_address != SERVER_ADDRESS) + { + error_counter++; + } +} + +static void pppoe_server_packet_receive(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id) +{ + +NX_PACKET *packet_ptr; + + /* Get the notify that receive the PPPoE Session data. */ + + /* Call PPP Server to receive the PPP data fame. */ + packet_ptr = (NX_PACKET *)(packet_id); + nx_ppp_packet_receive(&ppp_server, packet_ptr); +} + +/* PPP Server send function. */ +static void ppp_server_packet_send(NX_PACKET *packet_ptr) +{ + +/* For Express Logic's PPP test, the session should be the first session, so set interfaceHandle as 0. */ +UINT interfaceHandle = 0; + + /* Directly Call PPPoE send function to send out the data through PPPoE module. */ + nx_pppoe_server_session_packet_send(&pppoe_server, interfaceHandle, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pppoe_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPPoE API Test............................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/pppoe_test/netx_pppoe_basic_test.c b/test/regression/pppoe_test/netx_pppoe_basic_test.c new file mode 100644 index 00000000..59d2c211 --- /dev/null +++ b/test/regression/pppoe_test/netx_pppoe_basic_test.c @@ -0,0 +1,457 @@ +/* This case tests the basic connection of PPPoE server and client. */ + +#include "nx_pppoe_client.h" +#include "nx_pppoe_server.h" +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_PPP_PPPOE_ENABLE) && defined(NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE) && defined(NX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE) && (NX_PHYSICAL_HEADER >= 24) && !defined(NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE) + +/* Defined NX_PPP_PPPOE_ENABLE if use Express Logic's PPP, since PPP module has been modified to match PPPoE moduler under this definition. */ + +/* If the driver is not initialized in other module, define NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE to initialize the driver in PPPoE module . + In this demo, the driver has been initialized in IP module. */ + +/* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE: + If defined, enables the feature that controls the PPPoE session. + PPPoE server does not automatically response to the request until application call specific API. */ + +/* Define the block size. */ +#define NX_PACKET_POOL_SIZE ((1536 + sizeof(NX_PACKET)) * 12) +#define DEMO_STACK_SIZE 2048 +#define PPPOE_THREAD_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD thread_server; +static TX_THREAD thread_client; + +/* Define the packet pool and IP instance for normal IP instnace. */ +static NX_PACKET_POOL pool_server; +static NX_IP ip_server; +static NX_PACKET_POOL pool_client; +static NX_IP ip_client; +static CHAR pool_buffer_server[NX_PACKET_POOL_SIZE]; +static CHAR pool_buffer_client[NX_PACKET_POOL_SIZE]; + +/* Define the PPP Server instance. */ +static NX_PPP ppp_server; +static NX_PPP ppp_client; + +/* Define the PPPoE Server instance. */ +static NX_PPPOE_SERVER pppoe_server; +static NX_PPPOE_CLIENT pppoe_client; + +/* Define the counters. */ +static CHAR *pointer; +static ULONG error_counter; + +/* Define thread prototypes. */ +static void thread_server_entry(ULONG thread_input); +static void thread_client_entry(ULONG thread_input); + +/***** Substitute your PPP driver entry function here *********/ +extern void _nx_ppp_driver(NX_IP_DRIVER *driver_req_ptr); + +/***** Substitute your Ethernet driver entry function here *********/ +extern void _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); + +/* Define the callback functions. */ +static void pppoe_server_packet_receive(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id); + +/* Define the porting layer function for Express Logic's PPP. + Functions to be provided by PPP for calling by the PPPoE Stack. */ +static void ppp_server_packet_send(NX_PACKET *packet_ptr); + +/* Define the porting layer function for Express Logic's PPP. + Functions to be provided by PPP for calling by the PPPoE Stack. */ +static void ppp_client_packet_send(NX_PACKET *packet_ptr); +static void pppoe_client_packet_receive(NX_PACKET *packet_ptr); + +#define SERVER_ADDRESS IP_ADDRESS(192, 168, 10, 43) +#define CLIENT_ADDRESS IP_ADDRESS(192, 168, 10, 44) + +#define SERVICE_NAME_1 "test_service_1" +#define SERVICE_NAME_2 "test_service_2" + +static UINT generate_login(CHAR *name, CHAR *password) +{ + + /* Make a name and password, called "myname" and "mypassword". */ + name[0] = 'm'; + name[1] = 'y'; + name[2] = 'n'; + name[3] = 'a'; + name[4] = 'm'; + name[5] = 'e'; + name[6] = (CHAR) 0; + + password[0] = 'm'; + password[1] = 'y'; + password[2] = 'p'; + password[3] = 'a'; + password[4] = 's'; + password[5] = 's'; + password[6] = 'w'; + password[7] = 'o'; + password[8] = 'r'; + password[9] = 'd'; + password[10] = (CHAR) 0; + + return(NX_SUCCESS); +} + +static UINT verify_login(CHAR *name, CHAR *password) +{ + +if ((name[0] == 'm') && + (name[1] == 'y') && + (name[2] == 'n') && + (name[3] == 'a') && + (name[4] == 'm') && + (name[5] == 'e') && + (name[6] == (CHAR) 0) && + (password[0] == 'm') && + (password[1] == 'y') && + (password[2] == 'p') && + (password[3] == 'a') && + (password[4] == 's') && + (password[5] == 's') && + (password[6] == 'w') && + (password[7] == 'o') && + (password[8] == 'r') && + (password[9] == 'd') && + (password[10] == (CHAR) 0)) + return(NX_SUCCESS); + else + return(NX_PPP_ERROR); +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pppoe_basic_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool for normal IP instance. */ + status = nx_packet_pool_create(&pool_server, "Server Packet Pool", + (1536 + sizeof(NX_PACKET)), + pool_buffer_server, NX_PACKET_POOL_SIZE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create an normal IP instance. */ + status = nx_ip_create(&ip_server, "Server IP Instance", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_server, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_server, "PPP Server Instance", &ip_server, pointer, 2048, 1, &pool_server, NX_NULL, NX_NULL); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Set the PPP packet send function. */ + status = nx_ppp_packet_send_set(&ppp_server, ppp_server_packet_send); + + /* Check for PPP packet send function set error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_server, SERVER_ADDRESS, CLIENT_ADDRESS); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_pap_enable(&ppp_server, NX_NULL, verify_login); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for Normal IP Instance. */ + status = nx_arp_enable(&ip_server, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP */ + status = nx_icmp_enable(&ip_server); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&thread_server, "thread server", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create a packet pool for normal IP instance. */ + status = nx_packet_pool_create(&pool_client, "Client Packet Pool", + (1536 + sizeof(NX_PACKET)), + pool_buffer_client, NX_PACKET_POOL_SIZE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create an normal IP instance. */ + status = nx_ip_create(&ip_client, "Client IP Instance", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_client, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_client, "PPP Client Instance", &ip_client, pointer, 2048, 1, &pool_client, NX_NULL, NX_NULL); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Set the PPP packet send function. */ + status = nx_ppp_packet_send_set(&ppp_client, ppp_client_packet_send); + + /* Check for PPP packet send function set error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_client, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the since it generates the name and password for the peer.. */ + status = nx_ppp_pap_enable(&ppp_client, generate_login, NX_NULL); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for Normal IP Instance. */ + status = nx_arp_enable(&ip_client, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP */ + status = nx_icmp_enable(&ip_client); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&thread_client, "thread client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + +} + +static void thread_client_entry(ULONG thread_input) +{ +UINT status; +ULONG ip_status; +NX_PACKET *recv_pkt; +ULONG ip_address; +ULONG network_mask; + + /* Create the PPPoE instance. */ + status = nx_pppoe_client_create(&pppoe_client, (UCHAR *)"PPPoE Client", &ip_client, 0, &pool_client, pointer, PPPOE_THREAD_SIZE, 4, _nx_ram_network_driver, pppoe_client_packet_receive); + pointer = pointer + PPPOE_THREAD_SIZE; + if (status) + { + error_counter++; + } + + /* Set service name. */ + nx_pppoe_client_service_name_set(&pppoe_client, SERVICE_NAME_1); + + /* Establish PPPoE Client sessione. */ + status = nx_pppoe_client_session_connect(&pppoe_client, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Wait for the link to come up. */ + status = nx_ip_interface_status_check(&ip_client, 0, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Check client IP address. */ + status = nx_ip_address_get(&ip_client, &ip_address, &network_mask); + if (status || ip_address != CLIENT_ADDRESS) + { + error_counter++; + } + + /* Ping test. */ + status = nx_icmp_ping(&ip_client, SERVER_ADDRESS, "abcd", 4, &recv_pkt, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + else + { + nx_packet_release(recv_pkt); + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* PPPoE Client receive function. */ +static void pppoe_client_packet_receive(NX_PACKET *packet_ptr) +{ + + /* Call PPP Client to receive the PPP data fame. */ + nx_ppp_packet_receive(&ppp_client, packet_ptr); +} + +/* PPP Client send function. */ +static void ppp_client_packet_send(NX_PACKET *packet_ptr) +{ + + /* Directly Call PPPoE send function to send out the data through PPPoE module. */ + nx_pppoe_client_session_packet_send(&pppoe_client, packet_ptr); +} + +/* Define the server threads. */ + +static void thread_server_entry(ULONG thread_input) +{ +UINT status; +ULONG ip_status; +ULONG ip_address; +ULONG network_mask; +UCHAR *service_names[2]; +UINT service_names_count = 2; + + /* Print out test information banner. */ + printf("NetX Test: PPPoE Basic Test.........................................."); + + /* Create the PPPoE instance. */ + status = nx_pppoe_server_create(&pppoe_server, (UCHAR *)"PPPoE Server", &ip_server, 0, _nx_ram_network_driver, &pool_server, pointer, PPPOE_THREAD_SIZE, 4); + pointer = pointer + PPPOE_THREAD_SIZE; + if (status) + { + error_counter++; + } + + /* Set the callback notify function. */ + status = nx_pppoe_server_callback_notify_set(&pppoe_server, NX_NULL, NX_NULL, NX_NULL, NX_NULL, pppoe_server_packet_receive, NX_NULL); + if (status) + { + error_counter++; + } + + /* Set service name. */ + service_names[0] = SERVICE_NAME_1; + service_names[1] = SERVICE_NAME_2; + nx_pppoe_server_service_name_set(&pppoe_server, service_names, service_names_count); + + /* Enable PPPoE Server. */ + status = nx_pppoe_server_enable(&pppoe_server); + if (status) + { + error_counter++; + } + + tx_thread_resume(&thread_client); + + /* Wait for the link to come up. */ + status = nx_ip_interface_status_check(&ip_server, 0, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Check server IP address. */ + status = nx_ip_address_get(&ip_server, &ip_address, &network_mask); + if (status || ip_address != SERVER_ADDRESS) + { + error_counter++; + } +} + +static void pppoe_server_packet_receive(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id) +{ + +NX_PACKET *packet_ptr; + + /* Get the notify that receive the PPPoE Session data. */ + + /* Call PPP Server to receive the PPP data fame. */ + packet_ptr = (NX_PACKET *)(packet_id); + nx_ppp_packet_receive(&ppp_server, packet_ptr); +} + +/* PPP Server send function. */ +static void ppp_server_packet_send(NX_PACKET *packet_ptr) +{ + +/* For Express Logic's PPP test, the session should be the first session, so set interfaceHandle as 0. */ +UINT interfaceHandle = 0; + + /* Directly Call PPPoE send function to send out the data through PPPoE module. */ + nx_pppoe_server_session_packet_send(&pppoe_server, interfaceHandle, packet_ptr); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pppoe_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPPoE Basic Test..........................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/pppoe_test/netx_pppoe_session_control_test.c b/test/regression/pppoe_test/netx_pppoe_session_control_test.c new file mode 100644 index 00000000..fbe55af9 --- /dev/null +++ b/test/regression/pppoe_test/netx_pppoe_session_control_test.c @@ -0,0 +1,542 @@ +/* This case tests the basic connection when session control is enabled. */ + +#include "tx_api.h" +#include "nx_api.h" +#include "nx_ppp.h" +#include "nx_pppoe_server.h" +#include "nx_pppoe_client.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(NX_PPP_PPPOE_ENABLE) && defined(NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE) && defined(NX_PPPOE_CLIENT_INITIALIZE_DRIVER_ENABLE) && (NX_PHYSICAL_HEADER >= 24) + +/* Defined NX_PPP_PPPOE_ENABLE if use Express Logic's PPP, since PPP module has been modified to match PPPoE moduler under this definition. */ + +/* If the driver is not initialized in other module, define NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE to initialize the driver in PPPoE module . + In this demo, the driver has been initialized in IP module. */ + +/* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE: + If defined, enables the feature that controls the PPPoE session. + PPPoE server does not automatically response to the request until application call specific API. */ + +/* Define the block size. */ +#define NX_PACKET_POOL_SIZE ((1536 + sizeof(NX_PACKET)) * 20) +#define DEMO_STACK_SIZE 2048 +#define PPPOE_THREAD_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ +static TX_THREAD thread_server; +static TX_THREAD thread_client; + +/* Define the packet pool and IP instance for normal IP instnace. */ +static NX_PACKET_POOL pool_server; +static NX_IP ip_server; +static NX_PACKET_POOL pool_client; +static NX_IP ip_client; +static CHAR pool_buffer_server[NX_PACKET_POOL_SIZE]; +static CHAR pool_buffer_client[NX_PACKET_POOL_SIZE]; + +/* Define the PPP Server instance. */ +static NX_PPP ppp_server; +static NX_PPP ppp_client; + +/* Define the PPPoE Server instance. */ +static NX_PPPOE_SERVER pppoe_server; +static NX_PPPOE_CLIENT pppoe_client; + +/* Define the counters. */ +static CHAR *pointer; +static ULONG error_counter; + +/* Define thread prototypes. */ +static void thread_server_entry(ULONG thread_input); +static void thread_client_entry(ULONG thread_input); + +/***** Substitute your PPP driver entry function here *********/ +extern void _nx_ppp_driver(NX_IP_DRIVER *driver_req_ptr); + +/***** Substitute your Ethernet driver entry function here *********/ +extern void _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr); + +/* Define the porting layer function for Express Logic's PPP. + Functions to be provided by PPP for calling by the PPPoE Stack. */ +static void ppp_server_packet_send(NX_PACKET *packet_ptr); + +/* Define the porting layer function for Express Logic's PPP. + Functions to be provided by PPP for calling by the PPPoE Stack. */ +static void ppp_client_packet_send(NX_PACKET *packet_ptr); +static void pppoe_client_packet_receive(NX_PACKET *packet_ptr); + +/* Define the callback functions. */ +static void PppDiscoverReq(UINT interfaceHandle); +static void PppOpenReq(UINT interfaceHandle, ULONG length, UCHAR *data); +static void PppCloseRsp(UINT interfaceHandle); +static void PppCloseReq(UINT interfaceHandle); +static void PppTransmitDataReq(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id); +static void PppReceiveDataRsp(UINT interfaceHandle, UCHAR *data); + +#define SERVER_ADDRESS IP_ADDRESS(192, 168, 10, 43) +#define CLIENT_ADDRESS IP_ADDRESS(192, 168, 10, 44) + +#define SERVICE_NAME_1 "test_service_1" +#define SERVICE_NAME_2 "test_service_2" +#define SERVICES "test_service_1\0test_service_2" + +static UINT generate_login(CHAR *name, CHAR *password) +{ + + /* Make a name and password, called "myname" and "mypassword". */ + name[0] = 'm'; + name[1] = 'y'; + name[2] = 'n'; + name[3] = 'a'; + name[4] = 'm'; + name[5] = 'e'; + name[6] = (CHAR) 0; + + password[0] = 'm'; + password[1] = 'y'; + password[2] = 'p'; + password[3] = 'a'; + password[4] = 's'; + password[5] = 's'; + password[6] = 'w'; + password[7] = 'o'; + password[8] = 'r'; + password[9] = 'd'; + password[10] = (CHAR) 0; + + return(NX_SUCCESS); +} + +static UINT verify_login(CHAR *name, CHAR *password) +{ + +if ((name[0] == 'm') && + (name[1] == 'y') && + (name[2] == 'n') && + (name[3] == 'a') && + (name[4] == 'm') && + (name[5] == 'e') && + (name[6] == (CHAR) 0) && + (password[0] == 'm') && + (password[1] == 'y') && + (password[2] == 'p') && + (password[3] == 'a') && + (password[4] == 's') && + (password[5] == 's') && + (password[6] == 'w') && + (password[7] == 'o') && + (password[8] == 'r') && + (password[9] == 'd') && + (password[10] == (CHAR) 0)) + return(NX_SUCCESS); + else + return(NX_PPP_ERROR); +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pppoe_session_control_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool for normal IP instance. */ + status = nx_packet_pool_create(&pool_server, "Server Packet Pool", + (1536 + sizeof(NX_PACKET)), + pool_buffer_server, NX_PACKET_POOL_SIZE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create an normal IP instance. */ + status = nx_ip_create(&ip_server, "Server IP Instance", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_server, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_server, "PPP Server Instance", &ip_server, pointer, 2048, 1, &pool_server, NX_NULL, NX_NULL); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Set the PPP packet send function. */ + status = nx_ppp_packet_send_set(&ppp_server, ppp_server_packet_send); + + /* Check for PPP packet send function set error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_server, SERVER_ADDRESS, CLIENT_ADDRESS); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */ + status = nx_ppp_pap_enable(&ppp_server, NX_NULL, verify_login); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for Normal IP Instance. */ + status = nx_arp_enable(&ip_server, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP */ + status = nx_icmp_enable(&ip_server); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&thread_server, "thread server", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 5, 5, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create a packet pool for normal IP instance. */ + status = nx_packet_pool_create(&pool_client, "Client Packet Pool", + (1536 + sizeof(NX_PACKET)), + pool_buffer_client, NX_PACKET_POOL_SIZE); + + /* Check for error. */ + if (status) + error_counter++; + + /* Create an normal IP instance. */ + status = nx_ip_create(&ip_client, "Client IP Instance", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_client, nx_ppp_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for error. */ + if (status) + error_counter++; + + /* Create the PPP instance. */ + status = nx_ppp_create(&ppp_client, "PPP Client Instance", &ip_client, pointer, 2048, 1, &pool_client, NX_NULL, NX_NULL); + pointer = pointer + 2048; + + /* Check for PPP create error. */ + if (status) + error_counter++; + + /* Set the PPP packet send function. */ + status = nx_ppp_packet_send_set(&ppp_client, ppp_client_packet_send); + + /* Check for PPP packet send function set error. */ + if (status) + error_counter++; + + /* Define IP address. This PPP instance is effectively the client since it doesn't have any IP addresses. */ + status = nx_ppp_ip_address_assign(&ppp_client, IP_ADDRESS(0, 0, 0, 0), IP_ADDRESS(0, 0, 0, 0)); + + /* Check for PPP IP address assign error. */ + if (status) + error_counter++; + + /* Setup PAP, this PPP instance is effectively the since it generates the name and password for the peer.. */ + status = nx_ppp_pap_enable(&ppp_client, generate_login, NX_NULL); + + /* Check for PPP PAP enable error. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for Normal IP Instance. */ + status = nx_arp_enable(&ip_client, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable ICMP */ + status = nx_icmp_enable(&ip_client); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&thread_client, "thread client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_DONT_START); + pointer = pointer + DEMO_STACK_SIZE; + +} + +static void thread_client_entry(ULONG thread_input) +{ +UINT status; +ULONG ip_status; +NX_PACKET *recv_pkt; +ULONG ip_address; +ULONG network_mask; + + /* Create the PPPoE instance. */ + status = nx_pppoe_client_create(&pppoe_client, (UCHAR *)"PPPoE Client", &ip_client, 0, &pool_client, pointer, PPPOE_THREAD_SIZE, 4, _nx_ram_network_driver, pppoe_client_packet_receive); + pointer = pointer + PPPOE_THREAD_SIZE; + if (status) + { + error_counter++; + } + + /* Set service name. */ + nx_pppoe_client_service_name_set(&pppoe_client, SERVICE_NAME_1); + + /* Establish PPPoE Client sessione. */ + status = nx_pppoe_client_session_connect(&pppoe_client, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Wait for the link to come up. */ + status = nx_ip_interface_status_check(&ip_client, 0, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Check client IP address. */ + status = nx_ip_address_get(&ip_client, &ip_address, &network_mask); + if (status || ip_address != CLIENT_ADDRESS) + { + error_counter++; + } + + /* Ping test. */ + status = nx_icmp_ping(&ip_client, SERVER_ADDRESS, "abcd", 4, &recv_pkt, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + else + { + nx_packet_release(recv_pkt); + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* PPPoE Client receive function. */ +static void pppoe_client_packet_receive(NX_PACKET *packet_ptr) +{ + + /* Call PPP Client to receive the PPP data fame. */ + nx_ppp_packet_receive(&ppp_client, packet_ptr); +} + +/* PPP Client send function. */ +static void ppp_client_packet_send(NX_PACKET *packet_ptr) +{ + + /* Directly Call PPPoE send function to send out the data through PPPoE module. */ + nx_pppoe_client_session_packet_send(&pppoe_client, packet_ptr); +} + +/* Define the server threads. */ + +static void thread_server_entry(ULONG thread_input) +{ +UINT status; +ULONG ip_status; +ULONG ip_address; +ULONG network_mask; +#ifndef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE +UCHAR *service_names[2]; +UINT service_names_count = 2; +#endif + + /* Print out test information banner. */ + printf("NetX Test: PPPoE Session Control Test................................"); + + /* Create the PPPoE instance. */ + status = nx_pppoe_server_create(&pppoe_server, (UCHAR *)"PPPoE Server", &ip_server, 0, _nx_ram_network_driver, &pool_server, pointer, PPPOE_THREAD_SIZE, 4); + pointer = pointer + PPPOE_THREAD_SIZE; + if (status) + { + error_counter++; + } + + /* Set the callback notify function. */ + status = nx_pppoe_server_callback_notify_set(&pppoe_server, PppDiscoverReq, PppOpenReq, PppCloseRsp, PppCloseReq, PppTransmitDataReq, PppReceiveDataRsp); + if (status) + { + error_counter++; + return; + } + +#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE + + /* Call function to set the default service Name. */ + PppInitInd(sizeof(SERVICE_NAME_1), SERVICE_NAME_1); +#else + + /* Set the service Name. */ + service_names[0] = SERVICE_NAME_1; + service_names[1] = SERVICE_NAME_2; + nx_pppoe_server_service_name_set(&pppoe_server, service_names, service_names_count); +#endif + + /* Enable PPPoE Server. */ + status = nx_pppoe_server_enable(&pppoe_server); + if (status) + { + error_counter++; + } + + tx_thread_resume(&thread_client); + + /* Wait for the link to come up. */ + status = nx_ip_interface_status_check(&ip_server, 0, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER); + if (status) + { + error_counter++; + } + + /* Check server IP address. */ + status = nx_ip_address_get(&ip_server, &ip_address, &network_mask); + if (status || ip_address != SERVER_ADDRESS) + { + error_counter++; + } +} + +void PppDiscoverReq(UINT interfaceHandle) +{ + + /* Receive the PPPoE Discovery Initiation Message. */ + +#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE + /* Call PPPoE function to allow TTP's software to define the Service Name field of the PADO packet. */ + PppDiscoverCnf(sizeof(SERVICES), SERVICES, interfaceHandle); +#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */ +} + +void PppOpenReq(UINT interfaceHandle, ULONG length, UCHAR *data) +{ + + /* Get the notify that receive the PPPoE Discovery Request Message. */ + +#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE + /* Call PPPoE function to allow TTP's software to accept the PPPoE session. */ + PppOpenCnf(NX_TRUE, interfaceHandle); +#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */ +} + +void PppCloseRsp(UINT interfaceHandle) +{ + + /* Get the notify that receive the PPPoE Discovery Terminate Message. */ + +#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE + /* Call PPPoE function to allow TTP's software to confirm that the handle has been freed. */ + PppCloseCnf(interfaceHandle); +#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */ +} + +void PppCloseReq(UINT interfaceHandle) +{ + + /* Get the notify that PPPoE Discovery Terminate Message has been sent. */ + +} + +void PppReceiveDataRsp(UINT interfaceHandle, UCHAR *data) +{ + + /* Get the notify that the PPPoE Session data has been sent. */ + +} + +static void PppTransmitDataReq(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id) +{ + +NX_PACKET *packet_ptr; + + /* Get the notify that receive the PPPoE Session data. */ + + /* Call PPP Server to receive the PPP data fame. */ + packet_ptr = (NX_PACKET *)(packet_id); + nx_ppp_packet_receive(&ppp_server, packet_ptr); + +#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE + /* Call PPPoE function to confirm that the data has been processed. */ + PppTransmitDataCnf(interfaceHandle, data, 0); +#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */ +} + +/* PPP Server send function. */ +static void ppp_server_packet_send(NX_PACKET *packet_ptr) +{ + +/* For Express Logic's PPP test, the session should be the first session, so set interfaceHandle as 0. */ +UINT interfaceHandle = 0; + +#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE +NX_PACKET *temp_packet = packet_ptr; + + while(packet_ptr) + { + + /* Call functions to be provided by PPPoE for TTP. */ + PppReceiveDataInd(interfaceHandle, (packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr), packet_ptr -> nx_packet_prepend_ptr); + + /* Move to the next packet structure. */ + packet_ptr = packet_ptr -> nx_packet_next; + } + + nx_packet_transmit_release(temp_packet); +#else + + /* Directly Call PPPoE send function to send out the data through PPPoE module. */ + nx_pppoe_server_session_packet_send(&pppoe_server, interfaceHandle, packet_ptr); +#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */ +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_pppoe_session_control_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: PPPoE Session Control Test................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/ptp_test/netx_ptp_client_announce_timeout_test.c b/test/regression/ptp_test/netx_ptp_client_announce_timeout_test.c new file mode 100644 index 00000000..49ba4779 --- /dev/null +++ b/test/regression/ptp_test/netx_ptp_client_announce_timeout_test.c @@ -0,0 +1,254 @@ +/* PTP Announce test. This test case validates on Announce timeout, PTP client will trigger an event. */ + +#include "netx_ptp_utility.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET generic_socket; +static NX_UDP_SOCKET event_socket; +static NX_PTP_CLIENT ptp_client; + +static NX_PTP_TIME sync_ts = {0x0, 0x5F97CD71, 0x240d93b2}; +static NX_PTP_TIME follow_up_ts = {0x0, 0x5F97CD71, 0x240e29e0}; +static NX_PTP_TIME delay_response_ts = {0x0, 0x5F97CD71, 0x2494b730}; +static NX_PTP_TIME synced_time; +static NX_PTP_TIME expected_time; +static USHORT synced_utc_offset; +static USHORT expected_utc_offset; +static UCHAR ptp_stack[2048]; +static UCHAR ptp_sync_received = NX_FALSE; +static UCHAR ptp_announce_timeout = NX_FALSE; +static ULONG ptp_announce_tick = 0; +static ULONG ptp_announce_timeout_tick = 0; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ptp_client_announce_timeout_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: PTP Announce Timeout Test ................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + ASSERT_SUCCESS(status); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + ASSERT_SUCCESS(status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + ASSERT_SUCCESS(status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check UDP enable status. */ + if(status) + ASSERT_SUCCESS(status); +} + + +/* PTP handler. */ +static UINT ptp_event_callback(NX_PTP_CLIENT *ptp_client_ptr, UINT event, VOID *event_data, VOID *callback_data) +{ +NX_PTP_DATE_TIME date; + + NX_PARAMETER_NOT_USED(callback_data); + + switch (event) + { + case NX_PTP_CLIENT_EVENT_MASTER: + { + DBGPRINTF("new MASTER clock!\r\n"); + + ptp_announce_tick = tx_time_get(); + break; + } + + case NX_PTP_CLIENT_EVENT_SYNC: + { + nx_ptp_client_sync_info_get((NX_PTP_CLIENT_SYNC *)event_data, NX_NULL, &synced_utc_offset); + DBGPRINTF("SYNC event: utc offset=%d\r\n", synced_utc_offset); + + /* read the PTP clock */ + nx_ptp_client_time_get(ptp_client_ptr, &synced_time); + + /* convert PTP time to UTC date and time */ + nx_ptp_client_utility_convert_time_to_date(&synced_time, -synced_utc_offset, &date); + + /* display the current time */ + DBGPRINTF("ts: %d%d.%d\r\n", synced_time.second_high, + synced_time.second_low, + synced_time.nanosecond); + DBGPRINTF("%2u/%02u/%u %02u:%02u:%02u.%09lu\r\n", date.day, date.month, date.year, + date.hour, date.minute, date.second, + date.nanosecond); + + ASSERT_TRUE(ptp_sync_received == NX_FALSE); + ptp_sync_received = NX_TRUE; + break; + } + + case NX_PTP_CLIENT_EVENT_TIMEOUT: + { + DBGPRINTF("Master clock TIMEOUT!\r\n"); + + ASSERT_TRUE(ptp_announce_timeout == NX_FALSE); + ptp_announce_timeout = NX_TRUE; + ptp_announce_timeout_tick = tx_time_get(); + break; + } + default: + { + break; + } + } + + return(0); +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +UINT timeout_ticks; + + /* Reset synced time. */ + memset(&synced_time, 0, sizeof(synced_time)); + synced_utc_offset = 0xFFFF; + + /* Set expected value. */ + expected_utc_offset = 0x1234; + expected_time.second_high = (delay_response_ts.second_high + follow_up_ts.second_high) / 2; + expected_time.second_low = (delay_response_ts.second_low + follow_up_ts.second_low) / 2; + expected_time.nanosecond = (delay_response_ts.nanosecond + follow_up_ts.nanosecond) / 2; + + /* Create the PTP client instance */ + status = nx_ptp_client_create(&ptp_client, &ip_0, 0, &pool_0, + 2, ptp_stack, sizeof(ptp_stack), + nx_ptp_client_soft_clock_callback, NX_NULL); + ASSERT_SUCCESS(status); + + /* start the PTP client */ + status = nx_ptp_client_start(&ptp_client, NX_NULL, 0, 0, 0, ptp_event_callback, NX_NULL); + ASSERT_SUCCESS(status); + + /* Sleep 5 seconds for sync up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Validate PTP clock synced. */ + ASSERT_TRUE(ptp_sync_received); + + /* Sleep until timeout. */ + timeout_ticks = NX_PTP_CLIENT_ANNOUNCE_RECEIPT_TIMEOUT * + (1 << NX_PTP_CLIENT_LOG_ANNOUNCE_INTERVAL) * + NX_IP_PERIODIC_RATE; + tx_thread_sleep(timeout_ticks); + + /* Validate PTP clock timeout. */ + ASSERT_TRUE(ptp_announce_timeout); + + /* Validate ticks elasped for Announce timeout. */ + ASSERT_TRUE((ptp_announce_timeout_tick - ptp_announce_tick) > (timeout_ticks - TX_TIMER_TICKS_PER_SECOND / NX_PTP_CLIENT_TIMER_TICKS_PER_SECOND)); + ASSERT_TRUE((ptp_announce_timeout_tick - ptp_announce_tick) <= timeout_ticks); + + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* This thread acts as PTP server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +DELAY_REQUEST_CONTEXT context; +UINT status; + + create_socket(&ip_1, &generic_socket, PTP_GENERAL_UDP_PORT); + create_socket(&ip_1, &event_socket, PTP_EVENT_UDP_PORT); + + /* Sleep 1 second to wait for PTP thread running. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Send announce. */ + send_announce(&generic_socket, &pool_0, expected_utc_offset); + + /* Send sync. */ + send_sync(&event_socket, &pool_0, &sync_ts); + + /* Send follow up. */ + send_follow_up(&generic_socket, &pool_0, &follow_up_ts); + + /* Wait for delay request. */ + status = receive_delay_request(&event_socket, &context, NX_WAIT_FOREVER); + ASSERT_SUCCESS(status); + + /* Send delay response. */ + send_delay_response(&generic_socket, &pool_0, &context, &delay_response_ts); +} \ No newline at end of file diff --git a/test/regression/ptp_test/netx_ptp_client_api_test.c b/test/regression/ptp_test/netx_ptp_client_api_test.c new file mode 100644 index 00000000..71b5de61 --- /dev/null +++ b/test/regression/ptp_test/netx_ptp_client_api_test.c @@ -0,0 +1,279 @@ +/* PTP API test. This test case extends the basic test case to cover API not tested by others. */ + +#include "netx_ptp_utility.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET generic_socket; +static NX_UDP_SOCKET event_socket; +static NX_PTP_CLIENT ptp_client; + +static NX_PTP_TIME sync_ts = {0x0, 0x5F97CD71, 0x240d93b2}; +static NX_PTP_TIME follow_up_ts = {0x0, 0x5F97CD71, 0x240e29e0}; +static NX_PTP_TIME delay_response_ts = {0x0, 0x5F97CD71, 0x2494b730}; +static NX_PTP_TIME synced_time; +static NX_PTP_TIME expected_time; +static USHORT synced_utc_offset; +static USHORT expected_utc_offset; +static UCHAR ptp_stack[2048]; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ptp_client_api_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: PTP API Test ............................................."); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + ASSERT_SUCCESS(status); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + ASSERT_SUCCESS(status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + ASSERT_SUCCESS(status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check UDP enable status. */ + if(status) + ASSERT_SUCCESS(status); +} + + +/* PTP handler. */ +static UINT ptp_event_callback(NX_PTP_CLIENT *ptp_client_ptr, UINT event, VOID *event_data, VOID *callback_data) +{ +NX_PTP_DATE_TIME date; +NXD_ADDRESS address; +UCHAR *port_identity; +UINT port_identity_length; +UCHAR priority1, priority2; +UCHAR clock_class, clock_accuracy; +USHORT clock_variance; +UCHAR *grandmaster_identity; +UINT grandmaster_identity_length; +USHORT steps_removed; +UCHAR time_source; + + NX_PARAMETER_NOT_USED(callback_data); + + switch (event) + { + case NX_PTP_CLIENT_EVENT_MASTER: + { + DBGPRINTF("new MASTER clock!\r\n"); + nx_ptp_client_master_info_get((NX_PTP_CLIENT_MASTER *)event_data, &address, &port_identity, + &port_identity_length, &priority1, &priority2, &clock_class, + &clock_accuracy, &clock_variance, &grandmaster_identity, + &grandmaster_identity_length, &steps_removed, &time_source); + ASSERT_TRUE(address.nxd_ip_address.v4 == IP_ADDRESS(1, 2, 3, 5)); + ASSERT_TRUE(address.nxd_ip_version == NX_IP_VERSION_V4); + ASSERT_TRUE(port_identity_length == NX_PTP_CLOCK_PORT_IDENTITY_SIZE); + ASSERT_SUCCESS(memcmp(port_identity, "\x46\xe7\xc8\xff\xfe\x71\x61\xa1\x00\x01", port_identity_length)); + ASSERT_TRUE(priority1 == 128); + ASSERT_TRUE(priority2 == 128); + ASSERT_TRUE(clock_class == 127); + ASSERT_TRUE(clock_accuracy == 0xfe); + ASSERT_TRUE(clock_variance == 0x7060); + ASSERT_TRUE(grandmaster_identity_length == NX_PTP_CLOCK_IDENTITY_SIZE); + ASSERT_SUCCESS(memcmp(grandmaster_identity, "\x46\xe7\xc8\xff\xfe\x71\x61\xa1\x00\x00", port_identity_length)); + ASSERT_TRUE(steps_removed == 0); + ASSERT_TRUE(time_source == 0xa0); + break; + } + + case NX_PTP_CLIENT_EVENT_SYNC: + { + nx_ptp_client_sync_info_get((NX_PTP_CLIENT_SYNC *)event_data, NX_NULL, &synced_utc_offset); + DBGPRINTF("SYNC event: utc offset=%d\r\n", synced_utc_offset); + + /* read the PTP clock */ + nx_ptp_client_time_get(ptp_client_ptr, &synced_time); + + /* convert PTP time to UTC date and time */ + nx_ptp_client_utility_convert_time_to_date(&synced_time, -synced_utc_offset, &date); + + /* display the current time */ + DBGPRINTF("ts: %d%d.%d\r\n", synced_time.second_high, + synced_time.second_low, + synced_time.nanosecond); + DBGPRINTF("%2u/%02u/%u %02u:%02u:%02u.%09lu\r\n", date.day, date.month, date.year, + date.hour, date.minute, date.second, + date.nanosecond); + + break; + } + + case NX_PTP_CLIENT_EVENT_TIMEOUT: + { + DBGPRINTF("Master clock TIMEOUT!\r\n"); + break; + } + default: + { + break; + } + } + + return(0); +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PTP_TIME ts_zero = {0}; +NX_PTP_TIME ts_diff = {1, 1, 1}; + + /* Reset synced time. */ + memset(&synced_time, 0, sizeof(synced_time)); + synced_utc_offset = 0xFFFF; + + /* Set expected value. */ + expected_utc_offset = 0x1234; + expected_time.second_high = (delay_response_ts.second_high + follow_up_ts.second_high) / 2; + expected_time.second_low = (delay_response_ts.second_low + follow_up_ts.second_low) / 2; + expected_time.nanosecond = (delay_response_ts.nanosecond + follow_up_ts.nanosecond) / 2; + + /* Create the PTP client instance */ + status = nx_ptp_client_create(&ptp_client, &ip_0, 0, &pool_0, + 2, ptp_stack, sizeof(ptp_stack), + nx_ptp_client_soft_clock_callback, NX_NULL); + ASSERT_SUCCESS(status); + + /* Set timestamp to all zero. */ + status = nx_ptp_client_time_set(&ptp_client, &ts_zero); + ASSERT_SUCCESS(status); + + /* start the PTP client */ + status = nx_ptp_client_start(&ptp_client, NX_NULL, 0, 0, 0, ptp_event_callback, NX_NULL); + ASSERT_SUCCESS(status); + + /* Sleep 5 seconds for sync up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Compare synced time. */ + ASSERT_TRUE(synced_utc_offset == expected_utc_offset); + + /* Set timestamp to all zero when PTP already started. */ + status = nx_ptp_client_time_set(&ptp_client, &ts_zero); + ASSERT_TRUE(status == NX_PTP_CLIENT_ALREADY_STARTED); + + /* Diff time. */ + status = nx_ptp_client_utility_time_diff(&synced_time, &expected_time, &ts_diff); + ASSERT_SUCCESS(status); + ASSERT_TRUE(ts_diff.second_high == 0); + ASSERT_TRUE(ts_diff.second_low == 0); + ASSERT_TRUE(ts_diff.nanosecond / 1000000 <= 1000 / NX_PTP_CLIENT_TIMER_TICKS_PER_SECOND); + + /* Cleanup */ + status = nx_ptp_client_stop(&ptp_client); + ASSERT_SUCCESS(status); + + status = nx_ptp_client_delete(&ptp_client); + ASSERT_SUCCESS(status); + + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* This thread acts as PTP server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +DELAY_REQUEST_CONTEXT context; +UINT status; + + create_socket(&ip_1, &generic_socket, PTP_GENERAL_UDP_PORT); + create_socket(&ip_1, &event_socket, PTP_EVENT_UDP_PORT); + + /* Sleep 1 second to wait for PTP thread running. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Send announce. */ + send_announce(&generic_socket, &pool_0, expected_utc_offset); + + /* Send sync. */ + send_sync(&event_socket, &pool_0, &sync_ts); + + /* Send follow up. */ + send_follow_up(&generic_socket, &pool_0, &follow_up_ts); + + /* Wait for delay request. */ + status = receive_delay_request(&event_socket, &context, NX_WAIT_FOREVER); + ASSERT_SUCCESS(status); + + /* Send delay response. */ + send_delay_response(&generic_socket, &pool_0, &context, &delay_response_ts); +} \ No newline at end of file diff --git a/test/regression/ptp_test/netx_ptp_client_basic_test.c b/test/regression/ptp_test/netx_ptp_client_basic_test.c new file mode 100644 index 00000000..af7121ac --- /dev/null +++ b/test/regression/ptp_test/netx_ptp_client_basic_test.c @@ -0,0 +1,234 @@ +/* PTP basic test. This test case validates basic procedure of PTP client synchronize. */ + +#include "netx_ptp_utility.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET generic_socket; +static NX_UDP_SOCKET event_socket; +static NX_PTP_CLIENT ptp_client; + +static NX_PTP_TIME sync_ts = {0x0, 0x5F97CD71, 0x240d93b2}; +static NX_PTP_TIME follow_up_ts = {0x0, 0x5F97CD71, 0x240e29e0}; +static NX_PTP_TIME delay_response_ts = {0x0, 0x5F97CD71, 0x2494b730}; +static NX_PTP_TIME synced_time; +static NX_PTP_TIME expected_time; +static USHORT synced_utc_offset; +static USHORT expected_utc_offset; +static UCHAR ptp_stack[2048]; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ptp_client_basic_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: PTP Basic Test ..........................................."); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + ASSERT_SUCCESS(status); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + ASSERT_SUCCESS(status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + ASSERT_SUCCESS(status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check UDP enable status. */ + if(status) + ASSERT_SUCCESS(status); +} + + +/* PTP handler. */ +static UINT ptp_event_callback(NX_PTP_CLIENT *ptp_client_ptr, UINT event, VOID *event_data, VOID *callback_data) +{ +NX_PTP_DATE_TIME date; + + NX_PARAMETER_NOT_USED(callback_data); + + switch (event) + { + case NX_PTP_CLIENT_EVENT_MASTER: + { + DBGPRINTF("new MASTER clock!\r\n"); + break; + } + + case NX_PTP_CLIENT_EVENT_SYNC: + { + nx_ptp_client_sync_info_get((NX_PTP_CLIENT_SYNC *)event_data, NX_NULL, &synced_utc_offset); + DBGPRINTF("SYNC event: utc offset=%d\r\n", synced_utc_offset); + + /* read the PTP clock */ + nx_ptp_client_time_get(ptp_client_ptr, &synced_time); + + /* convert PTP time to UTC date and time */ + nx_ptp_client_utility_convert_time_to_date(&synced_time, -synced_utc_offset, &date); + + /* display the current time */ + DBGPRINTF("ts: %d%d.%d\r\n", synced_time.second_high, + synced_time.second_low, + synced_time.nanosecond); + DBGPRINTF("%2u/%02u/%u %02u:%02u:%02u.%09lu\r\n", date.day, date.month, date.year, + date.hour, date.minute, date.second, + date.nanosecond); + + break; + } + + case NX_PTP_CLIENT_EVENT_TIMEOUT: + { + DBGPRINTF("Master clock TIMEOUT!\r\n"); + break; + } + default: + { + break; + } + } + + return(0); +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PTP_TIME ts_diff = {1, 1, 1}; + + /* Reset synced time. */ + memset(&synced_time, 0, sizeof(synced_time)); + synced_utc_offset = 0xFFFF; + + /* Set expected value. */ + expected_utc_offset = 0x1234; + expected_time.second_high = (delay_response_ts.second_high + follow_up_ts.second_high) / 2; + expected_time.second_low = (delay_response_ts.second_low + follow_up_ts.second_low) / 2; + expected_time.nanosecond = (delay_response_ts.nanosecond + follow_up_ts.nanosecond) / 2; + + /* Create the PTP client instance */ + status = nx_ptp_client_create(&ptp_client, &ip_0, 0, &pool_0, + 2, ptp_stack, sizeof(ptp_stack), + nx_ptp_client_soft_clock_callback, NX_NULL); + ASSERT_SUCCESS(status); + + /* start the PTP client */ + status = nx_ptp_client_start(&ptp_client, NX_NULL, 0, 0, 0, ptp_event_callback, NX_NULL); + ASSERT_SUCCESS(status); + + /* Sleep 5 seconds for sync up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Compare synced time. */ + ASSERT_TRUE(synced_utc_offset == expected_utc_offset); + status = nx_ptp_client_utility_time_diff(&synced_time, &expected_time, &ts_diff); + ASSERT_SUCCESS(status); + ASSERT_TRUE(ts_diff.second_high == 0); + ASSERT_TRUE(ts_diff.second_low == 0); + ASSERT_TRUE(ts_diff.nanosecond / 1000000 <= 1000 / NX_PTP_CLIENT_TIMER_TICKS_PER_SECOND); + + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* This thread acts as PTP server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +DELAY_REQUEST_CONTEXT context; +UINT status; + + create_socket(&ip_1, &generic_socket, PTP_GENERAL_UDP_PORT); + create_socket(&ip_1, &event_socket, PTP_EVENT_UDP_PORT); + + /* Sleep 1 second to wait for PTP thread running. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Send announce. */ + send_announce(&generic_socket, &pool_0, expected_utc_offset); + + /* Send sync. */ + send_sync(&event_socket, &pool_0, &sync_ts); + + /* Send follow up. */ + send_follow_up(&generic_socket, &pool_0, &follow_up_ts); + + /* Wait for delay request. */ + status = receive_delay_request(&event_socket, &context, NX_WAIT_FOREVER); + ASSERT_SUCCESS(status); + + /* Send delay response. */ + send_delay_response(&generic_socket, &pool_0, &context, &delay_response_ts); +} \ No newline at end of file diff --git a/test/regression/ptp_test/netx_ptp_client_calibrate_test.c b/test/regression/ptp_test/netx_ptp_client_calibrate_test.c new file mode 100644 index 00000000..6a9c892c --- /dev/null +++ b/test/regression/ptp_test/netx_ptp_client_calibrate_test.c @@ -0,0 +1,348 @@ +/* PTP calibrate test. This test case validates calibration of PTP client with different values. */ + +#include "netx_ptp_utility.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET generic_socket; +static NX_UDP_SOCKET event_socket; +static NX_PTP_CLIENT ptp_client; + +static NX_PTP_TIME sync_ts = {0x0, 0x5F97CD71, 0x240d93b2}; +static NX_PTP_TIME follow_up_ts = {0x0, 0x5F97CD71, 0x240e29e0}; +static NX_PTP_TIME delay_response_ts = {0x0, 0x5F97CD71, 0x2494b730}; +static NX_PTP_TIME synced_time; +static NX_PTP_TIME expected_time; +static USHORT synced_utc_offset; +static USHORT expected_utc_offset; +static UCHAR ptp_stack[2048]; +static UINT test_index; + +TEST_TIMESTAMP test_timestamps[] = +{ + + /* Basic */ + { + {0x0, 0x0, 0x0}, /* Sync */ + {0x0, 0x5F97CD71, 0x240e29e0}, /* FollowUp */ + {0x0, 0x5F97CD71, 0x2494b730}, /* DelayResponse */ + {0x0, 0x0, 0x0}, /* FollowUp_received */ + {0x0, 0x0, 0x0}, /* DelayRequest */ + }, + + /* offsetFromMaster is 0 */ + { + {0x0, 0x0, 0x0}, /* Sync */ + {0x0, 0x5F97CD71, 0x240e29e0}, /* FollowUp */ + {0x0, 0x5F97CD71, 0x2494b730}, /* DelayResponse */ + {0x0, 0x5F97CD71, 0x240e29e0}, /* FollowUp_received */ + {0x0, 0x5F97CD71, 0x2494b730}, /* DelayRequest */ + }, + + /* offsetFromMaster is positive and less than 1s */ + { + {0x0, 0x0, 0x0}, /* Sync */ + {0x0, 0x5F97CD71, 0x240e29e0}, /* FollowUp */ + {0x0, 0x5F97CD71, 0x2494b730}, /* DelayResponse */ + {0x0, 0x5F97CD71, 0x240e29e0}, /* FollowUp_received */ + {0x0, 0x5F97CD71, 0x2494b710}, /* DelayRequest */ + }, + + /* offsetFromMaster is positive and larger than 1s but need to increase second */ + { + {0x0, 0x0, 0x0}, /* Sync */ + {0x0, 0x5F97CD71, 0x240e29e0}, /* FollowUp */ + {0x0, 0x5F97CD71, 0x2494b730}, /* DelayResponse */ + {0x0, 0x5F97CD6F, 0x35efcce0}, /* FollowUp_received */ + {0x0, 0x5F97CD6F, 0x36765a10}, /* DelayRequest */ + }, + + /* offsetFromMaster is positive and less than 1s but the nanosecond will overflow */ + { + {0x0, 0x0, 0x0}, /* Sync */ + {0x0, 0x5F97CD71, 0x240e29e0}, /* FollowUp */ + {0x0, 0x5F97CD71, 0x2494b730}, /* DelayResponse */ + {0x0, 0x5F97CD70, 0x35efcce0}, /* FollowUp_received */ + {0x0, 0x5F97CD70, 0x36765a10}, /* DelayRequest */ + }, + + /* offsetFromMaster is negative and less than 1s */ + { + {0x0, 0x0, 0x0}, /* Sync */ + {0x0, 0x5F97CD71, 0x240e29e0}, /* FollowUp */ + {0x0, 0x5F97CD71, 0x2494b730}, /* DelayResponse */ + {0x0, 0x5F97CD71, 0x240e29f0}, /* FollowUp_received */ + {0x0, 0x5F97CD71, 0x2494b740}, /* DelayRequest */ + }, + + /* offsetFromMaster is negative and larger than 1s but need to decrease second */ + { + {0x0, 0x0, 0x0}, /* Sync */ + {0x0, 0x5F97CD71, 0x240e29e0}, /* FollowUp */ + {0x0, 0x5F97CD71, 0x2494b730}, /* DelayResponse */ + {0x0, 0x5F97CD73, 0x3b4d1760}, /* FollowUp_received */ + {0x0, 0x5F97CD74, 0x00000040}, /* DelayRequest */ + }, + + /* offsetFromMaster is negative and less than 1s but need to decrease second */ + { + {0x0, 0x0, 0x0}, /* Sync */ + {0x0, 0x5F97CD71, 0x240e29e0}, /* FollowUp */ + {0x0, 0x5F97CD71, 0x2494b730}, /* DelayResponse */ + {0x0, 0x5F97CD71, 0x3b4d1760}, /* FollowUp_received */ + {0x0, 0x5F97CD72, 0x00000040}, /* DelayRequest */ + }, +}; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ptp_client_calibrate_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: PTP Calibrate Test ......................................."); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + ASSERT_SUCCESS(status); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _netx_ptp_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + ASSERT_SUCCESS(status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + ASSERT_SUCCESS(status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check UDP enable status. */ + if(status) + ASSERT_SUCCESS(status); +} + + +/* PTP handler. */ +static UINT ptp_event_callback(NX_PTP_CLIENT *ptp_client_ptr, UINT event, VOID *event_data, VOID *callback_data) +{ +NX_PTP_DATE_TIME date; + + NX_PARAMETER_NOT_USED(callback_data); + + switch (event) + { + case NX_PTP_CLIENT_EVENT_MASTER: + { + DBGPRINTF("new MASTER clock!\r\n"); + break; + } + + case NX_PTP_CLIENT_EVENT_SYNC: + { + nx_ptp_client_sync_info_get((NX_PTP_CLIENT_SYNC *)event_data, NX_NULL, &synced_utc_offset); + DBGPRINTF("SYNC event: utc offset=%d\r\n", synced_utc_offset); + + /* read the PTP clock */ + nx_ptp_client_time_get(ptp_client_ptr, &synced_time); + + /* convert PTP time to UTC date and time */ + nx_ptp_client_utility_convert_time_to_date(&synced_time, -synced_utc_offset, &date); + + /* display the current time */ + DBGPRINTF("ts: %d%d.%d\r\n", synced_time.second_high, + synced_time.second_low, + synced_time.nanosecond); + DBGPRINTF("%2u/%02u/%u %02u:%02u:%02u.%09lu\r\n", date.day, date.month, date.year, + date.hour, date.minute, date.second, + date.nanosecond); + + break; + } + + case NX_PTP_CLIENT_EVENT_TIMEOUT: + { + DBGPRINTF("Master clock TIMEOUT!\r\n"); + break; + } + default: + { + break; + } + } + + return(0); +} + +/* Hijack callback function to modify timestamp. */ +static UINT clock_callback(NX_PTP_CLIENT *client_ptr, UINT operation, + NX_PTP_TIME *time_ptr, NX_PACKET *packet_ptr, + VOID *callback_data) +{ + if (operation == NX_PTP_CLIENT_CLOCK_PACKET_TS_PREPARE) + { + + /* Update DelayRequest timestamp. */ + clock_callback(client_ptr, NX_PTP_CLIENT_CLOCK_SET, + &test_timestamps[test_index].delay_request, NX_NULL, callback_data); + } + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + return(_netx_ptp_clock_callback(client_ptr, operation, time_ptr, packet_ptr, callback_data)); +#else + return(nx_ptp_client_soft_clock_callback(client_ptr, operation, time_ptr, packet_ptr, callback_data)); +#endif +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; + + /* Create the PTP client instance */ + status = nx_ptp_client_create(&ptp_client, &ip_0, 0, &pool_0, + 2, ptp_stack, sizeof(ptp_stack), + clock_callback, NX_NULL); + ASSERT_SUCCESS(status); + + for (test_index = 0; test_index < sizeof(test_timestamps) / sizeof(TEST_TIMESTAMP); test_index++) + { + + /* Start the PTP client */ + status = nx_ptp_client_start(&ptp_client, NX_NULL, 0, 0, 0, ptp_event_callback, NX_NULL); + ASSERT_SUCCESS(status); + + /* Reset synced time. */ + memset(&synced_time, 0, sizeof(synced_time)); + synced_utc_offset = 0xFFFF; + + /* Set expected value. */ + expected_utc_offset = 0x1234 + test_index; + calibrate_timestamp(&test_timestamps[test_index], &expected_time); + + /* Wake up server thread. */ + tx_thread_resume(&ntest_1); + + /* Sleep 5 seconds for sync up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Compare synced time. */ + ASSERT_TRUE(synced_utc_offset == expected_utc_offset); + ASSERT_SUCCESS(memcmp(&synced_time, &expected_time, sizeof(expected_time))); + + /* Stop the PTP client */ + status = nx_ptp_client_stop(&ptp_client); + ASSERT_SUCCESS(status); + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* This thread acts as PTP server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +DELAY_REQUEST_CONTEXT context; +UINT status; +UINT i; +UINT priority; + + create_socket(&ip_1, &generic_socket, PTP_GENERAL_UDP_PORT); + create_socket(&ip_1, &event_socket, PTP_EVENT_UDP_PORT); + + for (i = 0; i < sizeof(test_timestamps) / sizeof(TEST_TIMESTAMP); i++) + { + + /* Suspend current thread and wait for client thread. */ + tx_thread_suspend(tx_thread_identify()); + + /* Sleep 1 second to wait for PTP thread running. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Send announce. */ + send_announce(&generic_socket, &pool_0, expected_utc_offset); + + /* Set the timestamp of FollowUp received. */ + clock_callback(&ptp_client, NX_PTP_CLIENT_CLOCK_SET, + &test_timestamps[i].sync_received, NX_NULL, NX_NULL); + + /* Send sync. */ + send_sync(&event_socket, &pool_0, &test_timestamps[i].sync); + + /* Send follow up. */ + send_follow_up(&generic_socket, &pool_0, &test_timestamps[i].follow_up); + + /* Wait for delay request. */ + status = receive_delay_request(&event_socket, &context, NX_WAIT_FOREVER); + ASSERT_SUCCESS(status); + + /* Send delay response. */ + send_delay_response(&generic_socket, &pool_0, &context, &test_timestamps[i].delay_response); + } +} \ No newline at end of file diff --git a/test/regression/ptp_test/netx_ptp_client_ipv6_test.c b/test/regression/ptp_test/netx_ptp_client_ipv6_test.c new file mode 100644 index 00000000..de3cea03 --- /dev/null +++ b/test/regression/ptp_test/netx_ptp_client_ipv6_test.c @@ -0,0 +1,260 @@ +/* PTP IPv6 test. This test case validates PTP client synchronize over IPv6. + To run this test case, NetXDuo must be built with NX_ENABLE_IPV6_MULTICAST and FEATURE_NX_IPV6. +*/ + +#include "netx_ptp_utility.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET generic_socket; +static NX_UDP_SOCKET event_socket; +static NX_PTP_CLIENT ptp_client; + +static NX_PTP_TIME sync_ts = {0x0, 0x5F97CD71, 0x240d93b2}; +static NX_PTP_TIME follow_up_ts = {0x0, 0x5F97CD71, 0x240e29e0}; +static NX_PTP_TIME delay_response_ts = {0x0, 0x5F97CD71, 0x2494b730}; +static NX_PTP_TIME synced_time; +static NX_PTP_TIME expected_time; +static USHORT synced_utc_offset; +static USHORT expected_utc_offset; +static UCHAR ptp_stack[2048]; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ptp_client_ipv6_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: PTP IPv6 Test ............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + ASSERT_SUCCESS(status); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + ASSERT_SUCCESS(status); + +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) + /* Enable IPv6 for both IP instances. */ + status = nxd_ipv6_enable(&ip_0); + status += nxd_ipv6_enable(&ip_1); + + /* Check IPv6 enable status. */ + ASSERT_SUCCESS(status); + + /* Enable ICMPv6 processing for both IP instances. */ + status = nxd_icmp_enable(&ip_0); + status += nxd_icmp_enable(&ip_1); + + /* Check ICMPv6 enable status. */ + ASSERT_SUCCESS(status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check UDP enable status. */ + ASSERT_SUCCESS(status); +#endif +} + +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) + +/* PTP handler. */ +static UINT ptp_event_callback(NX_PTP_CLIENT *ptp_client_ptr, UINT event, VOID *event_data, VOID *callback_data) +{ +NX_PTP_DATE_TIME date; + + NX_PARAMETER_NOT_USED(callback_data); + + switch (event) + { + case NX_PTP_CLIENT_EVENT_MASTER: + { + DBGPRINTF("new MASTER clock!\r\n"); + break; + } + + case NX_PTP_CLIENT_EVENT_SYNC: + { + nx_ptp_client_sync_info_get((NX_PTP_CLIENT_SYNC *)event_data, NX_NULL, &synced_utc_offset); + DBGPRINTF("SYNC event: utc offset=%d\r\n", synced_utc_offset); + + /* read the PTP clock */ + nx_ptp_client_time_get(ptp_client_ptr, &synced_time); + + /* convert PTP time to UTC date and time */ + nx_ptp_client_utility_convert_time_to_date(&synced_time, -synced_utc_offset, &date); + + /* display the current time */ + DBGPRINTF("ts: %d%d.%d\r\n", synced_time.second_high, + synced_time.second_low, + synced_time.nanosecond); + DBGPRINTF("%2u/%02u/%u %02u:%02u:%02u.%09lu\r\n", date.day, date.month, date.year, + date.hour, date.minute, date.second, + date.nanosecond); + + break; + } + + case NX_PTP_CLIENT_EVENT_TIMEOUT: + { + DBGPRINTF("Master clock TIMEOUT!\r\n"); + break; + } + default: + { + break; + } + } + + return(0); +} +#endif + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) +UINT status; +NX_PTP_TIME ts_diff = {1, 1, 1}; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + ASSERT_SUCCESS(status); + + /* Sleep for DAD. */ + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + /* Reset synced time. */ + memset(&synced_time, 0, sizeof(synced_time)); + synced_utc_offset = 0xFFFF; + + /* Set expected value. */ + expected_utc_offset = 0x1234; + expected_time.second_high = (delay_response_ts.second_high + follow_up_ts.second_high) / 2; + expected_time.second_low = (delay_response_ts.second_low + follow_up_ts.second_low) / 2; + expected_time.nanosecond = (delay_response_ts.nanosecond + follow_up_ts.nanosecond) / 2; + + /* Create the PTP client instance */ + status = nx_ptp_client_create(&ptp_client, &ip_0, 0, &pool_0, + 2, ptp_stack, sizeof(ptp_stack), + nx_ptp_client_soft_clock_callback, NX_NULL); + ASSERT_SUCCESS(status); + + /* start the PTP client */ + status = nx_ptp_client_start(&ptp_client, NX_NULL, 0, 0, 0, ptp_event_callback, NX_NULL); + ASSERT_SUCCESS(status); + + /* Sleep 5 seconds for sync up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Compare synced time. */ + ASSERT_TRUE(synced_utc_offset == expected_utc_offset); + status = nx_ptp_client_utility_time_diff(&synced_time, &expected_time, &ts_diff); + ASSERT_SUCCESS(status); + ASSERT_TRUE(ts_diff.second_high == 0); + ASSERT_TRUE(ts_diff.second_low == 0); + ASSERT_TRUE(ts_diff.nanosecond / 1000000 <= 1000 / NX_PTP_CLIENT_TIMER_TICKS_PER_SECOND); +#endif + + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* This thread acts as PTP server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) +DELAY_REQUEST_CONTEXT context; +UINT status; + + /* Set the IPv6 address. */ + status = nxd_ipv6_address_set(&ip_1, 0, NX_NULL, 10, NX_NULL); + ASSERT_SUCCESS(status); + + /* Sleep for DAD. */ + tx_thread_sleep(3 * NX_IP_PERIODIC_RATE); + + create_socket(&ip_1, &generic_socket, PTP_GENERAL_UDP_PORT); + create_socket(&ip_1, &event_socket, PTP_EVENT_UDP_PORT); + + /* Sleep 1 second to wait for PTP thread running. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Set data through IPv6. */ + set_ip_version(NX_IP_VERSION_V6); + + /* Send announce. */ + send_announce(&generic_socket, &pool_0, expected_utc_offset); + + /* Send sync. */ + send_sync(&event_socket, &pool_0, &sync_ts); + + /* Send follow up. */ + send_follow_up(&generic_socket, &pool_0, &follow_up_ts); + + /* Wait for delay request. */ + status = receive_delay_request(&event_socket, &context, NX_WAIT_FOREVER); + ASSERT_SUCCESS(status); + + /* Send delay response. */ + send_delay_response(&generic_socket, &pool_0, &context, &delay_response_ts); +#endif +} \ No newline at end of file diff --git a/test/regression/ptp_test/netx_ptp_client_master_selection_test.c b/test/regression/ptp_test/netx_ptp_client_master_selection_test.c new file mode 100644 index 00000000..a17a6268 --- /dev/null +++ b/test/regression/ptp_test/netx_ptp_client_master_selection_test.c @@ -0,0 +1,322 @@ +/* PTP master selection test. This test case validates, + 1. Event master will be triggered when different utc offset is announced. + 2. Master clock port identity must be same during sync. + 3. Master clock port can be changed after timeout. +*/ + +#include "netx_ptp_utility.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET generic_socket; +static NX_UDP_SOCKET event_socket; +static NX_PTP_CLIENT ptp_client; + +static NX_PTP_TIME sync_ts = {0x0, 0x5F97CD71, 0x240d93b2}; +static NX_PTP_TIME follow_up_ts = {0x0, 0x5F97CD71, 0x240e29e0}; +static NX_PTP_TIME delay_response_ts = {0x0, 0x5F97CD71, 0x2494b730}; +static NX_PTP_TIME synced_time; +static NX_PTP_TIME expected_time; +static USHORT synced_utc_offset; +static USHORT expected_utc_offset; +static UCHAR ptp_stack[2048]; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ptp_client_basic_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: PTP Master Selection Test ................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + ASSERT_SUCCESS(status); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + ASSERT_SUCCESS(status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + ASSERT_SUCCESS(status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check UDP enable status. */ + if(status) + ASSERT_SUCCESS(status); +} + + +/* PTP handler. */ +static UINT ptp_event_callback(NX_PTP_CLIENT *ptp_client_ptr, UINT event, VOID *event_data, VOID *callback_data) +{ +NX_PTP_DATE_TIME date; + + NX_PARAMETER_NOT_USED(callback_data); + + switch (event) + { + case NX_PTP_CLIENT_EVENT_MASTER: + { + DBGPRINTF("new MASTER clock!\r\n"); + break; + } + + case NX_PTP_CLIENT_EVENT_SYNC: + { + nx_ptp_client_sync_info_get((NX_PTP_CLIENT_SYNC *)event_data, NX_NULL, &synced_utc_offset); + DBGPRINTF("SYNC event: utc offset=%d\r\n", synced_utc_offset); + + /* read the PTP clock */ + nx_ptp_client_time_get(ptp_client_ptr, &synced_time); + + /* convert PTP time to UTC date and time */ + nx_ptp_client_utility_convert_time_to_date(&synced_time, -synced_utc_offset, &date); + + /* display the current time */ + DBGPRINTF("ts: %d%d.%d\r\n", synced_time.second_high, + synced_time.second_low, + synced_time.nanosecond); + DBGPRINTF("%2u/%02u/%u %02u:%02u:%02u.%09lu\r\n", date.day, date.month, date.year, + date.hour, date.minute, date.second, + date.nanosecond); + + break; + } + + case NX_PTP_CLIENT_EVENT_TIMEOUT: + { + DBGPRINTF("Master clock TIMEOUT!\r\n"); + break; + } + default: + { + break; + } + } + + return(0); +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +UINT i; +NX_PTP_TIME ts_zero = {0}; +UINT timeout_ticks; + + /* Set expected value. */ + expected_utc_offset = 0x1234; + expected_time.second_high = (delay_response_ts.second_high + follow_up_ts.second_high) / 2; + expected_time.second_low = (delay_response_ts.second_low + follow_up_ts.second_low) / 2; + expected_time.nanosecond = (delay_response_ts.nanosecond + follow_up_ts.nanosecond) / 2; + + /* Create the PTP client instance */ + status = nx_ptp_client_create(&ptp_client, &ip_0, 0, &pool_0, + 2, ptp_stack, sizeof(ptp_stack), + nx_ptp_client_soft_clock_callback, NX_NULL); + ASSERT_SUCCESS(status); + + for (i = 0; i < 3; i++) + { + + /* Reset synced time. */ + memset(&synced_time, 0, sizeof(synced_time)); + synced_utc_offset = 0xFFFF; + + if (i < 2) + { + + /* start the PTP client */ + status = nx_ptp_client_start(&ptp_client, NX_NULL, 0, 0, 0, ptp_event_callback, NX_NULL); + ASSERT_SUCCESS(status); + } + + /* Reset synced time. */ + memset(&synced_time, 0, sizeof(synced_time)); + synced_utc_offset = 0xFFFF; + + /* Wake up server thread. */ + tx_thread_resume(&ntest_1); + + /* Sleep 5 seconds for sync up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Compare synced time. */ + if (i == 1) + { + + /* Time not synched. */ + ASSERT_TRUE(synced_utc_offset == 0xFFFF); + ASSERT_SUCCESS(memcmp(&synced_time, &ts_zero, sizeof(ts_zero))); + } + else + { + + /* Time synched. */ + ASSERT_TRUE(synced_utc_offset == expected_utc_offset); + ASSERT_SUCCESS(memcmp(&synced_time, &expected_time, sizeof(expected_time))); + } + + if (i == 0) + { + + /* Wake up server thread to send another Announce. */ + tx_thread_resume(&ntest_1); + + /* Sleep 5 seconds for sync up. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + ASSERT_TRUE(synced_utc_offset == (expected_utc_offset + 1)); + + /* Stop the PTP client */ + status = nx_ptp_client_stop(&ptp_client); + ASSERT_SUCCESS(status); + } + else if (i == 1) + { + + /* Sleep until timeout. */ + timeout_ticks = NX_PTP_CLIENT_ANNOUNCE_RECEIPT_TIMEOUT * + (1 << NX_PTP_CLIENT_LOG_ANNOUNCE_INTERVAL) * + NX_IP_PERIODIC_RATE; + tx_thread_sleep(timeout_ticks); + } + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* This thread acts as PTP server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +DELAY_REQUEST_CONTEXT context; +UINT status; +UINT i; + + create_socket(&ip_1, &generic_socket, PTP_GENERAL_UDP_PORT); + create_socket(&ip_1, &event_socket, PTP_EVENT_UDP_PORT); + + for (i = 0; i < 3; i++) + { + + /* Suspend current thread and wait for client thread. */ + tx_thread_suspend(tx_thread_identify()); + + /* Sleep 1 second to wait for PTP thread running. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Send announce. */ + send_announce(&generic_socket, &pool_0, expected_utc_offset); + + if (i == 1) + { + + /* Change the clock identify. */ + set_clock_id((UCHAR *)"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99"); + } + + /* Send sync. */ + send_sync(&event_socket, &pool_0, &sync_ts); + + /* Send follow up. */ + send_follow_up(&generic_socket, &pool_0, &follow_up_ts); + + if (i == 1) + { + + /* Wait for delay request. */ + status = receive_delay_request(&event_socket, &context, NX_IP_PERIODIC_RATE); + ASSERT_TRUE(status == NX_NO_PACKET); + continue; + } + + /* Wait for delay request. */ + status = receive_delay_request(&event_socket, &context, NX_IP_PERIODIC_RATE); + ASSERT_SUCCESS(status); + + /* Send delay response. */ + send_delay_response(&generic_socket, &pool_0, &context, &delay_response_ts); + + if (i == 0) + { + + /* Suspend current thread and wait for client thread. */ + tx_thread_suspend(tx_thread_identify()); + + /* Send another Announce with different utc offset. */ + send_announce(&generic_socket, &pool_0, expected_utc_offset + 1); + } + } +} \ No newline at end of file diff --git a/test/regression/ptp_test/netx_ptp_client_two_steps_off_test.c b/test/regression/ptp_test/netx_ptp_client_two_steps_off_test.c new file mode 100644 index 00000000..f61c48c8 --- /dev/null +++ b/test/regression/ptp_test/netx_ptp_client_two_steps_off_test.c @@ -0,0 +1,234 @@ +/* PTP two steps off test. This test case validates two steps off procedure of PTP client synchronize. */ + +#include "netx_ptp_utility.h" + +#define DEMO_STACK_SIZE 2048 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET generic_socket; +static NX_UDP_SOCKET event_socket; +static NX_PTP_CLIENT ptp_client; + +static NX_PTP_TIME sync_ts = {0x0, 0x5F97CD71, 0x240d93b2}; +static NX_PTP_TIME follow_up_ts = {0x0, 0x5F97CD71, 0x240e29e0}; +static NX_PTP_TIME delay_response_ts = {0x0, 0x5F97CD71, 0x2494b730}; +static NX_PTP_TIME synced_time; +static NX_PTP_TIME expected_time; +static USHORT synced_utc_offset; +static USHORT expected_utc_offset; +static UCHAR ptp_stack[2048]; + + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_ptp_client_two_steps_off_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: PTP Two Steps Off Test ..................................."); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the main thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the main thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + + if(status) + ASSERT_SUCCESS(status); + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + + if(status) + ASSERT_SUCCESS(status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check ARP enable status. */ + if(status) + ASSERT_SUCCESS(status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + + /* Check UDP enable status. */ + if(status) + ASSERT_SUCCESS(status); +} + + +/* PTP handler. */ +static UINT ptp_event_callback(NX_PTP_CLIENT *ptp_client_ptr, UINT event, VOID *event_data, VOID *callback_data) +{ +NX_PTP_DATE_TIME date; + + NX_PARAMETER_NOT_USED(callback_data); + + switch (event) + { + case NX_PTP_CLIENT_EVENT_MASTER: + { + DBGPRINTF("new MASTER clock!\r\n"); + break; + } + + case NX_PTP_CLIENT_EVENT_SYNC: + { + nx_ptp_client_sync_info_get((NX_PTP_CLIENT_SYNC *)event_data, NX_NULL, &synced_utc_offset); + DBGPRINTF("SYNC event: utc offset=%d\r\n", synced_utc_offset); + + /* read the PTP clock */ + nx_ptp_client_time_get(ptp_client_ptr, &synced_time); + + /* convert PTP time to UTC date and time */ + nx_ptp_client_utility_convert_time_to_date(&synced_time, -synced_utc_offset, &date); + + /* display the current time */ + DBGPRINTF("ts: %d%d.%d\r\n", synced_time.second_high, + synced_time.second_low, + synced_time.nanosecond); + DBGPRINTF("%2u/%02u/%u %02u:%02u:%02u.%09lu\r\n", date.day, date.month, date.year, + date.hour, date.minute, date.second, + date.nanosecond); + + break; + } + + case NX_PTP_CLIENT_EVENT_TIMEOUT: + { + DBGPRINTF("Master clock TIMEOUT!\r\n"); + break; + } + default: + { + break; + } + } + + return(0); +} + +/* Define the test threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NX_PTP_TIME ts_diff = {1, 1, 1}; + + /* Reset synced time. */ + memset(&synced_time, 0, sizeof(synced_time)); + synced_utc_offset = 0xFFFF; + + /* Set expected value. */ + expected_utc_offset = 0x1234; + expected_time.second_high = (delay_response_ts.second_high + sync_ts.second_high) / 2; + expected_time.second_low = (delay_response_ts.second_low + sync_ts.second_low) / 2; + expected_time.nanosecond = (delay_response_ts.nanosecond + sync_ts.nanosecond) / 2; + + /* Create the PTP client instance */ + status = nx_ptp_client_create(&ptp_client, &ip_0, 0, &pool_0, + 2, ptp_stack, sizeof(ptp_stack), + nx_ptp_client_soft_clock_callback, NX_NULL); + ASSERT_SUCCESS(status); + + /* start the PTP client */ + status = nx_ptp_client_start(&ptp_client, NX_NULL, 0, 0, 0, ptp_event_callback, NX_NULL); + ASSERT_SUCCESS(status); + + /* Sleep 5 seconds for sync up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Compare synced time. */ + ASSERT_TRUE(synced_utc_offset == expected_utc_offset); + status = nx_ptp_client_utility_time_diff(&synced_time, &expected_time, &ts_diff); + ASSERT_SUCCESS(status); + ASSERT_TRUE(ts_diff.second_high == 0); + ASSERT_TRUE(ts_diff.second_low == 0); + ASSERT_TRUE(ts_diff.nanosecond / 1000000 <= 1000 / NX_PTP_CLIENT_TIMER_TICKS_PER_SECOND); + + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* This thread acts as PTP server, accepting the connection. */ +static void ntest_1_entry(ULONG thread_input) +{ +DELAY_REQUEST_CONTEXT context; +UINT status; + + create_socket(&ip_1, &generic_socket, PTP_GENERAL_UDP_PORT); + create_socket(&ip_1, &event_socket, PTP_EVENT_UDP_PORT); + + /* Sleep 1 second to wait for PTP thread running. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Set two steps off. */ + set_two_steps(NX_FALSE); + + /* Send announce. */ + send_announce(&generic_socket, &pool_0, expected_utc_offset); + + /* Send sync. */ + send_sync(&event_socket, &pool_0, &sync_ts); + + /* Wait for delay request. */ + status = receive_delay_request(&event_socket, &context, NX_WAIT_FOREVER); + ASSERT_SUCCESS(status); + + /* Send delay response. */ + send_delay_response(&generic_socket, &pool_0, &context, &delay_response_ts); +} \ No newline at end of file diff --git a/test/regression/ptp_test/netx_ptp_utility.c b/test/regression/ptp_test/netx_ptp_utility.c new file mode 100644 index 00000000..a6f384ac --- /dev/null +++ b/test/regression/ptp_test/netx_ptp_utility.c @@ -0,0 +1,526 @@ + +#include "netx_ptp_utility.h" + +#define NANOSECONDS_PER_SEC 1000000000L + +extern VOID _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* +Precision Time Protocol (IEEE1588) + 0000 .... = transportSpecific: 0x0 + .... 1011 = messageId: Announce Message (0xb) + 0000 .... = Reserved: 0 + .... 0010 = versionPTP: 2 + messageLength: 64 + subdomainNumber: 0 + Reserved: 0 + flags: 0x0000 + correction: 0.000000 nanoseconds + Reserved: 0 + ClockIdentity: 0x46e7c8fffe7161a1 + SourcePortID: 1 + sequenceId: 61 + control: Other Message (5) + logMessagePeriod: 1 + originTimestamp (seconds): 0 + originTimestamp (nanoseconds): 0 + originCurrentUTCOffset: 0 + priority1: 128 + grandmasterClockClass: 127 + grandmasterClockAccuracy: Accuracy Unknown (0xfe) + grandmasterClockVariance: 28768 + priority2: 128 + grandmasterClockIdentity: 0x46e7c8fffe7161a1 + localStepsRemoved: 0 + TimeSource: INTERNAL_OSCILLATOR (0xa0) +*/ +static UCHAR announce_data[] = \ +"\x0b\x02\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ +"\x00\x00\x00\x00\x46\xe7\xc8\xff\xfe\x71\x61\xa1\x00\x01\x00\x3d" \ +"\x05\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x22\x80" \ +"\x7f\xfe\x70\x60\x80\x46\xe7\xc8\xff\xfe\x71\x61\xa1\x00\x00\xa0"; + +/* +Precision Time Protocol (IEEE1588) + 0000 .... = transportSpecific: 0x0 + .... 0000 = messageId: Sync Message (0x0) + 0000 .... = Reserved: 0 + .... 0010 = versionPTP: 2 + messageLength: 44 + subdomainNumber: 0 + Reserved: 0 + flags: 0x0200 + correction: 0.000000 nanoseconds + Reserved: 0 + ClockIdentity: 0x46e7c8fffe7161a1 + SourcePortID: 1 + sequenceId: 123 + control: Sync Message (0) + logMessagePeriod: 0 + originTimestamp (seconds): 1603784044 + originTimestamp (nanoseconds): 604899854 +*/ +static UCHAR sync_data[] = \ +"\x00\x02\x00\x2c\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ +"\x00\x00\x00\x00\x46\xe7\xc8\xff\xfe\x71\x61\xa1\x00\x01\x00\x7b" \ +"\x00\x00\x00\x00\x5f\x97\xcd\x6c\x24\x0e\x0a\x0e"; + +/* +Precision Time Protocol (IEEE1588) + 0000 .... = transportSpecific: 0x0 + .... 1000 = messageId: Follow_Up Message (0x8) + 0000 .... = Reserved: 0 + .... 0010 = versionPTP: 2 + messageLength: 44 + subdomainNumber: 0 + Reserved: 0 + flags: 0x0400 + correction: 0.000000 nanoseconds + Reserved: 0 + ClockIdentity: 0x46e7c8fffe7161a1 + SourcePortID: 1 + sequenceId: 123 + control: Follow_Up Message (2) + logMessagePeriod: 0 + preciseOriginTimestamp (seconds): 1603784044 + preciseOriginTimestamp (nanoseconds): 604908000 +*/ +static UCHAR follow_up_data[] = \ +"\x08\x02\x00\x2c\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ +"\x00\x00\x00\x00\x46\xe7\xc8\xff\xfe\x71\x61\xa1\x00\x01\x00\x7b" \ +"\x02\x00\x00\x00\x5f\x97\xcd\x6c\x24\x0e\x29\xe0"; + +/* +Precision Time Protocol (IEEE1588) + 0000 .... = transportSpecific: 0x0 + .... 1001 = messageId: Delay_Resp Message (0x9) + 0000 .... = Reserved: 0 + .... 0010 = versionPTP: 2 + messageLength: 54 + subdomainNumber: 0 + Reserved: 0 + flags: 0x0000 + correction: 0.000000 nanoseconds + Reserved: 0 + ClockIdentity: 0x46e7c8fffe7161a1 + SourcePortID: 1 + sequenceId: 1 + control: Delay_Resp Message (3) + logMessagePeriod: 0 + receiveTimestamp (seconds): 1603784044 + receiveTimestamp (nanoseconds): 613726000 + requestingSourcePortIdentity: 0x001122fffe334457 + requestingSourcePortId: 1 +*/ +static UCHAR delay_resp_data[] = \ +"\x09\x02\x00\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \ +"\x00\x00\x00\x00\x46\xe7\xc8\xff\xfe\x71\x61\xa1\x00\x01\x00\x01" \ +"\x03\x00\x00\x00\x5f\x97\xcd\x6c\x24\x94\xb7\x30\x00\x11\x22\xff" \ +"\xfe\x33\x44\x57\x00\x01"; + +static UCHAR use_two_steps = NX_TRUE; +static NX_PTP_CLIENT *ptp_client_ptr = NX_NULL; +static NX_PTP_TIME ptp_timestamp = {0}; +static UCHAR use_ipv4 = NX_TRUE; + +static VOID send_udp_data(NX_UDP_SOCKET *socket_ptr, NX_PACKET_POOL *pool_ptr, + UINT port, UCHAR *data, UINT size) +{ +NX_PACKET *packet_ptr; +UINT status; +#ifndef NX_DISABLE_IPV6 +NXD_ADDRESS ipv6_addr; +#endif + + /* Allocate a packet. */ + status = nx_packet_allocate(pool_ptr, &packet_ptr, NX_UDP_PACKET, NX_NO_WAIT); + ASSERT_SUCCESS(status); + + /* Append announce data. */ + status = nx_packet_data_append(packet_ptr, data, size, pool_ptr, NX_NO_WAIT); + ASSERT_SUCCESS(status); + + /* Send out the packet. */ + if (use_ipv4) + { + status = nx_udp_socket_send(socket_ptr, packet_ptr, PTP_IPV4_MULTICAST_ADDR, port); + } +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) + else + { + PTP_IPV6_MULTICAST_ADDR_SET(&ipv6_addr); + status = nxd_udp_socket_send(socket_ptr, packet_ptr, &ipv6_addr, port); + } +#endif + + ASSERT_SUCCESS(status); +} + +static VOID fill_timestamp(UCHAR *buffer, NX_PTP_TIME *ts) +{ + buffer[0] = (ts -> second_high >> 8) & 0xFF; + buffer[1] = ts -> second_high & 0xFF; + buffer[2] = (ts -> second_low >> 24) & 0xFF; + buffer[3] = (ts -> second_low >> 16) & 0xFF; + buffer[4] = (ts -> second_low >> 8) & 0xFF; + buffer[5] = ts -> second_low & 0xFF; + buffer[6] = (ts -> nanosecond >> 24) & 0xFF; + buffer[7] = (ts -> nanosecond >> 16) & 0xFF; + buffer[8] = (ts -> nanosecond >> 8) & 0xFF; + buffer[9] = ts -> nanosecond & 0xFF; +} + +VOID create_socket(NX_IP *ip_ptr, NX_UDP_SOCKET *socket_ptr, UINT port) +{ +UINT status; +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) +NXD_ADDRESS ipv6_addr; +#endif + + /* Create a UDP socket. */ + status = nx_udp_socket_create(ip_ptr, socket_ptr, "UDP Socket", NX_IP_NORMAL, + NX_FRAGMENT_OKAY, 0x80, 5); + ASSERT_SUCCESS(status); + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(socket_ptr, port, NX_NO_WAIT); + ASSERT_SUCCESS(status); + + /* Join multicast group. */ + status = nx_ipv4_multicast_interface_join(ip_ptr, PTP_IPV4_MULTICAST_ADDR, 0); + ASSERT_SUCCESS(status); + +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) + PTP_IPV6_MULTICAST_ADDR_SET(&ipv6_addr); + status = nxd_ipv6_multicast_interface_join(ip_ptr, &ipv6_addr, 0); + ASSERT_SUCCESS(status); +#endif +} + +VOID send_announce(NX_UDP_SOCKET *socket_ptr, NX_PACKET_POOL *pool_ptr, USHORT utc_offset) +{ + + /* Adjust utc offset. */ + NX_CHANGE_USHORT_ENDIAN(utc_offset); + memcpy(&announce_data[44], &utc_offset, sizeof(utc_offset)); + + /* Send out announce packet. */ + send_udp_data(socket_ptr, pool_ptr, PTP_GENERAL_UDP_PORT, + announce_data, sizeof(announce_data)); +} + +VOID send_sync(NX_UDP_SOCKET *socket_ptr, NX_PACKET_POOL *pool_ptr, NX_PTP_TIME *ts) +{ + if (use_two_steps) + { + sync_data[6] |= 0x2; + } + else + { + sync_data[6] &= 0xFD; + } + + + /* Adjust timestamp. */ + fill_timestamp(&sync_data[34], ts); + + /* Send out sync packet. */ + send_udp_data(socket_ptr, pool_ptr, PTP_EVENT_UDP_PORT, + sync_data, sizeof(sync_data)); +} + +VOID send_follow_up(NX_UDP_SOCKET *socket_ptr, NX_PACKET_POOL *pool_ptr, NX_PTP_TIME *ts) +{ + + /* Adjust timestamp. */ + fill_timestamp(&follow_up_data[34], ts); + + /* Send out follow up packet. */ + send_udp_data(socket_ptr, pool_ptr, PTP_GENERAL_UDP_PORT, + follow_up_data, sizeof(follow_up_data)); +} + +VOID send_delay_response(NX_UDP_SOCKET *socket_ptr, NX_PACKET_POOL *pool_ptr, + DELAY_REQUEST_CONTEXT *context, NX_PTP_TIME *ts) +{ + + /* Adjust timestamp. */ + fill_timestamp(&delay_resp_data[34], ts); + + /* Adjust clock ID and sequence ID. */ + memcpy(&delay_resp_data[30], context -> sequence_id, 2); + + memcpy(&delay_resp_data[sizeof(delay_resp_data) - 11], context -> clock_id, + NX_PTP_CLOCK_PORT_IDENTITY_SIZE); + + /* Send out delay resp packet. */ + send_udp_data(socket_ptr, pool_ptr, PTP_GENERAL_UDP_PORT, + delay_resp_data, sizeof(delay_resp_data)); +} + +UINT receive_delay_request(NX_UDP_SOCKET *socket_ptr, DELAY_REQUEST_CONTEXT *context, + UINT wait_option) +{ +NX_PACKET *packet_ptr; +NXD_ADDRESS ip_address; +ULONG bytes_copied; +UINT port; +UINT status; + + + status = nx_udp_socket_receive(socket_ptr, &packet_ptr, wait_option); + if (status) + { + return(status); + } + + status = nxd_udp_source_extract(packet_ptr, &ip_address, &port); + ASSERT_SUCCESS(status); + ASSERT_TRUE(port == PTP_EVENT_UDP_PORT); + + status = nx_packet_data_extract_offset(packet_ptr, 20, context -> clock_id, + NX_PTP_CLOCK_PORT_IDENTITY_SIZE, + &bytes_copied); + ASSERT_SUCCESS(status); + ASSERT_TRUE(bytes_copied == NX_PTP_CLOCK_PORT_IDENTITY_SIZE); + + status = nx_packet_data_extract_offset(packet_ptr, 30, context -> sequence_id, + 2, &bytes_copied); + ASSERT_SUCCESS(status); + ASSERT_TRUE(bytes_copied == 2); + + return(NX_SUCCESS); +} + + +VOID set_two_steps(UCHAR two_steps) +{ + use_two_steps = two_steps; +} + + +VOID set_clock_id(UCHAR *clock_id) +{ + + /* Adjust clock ID. */ + memcpy(&announce_data[20], clock_id, NX_PTP_CLOCK_PORT_IDENTITY_SIZE); + memcpy(&sync_data[20], clock_id, NX_PTP_CLOCK_PORT_IDENTITY_SIZE); + memcpy(&follow_up_data[20], clock_id, NX_PTP_CLOCK_PORT_IDENTITY_SIZE); + memcpy(&delay_resp_data[20], clock_id, NX_PTP_CLOCK_PORT_IDENTITY_SIZE); +} + + +VOID set_ip_version(UCHAR ip_version) +{ + if (ip_version == NX_IP_VERSION_V4) + { + use_ipv4 = NX_TRUE; + } +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) + else + { + use_ipv4 = NX_FALSE; + } +#endif +} + + +VOID calibrate_timestamp(TEST_TIMESTAMP *test_ts, NX_PTP_TIME *ts) +{ +ULONG64 second_low; +ULONG64 carry; +long long nanosecond; +NX_PTP_TIME *t1; + + /* Means of following symbols, + t1 is timestamp of Sync if two step is disabled, + or else, it is timestamp of FollowUp. + t2 is timestamp of Sync received. + t3 is timestamp of DelayRequest sent. Also equals client_clock in the test + t4 is timestamp of DelayRequest in DelayResponse packet. + + meanPathDelay between client and server is, + [(t2-t1)+(t4-t3)]/2 + + offsetFromMaster = client_clock - master_clock + = t2 - t1 - meanPathDelay - correctionField + + master_clock = [(t4+t3)-(t2-t1)]/2 + + Note, The recommendation that the timestamps themselves be + the best possible estimate of the time enables simple devices + that only need approximate time to ignore the correctionField. + */ + + if ((test_ts -> follow_up.second_high == 0) && + (test_ts -> follow_up.second_low == 0) && + (test_ts -> follow_up.nanosecond == 0)) + { + + /* No FollowUp timestamp. Use Sync timestamp. */ + t1 = &test_ts -> sync; + } + else + { + + /* Use FollowUp timestamp. */ + t1 = &test_ts -> follow_up; + } + + ts -> second_high = (test_ts -> delay_response.second_high + test_ts -> delay_request.second_high) - + (test_ts -> sync_received.second_high - t1 -> second_high); + if (ts -> second_high & 1) + { + carry = 0x100000000; + } + else + { + carry = 0; + } + ts -> second_high /= 2; + + second_low = carry + ((ULONG64)test_ts -> delay_response.second_low + (ULONG64)test_ts -> delay_request.second_low) - + ((ULONG64)test_ts -> sync_received.second_low - (ULONG64)t1 -> second_low); + if (second_low & 1) + { + carry = NANOSECONDS_PER_SEC; + } + else + { + carry = 0; + } + second_low /= 2; + + nanosecond = (carry + ((long long)test_ts -> delay_response.nanosecond + (long long)test_ts -> delay_request.nanosecond) - + ((long long)test_ts -> sync_received.nanosecond - (long long)t1 -> nanosecond)) / 2; + + /* Adjust according to carry. */ + while (nanosecond >= NANOSECONDS_PER_SEC) + { + nanosecond -= NANOSECONDS_PER_SEC; + second_low++; + } + + if (nanosecond < 0) + { + nanosecond += NANOSECONDS_PER_SEC; + if (second_low == 0) + { + ts -> second_high--; + second_low = 0xFFFFFFFF; + } + else + { + second_low--; + } + + } + + while (second_low > 0xFFFFFFFF) + { + second_low -= 0xFFFFFFFF; + ts -> second_high++; + } + + ts -> second_low = (ULONG)second_low; + ts -> nanosecond = (LONG)nanosecond; +} + +VOID _netx_ptp_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req) +{ +NX_PACKET *packet_ptr; + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY + if (driver_req -> nx_ip_driver_command == NX_LINK_PACKET_SEND) + { + packet_ptr = driver_req -> nx_ip_driver_packet; + if (packet_ptr -> nx_packet_interface_capability_flag & NX_INTERFACE_CAPABILITY_PTP_TIMESTAMP) + { + + /* call notification callback */ + nx_ptp_client_packet_timestamp_notify(ptp_client_ptr, packet_ptr, &ptp_timestamp); + } + } +#endif + + _nx_ram_network_driver(driver_req); +} + +#ifdef NX_ENABLE_INTERFACE_CAPABILITY +UINT _netx_ptp_clock_callback(NX_PTP_CLIENT *client_ptr, UINT operation, + NX_PTP_TIME *time_ptr, NX_PACKET *packet_ptr, + VOID *callback_data) +{ + + NX_PARAMETER_NOT_USED(callback_data); + + switch (operation) + { + + /* Save pointer to PTP client. */ + case NX_PTP_CLIENT_CLOCK_INIT: + ptp_client_ptr = client_ptr; + break; + + /* Set clock. */ + case NX_PTP_CLIENT_CLOCK_SET: + ptp_timestamp = *time_ptr; + break; + + /* Extract timestamp from packet. */ + case NX_PTP_CLIENT_CLOCK_PACKET_TS_EXTRACT: + *time_ptr = ptp_timestamp; + break; + + /* Get clock. */ + case NX_PTP_CLIENT_CLOCK_GET: + *time_ptr = ptp_timestamp; + break; + + /* Adjust clock. */ + case NX_PTP_CLIENT_CLOCK_ADJUST: + ptp_timestamp.nanosecond += time_ptr -> nanosecond; + if (ptp_timestamp.nanosecond >= NANOSECONDS_PER_SEC) + { + ptp_timestamp.nanosecond -= NANOSECONDS_PER_SEC; + if (ptp_timestamp.second_low == 0xFFFFFFFF) + { + ptp_timestamp.second_high++; + ptp_timestamp.second_low = 0; + } + else + { + ptp_timestamp.second_low++; + } + } + else if (ptp_timestamp.nanosecond < 0) + { + ptp_timestamp.nanosecond += NANOSECONDS_PER_SEC; + if (ptp_timestamp.second_low == 0) + { + ptp_timestamp.second_high--; + ptp_timestamp.second_low = 0xFFFFFFFF; + } + else + { + ptp_timestamp.second_low--; + } + } + break; + + /* Prepare timestamp for current packet. */ + case NX_PTP_CLIENT_CLOCK_PACKET_TS_PREPARE: + packet_ptr -> nx_packet_interface_capability_flag |= NX_INTERFACE_CAPABILITY_PTP_TIMESTAMP; + break; + + /* Update soft timer. */ + case NX_PTP_CLIENT_CLOCK_SOFT_TIMER_UPDATE: + break; + + default: + return(NX_PTP_PARAM_ERROR); + } + + return(NX_SUCCESS); +} +#endif \ No newline at end of file diff --git a/test/regression/ptp_test/netx_ptp_utility.h b/test/regression/ptp_test/netx_ptp_utility.h new file mode 100644 index 00000000..88eda3bd --- /dev/null +++ b/test/regression/ptp_test/netx_ptp_utility.h @@ -0,0 +1,70 @@ +#ifndef TEST_UTILITY_H +#define TEST_UTILITY_H + +#include "nxd_ptp_client.h" + +void test_control_return(UINT status); + +#ifdef DEBUG +#define DBGPRINTF(...) printf(##__VA_ARGS__) +#else +#define DBGPRINTF(...) +#endif + +#define ASSERT_DEBUG(c) printf("\n[%s:%d]Assert fail: %s\n", __FILE__, __LINE__, (c)); +#define ASSERT_TRUE(p) {if (!(p)) {ASSERT_DEBUG(#p);test_control_return(1);}} +#define ASSERT_SUCCESS(v) ASSERT_TRUE((v) == 0) + +/* Define the UDP ports */ +#define PTP_EVENT_UDP_PORT 319 +#define PTP_GENERAL_UDP_PORT 320 + +/* Define the IPv4 multicast address "224.0.1.129" */ +#define PTP_IPV4_MULTICAST_ADDR IP_ADDRESS(224,0,1,129) + +/* Define the IPv6 multicast address "ff0e::181" */ +#define PTP_IPV6_MULTICAST_ADDR_SET(x) { \ + (x) -> nxd_ip_version = NX_IP_VERSION_V6; \ + (x) -> nxd_ip_address.v6[0] = 0xff0e0000UL; \ + (x) -> nxd_ip_address.v6[1] = 0; \ + (x) -> nxd_ip_address.v6[2] = 0; \ + (x) -> nxd_ip_address.v6[3] = 0x181; } + +typedef struct +{ + + /* Timestamp from master. */ + NX_PTP_TIME sync; + NX_PTP_TIME follow_up; + NX_PTP_TIME delay_response; + + /* Timestamp from client. */ + NX_PTP_TIME sync_received; + NX_PTP_TIME delay_request; +} TEST_TIMESTAMP; + +typedef struct +{ + UCHAR clock_id[NX_PTP_CLOCK_PORT_IDENTITY_SIZE]; + UCHAR sequence_id[2]; +} DELAY_REQUEST_CONTEXT; + + +VOID create_socket(NX_IP *ip_ptr, NX_UDP_SOCKET *socket_ptr, UINT port); +VOID send_announce(NX_UDP_SOCKET *socket_ptr, NX_PACKET_POOL *pool_ptr, USHORT utc_offset); +VOID send_sync(NX_UDP_SOCKET *socket_ptr, NX_PACKET_POOL *pool_ptr, NX_PTP_TIME *ts); +VOID send_follow_up(NX_UDP_SOCKET *socket_ptr, NX_PACKET_POOL *pool_ptr, NX_PTP_TIME *ts); +VOID send_delay_response(NX_UDP_SOCKET *socket_ptr, NX_PACKET_POOL *pool_ptr, + DELAY_REQUEST_CONTEXT *context, NX_PTP_TIME *ts); +UINT receive_delay_request(NX_UDP_SOCKET *socket_ptr, DELAY_REQUEST_CONTEXT *context, + UINT wait_option); +VOID set_two_steps(UCHAR two_steps); +VOID set_clock_id(UCHAR *clock_id); +VOID set_ip_version(UCHAR ip_version); +VOID calibrate_timestamp(TEST_TIMESTAMP *test_ts, NX_PTP_TIME *ts); +VOID _netx_ptp_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +UINT _netx_ptp_clock_callback(NX_PTP_CLIENT *client_ptr, UINT operation, + NX_PTP_TIME *time_ptr, NX_PACKET *packet_ptr, + VOID *callback_data); + +#endif /* TEST_UTILITY_H */ \ No newline at end of file diff --git a/test/regression/rtp_test/netx_rtcp_abnormal_packet_test.c b/test/regression/rtp_test/netx_rtcp_abnormal_packet_test.c new file mode 100644 index 00000000..66d809dc --- /dev/null +++ b/test/regression/rtp_test/netx_rtcp_abnormal_packet_test.c @@ -0,0 +1,337 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define RTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTP_CLIENT_RTP_PORT 6002 +#define RTP_CLIENT_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE_VIDEO 96 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET rtp_client_socket; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; + +/* Define the counters used in the test application... */ +static TX_SEMAPHORE semaphore_test_done; + +typedef struct PACKET_DATA_STRUCT{ + UCHAR *data; + ULONG length; +}PACKET_DATA; + +/* Define RTCP packet for testing. +--receiver report-- + version: RFC 1899 Version (2) + padding: True + reception report count: 1 + packet type: receiver report (201) + length: 7 + sender ssrc: 1052681868 + source 1: + identifier: 11478 + fraction lost: 255 + cumulative number of packets lost: -1 + extended highest sequence number received: 94974 + interarrival jitter: 444 + last SR timestamp: 0 + delay since last SR timestamp: 0 +--source description-- + version: RFC 1899 Version (2) + padding: False + source count: 1 + packet type: source description (202) + length: 5 + chunk 1: + indentifier: 1052681868 + sdes item: + type: CNAME (1) + length:13 + text: cn-test-cname + type: END (0) +*/ + +/* Invalid padding value. */ +static UCHAR test_rtcp_packet_data_0[]={ +0xa1, 0xc9, 0x00, 0x07, 0x3e, 0xbe, 0xa6, 0x8c, 0x00, 0x00, 0x2c, 0xd6, 0xff, 0xff, 0xff, 0xff, +0x00, 0x01, 0x72, 0xfe, 0x00, 0x00, 0x01, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x81, 0xca, 0x00, 0x05, 0x3e, 0xbe, 0xa6, 0x8c, 0x01, 0x0d, 0x63, 0x6e, 0x2d, 0x74, 0x65, 0x73, +0x74, 0x2d, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x00}; + +/* Invalid RTCP packet type. */ +static UCHAR test_rtcp_packet_data_1[]={ +0x81, 0x00, 0x00, 0x07, 0x3e, 0xbe, 0xa6, 0x8c, 0x00, 0x00, 0x2c, 0xd6, 0xff, 0xff, 0xff, 0xff, +0x00, 0x01, 0x72, 0xfe, 0x00, 0x00, 0x01, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x81, 0xca, 0x00, 0x05, 0x3e, 0xbe, 0xa6, 0x8c, 0x01, 0x0d, 0x63, 0x6e, 0x2d, 0x74, 0x65, 0x73, +0x74, 0x2d, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x00}; + +/* Invalid RR packet type version. */ +static UCHAR test_rtcp_packet_data_2[]={ +0x71, 0xc9, 0x00, 0x07, 0x3e, 0xbe, 0xa6, 0x8c, 0x00, 0x00, 0x2c, 0xd6, 0xff, 0xff, 0xff, 0xff, +0x00, 0x01, 0x72, 0xfe, 0x00, 0x00, 0x01, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x81, 0xca, 0x00, 0x05, 0x3e, 0xbe, 0xa6, 0x8c, 0x01, 0x0d, 0x63, 0x6e, 0x2d, 0x74, 0x65, 0x73, +0x74, 0x2d, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x00}; + +/* Invalid RR packet length. */ +static UCHAR test_rtcp_packet_data_3[]={ +0x81, 0xc9, 0x00, 0x06, 0x3e, 0xbe, 0xa6, 0x8c, 0x00, 0x00, 0x2c, 0xd6, 0xff, 0xff, 0xff, 0xff, +0x00, 0x01, 0x72, 0xfe, 0x00, 0x00, 0x01, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x81, 0xca, 0x00, 0x05, 0x3e, 0xbe, 0xa6, 0x8c, 0x01, 0x0d, 0x63, 0x6e, 0x2d, 0x74, 0x65, 0x73, +0x74, 0x2d, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x00}; + +/* Invalid SDES packet type version. */ +static UCHAR test_rtcp_packet_data_4[]={ +0x80, 0xc9, 0x00, 0x01, 0x3e, 0xbe, 0xa6, 0x8c, +0x71, 0xca, 0x00, 0x05, 0x3e, 0xbe, 0xa6, 0x8c, 0x01, 0x0d, 0x63, 0x6e, 0x2d, 0x74, 0x65, 0x73, +0x74, 0x2d, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x00}; + +/* Invalid SDES packet length. */ +static UCHAR test_rtcp_packet_data_5[]={ +0x80, 0xc9, 0x00, 0x01, 0x3e, 0xbe, 0xa6, 0x8c, +0x81, 0xca, 0x00, 0x06, 0x3e, 0xbe, 0xa6, 0x8c, 0x01, 0x0d, 0x63, 0x6e, 0x2d, 0x74, 0x65, 0x73, +0x74, 0x2d, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x00}; + +/* Invalid SDES packet cname string length. */ +static UCHAR test_rtcp_packet_data_6[]={ +0x80, 0xc9, 0x00, 0x01, 0x3e, 0xbe, 0xa6, 0x8c, +0x81, 0xca, 0x00, 0x05, 0x3e, 0xbe, 0xa6, 0x8c, 0x01, 0x0f, 0x63, 0x6e, 0x2d, 0x74, 0x65, 0x73, +0x74, 0x2d, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x00}; + +/* Invalid SDES packet without chunk item block. */ +static UCHAR test_rtcp_packet_data_7[]={ +0x80, 0xc9, 0x00, 0x01, 0x3e, 0xbe, 0xa6, 0x8c, +0x81, 0xca, 0x00, 0x01, 0x3e, 0xbe, 0xa6, 0x8c}; + +/* Tnvalid SDES packet without chunk block. */ +static UCHAR test_rtcp_packet_data_8[]={ +0x80, 0xc9, 0x00, 0x01, 0x3e, 0xbe, 0xa6, 0x8c, +0x81, 0xca, 0x00, 0x00}; + +/* RR packet wrong ssrc. */ +static UCHAR test_rtcp_packet_data_9[]={ +0x81, 0xc9, 0x00, 0x07, 0x3e, 0xbe, 0xa6, 0x8c, 0x10, 0x00, 0x2c, 0xd6, 0xff, 0xff, 0xff, 0xff, +0x00, 0x01, 0x72, 0xfe, 0x00, 0x00, 0x01, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +/* Unsupported SDES item type. */ +static UCHAR test_rtcp_packet_data_10[]={ +0x80, 0xc9, 0x00, 0x01, 0x3e, 0xbe, 0xa6, 0x8c, +0x81, 0xca, 0x00, 0x05, 0x3e, 0xbe, 0xa6, 0x8c, 0x02, 0x0d, 0x63, 0x6e, 0x2d, 0x74, 0x65, 0x73, +0x74, 0x2d, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x00}; + +/* Invalid header. */ +static UCHAR test_rtcp_packet_data_11[]={ +0x81, 0xc9, 0x00}; + +static PACKET_DATA test_rtcp_packet_data_list[]={ +{test_rtcp_packet_data_0, sizeof(test_rtcp_packet_data_0)}, +{test_rtcp_packet_data_1, sizeof(test_rtcp_packet_data_1)}, +{test_rtcp_packet_data_2, sizeof(test_rtcp_packet_data_2)}, +{test_rtcp_packet_data_3, sizeof(test_rtcp_packet_data_3)}, +{test_rtcp_packet_data_4, sizeof(test_rtcp_packet_data_4)}, +{test_rtcp_packet_data_5, sizeof(test_rtcp_packet_data_5)}, +{test_rtcp_packet_data_6, sizeof(test_rtcp_packet_data_6)}, +{test_rtcp_packet_data_7, sizeof(test_rtcp_packet_data_7)}, +{test_rtcp_packet_data_8, sizeof(test_rtcp_packet_data_8)}, +{test_rtcp_packet_data_9, sizeof(test_rtcp_packet_data_9)}, +{test_rtcp_packet_data_10, sizeof(test_rtcp_packet_data_10)}, +{test_rtcp_packet_data_11, sizeof(test_rtcp_packet_data_11)}, +{NX_NULL, 0} +}; + +static UCHAR rtcp_packet_is_processed = NX_FALSE; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static UINT test_rtcp_receiver_report_callback(NX_RTP_SESSION *session, NX_RTCP_RECEIVER_REPORT *report); +static UINT test_rtcp_sdes_callback(NX_RTCP_SDES_INFO *sdes_info); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtcp_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTCP Abnormal Packet Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + CHECK_STATUS(0, status); + status = nx_udp_enable(&ip_1); + CHECK_STATUS(0, status); + + tx_semaphore_create(&semaphore_test_done, "semaphore test done", 0); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS client_ip_address; + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + nx_rtp_sender_rtcp_receiver_report_callback_set(&rtp_0, test_rtcp_receiver_report_callback); + nx_rtp_sender_rtcp_sdes_callback_set(&rtp_0, test_rtcp_sdes_callback); + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE_VIDEO, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + + /* Set session ssrc value the same as the source identifier in test_rtcp_packet_data packet. */ + rtp_session_0.nx_rtp_session_ssrc = 11478; + + CHECK_STATUS(0, status); + + status = tx_semaphore_get(&semaphore_test_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + CHECK_STATUS(NX_FALSE, rtcp_packet_is_processed); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the client threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *send_packet; +UINT status; +PACKET_DATA *test_data = test_rtcp_packet_data_list; + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_1, &rtp_client_socket, "RTP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_socket, RTP_CLIENT_RTCP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + while(test_data->data) + { + status = nx_packet_allocate(&pool_0, &send_packet, NX_UDP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(send_packet, test_data->data, test_data->length, &pool_0, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_udp_socket_send(&rtp_client_socket, send_packet, RTP_SERVER_ADDRESS, rtp_0.nx_rtp_sender_rtcp_port); + CHECK_STATUS(0, status); + + test_data++; + } + + tx_semaphore_put(&semaphore_test_done); +} + +static UINT test_rtcp_receiver_report_callback(NX_RTP_SESSION *session, NX_RTCP_RECEIVER_REPORT *report) +{ + rtcp_packet_is_processed = NX_TRUE; + + return(NX_SUCCESS); +} + +static UINT test_rtcp_sdes_callback(NX_RTCP_SDES_INFO *sdes_info) +{ + rtcp_packet_is_processed = NX_TRUE; + + return NX_SUCCESS; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtcp_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTCP Abnormal Packet Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtcp_basic_test.c b/test/regression/rtp_test/netx_rtcp_basic_test.c new file mode 100644 index 00000000..2b33d979 --- /dev/null +++ b/test/regression/rtp_test/netx_rtcp_basic_test.c @@ -0,0 +1,232 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define RTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTP_CLIENT_RTP_PORT 6002 +#define RTP_CLIENT_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE_VIDEO 96 +#define RTP_PAYLOAD_TYPE_AUDIO 97 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define test data. */ +#define TEST_TIMESTAMP 1234 +#define TEST_MSW 123 +#define TEST_LSW 456 +#define TEST_TIME_DURATION (6 * TX_TIMER_TICKS_PER_SECOND) + +static UCHAR test_rtp_packet_data[] = "test rtp packet data"; + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET rtcp_client_socket; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; +static NX_RTP_SESSION rtp_session_1; +static NX_RTP_SESSION rtp_session_2; + +/* Define the counters used in the test application... */ +static UINT rtcp_packet_counter = 0; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtcp_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTCP Basic Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + CHECK_STATUS(0, status); + status = nx_udp_enable(&ip_1); + CHECK_STATUS(0, status); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS client_ip_address; +NX_PACKET *send_packet; +UINT time_start; + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + rtp_session_0.nx_rtp_session_ssrc = 11478; + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE_VIDEO, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_1, RTP_PAYLOAD_TYPE_AUDIO, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_2, RTP_PAYLOAD_TYPE_AUDIO, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + CHECK_STATUS(0, status); + + /* If more than one rtp packet is sent during the first tick, rtcp packet will also be sent more than once. + To make a stable test result, wait for a tick here to avoid this situation. */ + tx_thread_sleep(1); + + time_start = tx_time_get(); + + while(tx_time_get() - time_start < TEST_TIME_DURATION) + { + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &send_packet, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(send_packet, (void*)test_rtp_packet_data, sizeof(test_rtp_packet_data), rtp_0.nx_rtp_sender_ip_ptr->nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_packet_send(&rtp_session_0, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + + CHECK_STATUS(0, status); + } + + /* Check if there is memory leak. */ + CHECK_STATUS(pool_0.nx_packet_pool_total, pool_0.nx_packet_pool_available); + + /* Check rtcp packet count. */ + CHECK_STATUS(TEST_TIME_DURATION / (TX_TIMER_TICKS_PER_SECOND * NX_RTCP_INTERVAL) + 1, rtcp_packet_counter); + + status = nx_rtp_sender_session_delete(&rtp_session_2); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_delete(&rtp_session_1); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_delete(&rtp_session_0); + CHECK_STATUS(0, status); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the client threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *received_packet; +UINT status; + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_1, &rtcp_client_socket, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtcp_client_socket, RTP_CLIENT_RTCP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + while(nx_udp_socket_receive(&rtcp_client_socket, &received_packet, (NX_RTCP_INTERVAL + 1) * TX_TIMER_TICKS_PER_SECOND) == NX_SUCCESS) + { + rtcp_packet_counter++;; + nx_packet_release(received_packet); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtcp_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTCP Basic Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtcp_packet_process_test.c b/test/regression/rtp_test/netx_rtcp_packet_process_test.c new file mode 100644 index 00000000..637bdc55 --- /dev/null +++ b/test/regression/rtp_test/netx_rtcp_packet_process_test.c @@ -0,0 +1,279 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define RTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTP_CLIENT_RTP_PORT 6002 +#define RTP_CLIENT_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE_VIDEO 96 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET rtp_client_socket; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; + +/* Define the counters used in the test application... */ +static TX_SEMAPHORE semaphore_test_done; + +/* Define RTCP packet for testing. +--receiver report-- + version: RFC 1899 Version (2) + padding: False + reception report count: 1 + packet type: receiver report (201) + length: 7 + sender ssrc: 1052681868 + source 1: + identifier: 11478 + fraction lost: 255 + cumulative number of packets lost: -1 + extended highest sequence number received: 94974 + interarrival jitter: 444 + last SR timestamp: 0 + delay since last SR timestamp: 0 +--source description-- + version: RFC 1899 Version (2) + padding: False + source count: 1 + packet type: source description (202) + length: 5 + chunk 1: + indentifier: 1052681868 + sdes item: + type: CNAME (1) + length:13 + text: cn-test-cname + type: END (0) +*/ +static UCHAR test_rtcp_packet_data[]={ +0x81, 0xc9, 0x00, 0x07, 0x3e, 0xbe, 0xa6, 0x8c, 0x00, 0x00, 0x2c, 0xd6, 0xff, 0xff, 0xff, 0xff, +0x00, 0x01, 0x72, 0xfe, 0x00, 0x00, 0x01, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x81, 0xca, 0x00, 0x05, 0x3e, 0xbe, 0xa6, 0x8c, 0x01, 0x0d, 0x63, 0x6e, 0x2d, 0x74, 0x65, 0x73, +0x74, 0x2d, 0x63, 0x6e, 0x61, 0x6d, 0x65, 0x00}; + +static UCHAR test_rtp_receiver_cname[] = "cn-test-cname"; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static UINT test_rtcp_receiver_report_callback(NX_RTP_SESSION *session, NX_RTCP_RECEIVER_REPORT *report); +static UINT test_rtcp_sdes_callback(NX_RTCP_SDES_INFO *sdes_info); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtcp_packet_process_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTCP Packet Pocess Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + CHECK_STATUS(0, status); + status = nx_udp_enable(&ip_1); + CHECK_STATUS(0, status); + + tx_semaphore_create(&semaphore_test_done, "semaphore test done", 0); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS client_ip_address; + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + nx_rtp_sender_rtcp_receiver_report_callback_set(&rtp_0, test_rtcp_receiver_report_callback); + nx_rtp_sender_rtcp_sdes_callback_set(&rtp_0, test_rtcp_sdes_callback); + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE_VIDEO, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + + /* Set session ssrc value the same as the source identifier in test_rtcp_packet_data packet. */ + rtp_session_0.nx_rtp_session_ssrc = 11478; + + CHECK_STATUS(0, status); + + status = tx_semaphore_get(&semaphore_test_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = tx_semaphore_get(&semaphore_test_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = tx_semaphore_get(&semaphore_test_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the client threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *send_packet; +UINT status; + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_1, &rtp_client_socket, "RTP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_socket, RTP_CLIENT_RTCP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_allocate(&pool_0, &send_packet, NX_UDP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(send_packet, test_rtcp_packet_data, sizeof(test_rtcp_packet_data), &pool_0, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_udp_socket_send(&rtp_client_socket, send_packet, RTP_SERVER_ADDRESS, rtp_0.nx_rtp_sender_rtcp_port); + CHECK_STATUS(0, status); + + /* Set rtcp receiver report callback to NULL. */ + status = nx_rtp_sender_rtcp_receiver_report_callback_set(&rtp_0, NX_NULL); + CHECK_STATUS(0, status); + + /* Set rtcp sdes callback to NULL. */ + status = nx_rtp_sender_rtcp_sdes_callback_set(&rtp_0, NX_NULL); + CHECK_STATUS(0, status); + + status = nx_packet_allocate(&pool_0, &send_packet, NX_UDP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(send_packet, test_rtcp_packet_data, sizeof(test_rtcp_packet_data), &pool_0, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_udp_socket_send(&rtp_client_socket, send_packet, RTP_SERVER_ADDRESS, rtp_0.nx_rtp_sender_rtcp_port); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_test_done); +} + +static UINT test_rtcp_receiver_report_callback(NX_RTP_SESSION *session, NX_RTCP_RECEIVER_REPORT *report) +{ + if((report->receiver_ssrc == 1052681868) && + (report->fraction_loss == 255) && + (report->packet_loss == -1) && + (report->extended_max = 94974) && + (report->jitter == 444) && + (report->last_sr == 0) && + (report->delay == 0)) + { + tx_semaphore_put(&semaphore_test_done); + } + + return(NX_SUCCESS); +} + +static UINT test_rtcp_sdes_callback(NX_RTCP_SDES_INFO *sdes_info) +{ + if((sdes_info->ssrc == 1052681868) && + (strncmp(sdes_info->cname, test_rtp_receiver_cname, sizeof(test_rtp_receiver_cname) - 1) == 0) && + (sdes_info->cname_length == sizeof(test_rtp_receiver_cname) - 1)) + { + tx_semaphore_put(&semaphore_test_done); + } + + return NX_SUCCESS; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtcp_packet_process_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTCP Packet Process Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtcp_packet_send_test.c b/test/regression/rtp_test/netx_rtcp_packet_send_test.c new file mode 100644 index 00000000..424f8aa1 --- /dev/null +++ b/test/regression/rtp_test/netx_rtcp_packet_send_test.c @@ -0,0 +1,203 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 24 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define RTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTP_CLIENT_RTP_PORT 6002 +#define RTP_CLIENT_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE_VIDEO 96 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define test data. */ +#define TEST_TIMESTAMP 1234 +#define TEST_MSW 123 +#define TEST_LSW 456 + +static UCHAR test_rtp_packet_data[] = "test rtp packet data"; +static UCHAR test_rtcp_packet_data[] = {0x80, 0xc8, 0x0, 0x6, 0x0, 0x0, 0x2c, 0xd6, 0x0, 0x0, 0x0, 0x7b, 0x0, 0x0, 0x1, 0xc8, 0x0, 0x0, 0x4, 0xd2, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x81, 0xca, 0x0, 0x8, 0x0, 0x0, 0x2c, 0xd6, 0x1, 0x17, 0x41, 0x7a, 0x75, +0x72, 0x65, 0x52, 0x54, 0x4f, 0x53, 0x40, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x0, 0x0, 0x0}; + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET rtcp_client_socket; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; + +/* Define the counters used in the test application... */ + +static TX_SEMAPHORE semaphore_test_done; + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtcp_packet_send_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTCP Packet Send Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + CHECK_STATUS(0, status); + status = nx_udp_enable(&ip_1); + CHECK_STATUS(0, status); + + tx_semaphore_create(&semaphore_test_done, "semaphore test done", 0); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS client_ip_address; +NX_PACKET *send_packet; + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE_VIDEO, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + rtp_session_0.nx_rtp_session_ssrc = 11478; + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &send_packet, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(send_packet, (void*)test_rtp_packet_data, sizeof(test_rtp_packet_data), rtp_0.nx_rtp_sender_ip_ptr->nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_packet_send(&rtp_session_0, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + + CHECK_STATUS(0, status); + + status = tx_semaphore_get(&semaphore_test_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the client threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *received_packet; +UINT status; + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_1, &rtcp_client_socket, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtcp_client_socket, RTP_CLIENT_RTCP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_udp_socket_receive(&rtcp_client_socket, &received_packet, 5 * NX_IP_PERIODIC_RATE); + if ((status == NX_SUCCESS) && + (received_packet->nx_packet_length == sizeof(test_rtcp_packet_data)) && + (memcmp(received_packet->nx_packet_prepend_ptr, test_rtcp_packet_data, sizeof(test_rtcp_packet_data)) == 0)) + { + tx_semaphore_put(&semaphore_test_done); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtcp_packet_send_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTCP Packet Send Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtp_api_test.c b/test/regression/rtp_test/netx_rtp_api_test.c new file mode 100644 index 00000000..776e26de --- /dev/null +++ b/test/regression/rtp_test/netx_rtp_api_test.c @@ -0,0 +1,152 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD test_thread; + +/* Define the ThreadX object control blocks... */ + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; + +/* Define thread prototypes. */ + +static void test_entry(ULONG thread_input); + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&test_thread, "Test thread", test_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); +} + +void test_entry(ULONG thread_input) +{ +UINT status; +UINT rtp_port; + + + /* Print out test information banner. */ + printf("NetX Test: RTP API Test............................................"); + + memset(&rtp_0, 0, sizeof(NX_RTP_SENDER)); + + /* Test and check nx_rtp_sender_create */ + status = nx_rtp_sender_create(NX_NULL, NX_NULL, NX_NULL, NX_NULL, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtp_sender_create(&rtp_0, NX_NULL, NX_NULL, NX_NULL, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtp_sender_create(&rtp_0, &ip_0, NX_NULL, NX_NULL, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, NX_NULL, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Test and check nx_rtp_sender_delete */ + status = nx_rtp_sender_delete(NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Test and check nx_rtp_sender_port_get */ + status = nx_rtp_sender_port_get(NX_NULL, NX_NULL, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtp_sender_port_get(&rtp_0, NX_NULL, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtp_sender_port_get(&rtp_0, &rtp_port, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Test and check nx_rtp_sender_session_create */ + status = nx_rtp_sender_session_create(NX_NULL, NX_NULL, 0, 0, NX_NULL, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtp_sender_session_create(&rtp_0, NX_NULL, 0, 0, NX_NULL, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, 0, 0, NX_NULL, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Test and check nx_rtp_sender_session_packet_allocate */ + status = nx_rtp_sender_session_packet_allocate(NX_NULL, NX_NULL, NX_WAIT_FOREVER); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, NX_NULL, NX_WAIT_FOREVER); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Test and check nx_rtp_sender_session_sequence_number_get */ + status = nx_rtp_sender_session_sequence_number_get(NX_NULL, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtp_sender_session_sequence_number_get(&rtp_session_0, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Test and check nx_rtp_sender_session_ssrc_get */ + status = nx_rtp_sender_session_ssrc_get(NX_NULL, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtp_sender_session_ssrc_get(&rtp_session_0, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Test and check nx_rtp_sender_session_packet_send */ + status = nx_rtp_sender_session_packet_send(NX_NULL, NX_NULL, NX_NULL, 0, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtp_sender_session_packet_send(&rtp_session_0, NX_NULL, NX_NULL, 0, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Test and check RTCP API functions */ + status = nx_rtp_sender_rtcp_receiver_report_callback_set(NX_NULL, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + + status = nx_rtp_sender_rtcp_receiver_report_callback_set(&rtp_0, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + + status = nx_rtp_sender_rtcp_sdes_callback_set(NX_NULL, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + + status = nx_rtp_sender_rtcp_sdes_callback_set(&rtp_0, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTP API Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtp_basic_test.c b/test/regression/rtp_test/netx_rtp_basic_test.c new file mode 100644 index 00000000..74afc3da --- /dev/null +++ b/test/regression/rtp_test/netx_rtp_basic_test.c @@ -0,0 +1,264 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 10 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define RTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTP_CLIENT_RTP_PORT 6002 +#define RTP_CLIENT_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE 96 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define test data. */ +#define TEST_TIMESTAMP 1234 +#define TEST_MSW 123 +#define TEST_LSW 456 + +static UCHAR test_rtp_packet_data[] = "test rtp packet data"; + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET rtp_client_socket; + +static TX_SEMAPHORE semaphore_test_0_done; +static TX_SEMAPHORE semaphore_test_1_done; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; +static UINT rtp_port; +static UINT rtcp_port; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_basic_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTP Basic Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *)first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + CHECK_STATUS(0, status); + status = nx_udp_enable(&ip_1); + CHECK_STATUS(0, status); + + /* Create semaphores for test done notification */ + tx_semaphore_create(&semaphore_test_0_done, "semaphore test 0", 0); + tx_semaphore_create(&semaphore_test_1_done, "semaphore test 1", 0); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS client_ip_address; +NX_PACKET *send_packet; +UINT time_start; + + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + /* Get the udp port pair for rtp and rtcp */ + status = nx_rtp_sender_port_get(&rtp_0, &rtp_port, &rtcp_port); + CHECK_STATUS(0, status); + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + CHECK_STATUS(0, status); + + /* If more than one rtp packet is sent during the first tick, rtcp packet will also be sent more than once. + To make a stable test result, wait for a tick here to avoid this situation. */ + tx_thread_sleep(1); + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &send_packet, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(send_packet, (void*)test_rtp_packet_data, sizeof(test_rtp_packet_data), rtp_0.nx_rtp_sender_ip_ptr->nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_packet_send(&rtp_session_0, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + /* Wait for the check in test thread 1 done. */ + status = tx_semaphore_get(&semaphore_test_1_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Delete and release resources */ + status = nx_rtp_sender_session_delete(&rtp_session_0); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_delete(&rtp_0); + CHECK_STATUS(0, status); + + /* Put the semaphore to notify thread 1 it is fine to check resource leakage. */ + tx_semaphore_put(&semaphore_test_0_done); +} + +/* Define the client threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *received_packet; +UINT status; +UCHAR *data; + + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_1, &rtp_client_socket, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_socket, RTP_CLIENT_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_socket, &received_packet, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + /* Validate RTP payload data */ + data = received_packet -> nx_packet_prepend_ptr; + + /* Check RTP version byte */ + CHECK_STATUS(0x80, *data); + + /* Move to check RTP data byte for payload type with marker */ + data++; + CHECK_STATUS((0x80 | RTP_PAYLOAD_TYPE), *data); + + /* Move to check RTP data bytes for sequence number */ + data++; + CHECK_STATUS((rtp_session_0.nx_rtp_session_sequence_number - 1), (data[0] << 8 | data[1])); + + /* Move to check RTP data bytes for time stamp */ + data += 2; + CHECK_STATUS(rtp_session_0.nx_rtp_session_rtp_timestamp, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for ssrc */ + data += 4; + CHECK_STATUS(rtp_session_0.nx_rtp_session_ssrc, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for data payload */ + data += 4; + for (UINT i = 0; i < sizeof(test_rtp_packet_data); i++) + { + CHECK_STATUS(*(test_rtp_packet_data + i), data[i]); + } + + /* Release the receive packet when the check finishes. */ + nx_packet_release(received_packet); + + /* Set the flag to notify test thread 0 that the check finishes. */ + tx_semaphore_put(&semaphore_test_1_done); + + /* Wait for the check in test thread 0 done. */ + status = tx_semaphore_get(&semaphore_test_0_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check if there is memory leak. */ + CHECK_STATUS(pool_0.nx_packet_pool_total, pool_0.nx_packet_pool_available); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTP Basic Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtp_free_udp_port_find_test.c b/test/regression/rtp_test/netx_rtp_free_udp_port_find_test.c new file mode 100644 index 00000000..8eea5e8d --- /dev/null +++ b/test/regression/rtp_test/netx_rtp_free_udp_port_find_test.c @@ -0,0 +1,224 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "nx_udp.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 10 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define RTP_CLIENT_RTP_PORT 6002 +#define RTP_CLIENT_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE 96 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +static NX_UDP_SOCKET udp_socket_0; +static NX_UDP_SOCKET udp_socket_1; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static UINT rtp_port; +static UINT rtcp_port; + +static NX_UDP_SOCKET my_socket[NX_MAX_PORT + 1]; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_free_udp_port_find_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTP Free UDP Port Find Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *)first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + CHECK_STATUS(0, status); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +UINT i; + + + /* Create the test udp socket for use */ + status = nx_udp_socket_create(&ip_0, &udp_socket_0, "Test Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + status += nx_udp_socket_create(&ip_0, &udp_socket_1, "Test Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + /* Test 1: occupy the initial rtp port to test if rtp sender can find and bind following ports */ + status = nx_udp_socket_bind(&udp_socket_0, NX_RTP_SENDER_INITIAL_RTP_PORT, NX_NO_WAIT); + status += nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + status += nx_rtp_sender_port_get(&rtp_0, &rtp_port, &rtcp_port); + CHECK_STATUS(0, status); + CHECK_STATUS(NX_RTP_SENDER_INITIAL_RTP_PORT + 2, rtp_port); /* rtp port shall be an even number */ + CHECK_STATUS(NX_RTP_SENDER_INITIAL_RTP_PORT + 3, rtcp_port); /* rtcp port shall be an odd number next to rtp port */ + nx_udp_socket_unbind(&udp_socket_0); + status = nx_rtp_sender_delete(&rtp_0); + CHECK_STATUS(0, status); + + /* Test 2: occupy the initial rtcp port to test if rtp sender can find and bind following ports */ + status = nx_udp_socket_bind(&udp_socket_0, (NX_RTP_SENDER_INITIAL_RTP_PORT + 1), NX_NO_WAIT); + CHECK_STATUS(0, status); + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + status += nx_rtp_sender_port_get(&rtp_0, &rtp_port, &rtcp_port); + CHECK_STATUS(0, status); + CHECK_STATUS(NX_RTP_SENDER_INITIAL_RTP_PORT + 2, rtp_port); /* rtp port shall be an even number */ + CHECK_STATUS(NX_RTP_SENDER_INITIAL_RTP_PORT + 3, rtcp_port); /* rtcp port shall be an odd number next to rtp port */ + nx_udp_socket_unbind(&udp_socket_0); + status = nx_rtp_sender_delete(&rtp_0); + CHECK_STATUS(0, status); + + /* Test 3: occupy the initial rtp port and the next rtcp port to test if rtp sender can find and bind following ports */ + status = nx_udp_socket_bind(&udp_socket_0, (NX_RTP_SENDER_INITIAL_RTP_PORT), NX_NO_WAIT); + status += nx_udp_socket_bind(&udp_socket_1, (NX_RTP_SENDER_INITIAL_RTP_PORT + 3), NX_NO_WAIT); + CHECK_STATUS(0, status); + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + status += nx_rtp_sender_port_get(&rtp_0, &rtp_port, &rtcp_port); + CHECK_STATUS(0, status); + CHECK_STATUS(NX_RTP_SENDER_INITIAL_RTP_PORT + 4, rtp_port); /* rtp port shall be an even number */ + CHECK_STATUS(NX_RTP_SENDER_INITIAL_RTP_PORT + 5, rtcp_port); /* rtcp port shall be an odd number next to rtp port */ + nx_udp_socket_unbind(&udp_socket_0); + nx_udp_socket_unbind(&udp_socket_1); + status = nx_rtp_sender_delete(&rtp_0); + CHECK_STATUS(0, status); + + /* Test 4: occupy all odd ports and see no free ports. */ + for (i = (NX_RTP_SENDER_INITIAL_RTP_PORT + 1); i <= NX_MAX_PORT; i += 2) + { + status = nx_udp_socket_create(&ip_0, &my_socket[i], "Socket Array", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&my_socket[i], i, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(NX_NO_FREE_PORTS, status); + + /* Test 5: occupy all odd ports as well as port 65532 & 65534, unbind port 65533 and see no free ports. */ + status = nx_udp_socket_create(&ip_0, &my_socket[65534], "Socket Array", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&my_socket[65534], 65534, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_create(&ip_0, &my_socket[65532], "Socket Array", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_udp_socket_bind(&my_socket[65532], 65532, NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Unbind port 65533. */ + status = nx_udp_socket_unbind(&my_socket[65533]); + + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(NX_NO_FREE_PORTS, status); + + /* Finally, delete the sockets and check if there is memory leak. */ + nx_udp_socket_delete(&udp_socket_0); + nx_udp_socket_delete(&udp_socket_1); + CHECK_STATUS(pool_0.nx_packet_pool_total, pool_0.nx_packet_pool_available); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_free_udp_port_find_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTP Free UDP Port Find Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtp_multi_clients_test.c b/test/regression/rtp_test/netx_rtp_multi_clients_test.c new file mode 100644 index 00000000..06d0476a --- /dev/null +++ b/test/regression/rtp_test/netx_rtp_multi_clients_test.c @@ -0,0 +1,380 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 20 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1, 2, 3, 4) +#define RTP_CLIENT_1_ADDRESS IP_ADDRESS(1, 2, 3, 5) +#define RTP_CLIENT_2_ADDRESS IP_ADDRESS(1, 2, 3, 6) +#define RTP_CLIENT_1_RTP_PORT 6002 +#define RTP_CLIENT_1_RTCP_PORT 6003 +#define RTP_CLIENT_2_RTP_PORT 6002 +#define RTP_CLIENT_2_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE 96 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define test data. */ +#define TEST_TIMESTAMP 1234 +#define TEST_MSW 123 +#define TEST_LSW 456 + +/* Define the number of tests to do */ +#define TEST_CYCLES 5 + +static UCHAR test_rtp_packet_data[] = "test rtp packet data"; + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static TX_THREAD ntest_2; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; +static NX_UDP_SOCKET rtp_client_1_socket; +static NX_UDP_SOCKET rtp_client_2_socket; + +static TX_SEMAPHORE semaphore_test_1_done; +static TX_SEMAPHORE semaphore_test_2_done; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; +static NX_RTP_SESSION rtp_session_1; +static UINT rtp_port; +static UINT rtcp_port; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_2_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_multi_clients_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTP Multi-Clients Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *)first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_2, "thread 2", ntest_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_1_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 2", RTP_CLIENT_2_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for all IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + status += nx_udp_enable(&ip_2); + CHECK_STATUS(0, status); + + /* Create semaphores for test done notification */ + tx_semaphore_create(&semaphore_test_1_done, "semaphore test 1", 0); + tx_semaphore_create(&semaphore_test_2_done, "semaphore test 2", 0); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS client_1_ip_address; +NXD_ADDRESS client_2_ip_address; +NX_PACKET *send_packet; +UINT time_start; + + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + /* Get the udp port pair for rtp and rtcp */ + status = nx_rtp_sender_port_get(&rtp_0, &rtp_port, &rtcp_port); + CHECK_STATUS(0, status); + + /* Setup rtp sender session. */ + client_1_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_1_ip_address.nxd_ip_address.v4 = RTP_CLIENT_1_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE, + 0, &client_1_ip_address, + RTP_CLIENT_1_RTP_PORT, RTP_CLIENT_1_RTCP_PORT); + CHECK_STATUS(0, status); + + /* Setup rtp sender session. */ + client_2_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_2_ip_address.nxd_ip_address.v4 = RTP_CLIENT_2_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_1, RTP_PAYLOAD_TYPE, + 0, &client_2_ip_address, + RTP_CLIENT_2_RTP_PORT, RTP_CLIENT_2_RTCP_PORT); + CHECK_STATUS(0, status); + + /* Wait for client threads ready. */ + tx_thread_sleep(20); + + /* Begin test cycles */ + for (UINT i = 0; i < TEST_CYCLES; i++) + { + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &send_packet, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(send_packet, (void*)test_rtp_packet_data, sizeof(test_rtp_packet_data), rtp_0.nx_rtp_sender_ip_ptr->nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_packet_send(&rtp_session_0, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_1, &send_packet, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(send_packet, (void*)test_rtp_packet_data, sizeof(test_rtp_packet_data), rtp_0.nx_rtp_sender_ip_ptr->nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_packet_send(&rtp_session_1, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + } + + /* Wait for the check in test thread 1 done. */ + status = tx_semaphore_get(&semaphore_test_1_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait for the check in test thread 2 done. */ + status = tx_semaphore_get(&semaphore_test_2_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Delete and release resources */ + status = nx_rtp_sender_session_delete(&rtp_session_0); + status += nx_rtp_sender_session_delete(&rtp_session_1); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_delete(&rtp_0); + CHECK_STATUS(0, status); + + /* Check if there is memory leak. */ + CHECK_STATUS(pool_0.nx_packet_pool_total, pool_0.nx_packet_pool_available); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the first client threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *received_packet; +UINT status; +UCHAR *data; + + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_1, &rtp_client_1_socket, "RTCP Client 1 Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_1_socket, RTP_CLIENT_1_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Begin test cycles */ + for (UINT i = 0; i < TEST_CYCLES; i++) + { + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_1_socket, &received_packet, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + /* Validate RTP payload data */ + data = received_packet -> nx_packet_prepend_ptr; + + /* Check RTP version byte */ + CHECK_STATUS(0x80, *data); + + /* Move to check RTP data byte for payload type with marker */ + data++; + CHECK_STATUS((0x80 | RTP_PAYLOAD_TYPE), *data); + + /* Move to check RTP data bytes for sequence number */ + data++; + CHECK_STATUS((rtp_session_0.nx_rtp_session_sequence_number - 1), (data[0] << 8 | data[1])); + + /* Move to check RTP data bytes for time stamp */ + data += 2; + CHECK_STATUS(rtp_session_0.nx_rtp_session_rtp_timestamp, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for ssrc */ + data += 4; + CHECK_STATUS(rtp_session_0.nx_rtp_session_ssrc, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for data payload */ + data += 4; + for (UINT i = 0; i < sizeof(test_rtp_packet_data); i++) + { + CHECK_STATUS(*(test_rtp_packet_data + i), data[i]); + } + + /* Release the receive packet when the check finishes. */ + nx_packet_release(received_packet); + } + + /* Set the flag to notify test thread 0 that the check finishes. */ + tx_semaphore_put(&semaphore_test_1_done); +} + +/* Define the second client threads. */ +static void ntest_2_entry(ULONG thread_input) +{ +NX_PACKET *received_packet; +UINT status; +UCHAR *data; + + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_2, &rtp_client_2_socket, "RTCP Client 2 Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_2_socket, RTP_CLIENT_2_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Begin test cycles */ + for (UINT i = 0; i < TEST_CYCLES; i++) + { + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_2_socket, &received_packet, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + /* Validate RTP payload data */ + data = received_packet -> nx_packet_prepend_ptr; + + /* Check RTP version byte */ + CHECK_STATUS(0x80, *data); + + /* Move to check RTP data byte for payload type with marker */ + data++; + CHECK_STATUS((0x80 | RTP_PAYLOAD_TYPE), *data); + + /* Move to check RTP data bytes for sequence number */ + data++; + CHECK_STATUS((rtp_session_1.nx_rtp_session_sequence_number - 1), (data[0] << 8 | data[1])); + + /* Move to check RTP data bytes for time stamp */ + data += 2; + CHECK_STATUS(rtp_session_1.nx_rtp_session_rtp_timestamp, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for ssrc */ + data += 4; + CHECK_STATUS(rtp_session_1.nx_rtp_session_ssrc, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for data payload */ + data += 4; + for (UINT i = 0; i < sizeof(test_rtp_packet_data); i++) + { + CHECK_STATUS(*(test_rtp_packet_data + i), data[i]); + } + + /* Release the receive packet when the check finishes. */ + nx_packet_release(received_packet); + } + + /* Set the flag to notify test thread 0 that the check finishes. */ + tx_semaphore_put(&semaphore_test_2_done); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_multi_clients_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTP Multi-Clients Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtp_multi_interfaces_test.c b/test/regression/rtp_test/netx_rtp_multi_interfaces_test.c new file mode 100644 index 00000000..c572d898 --- /dev/null +++ b/test/regression/rtp_test/netx_rtp_multi_interfaces_test.c @@ -0,0 +1,948 @@ +/* This case tests RTSP with RTP. */ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) && (NX_MAX_PHYSICAL_INTERFACES > 1) +#include "nx_rtp_sender.h" +#include "nx_rtsp_server.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UCHAR rtsp_stack[DEMO_STACK_SIZE]; + +static TX_THREAD client_0_thread; +static TX_THREAD client_1_thread; +static NX_PACKET_POOL client_0_pool; +static NX_PACKET_POOL client_1_pool; +static NX_IP client_0_ip; +static NX_IP client_1_ip; +static NX_TCP_SOCKET rtsp_client_0; +static NX_TCP_SOCKET rtsp_client_1; +static NX_UDP_SOCKET rtp_client_0; +static NX_UDP_SOCKET rtp_client_1; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_RTSP_SERVER rtsp_server; +static NX_RTP_SENDER rtp_server; +static NX_RTP_SESSION rtp_session_0; +static NX_RTP_SESSION rtp_session_1; + +static UINT error_counter; + +static TX_SEMAPHORE semaphore_client_0_start; +static TX_SEMAPHORE semaphore_client_1_start; +static TX_SEMAPHORE semaphore_rtp_send_0; +static TX_SEMAPHORE semaphore_rtp_send_1; +static TX_EVENT_FLAGS_GROUP events_play; + + +static void thread_client_0_entry(ULONG thread_input); +static void thread_client_1_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr); +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length); +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_SERVER_1_ADDRESS IP_ADDRESS(10,3,3,4) +#define TEST_CLIENT_0_ADDRESS IP_ADDRESS(1,2,3,5) +#define TEST_CLIENT_1_ADDRESS IP_ADDRESS(10,3,3,5) +#define RTSP_SERVER_PORT 554 + +#define RTSP_0_SESSION_ID 23754311 +#define RTSP_1_SESSION_ID 23754312 +#define RTP_0_RTP_PORT 49752 +#define RTP_0_RTCP_PORT 49753 +#define RTP_1_RTP_PORT 49754 +#define RTP_1_RTCP_PORT 49755 + +#define RTP_PAYLOAD_TYPE_0 96 +#define RTP_PAYLOAD_TYPE_1 97 +#define RTP_TIMESTAMP_INIT_VALUE 40 +#define CNAME "AzureRTOS@microsoft.com" +#define TEST_MSW 123 +#define TEST_LSW 456 + +/* Define events for the server task */ +#define ALL_EVENTS ((ULONG)0xFFFFFFFF) +#define PLAY_0_EVENT ((ULONG)0x00000001) +#define PLAY_1_EVENT ((ULONG)0x00000002) +#define DONE_0_EVENT ((ULONG)0x00000004) +#define DONE_1_EVENT ((ULONG)0x00000008) + +static UCHAR rtsp_0_option_request[] = "\ +OPTIONS rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_1_option_request[] = "\ +OPTIONS rtsp://10.3.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_0_describe_request[] = "\ +DESCRIBE rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_1_describe_request[] = "\ +DESCRIBE rtsp://10.3.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_0_setup_request[] = "\ +SETUP rtsp://1.2.3.4:554/live.stream/trackID=0 RTSP/1.0\r\n\ +CSeq: 4\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49752-49753\r\n\r\n\ +"; + +static UCHAR rtsp_1_setup_request[] = "\ +SETUP rtsp://10.3.3.4:554/live.stream/trackID=1 RTSP/1.0\r\n\ +CSeq: 4\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49754-49755\r\n\r\n\ +"; + +static UCHAR rtsp_0_play_request[] = "\ +PLAY rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +static UCHAR rtsp_1_play_request[] = "\ +PLAY rtsp://10.3.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754312\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +static UCHAR rtsp_0_pause_request[] = "\ +PAUSE rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 7\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_1_pause_request[] = "\ +PAUSE rtsp://10.3.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 7\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754312\r\n\r\n\ +"; + +static UCHAR rtsp_0_teardown_request[] = "\ +TEARDOWN rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 8\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_1_teardown_request[] = "\ +TEARDOWN rtsp://10.3.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 8\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754312\r\n\r\n\ +"; + +typedef enum +{ + OPTION_INDEX, + DESCRIBE_INDEX, + SETUP_INDEX, + PLAY_INDEX, + TEARDOWN_INDEX +}REQUEST_INDEX; + +static UCHAR *client_0_rtsp_request_list[] = +{ +rtsp_0_option_request, +rtsp_0_describe_request, +rtsp_0_setup_request, +rtsp_0_play_request, +rtsp_0_teardown_request, +}; + +static UCHAR *client_1_rtsp_request_list[] = +{ +rtsp_1_option_request, +rtsp_1_describe_request, +rtsp_1_setup_request, +rtsp_1_play_request, +rtsp_1_teardown_request, +}; + +static UINT client_0_rtsp_request_size[] = +{ +sizeof(rtsp_0_option_request) - 1, +sizeof(rtsp_0_describe_request) - 1, +sizeof(rtsp_0_setup_request) - 1, +sizeof(rtsp_0_play_request) - 1, +sizeof(rtsp_0_teardown_request) - 1, +}; + +static UINT client_1_rtsp_request_size[] = +{ +sizeof(rtsp_1_option_request) - 1, +sizeof(rtsp_1_describe_request) - 1, +sizeof(rtsp_1_setup_request) - 1, +sizeof(rtsp_1_play_request) - 1, +sizeof(rtsp_1_teardown_request) - 1, +}; + +static UINT client_0_rtsp_request_num = sizeof(client_0_rtsp_request_size) / sizeof(UINT); +static UINT client_1_rtsp_request_num = sizeof(client_1_rtsp_request_size) / sizeof(UINT); + +static UCHAR rtp_data[] = "rtp data for test"; + +static CHAR *sdp="v=0\r\ns=MPEG-1 or 2 Audio, streamed by the NetX RTSP Server\r\n\ +m=video 0 RTP/AVP 96\r\n\ +a=rtpmap:96 H264/90000\r\n\ +a=fmtp:96 profile-level-id=42A01E; packetization-mode=1\r\n\ +a=control:trackID=0\r\n\ +m=audio 0 RTP/AVP 97\r\n\ +a=rtpmap:97 mpeg4-generic/44100/1\r\n\ +a=fmtp:97 SizeLength=13\r\n\ +a=control:trackID=1\r\n"; + +static UINT seq_0 = 0, seq_1 = 0; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_multi_interfaces_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Attach a new ip interface to server ip. */ + status = nx_ip_interface_attach(&server_ip, "Test Server IP 1 Interface", TEST_SERVER_1_ADDRESS, + 0xFFFFFF00UL, _nx_ram_network_driver_1024); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_0_thread, "Test Client 0", thread_client_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + status = tx_thread_create(&client_1_thread, "Test Client 1", thread_client_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_0_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + status = nx_packet_pool_create(&client_1_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_0_ip, "Test Client IP 0", TEST_CLIENT_0_ADDRESS, + 0xFFFFFF00UL, &client_0_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_1_ip, "Test Client IP 1", TEST_CLIENT_1_ADDRESS, + 0xFFFFFF00UL, &client_1_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable arp */ + status = nx_arp_enable(&client_0_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + status = nx_arp_enable(&client_1_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_0_ip); + CHECK_STATUS(0, status); + status = nx_tcp_enable(&client_1_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&client_0_ip); + CHECK_STATUS(0, status); + status = nx_udp_enable(&client_1_ip); + CHECK_STATUS(0, status); + + /* Create semaphores and events group. */ + tx_semaphore_create(&semaphore_client_0_start, "semaphore client 0 start", 0); + tx_semaphore_create(&semaphore_client_1_start, "semaphore client 1 start", 0); + tx_semaphore_create(&semaphore_rtp_send_0, "semaphore rtp send 0", 0); + tx_semaphore_create(&semaphore_rtp_send_1, "semaphore rtp send 1", 0); + status = tx_event_flags_create(&events_play, "events play"); + CHECK_STATUS(0, status); +} + +void thread_client_0_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_0_ip, &rtsp_client_0, "Test Client 0 Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client_0, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&client_0_ip, &rtp_client_0, "RTCP Client 0 Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_0, RTP_0_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_client_0_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_0, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < client_0_rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_0_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, client_0_rtsp_request_list[i], client_0_rtsp_request_size[i], &client_0_pool, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client_0, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=1.2.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%ld", + RTP_0_RTP_PORT, RTP_0_RTCP_PORT, + rtp_server.nx_rtp_sender_rtp_port, + rtp_server.nx_rtp_sender_rtcp_port, + rtp_session_0.nx_rtp_session_ssrc); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://1.2.3.4:554/live.stream/trackID=0;seq=%d;rtptime=%d", + seq_0, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, "Range: npt=0.0-", sizeof("Range: npt=0.0-") - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + tx_semaphore_get(&semaphore_rtp_send_0, NX_WAIT_FOREVER); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_0, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + nx_tcp_socket_disconnect(&rtsp_client_0, NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_event_flags_set(&events_play, DONE_0_EVENT, TX_OR); + nx_tcp_client_socket_unbind(&rtsp_client_0); + nx_tcp_socket_delete(&rtsp_client_0); +} + +void thread_client_1_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_1_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_1_ip, &rtsp_client_1, "Test Client 1 Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client_1, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&client_1_ip, &rtp_client_1, "RTCP Client 1 Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_1, RTP_1_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_client_1_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_1, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < client_1_rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_1_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, client_1_rtsp_request_list[i], client_1_rtsp_request_size[i], &client_1_pool, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client_1, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client_1, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=10.3.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%ld", + RTP_1_RTP_PORT, RTP_1_RTCP_PORT, + rtp_server.nx_rtp_sender_rtp_port, + rtp_server.nx_rtp_sender_rtcp_port, + rtp_session_1.nx_rtp_session_ssrc); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://10.3.3.4:554/live.stream/trackID=1;seq=%d;rtptime=%d", + seq_1, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, "Range: npt=0.0-", sizeof("Range: npt=0.0-") - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + tx_semaphore_get(&semaphore_rtp_send_1, NX_WAIT_FOREVER); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_1, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + nx_tcp_socket_disconnect(&rtsp_client_1, NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_event_flags_set(&events_play, DONE_1_EVENT, TX_OR); + nx_tcp_client_socket_unbind(&rtsp_client_1); + nx_tcp_socket_delete(&rtsp_client_1); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +ULONG events = 0; +USHORT client_0_done = NX_FALSE; +USHORT client_1_done = NX_FALSE; + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP Multi Interfaces Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Create RTSP server. */ + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_delete(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + /* Set callback functions. */ + nx_rtsp_server_describe_callback_set(&rtsp_server, rtsp_describe_callback); + nx_rtsp_server_setup_callback_set(&rtsp_server, rtsp_setup_callback); + nx_rtsp_server_play_callback_set(&rtsp_server, rtsp_play_callback); + nx_rtsp_server_teardown_callback_set(&rtsp_server, rtsp_teardown_callback); + nx_rtsp_server_pause_callback_set(&rtsp_server, rtsp_pause_callback); + nx_rtsp_server_set_parameter_callback_set(&rtsp_server, rtsp_set_parameter_callback); + + /* Start RTSP server. */ + status = nx_rtsp_server_start(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_stop(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_start(&rtsp_server); + CHECK_STATUS(0, status); + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_server, &server_ip, &server_pool, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_client_0_start); + tx_semaphore_put(&semaphore_client_1_start); + + while ((client_0_done) == (NX_FALSE) || (client_1_done == NX_FALSE)) + { + + /* Wait for events to do */ + tx_event_flags_get(&events_play, ALL_EVENTS, TX_OR_CLEAR, &events, TX_WAIT_FOREVER); + + if (events & PLAY_0_EVENT) + { + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(packet_ptr, rtp_data, sizeof(rtp_data) - 1, rtp_server.nx_rtp_sender_ip_ptr -> nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Send packet. */ + status = nx_rtp_sender_session_packet_send(&rtp_session_0, packet_ptr, RTP_TIMESTAMP_INIT_VALUE, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_rtp_send_0); + } + + if (events & PLAY_1_EVENT) + { + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_1, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(packet_ptr, rtp_data, sizeof(rtp_data) - 1, rtp_server.nx_rtp_sender_ip_ptr -> nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Send packet. */ + status = nx_rtp_sender_session_packet_send(&rtp_session_1, packet_ptr, RTP_TIMESTAMP_INIT_VALUE, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_rtp_send_1); + } + + if (events & DONE_0_EVENT) + { + client_0_done = NX_TRUE; + } + + if (events & DONE_1_EVENT) + { + client_1_done = NX_TRUE; + } + } + + /* Stop and delete rtsp server */ + status = nx_rtsp_server_stop(&rtsp_server); + CHECK_STATUS(0, status); + status = nx_rtsp_server_delete(&rtsp_server); + CHECK_STATUS(0, status); + + /* Check packet pool. */ + CHECK_STATUS(server_pool.nx_packet_pool_available, server_pool.nx_packet_pool_total); + CHECK_STATUS(client_0_pool.nx_packet_pool_available, client_0_pool.nx_packet_pool_total); + CHECK_STATUS(client_1_pool.nx_packet_pool_available, client_1_pool.nx_packet_pool_total); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ +UINT status; + + status = nx_rtsp_server_sdp_set(rtsp_client_ptr, sdp, strlen(sdp)); + return(status); +} + +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr) +{ +UINT status; +UINT rtp_port, rtcp_port; + + /* Get the created and found ports */ + status = nx_rtp_sender_port_get(&rtp_server, &rtp_port, &rtcp_port); + if (status) + { + return(status); + } + transport_ptr -> server_rtp_port = rtp_port; + transport_ptr -> server_rtcp_port = rtcp_port; + + if (strstr(uri, "trackID=0")) + { + /* Setup rtp sender session */ + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_0, RTP_PAYLOAD_TYPE_0, + transport_ptr -> interface_index, &(transport_ptr -> client_ip_address), + transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port); + CHECK_STATUS(0, status); + + /* Obtain generated ssrc */ + status = nx_rtp_sender_session_ssrc_get(&rtp_session_0, &(transport_ptr -> rtp_ssrc)); + CHECK_STATUS(0, status); + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_0_SESSION_ID; + } + else if (strstr(uri, "trackID=1")) + { + /* Setup rtp sender session */ + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_1, RTP_PAYLOAD_TYPE_1, + transport_ptr -> interface_index, &(transport_ptr -> client_ip_address), + transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port); + CHECK_STATUS(0, status); + + /* Obtain generated ssrc */ + status = nx_rtp_sender_session_ssrc_get(&rtp_session_1, &(transport_ptr -> rtp_ssrc)); + CHECK_STATUS(0, status); + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_1_SESSION_ID; + } + else + { + status = NX_RTSP_SERVER_INVALID_REQUEST; + } + + return(status); +} + +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ +UINT status; + + + if (rtsp_client_ptr -> nx_rtsp_client_request_packet -> nx_packet_address.nx_packet_interface_ptr + == &(server_ip.nx_ip_interface[0])) + { + + /* Retrieve the sequence number through rtp sender functions */ + nx_rtp_sender_session_sequence_number_get(&rtp_session_0, &seq_0); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, seq_0, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_range_npt_set(rtsp_client_ptr, 0, 30000); + CHECK_STATUS(0, status); + + tx_event_flags_set(&events_play, PLAY_0_EVENT, TX_OR); + } + else if (rtsp_client_ptr -> nx_rtsp_client_request_packet -> nx_packet_address.nx_packet_interface_ptr + == &(server_ip.nx_ip_interface[1])) + { + + /* Retrieve the sequence number through rtp sender functions */ + nx_rtp_sender_session_sequence_number_get(&rtp_session_1, &seq_1); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=1", sizeof("trackID=1") - 1, seq_1, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + tx_event_flags_set(&events_play, PLAY_1_EVENT, TX_OR); + } + else + { + status = NX_RTSP_SERVER_INVALID_REQUEST; + } + + return(status); +} + +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + + if (rtsp_client_ptr -> nx_rtsp_client_request_packet -> nx_packet_address.nx_packet_interface_ptr + == &(server_ip.nx_ip_interface[0])) + { + nx_rtp_sender_session_delete(&rtp_session_0); + } + else if (rtsp_client_ptr -> nx_rtsp_client_request_packet -> nx_packet_address.nx_packet_interface_ptr + == &(server_ip.nx_ip_interface[1])) + { + nx_rtp_sender_session_delete(&rtp_session_1); + } + else + { + return(NX_RTSP_SERVER_INVALID_REQUEST); + } + + return(NX_SUCCESS); +} + +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr) +{ + return(NX_SUCCESS); +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_multi_interfaces_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP Multi Interfaces Test.......................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtp_multicast_test.c b/test/regression/rtp_test/netx_rtp_multicast_test.c new file mode 100644 index 00000000..9741da2f --- /dev/null +++ b/test/regression/rtp_test/netx_rtp_multicast_test.c @@ -0,0 +1,372 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 20 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define DEMO_MULTICAST_IP_ADDRESS IP_ADDRESS(224, 1, 0, 55) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1, 2, 3, 4) +#define RTP_CLIENT_1_ADDRESS IP_ADDRESS(1, 2, 3, 5) +#define RTP_CLIENT_2_ADDRESS IP_ADDRESS(1, 2, 3, 6) +#define RTP_CLIENT_RTP_PORT 6002 +#define RTP_CLIENT_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE 96 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define test data. */ +#define TEST_TIMESTAMP 1234 +#define TEST_MSW 123 +#define TEST_LSW 456 + +/* Define the number of tests to do */ +#define TEST_CYCLES 5 + +static UCHAR test_rtp_packet_data[] = "test rtp packet data"; + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; +static TX_THREAD ntest_2; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_IP ip_2; +static NX_UDP_SOCKET rtp_client_1_socket; +static NX_UDP_SOCKET rtp_client_2_socket; + +static TX_SEMAPHORE semaphore_test_1_done; +static TX_SEMAPHORE semaphore_test_2_done; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; +static UINT rtp_port; +static UINT rtcp_port; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +static void ntest_2_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_multicast_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTP Multicast Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *)first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_2, "thread 2", ntest_2_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_1_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_2, "NetX IP Instance 2", RTP_CLIENT_2_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 2. */ + status = nx_arp_enable(&ip_2, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for all IP instances. */ + status = nx_udp_enable(&ip_0); + status += nx_udp_enable(&ip_1); + status += nx_udp_enable(&ip_2); + CHECK_STATUS(0, status); + + /* Create semaphores for test done notification */ + tx_semaphore_create(&semaphore_test_1_done, "semaphore test 1", 0); + tx_semaphore_create(&semaphore_test_2_done, "semaphore test 2", 0); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS client_ip_address; +NX_PACKET *send_packet; +UINT time_start; + + + /* Enable IGMP & join in multicast group. */ + status = nx_igmp_enable(&ip_0); + status = nx_igmp_multicast_join(&ip_0, DEMO_MULTICAST_IP_ADDRESS); + CHECK_STATUS(0, status); + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + /* Get the udp port pair for rtp and rtcp */ + status = nx_rtp_sender_port_get(&rtp_0, &rtp_port, &rtcp_port); + CHECK_STATUS(0, status); + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = DEMO_MULTICAST_IP_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + CHECK_STATUS(0, status); + + /* Wait for client threads ready. */ + tx_thread_sleep(20); + + /* Begin test cycles */ + for (UINT i = 0; i < TEST_CYCLES; i++) + { + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &send_packet, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(send_packet, (void*)test_rtp_packet_data, sizeof(test_rtp_packet_data), rtp_0.nx_rtp_sender_ip_ptr->nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_packet_send(&rtp_session_0, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + } + + /* Wait for the check in test thread 1 done. */ + status = tx_semaphore_get(&semaphore_test_1_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait for the check in test thread 2 done. */ + status = tx_semaphore_get(&semaphore_test_2_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Delete and release resources */ + status = nx_rtp_sender_session_delete(&rtp_session_0); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_delete(&rtp_0); + CHECK_STATUS(0, status); + + /* Check if there is memory leak. */ + CHECK_STATUS(pool_0.nx_packet_pool_total, pool_0.nx_packet_pool_available); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Define the first client threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *received_packet; +UINT status; +UCHAR *data; + + + /* Enable IGMP & join in multicast group. */ + status = nx_igmp_enable(&ip_1); + status += nx_igmp_multicast_join(&ip_1, DEMO_MULTICAST_IP_ADDRESS); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_1, &rtp_client_1_socket, "RTCP Client 1 Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_1_socket, RTP_CLIENT_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Begin test cycles */ + for (UINT i = 0; i < TEST_CYCLES; i++) + { + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_1_socket, &received_packet, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + /* Validate RTP payload data */ + data = received_packet -> nx_packet_prepend_ptr; + + /* Check RTP version byte */ + CHECK_STATUS(0x80, *data); + + /* Move to check RTP data byte for payload type with marker */ + data++; + CHECK_STATUS((0x80 | RTP_PAYLOAD_TYPE), *data); + + /* Move to check RTP data bytes for sequence number */ + data++; + CHECK_STATUS((rtp_session_0.nx_rtp_session_sequence_number - 1), (data[0] << 8 | data[1])); + + /* Move to check RTP data bytes for time stamp */ + data += 2; + CHECK_STATUS(rtp_session_0.nx_rtp_session_rtp_timestamp, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for ssrc */ + data += 4; + CHECK_STATUS(rtp_session_0.nx_rtp_session_ssrc, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for data payload */ + data += 4; + for (UINT i = 0; i < sizeof(test_rtp_packet_data); i++) + { + CHECK_STATUS(*(test_rtp_packet_data + i), data[i]); + } + + /* Release the receive packet when the check finishes. */ + nx_packet_release(received_packet); + } + + /* Set the flag to notify test thread 0 that the check finishes. */ + tx_semaphore_put(&semaphore_test_1_done); +} + +/* Define the second client threads. */ +static void ntest_2_entry(ULONG thread_input) +{ +NX_PACKET *received_packet; +UINT status; +UCHAR *data; + + /* Enable IGMP & join in multicast group. */ + status = nx_igmp_enable(&ip_2); + status += nx_igmp_multicast_join(&ip_2, DEMO_MULTICAST_IP_ADDRESS); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_2, &rtp_client_2_socket, "RTCP Client 2 Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_2_socket, RTP_CLIENT_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Begin test cycles */ + for (UINT i = 0; i < TEST_CYCLES; i++) + { + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_2_socket, &received_packet, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + /* Validate RTP payload data */ + data = received_packet -> nx_packet_prepend_ptr; + + /* Check RTP version byte */ + CHECK_STATUS(0x80, *data); + + /* Move to check RTP data byte for payload type with marker */ + data++; + CHECK_STATUS((0x80 | RTP_PAYLOAD_TYPE), *data); + + /* Move to check RTP data bytes for sequence number */ + data++; + CHECK_STATUS((rtp_session_0.nx_rtp_session_sequence_number - 1), (data[0] << 8 | data[1])); + + /* Move to check RTP data bytes for time stamp */ + data += 2; + CHECK_STATUS(rtp_session_0.nx_rtp_session_rtp_timestamp, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for ssrc */ + data += 4; + CHECK_STATUS(rtp_session_0.nx_rtp_session_ssrc, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for data payload */ + data += 4; + for (UINT i = 0; i < sizeof(test_rtp_packet_data); i++) + { + CHECK_STATUS(*(test_rtp_packet_data + i), data[i]); + } + + /* Release the receive packet when the check finishes. */ + nx_packet_release(received_packet); + } + + /* Set the flag to notify test thread 0 that the check finishes. */ + tx_semaphore_put(&semaphore_test_2_done); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_multicast_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTP Multicast Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtp_session_aac_send_test.c b/test/regression/rtp_test/netx_rtp_session_aac_send_test.c new file mode 100644 index 00000000..f35422d6 --- /dev/null +++ b/test/regression/rtp_test/netx_rtp_session_aac_send_test.c @@ -0,0 +1,383 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 10 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define RTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTP_CLIENT_RTP_PORT 6002 +#define RTP_CLIENT_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE 96 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define test data. */ +#define TEST_TIMESTAMP 1234 +#define TEST_MSW 123 +#define TEST_LSW 456 + +/* Define the number of tests to do */ +#define TEST_CYCLES 4 + +static UCHAR test_rtp_packet_data[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* Test data */ +}; /* test_rtp_packet_data */ + +static UCHAR test_long_rtp_packet_data[] = { /* Test data */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, +}; /* test_long_rtp_packet_data */ + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET rtp_client_socket; + +static TX_SEMAPHORE semaphore_test_0_done; +static TX_SEMAPHORE semaphore_test_1_done; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; +static UINT rtp_port; +static UINT rtcp_port; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_session_aac_send_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTP Session AAC Send Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *)first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + CHECK_STATUS(0, status); + status = nx_udp_enable(&ip_1); + CHECK_STATUS(0, status); + + /* Create semaphores for test done notification */ + tx_semaphore_create(&semaphore_test_0_done, "semaphore test 0", 0); + tx_semaphore_create(&semaphore_test_1_done, "semaphore test 1", 0); +} + +static UINT validate_rtp_aac_data(UCHAR *data, UINT data_length) +{ +UINT i; +UCHAR *data_ptr = data; +ULONG size; + + + /* The first 2 bytes are always 0x0010 */ + if (data_ptr[0] != 0x00 || data_ptr[1] != 0x10) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr += 2; + + /* Compute data size and compare with passed data length */ + size = (ULONG)(data_ptr[0] << 5 | data_ptr[1] >> 3); + if (size != (data_length - 4)) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr += 2; + + /* Check aac data */ + i = 0; + while (data_ptr < (data + data_length)) + { + if (*data_ptr != test_rtp_packet_data[i]) + { + return(NX_NOT_SUCCESSFUL); + } + + i++; + data_ptr++; + } + + return(NX_SUCCESS); +} + +static UINT validate_long_rtp_aac_data(UCHAR *data, UINT data_length) +{ +UCHAR *data_ptr = data; +ULONG size; +static ULONG offset = 0; + + + /* The first 2 bytes are always 0x0010 */ + if (data_ptr[0] != 0x00 || data_ptr[1] != 0x10) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr += 2; + + /* Compute data size and compare with passed data length */ + size = (ULONG)(data_ptr[0] << 5 | data_ptr[1] >> 3); + if (size != (data_length - 4)) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr += 2; + + /* Check aac data */ + while (data_ptr < (data + data_length)) + { + if (*data_ptr != test_long_rtp_packet_data[offset]) + { + return(NX_NOT_SUCCESSFUL); + } + + offset++; + data_ptr++; + } + + return(NX_SUCCESS); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS client_ip_address; +NX_PACKET *send_packet; +UINT time_start; +ULONG temp_socket_id; + + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + /* Get the udp port pair for rtp and rtcp */ + status = nx_rtp_sender_port_get(&rtp_0, &rtp_port, &rtcp_port); + CHECK_STATUS(0, status); + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + CHECK_STATUS(0, status); + + /* If more than one rtp packet is sent during the first tick, rtcp packet will also be sent more than once. + To make a stable test result, wait for a tick here to avoid this situation. */ + tx_thread_sleep(1); + + /* ---- Test cycle 1 ---- */ + + /* Send aac data. */ + status = nx_rtp_sender_session_aac_send(&rtp_session_0, test_rtp_packet_data, sizeof(test_rtp_packet_data), TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(NX_SUCCESS, status); + + /* ---- Test cycle 2 ~ 4 ---- */ + + /* Send aac data. */ + status = nx_rtp_sender_session_aac_send(&rtp_session_0, test_long_rtp_packet_data, sizeof(test_long_rtp_packet_data), TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(NX_SUCCESS, status); + + /* Wait for the check in test thread 1 done. */ + status = tx_semaphore_get(&semaphore_test_1_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Delete and release resources */ + status = nx_rtp_sender_session_delete(&rtp_session_0); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_delete(&rtp_0); + CHECK_STATUS(0, status); + + /* Put the semaphore to notify thread 1 it is fine to check resource leakage. */ + tx_semaphore_put(&semaphore_test_0_done); +} + +/* Define the client threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *received_packet; +UINT j; +UINT status; +UCHAR *data; +UINT test_data_pos = 0; +ULONG offset = 0; + + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_1, &rtp_client_socket, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_socket, RTP_CLIENT_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for (UINT i = 0; i < TEST_CYCLES; i++) + { + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_socket, &received_packet, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + /* Validate RTP payload data */ + data = received_packet -> nx_packet_prepend_ptr; + + /* Check RTP version byte */ + CHECK_STATUS(0x80, *data); + + /* Move to check RTP data byte for payload type with marker */ + data++; + if (i == 1 || i == 2) + { + CHECK_STATUS((RTP_PAYLOAD_TYPE), *data); + } + else + { + CHECK_STATUS((NX_RTP_HEADER_MARKER_BIT | RTP_PAYLOAD_TYPE), *data); + } + + /* Move to check RTP data bytes for sequence number */ + data++; + CHECK_STATUS((rtp_session_0.nx_rtp_session_sequence_number - 1), (data[0] << 8 | data[1])); + + /* Move to check RTP data bytes for time stamp */ + data += 2; + CHECK_STATUS(rtp_session_0.nx_rtp_session_rtp_timestamp, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for ssrc */ + data += 4; + CHECK_STATUS(rtp_session_0.nx_rtp_session_ssrc, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for data payload */ + data += 4; + if (i == 0) + { + status = validate_rtp_aac_data(data, received_packet -> nx_packet_length - 12); + CHECK_STATUS(NX_SUCCESS, status); + } + else if (i >= 1 && i <= 3) + { + status = validate_long_rtp_aac_data(data, received_packet -> nx_packet_length - 12); + if (status) + CHECK_STATUS(NX_SUCCESS, status); + } + + /* Release the receive packet when the check finishes. */ + nx_packet_release(received_packet); + } + + /* Set the flag to notify test thread 0 that the check finishes. */ + tx_semaphore_put(&semaphore_test_1_done); + + /* Wait for the check in test thread 0 done. */ + status = tx_semaphore_get(&semaphore_test_0_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check if there is memory leak. */ + CHECK_STATUS(pool_0.nx_packet_pool_total, pool_0.nx_packet_pool_available); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_session_aac_send_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTP Session AAC Send Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtp_session_h264_send_test.c b/test/regression/rtp_test/netx_rtp_session_h264_send_test.c new file mode 100644 index 00000000..d78613f3 --- /dev/null +++ b/test/regression/rtp_test/netx_rtp_session_h264_send_test.c @@ -0,0 +1,499 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 10 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define RTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTP_CLIENT_RTP_PORT 6002 +#define RTP_CLIENT_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE 96 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define test data. */ +#define TEST_TIMESTAMP 1234 +#define TEST_MSW 123 +#define TEST_LSW 456 + +/* Define the number of tests to do */ +#define TEST_CYCLES (6 + 8) /* 6 packets, 8 slices */ + +/* Define h264 test data */ +static UCHAR test_rtp_packet_data[] = { 0x00, 0x00, 0x01, 0x65, /* h264 header started with 0x000001 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* Test data */ +}; /* test_rtp_packet_data */ + +static UCHAR test_medium_rtp_packet_data[] = { 0x00, 0x00, 0x00, 0x01, 0x65, /* h264 header started with 0x00000001 */ + + /* Test data */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, +}; /* test_rtp_packet_data */ + +static UCHAR test_long_rtp_packet_data[] = { 0x00, 0x00, 0x00, 0x01, 0x65, /* h264 header started with 0x00000001 */ + + /* Test data */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, +}; /* test_rtp_packet_data */ + +static UCHAR test_rtp_packet_slices_data[] = { 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x00, 0x00, 0x00, 0x01, 0x61, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, +}; /* test_rtp_packet_data */ + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET rtp_client_socket; + +static TX_SEMAPHORE semaphore_test_0_done; +static TX_SEMAPHORE semaphore_test_1_done; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; +static UINT rtp_port; +static UINT rtcp_port; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_session_h264_send_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTP Session H264 Send Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *)first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + CHECK_STATUS(0, status); + status = nx_udp_enable(&ip_1); + CHECK_STATUS(0, status); + + /* Create semaphores for test done notification */ + tx_semaphore_create(&semaphore_test_0_done, "semaphore test 0", 0); + tx_semaphore_create(&semaphore_test_1_done, "semaphore test 1", 0); +} + +static UINT validate_rtp_h264_data(UCHAR *data, UINT data_length) +{ +UINT i; +UCHAR *data_ptr = data; + + + /* In single NAL mode, the first byte shall be the same as the first pointful byte in the source h264 header*/ + if (data_ptr[0] != 0x65) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr++; + + /* Check h264 image data */ + i = 0; + while (data_ptr < (data + data_length)) + { + if (*data_ptr != test_rtp_packet_data[4 + i]) /* Skip 4 header bytes */ + { + return(NX_NOT_SUCCESSFUL); + } + + i++; + data_ptr++; + } + + return(NX_SUCCESS); +} + +static UINT validate_rtp_h264_fragmentation_data(UINT index, UCHAR *data, UINT data_length) +{ +UCHAR *test_data; +UCHAR *data_ptr = data; +static ULONG offset = 0; + + + /* 0x7C: high priority and FU-A mode */ + if (data_ptr[0] != 0x7C) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr++; + + switch (index) + { + case 1: + test_data = test_medium_rtp_packet_data; + /* 0x85: start bit set and IDR picture */ + if (data_ptr[0] != 0x85) + { + return(NX_NOT_SUCCESSFUL); + } + break; + + case 3: + test_data = test_long_rtp_packet_data; + /* 0x85: start bit set and IDR picture */ + if (data_ptr[0] != 0x85) + { + return(NX_NOT_SUCCESSFUL); + } + break; + + case 4: + test_data = test_long_rtp_packet_data; + /* 0x05: IDR picture */ + if (data_ptr[0] != 0x05) + { + return(NX_NOT_SUCCESSFUL); + } + break; + + case 2: + test_data = test_medium_rtp_packet_data; + /* 0x45: end bit set and IDR picture */ + if (data_ptr[0] != 0x45) + { + return(NX_NOT_SUCCESSFUL); + } + break; + case 5: + test_data = test_long_rtp_packet_data; + /* 0x45: end bit set and IDR picture */ + if (data_ptr[0] != 0x45) + { + return(NX_NOT_SUCCESSFUL); + } + break; + + default: + return(NX_NOT_SUCCESSFUL); + } + data_ptr++; + + /* Check JPEG image data */ + while (data_ptr < (data + data_length)) + { + if (*data_ptr != test_data[5 + offset]) /* Skip 5 header bytes */ + { + return(NX_NOT_SUCCESSFUL); + } + + offset++; + data_ptr++; + } + + /* Clear offset for long data test */ + if (index == 2) + { + offset = 0; + } + + return(NX_SUCCESS); +} + +static UINT validate_rtp_h264_slice_data(UCHAR *data, UINT data_length) +{ +UINT i; +UCHAR *data_ptr = data; + + + /* In single NAL mode, the first byte shall be the same as the first pointful byte in the source h264 header*/ + if (data_ptr[0] != 0x61) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr++; + + /* Check h264 image data */ + i = 0; + while (1) + { + if (*data_ptr != test_rtp_packet_data[4 + i]) /* Skip 4 header bytes */ + { + return(NX_NOT_SUCCESSFUL); + } + + if (data_ptr >= (data + data_length - 4)) /* Skip 4 byte h264 header */ + { + break; + } + + i++; + data_ptr++; + } + + return(NX_SUCCESS); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS client_ip_address; +NX_PACKET *send_packet; +UINT time_start; +ULONG temp_socket_id; + + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + /* Get the udp port pair for rtp and rtcp */ + status = nx_rtp_sender_port_get(&rtp_0, &rtp_port, &rtcp_port); + CHECK_STATUS(0, status); + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + CHECK_STATUS(0, status); + + /* If more than one rtp packet is sent during the first tick, rtcp packet will also be sent more than once. + To make a stable test result, wait for a tick here to avoid this situation. */ + tx_thread_sleep(1); + + /* ---- Test cycle 1 ---- */ + + /* Send h264 data. */ + status = nx_rtp_sender_session_h264_send(&rtp_session_0, test_rtp_packet_data, sizeof(test_rtp_packet_data), TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(NX_SUCCESS, status); + + /* ---- Test cycle 2 ~ 3 ---- */ + /* Send h264 data. */ + status = nx_rtp_sender_session_h264_send(&rtp_session_0, test_medium_rtp_packet_data, sizeof(test_medium_rtp_packet_data), TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(NX_SUCCESS, status); + + /* ---- Test cycle 4 ~ 6 ---- */ + + /* Send h264 data. */ + status = nx_rtp_sender_session_h264_send(&rtp_session_0, test_long_rtp_packet_data, sizeof(test_long_rtp_packet_data), TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(NX_SUCCESS, status); + + /* ---- Test cycle 7 ~ 14 ---- */ + + /* Send h264 data. */ + status = nx_rtp_sender_session_h264_send(&rtp_session_0, test_rtp_packet_slices_data, sizeof(test_rtp_packet_slices_data), TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(NX_SUCCESS, status); + + /* Wait for the check in test thread 1 done. */ + status = tx_semaphore_get(&semaphore_test_1_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Delete and release resources */ + status = nx_rtp_sender_session_delete(&rtp_session_0); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_delete(&rtp_0); + CHECK_STATUS(0, status); + + /* Put the semaphore to notify thread 1 it is fine to check resource leakage. */ + tx_semaphore_put(&semaphore_test_0_done); +} + +/* Define the client threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *received_packet; +UINT j; +UINT status; +UCHAR *data; +UINT test_data_pos = 0; +ULONG offset = 0; + + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_1, &rtp_client_socket, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_socket, RTP_CLIENT_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for (UINT i = 0; i < TEST_CYCLES; i++) + { + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_socket, &received_packet, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + /* Validate RTP payload data */ + data = received_packet -> nx_packet_prepend_ptr; + + /* Check RTP version byte */ + CHECK_STATUS(0x80, *data); + + /* Move to check RTP data byte for payload type with marker */ + data++; + if (i == 0 || i == 2 || i == 5 || i == 13) + { + CHECK_STATUS((NX_RTP_HEADER_MARKER_BIT | RTP_PAYLOAD_TYPE), *data); + } + else + { + CHECK_STATUS((RTP_PAYLOAD_TYPE), *data); + } + + /* Move to check RTP data bytes for sequence number */ + data++; + CHECK_STATUS((rtp_session_0.nx_rtp_session_sequence_number - 1), (data[0] << 8 | data[1])); + + /* Move to check RTP data bytes for time stamp */ + data += 2; + CHECK_STATUS(rtp_session_0.nx_rtp_session_rtp_timestamp, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for ssrc */ + data += 4; + CHECK_STATUS(rtp_session_0.nx_rtp_session_ssrc, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for data payload */ + data += 4; + if (i == 0) + { + status = validate_rtp_h264_data(data, received_packet -> nx_packet_length - 12); + CHECK_STATUS(NX_SUCCESS, status); + } + else if (i >= 1 && i <= 5) + { + status = validate_rtp_h264_fragmentation_data(i, data, received_packet -> nx_packet_length - 12); + CHECK_STATUS(NX_SUCCESS, status); + } + else + { + status = validate_rtp_h264_slice_data(data, received_packet -> nx_packet_length - 12); + if (status) + CHECK_STATUS(NX_SUCCESS, status); + } + + /* Release the receive packet when the check finishes. */ + nx_packet_release(received_packet); + } + + /* Set the flag to notify test thread 0 that the check finishes. */ + tx_semaphore_put(&semaphore_test_1_done); + + /* Wait for the check in test thread 0 done. */ + status = tx_semaphore_get(&semaphore_test_0_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check if there is memory leak. */ + CHECK_STATUS(pool_0.nx_packet_pool_total, pool_0.nx_packet_pool_available); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_session_h264_send_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTP Session H264 Send Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtp_session_jpeg_send_test.c b/test/regression/rtp_test/netx_rtp_session_jpeg_send_test.c new file mode 100644 index 00000000..5225ac01 --- /dev/null +++ b/test/regression/rtp_test/netx_rtp_session_jpeg_send_test.c @@ -0,0 +1,558 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 10 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define RTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTP_CLIENT_RTP_PORT 6002 +#define RTP_CLIENT_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE 96 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define test data. */ +#define TEST_TIMESTAMP 1234 +#define TEST_MSW 123 +#define TEST_LSW 456 + +/* Define the number of tests to do */ +#define TEST_CYCLES 4 + +/* Define jpeg test data */ +#define TEST_JPEG_Q_TABLE_SIZE 64 +#define TEST_JPEG_Q_TABLE_START_POS (2 + 2 + 0x10 + 5) +#define TEST_JPEG_IMAGE_DATA_START_POS (TEST_JPEG_Q_TABLE_START_POS + TEST_JPEG_Q_TABLE_SIZE + 2 + 0x11 + 2 + 0x0C) +static UCHAR test_rtp_packet_data[] = { 0xFF, 0xD8, /* JPEG file header */ + + /* APP0 */ + 0xFF, 0xE0, 0x00, 0x10, + 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, + + /* Quntization tables */ + 0xFF, 0xDB, 0x00, 0x43, + 0x00, + 0x07, 0x05, 0x05, 0x06, 0x05, 0x04, 0x07, 0x06, 0x06, 0x06, 0x08, 0x07, 0x07, 0x08, 0x0B, 0x12, + 0x0B, 0x0B, 0x0A, 0x0A, 0x0B, 0x16, 0x0F, 0x10, 0x0D, 0x12, 0x1A, 0x16, 0x1B, 0x1A, 0x19, 0x16, + 0x19, 0x18, 0x1C, 0x20, 0x28, 0x22, 0x1C, 0x1E, 0x26, 0x1E, 0x18, 0x19, 0x23, 0x30, 0x24, 0x26, + 0x2A, 0x2B, 0x2D, 0x2E, 0x2D, 0x1B, 0x22, 0x32, 0x35, 0x31, 0x2C, 0x35, 0x28, 0x2C, 0x2D, 0x2C, + + /* Baseline information */ + 0xFF, 0xC0, 0x00, 0x11, + 0x08, 0x00, 0x84, 0x00, 0x84, 0x03, 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, + + 0xFF, 0xDA, /* JPEG image data begin marker */ + 0x00, 0x0C, + 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00, /* Data header */ + + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* Test data */ + 0xFF, 0xD9 /* JPEG image data end marker*/ +}; /* test_rtp_packet_data */ + +#define TEST_LONG_JPEG_Q_TABLE_1_START_POS (2 + 2 + 0x10 + 5) +#define TEST_LONG_JPEG_Q_TABLE_2_START_POS (TEST_LONG_JPEG_Q_TABLE_1_START_POS + TEST_JPEG_Q_TABLE_SIZE + 5) +#define TEST_LONG_JPEG_BASELINE_INFO_START_POS (TEST_LONG_JPEG_Q_TABLE_2_START_POS + TEST_JPEG_Q_TABLE_SIZE) +#define TEST_LONG_JPEG_HUFFMAN_TABLE_START_POS (TEST_LONG_JPEG_BASELINE_INFO_START_POS + 2 + 0x11) +#define TEST_LONG_JPEG_IMAGE_DATA_START_POS (TEST_LONG_JPEG_HUFFMAN_TABLE_START_POS + 2 + 0x1C + 2 + 0x3E + 2 + 0x19 + 2 + 0x23 + 2 + 0x0C) +static UCHAR test_long_rtp_packet_data[] = { 0xFF, 0xD8, /* JPEG file header */ + + /* APP0 */ + 0xFF, 0xE0, 0x00, 0x10, + 0x4A, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, + + /* Quntization tables */ + 0xFF, 0xDB, 0x00, 0x43, + 0x00, + 0x07, 0x05, 0x05, 0x06, 0x05, 0x04, 0x07, 0x06, 0x06, 0x06, 0x08, 0x07, 0x07, 0x08, 0x0B, 0x12, + 0x0B, 0x0B, 0x0A, 0x0A, 0x0B, 0x16, 0x0F, 0x10, 0x0D, 0x12, 0x1A, 0x16, 0x1B, 0x1A, 0x19, 0x16, + 0x19, 0x18, 0x1C, 0x20, 0x28, 0x22, 0x1C, 0x1E, 0x26, 0x1E, 0x18, 0x19, 0x23, 0x30, 0x24, 0x26, + 0x2A, 0x2B, 0x2D, 0x2E, 0x2D, 0x1B, 0x22, 0x32, 0x35, 0x31, 0x2C, 0x35, 0x28, 0x2C, 0x2D, 0x2C, + 0xFF, 0xDB, 0x00, 0x43, + 0x01, + 0x07, 0x08, 0x08, 0x0B, 0x09, 0x0B, 0x15, 0x0B, 0x0B, 0x15, 0x2C, 0x1D, 0x19, 0x1D, 0x2C, 0x2C, + 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, + 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, + 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, 0x2C, + + /* Baseline information */ + 0xFF, 0xC0, 0x00, 0x11, + 0x08, 0x00, 0x84, 0x00, 0x84, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, + + /* Huffman tables */ + 0xFF, 0xC4, 0x00, 0x1C, + 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x01, 0x02, 0x08, + 0xFF, 0xC4, 0x00, 0x3E, + 0x10, 0x00, 0x02, 0x01, 0x03, 0x02, 0x03, 0x05, 0x04, 0x06, 0x08, 0x06, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x06, 0x21, 0x31, 0x13, 0x41, 0x51, 0x61, + 0x71, 0x07, 0x22, 0x32, 0x72, 0x14, 0x42, 0x81, 0x91, 0xA1, 0xC1, 0x23, 0x33, 0x43, 0x52, 0x62, + 0xB1, 0xD1, 0xE1, 0x15, 0x24, 0x34, 0x92, 0xA2, 0xF0, 0x44, 0xB2, 0xF1, + 0xFF, 0xC4, 0x00, 0x19, + 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x03, 0x01, 0x04, 0x05, + 0xFF, 0xC4, 0x00, 0x23, + 0x11, 0x00, 0x02, 0x02, 0x02, 0x01, 0x03, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x02, 0x11, 0x03, 0x31, 0x21, 0x12, 0x22, 0x41, 0x04, 0x13, 0x32, 0x51, 0x61, + 0xF0, + + 0xFF, 0xDA, /* JPEG image data begin marker */ + 0x00, 0x0C, + 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00, /* Data header */ + + /* Test data */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0xFF, 0xD9 /* JPEG image data end marker*/ +}; /* test_rtp_packet_data */ + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET rtp_client_socket; + +static TX_SEMAPHORE semaphore_test_0_done; +static TX_SEMAPHORE semaphore_test_1_done; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; +static UINT rtp_port; +static UINT rtcp_port; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern VOID _nx_ram_network_driver_256(NX_IP_DRIVER *driver_req_ptr); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_session_jpeg_send_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTP Session JPEG Send Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *)first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + CHECK_STATUS(0, status); + status = nx_udp_enable(&ip_1); + CHECK_STATUS(0, status); + + /* Create semaphores for test done notification */ + tx_semaphore_create(&semaphore_test_0_done, "semaphore test 0", 0); + tx_semaphore_create(&semaphore_test_1_done, "semaphore test 1", 0); +} + +static UINT validate_rtp_jpeg_data(UCHAR *data, UINT data_length) +{ +UINT i; +ULONG size_offset; +UCHAR *data_ptr = data; + + + /* The first byte is always 0 */ + if (data_ptr[0] != 0x00) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr++; + + /* Compute size_offset and compare with target offset */ + size_offset = (ULONG)(data_ptr[0] << 16 | data_ptr[1] << 8 | data_ptr[2]); + if (size_offset != 0) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr += 3; + + /* Check rtp/jpeg type, for YUV420 (0x21 in jpeg image), type shall be 0 */ + if (data_ptr[0] != 0x00) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr++; + + /* Check Q value */ + if (data_ptr[0] != 0xFF) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr++; + + /* Check jpeg image width and height */ + if ((data_ptr[0] != (0x84 >> 3)) || (data_ptr[1] != (0x84 >> 3))) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr += 2; + + /* Check quantization table header */ + if (data_ptr[0] != 0x00 || data_ptr[1] != 0x00 || data_ptr[2] != 0x00 || data_ptr[3] != 0x40) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr += 4; + + /* Check the quantization table */ + for (i = 0; i < TEST_JPEG_Q_TABLE_SIZE; i++) + { + if (data_ptr[i] != test_rtp_packet_data[TEST_JPEG_Q_TABLE_START_POS + i]) + { + return(NX_NOT_SUCCESSFUL); + } + } + data_ptr += TEST_JPEG_Q_TABLE_SIZE; + + /* Check JPEG image data */ + i = 0; + while (data_ptr < (data + data_length)) + { + if (*data_ptr != test_rtp_packet_data[TEST_JPEG_IMAGE_DATA_START_POS + i]) + { + return(NX_NOT_SUCCESSFUL); + } + + i++; + data_ptr++; + } + + return(NX_SUCCESS); +} + +static UINT validate_long_rtp_jpeg_data(UCHAR *data, UINT data_length) +{ +UINT i; +ULONG size_offset; +UCHAR *data_ptr = data; +static ULONG offset = 0; + + /* The first byte is always 0 */ + if (data_ptr[0] != 0x00) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr++; + + /* Compute size_offset and compare with target offset */ + size_offset = (ULONG)(data_ptr[0] << 16 | data_ptr[1] << 8 | data_ptr[2]); + if (size_offset != offset) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr += 3; + + /* Check rtp/jpeg type, for YUV422 (0x22 in jpeg image), type shall be 1 */ + if (data_ptr[0] != 0x01) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr++; + + /* Check Q value */ + if (data_ptr[0] != 0xFF) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr++; + + /* Check jpeg image width and height */ + if ((data_ptr[0] != (0x84 >> 3)) || (data_ptr[1] != (0x84 >> 3))) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr += 2; + + /* Only first fragmented packet contains quantization tables */ + if (offset == 0) + { + + /* Check quantization table header */ + if (data_ptr[0] != 0x00 || data_ptr[1] != 0x00 || data_ptr[2] != 0x00 || data_ptr[3] != 0x80) + { + return(NX_NOT_SUCCESSFUL); + } + data_ptr += 4; + + /* Check both 2 quantization tables */ + for (i = 0; i < TEST_JPEG_Q_TABLE_SIZE; i++) + { + if (data_ptr[i] != test_long_rtp_packet_data[TEST_LONG_JPEG_Q_TABLE_1_START_POS + i]) + { + return(NX_NOT_SUCCESSFUL); + } + + if (data_ptr[TEST_JPEG_Q_TABLE_SIZE + i] != test_long_rtp_packet_data[TEST_LONG_JPEG_Q_TABLE_2_START_POS + i]) + { + return(NX_NOT_SUCCESSFUL); + } + } + data_ptr += TEST_JPEG_Q_TABLE_SIZE * 2; + } + + /* Check JPEG image data */ + while (data_ptr < (data + data_length)) + { + if (*data_ptr != test_long_rtp_packet_data[TEST_LONG_JPEG_IMAGE_DATA_START_POS + offset]) + { + return(NX_NOT_SUCCESSFUL); + } + + offset++; + data_ptr++; + } + + return(NX_SUCCESS); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS client_ip_address; +NX_PACKET *send_packet; +UINT time_start; +ULONG temp_socket_id; + + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + /* Get the udp port pair for rtp and rtcp */ + status = nx_rtp_sender_port_get(&rtp_0, &rtp_port, &rtcp_port); + CHECK_STATUS(0, status); + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + CHECK_STATUS(0, status); + + /* If more than one rtp packet is sent during the first tick, rtcp packet will also be sent more than once. + To make a stable test result, wait for a tick here to avoid this situation. */ + tx_thread_sleep(1); + + /* ---- Test cycle 1 ---- */ + + /* Send jpeg data. */ + status = nx_rtp_sender_session_jpeg_send(&rtp_session_0, test_rtp_packet_data, sizeof(test_rtp_packet_data), TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(NX_SUCCESS, status); + + /* ---- Test cycle 2 ~ 4 ---- */ + + /* Send jpeg data. */ + status = nx_rtp_sender_session_jpeg_send(&rtp_session_0, test_long_rtp_packet_data, sizeof(test_long_rtp_packet_data), TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(NX_SUCCESS, status); + + /* Wait for the check in test thread 1 done. */ + status = tx_semaphore_get(&semaphore_test_1_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Delete and release resources */ + status = nx_rtp_sender_session_delete(&rtp_session_0); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_delete(&rtp_0); + CHECK_STATUS(0, status); + + /* Put the semaphore to notify thread 1 it is fine to check resource leakage. */ + tx_semaphore_put(&semaphore_test_0_done); +} + +/* Define the client threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *received_packet; +UINT j; +UINT status; +UCHAR *data; +UINT test_data_pos = 0; +ULONG offset = 0; + + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_1, &rtp_client_socket, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_socket, RTP_CLIENT_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for (UINT i = 0; i < TEST_CYCLES; i++) + { + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_socket, &received_packet, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + /* Validate RTP payload data */ + data = received_packet -> nx_packet_prepend_ptr; + + /* Check RTP version byte */ + CHECK_STATUS(0x80, *data); + + /* Move to check RTP data byte for payload type with marker */ + data++; + if (i == 1 || i == 2) + { + CHECK_STATUS((RTP_PAYLOAD_TYPE), *data); + } + else + { + CHECK_STATUS((NX_RTP_HEADER_MARKER_BIT | RTP_PAYLOAD_TYPE), *data); + } + + /* Move to check RTP data bytes for sequence number */ + data++; + CHECK_STATUS((rtp_session_0.nx_rtp_session_sequence_number - 1), (data[0] << 8 | data[1])); + + /* Move to check RTP data bytes for time stamp */ + data += 2; + CHECK_STATUS(rtp_session_0.nx_rtp_session_rtp_timestamp, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for ssrc */ + data += 4; + CHECK_STATUS(rtp_session_0.nx_rtp_session_ssrc, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for data payload */ + data += 4; + if (i == 0) + { + status = validate_rtp_jpeg_data(data, received_packet -> nx_packet_length - 12); + CHECK_STATUS(NX_SUCCESS, status); + } + else if (i >= 1 && i <= 3) + { + status = validate_long_rtp_jpeg_data(data, received_packet -> nx_packet_length - 12); + if (status) + CHECK_STATUS(NX_SUCCESS, status); + } + + /* Release the receive packet when the check finishes. */ + nx_packet_release(received_packet); + } + + /* Set the flag to notify test thread 0 that the check finishes. */ + tx_semaphore_put(&semaphore_test_1_done); + + /* Wait for the check in test thread 0 done. */ + status = tx_semaphore_get(&semaphore_test_0_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check if there is memory leak. */ + CHECK_STATUS(pool_0.nx_packet_pool_total, pool_0.nx_packet_pool_available); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_session_jpeg_send_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTP Session JPEG Send Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtp_test/netx_rtp_session_packet_send_test.c b/test/regression/rtp_test/netx_rtp_session_packet_send_test.c new file mode 100644 index 00000000..a23b1057 --- /dev/null +++ b/test/regression/rtp_test/netx_rtp_session_packet_send_test.c @@ -0,0 +1,355 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" + +#define DEMO_STACK_SIZE 4096 + +#define NUM_PACKETS 10 +#define PACKET_SIZE 1536 +#define PACKET_POOL_SIZE (NUM_PACKETS * (PACKET_SIZE + sizeof(NX_PACKET))) + +#define RTP_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define RTP_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTP_CLIENT_RTP_PORT 6002 +#define RTP_CLIENT_RTCP_PORT 6003 +#define RTP_PAYLOAD_TYPE 96 +#define CNAME "AzureRTOS@microsoft.com" + +/* Define test data. */ +#define TEST_TIMESTAMP 1234 +#define TEST_MSW 123 +#define TEST_LSW 456 + +#define TEST_SAMPLE_FACTOR 2 + +/* Define the number of tests to do */ +#define TEST_CYCLES 7 + +static UCHAR test_rtp_packet_data[] = "test rtp packet data"; +static UCHAR test_long_rtp_packet_data[200]; + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD ntest_0; +static TX_THREAD ntest_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_IP ip_1; +static NX_UDP_SOCKET rtp_client_socket; + +static TX_SEMAPHORE semaphore_test_0_done; +static TX_SEMAPHORE semaphore_test_1_done; + +/* Define rtp sender control block. */ +static NX_RTP_SENDER rtp_0; +static NX_RTP_SESSION rtp_session_0; +static UINT rtp_port; +static UINT rtcp_port; + + +/* Define thread prototypes. */ + +static void ntest_0_entry(ULONG thread_input); +static void ntest_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); +extern void test_control_return(UINT status); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_session_packet_send_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTP Session Packet Send Test............................................"); + + /* Setup the working pointer. */ + pointer = (CHAR *)first_unused_memory; + + /* Create the server thread. */ + tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the client thread. */ + tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", PACKET_SIZE, pointer, PACKET_POOL_SIZE); + pointer = pointer + PACKET_POOL_SIZE; + CHECK_STATUS(0, status); + + /* Create server IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", RTP_SERVER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Create client IP instance. */ + status = nx_ip_create(&ip_1, "NetX IP Instance 1", RTP_CLIENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status = nx_arp_enable(&ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&ip_0); + CHECK_STATUS(0, status); + status = nx_udp_enable(&ip_1); + CHECK_STATUS(0, status); + + /* Create semaphores for test done notification */ + tx_semaphore_create(&semaphore_test_0_done, "semaphore test 0", 0); + tx_semaphore_create(&semaphore_test_1_done, "semaphore test 1", 0); +} + +/* Define server threads. */ +static void ntest_0_entry(ULONG thread_input) +{ +UINT status; +NXD_ADDRESS client_ip_address; +NX_PACKET *send_packet; +UINT time_start; +ULONG temp_socket_id; + + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_0, &ip_0, &pool_0, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + /* Get the udp port pair for rtp and rtcp */ + status = nx_rtp_sender_port_get(&rtp_0, &rtp_port, &rtcp_port); + CHECK_STATUS(0, status); + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = RTP_CLIENT_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_0, &rtp_session_0, RTP_PAYLOAD_TYPE, + 0, &client_ip_address, + RTP_CLIENT_RTP_PORT, RTP_CLIENT_RTCP_PORT); + CHECK_STATUS(0, status); + + /* If more than one rtp packet is sent during the first tick, rtcp packet will also be sent more than once. + To make a stable test result, wait for a tick here to avoid this situation. */ + tx_thread_sleep(1); + + /* ---- Test cycle 1 ---- */ + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &send_packet, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(send_packet, (void*)test_rtp_packet_data, sizeof(test_rtp_packet_data), rtp_0.nx_rtp_sender_ip_ptr->nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + +#ifndef TX_DISABLE_ERROR_CHECKING + /* Reserver the rtp socket id, set the rtp socket id to 0 to force the send fail */ + temp_socket_id = rtp_session_0.nx_rtp_sender -> nx_rtp_sender_rtp_socket.nx_udp_socket_id; + rtp_session_0.nx_rtp_sender -> nx_rtp_sender_rtp_socket.nx_udp_socket_id = 0; + status = nx_rtp_sender_session_packet_send(&rtp_session_0, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Recover the socket id */ + rtp_session_0.nx_rtp_sender -> nx_rtp_sender_rtp_socket.nx_udp_socket_id = temp_socket_id; + + /* Check if the function can return error status when prepend pointer is incorrect */ + send_packet -> nx_packet_prepend_ptr--; + status = nx_rtp_sender_session_packet_send(&rtp_session_0, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(NX_UNDERFLOW, status); + + /* Set back prepend pointer to correct position and check the send function could execute correctly */ + send_packet -> nx_packet_prepend_ptr++; +#endif /* TX_DISABLE_ERROR_CHECKING */ + + status = nx_rtp_sender_session_packet_send(&rtp_session_0, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + /* ---- Test cycle 2 ~ 4 ---- */ + send_packet = NX_NULL; + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &send_packet, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet many times to have 3 fragmentation packets. */ + for (UINT i = 0; i < sizeof(test_long_rtp_packet_data); i++) + { + test_long_rtp_packet_data[i] = i % 100; + } + status = nx_packet_data_append(send_packet, (void*)test_long_rtp_packet_data, sizeof(test_long_rtp_packet_data), rtp_0.nx_rtp_sender_ip_ptr->nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + status = nx_rtp_sender_session_packet_send(&rtp_session_0, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + /* ---- Test cycle 5 ~ 7 ---- */ + send_packet = NX_NULL; + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &send_packet, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + status = nx_packet_data_append(send_packet, (void*)test_long_rtp_packet_data, sizeof(test_long_rtp_packet_data), rtp_0.nx_rtp_sender_ip_ptr->nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Set the sample factor to trigger sample-based mode, and then send fragmentation packets in order to observer timestamp automatical change */ + status = nx_rtp_sender_session_sample_factor_set(&rtp_session_0, TEST_SAMPLE_FACTOR); + status = nx_rtp_sender_session_packet_send(&rtp_session_0, send_packet, TEST_TIMESTAMP, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + /* Wait for the check in test thread 1 done. */ + status = tx_semaphore_get(&semaphore_test_1_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Delete and release resources */ + status = nx_rtp_sender_session_delete(&rtp_session_0); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_delete(&rtp_0); + CHECK_STATUS(0, status); + + /* Put the semaphore to notify thread 1 it is fine to check resource leakage. */ + tx_semaphore_put(&semaphore_test_0_done); +} + +/* Define the client threads. */ +static void ntest_1_entry(ULONG thread_input) +{ +NX_PACKET *received_packet; +UINT status; +UCHAR *data; +UINT test_data_pos = 0; + + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&ip_1, &rtp_client_socket, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_socket, RTP_CLIENT_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for (UINT i = 0; i < TEST_CYCLES; i++) + { + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_socket, &received_packet, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + /* Validate RTP payload data */ + data = received_packet -> nx_packet_prepend_ptr; + + /* Check RTP version byte */ + CHECK_STATUS(0x80, *data); + + /* Move to check RTP data byte for payload type with marker */ + data++; + if (i == 1 || i == 2) + { + CHECK_STATUS((RTP_PAYLOAD_TYPE), *data); + } + else + { + CHECK_STATUS((NX_RTP_HEADER_MARKER_BIT | RTP_PAYLOAD_TYPE), *data); + } + + /* Move to check RTP data bytes for sequence number */ + data++; + CHECK_STATUS((rtp_session_0.nx_rtp_session_sequence_number - 1), (data[0] << 8 | data[1])); + + /* Move to check RTP data bytes for time stamp */ + data += 2; + CHECK_STATUS(rtp_session_0.nx_rtp_session_rtp_timestamp, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for ssrc */ + data += 4; + CHECK_STATUS(rtp_session_0.nx_rtp_session_ssrc, (ULONG)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3])); + + /* Move to check RTP data bytes for data payload */ + data += 4; + if (i == 0) + { + for (UINT j = 0; j < sizeof(test_rtp_packet_data); j++) + { + CHECK_STATUS(*(test_rtp_packet_data + j), data[j]); + } + } + else if (i >= 1 && i <= 6) + { + + /* Check fragmentation packets in frame-based mode */ + while (data < received_packet -> nx_packet_append_ptr) + { + CHECK_STATUS(test_long_rtp_packet_data[test_data_pos], *data); + test_data_pos++; + data++; + } + + /* Check and reset test data position for following test to use */ + if (i == 3 || i == 6) + { + test_data_pos = 0; + } + } + + /* Release the receive packet when the check finishes. */ + nx_packet_release(received_packet); + } + + /* Set the flag to notify test thread 0 that the check finishes. */ + tx_semaphore_put(&semaphore_test_1_done); + + /* Wait for the check in test thread 0 done. */ + status = tx_semaphore_get(&semaphore_test_0_done, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check if there is memory leak. */ + CHECK_STATUS(pool_0.nx_packet_pool_total, pool_0.nx_packet_pool_available); + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtp_session_packet_send_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTP Session Packet Send Test............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtsp_test/netx_rtsp_api_test.c b/test/regression/rtsp_test/netx_rtsp_api_test.c new file mode 100644 index 00000000..24069021 --- /dev/null +++ b/test/regression/rtsp_test/netx_rtsp_api_test.c @@ -0,0 +1,312 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_ERROR_CHECKING) && defined(__PRODUCT_NETXDUO__) +#include "nx_rtsp_server.h" + +#define DEMO_STACK_SIZE 4096 + +#define TEST_RTSP_STACK_SIZE 2048 +#define TEST_RTSP_SERVER_PORT 554 +#define TEST_RTSP_SERVER_PRIORITY 3 + +/* Define the ThreadX object control blocks... */ + +static TX_THREAD test_thread; + +/* Define the ThreadX object control blocks... */ + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define rtsp server control block. */ +static NX_RTSP_SERVER rtsp_0; + +static UCHAR rtsp_stack[TEST_RTSP_STACK_SIZE]; + +/* Define thread prototypes. */ + +static void test_entry(ULONG thread_input); + +static UINT describe_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + return 0; +} + +static UINT setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr) +{ + return 0; +} + +static UINT play_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ + return 0; +} + +static UINT set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length) +{ + return 0; +} + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_api_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&test_thread, "Test thread", test_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); +} + +void test_entry(ULONG thread_input) +{ +UINT status; +UCHAR test_sdp[] = "test_sdp"; +UCHAR test_track_id[] = "test_track_id"; +NX_RTSP_CLIENT *client_ptr; +NX_RTSP_CLIENT_REQUEST test_request; +NX_PACKET test_packet; + + + /* Print out test information banner. */ + printf("NetX Test: RTSP API Test............................................."); + + memset(&rtsp_0, 0, sizeof(NX_RTSP_SERVER)); + + /* Test nx_rtsp_server_create. */ + status = nx_rtsp_server_create(NX_NULL, "RTSP Server", sizeof("RTSP Server") - 1, &ip_0, &pool_0, rtsp_stack, + TEST_RTSP_STACK_SIZE, TEST_RTSP_SERVER_PRIORITY, TEST_RTSP_SERVER_PORT, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_create(&rtsp_0, "RTSP Server", sizeof("RTSP Server") - 1, NX_NULL, &pool_0, rtsp_stack, + TEST_RTSP_STACK_SIZE, TEST_RTSP_SERVER_PRIORITY, TEST_RTSP_SERVER_PORT, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_create(&rtsp_0, "RTSP Server", sizeof("RTSP Server") - 1, &ip_0, NX_NULL, rtsp_stack, + TEST_RTSP_STACK_SIZE, TEST_RTSP_SERVER_PRIORITY, TEST_RTSP_SERVER_PORT, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_create(&rtsp_0, "RTSP Server", sizeof("RTSP Server") - 1, &ip_0, &pool_0, NX_NULL, + TEST_RTSP_STACK_SIZE, TEST_RTSP_SERVER_PRIORITY, TEST_RTSP_SERVER_PORT, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + status = nx_rtsp_server_create(&rtsp_0, "RTSP Server", sizeof("RTSP Server") - 1, &ip_0, &pool_0, rtsp_stack, + TEST_RTSP_STACK_SIZE, TEST_RTSP_SERVER_PRIORITY, TEST_RTSP_SERVER_PORT, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = 0; + + /* Test nx_rtsp_server_delete. */ + status = nx_rtsp_server_delete(NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_delete(&rtsp_0); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Test nx_rtsp_server_start. */ + status = nx_rtsp_server_start(NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_start(&rtsp_0); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Test nx_rtsp_server_stop. */ + status = nx_rtsp_server_stop(NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_stop(&rtsp_0); + CHECK_STATUS(NX_PTR_ERROR, status); + + /* Initialize the client structure. */ + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + client_ptr = &(rtsp_0.nx_rtsp_server_client_list[0]); + client_ptr -> nx_rtsp_client_server_ptr = &rtsp_0; + client_ptr -> nx_rtsp_client_request_ptr = &test_request; + client_ptr -> nx_rtsp_client_response_packet = &test_packet; + + /* Test nx_rtsp_server_sdp_set. */ + test_request.nx_rtsp_client_request_method = NX_RTSP_METHOD_SETUP; + status = nx_rtsp_server_sdp_set(NX_NULL, test_sdp, sizeof(test_sdp) - 1); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_sdp_set(client_ptr, NX_NULL, sizeof(test_sdp) - 1); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_sdp_set(client_ptr, test_sdp, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + client_ptr -> nx_rtsp_client_server_ptr = NX_NULL; + status = nx_rtsp_server_sdp_set(client_ptr, test_sdp, sizeof(test_sdp) - 1); + CHECK_STATUS(NX_PTR_ERROR, status); + client_ptr -> nx_rtsp_client_server_ptr = &rtsp_0; + rtsp_0.nx_rtsp_server_id = 0; + status = nx_rtsp_server_sdp_set(client_ptr, test_sdp, sizeof(test_sdp) - 1); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + client_ptr -> nx_rtsp_client_response_packet = NX_NULL; + status = nx_rtsp_server_sdp_set(client_ptr, test_sdp, sizeof(test_sdp) - 1); + CHECK_STATUS(NX_RTSP_SERVER_NO_PACKET, status); + client_ptr -> nx_rtsp_client_response_packet = &test_packet; + test_request.nx_rtsp_client_request_method = NX_RTSP_METHOD_PLAY; + status = nx_rtsp_server_sdp_set(client_ptr, test_sdp, sizeof(test_sdp) - 1); + CHECK_STATUS(NX_RTSP_SERVER_INVALID_REQUEST, status); + + /* Test nx_rtsp_server_rtp_info_set. */ + status = nx_rtsp_server_rtp_info_set(NX_NULL, test_track_id, sizeof(test_track_id) - 1, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_rtp_info_set(client_ptr, NX_NULL, sizeof(test_track_id) - 1, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_rtp_info_set(client_ptr, test_track_id, 0, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + client_ptr -> nx_rtsp_client_server_ptr = NX_NULL; + status = nx_rtsp_server_rtp_info_set(client_ptr, test_track_id, sizeof(test_track_id) - 1, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + client_ptr -> nx_rtsp_client_server_ptr = &rtsp_0; + rtsp_0.nx_rtsp_server_id = 0; + status = nx_rtsp_server_rtp_info_set(client_ptr, test_track_id, sizeof(test_track_id) - 1, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + client_ptr -> nx_rtsp_client_response_packet = NX_NULL; + status = nx_rtsp_server_rtp_info_set(client_ptr, test_track_id, sizeof(test_track_id) - 1, 0, 0); + CHECK_STATUS(NX_RTSP_SERVER_NO_PACKET, status); + client_ptr -> nx_rtsp_client_response_packet = &test_packet; + test_request.nx_rtsp_client_request_method = NX_RTSP_METHOD_PAUSE; + status = nx_rtsp_server_rtp_info_set(client_ptr, test_track_id, sizeof(test_track_id) - 1, 0, 0); + CHECK_STATUS(NX_RTSP_SERVER_INVALID_REQUEST, status); + + /* Test nx_rtsp_server_range_npt_set. */ + status = nx_rtsp_server_range_npt_set(NX_NULL, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + client_ptr -> nx_rtsp_client_server_ptr = NX_NULL; + status = nx_rtsp_server_range_npt_set(client_ptr, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + client_ptr -> nx_rtsp_client_server_ptr = &rtsp_0; + rtsp_0.nx_rtsp_server_id = 0; + status = nx_rtsp_server_range_npt_set(client_ptr, 0, 0); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + test_request.nx_rtsp_client_request_method = NX_RTSP_METHOD_DESCRIBE; + status = nx_rtsp_server_range_npt_set(client_ptr, 0, 0); + CHECK_STATUS(NX_RTSP_SERVER_INVALID_REQUEST, status); + test_request.nx_rtsp_client_request_method = NX_RTSP_METHOD_PLAY; + status = nx_rtsp_server_range_npt_set(client_ptr, 1, 0); + CHECK_STATUS(NX_RTSP_SERVER_INVALID_PARAMETER, status); + + /* Test nx_rtsp_server_error_response_send. */ + status = nx_rtsp_server_error_response_send(NX_NULL, 200); + CHECK_STATUS(NX_PTR_ERROR, status); + client_ptr -> nx_rtsp_client_server_ptr = NX_NULL; + status = nx_rtsp_server_error_response_send(client_ptr, 200); + CHECK_STATUS(NX_PTR_ERROR, status); + client_ptr -> nx_rtsp_client_server_ptr = &rtsp_0; + rtsp_0.nx_rtsp_server_id = 0; + status = nx_rtsp_server_error_response_send(client_ptr, 200); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + client_ptr -> nx_rtsp_client_response_packet = NX_NULL; + status = nx_rtsp_server_error_response_send(client_ptr, 200); + CHECK_STATUS(NX_RTSP_SERVER_NO_PACKET, status); + client_ptr -> nx_rtsp_client_response_packet = &test_packet; + status = nx_rtsp_server_error_response_send(client_ptr, 0); + CHECK_STATUS(NX_RTSP_SERVER_INVALID_PARAMETER, status); + + /* Test nx_rtsp_server_keepalive_update. */ + status = nx_rtsp_server_keepalive_update(NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + client_ptr -> nx_rtsp_client_server_ptr = NX_NULL; + status = nx_rtsp_server_keepalive_update(client_ptr); + CHECK_STATUS(NX_PTR_ERROR, status); + client_ptr -> nx_rtsp_client_server_ptr = &rtsp_0; + rtsp_0.nx_rtsp_server_id = 0; + status = nx_rtsp_server_keepalive_update(client_ptr); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + + /* Test nx_rtsp_server_describe_callback_set. */ + status = nx_rtsp_server_describe_callback_set(NX_NULL, describe_teardown_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_describe_callback_set(&rtsp_0, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = 0; + status = nx_rtsp_server_describe_callback_set(&rtsp_0, describe_teardown_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + + /* Test nx_rtsp_server_teardown_callback_set. */ + status = nx_rtsp_server_teardown_callback_set(NX_NULL, describe_teardown_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_teardown_callback_set(&rtsp_0, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = 0; + status = nx_rtsp_server_teardown_callback_set(&rtsp_0, describe_teardown_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + + /* Test nx_rtsp_server_setup_callback_set. */ + status = nx_rtsp_server_setup_callback_set(NX_NULL, setup_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_setup_callback_set(&rtsp_0, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = 0; + status = nx_rtsp_server_setup_callback_set(&rtsp_0, setup_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + + /* Test nx_rtsp_server_play_callback_set. */ + status = nx_rtsp_server_play_callback_set(NX_NULL, play_pause_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_play_callback_set(&rtsp_0, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = 0; + status = nx_rtsp_server_play_callback_set(&rtsp_0, play_pause_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + + /* Test nx_rtsp_server_pause_callback_set. */ + status = nx_rtsp_server_pause_callback_set(NX_NULL, play_pause_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_pause_callback_set(&rtsp_0, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = 0; + status = nx_rtsp_server_pause_callback_set(&rtsp_0, play_pause_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + + /* Test nx_rtsp_server_set_parameter_callback_set. */ + status = nx_rtsp_server_set_parameter_callback_set(NX_NULL, set_parameter_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + status = nx_rtsp_server_set_parameter_callback_set(&rtsp_0, NX_NULL); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = 0; + status = nx_rtsp_server_set_parameter_callback_set(&rtsp_0, set_parameter_callback); + CHECK_STATUS(NX_PTR_ERROR, status); + rtsp_0.nx_rtsp_server_id = NX_RTSP_SERVER_ID; + + /* Return the test result. */ + printf("SUCCESS!\n"); + test_control_return(0); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_api_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTSP API Test.............................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtsp_test/netx_rtsp_client_timeout_test.c b/test/regression/rtsp_test/netx_rtsp_client_timeout_test.c new file mode 100644 index 00000000..d164d577 --- /dev/null +++ b/test/regression/rtsp_test/netx_rtsp_client_timeout_test.c @@ -0,0 +1,952 @@ +/* This case tests: + 1. Client 0 and client 1 connect to RTSP server; + 2. CLient 2 tries to connect to RTSP server but fails because the NX_RTSP_SERVER_MAX_CLIENTS is 2; + 3. Client 0 is timeout after NX_RTSP_SERVER_ACTIVITY_TIMEOUT; + 4. Client 1 keeps alive by calling the nx_rtsp_server_keepalive_update(); + 5. Client 2 connects to RTSP server successfully because client 0 is disconnected after timeout. */ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nx_rtsp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && (NX_RTSP_SERVER_MAX_CLIENTS == 2) + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UCHAR rtsp_stack[DEMO_STACK_SIZE]; +static UCHAR thread_2_stack[DEMO_STACK_SIZE]; + +static TX_THREAD client_thread_0; +static NX_PACKET_POOL client_pool_0; +static NX_IP client_ip_0; +static NX_TCP_SOCKET rtsp_client_0; + +static TX_THREAD client_thread_1; +static NX_PACKET_POOL client_pool_1; +static NX_IP client_ip_1; +static NX_TCP_SOCKET rtsp_client_1; + +static TX_THREAD client_thread_2; +static NX_TCP_SOCKET rtsp_client_2; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_RTSP_SERVER rtsp_server; + +static UINT error_counter; + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_0_done; +static TX_SEMAPHORE semaphore_client_1_done; +static TX_SEMAPHORE semaphore_client_2_done; +static TX_SEMAPHORE semaphore_client_connected; +static TX_SEMAPHORE semaphore_client_disconnected; + +static void thread_client_0_entry(ULONG thread_input); +static void thread_client_1_entry(ULONG thread_input); +static void thread_client_2_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr); +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length); +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_0_ADDRESS IP_ADDRESS(1,2,3,5) +#define TEST_CLIENT_1_ADDRESS IP_ADDRESS(1,2,3,6) +#define RTSP_SERVER_PORT 554 + +#define RTSP_SESSION_ID_0 23754311 +#define RTSP_SESSION_ID_1 23754312 +#define RTSP_SESSION_ID_2 23754313 + +#define RTP_SERVER_RTP_PORT 6002 +#define RTP_SERVER_RTCP_PORT 6003 +#define RTP_0_RTP_PORT 49752 +#define RTP_0_RTCP_PORT 49753 +#define RTP_1_RTP_PORT 49754 +#define RTP_1_RTCP_PORT 49755 +#define RTP_2_RTP_PORT 49756 +#define RTP_2_RTCP_PORT 49757 + +#define RTP_0_SSRC 1111 +#define RTP_1_SSRC 2222 +#define RTP_2_SSRC 3333 +#define RTP_0_VIDEO_SEQ 1234 +#define RTP_1_VIDEO_SEQ 1235 +#define RTP_2_VIDEO_SEQ 1236 +#define RTP_TIMESTAMP_INIT_VALUE 40 + +static UCHAR rtsp_option_request_0[] = "\ +OPTIONS rtsp://1.2.3.4:554/stream0 RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_option_request_1[] = "\ +OPTIONS rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_option_request_2[] = "\ +OPTIONS rtsp://1.2.3.4:554/stream2 RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_describe_request_0[] = "\ +DESCRIBE rtsp://1.2.3.4:554/stream0 RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_describe_request_1[] = "\ +DESCRIBE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_describe_request_2[] = "\ +DESCRIBE rtsp://1.2.3.4:554/stream2 RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_0[] = "\ +SETUP rtsp://1.2.3.4:554/stream0/trackID=0 RTSP/1.0\r\n\ +CSeq: 4\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49752-49753\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_1[] = "\ +SETUP rtsp://1.2.3.4:554/stream1/trackID=0 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49754-49755\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_2[] = "\ +SETUP rtsp://1.2.3.4:554/stream2/trackID=0 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49756-49757\r\n\r\n\ +"; + +static UCHAR rtsp_play_request_0[] = "\ +PLAY rtsp://1.2.3.4:554/stream0 RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +static UCHAR rtsp_play_request_1[] = "\ +PLAY rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754312\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +static UCHAR rtsp_play_request_2[] = "\ +PLAY rtsp://1.2.3.4:554/stream2 RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754313\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +typedef enum +{ + OPTION_INDEX, + DESCRIBE_INDEX, + SETUP_INDEX, + PLAY_INDEX, + TEARDOWN_INDEX +}REQUEST_INDEX; + +static UCHAR *rtsp_request_list_0[] = +{ +rtsp_option_request_0, +rtsp_describe_request_0, +rtsp_setup_request_0, +rtsp_play_request_0, +}; + +static UCHAR *rtsp_request_list_1[] = +{ +rtsp_option_request_1, +rtsp_describe_request_1, +rtsp_setup_request_1, +rtsp_play_request_1, +}; + +static UCHAR *rtsp_request_list_2[] = +{ +rtsp_option_request_2, +rtsp_describe_request_2, +rtsp_setup_request_2, +rtsp_play_request_2, +}; + +static UINT rtsp_request_size_0[] = +{ +sizeof(rtsp_option_request_0) - 1, +sizeof(rtsp_describe_request_0) - 1, +sizeof(rtsp_setup_request_0) - 1, +sizeof(rtsp_play_request_0) - 1, +}; + +static UINT rtsp_request_size_1[] = +{ +sizeof(rtsp_option_request_1) - 1, +sizeof(rtsp_describe_request_1) - 1, +sizeof(rtsp_setup_request_1) - 1, +sizeof(rtsp_play_request_1) - 1, +}; + +static UINT rtsp_request_size_2[] = +{ +sizeof(rtsp_option_request_2) - 1, +sizeof(rtsp_describe_request_2) - 1, +sizeof(rtsp_setup_request_2) - 1, +sizeof(rtsp_play_request_2) - 1, +}; + +static UINT rtsp_request_num = sizeof(rtsp_request_size_0) / sizeof(UINT); + +static NX_RTSP_CLIENT *rtsp_client_ptr_0 = NX_NULL, *rtsp_client_ptr_1 = NX_NULL, *rtsp_client_ptr_2 = NX_NULL; + +static UINT disconnect_count = 0; + +static CHAR *sdp="v=0\r\ns=MPEG-1 or 2 Audio, streamed by the NetX RTSP Server\r\n\ +m=video 0 RTP/AVP 96\r\n\ +a=rtpmap:96 H264/90000\r\n\ +a=fmtp:96 profile-level-id=42A01E; packetization-mode=1\r\n\ +a=control:trackID=0\r\n\ +"; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_client_timeout_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread_0, "Test Client 0", thread_client_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool_0, "Test Client Packet Pool 0", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip_0, "Test Client IP 0", TEST_CLIENT_0_ADDRESS, + 0xFFFFFF00UL, &client_pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip_0); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread_1, "Test Client 1", thread_client_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool_1, "Test Client Packet Pool 1", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip_1, "Test Client IP 1", TEST_CLIENT_1_ADDRESS, + 0xFFFFFF00UL, &client_pool_1, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip_1); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread_2, "Test Client 2", thread_client_2_entry, 0, + thread_2_stack, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + CHECK_STATUS(0, status); + + /* Create semaphores. */ + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_0_done, "semaphore client 0 done", 0); + tx_semaphore_create(&semaphore_client_1_done, "semaphore client 1 done", 0); + tx_semaphore_create(&semaphore_client_2_done, "semaphore client 2 done", 0); + tx_semaphore_create(&semaphore_client_connected, "semaphore client connected", 0); + tx_semaphore_create(&semaphore_client_disconnected, "semaphore client disconnected", 0); +} + +void thread_client_0_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_ip_0, &rtsp_client_0, "Test Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client_0, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_0, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_client_connected); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool_0, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list_0[i], rtsp_request_size_0[i], &client_pool_0, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client_0, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=1.2.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%d", + RTP_0_RTP_PORT, RTP_0_RTCP_PORT, RTP_SERVER_RTP_PORT, RTP_SERVER_RTCP_PORT, RTP_0_SSRC); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://1.2.3.4:554/stream0/trackID=0;seq=%d;rtptime=%d", + RTP_0_VIDEO_SEQ, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + tx_thread_sleep((NX_RTSP_SERVER_ACTIVITY_TIMEOUT + 5) * NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_0_done); +} + +void thread_client_1_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_ip_1, &rtsp_client_1, "Test Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client_1, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_1, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_client_connected); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool_1, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list_1[i], rtsp_request_size_1[i], &client_pool_1, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client_1, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client_1, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=1.2.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%d", + RTP_1_RTP_PORT, RTP_1_RTCP_PORT, RTP_SERVER_RTP_PORT, RTP_SERVER_RTCP_PORT, RTP_1_SSRC); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://1.2.3.4:554/stream1/trackID=0;seq=%d;rtptime=%d", + RTP_1_VIDEO_SEQ, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + while (i < (NX_RTSP_SERVER_ACTIVITY_TIMEOUT + 5)) + { + nx_rtsp_server_keepalive_update(rtsp_client_ptr_1); + tx_thread_sleep(NX_IP_PERIODIC_RATE); + i++; + } + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_1_done); +} + +void thread_client_2_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_ip_0, &rtsp_client_2, "Test Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client_2, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait until other clients are connected. */ + tx_semaphore_get(&semaphore_client_connected, NX_WAIT_FOREVER); + tx_semaphore_get(&semaphore_client_connected, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_2, &server_ip_address, RTSP_SERVER_PORT, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(NX_NOT_CONNECTED, status); + + /* Wait until one client is disconnected. */ + tx_semaphore_get(&semaphore_client_disconnected, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_2, &server_ip_address, RTSP_SERVER_PORT, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool_0, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list_2[i], rtsp_request_size_2[i], &client_pool_0, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client_2, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client_2, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=1.2.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%d", + RTP_2_RTP_PORT, RTP_2_RTCP_PORT, RTP_SERVER_RTP_PORT, RTP_SERVER_RTCP_PORT, RTP_2_SSRC); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://1.2.3.4:554/stream2/trackID=0;seq=%d;rtptime=%d", + RTP_2_VIDEO_SEQ, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_2_done); +} + + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; + + + /* Print out test information banner. */ + printf("NetX Test: RTSP Client Timeout Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Create RTSP server. */ + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + /* Set callback functions. */ + nx_rtsp_server_describe_callback_set(&rtsp_server, rtsp_describe_callback); + nx_rtsp_server_setup_callback_set(&rtsp_server, rtsp_setup_callback); + nx_rtsp_server_play_callback_set(&rtsp_server, rtsp_play_callback); + nx_rtsp_server_teardown_callback_set(&rtsp_server, rtsp_teardown_callback); + nx_rtsp_server_pause_callback_set(&rtsp_server, rtsp_pause_callback); + nx_rtsp_server_set_parameter_callback_set(&rtsp_server, rtsp_set_parameter_callback); + + /* Start RTSP server. */ + nx_rtsp_server_start(&rtsp_server); + + tx_semaphore_put(&semaphore_server_start); + tx_semaphore_put(&semaphore_server_start); + + tx_semaphore_get(&semaphore_client_0_done, NX_WAIT_FOREVER); + tx_semaphore_get(&semaphore_client_1_done, NX_WAIT_FOREVER); + tx_semaphore_get(&semaphore_client_2_done, NX_WAIT_FOREVER); + + if ((disconnect_count != 1) || rtsp_server.nx_rtsp_server_connected_client_count != 2) + { + error_counter++; + } + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool_0.nx_packet_pool_available != client_pool_0.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool_1.nx_packet_pool_available != client_pool_1.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ +UINT status; + + status = nx_rtsp_server_sdp_set(rtsp_client_ptr, sdp, strlen(sdp)); + return(status); +} + +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr) +{ +UINT status = NX_SUCCESS; + + transport_ptr -> server_rtp_port = RTP_SERVER_RTP_PORT; + transport_ptr -> server_rtcp_port = RTP_SERVER_RTCP_PORT; + + if (strstr(uri, "stream0")) + { + + /* Obtain generated ssrc */ + transport_ptr -> rtp_ssrc = RTP_0_SSRC; + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_SESSION_ID_0; + + /* Store the client pointer. */ + rtsp_client_ptr_0 = rtsp_client_ptr; + } + else if (strstr(uri, "stream1")) + { + + /* Obtain generated ssrc */ + transport_ptr -> rtp_ssrc = RTP_1_SSRC; + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_SESSION_ID_1; + + /* Store the client pointer. */ + rtsp_client_ptr_1 = rtsp_client_ptr; + } + else if (strstr(uri, "stream2")) + { + + /* Obtain generated ssrc */ + transport_ptr -> rtp_ssrc = RTP_2_SSRC; + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_SESSION_ID_2; + + /* Store the client pointer. */ + rtsp_client_ptr_2 = rtsp_client_ptr; + } + else + { + status = NX_RTSP_SERVER_INVALID_REQUEST; + } + + return(status); +} + +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ +UINT status; + + if (strstr(uri, "stream0")) + { + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, RTP_0_VIDEO_SEQ, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + } + else if (strstr(uri, "stream1")) + { + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, RTP_1_VIDEO_SEQ, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + } + else if (strstr(uri, "stream2")) + { + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, RTP_2_VIDEO_SEQ, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + } + else + { + status = NX_RTSP_SERVER_INVALID_REQUEST; + } + + return(status); +} + +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr) +{ + if (rtsp_client_ptr != rtsp_client_ptr_0) + { + error_counter++; + } + disconnect_count++; + tx_semaphore_put(&semaphore_client_disconnected); + return(NX_SUCCESS); +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_client_timeout_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTSP Client Timeout Test..................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtsp_test/netx_rtsp_delete_beforehand_test.c b/test/regression/rtsp_test/netx_rtsp_delete_beforehand_test.c new file mode 100644 index 00000000..fd23fc1e --- /dev/null +++ b/test/regression/rtsp_test/netx_rtsp_delete_beforehand_test.c @@ -0,0 +1,695 @@ +/* This case tests RTSP with RTP. */ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" +#include "nx_rtsp_server.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UCHAR rtsp_stack[DEMO_STACK_SIZE]; + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_TCP_SOCKET rtsp_client; +static NX_UDP_SOCKET rtp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_RTSP_SERVER rtsp_server; +static NX_RTP_SENDER rtp_server; +static NX_RTP_SESSION rtp_session_video; +static NX_RTP_SESSION rtp_session_audio; + +static UINT error_counter; + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_done; +static TX_SEMAPHORE semaphore_play; +static TX_SEMAPHORE semaphore_rtp_send; +static TX_SEMAPHORE semaphore_pause_received; + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr); +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length); +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTSP_SERVER_PORT 554 + +#define RTSP_SESSION_ID 23754311 +#define RTP_VIDEO_RTP_PORT 49752 +#define RTP_VIDEO_RTCP_PORT 49753 +#define RTP_AUDIO_RTP_PORT 49754 +#define RTP_AUDIO_RTCP_PORT 49755 + +#define RTP_PAYLOAD_TYPE_VIDEO 96 +#define RTP_PAYLOAD_TYPE_AUDIO 97 +#define RTP_TIMESTAMP_INIT_VALUE 40 +#define CNAME "AzureRTOS@microsoft.com" +#define TEST_MSW 123 +#define TEST_LSW 456 + +static UCHAR rtsp_option_request[] = "\ +OPTIONS rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_describe_request[] = "\ +DESCRIBE rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_0[] = "\ +SETUP rtsp://1.2.3.4:554/live.stream/trackID=0 RTSP/1.0\r\n\ +CSeq: 4\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49752-49753\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_1[] = "\ +SETUP rtsp://1.2.3.4:554/live.stream/trackID=1 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49754-49755\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_play_request[] = "\ +PLAY rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +static UCHAR rtsp_pause_request[] = "\ +PAUSE rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 7\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_teardown_request[] = "\ +TEARDOWN rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 8\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +typedef enum +{ + OPTION_INDEX, + DESCRIBE_INDEX, + SETUP_0_INDEX, + SETUP_1_INDEX, + PLAY_INDEX, + PAUSE_INDEX, +}REQUEST_INDEX; + +static UCHAR *rtsp_request_list[] = +{ +rtsp_option_request, +rtsp_describe_request, +rtsp_setup_request_0, +rtsp_setup_request_1, +rtsp_play_request, +rtsp_pause_request, +}; + +static UINT rtsp_request_size[] = +{ +sizeof(rtsp_option_request) - 1, +sizeof(rtsp_describe_request) - 1, +sizeof(rtsp_setup_request_0) - 1, +sizeof(rtsp_setup_request_1) - 1, +sizeof(rtsp_play_request) - 1, +sizeof(rtsp_pause_request) - 1, +}; + +static UINT rtsp_request_num = sizeof(rtsp_request_size) / sizeof(UINT); + +static UCHAR rtp_data[] = "rtp data for test"; + +static CHAR *sdp="v=0\r\ns=MPEG-1 or 2 Audio, streamed by the NetX RTSP Server\r\n\ +m=video 0 RTP/AVP 96\r\n\ +a=rtpmap:96 H264/90000\r\n\ +a=fmtp:96 profile-level-id=42A01E; packetization-mode=1\r\n\ +a=control:trackID=0\r\n\ +m=audio 0 RTP/AVP 97\r\n\ +a=rtpmap:97 mpeg4-generic/44100/1\r\n\ +a=fmtp:97 SizeLength=13\r\n\ +a=control:trackID=1\r\n"; + +static UINT video_seq = 0, audio_seq = 0; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_delete_beforehand_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&client_ip); + CHECK_STATUS(0, status); + + /* Create semaphores. */ + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_done, "semaphore client done", 0); + tx_semaphore_create(&semaphore_play, "semaphore play", 0); + tx_semaphore_create(&semaphore_rtp_send, "semaphore rtp send", 0); + tx_semaphore_create(&semaphore_pause_received, "semaphore teardown received", 0); +} + +void thread_client_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; +ULONG content_length = 0; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_ip, &rtsp_client, "Test Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&client_ip, &rtp_client, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client, RTP_VIDEO_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list[i], rtsp_request_size[i], &client_pool, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Since the test for teardown command is changed, break after send the request. */ + if (i == (rtsp_request_num - 1)) + { + + tx_semaphore_get(&semaphore_pause_received, NX_WAIT_FOREVER); + + /* Delete the server before nx_rtsp_server_disconnect called. + This test is to see if the server can be deleted normally. */ + nx_rtsp_server_delete(&rtsp_server); + break; + } + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the Content-length field. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Content-Length: "); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + /* Skip 16 bytes field header. */ + buffer_ptr += 16; + + /* Convert the length into a numeric value. */ + while ((buffer_ptr < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr >= '0') && (*buffer_ptr <= '9')) + { + + /* Update the content length. */ + content_length = content_length * 10; + content_length += (UINT)(*buffer_ptr) - '0'; + + /* Move the buffer pointer forward. */ + buffer_ptr++; + } + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + /* Skip 4 bytes terminators. */ + buffer_ptr += 4; + + /* Check content length. */ + CHECK_STATUS(content_length, (packet_ptr -> nx_packet_append_ptr - buffer_ptr)); + + /* Check the sdp information. */ + status = memcmp(buffer_ptr, sdp, (ULONG)strlen(sdp)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_0_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=1.2.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%ld", + RTP_VIDEO_RTP_PORT, RTP_VIDEO_RTCP_PORT, + rtp_server.nx_rtp_sender_rtp_port, + rtp_server.nx_rtp_sender_rtcp_port, + rtp_session_video.nx_rtp_session_ssrc); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_1_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=1.2.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%ld", + RTP_AUDIO_RTP_PORT, RTP_AUDIO_RTCP_PORT, + rtp_server.nx_rtp_sender_rtp_port, + rtp_server.nx_rtp_sender_rtcp_port, + rtp_session_audio.nx_rtp_session_ssrc); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://1.2.3.4:554/live.stream/trackID=0;seq=%d;rtptime=%d,url=rtsp://1.2.3.4:554/live.stream/trackID=1;seq=%d;rtptime=%d", + video_seq, RTP_TIMESTAMP_INIT_VALUE, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, "Range: npt=0.0-30.0", sizeof("Range: npt=0.0-30.0") - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + tx_semaphore_get(&semaphore_rtp_send, NX_WAIT_FOREVER); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PAUSE_INDEX) + { + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, "Range: npt=10.0-30.0", sizeof("Range: npt=10.0-30.0") - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + nx_tcp_socket_disconnect(&rtsp_client, NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_done); + nx_tcp_client_socket_unbind(&rtsp_client); + nx_tcp_socket_delete(&rtsp_client); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP Delete Beforehand Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Create RTSP server. */ + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 5, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + /* Set callback functions. */ + nx_rtsp_server_describe_callback_set(&rtsp_server, rtsp_describe_callback); + nx_rtsp_server_setup_callback_set(&rtsp_server, rtsp_setup_callback); + nx_rtsp_server_play_callback_set(&rtsp_server, rtsp_play_callback); + nx_rtsp_server_teardown_callback_set(&rtsp_server, rtsp_teardown_callback); + nx_rtsp_server_pause_callback_set(&rtsp_server, rtsp_pause_callback); + nx_rtsp_server_set_parameter_callback_set(&rtsp_server, rtsp_set_parameter_callback); + + /* Start RTSP server. */ + status = nx_rtsp_server_start(&rtsp_server); + CHECK_STATUS(0, status); + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_server, &server_ip, &server_pool, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_server_start); + + tx_semaphore_get(&semaphore_play, NX_WAIT_FOREVER); + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_video, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(packet_ptr, rtp_data, sizeof(rtp_data) - 1, rtp_server.nx_rtp_sender_ip_ptr -> nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Send packet. */ + status = nx_rtp_sender_session_packet_send(&rtp_session_video, packet_ptr, RTP_TIMESTAMP_INIT_VALUE, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_rtp_send); + + tx_semaphore_get(&semaphore_client_done, NX_WAIT_FOREVER); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ +UINT status; + + status = nx_rtsp_server_sdp_set(rtsp_client_ptr, sdp, strlen(sdp)); + return(status); +} + +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr) +{ +UINT status; +UINT rtp_port, rtcp_port; + + /* Get the created and found ports */ + status = nx_rtp_sender_port_get(&rtp_server, &rtp_port, &rtcp_port); + if (status) + { + return(status); + } + transport_ptr -> server_rtp_port = rtp_port; + transport_ptr -> server_rtcp_port = rtcp_port; + + if (strstr(uri, "trackID=0")) + { + /* Setup rtp sender session */ + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_video, RTP_PAYLOAD_TYPE_VIDEO, + transport_ptr -> interface_index, &(transport_ptr -> client_ip_address), + transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port); + CHECK_STATUS(0, status); + + /* Obtain generated ssrc */ + status = nx_rtp_sender_session_ssrc_get(&rtp_session_video, &(transport_ptr -> rtp_ssrc)); + CHECK_STATUS(0, status); + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_SESSION_ID; + } + else if (strstr(uri, "trackID=1")) + { + /* Setup rtp sender session */ + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_audio, RTP_PAYLOAD_TYPE_AUDIO, + transport_ptr -> interface_index, &(transport_ptr -> client_ip_address), + transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port); + CHECK_STATUS(0, status); + + /* Obtain generated ssrc */ + status = nx_rtp_sender_session_ssrc_get(&rtp_session_audio, &(transport_ptr -> rtp_ssrc)); + CHECK_STATUS(0, status); + } + else + { + status = NX_RTSP_SERVER_INVALID_REQUEST; + } + + return(status); +} + +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ +UINT status; + + /* Retrieve the sequence number through rtp sender functions */ + nx_rtp_sender_session_sequence_number_get(&rtp_session_video, &video_seq); + nx_rtp_sender_session_sequence_number_get(&rtp_session_audio, &audio_seq); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, video_seq, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=1", sizeof("trackID=1") - 1, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_range_npt_set(rtsp_client_ptr, 0, 30000); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_play); + + return(status); +} + +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + return(NX_NOT_SUCCESSFUL); +} + +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ +UINT status; + + status = nx_rtsp_server_range_npt_set(rtsp_client_ptr, 10000, 30000); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_pause_received); + + return(status); +} + +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr) +{ + return(NX_SUCCESS); +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_delete_beforehand_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP Delete Beforehand Test.......................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtsp_test/netx_rtsp_error_response_test.c b/test/regression/rtsp_test/netx_rtsp_error_response_test.c new file mode 100644 index 00000000..fa331ec4 --- /dev/null +++ b/test/regression/rtsp_test/netx_rtsp_error_response_test.c @@ -0,0 +1,402 @@ +/* This case tests sending error response. */ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) +#include "nx_rtsp_server.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UCHAR rtsp_stack[DEMO_STACK_SIZE]; + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_TCP_SOCKET rtsp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_RTSP_SERVER rtsp_server; + +static UINT error_counter; + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_done; + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr); +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length); +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTSP_SERVER_PORT 554 + +static UCHAR rtsp_setup_request_tcp[] = "\ +SETUP rtsp://1.2.3.4:554/live.stream/trackID=0 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP/TCP;unicast;interleaved=0-1\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_multicast[] = "\ +SETUP rtsp://1.2.3.4:554/live.stream/trackID=0 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;multicast;destination=225.219.201.15;port=7000-7001;ttl=127\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_unicast_error_id[] = "\ +SETUP rtsp://1.2.3.4:554/live.stream/trackID=0 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49754-49755\r\n\ +Session: 23754322\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_unicast_no_port[] = "\ +SETUP rtsp://1.2.3.4:554/live.stream/trackID=0 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_set_parameter[] = "\ +SET_PARAMETER rtsp://example.com/fizzle/foo RTSP/1.0\r\n\ +CSeq: 5\r\n\ +Session: 23754311\r\n\ +Content-length: 20\r\n\ +Content-type: text/parameters\r\n\ +\r\n\ +barparam: barstuff\r\n\ +"; + +static UCHAR error_response_461[] = "RTSP/1.0 461 UNSUPPORTED TRANSPORT\r\nCSeq: 5\r\nServer: RTSP Server\r\n\r\n"; + +static UCHAR error_response_454[] = "RTSP/1.0 454 SESSION NOT FOUND\r\nCSeq: 5\r\nServer: RTSP Server\r\n\r\n"; + +static UCHAR error_response_458[] = "RTSP/1.0 458 PARAMETER IS READONLY\r\nCSeq: 5\r\nServer: RTSP Server\r\n\r\n"; + +static UCHAR *rtsp_request_list[] = +{ +rtsp_setup_request_tcp, +rtsp_setup_request_multicast, +rtsp_setup_request_unicast_error_id, +rtsp_setup_request_unicast_no_port, +rtsp_setup_request_set_parameter, +}; + +static UINT rtsp_request_size[] = +{ +sizeof(rtsp_setup_request_tcp) - 1, +sizeof(rtsp_setup_request_multicast) - 1, +sizeof(rtsp_setup_request_unicast_error_id) - 1, +sizeof(rtsp_setup_request_unicast_no_port) - 1, +sizeof(rtsp_setup_request_set_parameter) - 1, +}; + +static UCHAR *rtsp_response_list[] = +{ +error_response_461, +error_response_461, +error_response_454, +error_response_461, +error_response_458, +}; + +static UINT rtsp_response_size[] = +{ +sizeof(error_response_461) - 1, +sizeof(error_response_461) - 1, +sizeof(error_response_454) - 1, +sizeof(error_response_461) - 1, +sizeof(error_response_458) - 1, +}; + +static UINT rtsp_request_num = sizeof(rtsp_request_size) / sizeof(UINT); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_error_response_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + CHECK_STATUS(0, status); + + /* Create semaphores. */ + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_done, "semaphore client done", 0); +} + +void thread_client_entry(ULONG thread_input) +{ +UINT i, j, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_ip, &rtsp_client, "Test Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + for (i = 0 ; i < rtsp_request_num; i++) + { + + status = nxd_tcp_client_socket_connect(&rtsp_client, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Set static session ID for test. */ + for (j = 0; j < NX_RTSP_SERVER_MAX_CLIENTS; j++) + { + rtsp_server.nx_rtsp_server_client_list[j].nx_rtsp_client_session_id = 23754311; + } + + /* Send data. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list[i], rtsp_request_size[i], &client_pool, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from server. */ + status = nx_tcp_socket_receive(&rtsp_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, rtsp_response_list[i], rtsp_response_size[i]); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + nx_tcp_socket_disconnect(&rtsp_client, NX_IP_PERIODIC_RATE); + } + + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_done); + nx_tcp_client_socket_unbind(&rtsp_client); + nx_tcp_socket_delete(&rtsp_client); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTSP Error Response Test.................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Create RTSP server. */ + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + /* Set callback functions. */ + nx_rtsp_server_describe_callback_set(&rtsp_server, rtsp_describe_callback); + nx_rtsp_server_setup_callback_set(&rtsp_server, rtsp_setup_callback); + nx_rtsp_server_play_callback_set(&rtsp_server, rtsp_play_callback); + nx_rtsp_server_teardown_callback_set(&rtsp_server, rtsp_teardown_callback); + nx_rtsp_server_pause_callback_set(&rtsp_server, rtsp_pause_callback); + nx_rtsp_server_set_parameter_callback_set(&rtsp_server, rtsp_set_parameter_callback); + + /* Start RTSP server. */ + nx_rtsp_server_start(&rtsp_server); + + tx_semaphore_put(&semaphore_server_start); + + tx_semaphore_get(&semaphore_client_done, NX_WAIT_FOREVER); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + + return(NX_SUCCESS); +} + +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length) +{ +UINT status; + + status = nx_rtsp_server_error_response_send(rtsp_client_ptr, NX_RTSP_STATUS_CODE_PARAMETER_IS_READONLY); + CHECK_STATUS(0, status); + + return(NX_RTSP_STATUS_CODE_PARAMETER_IS_READONLY); +} + +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr) +{ + return(NX_SUCCESS); +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_error_response_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTSP Error Response Test..................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtsp_test/netx_rtsp_multiple_clients_test.c b/test/regression/rtsp_test/netx_rtsp_multiple_clients_test.c new file mode 100644 index 00000000..5f178f3f --- /dev/null +++ b/test/regression/rtsp_test/netx_rtsp_multiple_clients_test.c @@ -0,0 +1,871 @@ +/* This case tests RTSP server connects with multiple clients. */ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" +#if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" +#include "nx_rtsp_server.h" +#endif + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && (NX_RTSP_SERVER_MAX_CLIENTS >= 2) + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UCHAR rtsp_stack[DEMO_STACK_SIZE]; + +static TX_THREAD client_thread_0; +static NX_PACKET_POOL client_pool_0; +static NX_IP client_ip_0; +static NX_TCP_SOCKET rtsp_client_0; +static NX_UDP_SOCKET rtp_client_0; + +static TX_THREAD client_thread_1; +static NX_PACKET_POOL client_pool_1; +static NX_IP client_ip_1; +static NX_TCP_SOCKET rtsp_client_1; +static NX_UDP_SOCKET rtp_client_1; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_RTSP_SERVER rtsp_server; +static NX_RTP_SENDER rtp_server; +static NX_RTP_SESSION rtp_session_0; +static NX_RTP_SESSION rtp_session_1; + +static UINT error_counter; + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_0_done; +static TX_SEMAPHORE semaphore_client_1_done; +static TX_SEMAPHORE semaphore_play_0; +static TX_SEMAPHORE semaphore_rtp_0_send; +static TX_SEMAPHORE semaphore_play_1; +static TX_SEMAPHORE semaphore_rtp_1_send; + +static void thread_client_0_entry(ULONG thread_input); +static void thread_client_1_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr); +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length); +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_0_ADDRESS IP_ADDRESS(1,2,3,5) +#define TEST_CLIENT_1_ADDRESS IP_ADDRESS(1,2,3,6) +#define RTSP_SERVER_PORT 554 + +#define RTSP_SESSION_ID_0 23754311 +#define RTSP_SESSION_ID_1 23754312 +#define RTP_0_RTP_PORT 49752 +#define RTP_0_RTCP_PORT 49753 +#define RTP_1_RTP_PORT 49754 +#define RTP_1_RTCP_PORT 49755 + +#define RTP_PAYLOAD_TYPE_VIDEO 96 +#define RTP_TIMESTAMP_INIT_VALUE 40 +#define CNAME "AzureRTOS@microsoft.com" +#define TEST_MSW 123 +#define TEST_LSW 456 + +static UCHAR rtsp_option_request_0[] = "\ +OPTIONS rtsp://1.2.3.4:554/stream0 RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_option_request_1[] = "\ +OPTIONS rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_describe_request_0[] = "\ +DESCRIBE rtsp://1.2.3.4:554/stream0 RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_describe_request_1[] = "\ +DESCRIBE rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_0[] = "\ +SETUP rtsp://1.2.3.4:554/stream0/trackID=0 RTSP/1.0\r\n\ +CSeq: 4\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49752-49753\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_1[] = "\ +SETUP rtsp://1.2.3.4:554/stream1/trackID=0 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49754-49755\r\n\r\n\ +"; + +static UCHAR rtsp_play_request_0[] = "\ +PLAY rtsp://1.2.3.4:554/stream0 RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +static UCHAR rtsp_play_request_1[] = "\ +PLAY rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754312\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +static UCHAR rtsp_teardown_request_0[] = "\ +TEARDOWN rtsp://1.2.3.4:554/stream0 RTSP/1.0\r\n\ +CSeq: 7\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_teardown_request_1[] = "\ +TEARDOWN rtsp://1.2.3.4:554/stream1 RTSP/1.0\r\n\ +CSeq: 7\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754312\r\n\r\n\ +"; + +typedef enum +{ + OPTION_INDEX, + DESCRIBE_INDEX, + SETUP_INDEX, + PLAY_INDEX, + TEARDOWN_INDEX +}REQUEST_INDEX; + +static UCHAR *rtsp_request_list_0[] = +{ +rtsp_option_request_0, +rtsp_describe_request_0, +rtsp_setup_request_0, +rtsp_play_request_0, +rtsp_teardown_request_0, +}; + +static UCHAR *rtsp_request_list_1[] = +{ +rtsp_option_request_1, +rtsp_describe_request_1, +rtsp_setup_request_1, +rtsp_play_request_1, +rtsp_teardown_request_1, +}; + +static UINT rtsp_request_size_0[] = +{ +sizeof(rtsp_option_request_0) - 1, +sizeof(rtsp_describe_request_0) - 1, +sizeof(rtsp_setup_request_0) - 1, +sizeof(rtsp_play_request_0) - 1, +sizeof(rtsp_teardown_request_0) - 1, +}; + +static UINT rtsp_request_size_1[] = +{ +sizeof(rtsp_option_request_1) - 1, +sizeof(rtsp_describe_request_1) - 1, +sizeof(rtsp_setup_request_1) - 1, +sizeof(rtsp_play_request_1) - 1, +sizeof(rtsp_teardown_request_1) - 1, +}; + +static UINT rtsp_request_num = sizeof(rtsp_request_size_0) / sizeof(UINT); + +static UCHAR rtp_data[] = "rtp data for test"; + +static CHAR *sdp="v=0\r\ns=MPEG-1 or 2 Audio, streamed by the NetX RTSP Server\r\n\ +m=video 0 RTP/AVP 96\r\n\ +a=rtpmap:96 H264/90000\r\n\ +a=fmtp:96 profile-level-id=42A01E; packetization-mode=1\r\n\ +a=control:trackID=0\r\n\ +"; + +static UINT video_seq_0 = 0, video_seq_1 = 0; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_multiple_clients_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread_0, "Test Client 0", thread_client_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool_0, "Test Client Packet Pool 0", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip_0, "Test Client IP 0", TEST_CLIENT_0_ADDRESS, + 0xFFFFFF00UL, &client_pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip_0); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&client_ip_0); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread_1, "Test Client 1", thread_client_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool_1, "Test Client Packet Pool 1", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip_1, "Test Client IP 1", TEST_CLIENT_1_ADDRESS, + 0xFFFFFF00UL, &client_pool_1, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip_1); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&client_ip_1); + CHECK_STATUS(0, status); + + /* Create semaphores. */ + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_0_done, "semaphore client 0 done", 0); + tx_semaphore_create(&semaphore_client_1_done, "semaphore client 1 done", 0); + tx_semaphore_create(&semaphore_play_0, "semaphore play 0", 0); + tx_semaphore_create(&semaphore_rtp_0_send, "semaphore rtp 0 send", 0); + tx_semaphore_create(&semaphore_play_1, "semaphore play 1", 0); + tx_semaphore_create(&semaphore_rtp_1_send, "semaphore rtp 1 send", 0); +} + +void thread_client_0_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_ip_0, &rtsp_client_0, "Test Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client_0, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&client_ip_0, &rtp_client_0, "RTCP Client Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_0, RTP_0_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_0, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool_0, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list_0[i], rtsp_request_size_0[i], &client_pool_0, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client_0, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=1.2.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%ld", + RTP_0_RTP_PORT, RTP_0_RTCP_PORT, + rtp_server.nx_rtp_sender_rtp_port, + rtp_server.nx_rtp_sender_rtcp_port, + rtp_session_0.nx_rtp_session_ssrc); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://1.2.3.4:554/stream0/trackID=0;seq=%d;rtptime=%d", + video_seq_0, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + tx_semaphore_get(&semaphore_rtp_0_send, NX_WAIT_FOREVER); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_0, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + nx_tcp_socket_disconnect(&rtsp_client_0, NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_0_done); + nx_tcp_client_socket_unbind(&rtsp_client_0); + nx_tcp_socket_delete(&rtsp_client_0); +} + +void thread_client_1_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_ip_1, &rtsp_client_1, "Test Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client_1, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&client_ip_1, &rtp_client_1, "RTCP Client Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_1, RTP_1_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_1, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool_1, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list_1[i], rtsp_request_size_1[i], &client_pool_1, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client_1, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client_1, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=1.2.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%ld", + RTP_1_RTP_PORT, RTP_1_RTCP_PORT, + rtp_server.nx_rtp_sender_rtp_port, + rtp_server.nx_rtp_sender_rtcp_port, + rtp_session_1.nx_rtp_session_ssrc); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://1.2.3.4:554/stream1/trackID=0;seq=%d;rtptime=%d", + video_seq_1, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + tx_semaphore_get(&semaphore_rtp_1_send, NX_WAIT_FOREVER); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_1, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + nx_tcp_socket_disconnect(&rtsp_client_1, NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_1_done); + nx_tcp_client_socket_unbind(&rtsp_client_1); + nx_tcp_socket_delete(&rtsp_client_1); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + + /* Print out test information banner. */ + printf("NetX Test: RTSP Multiple Clients Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Create RTSP server. */ + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + /* Set callback functions. */ + nx_rtsp_server_describe_callback_set(&rtsp_server, rtsp_describe_callback); + nx_rtsp_server_setup_callback_set(&rtsp_server, rtsp_setup_callback); + nx_rtsp_server_play_callback_set(&rtsp_server, rtsp_play_callback); + nx_rtsp_server_teardown_callback_set(&rtsp_server, rtsp_teardown_callback); + nx_rtsp_server_pause_callback_set(&rtsp_server, rtsp_pause_callback); + nx_rtsp_server_set_parameter_callback_set(&rtsp_server, rtsp_set_parameter_callback); + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_server, &server_ip, &server_pool, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + /* Start RTSP server. */ + nx_rtsp_server_start(&rtsp_server); + + tx_semaphore_put(&semaphore_server_start); + tx_semaphore_put(&semaphore_server_start); + + tx_semaphore_get(&semaphore_play_0, NX_WAIT_FOREVER); + tx_semaphore_get(&semaphore_play_1, NX_WAIT_FOREVER); + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(packet_ptr, rtp_data, sizeof(rtp_data) - 1, rtp_server.nx_rtp_sender_ip_ptr -> nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Send packet. */ + status = nx_rtp_sender_session_packet_send(&rtp_session_0, packet_ptr, RTP_TIMESTAMP_INIT_VALUE, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_1, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(packet_ptr, rtp_data, sizeof(rtp_data) - 1, rtp_server.nx_rtp_sender_ip_ptr -> nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Send packet. */ + status = nx_rtp_sender_session_packet_send(&rtp_session_1, packet_ptr, RTP_TIMESTAMP_INIT_VALUE, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_rtp_0_send); + tx_semaphore_put(&semaphore_rtp_1_send); + + tx_semaphore_get(&semaphore_client_0_done, NX_WAIT_FOREVER); + tx_semaphore_get(&semaphore_client_1_done, NX_WAIT_FOREVER); + + status = nx_rtsp_server_stop(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_delete(&rtsp_server); + CHECK_STATUS(0, status); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool_0.nx_packet_pool_available != client_pool_0.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool_1.nx_packet_pool_available != client_pool_1.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ +UINT status; + + status = nx_rtsp_server_sdp_set(rtsp_client_ptr, sdp, strlen(sdp)); + return(status); +} + +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr) +{ +UINT status; +UINT rtp_port, rtcp_port; + + /* Get the created and found ports */ + status = nx_rtp_sender_port_get(&rtp_server, &rtp_port, &rtcp_port); + if (status) + { + return(status); + } + transport_ptr -> server_rtp_port = rtp_port; + transport_ptr -> server_rtcp_port = rtcp_port; + + if (strstr(uri, "stream0")) + { + /* Setup rtp sender session */ + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_0, RTP_PAYLOAD_TYPE_VIDEO, + transport_ptr -> interface_index, &(transport_ptr -> client_ip_address), + transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port); + CHECK_STATUS(0, status); + + /* Obtain generated ssrc */ + status = nx_rtp_sender_session_ssrc_get(&rtp_session_0, &(transport_ptr -> rtp_ssrc)); + CHECK_STATUS(0, status); + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_SESSION_ID_0; + } + else if (strstr(uri, "stream1")) + { + /* Setup rtp sender session */ + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_1, RTP_PAYLOAD_TYPE_VIDEO, + transport_ptr -> interface_index, &(transport_ptr -> client_ip_address), + transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port); + CHECK_STATUS(0, status); + + /* Obtain generated ssrc */ + status = nx_rtp_sender_session_ssrc_get(&rtp_session_1, &(transport_ptr -> rtp_ssrc)); + CHECK_STATUS(0, status); + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_SESSION_ID_1; + } + else + { + status = NX_RTSP_SERVER_INVALID_REQUEST; + } + + return(status); +} + +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ +UINT status; + + if (strstr(uri, "stream0")) + { + + /* Retrieve the sequence number through rtp sender functions */ + nx_rtp_sender_session_sequence_number_get(&rtp_session_0, &video_seq_0); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, video_seq_0, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_play_0); + } + else if (strstr(uri, "stream1")) + { + + /* Retrieve the sequence number through rtp sender functions */ + nx_rtp_sender_session_sequence_number_get(&rtp_session_1, &video_seq_1); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, video_seq_1, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_play_1); + } + else + { + status = NX_RTSP_SERVER_INVALID_REQUEST; + } + + return(status); +} + +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + if (strstr(uri, "stream0")) + { + nx_rtp_sender_session_delete(&rtp_session_0); + } + else if (strstr(uri, "stream1")) + { + nx_rtp_sender_session_delete(&rtp_session_1); + } + + return(NX_SUCCESS); +} + +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr) +{ + return(NX_SUCCESS); +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_multiple_clients_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTSP Multiple Clients Test................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtsp_test/netx_rtsp_multiple_request_test.c b/test/regression/rtsp_test/netx_rtsp_multiple_request_test.c new file mode 100644 index 00000000..f927a97e --- /dev/null +++ b/test/regression/rtsp_test/netx_rtsp_multiple_request_test.c @@ -0,0 +1,359 @@ +/* This case tests RTSP request in multiple packets. */ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) +#include "nx_rtsp_server.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UCHAR rtsp_stack[DEMO_STACK_SIZE]; + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_TCP_SOCKET rtsp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_RTSP_SERVER rtsp_server; + +static UINT error_counter; + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_done; + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr); +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length); +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTSP_SERVER_PORT 554 + +#define TEST_LOOP 3 + +/* Test packet, length = 157 = 54 + 11 + 19 + 20 + 30 + 20. */ +static UCHAR test_data[] = "\ +SET_PARAMETER rtsp://example.com/fizzle/foo RTSP/1.0\r\n\ +CSeq: 421\r\n\ +Session: 23754311\r\n\ +Content-length: 20\r\n\ +Content-type: text/parameters\r\n\ +\r\n\ +barparam: barstuff\r\n\ +"; + +static UCHAR expected_response[] = "RTSP/1.0 200 OK\r\nCSeq: 421\r\nServer: RTSP Server\r\n\r\n"; + +static UINT test_size[TEST_LOOP][3] = +{ + {50, 39, 68}, // Conten-length in multiple packets. + {69, 70, 18}, // Content in multiple packets. + {39, 98, 20}, // Header in multiple packets and content in another packet +}; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_multiple_request_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + CHECK_STATUS(0, status); + + /* Create semaphores. */ + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_done, "semaphore client done", 0); +} + +void thread_client_entry(ULONG thread_input) +{ +UINT i, j, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_ip, &rtsp_client, "Test Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + for (i = 0 ; i < TEST_LOOP; i++) + { + + status = nxd_tcp_client_socket_connect(&rtsp_client, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Set static session ID for test. */ + for (j = 0; j < NX_RTSP_SERVER_MAX_CLIENTS; j++) + { + rtsp_server.nx_rtsp_server_client_list[j].nx_rtsp_client_session_id = 23754311; + } + + /* Send data. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, test_data, test_size[i][0], &client_pool, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Send data 1. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, test_data + test_size[i][0], test_size[i][1], &client_pool, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Send data 2. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, test_data + test_size[i][0] + test_size[i][1], test_size[i][2], &client_pool, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from server. */ + status = nx_tcp_socket_receive(&rtsp_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, expected_response, sizeof(expected_response) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + nx_tcp_socket_disconnect(&rtsp_client, NX_IP_PERIODIC_RATE); + } + + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_done); + nx_tcp_client_socket_unbind(&rtsp_client); + nx_tcp_socket_delete(&rtsp_client); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; + + /* Print out test information banner. */ + printf("NetX Test: RTSP Multiple Request Test................................"); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Create RTSP server. */ + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + /* Set callback functions. */ + nx_rtsp_server_describe_callback_set(&rtsp_server, rtsp_describe_callback); + nx_rtsp_server_setup_callback_set(&rtsp_server, rtsp_setup_callback); + nx_rtsp_server_play_callback_set(&rtsp_server, rtsp_play_callback); + nx_rtsp_server_teardown_callback_set(&rtsp_server, rtsp_teardown_callback); + nx_rtsp_server_pause_callback_set(&rtsp_server, rtsp_pause_callback); + nx_rtsp_server_set_parameter_callback_set(&rtsp_server, rtsp_set_parameter_callback); + + /* Start RTSP server. */ + nx_rtsp_server_start(&rtsp_server); + + tx_semaphore_put(&semaphore_server_start); + + tx_semaphore_get(&semaphore_client_done, NX_WAIT_FOREVER); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + + return(NX_SUCCESS); +} + +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length) +{ + + if ((parameter_length != 20) || (memcmp(parameter_ptr, "barparam: barstuff", sizeof("barparam: barstuff") - 1) != 0)) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + return(NX_SUCCESS); +} + +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr) +{ + return(NX_SUCCESS); +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_multiple_request_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTSP Multiple Request Test................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtsp_test/netx_rtsp_rtp_basic_test.c b/test/regression/rtsp_test/netx_rtsp_rtp_basic_test.c new file mode 100644 index 00000000..5bd35c79 --- /dev/null +++ b/test/regression/rtsp_test/netx_rtsp_rtp_basic_test.c @@ -0,0 +1,704 @@ +/* This case tests RTSP with RTP. */ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" +#include "nx_rtsp_server.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UCHAR rtsp_stack[DEMO_STACK_SIZE]; + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_TCP_SOCKET rtsp_client; +static NX_UDP_SOCKET rtp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_RTSP_SERVER rtsp_server; +static NX_RTP_SENDER rtp_server; +static NX_RTP_SESSION rtp_session_video; +static NX_RTP_SESSION rtp_session_audio; + +static UINT error_counter; + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_done; +static TX_SEMAPHORE semaphore_play; +static TX_SEMAPHORE semaphore_rtp_send; + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr); +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length); +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTSP_SERVER_PORT 554 + +#define RTSP_SESSION_ID 23754311 +#define RTP_VIDEO_RTP_PORT 49752 +#define RTP_VIDEO_RTCP_PORT 49753 +#define RTP_AUDIO_RTP_PORT 49754 +#define RTP_AUDIO_RTCP_PORT 49755 + +#define RTP_PAYLOAD_TYPE_VIDEO 96 +#define RTP_PAYLOAD_TYPE_AUDIO 97 +#define RTP_TIMESTAMP_INIT_VALUE 40 +#define CNAME "AzureRTOS@microsoft.com" +#define TEST_MSW 123 +#define TEST_LSW 456 + +static UCHAR rtsp_option_request[] = "\ +OPTIONS rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_describe_request[] = "\ +DESCRIBE rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_0[] = "\ +SETUP rtsp://1.2.3.4:554/live.stream/trackID=0 RTSP/1.0\r\n\ +CSeq: 4\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49752-49753\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_1[] = "\ +SETUP rtsp://1.2.3.4:554/live.stream/trackID=1 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49754-49755\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_play_request[] = "\ +PLAY rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +static UCHAR rtsp_pause_request[] = "\ +PAUSE rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 7\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_teardown_request[] = "\ +TEARDOWN rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 8\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +typedef enum +{ + OPTION_INDEX, + DESCRIBE_INDEX, + SETUP_0_INDEX, + SETUP_1_INDEX, + PLAY_INDEX, + PAUSE_INDEX, + TEARDOWN_INDEX +}REQUEST_INDEX; + +static UCHAR *rtsp_request_list[] = +{ +rtsp_option_request, +rtsp_describe_request, +rtsp_setup_request_0, +rtsp_setup_request_1, +rtsp_play_request, +rtsp_pause_request, +rtsp_teardown_request, +}; + +static UINT rtsp_request_size[] = +{ +sizeof(rtsp_option_request) - 1, +sizeof(rtsp_describe_request) - 1, +sizeof(rtsp_setup_request_0) - 1, +sizeof(rtsp_setup_request_1) - 1, +sizeof(rtsp_play_request) - 1, +sizeof(rtsp_pause_request) - 1, +sizeof(rtsp_teardown_request) - 1, +}; + +static UINT rtsp_request_num = sizeof(rtsp_request_size) / sizeof(UINT); + +static UCHAR rtp_data[] = "rtp data for test"; + +static CHAR *sdp="v=0\r\ns=MPEG-1 or 2 Audio, streamed by the NetX RTSP Server\r\n\ +m=video 0 RTP/AVP 96\r\n\ +a=rtpmap:96 H264/90000\r\n\ +a=fmtp:96 profile-level-id=42A01E; packetization-mode=1\r\n\ +a=control:trackID=0\r\n\ +m=audio 0 RTP/AVP 97\r\n\ +a=rtpmap:97 mpeg4-generic/44100/1\r\n\ +a=fmtp:97 SizeLength=13\r\n\ +a=control:trackID=1\r\n"; + +static UINT video_seq = 0, audio_seq = 0; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_rtp_basic_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&client_ip); + CHECK_STATUS(0, status); + + /* Create semaphores. */ + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_done, "semaphore client done", 0); + tx_semaphore_create(&semaphore_play, "semaphore play", 0); + tx_semaphore_create(&semaphore_rtp_send, "semaphore rtp send", 0); +} + +void thread_client_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; +ULONG content_length = 0; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_ip, &rtsp_client, "Test Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&client_ip, &rtp_client, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client, RTP_VIDEO_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list[i], rtsp_request_size[i], &client_pool, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the Content-length field. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Content-Length: "); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + /* Skip 16 bytes field header. */ + buffer_ptr += 16; + + /* Convert the length into a numeric value. */ + while ((buffer_ptr < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr >= '0') && (*buffer_ptr <= '9')) + { + + /* Update the content length. */ + content_length = content_length * 10; + content_length += (UINT)(*buffer_ptr) - '0'; + + /* Move the buffer pointer forward. */ + buffer_ptr++; + } + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + /* Skip 4 bytes terminators. */ + buffer_ptr += 4; + + /* Check content length. */ + CHECK_STATUS(content_length, (packet_ptr -> nx_packet_append_ptr - buffer_ptr)); + + /* Check the sdp information. */ + status = memcmp(buffer_ptr, sdp, (ULONG)strlen(sdp)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_0_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=1.2.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%ld", + RTP_VIDEO_RTP_PORT, RTP_VIDEO_RTCP_PORT, + rtp_server.nx_rtp_sender_rtp_port, + rtp_server.nx_rtp_sender_rtcp_port, + rtp_session_video.nx_rtp_session_ssrc); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_1_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=1.2.3.4;client_port=%d-%d;server_port=%d-%d;ssrc=%ld", + RTP_AUDIO_RTP_PORT, RTP_AUDIO_RTCP_PORT, + rtp_server.nx_rtp_sender_rtp_port, + rtp_server.nx_rtp_sender_rtcp_port, + rtp_session_audio.nx_rtp_session_ssrc); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://1.2.3.4:554/live.stream/trackID=0;seq=%d;rtptime=%d,url=rtsp://1.2.3.4:554/live.stream/trackID=1;seq=%d;rtptime=%d", + video_seq, RTP_TIMESTAMP_INIT_VALUE, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, "Range: npt=0.0-30.0", sizeof("Range: npt=0.0-30.0") - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + tx_semaphore_get(&semaphore_rtp_send, NX_WAIT_FOREVER); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PAUSE_INDEX) + { + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, "Range: npt=10.0-30.0", sizeof("Range: npt=10.0-30.0") - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + nx_tcp_socket_disconnect(&rtsp_client, NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_done); + nx_tcp_client_socket_unbind(&rtsp_client); + nx_tcp_socket_delete(&rtsp_client); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP Basic Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Create RTSP server. */ + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_delete(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + /* Set callback functions. */ + nx_rtsp_server_describe_callback_set(&rtsp_server, rtsp_describe_callback); + nx_rtsp_server_setup_callback_set(&rtsp_server, rtsp_setup_callback); + nx_rtsp_server_play_callback_set(&rtsp_server, rtsp_play_callback); + nx_rtsp_server_teardown_callback_set(&rtsp_server, rtsp_teardown_callback); + nx_rtsp_server_pause_callback_set(&rtsp_server, rtsp_pause_callback); + nx_rtsp_server_set_parameter_callback_set(&rtsp_server, rtsp_set_parameter_callback); + + /* Start RTSP server. */ + status = nx_rtsp_server_start(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_stop(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_start(&rtsp_server); + CHECK_STATUS(0, status); + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_server, &server_ip, &server_pool, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_server_start); + + tx_semaphore_get(&semaphore_play, NX_WAIT_FOREVER); + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_video, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(packet_ptr, rtp_data, sizeof(rtp_data) - 1, rtp_server.nx_rtp_sender_ip_ptr -> nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Send packet. */ + status = nx_rtp_sender_session_packet_send(&rtp_session_video, packet_ptr, RTP_TIMESTAMP_INIT_VALUE, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_rtp_send); + + tx_semaphore_get(&semaphore_client_done, NX_WAIT_FOREVER); + + status = nx_rtsp_server_stop(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_delete(&rtsp_server); + CHECK_STATUS(0, status); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ +UINT status; + + status = nx_rtsp_server_sdp_set(rtsp_client_ptr, sdp, strlen(sdp)); + return(status); +} + +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr) +{ +UINT status; +UINT rtp_port, rtcp_port; + + /* Get the created and found ports */ + status = nx_rtp_sender_port_get(&rtp_server, &rtp_port, &rtcp_port); + if (status) + { + return(status); + } + transport_ptr -> server_rtp_port = rtp_port; + transport_ptr -> server_rtcp_port = rtcp_port; + + if (strstr(uri, "trackID=0")) + { + /* Setup rtp sender session */ + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_video, RTP_PAYLOAD_TYPE_VIDEO, + transport_ptr -> interface_index, &(transport_ptr -> client_ip_address), + transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port); + CHECK_STATUS(0, status); + + /* Obtain generated ssrc */ + status = nx_rtp_sender_session_ssrc_get(&rtp_session_video, &(transport_ptr -> rtp_ssrc)); + CHECK_STATUS(0, status); + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_SESSION_ID; + } + else if (strstr(uri, "trackID=1")) + { + /* Setup rtp sender session */ + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_audio, RTP_PAYLOAD_TYPE_AUDIO, + transport_ptr -> interface_index, &(transport_ptr -> client_ip_address), + transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port); + CHECK_STATUS(0, status); + + /* Obtain generated ssrc */ + status = nx_rtp_sender_session_ssrc_get(&rtp_session_audio, &(transport_ptr -> rtp_ssrc)); + CHECK_STATUS(0, status); + } + else + { + status = NX_RTSP_SERVER_INVALID_REQUEST; + } + + return(status); +} + +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ +UINT status; + + /* Retrieve the sequence number through rtp sender functions */ + nx_rtp_sender_session_sequence_number_get(&rtp_session_video, &video_seq); + nx_rtp_sender_session_sequence_number_get(&rtp_session_audio, &audio_seq); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, video_seq, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=1", sizeof("trackID=1") - 1, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_range_npt_set(rtsp_client_ptr, 0, 30000); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_play); + + return(status); +} + +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + + nx_rtp_sender_session_delete(&rtp_session_video); + nx_rtp_sender_session_delete(&rtp_session_audio); + + return(NX_SUCCESS); +} + +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ +UINT status; + + status = nx_rtsp_server_range_npt_set(rtsp_client_ptr, 10000, 30000); + CHECK_STATUS(0, status); + + return(status); +} + +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr) +{ + return(NX_SUCCESS); +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_rtp_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP Basic Test.......................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtsp_test/netx_rtsp_rtp_ipv6_basic_test.c b/test/regression/rtsp_test/netx_rtsp_rtp_ipv6_basic_test.c new file mode 100644 index 00000000..52b2d792 --- /dev/null +++ b/test/regression/rtsp_test/netx_rtsp_rtp_ipv6_basic_test.c @@ -0,0 +1,722 @@ +/* This case tests RTSP with RTP. */ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if defined(FEATURE_NX_IPV6) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" +#include "nx_rtsp_server.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UCHAR rtsp_stack[DEMO_STACK_SIZE]; + +static TX_THREAD client_thread; +static NX_PACKET_POOL client_pool; +static NX_IP client_ip; +static NX_TCP_SOCKET rtsp_client; +static NX_UDP_SOCKET rtp_client; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_RTSP_SERVER rtsp_server; +static NX_RTP_SENDER rtp_server; +static NX_RTP_SESSION rtp_session_video; +static NX_RTP_SESSION rtp_session_audio; + +static UINT error_counter; + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_done; +static TX_SEMAPHORE semaphore_play; +static TX_SEMAPHORE semaphore_rtp_send; + + +static void thread_client_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr); +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length); +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr); + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_ADDRESS IP_ADDRESS(1,2,3,5) +#define RTSP_SERVER_PORT 554 + +#define RTSP_SESSION_ID 23754311 +#define RTP_VIDEO_RTP_PORT 49752 +#define RTP_VIDEO_RTCP_PORT 49753 +#define RTP_AUDIO_RTP_PORT 49754 +#define RTP_AUDIO_RTCP_PORT 49755 + +#define RTP_PAYLOAD_TYPE_VIDEO 96 +#define RTP_PAYLOAD_TYPE_AUDIO 97 +#define RTP_TIMESTAMP_INIT_VALUE 40 +#define CNAME "AzureRTOS@microsoft.com" +#define TEST_MSW 123 +#define TEST_LSW 456 + +static NXD_ADDRESS server_ip_address; +static NXD_ADDRESS client_ip_address; + +static UCHAR rtsp_option_request[] = "\ +OPTIONS rtsp://[2001::4]:554/live.stream RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_describe_request[] = "\ +DESCRIBE rtsp://[2001::4]:554/live.stream RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_0[] = "\ +SETUP rtsp://[2001::4]:554/live.stream/trackID=0 RTSP/1.0\r\n\ +CSeq: 4\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49752-49753\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_1[] = "\ +SETUP rtsp://[2001::4]:554/live.stream/trackID=1 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;unicast;client_port=49754-49755\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_play_request[] = "\ +PLAY rtsp://[2001::4]:554/live.stream RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +static UCHAR rtsp_pause_request[] = "\ +PAUSE rtsp://[2001::4]:554/live.stream RTSP/1.0\r\n\ +CSeq: 7\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_teardown_request[] = "\ +TEARDOWN rtsp://[2001::4]:554/live.stream RTSP/1.0\r\n\ +CSeq: 8\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +typedef enum +{ + OPTION_INDEX, + DESCRIBE_INDEX, + SETUP_0_INDEX, + SETUP_1_INDEX, + PLAY_INDEX, + PAUSE_INDEX, + TEARDOWN_INDEX +}REQUEST_INDEX; + +static UCHAR *rtsp_request_list[] = +{ +rtsp_option_request, +rtsp_describe_request, +rtsp_setup_request_0, +rtsp_setup_request_1, +rtsp_play_request, +rtsp_pause_request, +rtsp_teardown_request, +}; + +static UINT rtsp_request_size[] = +{ +sizeof(rtsp_option_request) - 1, +sizeof(rtsp_describe_request) - 1, +sizeof(rtsp_setup_request_0) - 1, +sizeof(rtsp_setup_request_1) - 1, +sizeof(rtsp_play_request) - 1, +sizeof(rtsp_pause_request) - 1, +sizeof(rtsp_teardown_request) - 1, +}; + +static UINT rtsp_request_num = sizeof(rtsp_request_size) / sizeof(UINT); + +static UCHAR rtp_data[] = "rtp data for test"; + +static CHAR *sdp="v=0\r\ns=MPEG-1 or 2 Audio, streamed by the NetX RTSP Server\r\n\ +m=video 0 RTP/AVP 96\r\n\ +a=rtpmap:96 H264/90000\r\n\ +a=fmtp:96 profile-level-id=42A01E; packetization-mode=1\r\n\ +a=control:trackID=0\r\n\ +m=audio 0 RTP/AVP 97\r\n\ +a=rtpmap:97 mpeg4-generic/44100/1\r\n\ +a=fmtp:97 SizeLength=13\r\n\ +a=control:trackID=1\r\n"; + +static UINT video_seq = 0, audio_seq = 0; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_rtp_ipv6_basic_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable IPv6 */ + nxd_ipv6_enable(&server_ip); + + /* Set server ip primary link local address. */ + server_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + server_ip_address.nxd_ip_address.v6[0] = 0x20010000; + server_ip_address.nxd_ip_address.v6[1] = 0; + server_ip_address.nxd_ip_address.v6[2] = 0; + server_ip_address.nxd_ip_address.v6[3] = 4; + status = nxd_ipv6_address_set(&server_ip, 0, &server_ip_address, 64, NULL); + CHECK_STATUS(0, status); + + status = nxd_icmp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread, "Test Client", thread_client_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool, "Test Client Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "Test Client IP", TEST_CLIENT_ADDRESS, + 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable IPv6 */ + nxd_ipv6_enable(&client_ip); + + /* Set client ip primary link local address. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + client_ip_address.nxd_ip_address.v6[0] = 0x20010000; + client_ip_address.nxd_ip_address.v6[1] = 0; + client_ip_address.nxd_ip_address.v6[2] = 0; + client_ip_address.nxd_ip_address.v6[3] = 3; + status = nxd_ipv6_address_set(&client_ip, 0, &client_ip_address, 64, NULL); + CHECK_STATUS(0, status); + + status = nxd_icmp_enable(&client_ip); + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&client_ip); + CHECK_STATUS(0, status); + + /* Create semaphores. */ + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_done, "semaphore client done", 0); + tx_semaphore_create(&semaphore_play, "semaphore play", 0); + tx_semaphore_create(&semaphore_rtp_send, "semaphore rtp send", 0); +} + +void thread_client_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; +ULONG content_length = 0; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + status = nx_tcp_socket_create(&client_ip, &rtsp_client, "Test Client Socket", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&client_ip, &rtp_client, "RTCP Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client, RTP_VIDEO_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list[i], rtsp_request_size[i], &client_pool, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the Content-length field. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Content-Length: "); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + /* Skip 16 bytes field header. */ + buffer_ptr += 16; + + /* Convert the length into a numeric value. */ + while ((buffer_ptr < packet_ptr -> nx_packet_append_ptr) && (*buffer_ptr >= '0') && (*buffer_ptr <= '9')) + { + + /* Update the content length. */ + content_length = content_length * 10; + content_length += (UINT)(*buffer_ptr) - '0'; + + /* Move the buffer pointer forward. */ + buffer_ptr++; + } + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + /* Skip 4 bytes terminators. */ + buffer_ptr += 4; + + /* Check content length. */ + CHECK_STATUS(content_length, (packet_ptr -> nx_packet_append_ptr - buffer_ptr)); + + /* Check the sdp information. */ + status = memcmp(buffer_ptr, sdp, (ULONG)strlen(sdp)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_0_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=2001:0000:0000:0000:0000:0000:0000:0004;client_port=%d-%d;server_port=%d-%d;ssrc=%ld", + RTP_VIDEO_RTP_PORT, RTP_VIDEO_RTCP_PORT, + rtp_server.nx_rtp_sender_rtp_port, + rtp_server.nx_rtp_sender_rtcp_port, + rtp_session_video.nx_rtp_session_ssrc); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_1_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;unicast;source=2001:0000:0000:0000:0000:0000:0000:0004;client_port=%d-%d;server_port=%d-%d;ssrc=%ld", + RTP_AUDIO_RTP_PORT, RTP_AUDIO_RTCP_PORT, + rtp_server.nx_rtp_sender_rtp_port, + rtp_server.nx_rtp_sender_rtcp_port, + rtp_session_audio.nx_rtp_session_ssrc); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://[2001::4]:554/live.stream/trackID=0;seq=%d;rtptime=%d,url=rtsp://[2001::4]:554/live.stream/trackID=1;seq=%d;rtptime=%d", + video_seq, RTP_TIMESTAMP_INIT_VALUE, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, "Range: npt=0.0-30.0", sizeof("Range: npt=0.0-30.0") - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + tx_semaphore_get(&semaphore_rtp_send, NX_WAIT_FOREVER); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PAUSE_INDEX) + { + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, "Range: npt=10.0-30.0", sizeof("Range: npt=10.0-30.0") - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + nx_tcp_socket_disconnect(&rtsp_client, NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_done); + nx_tcp_client_socket_unbind(&rtsp_client); + nx_tcp_socket_delete(&rtsp_client); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP IPv6 Basic Test......................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Create RTSP server. */ + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_delete(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + /* Set callback functions. */ + nx_rtsp_server_describe_callback_set(&rtsp_server, rtsp_describe_callback); + nx_rtsp_server_setup_callback_set(&rtsp_server, rtsp_setup_callback); + nx_rtsp_server_play_callback_set(&rtsp_server, rtsp_play_callback); + nx_rtsp_server_teardown_callback_set(&rtsp_server, rtsp_teardown_callback); + nx_rtsp_server_pause_callback_set(&rtsp_server, rtsp_pause_callback); + nx_rtsp_server_set_parameter_callback_set(&rtsp_server, rtsp_set_parameter_callback); + + /* Start RTSP server. */ + status = nx_rtsp_server_start(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_stop(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_start(&rtsp_server); + CHECK_STATUS(0, status); + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_server, &server_ip, &server_pool, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_server_start); + + tx_semaphore_get(&semaphore_play, NX_WAIT_FOREVER); + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_video, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(packet_ptr, rtp_data, sizeof(rtp_data) - 1, rtp_server.nx_rtp_sender_ip_ptr -> nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Send packet. */ + status = nx_rtp_sender_session_packet_send(&rtp_session_video, packet_ptr, RTP_TIMESTAMP_INIT_VALUE, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_rtp_send); + + tx_semaphore_get(&semaphore_client_done, NX_WAIT_FOREVER); + + status = nx_rtsp_server_stop(&rtsp_server); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_delete(&rtsp_server); + CHECK_STATUS(0, status); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool.nx_packet_pool_available != client_pool.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ +UINT status; + + status = nx_rtsp_server_sdp_set(rtsp_client_ptr, sdp, strlen(sdp)); + return(status); +} + +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr) +{ +UINT status; +UINT rtp_port, rtcp_port; + + /* Get the created and found ports */ + status = nx_rtp_sender_port_get(&rtp_server, &rtp_port, &rtcp_port); + if (status) + { + return(status); + } + transport_ptr -> server_rtp_port = rtp_port; + transport_ptr -> server_rtcp_port = rtcp_port; + + if (strstr(uri, "trackID=0")) + { + /* Setup rtp sender session */ + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_video, RTP_PAYLOAD_TYPE_VIDEO, + transport_ptr -> interface_index, &(transport_ptr -> client_ip_address), + transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port); + CHECK_STATUS(0, status); + + /* Obtain generated ssrc */ + status = nx_rtp_sender_session_ssrc_get(&rtp_session_video, &(transport_ptr -> rtp_ssrc)); + CHECK_STATUS(0, status); + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_SESSION_ID; + } + else if (strstr(uri, "trackID=1")) + { + /* Setup rtp sender session */ + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_audio, RTP_PAYLOAD_TYPE_AUDIO, + transport_ptr -> interface_index, &(transport_ptr -> client_ip_address), + transport_ptr -> client_rtp_port, transport_ptr -> client_rtcp_port); + CHECK_STATUS(0, status); + + /* Obtain generated ssrc */ + status = nx_rtp_sender_session_ssrc_get(&rtp_session_audio, &(transport_ptr -> rtp_ssrc)); + CHECK_STATUS(0, status); + } + else + { + status = NX_RTSP_SERVER_INVALID_REQUEST; + } + + return(status); +} + +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ +UINT status; + + /* Retrieve the sequence number through rtp sender functions */ + nx_rtp_sender_session_sequence_number_get(&rtp_session_video, &video_seq); + nx_rtp_sender_session_sequence_number_get(&rtp_session_audio, &audio_seq); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, video_seq, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=1", sizeof("trackID=1") - 1, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_range_npt_set(rtsp_client_ptr, 0, 30000); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_play); + + return(status); +} + +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + + nx_rtp_sender_session_delete(&rtp_session_video); + nx_rtp_sender_session_delete(&rtp_session_audio); + + return(NX_SUCCESS); +} + +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ +UINT status; + + status = nx_rtsp_server_range_npt_set(rtsp_client_ptr, 10000, 30000); + CHECK_STATUS(0, status); + + return(status); +} + +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr) +{ + return(NX_SUCCESS); +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_rtp_ipv6_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP IPv6 Basic Test.......................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtsp_test/netx_rtsp_rtp_ipv6_multicast_test.c b/test/regression/rtsp_test/netx_rtsp_rtp_ipv6_multicast_test.c new file mode 100644 index 00000000..75c62b66 --- /dev/null +++ b/test/regression/rtsp_test/netx_rtsp_rtp_ipv6_multicast_test.c @@ -0,0 +1,931 @@ +/* This case tests RTSP with RTP in multicast mode. */ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" +#include "nx_rtsp_server.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UCHAR rtsp_stack[DEMO_STACK_SIZE]; + +static TX_THREAD client_thread_0; +static NX_PACKET_POOL client_pool_0; +static NX_IP client_ip_0; +static NX_TCP_SOCKET rtsp_client_0; +static NX_UDP_SOCKET rtp_client_0; + +static TX_THREAD client_thread_1; +static NX_PACKET_POOL client_pool_1; +static NX_IP client_ip_1; +static NX_TCP_SOCKET rtsp_client_1; +static NX_UDP_SOCKET rtp_client_1; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_RTSP_SERVER rtsp_server; +static NX_RTP_SENDER rtp_server; +static NX_RTP_SESSION rtp_session_video; +static NX_RTP_SESSION rtp_session_audio; + +static UINT error_counter; + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_0_done; +static TX_SEMAPHORE semaphore_client_1_done; +static TX_SEMAPHORE semaphore_play; +static TX_SEMAPHORE semaphore_rtp_send; + +static NXD_ADDRESS group_address[8]; +static NXD_ADDRESS server_ip_address; +static NXD_ADDRESS client_0_ip_address; +static NXD_ADDRESS client_1_ip_address; + +static void thread_client_0_entry(ULONG thread_input); +static void thread_client_1_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr); +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length); +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr); + +/* Define ipv6 multicast group address. */ +#define GROUP_ADDRESS_0 0xff020000 +#define GROUP_ADDRESS_1 0x00000000 +#define GROUP_ADDRESS_2 0x00000000 +#define GROUP_ADDRESS_3 0x01020301 + +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_0_ADDRESS IP_ADDRESS(1,2,3,5) +#define TEST_CLIENT_1_ADDRESS IP_ADDRESS(1,2,3,6) +#define RTSP_SERVER_PORT 554 + +#define RTSP_SESSION_ID 23754311 +#define RTP_VIDEO_RTP_PORT 49752 +#define RTP_VIDEO_RTCP_PORT 49753 +#define RTP_AUDIO_RTP_PORT 49754 +#define RTP_AUDIO_RTCP_PORT 49755 + +#define RTP_PAYLOAD_TYPE_VIDEO 96 +#define RTP_PAYLOAD_TYPE_AUDIO 97 +#define RTP_TIMESTAMP_INIT_VALUE 40 +#define CNAME "AzureRTOS@microsoft.com" +#define TEST_MSW 123 +#define TEST_LSW 456 +#define TEST_TTL 128 + +static UCHAR rtsp_option_request[] = "\ +OPTIONS rtsp://[2001::4]:554/live.stream RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_describe_request[] = "\ +DESCRIBE rtsp://[2001::4]:554/live.stream RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_0[] = "\ +SETUP rtsp://[2001::4]:554/live.stream/trackID=0 RTSP/1.0\r\n\ +CSeq: 4\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;multicast;port=49752-49753\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_1[] = "\ +SETUP rtsp://[2001::4]:554/live.stream/trackID=1 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;multicast;port=49754-49755\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_play_request[] = "\ +PLAY rtsp://[2001::4]:554/live.stream RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +static UCHAR rtsp_pause_request[] = "\ +PAUSE rtsp://[2001::4]:554/live.stream RTSP/1.0\r\n\ +CSeq: 7\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_teardown_request[] = "\ +TEARDOWN rtsp://[2001::4]:554/live.stream RTSP/1.0\r\n\ +CSeq: 8\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +typedef enum +{ + OPTION_INDEX, + DESCRIBE_INDEX, + SETUP_0_INDEX, + SETUP_1_INDEX, + PLAY_INDEX, + PAUSE_INDEX, + TEARDOWN_INDEX +}REQUEST_INDEX; + +static UCHAR *rtsp_request_list[] = +{ +rtsp_option_request, +rtsp_describe_request, +rtsp_setup_request_0, +rtsp_setup_request_1, +rtsp_play_request, +rtsp_pause_request, +rtsp_teardown_request, +}; + +static UINT rtsp_request_size[] = +{ +sizeof(rtsp_option_request) - 1, +sizeof(rtsp_describe_request) - 1, +sizeof(rtsp_setup_request_0) - 1, +sizeof(rtsp_setup_request_1) - 1, +sizeof(rtsp_play_request) - 1, +sizeof(rtsp_pause_request) - 1, +sizeof(rtsp_teardown_request) - 1, +}; + +static UINT rtsp_request_num = sizeof(rtsp_request_size) / sizeof(UINT); + +static UCHAR rtp_data[] = "rtp data for test"; + +static CHAR *sdp="v=0\r\ns=MPEG-1 or 2 Audio, streamed by the NetX RTSP Server\r\n\ +m=video 6002 RTP/AVP 96\r\n\ +c=IN IP4 ff02:0000:0000:0000:0000:0000:0102:0301/20\r\n\ +a=rtpmap:96 H264/90000\r\n\ +a=fmtp:96 profile-level-id=42A01E; packetization-mode=1\r\n\ +a=control:trackID=0\r\n\ +m=audio 6002 RTP/AVP 97\r\n\ +c=IN IP4 ff02:0000:0000:0000:0000:0000:0102:0301/20\r\n\ +a=rtpmap:97 mpeg4-generic/44100/1\r\n\ +a=fmtp:97 SizeLength=13\r\n\ +a=control:trackID=1\r\n"; + +static UINT video_seq = 0, audio_seq = 0; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_rtp_multicast_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable IPv6 */ + nxd_ipv6_enable(&server_ip); + + /* Set server ip primary link local address. */ + server_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + server_ip_address.nxd_ip_address.v6[0] = 0x20010000; + server_ip_address.nxd_ip_address.v6[1] = 0; + server_ip_address.nxd_ip_address.v6[2] = 0; + server_ip_address.nxd_ip_address.v6[3] = 4; + status = nxd_ipv6_address_set(&server_ip, 0, &server_ip_address, 64, NULL); + CHECK_STATUS(0, status); + + status = nxd_icmp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread_0, "Test Client 0", thread_client_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool_0, "Test Client Packet Pool 0", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip_0, "Test Client IP 0", TEST_CLIENT_0_ADDRESS, + 0xFFFFFF00UL, &client_pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable IPv6 */ + nxd_ipv6_enable(&client_ip_0); + + /* Set client 0 ip primary link local address. */ + client_0_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + client_0_ip_address.nxd_ip_address.v6[0] = 0x20010000; + client_0_ip_address.nxd_ip_address.v6[1] = 0; + client_0_ip_address.nxd_ip_address.v6[2] = 0; + client_0_ip_address.nxd_ip_address.v6[3] = 3; + status = nxd_ipv6_address_set(&client_ip_0, 0, &client_0_ip_address, 64, NULL); + CHECK_STATUS(0, status); + + status = nxd_icmp_enable(&client_ip_0); + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip_0); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&client_ip_0); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread_1, "Test Client 1", thread_client_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool_1, "Test Client Packet Pool 1", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip_1, "Test Client IP 1", TEST_CLIENT_1_ADDRESS, + 0xFFFFFF00UL, &client_pool_1, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable IPv6 */ + nxd_ipv6_enable(&client_ip_1); + + /* Set client 1 ip primary link local address. */ + client_1_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + client_1_ip_address.nxd_ip_address.v6[0] = 0x20010000; + client_1_ip_address.nxd_ip_address.v6[1] = 0; + client_1_ip_address.nxd_ip_address.v6[2] = 0; + client_1_ip_address.nxd_ip_address.v6[3] = 2; + status = nxd_ipv6_address_set(&client_ip_1, 0, &client_1_ip_address, 64, NULL); + CHECK_STATUS(0, status); + + status = nxd_icmp_enable(&client_ip_1); + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip_1); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&client_ip_1); + CHECK_STATUS(0, status); + + /* Create semaphores. */ + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_0_done, "semaphore client 0 done", 0); + tx_semaphore_create(&semaphore_client_1_done, "semaphore client 1 done", 0); + tx_semaphore_create(&semaphore_play, "semaphore play", 0); + tx_semaphore_create(&semaphore_rtp_send, "semaphore rtp send", 0); +} + +void thread_client_0_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Enable IGMP & join in multicast group. */ + status = nx_igmp_enable(&client_ip_0); + status = nxd_ipv6_multicast_interface_join(&client_ip_0, &group_address[0], 0); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_create(&client_ip_0, &rtsp_client_0, "Test Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client_0, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&client_ip_0, &rtp_client_0, "RTCP Client Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_0, RTP_VIDEO_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_0, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool_0, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list[i], rtsp_request_size[i], &client_pool_0, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client_0, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_0_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;multicast;destination=FF02:0000:0000:0000:0000:0000:0102:0301;port=%d-%d;ttl=%d", + RTP_VIDEO_RTP_PORT, RTP_VIDEO_RTCP_PORT, TEST_TTL); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_1_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;multicast;destination=FF02:0000:0000:0000:0000:0000:0102:0301;port=%d-%d;ttl=%d", + RTP_AUDIO_RTP_PORT, RTP_AUDIO_RTCP_PORT, TEST_TTL); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://[2001::4]:554/live.stream/trackID=0;seq=%d;rtptime=%d,url=rtsp://[2001::4]:554/live.stream/trackID=1;seq=%d;rtptime=%d", + video_seq, RTP_TIMESTAMP_INIT_VALUE, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, "Range: npt=0.0-", sizeof("Range: npt=0.0-") - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + tx_semaphore_get(&semaphore_rtp_send, NX_WAIT_FOREVER); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_0, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PAUSE_INDEX) + { + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr != NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + nx_tcp_socket_disconnect(&rtsp_client_0, NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_0_done); + nx_tcp_client_socket_unbind(&rtsp_client_0); + nx_tcp_socket_delete(&rtsp_client_0); +} + +void thread_client_1_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Enable IGMP & join in multicast group. */ + status = nx_igmp_enable(&client_ip_1); + status = nxd_ipv6_multicast_interface_join(&client_ip_1, &group_address[0], 0); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_create(&client_ip_1, &rtsp_client_1, "Test Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client_1, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&client_ip_1, &rtp_client_1, "RTCP Client Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_1, RTP_VIDEO_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_1, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool_1, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list[i], rtsp_request_size[i], &client_pool_1, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client_1, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client_1, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_0_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;multicast;destination=FF02:0000:0000:0000:0000:0000:0102:0301;port=%d-%d;ttl=%d", + RTP_VIDEO_RTP_PORT, RTP_VIDEO_RTCP_PORT, TEST_TTL); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_1_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;multicast;destination=FF02:0000:0000:0000:0000:0000:0102:0301;port=%d-%d;ttl=%d", + RTP_AUDIO_RTP_PORT, RTP_AUDIO_RTCP_PORT, TEST_TTL); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://[2001::4]:554/live.stream/trackID=0;seq=%d;rtptime=%d,url=rtsp://[2001::4]:554/live.stream/trackID=1;seq=%d;rtptime=%d", + video_seq, RTP_TIMESTAMP_INIT_VALUE, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + tx_semaphore_get(&semaphore_rtp_send, NX_WAIT_FOREVER); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_1, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + } + + nx_tcp_socket_disconnect(&rtsp_client_1, NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_1_done); + nx_tcp_client_socket_unbind(&rtsp_client_1); + nx_tcp_socket_delete(&rtsp_client_1); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +NXD_ADDRESS client_ip_address; + + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP Multicast Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Set the group address . */ + group_address[0].nxd_ip_version = NX_IP_VERSION_V6; + group_address[0].nxd_ip_address.v6[0] = GROUP_ADDRESS_0; + group_address[0].nxd_ip_address.v6[1] = GROUP_ADDRESS_1; + group_address[0].nxd_ip_address.v6[2] = GROUP_ADDRESS_2; + group_address[0].nxd_ip_address.v6[3] = GROUP_ADDRESS_3; + + /* Enable IGMP & join in multicast group. */ + status = nx_igmp_enable(&server_ip); + CHECK_STATUS(0, status); + status = nxd_ipv6_multicast_interface_join(&server_ip, &group_address[0], 0); + CHECK_STATUS(0, status); + + /* Create RTSP server. */ + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + /* Set callback functions. */ + nx_rtsp_server_describe_callback_set(&rtsp_server, rtsp_describe_callback); + nx_rtsp_server_setup_callback_set(&rtsp_server, rtsp_setup_callback); + nx_rtsp_server_play_callback_set(&rtsp_server, rtsp_play_callback); + nx_rtsp_server_teardown_callback_set(&rtsp_server, rtsp_teardown_callback); + nx_rtsp_server_pause_callback_set(&rtsp_server, rtsp_pause_callback); + nx_rtsp_server_set_parameter_callback_set(&rtsp_server, rtsp_set_parameter_callback); + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_server, &server_ip, &server_pool, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + client_ip_address.nxd_ip_address.v6[0] = GROUP_ADDRESS_0; + client_ip_address.nxd_ip_address.v6[1] = GROUP_ADDRESS_1; + client_ip_address.nxd_ip_address.v6[2] = GROUP_ADDRESS_2; + client_ip_address.nxd_ip_address.v6[3] = GROUP_ADDRESS_3; + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_video, RTP_PAYLOAD_TYPE_VIDEO, + 0, &client_ip_address, + RTP_VIDEO_RTP_PORT, RTP_VIDEO_RTCP_PORT); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_audio, RTP_PAYLOAD_TYPE_VIDEO, + 0, &client_ip_address, + RTP_AUDIO_RTP_PORT, RTP_AUDIO_RTCP_PORT); + CHECK_STATUS(0, status); + + /* Start RTSP server. */ + nx_rtsp_server_start(&rtsp_server); + + tx_semaphore_put(&semaphore_server_start); + tx_semaphore_put(&semaphore_server_start); + + tx_semaphore_get(&semaphore_play, NX_WAIT_FOREVER); + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_video, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(packet_ptr, rtp_data, sizeof(rtp_data) - 1, rtp_server.nx_rtp_sender_ip_ptr -> nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Send packet. */ + status = nx_rtp_sender_session_packet_send(&rtp_session_video, packet_ptr, RTP_TIMESTAMP_INIT_VALUE, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_rtp_send); + tx_semaphore_put(&semaphore_rtp_send); + + tx_semaphore_get(&semaphore_client_0_done, NX_WAIT_FOREVER); + tx_semaphore_get(&semaphore_client_1_done, NX_WAIT_FOREVER); + + status = nx_rtsp_server_delete(&rtsp_server); + CHECK_STATUS(0, status); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool_0.nx_packet_pool_available != client_pool_0.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool_1.nx_packet_pool_available != client_pool_1.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ +UINT status; + + status = nx_rtsp_server_sdp_set(rtsp_client_ptr, sdp, strlen(sdp)); + return(status); +} + +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr) +{ +UINT status; +UINT rtp_port, rtcp_port; + + /* Get the created and found ports */ + status = nx_rtp_sender_port_get(&rtp_server, &rtp_port, &rtcp_port); + if (status) + { + return(status); + } + transport_ptr -> server_rtp_port = rtp_port; + transport_ptr -> server_rtcp_port = rtcp_port; + + transport_ptr -> client_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + transport_ptr -> client_ip_address.nxd_ip_address.v6[0] = GROUP_ADDRESS_0; + transport_ptr -> client_ip_address.nxd_ip_address.v6[1] = GROUP_ADDRESS_1; + transport_ptr -> client_ip_address.nxd_ip_address.v6[2] = GROUP_ADDRESS_2; + transport_ptr -> client_ip_address.nxd_ip_address.v6[3] = GROUP_ADDRESS_3; + transport_ptr -> multicast_ttl = TEST_TTL; + + if (strstr(uri, "trackID=0")) + { + transport_ptr -> client_rtp_port = RTP_VIDEO_RTP_PORT; + transport_ptr -> client_rtcp_port = RTP_VIDEO_RTCP_PORT; + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_SESSION_ID; + } + else if (strstr(uri, "trackID=1")) + { + transport_ptr -> client_rtp_port = RTP_AUDIO_RTP_PORT; + transport_ptr -> client_rtcp_port = RTP_AUDIO_RTCP_PORT; + } + else + { + status = NX_RTSP_SERVER_INVALID_REQUEST; + } + + return(status); +} + +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ +UINT status; + + /* Retrieve the sequence number through rtp sender functions */ + nx_rtp_sender_session_sequence_number_get(&rtp_session_video, &video_seq); + nx_rtp_sender_session_sequence_number_get(&rtp_session_audio, &audio_seq); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, video_seq, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=1", sizeof("trackID=1") - 1, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_play); + + return(status); +} + +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + + nx_rtp_sender_session_delete(&rtp_session_video); + nx_rtp_sender_session_delete(&rtp_session_audio); + + return(NX_SUCCESS); +} + +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr) +{ + return(NX_SUCCESS); +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_rtp_multicast_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP Multicast Test...................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/rtsp_test/netx_rtsp_rtp_multicast_test.c b/test/regression/rtsp_test/netx_rtsp_rtp_multicast_test.c new file mode 100644 index 00000000..963f8bbc --- /dev/null +++ b/test/regression/rtsp_test/netx_rtsp_rtp_multicast_test.c @@ -0,0 +1,886 @@ +/* This case tests RTSP with RTP in multicast mode. */ +#include "tx_api.h" +#include "nx_api.h" +#include "netxtestcontrol.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) +#include "nx_rtp_sender.h" +#include "nx_rtsp_server.h" + +#define DEMO_STACK_SIZE 4096 +#define PACKET_SIZE 1536 + +/* Define device drivers. */ +extern void _nx_ram_network_driver_1024(NX_IP_DRIVER *driver_req_ptr); + +static UCHAR rtsp_stack[DEMO_STACK_SIZE]; + +static TX_THREAD client_thread_0; +static NX_PACKET_POOL client_pool_0; +static NX_IP client_ip_0; +static NX_TCP_SOCKET rtsp_client_0; +static NX_UDP_SOCKET rtp_client_0; + +static TX_THREAD client_thread_1; +static NX_PACKET_POOL client_pool_1; +static NX_IP client_ip_1; +static NX_TCP_SOCKET rtsp_client_1; +static NX_UDP_SOCKET rtp_client_1; + +static TX_THREAD server_thread; +static NX_PACKET_POOL server_pool; +static NX_IP server_ip; +static NX_RTSP_SERVER rtsp_server; +static NX_RTP_SENDER rtp_server; +static NX_RTP_SESSION rtp_session_video; +static NX_RTP_SESSION rtp_session_audio; + +static UINT error_counter; + +static UINT connected_client_num = 0; + +static TX_SEMAPHORE semaphore_server_start; +static TX_SEMAPHORE semaphore_client_0_done; +static TX_SEMAPHORE semaphore_client_1_done; +static TX_SEMAPHORE semaphore_play; +static TX_SEMAPHORE semaphore_rtp_send; + +static void thread_client_0_entry(ULONG thread_input); +static void thread_client_1_entry(ULONG thread_input); +static void thread_server_entry(ULONG thread_input); +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr); +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length); +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length); +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length); +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr); + +#define TEST_MULTICAST_ADDRESS IP_ADDRESS(224, 1, 0, 55) +#define TEST_SERVER_ADDRESS IP_ADDRESS(1,2,3,4) +#define TEST_CLIENT_0_ADDRESS IP_ADDRESS(1,2,3,5) +#define TEST_CLIENT_1_ADDRESS IP_ADDRESS(1,2,3,6) +#define RTSP_SERVER_PORT 554 + +#define RTSP_SESSION_ID 23754311 +#define RTP_VIDEO_RTP_PORT 49752 +#define RTP_VIDEO_RTCP_PORT 49753 +#define RTP_AUDIO_RTP_PORT 49754 +#define RTP_AUDIO_RTCP_PORT 49755 + +#define RTP_PAYLOAD_TYPE_VIDEO 96 +#define RTP_PAYLOAD_TYPE_AUDIO 97 +#define RTP_TIMESTAMP_INIT_VALUE 40 +#define CNAME "AzureRTOS@microsoft.com" +#define TEST_MSW 123 +#define TEST_LSW 456 +#define TEST_TTL 128 + +static UCHAR rtsp_option_request[] = "\ +OPTIONS rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 2\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\r\n\ +"; + +static UCHAR rtsp_describe_request[] = "\ +DESCRIBE rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 3\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Accept: application/sdp\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_0[] = "\ +SETUP rtsp://1.2.3.4:554/live.stream/trackID=0 RTSP/1.0\r\n\ +CSeq: 4\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;multicast;port=49752-49753\r\n\r\n\ +"; + +static UCHAR rtsp_setup_request_1[] = "\ +SETUP rtsp://1.2.3.4:554/live.stream/trackID=1 RTSP/1.0\r\n\ +CSeq: 5\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Transport: RTP/AVP;multicast;port=49754-49755\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_play_request[] = "\ +PLAY rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 6\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\ +Range: npt=0.000-\r\n\r\n\ +"; + +static UCHAR rtsp_pause_request[] = "\ +PAUSE rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 7\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +static UCHAR rtsp_teardown_request[] = "\ +TEARDOWN rtsp://1.2.3.4:554/live.stream RTSP/1.0\r\n\ +CSeq: 8\r\n\ +User-Agent: LibVLC/3.0.17.4 (LIVE555 Streaming Media v2016.11.28)\r\n\ +Session: 23754311\r\n\r\n\ +"; + +typedef enum +{ + OPTION_INDEX, + DESCRIBE_INDEX, + SETUP_0_INDEX, + SETUP_1_INDEX, + PLAY_INDEX, + PAUSE_INDEX, + TEARDOWN_INDEX +}REQUEST_INDEX; + +static UCHAR *rtsp_request_list[] = +{ +rtsp_option_request, +rtsp_describe_request, +rtsp_setup_request_0, +rtsp_setup_request_1, +rtsp_play_request, +rtsp_pause_request, +rtsp_teardown_request, +}; + +static UINT rtsp_request_size[] = +{ +sizeof(rtsp_option_request) - 1, +sizeof(rtsp_describe_request) - 1, +sizeof(rtsp_setup_request_0) - 1, +sizeof(rtsp_setup_request_1) - 1, +sizeof(rtsp_play_request) - 1, +sizeof(rtsp_pause_request) - 1, +sizeof(rtsp_teardown_request) - 1, +}; + +static UINT rtsp_request_num = sizeof(rtsp_request_size) / sizeof(UINT); + +static UCHAR rtp_data[] = "rtp data for test"; + +static CHAR *sdp="v=0\r\ns=MPEG-1 or 2 Audio, streamed by the NetX RTSP Server\r\n\ +m=video 6002 RTP/AVP 96\r\n\ +c=IN IP4 224.1.0.1/20\r\n\ +a=rtpmap:96 H264/90000\r\n\ +a=fmtp:96 profile-level-id=42A01E; packetization-mode=1\r\n\ +a=control:trackID=0\r\n\ +m=audio 6002 RTP/AVP 97\r\n\ +c=IN IP4 224.1.0.1/20\r\n\ +a=rtpmap:97 mpeg4-generic/44100/1\r\n\ +a=fmtp:97 SizeLength=13\r\n\ +a=control:trackID=1\r\n"; + +static UINT video_seq = 0, audio_seq = 0; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_rtp_multicast_test_application_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + + error_counter = 0; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create a helper thread for the server. */ + tx_thread_create(&server_thread, "Test Server thread", thread_server_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create the server packet pool. */ + status = nx_packet_pool_create(&server_pool, "Test Server Packet Pool", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&server_ip, "Test Server IP", TEST_SERVER_ADDRESS, + 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + /* Enable ARP and supply ARP cache memory for the server IP instance. */ + status = nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&server_ip); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread_0, "Test Client 0", thread_client_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool_0, "Test Client Packet Pool 0", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip_0, "Test Client IP 0", TEST_CLIENT_0_ADDRESS, + 0xFFFFFF00UL, &client_pool_0, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip_0); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&client_ip_0); + CHECK_STATUS(0, status); + + /* Create the Test Client thread. */ + status = tx_thread_create(&client_thread_1, "Test Client 1", thread_client_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 6, 6, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + CHECK_STATUS(0, status); + + /* Create the Client packet pool. */ + status = nx_packet_pool_create(&client_pool_1, "Test Client Packet Pool 1", PACKET_SIZE, + pointer, PACKET_SIZE * 8); + pointer = pointer + PACKET_SIZE * 8; + CHECK_STATUS(0, status); + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip_1, "Test Client IP 1", TEST_CLIENT_1_ADDRESS, + 0xFFFFFF00UL, &client_pool_1, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + CHECK_STATUS(0, status); + + status = nx_arp_enable(&client_ip_1, (void *) pointer, 1024); + pointer = pointer + 1024; + CHECK_STATUS(0, status); + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip_1); + CHECK_STATUS(0, status); + + /* Enable UDP processing for both IP instances. */ + status = nx_udp_enable(&client_ip_1); + CHECK_STATUS(0, status); + + /* Create semaphores. */ + tx_semaphore_create(&semaphore_server_start, "semaphore server start", 0); + tx_semaphore_create(&semaphore_client_0_done, "semaphore client 0 done", 0); + tx_semaphore_create(&semaphore_client_1_done, "semaphore client 1 done", 0); + tx_semaphore_create(&semaphore_play, "semaphore play", 0); + tx_semaphore_create(&semaphore_rtp_send, "semaphore rtp send", 0); +} + +void thread_client_0_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Enable IGMP & join in multicast group. */ + status = nx_igmp_enable(&client_ip_0); + status = nx_igmp_multicast_join(&client_ip_0, TEST_MULTICAST_ADDRESS); + CHECK_STATUS(0, status); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_ip_0, &rtsp_client_0, "Test Client Socket 0", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client_0, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&client_ip_0, &rtp_client_0, "RTCP Client Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_0, RTP_VIDEO_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_0, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool_0, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list[i], rtsp_request_size[i], &client_pool_0, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client_0, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client_0, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_0_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;multicast;destination=224.1.0.55;port=%d-%d;ttl=%d", + RTP_VIDEO_RTP_PORT, RTP_VIDEO_RTCP_PORT, TEST_TTL); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_1_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;multicast;destination=224.1.0.55;port=%d-%d;ttl=%d", + RTP_AUDIO_RTP_PORT, RTP_AUDIO_RTCP_PORT, TEST_TTL); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://1.2.3.4:554/live.stream/trackID=0;seq=%d;rtptime=%d,url=rtsp://1.2.3.4:554/live.stream/trackID=1;seq=%d;rtptime=%d", + video_seq, RTP_TIMESTAMP_INIT_VALUE, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, "Range: npt=0.0-", sizeof("Range: npt=0.0-") - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + tx_semaphore_get(&semaphore_rtp_send, NX_WAIT_FOREVER); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_0, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PAUSE_INDEX) + { + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Range"); + if (buffer_ptr != NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + + tx_thread_sleep(2); + } + + nx_tcp_socket_disconnect(&rtsp_client_0, NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_0_done); + nx_tcp_client_socket_unbind(&rtsp_client_0); + nx_tcp_socket_delete(&rtsp_client_0); +} + +void thread_client_1_entry(ULONG thread_input) +{ +UINT i, status; +NX_PACKET *packet_ptr; +NXD_ADDRESS server_ip_address; +UCHAR *buffer_ptr; +UCHAR temp_string[256]; + + + /* Give IP task and driver a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Enable IGMP & join in multicast group. */ + status = nx_igmp_enable(&client_ip_1); + status = nx_igmp_multicast_join(&client_ip_1, TEST_MULTICAST_ADDRESS); + CHECK_STATUS(0, status); + + /* Set server IP address. */ + server_ip_address.nxd_ip_address.v4 = TEST_SERVER_ADDRESS; + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + + status = nx_tcp_socket_create(&client_ip_1, &rtsp_client_1, "Test Client Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1000, + NX_NULL, NX_NULL); + CHECK_STATUS(0, status); + + /* Bind and connect to server. */ + status = nx_tcp_client_socket_bind(&rtsp_client_1, NX_ANY_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Create the rtp client socket. */ + status = nx_udp_socket_create(&client_ip_1, &rtp_client_1, "RTCP Client Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + CHECK_STATUS(0, status); + + status = nx_udp_socket_bind(&rtp_client_1, RTP_VIDEO_RTP_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Wait test server started. */ + tx_semaphore_get(&semaphore_server_start, NX_WAIT_FOREVER); + + status = nxd_tcp_client_socket_connect(&rtsp_client_1, &server_ip_address, RTSP_SERVER_PORT, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + for ( i = 0; i < rtsp_request_num; i++) + { + + /* Send RTSP request data. */ + status = nx_packet_allocate(&client_pool_1, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_packet_data_append(packet_ptr, rtsp_request_list[i], rtsp_request_size[i], &client_pool_1, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + status = nx_tcp_socket_send(&rtsp_client_1, packet_ptr, NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Receive the response from RTSP server. */ + status = nx_tcp_socket_receive(&rtsp_client_1, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Check response status code. */ + status = memcmp(packet_ptr -> nx_packet_prepend_ptr, "RTSP/1.0 200 OK", sizeof("RTSP/1.0 200 OK") - 1); + CHECK_STATUS(0, status); + + /* Terminate the string. */ + *(packet_ptr -> nx_packet_append_ptr) = NX_NULL; + memset(temp_string, 0, sizeof(temp_string)); + + if (i == DESCRIBE_INDEX) + { + + /* Check the SDP. */ + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "\r\n\r\n"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr + 4, sdp, sizeof(sdp) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_0_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;multicast;destination=224.1.0.55;port=%d-%d;ttl=%d", + RTP_VIDEO_RTP_PORT, RTP_VIDEO_RTCP_PORT, TEST_TTL); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == SETUP_1_INDEX) + { + + sprintf(temp_string, "Transport: RTP/AVP;multicast;destination=224.1.0.55;port=%d-%d;ttl=%d", + RTP_AUDIO_RTP_PORT, RTP_AUDIO_RTCP_PORT, TEST_TTL); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "Transport"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else if (i == PLAY_INDEX) + { + + sprintf(temp_string, + "RTP-Info: url=rtsp://1.2.3.4:554/live.stream/trackID=0;seq=%d;rtptime=%d,url=rtsp://1.2.3.4:554/live.stream/trackID=1;seq=%d;rtptime=%d", + video_seq, RTP_TIMESTAMP_INIT_VALUE, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + + buffer_ptr = strstr(packet_ptr -> nx_packet_prepend_ptr, "RTP-Info"); + if (buffer_ptr == NX_NULL) + { + error_counter++; + CHECK_STATUS(0, error_counter); + } + + status = memcmp(buffer_ptr, temp_string, strlen(temp_string)); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + + tx_semaphore_get(&semaphore_rtp_send, NX_WAIT_FOREVER); + + /* Receive rtp data packet. */ + status = nx_udp_socket_receive(&rtp_client_1, &packet_ptr, 5 * TX_TIMER_TICKS_PER_SECOND); + CHECK_STATUS(0, status); + + status = memcmp(packet_ptr -> nx_packet_prepend_ptr + 12, rtp_data, sizeof(rtp_data) - 1); + CHECK_STATUS(0, status); + + nx_packet_release(packet_ptr); + } + else + { + nx_packet_release(packet_ptr); + } + + tx_thread_sleep(2); + } + + nx_tcp_socket_disconnect(&rtsp_client_1, NX_IP_PERIODIC_RATE); + + /* Set the flag. */ + tx_semaphore_put(&semaphore_client_1_done); + nx_tcp_client_socket_unbind(&rtsp_client_1); + nx_tcp_socket_delete(&rtsp_client_1); +} + +/* Define the helper Test server thread. */ +void thread_server_entry(ULONG thread_input) +{ +UINT status; +NX_PACKET *packet_ptr; +NXD_ADDRESS client_ip_address; + + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP Multicast Test..................................."); + + /* Check for earlier error. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give NetX a chance to initialize the system. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Enable IGMP & join in multicast group. */ + status = nx_igmp_enable(&server_ip); + status = nx_igmp_multicast_join(&server_ip, TEST_MULTICAST_ADDRESS); + CHECK_STATUS(0, status); + + /* Create RTSP server. */ + status = nx_rtsp_server_create(&rtsp_server, "RTSP Server", sizeof("RTSP Server") - 1,&server_ip, &server_pool, rtsp_stack, DEMO_STACK_SIZE, 3, RTSP_SERVER_PORT, rtsp_disconnect_callback); + CHECK_STATUS(0, status); + + /* Set callback functions. */ + nx_rtsp_server_describe_callback_set(&rtsp_server, rtsp_describe_callback); + nx_rtsp_server_setup_callback_set(&rtsp_server, rtsp_setup_callback); + nx_rtsp_server_play_callback_set(&rtsp_server, rtsp_play_callback); + nx_rtsp_server_teardown_callback_set(&rtsp_server, rtsp_teardown_callback); + nx_rtsp_server_pause_callback_set(&rtsp_server, rtsp_pause_callback); + nx_rtsp_server_set_parameter_callback_set(&rtsp_server, rtsp_set_parameter_callback); + + /* Create RTP sender. */ + status = nx_rtp_sender_create(&rtp_server, &server_ip, &server_pool, CNAME, sizeof(CNAME) - 1); + CHECK_STATUS(0, status); + + /* Setup rtp sender session. */ + client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + client_ip_address.nxd_ip_address.v4 = TEST_MULTICAST_ADDRESS; + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_video, RTP_PAYLOAD_TYPE_VIDEO, + 0, &client_ip_address, + RTP_VIDEO_RTP_PORT, RTP_VIDEO_RTCP_PORT); + CHECK_STATUS(0, status); + + status = nx_rtp_sender_session_create(&rtp_server, &rtp_session_audio, RTP_PAYLOAD_TYPE_VIDEO, + 0, &client_ip_address, + RTP_AUDIO_RTP_PORT, RTP_AUDIO_RTCP_PORT); + CHECK_STATUS(0, status); + + /* Start RTSP server. */ + nx_rtsp_server_start(&rtsp_server); + + tx_semaphore_put(&semaphore_server_start); + tx_semaphore_put(&semaphore_server_start); + + tx_semaphore_get(&semaphore_play, NX_WAIT_FOREVER); + + /* Allocate a packet */ + status = nx_rtp_sender_session_packet_allocate(&rtp_session_video, &packet_ptr, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Copy payload data into the packet. */ + status = nx_packet_data_append(packet_ptr, rtp_data, sizeof(rtp_data) - 1, rtp_server.nx_rtp_sender_ip_ptr -> nx_ip_default_packet_pool, 5 * NX_IP_PERIODIC_RATE); + CHECK_STATUS(0, status); + + /* Send packet. */ + status = nx_rtp_sender_session_packet_send(&rtp_session_video, packet_ptr, RTP_TIMESTAMP_INIT_VALUE, TEST_MSW, TEST_LSW, 1); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_rtp_send); + tx_semaphore_put(&semaphore_rtp_send); + + tx_semaphore_get(&semaphore_client_0_done, NX_WAIT_FOREVER); + tx_semaphore_get(&semaphore_client_1_done, NX_WAIT_FOREVER); + + status = nx_rtsp_server_delete(&rtsp_server); + CHECK_STATUS(0, status); + + /* Check packet pool. */ + if (server_pool.nx_packet_pool_available != server_pool.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool_0.nx_packet_pool_available != client_pool_0.nx_packet_pool_total) + { + error_counter++; + } + + if (client_pool_1.nx_packet_pool_available != client_pool_1.nx_packet_pool_total) + { + error_counter++; + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +static UINT rtsp_describe_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ +UINT status; + + status = nx_rtsp_server_sdp_set(rtsp_client_ptr, sdp, strlen(sdp)); + return(status); +} + +static UINT rtsp_setup_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, NX_RTSP_TRANSPORT *transport_ptr) +{ +UINT status; +UINT rtp_port, rtcp_port; + + /* Get the created and found ports */ + status = nx_rtp_sender_port_get(&rtp_server, &rtp_port, &rtcp_port); + if (status) + { + return(status); + } + transport_ptr -> server_rtp_port = rtp_port; + transport_ptr -> server_rtcp_port = rtcp_port; + + transport_ptr -> client_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + transport_ptr -> client_ip_address.nxd_ip_address.v4 = TEST_MULTICAST_ADDRESS; + transport_ptr -> multicast_ttl = TEST_TTL; + + if (strstr(uri, "trackID=0")) + { + transport_ptr -> client_rtp_port = RTP_VIDEO_RTP_PORT; + transport_ptr -> client_rtcp_port = RTP_VIDEO_RTCP_PORT; + + /* Set static session ID for test. */ + rtsp_client_ptr -> nx_rtsp_client_session_id = RTSP_SESSION_ID; + + connected_client_num++; + } + else if (strstr(uri, "trackID=1")) + { + transport_ptr -> client_rtp_port = RTP_AUDIO_RTP_PORT; + transport_ptr -> client_rtcp_port = RTP_AUDIO_RTCP_PORT; + } + else + { + status = NX_RTSP_SERVER_INVALID_REQUEST; + } + + return(status); +} + +static UINT rtsp_play_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ +UINT status; + + /* Retrieve the sequence number through rtp sender functions */ + nx_rtp_sender_session_sequence_number_get(&rtp_session_video, &video_seq); + nx_rtp_sender_session_sequence_number_get(&rtp_session_audio, &audio_seq); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=0", sizeof("trackID=0") - 1, video_seq, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + status = nx_rtsp_server_rtp_info_set(rtsp_client_ptr, "trackID=1", sizeof("trackID=1") - 1, audio_seq, RTP_TIMESTAMP_INIT_VALUE); + CHECK_STATUS(0, status); + + tx_semaphore_put(&semaphore_play); + + return(status); +} + +static UINT rtsp_teardown_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length) +{ + if (connected_client_num > 0) + { + connected_client_num--; + if (connected_client_num == 0) + { + nx_rtp_sender_session_delete(&rtp_session_video); + nx_rtp_sender_session_delete(&rtp_session_audio); + } + } + + return(NX_SUCCESS); +} + +static UINT rtsp_pause_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *range_ptr, UINT range_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_set_parameter_callback(NX_RTSP_CLIENT *rtsp_client_ptr, UCHAR *uri, UINT uri_length, UCHAR *parameter_ptr, ULONG parameter_length) +{ + return(NX_SUCCESS); +} + +static UINT rtsp_disconnect_callback(NX_RTSP_CLIENT *rtsp_client_ptr) +{ + return(NX_SUCCESS); +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_rtsp_rtp_multicast_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: RTSP RTP Multicast Test...................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/smtp_test/netx_smtp_abnormal_packet_test.c b/test/regression/smtp_test/netx_smtp_abnormal_packet_test.c new file mode 100644 index 00000000..ddd21517 --- /dev/null +++ b/test/regression/smtp_test/netx_smtp_abnormal_packet_test.c @@ -0,0 +1,515 @@ +/* This tests processing abnormal packet. */ + + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_smtp_client.h" +#else +#include "nx_smtp_client.h" +#endif + +#define DEMO_STACK_SIZE 2048 +#define SERVER_IPADR IP_ADDRESS(10, 0, 0, 1) +#define CLIENT_IPADR IP_ADDRESS(10, 0, 0, 10) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_PACKET_POOL server_packet_pool; +static NX_TCP_SOCKET server_socket; +static NX_SMTP_CLIENT smtp_client; + +#define SUBJECT_LINE "NetX Duo SMTP Client Demo" +#define MAIL_BODY ".NetX Duo SMTP client is a simple SMTP client implementation \r\n" \ + ".that allow embedded devices to send email to an SMTP server. \r\n" \ + "This feature is intended to allow a device to send simple status\r\n " \ + "reports using the most universal Internet application email.\r\n" \ + "The rest of this narrative is merely to supply this most interesting quote: \r\n" \ + "Perhaps the most vivid recollection of my youth is that of the local wheelmen, \r\n" \ + "led by my father, stopping at our home to eat pone, sip mint juleps, and flog \r\n" \ + "the field hands. This more than anything cultivated my life-long aversion \r\n" \ + "to bicycles. ~~ Tennessee Williams.\r\n\r\n" \ + "Nothing compares to the simple pleasure of a bike ride. --John F. Kennedy, (surely you've heard of him?)\r\n\r\n" \ + "Perhaps the most vivid recollection of my youth is that of being flogged \r\n" \ + "by the local wheelmen, along with the field hands, the postman, and a \r\n" \ + "young Tennessee Williams. This more than anything cultivated my life-long " \ + "aversion to his plays. -Truman Capote\r\n" \ + "When I see an adult on a bicycle, I do not despair for the future of the human race. H.G. Wells \r\n" \ + "during the Second World War, if the United States had retooled its \r\n" \ + "factories for manufacturing bicycles instead of munitions, we'd be one of \r\n" \ + "the healthiest, least oil-dependent, and most environmentally-sound \r\n" \ + "constituents in the Nazi empire today. -Ralph Nader." + + +#define PASSWORD "testpwd" +#define RECIPIENT_ADDRESS "recipient@domain.com" +#define LOCAL_DOMAIN "domain.com" +#define FROM_ADDRESS "recipient@domain.com" +#define USERNAME FROM_ADDRESS +#define SMTP_SERVER_PORT 25 + + +/* See the NetX Duo SMTP Client User Guide for how to set the authentication type. */ +#define CLIENT_AUTHENTICATION_TYPE NX_SMTP_CLIENT_AUTH_PLAIN + +#if defined(__PRODUCT_NETXDUO__) +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static UINT server_complete = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr); + +/* SMTP Tests. */ +static void smtp_test_initialize(); + +/* Send SMTP server response. */ +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT packet_number); + +extern char response_221_bye_pkt[80]; +extern int response_221_bye_size; + +static char invliad_response_220_greetings_pkt[] = { +0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, /* ...v..22 */ +0x30, 0x2d, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, /* 0-expres */ +0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, /* slogic.c */ +0x6f, 0x6d, 0x20, 0x45, 0x53, 0x4d, 0x54, 0x50, /* om ESMTP */ +0x20, 0x4d, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, /* MDaemon */ +0x20, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x33, 0x3b, /* 13.0.3; */ +0x20, 0x53, 0x61, 0x74, 0x2c, 0x20, 0x32, 0x33, /* Sat, 23 */ +0x20, 0x4d, 0x61, 0x72, 0x20, 0x32, 0x30, 0x31, /* Mar 201 */ +0x33, 0x20, 0x32, 0x32, 0x3a, 0x35, 0x38, 0x3a, /* 3 22:58: */ +0x31, 0x35, 0x20, 0x2d, 0x30, 0x37, 0x30, 0x30, /* 15 -0700 */ +0x0d, 0x0a, 0x32, 0x32, 0x30, 0x2d, 0x41, 0x6c, /* ..220-Al */ +0x6c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, /* l transa */ +0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, /* ctions a */ +0x6e, 0x64, 0x20, 0x49, 0x50, 0x20, 0x61, 0x64, /* nd IP ad */ +0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20, /* dresses */ +0x61, 0x72, 0x65, 0x20, 0x6c, 0x6f, 0x67, 0x67, /* are logg */ +0x65, 0x64, 0x2e, 0x0d, 0x0a, 0x32, 0x32, 0x30, /* ed...220 */ +0x2d, 0x2a, 0x0d, 0x0a, 0x32, 0x32, 0x30, 0x20, /* -*..220 */ +0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, /* Unauthor */ +0x69, 0x7a, 0x65, 0x64, 0x20, 0x72, 0x65, 0x6c, /* ized rel */ +0x61, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, /* aying is */ +0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x6c, /* strictl */ +0x79, 0x20, 0x70, 0x72, 0x6f, 0x68, 0x69, 0x62, /* y prohib */ +0x69, 0x74, 0x65, 0x64, 0x2e, 0x0d, 0x0a /* ited... */ +}; + +typedef struct SMTP_TEST_STRUCT +{ + char *smtp_test_pkt_data; + int smtp_test_pkt_size; +} SMTP_TEST; + + +static UINT msg_count = 0; + +static SMTP_TEST smtp_test[9]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SMTP client thread. */ + tx_thread_create(&thread_client, "thread client", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_server, "thread server", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "SMTP CLient IP", CLIENT_IPADR, 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "SMTP Server IP", SERVER_IPADR, 0xFFFFFF00UL, &server_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + status += nx_tcp_enable(&server_ip); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; + + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + +#if defined(__PRODUCT_NETXDUO__) + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + server_ip_address.nxd_ip_address.v4 = SERVER_IPADR; + + status = nxd_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + &server_ip_address, SMTP_SERVER_PORT); +#else + server_ip_address = SERVER_IPADR; + + status = nx_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + server_ip_address, SMTP_SERVER_PORT); +#endif + + if (status != NX_SUCCESS) + { + error_counter++; + } + + return; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG actual_status; +UINT wait_timeout = 300; + + + printf("NetX Test: SMTP Abnormal Packet Test................................."); + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&client_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the server get set up first. */ + tx_thread_sleep(20); + + + /* The SMTP test initialize. */ + smtp_test_initialize(); + + /* Create a mail instance with the above text message and recipient info. */ + status = nx_smtp_mail_send(&smtp_client, RECIPIENT_ADDRESS, NX_SMTP_MAIL_PRIORITY_NORMAL, + SUBJECT_LINE, MAIL_BODY, strlen(MAIL_BODY)); + + /* Create a mail instance with the above text message and recipient info. */ + + /* Check for errors. */ + if (status == NX_SUCCESS) + { + error_counter++; + } + + /* Give the server time to disconnect. */ + while(wait_timeout) + { + + if (server_complete) + break; + + tx_thread_sleep(20); + + wait_timeout -= 20; + } + + /* Release threadx resources used by client. */ + status = nx_smtp_client_delete(&smtp_client); + + /* Return the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* This thread task simulates SMTP server response to client requests. */ +static void thread_1_entry(ULONG thread_input) +{ + +UINT i; +ULONG actual_status; +NX_PACKET *my_packet; + + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the SMTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 8000, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the SMTP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SMTP_SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Act as the SMTP server to receive the SMTP Client query and send the SMTP response. */ + for (i = 0; i < msg_count; i++) + { + + if (i != 0) + { + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 10 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + continue; + } + + /* Release the packet. */ + nx_packet_release(my_packet); + } + + /* Send the SMTP response packet. */ + status = nx_smtp_response_packet_send(&server_socket, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Wait for Client process last message. */ + tx_thread_sleep(20); + + /* Unlisten and Unbind the TCP socket. */ + + status = nx_tcp_server_socket_unaccept(&server_socket); + status += nx_tcp_server_socket_unlisten(&server_ip, SMTP_SERVER_PORT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + server_complete = NX_TRUE; + +} + +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, 200); + + /* Check status. */ + if (status) + { + error_counter++; + return status; + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + smtp_test[packet_number].smtp_test_pkt_data, + smtp_test[packet_number].smtp_test_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = smtp_test[packet_number].smtp_test_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static void smtp_test_initialize() +{ + smtp_test[msg_count].smtp_test_pkt_data = &invliad_response_220_greetings_pkt[0]; + smtp_test[msg_count++].smtp_test_pkt_size = sizeof(invliad_response_220_greetings_pkt); + + smtp_test[msg_count].smtp_test_pkt_data = &response_221_bye_pkt[0]; + smtp_test[msg_count++].smtp_test_pkt_size = response_221_bye_size; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SMTP Abnormal Packet Test.................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/smtp_test/netx_smtp_auth_logon_function_test.c b/test/regression/smtp_test/netx_smtp_auth_logon_function_test.c new file mode 100644 index 00000000..50e82e87 --- /dev/null +++ b/test/regression/smtp_test/netx_smtp_auth_logon_function_test.c @@ -0,0 +1,591 @@ +/* This NetX test concentrates on the basic SMTP operation. The Server supports + auth login, auth plain and will send a one packet response to the EHLO message. The Client + then authenticates itself by AUTH LOGIN, sends a message of three packets, and quits. */ + + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_smtp_client.h" +#else +#include "nx_smtp_client.h" +#endif + +#define DEMO_STACK_SIZE 2048 +#define SERVER_IPADR IP_ADDRESS(10, 0, 0, 1) +#define CLIENT_IPADR IP_ADDRESS(10, 0, 0, 10) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_PACKET_POOL server_packet_pool; +static NX_TCP_SOCKET server_socket; +static NX_SMTP_CLIENT smtp_client; + +#define SUBJECT_LINE "NetX Duo SMTP Client Demo" +#define MAIL_BODY ".NetX Duo SMTP client is a simple SMTP client implementation \r\n" \ + ".that allow embedded devices to send email to an SMTP server. \r\n" \ + "This feature is intended to allow a device to send simple status\r\n " \ + "reports using the most universal Internet application email.\r\n" \ + "The rest of this narrative is merely to supply this most interesting quote: \r\n" \ + "Perhaps the most vivid recollection of my youth is that of the local wheelmen, \r\n" \ + "led by my father, stopping at our home to eat pone, sip mint juleps, and flog \r\n" \ + "the field hands. This more than anything cultivated my life-long aversion \r\n" \ + "to bicycles. ~~ Tennessee Williams.\r\n\r\n" \ + "Nothing compares to the simple pleasure of a bike ride. --John F. Kennedy, (surely you've heard of him?)\r\n\r\n" \ + "Perhaps the most vivid recollection of my youth is that of being flogged \r\n" \ + "by the local wheelmen, along with the field hands, the postman, and a \r\n" \ + "young Tennessee Williams. This more than anything cultivated my life-long " \ + "aversion to his plays. -Truman Capote\r\n" \ + "When I see an adult on a bicycle, I do not despair for the future of the human race. H.G. Wells \r\n" \ + "during the Second World War, if the United States had retooled its \r\n" \ + "factories for manufacturing bicycles instead of munitions, we'd be one of \r\n" \ + "the healthiest, least oil-dependent, and most environmentally-sound \r\n" \ + "constituents in the Nazi empire today. -Ralph Nader." + + +#define PASSWORD "testpwd" +#define RECIPIENT_ADDRESS "recipient@domain.com" +#define LOCAL_DOMAIN "domain.com" +#define FROM_ADDRESS "recipient@domain.com" +#define USERNAME FROM_ADDRESS +#define SMTP_SERVER_PORT 25 + + +/* See the NetX Duo SMTP Client User Guide for how to set the authentication type. */ +#define CLIENT_AUTHENTICATION_TYPE NX_SMTP_CLIENT_AUTH_LOGIN + +#if defined(__PRODUCT_NETXDUO__) +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static UINT server_complete = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr); + +/* SMTP Tests. */ +static void smtp_test_initialize(); + +/* Send SMTP server response. */ +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number); + +extern char response_220_greetings_pkt[185]; +extern int response_220_greetings_size; + +/* This is the one packet 250 EHLO message */ +extern char response_250_ehlo_pkt[145]; +extern int response_250_ehlo_size; + +extern char response_334_username_pkt[18]; +extern int response_334_username_size; + +extern char response_334_password_pkt[18]; +extern int response_334_password_size; + +extern char response_235_auth_passed_pkt[85]; +extern int response_235_auth_passed_size; + +extern char response_250_sender_ok_pkt[40]; +extern int response_250_sender_ok_size; + +extern char response_250_recipient_ok_pkt[43]; +extern int response_250_recipient_ok_size; + +extern char response_354_enter_mail_pkt[40]; +extern int response_354_enter_mail_size; + +extern char response_250_message_saved_pkt[92]; +extern int response_250_message_saved_size; + +extern char response_221_bye_pkt[80]; +extern int response_221_bye_size; + + +typedef struct SMTP_TEST_STRUCT +{ + char *smtp_test_pkt_data; + int smtp_test_pkt_size; +} SMTP_TEST; + + +#define MSG_COUNT 10 + +static SMTP_TEST smtp_test[MSG_COUNT]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_auth_logon_function_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SMTP client thread. */ + tx_thread_create(&thread_client, "thread client", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_server, "thread server", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "SMTP CLient IP", CLIENT_IPADR, 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "SMTP Server IP", SERVER_IPADR, 0xFFFFFF00UL, &server_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + status += nx_tcp_enable(&server_ip); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; + + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + +#if defined(__PRODUCT_NETXDUO__) + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + server_ip_address.nxd_ip_address.v4 = SERVER_IPADR; + + status = nxd_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + &server_ip_address, SMTP_SERVER_PORT); +#else + server_ip_address = SERVER_IPADR; + + status = nx_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + server_ip_address, SMTP_SERVER_PORT); +#endif + + if (status != NX_SUCCESS) + { + error_counter++; + } + + return; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG actual_status; +UINT wait_timeout = 300; + + + printf("NetX Test: SMTP Auth Logon Function Test............................."); + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&client_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the server get set up first. */ + tx_thread_sleep(20); + + + /* The SMTP test initialize. */ + smtp_test_initialize(); + + /* Create a mail instance with the above text message and recipient info. */ + status = nx_smtp_mail_send(&smtp_client, RECIPIENT_ADDRESS, NX_SMTP_MAIL_PRIORITY_NORMAL, + SUBJECT_LINE, MAIL_BODY, strlen(MAIL_BODY)); + + /* Create a mail instance with the above text message and recipient info. */ + + /* Check for errors. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Give the server time to disconnect. */ + while(wait_timeout) + { + + if (server_complete) + break; + + tx_thread_sleep(20); + + wait_timeout -= 20; + } + + /* Release threadx resources used by client. */ + status = nx_smtp_client_delete(&smtp_client); + + /* Return the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* This thread task simulates SMTP server response to client requests. */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +ULONG port; +ULONG peer_address; +UINT i; +UCHAR *work_ptr; +ULONG actual_status; + + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the SMTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 8000, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the SMTP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SMTP_SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Act as the SMTP server to receive the SMTP Client query and send the SMTP response. */ + for (i = 0; i < MSG_COUNT; i++ ) + { + + if (i == 0) + { + /* This is the greeting, we don't wait for a client response first...*/ + } + else + { + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 100 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + continue; + } + + /* Get the SMTP client TCP port. */ + status = nx_tcp_socket_peer_info_get(&server_socket, &peer_address, &port); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* This is the message data. We need to parse for the End Of Message marker. */ + if (i == 8) + { + /* Look for 0x0D 0x0A 0x2E 0x0d 0x0A indiating end of mail message. */ + work_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length - 5; + + if ((*work_ptr == 0x0D) && + (*(work_ptr + 1) == 0x0A) && + (*(work_ptr + 2) == 0x2E) && + (*(work_ptr + 3) == 0x0D) && + (*(work_ptr + 4) == 0x0A)) + + { + + /* Done iwth message, wait for QUIT command from client. */ + } + else + { + + /* Stay in this state. */ + + i--; + nx_packet_release(my_packet); + continue; + } + } + /* Release the packet. */ + nx_packet_release(my_packet); + } + /* Send the SMTP response packet. */ + status = nx_smtp_response_packet_send(&server_socket, port, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Wait for Client process last message. */ + tx_thread_sleep(20); + + /* Unlisten and Unbind the TCP socket. */ + + status = nx_tcp_server_socket_unaccept(&server_socket); + status += nx_tcp_server_socket_unlisten(&server_ip, SMTP_SERVER_PORT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + server_complete = NX_TRUE; + +} + +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, 200); + + /* Check status. */ + if (status) + { + error_counter++; + return status; + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + smtp_test[packet_number].smtp_test_pkt_data, + smtp_test[packet_number].smtp_test_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = smtp_test[packet_number].smtp_test_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static void smtp_test_initialize() +{ + + smtp_test[0].smtp_test_pkt_data = &response_220_greetings_pkt[0]; + smtp_test[0].smtp_test_pkt_size = response_220_greetings_size; + smtp_test[1].smtp_test_pkt_data = &response_250_ehlo_pkt[0]; + smtp_test[1].smtp_test_pkt_size = response_250_ehlo_size; + smtp_test[2].smtp_test_pkt_data = &response_334_username_pkt[0]; + smtp_test[2].smtp_test_pkt_size = response_334_username_size; + smtp_test[3].smtp_test_pkt_data = &response_334_password_pkt[0]; + smtp_test[3].smtp_test_pkt_size = response_334_password_size; + smtp_test[4].smtp_test_pkt_data = &response_235_auth_passed_pkt[0]; + smtp_test[4].smtp_test_pkt_size = response_235_auth_passed_size; + + smtp_test[5].smtp_test_pkt_data = &response_250_sender_ok_pkt[0]; + smtp_test[5].smtp_test_pkt_size = response_250_sender_ok_size; + smtp_test[6].smtp_test_pkt_data = &response_250_recipient_ok_pkt[0]; + smtp_test[6].smtp_test_pkt_size = response_250_recipient_ok_size; + smtp_test[7].smtp_test_pkt_data = &response_354_enter_mail_pkt[0]; + smtp_test[7].smtp_test_pkt_size = response_354_enter_mail_size; + + smtp_test[8].smtp_test_pkt_data = &response_250_message_saved_pkt[0]; + smtp_test[8].smtp_test_pkt_size = response_250_message_saved_size; + + smtp_test[9].smtp_test_pkt_data = &response_221_bye_pkt[0]; + smtp_test[9].smtp_test_pkt_size = response_221_bye_size; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_auth_logon_function_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SMTP Auth Logon Function Test.............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/smtp_test/netx_smtp_auth_no_type_function_test.c b/test/regression/smtp_test/netx_smtp_auth_no_type_function_test.c new file mode 100644 index 00000000..2dd4db63 --- /dev/null +++ b/test/regression/smtp_test/netx_smtp_auth_no_type_function_test.c @@ -0,0 +1,586 @@ +/* This NetX test concentrates on the basic SMTP operation. The Server supports + auth login, auth plain and will send a one packet response to the EHLO message. The Client + then authenticates itself by AUTH LOGIN, sends a message of three packets, and quits. */ + + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_smtp_client.h" +#else +#include "nx_smtp_client.h" +#endif + +#define DEMO_STACK_SIZE 2048 +#define SERVER_IPADR IP_ADDRESS(10, 0, 0, 1) +#define CLIENT_IPADR IP_ADDRESS(10, 0, 0, 10) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_PACKET_POOL server_packet_pool; +static NX_TCP_SOCKET server_socket; +static NX_SMTP_CLIENT smtp_client; + +#define SUBJECT_LINE "NetX Duo SMTP Client Demo" +#define MAIL_BODY ".NetX Duo SMTP client is a simple SMTP client implementation \r\n" \ + ".that allow embedded devices to send email to an SMTP server. \r\n" \ + "This feature is intended to allow a device to send simple status\r\n " \ + "reports using the most universal Internet application email.\r\n" \ + "The rest of this narrative is merely to supply this most interesting quote: \r\n" \ + "Perhaps the most vivid recollection of my youth is that of the local wheelmen, \r\n" \ + "led by my father, stopping at our home to eat pone, sip mint juleps, and flog \r\n" \ + "the field hands. This more than anything cultivated my life-long aversion \r\n" \ + "to bicycles. ~~ Tennessee Williams.\r\n\r\n" \ + "Nothing compares to the simple pleasure of a bike ride. --John F. Kennedy, (surely you've heard of him?)\r\n\r\n" \ + "Perhaps the most vivid recollection of my youth is that of being flogged \r\n" \ + "by the local wheelmen, along with the field hands, the postman, and a \r\n" \ + "young Tennessee Williams. This more than anything cultivated my life-long " \ + "aversion to his plays. -Truman Capote\r\n" \ + "When I see an adult on a bicycle, I do not despair for the future of the human race. H.G. Wells \r\n" \ + "during the Second World War, if the United States had retooled its \r\n" \ + "factories for manufacturing bicycles instead of munitions, we'd be one of \r\n" \ + "the healthiest, least oil-dependent, and most environmentally-sound \r\n" \ + "constituents in the Nazi empire today. -Ralph Nader." + + +#define PASSWORD "testpwd" +#define RECIPIENT_ADDRESS "recipient@domain.com" +#define LOCAL_DOMAIN "domain.com" +#define FROM_ADDRESS "recipient@domain.com" +#define USERNAME FROM_ADDRESS +#define SMTP_SERVER_PORT 25 + + +/* See the NetX Duo SMTP Client User Guide for how to set the authentication type. */ +#define CLIENT_AUTHENTICATION_TYPE NX_SMTP_CLIENT_AUTH_LOGIN + +#if defined(__PRODUCT_NETXDUO__) +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static UINT server_complete = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr); + +/* SMTP Tests. */ +static void smtp_test_initialize(); + +/* Send SMTP server response. */ +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number); + +extern char response_220_greetings_pkt[185]; +extern int response_220_greetings_size; + +/* This is the one packet 250 EHLO message */ +extern char response_250_ehlo_auth_no_type_pkt[145]; +extern int response_250_ehlo_auth_no_type_size; + +extern char response_334_pkt[6]; +extern int response_334_size; + +extern char response_235_auth_passed_pkt[85]; +extern int response_235_auth_passed_size; + +extern char response_250_sender_ok_pkt[40]; +extern int response_250_sender_ok_size; + +extern char response_250_recipient_ok_pkt[43]; +extern int response_250_recipient_ok_size; + +extern char response_354_enter_mail_pkt[40]; +extern int response_354_enter_mail_size; + +extern char response_250_message_saved_pkt[92]; +extern int response_250_message_saved_size; + +extern char response_221_bye_pkt[80]; +extern int response_221_bye_size; + + +typedef struct SMTP_TEST_STRUCT +{ + char *smtp_test_pkt_data; + int smtp_test_pkt_size; +} SMTP_TEST; + + +#define MSG_COUNT 9 + +static SMTP_TEST smtp_test[MSG_COUNT]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_auth_no_type_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SMTP client thread. */ + tx_thread_create(&thread_client, "thread client", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_server, "thread server", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "SMTP CLient IP", CLIENT_IPADR, 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "SMTP Server IP", SERVER_IPADR, 0xFFFFFF00UL, &server_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + status += nx_tcp_enable(&server_ip); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; + + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + +#if defined(__PRODUCT_NETXDUO__) + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + server_ip_address.nxd_ip_address.v4 = SERVER_IPADR; + + status = nxd_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + &server_ip_address, SMTP_SERVER_PORT); +#else + server_ip_address = SERVER_IPADR; + + status = nx_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + server_ip_address, SMTP_SERVER_PORT); +#endif + + if (status != NX_SUCCESS) + { + error_counter++; + } + + return; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG actual_status; +UINT wait_timeout = 300; + + + printf("NetX Test: SMTP Auth Logon Function Test............................."); + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&client_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the server get set up first. */ + tx_thread_sleep(20); + + + /* The SMTP test initialize. */ + smtp_test_initialize(); + + /* Create a mail instance with the above text message and recipient info. */ + status = nx_smtp_mail_send(&smtp_client, RECIPIENT_ADDRESS, NX_SMTP_MAIL_PRIORITY_NORMAL, + SUBJECT_LINE, MAIL_BODY, strlen(MAIL_BODY)); + + /* Create a mail instance with the above text message and recipient info. */ + + /* Check for errors. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Give the server time to disconnect. */ + while(wait_timeout) + { + + if (server_complete) + break; + + tx_thread_sleep(20); + + wait_timeout -= 20; + } + + /* Release threadx resources used by client. */ + status = nx_smtp_client_delete(&smtp_client); + + /* Return the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* This thread task simulates SMTP server response to client requests. */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +ULONG port; +ULONG peer_address; +UINT i; +UCHAR *work_ptr; +ULONG actual_status; + + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the SMTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 8000, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the SMTP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SMTP_SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Act as the SMTP server to receive the SMTP Client query and send the SMTP response. */ + for (i = 0; i < MSG_COUNT; i++ ) + { + + if (i == 0) + { + /* This is the greeting, we don't wait for a client response first...*/ + } + else + { + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 100 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + continue; + } + + /* Get the SMTP client TCP port. */ + status = nx_tcp_socket_peer_info_get(&server_socket, &peer_address, &port); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* This is the message data. We need to parse for the End Of Message marker. */ + if (i == 7) + { + /* Look for 0x0D 0x0A 0x2E 0x0d 0x0A indiating end of mail message. */ + work_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length - 5; + + if ((*work_ptr == 0x0D) && + (*(work_ptr + 1) == 0x0A) && + (*(work_ptr + 2) == 0x2E) && + (*(work_ptr + 3) == 0x0D) && + (*(work_ptr + 4) == 0x0A)) + + { + + /* Done iwth message, wait for QUIT command from client. */ + } + else + { + + /* Stay in this state. */ + + i--; + nx_packet_release(my_packet); + continue; + } + } + /* Release the packet. */ + nx_packet_release(my_packet); + } + /* Send the SMTP response packet. */ + status = nx_smtp_response_packet_send(&server_socket, port, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Wait for Client process last message. */ + tx_thread_sleep(20); + + /* Unlisten and Unbind the TCP socket. */ + + status = nx_tcp_server_socket_unaccept(&server_socket); + status += nx_tcp_server_socket_unlisten(&server_ip, SMTP_SERVER_PORT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + server_complete = NX_TRUE; + +} + +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, 200); + + /* Check status. */ + if (status) + { + error_counter++; + return status; + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + smtp_test[packet_number].smtp_test_pkt_data, + smtp_test[packet_number].smtp_test_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = smtp_test[packet_number].smtp_test_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static void smtp_test_initialize() +{ + + smtp_test[0].smtp_test_pkt_data = &response_220_greetings_pkt[0]; + smtp_test[0].smtp_test_pkt_size = response_220_greetings_size; + smtp_test[1].smtp_test_pkt_data = &response_250_ehlo_auth_no_type_pkt[0]; + smtp_test[1].smtp_test_pkt_size = response_250_ehlo_auth_no_type_size; + smtp_test[2].smtp_test_pkt_data = &response_334_pkt[0]; + smtp_test[2].smtp_test_pkt_size = response_334_size; + smtp_test[3].smtp_test_pkt_data = &response_235_auth_passed_pkt[0]; + smtp_test[3].smtp_test_pkt_size = response_235_auth_passed_size; + + smtp_test[4].smtp_test_pkt_data = &response_250_sender_ok_pkt[0]; + smtp_test[4].smtp_test_pkt_size = response_250_sender_ok_size; + smtp_test[5].smtp_test_pkt_data = &response_250_recipient_ok_pkt[0]; + smtp_test[5].smtp_test_pkt_size = response_250_recipient_ok_size; + smtp_test[6].smtp_test_pkt_data = &response_354_enter_mail_pkt[0]; + smtp_test[6].smtp_test_pkt_size = response_354_enter_mail_size; + + smtp_test[7].smtp_test_pkt_data = &response_250_message_saved_pkt[0]; + smtp_test[7].smtp_test_pkt_size = response_250_message_saved_size; + + smtp_test[8].smtp_test_pkt_data = &response_221_bye_pkt[0]; + smtp_test[8].smtp_test_pkt_size = response_221_bye_size; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_auth_no_type_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SMTP Auth Logon Function Test.............................N/A\n"); + + test_control_return(3); +} +#endif + + diff --git a/test/regression/smtp_test/netx_smtp_auth_no_type_test.c b/test/regression/smtp_test/netx_smtp_auth_no_type_test.c new file mode 100644 index 00000000..120be6e9 --- /dev/null +++ b/test/regression/smtp_test/netx_smtp_auth_no_type_test.c @@ -0,0 +1,586 @@ +/* This NetX test concentrates on the basic SMTP operation. The Server supports + auth login, auth plain and will send a one packet response to the EHLO message. The Client + then authenticates itself by AUTH LOGIN, sends a message of three packets, and quits. */ + + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_smtp_client.h" +#else +#include "nx_smtp_client.h" +#endif + +#define DEMO_STACK_SIZE 2048 +#define SERVER_IPADR IP_ADDRESS(10, 0, 0, 1) +#define CLIENT_IPADR IP_ADDRESS(10, 0, 0, 10) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_PACKET_POOL server_packet_pool; +static NX_TCP_SOCKET server_socket; +static NX_SMTP_CLIENT smtp_client; + +#define SUBJECT_LINE "NetX Duo SMTP Client Demo" +#define MAIL_BODY ".NetX Duo SMTP client is a simple SMTP client implementation \r\n" \ + ".that allow embedded devices to send email to an SMTP server. \r\n" \ + "This feature is intended to allow a device to send simple status\r\n " \ + "reports using the most universal Internet application email.\r\n" \ + "The rest of this narrative is merely to supply this most interesting quote: \r\n" \ + "Perhaps the most vivid recollection of my youth is that of the local wheelmen, \r\n" \ + "led by my father, stopping at our home to eat pone, sip mint juleps, and flog \r\n" \ + "the field hands. This more than anything cultivated my life-long aversion \r\n" \ + "to bicycles. ~~ Tennessee Williams.\r\n\r\n" \ + "Nothing compares to the simple pleasure of a bike ride. --John F. Kennedy, (surely you've heard of him?)\r\n\r\n" \ + "Perhaps the most vivid recollection of my youth is that of being flogged \r\n" \ + "by the local wheelmen, along with the field hands, the postman, and a \r\n" \ + "young Tennessee Williams. This more than anything cultivated my life-long " \ + "aversion to his plays. -Truman Capote\r\n" \ + "When I see an adult on a bicycle, I do not despair for the future of the human race. H.G. Wells \r\n" \ + "during the Second World War, if the United States had retooled its \r\n" \ + "factories for manufacturing bicycles instead of munitions, we'd be one of \r\n" \ + "the healthiest, least oil-dependent, and most environmentally-sound \r\n" \ + "constituents in the Nazi empire today. -Ralph Nader." + + +#define PASSWORD "testpwd" +#define RECIPIENT_ADDRESS "recipient@domain.com" +#define LOCAL_DOMAIN "domain.com" +#define FROM_ADDRESS "recipient@domain.com" +#define USERNAME FROM_ADDRESS +#define SMTP_SERVER_PORT 25 + + +/* See the NetX Duo SMTP Client User Guide for how to set the authentication type. */ +#define CLIENT_AUTHENTICATION_TYPE NX_SMTP_CLIENT_AUTH_LOGIN + +#if defined(__PRODUCT_NETXDUO__) +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static UINT server_complete = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr); + +/* SMTP Tests. */ +static void smtp_test_initialize(); + +/* Send SMTP server response. */ +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number); + +extern char response_220_greetings_pkt[185]; +extern int response_220_greetings_size; + +/* This is the one packet 250 EHLO message */ +extern char response_250_ehlo_auth_no_type_pkt[145]; +extern int response_250_ehlo_auth_no_type_size; + +extern char response_334_pkt[6]; +extern int response_334_size; + +extern char response_235_auth_passed_pkt[85]; +extern int response_235_auth_passed_size; + +extern char response_250_sender_ok_pkt[40]; +extern int response_250_sender_ok_size; + +extern char response_250_recipient_ok_pkt[43]; +extern int response_250_recipient_ok_size; + +extern char response_354_enter_mail_pkt[40]; +extern int response_354_enter_mail_size; + +extern char response_250_message_saved_pkt[92]; +extern int response_250_message_saved_size; + +extern char response_221_bye_pkt[80]; +extern int response_221_bye_size; + + +typedef struct SMTP_TEST_STRUCT +{ + char *smtp_test_pkt_data; + int smtp_test_pkt_size; +} SMTP_TEST; + + +#define MSG_COUNT 9 + +static SMTP_TEST smtp_test[MSG_COUNT]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_auth_no_type_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SMTP client thread. */ + tx_thread_create(&thread_client, "thread client", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_server, "thread server", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "SMTP CLient IP", CLIENT_IPADR, 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "SMTP Server IP", SERVER_IPADR, 0xFFFFFF00UL, &server_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + status += nx_tcp_enable(&server_ip); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; + + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + +#if defined(__PRODUCT_NETXDUO__) + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + server_ip_address.nxd_ip_address.v4 = SERVER_IPADR; + + status = nxd_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + &server_ip_address, SMTP_SERVER_PORT); +#else + server_ip_address = SERVER_IPADR; + + status = nx_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + server_ip_address, SMTP_SERVER_PORT); +#endif + + if (status != NX_SUCCESS) + { + error_counter++; + } + + return; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG actual_status; +UINT wait_timeout = 300; + + + printf("NetX Test: SMTP Auth No Type Test...................................."); + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&client_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the server get set up first. */ + tx_thread_sleep(20); + + + /* The SMTP test initialize. */ + smtp_test_initialize(); + + /* Create a mail instance with the above text message and recipient info. */ + status = nx_smtp_mail_send(&smtp_client, RECIPIENT_ADDRESS, NX_SMTP_MAIL_PRIORITY_NORMAL, + SUBJECT_LINE, MAIL_BODY, strlen(MAIL_BODY)); + + /* Create a mail instance with the above text message and recipient info. */ + + /* Check for errors. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Give the server time to disconnect. */ + while(wait_timeout) + { + + if (server_complete) + break; + + tx_thread_sleep(20); + + wait_timeout -= 20; + } + + /* Release threadx resources used by client. */ + status = nx_smtp_client_delete(&smtp_client); + + /* Return the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* This thread task simulates SMTP server response to client requests. */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +ULONG port; +ULONG peer_address; +UINT i; +UCHAR *work_ptr; +ULONG actual_status; + + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the SMTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 8000, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the SMTP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SMTP_SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Act as the SMTP server to receive the SMTP Client query and send the SMTP response. */ + for (i = 0; i < MSG_COUNT; i++ ) + { + + if (i == 0) + { + /* This is the greeting, we don't wait for a client response first...*/ + } + else + { + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 100 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + continue; + } + + /* Get the SMTP client TCP port. */ + status = nx_tcp_socket_peer_info_get(&server_socket, &peer_address, &port); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* This is the message data. We need to parse for the End Of Message marker. */ + if (i == 7) + { + /* Look for 0x0D 0x0A 0x2E 0x0d 0x0A indiating end of mail message. */ + work_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length - 5; + + if ((*work_ptr == 0x0D) && + (*(work_ptr + 1) == 0x0A) && + (*(work_ptr + 2) == 0x2E) && + (*(work_ptr + 3) == 0x0D) && + (*(work_ptr + 4) == 0x0A)) + + { + + /* Done iwth message, wait for QUIT command from client. */ + } + else + { + + /* Stay in this state. */ + + i--; + nx_packet_release(my_packet); + continue; + } + } + /* Release the packet. */ + nx_packet_release(my_packet); + } + /* Send the SMTP response packet. */ + status = nx_smtp_response_packet_send(&server_socket, port, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Wait for Client process last message. */ + tx_thread_sleep(20); + + /* Unlisten and Unbind the TCP socket. */ + + status = nx_tcp_server_socket_unaccept(&server_socket); + status += nx_tcp_server_socket_unlisten(&server_ip, SMTP_SERVER_PORT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + server_complete = NX_TRUE; + +} + +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, 200); + + /* Check status. */ + if (status) + { + error_counter++; + return status; + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + smtp_test[packet_number].smtp_test_pkt_data, + smtp_test[packet_number].smtp_test_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = smtp_test[packet_number].smtp_test_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static void smtp_test_initialize() +{ + + smtp_test[0].smtp_test_pkt_data = &response_220_greetings_pkt[0]; + smtp_test[0].smtp_test_pkt_size = response_220_greetings_size; + smtp_test[1].smtp_test_pkt_data = &response_250_ehlo_auth_no_type_pkt[0]; + smtp_test[1].smtp_test_pkt_size = response_250_ehlo_auth_no_type_size; + smtp_test[2].smtp_test_pkt_data = &response_334_pkt[0]; + smtp_test[2].smtp_test_pkt_size = response_334_size; + smtp_test[3].smtp_test_pkt_data = &response_235_auth_passed_pkt[0]; + smtp_test[3].smtp_test_pkt_size = response_235_auth_passed_size; + + smtp_test[4].smtp_test_pkt_data = &response_250_sender_ok_pkt[0]; + smtp_test[4].smtp_test_pkt_size = response_250_sender_ok_size; + smtp_test[5].smtp_test_pkt_data = &response_250_recipient_ok_pkt[0]; + smtp_test[5].smtp_test_pkt_size = response_250_recipient_ok_size; + smtp_test[6].smtp_test_pkt_data = &response_354_enter_mail_pkt[0]; + smtp_test[6].smtp_test_pkt_size = response_354_enter_mail_size; + + smtp_test[7].smtp_test_pkt_data = &response_250_message_saved_pkt[0]; + smtp_test[7].smtp_test_pkt_size = response_250_message_saved_size; + + smtp_test[8].smtp_test_pkt_data = &response_221_bye_pkt[0]; + smtp_test[8].smtp_test_pkt_size = response_221_bye_size; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_auth_no_type_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SMTP Auth No Type Test....................................N/A\n"); + + test_control_return(3); +} +#endif + + diff --git a/test/regression/smtp_test/netx_smtp_auth_none_test.c b/test/regression/smtp_test/netx_smtp_auth_none_test.c new file mode 100644 index 00000000..6b9771c7 --- /dev/null +++ b/test/regression/smtp_test/netx_smtp_auth_none_test.c @@ -0,0 +1,575 @@ +/* This NetX tests an SMTP Server configured for no authentication (the server + response to EHLO message contains no AUTH parameters). The client if configured + for LOGIN or PLAIN authentication can still try to authenticate itself but the + server may send an error message which will cause the client to abort. + + In this test case, the Client is configured for AUTH NONE, so the Client should + skip the authentication step and go directly to MAIL. The simulated server response + expects to go from EHLO to MAIL, skipping authentication. */ + + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_smtp_client.h" +#else +#include "nx_smtp_client.h" +#endif + +#define DEMO_STACK_SIZE 2048 +#define SERVER_IPADR IP_ADDRESS(10, 0, 0, 1) +#define CLIENT_IPADR IP_ADDRESS(10, 0, 0, 10) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_PACKET_POOL server_packet_pool; +static NX_TCP_SOCKET server_socket; +static NX_SMTP_CLIENT smtp_client; + +#define SUBJECT_LINE "NetX Duo SMTP Client Demo" +#define MAIL_BODY ".NetX Duo SMTP client is a simple SMTP client implementation \r\n" \ + ".that allow embedded devices to send email to an SMTP server. \r\n" \ + "This feature is intended to allow a device to send simple status\r\n " \ + "reports using the most universal Internet application email.\r\n" \ + "The rest of this narrative is merely to supply this most interesting quote: \r\n" \ + "Perhaps the most vivid recollection of my youth is that of the local wheelmen, \r\n" \ + "led by my father, stopping at our home to eat pone, sip mint juleps, and flog \r\n" \ + "the field hands. This more than anything cultivated my life-long aversion \r\n" \ + "to bicycles. ~~ Tennessee Williams.\r\n\r\n" \ + "Nothing compares to the simple pleasure of a bike ride. --John F. Kennedy, (surely you've heard of him?)\r\n\r\n" \ + "Perhaps the most vivid recollection of my youth is that of being flogged \r\n" \ + "by the local wheelmen, along with the field hands, the postman, and a \r\n" \ + "young Tennessee Williams. This more than anything cultivated my life-long " \ + "aversion to his plays. -Truman Capote\r\n" \ + "When I see an adult on a bicycle, I do not despair for the future of the human race. H.G. Wells \r\n" \ + "during the Second World War, if the United States had retooled its \r\n" \ + "factories for manufacturing bicycles instead of munitions, we'd be one of \r\n" \ + "the healthiest, least oil-dependent, and most environmentally-sound \r\n" \ + "constituents in the Nazi empire today. -Ralph Nader." + + +#define PASSWORD "testpwd" +#define RECIPIENT_ADDRESS "recipient@domain.com" +#define LOCAL_DOMAIN "domain.com" +#define FROM_ADDRESS "recipient@domain.com" +#define USERNAME FROM_ADDRESS +#define SMTP_SERVER_PORT 25 + + +/* Set the authentication type to none. */ +#define CLIENT_AUTHENTICATION_TYPE NX_SMTP_CLIENT_AUTH_NONE + +#if defined(__PRODUCT_NETXDUO__) +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static UINT server_complete = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr); + +/* SMTP Tests. */ +static void smtp_test_initialize(); + +/* Send SMTP server response. */ +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number); + +extern char response_220_greetings_pkt[185]; +extern int response_220_greetings_size; + +/* This is the one packet 250 EHLO message */ +extern char response_250_ehlo_noauth_pkt[145]; +extern int response_250_ehlo_noauth_size; + +extern char response_250_sender_ok_pkt[40]; +extern int response_250_sender_ok_size; + +extern char response_250_recipient_ok_pkt[43]; +extern int response_250_recipient_ok_size; + +extern char response_354_enter_mail_pkt[40]; +extern int response_354_enter_mail_size; + +extern char response_250_message_saved_pkt[92]; +extern int response_250_message_saved_size; + +extern char response_221_bye_pkt[80]; +extern int response_221_bye_size; + + +typedef struct SMTP_TEST_STRUCT +{ + char *smtp_test_pkt_data; + int smtp_test_pkt_size; +} SMTP_TEST; + + +#define MSG_COUNT 7 + +static SMTP_TEST smtp_test[MSG_COUNT]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_auth_none_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SMTP client thread. */ + tx_thread_create(&thread_client, "thread client", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_server, "thread server", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "SMTP CLient IP", CLIENT_IPADR, 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "SMTP Server IP", SERVER_IPADR, 0xFFFFFF00UL, &server_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + status += nx_tcp_enable(&server_ip); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; + + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + +#if defined(__PRODUCT_NETXDUO__) + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + server_ip_address.nxd_ip_address.v4 = SERVER_IPADR; + + status = nxd_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + &server_ip_address, SMTP_SERVER_PORT); +#else + server_ip_address = SERVER_IPADR; + + status = nx_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + server_ip_address, SMTP_SERVER_PORT); +#endif + + if (status != NX_SUCCESS) + { + error_counter++; + } + + return; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG actual_status; + + printf("NetX Test: SMTP No Authentication Test..............................."); + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&client_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the server get set up first. */ + tx_thread_sleep(20); + + + /* The SMTP test initialize. */ + smtp_test_initialize(); + + /* Create a mail instance with the above text message and recipient info. */ + status = nx_smtp_mail_send(&smtp_client, RECIPIENT_ADDRESS, NX_SMTP_MAIL_PRIORITY_NORMAL, + SUBJECT_LINE, MAIL_BODY, strlen(MAIL_BODY)); + + /* Create a mail instance with the above text message and recipient info. */ + + /* Check for errors. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Give the server time to disconnect. */ + while(1) + { + + if (server_complete) + break; + + tx_thread_sleep(20); + } + /* Release threadx resources used by client. */ + status = nx_smtp_client_delete(&smtp_client); + + /* Return the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* This thread task simulates SMTP server response to client requests. */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +ULONG port; +ULONG peer_address; +UINT i; +UCHAR *work_ptr; +ULONG actual_status; + + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the SMTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 8000, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the SMTP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SMTP_SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Act as the SMTP server to receive the SMTP Client query and send the SMTP response. */ + for (i = 0; i < MSG_COUNT; i++ ) + { + + if (i == 0) + { + /* This is the greeting, we don't wait for a client response first...*/ + } + else + { + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 100 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + continue; } + + /* Get the SMTP client TCP port. */ + status = nx_tcp_socket_peer_info_get(&server_socket, &peer_address, &port); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* This is the message data. We need to parse for the End Of Message marker. */ + if (i == 5) + { + /* Look for 0x0D 0x0A 0x2E 0x0d 0x0A indiating end of mail message. */ + work_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length - 5; + + if ((*work_ptr == 0x0D) && + (*(work_ptr + 1) == 0x0A) && + (*(work_ptr + 2) == 0x2E) && + (*(work_ptr + 3) == 0x0D) && + (*(work_ptr + 4) == 0x0A)) + + { + + /* Done iwth message, wait for QUIT command from client. */ + } + else + { + + /* Stay in this state. */ + + i--; + nx_packet_release(my_packet); + continue; + } + } + /* Release the packet. */ + nx_packet_release(my_packet); + } + /* Send the SMTP response packet. */ + status = nx_smtp_response_packet_send(&server_socket, port, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Wait for Client process last message. */ + tx_thread_sleep(20); + + /* Unlisten and Unbind the TCP socket. */ + + status = nx_tcp_server_socket_unaccept(&server_socket); + status += nx_tcp_server_socket_unlisten(&server_ip, SMTP_SERVER_PORT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + + server_complete = NX_TRUE; + +} + +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return status; + } + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + smtp_test[packet_number].smtp_test_pkt_data, + smtp_test[packet_number].smtp_test_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = smtp_test[packet_number].smtp_test_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static void smtp_test_initialize() +{ + + smtp_test[0].smtp_test_pkt_data = &response_220_greetings_pkt[0]; + smtp_test[0].smtp_test_pkt_size = response_220_greetings_size; + smtp_test[1].smtp_test_pkt_data = &response_250_ehlo_noauth_pkt[0]; + smtp_test[1].smtp_test_pkt_size = response_250_ehlo_noauth_size; + + smtp_test[2].smtp_test_pkt_data = &response_250_sender_ok_pkt[0]; + smtp_test[2].smtp_test_pkt_size = response_250_sender_ok_size; + smtp_test[3].smtp_test_pkt_data = &response_250_recipient_ok_pkt[0]; + smtp_test[3].smtp_test_pkt_size = response_250_recipient_ok_size; + smtp_test[4].smtp_test_pkt_data = &response_354_enter_mail_pkt[0]; + smtp_test[4].smtp_test_pkt_size = response_354_enter_mail_size; + + smtp_test[5].smtp_test_pkt_data = &response_250_message_saved_pkt[0]; + smtp_test[5].smtp_test_pkt_size = response_250_message_saved_size; + + smtp_test[6].smtp_test_pkt_data = &response_221_bye_pkt[0]; + smtp_test[6].smtp_test_pkt_size = response_221_bye_size; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_auth_none_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SMTP No Authentication Test...............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/smtp_test/netx_smtp_basic_function_test.c b/test/regression/smtp_test/netx_smtp_basic_function_test.c new file mode 100644 index 00000000..bb4cd4b8 --- /dev/null +++ b/test/regression/smtp_test/netx_smtp_basic_function_test.c @@ -0,0 +1,584 @@ +/* This NetX test concentrates on the basic SMTP operation. The Server supports + auth login, auth plain and will send a one packet response to the EHLO message. The Client + then authenticates itself by AUTH LOGIN, sends a message of three packets, and quits. */ + + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_smtp_client.h" +#else +#include "nx_smtp_client.h" +#endif + +#define DEMO_STACK_SIZE 2048 +#define SERVER_IPADR IP_ADDRESS(10, 0, 0, 1) +#define CLIENT_IPADR IP_ADDRESS(10, 0, 0, 10) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_PACKET_POOL server_packet_pool; +static NX_TCP_SOCKET server_socket; +static NX_SMTP_CLIENT smtp_client; + +#define SUBJECT_LINE "NetX Duo SMTP Client Demo" +#define MAIL_BODY ".NetX Duo SMTP client is a simple SMTP client implementation \r\n" \ + ".that allow embedded devices to send email to an SMTP server. \r\n" \ + "This feature is intended to allow a device to send simple status\r\n " \ + "reports using the most universal Internet application email.\r\n" \ + "The rest of this narrative is merely to supply this most interesting quote: \r\n" \ + "Perhaps the most vivid recollection of my youth is that of the local wheelmen, \r\n" \ + "led by my father, stopping at our home to eat pone, sip mint juleps, and flog \r\n" \ + "the field hands. This more than anything cultivated my life-long aversion \r\n" \ + "to bicycles. ~~ Tennessee Williams.\r\n\r\n" \ + "Nothing compares to the simple pleasure of a bike ride. --John F. Kennedy, (surely you've heard of him?)\r\n\r\n" \ + "Perhaps the most vivid recollection of my youth is that of being flogged \r\n" \ + "by the local wheelmen, along with the field hands, the postman, and a \r\n" \ + "young Tennessee Williams. This more than anything cultivated my life-long " \ + "aversion to his plays. -Truman Capote\r\n" \ + "When I see an adult on a bicycle, I do not despair for the future of the human race. H.G. Wells \r\n" \ + "during the Second World War, if the United States had retooled its \r\n" \ + "factories for manufacturing bicycles instead of munitions, we'd be one of \r\n" \ + "the healthiest, least oil-dependent, and most environmentally-sound \r\n" \ + "constituents in the Nazi empire today. -Ralph Nader." + + +#define PASSWORD "testpwd" +#define RECIPIENT_ADDRESS "recipient@domain.com" +#define LOCAL_DOMAIN "domain.com" +#define FROM_ADDRESS "recipient@domain.com" +#define USERNAME FROM_ADDRESS +#define SMTP_SERVER_PORT 25 + + +/* See the NetX Duo SMTP Client User Guide for how to set the authentication type. */ +#define CLIENT_AUTHENTICATION_TYPE NX_SMTP_CLIENT_AUTH_PLAIN + +#if defined(__PRODUCT_NETXDUO__) +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static UINT server_complete = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr); + +/* SMTP Tests. */ +static void smtp_test_initialize(); + +/* Send SMTP server response. */ +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number); + +extern char response_220_greetings_pkt[185]; +extern int response_220_greetings_size; + +/* This is the one packet 250 EHLO message */ +extern char response_250_ehlo_pkt[145]; +extern int response_250_ehlo_size; + +extern char response_334_pkt[6]; +extern int response_334_size; + +extern char response_235_auth_passed_pkt[85]; +extern int response_235_auth_passed_size; + +extern char response_250_sender_ok_pkt[40]; +extern int response_250_sender_ok_size; + +extern char response_250_recipient_ok_pkt[43]; +extern int response_250_recipient_ok_size; + +extern char response_354_enter_mail_pkt[40]; +extern int response_354_enter_mail_size; + +extern char response_250_message_saved_pkt[92]; +extern int response_250_message_saved_size; + +extern char response_221_bye_pkt[80]; +extern int response_221_bye_size; + + +typedef struct SMTP_TEST_STRUCT +{ + char *smtp_test_pkt_data; + int smtp_test_pkt_size; +} SMTP_TEST; + + +#define MSG_COUNT 9 + +static SMTP_TEST smtp_test[MSG_COUNT]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_basic_function_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SMTP client thread. */ + tx_thread_create(&thread_client, "thread client", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_server, "thread server", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "SMTP CLient IP", CLIENT_IPADR, 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "SMTP Server IP", SERVER_IPADR, 0xFFFFFF00UL, &server_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + status += nx_tcp_enable(&server_ip); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; + + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + +#if defined(__PRODUCT_NETXDUO__) + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + server_ip_address.nxd_ip_address.v4 = SERVER_IPADR; + + status = nxd_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + &server_ip_address, SMTP_SERVER_PORT); +#else + server_ip_address = SERVER_IPADR; + + status = nx_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + server_ip_address, SMTP_SERVER_PORT); +#endif + + if (status != NX_SUCCESS) + { + error_counter++; + } + + return; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG actual_status; +UINT wait_timeout = 300; + + + printf("NetX Test: SMTP Basic Function Test.................................."); + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&client_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the server get set up first. */ + tx_thread_sleep(20); + + + /* The SMTP test initialize. */ + smtp_test_initialize(); + + /* Create a mail instance with the above text message and recipient info. */ + status = nx_smtp_mail_send(&smtp_client, RECIPIENT_ADDRESS, NX_SMTP_MAIL_PRIORITY_NORMAL, + SUBJECT_LINE, MAIL_BODY, strlen(MAIL_BODY)); + + /* Create a mail instance with the above text message and recipient info. */ + + /* Check for errors. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Give the server time to disconnect. */ + while(wait_timeout) + { + + if (server_complete) + break; + + tx_thread_sleep(20); + + wait_timeout -= 20; + } + + /* Release threadx resources used by client. */ + status = nx_smtp_client_delete(&smtp_client); + + /* Return the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* This thread task simulates SMTP server response to client requests. */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +ULONG port; +ULONG peer_address; +UINT i; +UCHAR *work_ptr; +ULONG actual_status; + + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the SMTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 8000, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the SMTP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SMTP_SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Act as the SMTP server to receive the SMTP Client query and send the SMTP response. */ + for (i = 0; i < MSG_COUNT; i++ ) + { + + if (i == 0) + { + /* This is the greeting, we don't wait for a client response first...*/ + } + else + { + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 100 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + continue; + } + + /* Get the SMTP client TCP port. */ + status = nx_tcp_socket_peer_info_get(&server_socket, &peer_address, &port); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* This is the message data. We need to parse for the End Of Message marker. */ + if (i == 7) + { + /* Look for 0x0D 0x0A 0x2E 0x0d 0x0A indiating end of mail message. */ + work_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length - 5; + + if ((*work_ptr == 0x0D) && + (*(work_ptr + 1) == 0x0A) && + (*(work_ptr + 2) == 0x2E) && + (*(work_ptr + 3) == 0x0D) && + (*(work_ptr + 4) == 0x0A)) + + { + + /* Done iwth message, wait for QUIT command from client. */ + } + else + { + + /* Stay in this state. */ + + i--; + nx_packet_release(my_packet); + continue; + } + } + /* Release the packet. */ + nx_packet_release(my_packet); + } + /* Send the SMTP response packet. */ + status = nx_smtp_response_packet_send(&server_socket, port, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Wait for Client process last message. */ + tx_thread_sleep(20); + + /* Unlisten and Unbind the TCP socket. */ + + status = nx_tcp_server_socket_unaccept(&server_socket); + status += nx_tcp_server_socket_unlisten(&server_ip, SMTP_SERVER_PORT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + server_complete = NX_TRUE; + +} + +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, 200); + + /* Check status. */ + if (status) + { + error_counter++; + return status; + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + smtp_test[packet_number].smtp_test_pkt_data, + smtp_test[packet_number].smtp_test_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = smtp_test[packet_number].smtp_test_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static void smtp_test_initialize() +{ + + smtp_test[0].smtp_test_pkt_data = &response_220_greetings_pkt[0]; + smtp_test[0].smtp_test_pkt_size = response_220_greetings_size; + smtp_test[1].smtp_test_pkt_data = &response_250_ehlo_pkt[0]; + smtp_test[1].smtp_test_pkt_size = response_250_ehlo_size; + smtp_test[2].smtp_test_pkt_data = &response_334_pkt[0]; + smtp_test[2].smtp_test_pkt_size = response_334_size; + smtp_test[3].smtp_test_pkt_data = &response_235_auth_passed_pkt[0]; + smtp_test[3].smtp_test_pkt_size = response_235_auth_passed_size; + + smtp_test[4].smtp_test_pkt_data = &response_250_sender_ok_pkt[0]; + smtp_test[4].smtp_test_pkt_size = response_250_sender_ok_size; + smtp_test[5].smtp_test_pkt_data = &response_250_recipient_ok_pkt[0]; + smtp_test[5].smtp_test_pkt_size = response_250_recipient_ok_size; + smtp_test[6].smtp_test_pkt_data = &response_354_enter_mail_pkt[0]; + smtp_test[6].smtp_test_pkt_size = response_354_enter_mail_size; + + smtp_test[7].smtp_test_pkt_data = &response_250_message_saved_pkt[0]; + smtp_test[7].smtp_test_pkt_size = response_250_message_saved_size; + + smtp_test[8].smtp_test_pkt_data = &response_221_bye_pkt[0]; + smtp_test[8].smtp_test_pkt_size = response_221_bye_size; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_basic_function_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SMTP Basic Function Test..................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/smtp_test/netx_smtp_invalid_release_test.c b/test/regression/smtp_test/netx_smtp_invalid_release_test.c new file mode 100644 index 00000000..d2b81ab1 --- /dev/null +++ b/test/regression/smtp_test/netx_smtp_invalid_release_test.c @@ -0,0 +1,557 @@ +/* This NetX test concentrates on validating a bug in _nx_smtp_rsp_greeting. The packet released + in _nx_smtp_utility_read_server_code can be released again. */ + + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_smtp_client.h" +#else +#include "nx_smtp_client.h" +#endif + +#define DEMO_STACK_SIZE 2048 +#define SERVER_IPADR IP_ADDRESS(10, 0, 0, 1) +#define CLIENT_IPADR IP_ADDRESS(10, 0, 0, 10) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_PACKET_POOL server_packet_pool; +static NX_TCP_SOCKET server_socket; +static NX_SMTP_CLIENT smtp_client; + +#define SUBJECT_LINE "NetX Duo SMTP Client Demo" +#define MAIL_BODY ".NetX Duo SMTP client is a simple SMTP client implementation \r\n" \ + ".that allow embedded devices to send email to an SMTP server. \r\n" \ + "This feature is intended to allow a device to send simple status\r\n " \ + "reports using the most universal Internet application email.\r\n" \ + "The rest of this narrative is merely to supply this most interesting quote: \r\n" \ + "Perhaps the most vivid recollection of my youth is that of the local wheelmen, \r\n" \ + "led by my father, stopping at our home to eat pone, sip mint juleps, and flog \r\n" \ + "the field hands. This more than anything cultivated my life-long aversion \r\n" \ + "to bicycles. ~~ Tennessee Williams.\r\n\r\n" \ + "Nothing compares to the simple pleasure of a bike ride. --John F. Kennedy, (surely you've heard of him?)\r\n\r\n" \ + "Perhaps the most vivid recollection of my youth is that of being flogged \r\n" \ + "by the local wheelmen, along with the field hands, the postman, and a \r\n" \ + "young Tennessee Williams. This more than anything cultivated my life-long " \ + "aversion to his plays. -Truman Capote\r\n" \ + "When I see an adult on a bicycle, I do not despair for the future of the human race. H.G. Wells \r\n" \ + "during the Second World War, if the United States had retooled its \r\n" \ + "factories for manufacturing bicycles instead of munitions, we'd be one of \r\n" \ + "the healthiest, least oil-dependent, and most environmentally-sound \r\n" \ + "constituents in the Nazi empire today. -Ralph Nader." + + +#define PASSWORD "testpwd" +#define RECIPIENT_ADDRESS "recipient@domain.com" +#define LOCAL_DOMAIN "domain.com" +#define FROM_ADDRESS "recipient@domain.com" +#define USERNAME FROM_ADDRESS +#define SMTP_SERVER_PORT 25 + + +/* See the NetX Duo SMTP Client User Guide for how to set the authentication type. */ +#define CLIENT_AUTHENTICATION_TYPE NX_SMTP_CLIENT_AUTH_PLAIN + +#if defined(__PRODUCT_NETXDUO__) +static NXD_ADDRESS server_ip_address; +#else +static ULONG server_ip_address; +#endif + + +static UINT server_complete = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr); + +/* SMTP Tests. */ +static void smtp_test_initialize(); + +/* Send SMTP server response. */ +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number); + +extern char response_220_greetings_pkt[185]; +extern int response_220_greetings_size; + +/* This is the one packet 250 EHLO message */ +extern char response_250_ehlo_pkt[145]; +extern int response_250_ehlo_size; + +extern char response_334_pkt[6]; +extern int response_334_size; + +extern char response_235_auth_passed_pkt[85]; +extern int response_235_auth_passed_size; + +extern char response_250_sender_ok_pkt[40]; +extern int response_250_sender_ok_size; + +extern char response_250_recipient_ok_pkt[43]; +extern int response_250_recipient_ok_size; + +extern char response_354_enter_mail_pkt[40]; +extern int response_354_enter_mail_size; + +extern char response_250_message_saved_pkt[92]; +extern int response_250_message_saved_size; + +extern char response_221_bye_pkt[80]; +extern int response_221_bye_size; + + +typedef struct SMTP_TEST_STRUCT +{ + char *smtp_test_pkt_data; + int smtp_test_pkt_size; +} SMTP_TEST; + + +#define MSG_COUNT 1 + +static SMTP_TEST smtp_test[MSG_COUNT]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_invalid_release_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SMTP client thread. */ + tx_thread_create(&thread_client, "thread client", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_server, "thread server", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + return; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "SMTP CLient IP", CLIENT_IPADR, 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "SMTP Server IP", SERVER_IPADR, 0xFFFFFF00UL, &server_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + status += nx_tcp_enable(&server_ip); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; + + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + +#if defined(__PRODUCT_NETXDUO__) + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + server_ip_address.nxd_ip_address.v4 = SERVER_IPADR; + + status = nxd_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + &server_ip_address, SMTP_SERVER_PORT); +#else + server_ip_address = SERVER_IPADR; + + status = nx_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + server_ip_address, SMTP_SERVER_PORT); +#endif + + if (status != NX_SUCCESS) + { + error_counter++; + } + + return; +} + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG actual_status; +UINT wait_timeout = 300; + + + printf("NetX Test: SMTP Invalid Release Test................................."); + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&client_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the server get set up first. */ + tx_thread_sleep(20); + + + /* The SMTP test initialize. */ + smtp_test_initialize(); + + /* Create a mail instance with the above text message and recipient info. */ + nx_smtp_mail_send(&smtp_client, RECIPIENT_ADDRESS, NX_SMTP_MAIL_PRIORITY_NORMAL, + SUBJECT_LINE, MAIL_BODY, strlen(MAIL_BODY)); + + /* Release threadx resources used by client. */ + status = nx_smtp_client_delete(&smtp_client); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + error_counter++; + } + + /* Check invalid packet release count. */ + if (client_packet_pool.nx_packet_pool_invalid_releases != 0) + { + error_counter++; + } + + /* Return the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* This thread task simulates SMTP server response to client requests. */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +ULONG port; +ULONG peer_address; +UINT i; +UCHAR *work_ptr; +ULONG actual_status; + + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the SMTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 8000, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the SMTP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SMTP_SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Act as the SMTP server to receive the SMTP Client query and send the SMTP response. */ + for (i = 0; i < MSG_COUNT; i++ ) + { + + if (i == 0) + { + /* This is the greeting, we don't wait for a client response first...*/ + } + else + { + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 100 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + error_counter++; + continue; + } + + /* Get the SMTP client TCP port. */ + status = nx_tcp_socket_peer_info_get(&server_socket, &peer_address, &port); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* This is the message data. We need to parse for the End Of Message marker. */ + if (i == 7) + { + /* Look for 0x0D 0x0A 0x2E 0x0d 0x0A indiating end of mail message. */ + work_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length - 5; + + if ((*work_ptr == 0x0D) && + (*(work_ptr + 1) == 0x0A) && + (*(work_ptr + 2) == 0x2E) && + (*(work_ptr + 3) == 0x0D) && + (*(work_ptr + 4) == 0x0A)) + + { + + /* Done iwth message, wait for QUIT command from client. */ + } + else + { + + /* Stay in this state. */ + + i--; + nx_packet_release(my_packet); + continue; + } + } + /* Release the packet. */ + nx_packet_release(my_packet); + } + /* Send the SMTP response packet. */ + status = nx_smtp_response_packet_send(&server_socket, port, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + + /* Wait for Client process last message. */ + tx_thread_sleep(20); + + /* Unlisten and Unbind the TCP socket. */ + + nx_tcp_socket_disconnect(&server_socket, NX_NO_WAIT); + status = nx_tcp_server_socket_unaccept(&server_socket); + status += nx_tcp_server_socket_unlisten(&server_ip, SMTP_SERVER_PORT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + server_complete = NX_TRUE; + +} + +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, 200); + + /* Check status. */ + if (status) + { + error_counter++; + return status; + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + smtp_test[packet_number].smtp_test_pkt_data, + smtp_test[packet_number].smtp_test_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = smtp_test[packet_number].smtp_test_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static void smtp_test_initialize() +{ + + smtp_test[0].smtp_test_pkt_data = "2200"; /* Invalid value */ + smtp_test[0].smtp_test_pkt_size = 4; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_invalid_release_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SMTP Invalid Release Test.................................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/smtp_test/netx_smtp_missing_last_250_EHLO_message_test.c b/test/regression/smtp_test/netx_smtp_missing_last_250_EHLO_message_test.c new file mode 100644 index 00000000..444affe5 --- /dev/null +++ b/test/regression/smtp_test/netx_smtp_missing_last_250_EHLO_message_test.c @@ -0,0 +1,654 @@ +/* This NetX tests the SMTP client for handling a server 250 reply to EHLO which has multiple + 250 parameters but none of them have the 'final' 250 code e.g. 250 followed by space. + Therefore the SMTP client should abort the connection. The simulated server should not + count a failed nx_tcp_socket_receive() if it is sending the 'last' EHLO packet because + the Client is 'mute' waiting for the 250 packet with the last 250 marker. */ + + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_smtp_client.h" +#else +#include "nx_smtp_client.h" +#endif + +#define DEMO_STACK_SIZE 2048 +#define SERVER_IPADR IP_ADDRESS(10, 2, 41, 1) +#define CLIENT_IPADR IP_ADDRESS(10, 2, 41, 10) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_PACKET_POOL server_packet_pool; +static NX_TCP_SOCKET server_socket; +static NX_SMTP_CLIENT smtp_client; + +#define SUBJECT_LINE "NetX Duo SMTP Client Demo" +#define MAIL_BODY ".NetX Duo SMTP client is a simple SMTP client implementation \r\n" \ + ".that allow embedded devices to send email to an SMTP server. \r\n" \ + "This feature is intended to allow a device to send simple status\r\n " \ + "reports using the most universal Internet application email.\r\n" \ + "The rest of this narrative is merely to supply this most interesting quote: \r\n" \ + "Perhaps the most vivid recollection of my youth is that of the local wheelmen, \r\n" \ + "led by my father, stopping at our home to eat pone, sip mint juleps, and flog \r\n" \ + "the field hands. This more than anything cultivated my life-long aversion \r\n" \ + "to bicycles. ~~ Tennessee Williams.\r\n\r\n" \ + "Nothing compares to the simple pleasure of a bike ride. --John F. Kennedy, (surely you've heard of him?)\r\n\r\n" \ + "Perhaps the most vivid recollection of my youth is that of being flogged \r\n" \ + "by the local wheelmen, along with the field hands, the postman, and a \r\n" \ + "young Tennessee Williams. This more than anything cultivated my life-long " \ + "aversion to his plays. -Truman Capote\r\n" \ + "When I see an adult on a bicycle, I do not despair for the future of the human race. H.G. Wells \r\n" \ + "during the Second World War, if the United States had retooled its \r\n" \ + "factories for manufacturing bicycles instead of munitions, we'd be one of \r\n" \ + "the healthiest, least oil-dependent, and most environmentally-sound \r\n" \ + "constituents in the Nazi empire today. -Ralph Nader." + + +#define PASSWORD "testpwd" +#define RECIPIENT_ADDRESS "recipient@domain.com" +#define LOCAL_DOMAIN "domain.com" +#define FROM_ADDRESS "recipient@domain.com" +#define USERNAME FROM_ADDRESS +#define SMTP_SERVER_PORT 25 + + +/* This uses one packet for the server's EHLO response to client. Otherwise it sends + two packets for the EHLO response. */ + +/* See the NetX Duo SMTP Client User Guide for how to set the authentication type. */ +#define CLIENT_AUTHENTICATION_TYPE NX_SMTP_CLIENT_AUTH_PLAIN + +#if defined(__PRODUCT_NETXDUO__) +static NXD_ADDRESS server_ip_address; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_client; +#endif /* FEATURE_NX_IPV6 */ +#else +static ULONG server_ip_address; +#endif + +static UINT server_complete = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr); + +/* SMTP Tests. */ +static void smtp_test_initialize(); + +/* Send SMTP server response. */ +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number); + + +extern char response_220_greetings_pkt[185]; +extern int response_220_greetings_size; + + +/* These next two are the first and second packets of the EHLO message */ +extern char response_250_ehlo_first_pkt[145]; +extern int response_250_ehlo_first_size; + +extern char response_250_ehlo_notlast_pkt[10]; +extern int response_250_ehlo_notlast_size; + +extern char response_334_pkt[6]; +extern int response_334_size; + +extern char response_235_auth_passed_pkt[85]; +extern int response_235_auth_passed_size; + +extern char response_250_sender_ok_pkt[40]; +extern int response_250_sender_ok_size; + +extern char response_250_recipient_ok_pkt[43]; +extern int response_250_recipient_ok_size; + +extern char response_354_enter_mail_pkt[40]; +extern int response_354_enter_mail_size; + +extern char response_250_message_saved_pkt[92]; +extern int response_250_message_saved_size; + +extern char response_221_bye_pkt[80]; +extern int response_221_bye_size; + + +typedef struct SMTP_TEST_STRUCT +{ + char *smtp_test_pkt_data; + int smtp_test_pkt_size; +} SMTP_TEST; + + +#define MSG_COUNT 10 + +static SMTP_TEST smtp_test[MSG_COUNT]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_missing_last_250_EHLO_message_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SMTP client thread. */ + tx_thread_create(&thread_client, "thread client", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_server, "thread server", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "SMTP CLient IP", CLIENT_IPADR, 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "SMTP Server IP", SERVER_IPADR, 0xFFFFFF00UL, &server_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + status += nx_tcp_enable(&server_ip); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; + + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status += nxd_ipv6_enable(&client_ip); + status += nxd_ipv6_enable(&server_ip); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&client_ip); + status += nxd_icmp_enable(&server_ip); + + /* Check enable status. */ + if (status) + error_counter++; + + /* Set source and destination address with global address. */ + server_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + server_ip_address.nxd_ip_address.v6[0] = 0x20010DB8; + server_ip_address.nxd_ip_address.v6[1] = 0x00010001; + server_ip_address.nxd_ip_address.v6[2] = 0x021122FF; + server_ip_address.nxd_ip_address.v6[3] = 0xFE334456; + + address_client.nxd_ip_version = NX_IP_VERSION_V6; + address_client.nxd_ip_address.v6[0] = 0x20010DB8; + address_client.nxd_ip_address.v6[1] = 0x00010001; + address_client.nxd_ip_address.v6[2] = 0x021122FF; + address_client.nxd_ip_address.v6[3] = 0xFE334499; + + status = nxd_ipv6_address_set(&client_ip, 0, &server_ip_address, 64, NX_NULL); + status = nxd_ipv6_address_set(&server_ip, 0, &address_client, 64, NX_NULL); + +#endif /* FEATURE_NX_IPV6 */ + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + +#if defined(__PRODUCT_NETXDUO__) + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + server_ip_address.nxd_ip_address.v4 = SERVER_IPADR; + + status = nxd_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + &server_ip_address, SMTP_SERVER_PORT); +#else + server_ip_address = SERVER_IPADR; + + status = nx_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + server_ip_address, SMTP_SERVER_PORT); +#endif + + if (status != NX_SUCCESS) + { + error_counter++; + } + + return; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG actual_status; +UINT wait_timeout = 300; + + printf("NetX Test: SMTP Missing Last Packet EHLO Message Test................"); + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&client_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the server get set up first. */ + tx_thread_sleep(20); + + /* The SMTP test initialize. */ + smtp_test_initialize(); + + + /* Create a mail instance with the above text message and recipient info. */ + status = nx_smtp_mail_send(&smtp_client, RECIPIENT_ADDRESS, NX_SMTP_MAIL_PRIORITY_NORMAL, + SUBJECT_LINE, MAIL_BODY, strlen(MAIL_BODY)); + + /* Create a mail instance with the above text message and recipient info. */ + + /* Check for errors. This mail should not succeed! */ + if (status == NX_SUCCESS) + { + error_counter++; + } + + /* Give the server time to disconnect. */ + while(wait_timeout) + { + + if (server_complete) + break; + + tx_thread_sleep(20); + + wait_timeout -= 20; + } + + /* Release threadx resources used by client. */ + status = nx_smtp_client_delete(&smtp_client); + + /* Return the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +/* This thread task simulates SMTP server response to client requests. */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +ULONG port; +ULONG peer_address; +UINT i; +UCHAR *work_ptr; +ULONG actual_status; + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + // jlc restore tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the SMTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 8000, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the SMTP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SMTP_SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Act as the SMTP server to receive the SMTP Client query and send the SMTP response. */ + for (i = 0; i < MSG_COUNT; i++ ) + { + + if (i == 0) + { + /* This is the greeting, we don't wait to hear from client...*/ + } + else + { + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, 50 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + if (i != 3) + { + error_counter++; + } + + break; + } + + /* Get the SMTP client TCP port. */ + status = nx_tcp_socket_peer_info_get(&server_socket, &peer_address, &port); + + /* Check status. */ + if (status) + { + error_counter++; + } + + + if (i == 8) + { + /* Look for 0x0D 0x0A 0x2E 0x0d 0x0A indiating end of mail message. */ + work_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length - 5; + + if ((*work_ptr == 0x0D) && + (*(work_ptr + 1) == 0x0A) && + (*(work_ptr + 2) == 0x2E) && + (*(work_ptr + 3) == 0x0D) && + (*(work_ptr + 4) == 0x0A)) + + { + + /* Done iwth message, wait for QUIT command from client. */ + } + else + { + + /* Stay in this state. */ + + i--; + nx_packet_release(my_packet); + continue; + } + } + /* Release the packet. */ + nx_packet_release(my_packet); + } + /* Send the SMTP response packet. */ + status = nx_smtp_response_packet_send(&server_socket, port, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Check if this if the first EHLO packet. */ + if (i == 1) + { + + /* It is. Wait a beat and send the second one. */ + i++; + tx_thread_sleep(2); + + /* Send the SMTP response packet. */ + status = nx_smtp_response_packet_send(&server_socket, port, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + } + } + + /* Wait for Client process last message. */ + tx_thread_sleep(20); + + /* Unlisten and Unbind the TCP socket. */ + + status = nx_tcp_server_socket_unaccept(&server_socket); + status += nx_tcp_server_socket_unlisten(&server_ip, SMTP_SERVER_PORT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + server_complete = NX_TRUE; + +} + +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return status; + } + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + smtp_test[packet_number].smtp_test_pkt_data, + smtp_test[packet_number].smtp_test_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = smtp_test[packet_number].smtp_test_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static void smtp_test_initialize() +{ + smtp_test[0].smtp_test_pkt_data = &response_220_greetings_pkt[0]; + smtp_test[0].smtp_test_pkt_size = response_220_greetings_size; + smtp_test[1].smtp_test_pkt_data = &response_250_ehlo_first_pkt[0]; + smtp_test[1].smtp_test_pkt_size = response_250_ehlo_first_size; + smtp_test[2].smtp_test_pkt_data = &response_250_ehlo_notlast_pkt[0]; + smtp_test[2].smtp_test_pkt_size = response_250_ehlo_notlast_size; + smtp_test[3].smtp_test_pkt_data = &response_334_pkt[0]; + smtp_test[3].smtp_test_pkt_size = response_334_size; + smtp_test[4].smtp_test_pkt_data = &response_235_auth_passed_pkt[0]; + smtp_test[4].smtp_test_pkt_size = response_235_auth_passed_size; + + smtp_test[5].smtp_test_pkt_data = &response_250_sender_ok_pkt[0]; + smtp_test[5].smtp_test_pkt_size = response_250_sender_ok_size; + smtp_test[6].smtp_test_pkt_data = &response_250_recipient_ok_pkt[0]; + smtp_test[6].smtp_test_pkt_size = response_250_recipient_ok_size; + smtp_test[7].smtp_test_pkt_data = &response_354_enter_mail_pkt[0]; + smtp_test[7].smtp_test_pkt_size = response_354_enter_mail_size; + + smtp_test[8].smtp_test_pkt_data = &response_250_message_saved_pkt[0]; + smtp_test[8].smtp_test_pkt_size = response_250_message_saved_size; + + smtp_test[9].smtp_test_pkt_data = &response_221_bye_pkt[0]; + smtp_test[9].smtp_test_pkt_size = response_221_bye_size; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_missing_last_250_EHLO_message_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SMTP Missing Last Packet EHLO Message Test................N/A\n"); + + test_control_return(3); +} +#endif + + diff --git a/test/regression/smtp_test/netx_smtp_two_packet_EHLO_auth_last_message_test.c b/test/regression/smtp_test/netx_smtp_two_packet_EHLO_auth_last_message_test.c new file mode 100644 index 00000000..6a44c09b --- /dev/null +++ b/test/regression/smtp_test/netx_smtp_two_packet_EHLO_auth_last_message_test.c @@ -0,0 +1,665 @@ +/* This NetX tests the SMTP client for handling a server 250 reply to EHLO which has multiple + 250 parameters. The AUTH parameters are located in the second packet, not the first! + + Note that the Client authentication type must be PLAIN for the sequence to succeed. */ + + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_smtp_client.h" +#else +#include "nx_smtp_client.h" +#endif + +#define DEMO_STACK_SIZE 2048 +#define SERVER_IPADR IP_ADDRESS(10, 2, 41, 1) +#define CLIENT_IPADR IP_ADDRESS(10, 2, 41, 10) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_PACKET_POOL server_packet_pool; +static NX_TCP_SOCKET server_socket; +static NX_SMTP_CLIENT smtp_client; + +#define SUBJECT_LINE "NetX Duo SMTP Client Demo" +#define MAIL_BODY ".NetX Duo SMTP client is a simple SMTP client implementation \r\n" \ + ".that allow embedded devices to send email to an SMTP server. \r\n" \ + "This feature is intended to allow a device to send simple status\r\n " \ + "reports using the most universal Internet application email.\r\n" \ + "The rest of this narrative is merely to supply this most interesting quote: \r\n" \ + "Perhaps the most vivid recollection of my youth is that of the local wheelmen, \r\n" \ + "led by my father, stopping at our home to eat pone, sip mint juleps, and flog \r\n" \ + "the field hands. This more than anything cultivated my life-long aversion \r\n" \ + "to bicycles. ~~ Tennessee Williams.\r\n\r\n" \ + "Nothing compares to the simple pleasure of a bike ride. --John F. Kennedy, (surely you've heard of him?)\r\n\r\n" \ + "Perhaps the most vivid recollection of my youth is that of being flogged \r\n" \ + "by the local wheelmen, along with the field hands, the postman, and a \r\n" \ + "young Tennessee Williams. This more than anything cultivated my life-long " \ + "aversion to his plays. -Truman Capote\r\n" \ + "When I see an adult on a bicycle, I do not despair for the future of the human race. H.G. Wells \r\n" \ + "during the Second World War, if the United States had retooled its \r\n" \ + "factories for manufacturing bicycles instead of munitions, we'd be one of \r\n" \ + "the healthiest, least oil-dependent, and most environmentally-sound \r\n" \ + "constituents in the Nazi empire today. -Ralph Nader." + + +#define PASSWORD "testpwd" +#define RECIPIENT_ADDRESS "recipient@domain.com" +#define LOCAL_DOMAIN "domain.com" +#define FROM_ADDRESS "recipient@domain.com" +#define USERNAME FROM_ADDRESS +#define SMTP_SERVER_PORT 25 + + +#define CLIENT_AUTHENTICATION_TYPE NX_SMTP_CLIENT_AUTH_PLAIN + +#if defined(__PRODUCT_NETXDUO__) +static NXD_ADDRESS server_ip_address; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_client; +#endif /* FEATURE_NX_IPV6 */ +#else +static ULONG server_ip_address; +#endif + +static UINT server_complete = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr); + +/* SMTP Tests. */ +static void smtp_test_initialize(); + +/* Send SMTP server response. */ +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number); + + +extern char response_220_greetings_pkt[185]; +extern int response_220_greetings_size; + + +/* These next two are the first and second packets of the EHLO message */ +extern char response_250_ehlo_first_no_auth_pkt[145]; +extern int response_250_ehlo_first_no_auth_size; + +extern char response_250_ehlo_last_with_auth_pkt[42]; +extern int response_250_ehlo_last_with_auth_size; + +extern char response_334_pkt[6]; +extern int response_334_size; + +extern char response_235_auth_passed_pkt[85]; +extern int response_235_auth_passed_size; + +extern char response_250_sender_ok_pkt[40]; +extern int response_250_sender_ok_size; + +extern char response_250_recipient_ok_pkt[43]; +extern int response_250_recipient_ok_size; + +extern char response_354_enter_mail_pkt[40]; +extern int response_354_enter_mail_size; + +extern char response_250_message_saved_pkt[92]; +extern int response_250_message_saved_size; + +extern char response_221_bye_pkt[80]; +extern int response_221_bye_size; + + +typedef struct SMTP_TEST_STRUCT +{ + char *smtp_test_pkt_data; + int smtp_test_pkt_size; +} SMTP_TEST; + + +#define MSG_COUNT 10 + +static SMTP_TEST smtp_test[MSG_COUNT]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_two_packet_EHLO_auth_last_message_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SMTP client thread. */ + tx_thread_create(&thread_client, "thread client", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_server, "thread server", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "SMTP CLient IP", CLIENT_IPADR, 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "SMTP Server IP", SERVER_IPADR, 0xFFFFFF00UL, &server_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + status += nx_tcp_enable(&server_ip); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; + + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status += nxd_ipv6_enable(&client_ip); + status += nxd_ipv6_enable(&server_ip); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&client_ip); + status += nxd_icmp_enable(&server_ip); + + /* Check enable status. */ + if (status) + error_counter++; + + /* Set source and destination address with global address. */ + server_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + server_ip_address.nxd_ip_address.v6[0] = 0x20010DB8; + server_ip_address.nxd_ip_address.v6[1] = 0x00010001; + server_ip_address.nxd_ip_address.v6[2] = 0x021122FF; + server_ip_address.nxd_ip_address.v6[3] = 0xFE334456; + + address_client.nxd_ip_version = NX_IP_VERSION_V6; + address_client.nxd_ip_address.v6[0] = 0x20010DB8; + address_client.nxd_ip_address.v6[1] = 0x00010001; + address_client.nxd_ip_address.v6[2] = 0x021122FF; + address_client.nxd_ip_address.v6[3] = 0xFE334499; + + status = nxd_ipv6_address_set(&client_ip, 0, &server_ip_address, 64, NX_NULL); + status = nxd_ipv6_address_set(&server_ip, 0, &address_client, 64, NX_NULL); + +#endif /* FEATURE_NX_IPV6 */ + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + +#if defined(__PRODUCT_NETXDUO__) + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + server_ip_address.nxd_ip_address.v4 = SERVER_IPADR; + + status = nxd_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + &server_ip_address, SMTP_SERVER_PORT); +#else + server_ip_address = SERVER_IPADR; + + status = nx_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + server_ip_address, SMTP_SERVER_PORT); +#endif + + if (status != NX_SUCCESS) + { + error_counter++; + } + + return; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG actual_status; +UINT wait_timeout = 300; + + + printf("NetX Test: SMTP Two Packet EHLO Message Auth Last Test..............."); + + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD and let server set up. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&client_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the server get set up first. */ + tx_thread_sleep(20); + + /* The SMTP test initialize. */ + smtp_test_initialize(); + + + /* Create a mail instance with the above text message and recipient info. */ + status = nx_smtp_mail_send(&smtp_client, RECIPIENT_ADDRESS, NX_SMTP_MAIL_PRIORITY_NORMAL, + SUBJECT_LINE, MAIL_BODY, strlen(MAIL_BODY)); + + /* Create a mail instance with the above text message and recipient info. */ + + /* Check for errors. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Give the server time to disconnect. */ + while(wait_timeout) + { + + if (server_complete) + break; + + tx_thread_sleep(20); + + wait_timeout -= 20; + } + + /* Release threadx resources used by client. */ + status = nx_smtp_client_delete(&smtp_client); + + /* Return the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +/* This thread task simulates SMTP server response to client requests. */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +ULONG port; +ULONG peer_address; +UINT i; +UCHAR *work_ptr; +ULONG actual_status; + + /* Check for earlier errors. */ + if(error_counter) + { + + return; + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a TCP socket act as the SMTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 8000, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the SMTP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SMTP_SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Act as the SMTP server to receive the SMTP Client query and send the SMTP response. */ + for (i = 0; i < MSG_COUNT; i++ ) + { + + if (i == 0) + { + /* This is the greeting, we don't wait to hear from client...*/ + } + else + { + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + if (i == 2) + { + + /* The Client should be muted; it is waiting for the + second part of the EHLO message. */ + + /* But we still want to send the next part of the EHLO message. */ + } + else + { + /* If this is not the EHLO message, this is an error. */ + error_counter++; + continue; + } + } + else if (i == 2) + { + + /* The server should not receive a packet. The Client is not supposed to respond yet. */ + error_counter++; + continue; + } + + else if (i == 3) + { + + /* The server should not receive another EHLO message. */ + if (!memcmp(my_packet -> nx_packet_prepend_ptr, "EHLO", 4)) + { + + error_counter++; + continue; + } + } + + /* Get the SMTP client TCP port. */ + status = nx_tcp_socket_peer_info_get(&server_socket, &peer_address, &port); + + /* Check status. */ + if (status) + { + error_counter++; + } + + + if (i == 8) + { + /* Look for 0x0D 0x0A 0x2E 0x0d 0x0A indiating end of mail message. */ + work_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length - 5; + + if ((*work_ptr == 0x0D) && + (*(work_ptr + 1) == 0x0A) && + (*(work_ptr + 2) == 0x2E) && + (*(work_ptr + 3) == 0x0D) && + (*(work_ptr + 4) == 0x0A)) + + { + + /* Done iwth message, wait for QUIT command from client. */ + } + else + { + + /* Stay in this state. */ + + i--; + nx_packet_release(my_packet); + continue; + } + } + + if (my_packet) + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + } + /* Send the SMTP response packet. */ + status = nx_smtp_response_packet_send(&server_socket, port, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + } + + /* Wait for Client process last message. */ + tx_thread_sleep(20); + + /* Unlisten and Unbind the TCP socket. */ + + status = nx_tcp_server_socket_unaccept(&server_socket); + status += nx_tcp_server_socket_unlisten(&server_ip, SMTP_SERVER_PORT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + server_complete = NX_TRUE; + +} + +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return status; + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + smtp_test[packet_number].smtp_test_pkt_data, + smtp_test[packet_number].smtp_test_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = smtp_test[packet_number].smtp_test_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static void smtp_test_initialize() +{ + smtp_test[0].smtp_test_pkt_data = &response_220_greetings_pkt[0]; + smtp_test[0].smtp_test_pkt_size = response_220_greetings_size; + smtp_test[1].smtp_test_pkt_data = &response_250_ehlo_first_no_auth_pkt[0]; + smtp_test[1].smtp_test_pkt_size = response_250_ehlo_first_no_auth_size; + smtp_test[2].smtp_test_pkt_data = &response_250_ehlo_last_with_auth_pkt[0]; + smtp_test[2].smtp_test_pkt_size = response_250_ehlo_last_with_auth_size; + smtp_test[3].smtp_test_pkt_data = &response_334_pkt[0]; + smtp_test[3].smtp_test_pkt_size = response_334_size; + smtp_test[4].smtp_test_pkt_data = &response_235_auth_passed_pkt[0]; + smtp_test[4].smtp_test_pkt_size = response_235_auth_passed_size; + + smtp_test[5].smtp_test_pkt_data = &response_250_sender_ok_pkt[0]; + smtp_test[5].smtp_test_pkt_size = response_250_sender_ok_size; + smtp_test[6].smtp_test_pkt_data = &response_250_recipient_ok_pkt[0]; + smtp_test[6].smtp_test_pkt_size = response_250_recipient_ok_size; + smtp_test[7].smtp_test_pkt_data = &response_354_enter_mail_pkt[0]; + smtp_test[7].smtp_test_pkt_size = response_354_enter_mail_size; + + smtp_test[8].smtp_test_pkt_data = &response_250_message_saved_pkt[0]; + smtp_test[8].smtp_test_pkt_size = response_250_message_saved_size; + + smtp_test[9].smtp_test_pkt_data = &response_221_bye_pkt[0]; + smtp_test[9].smtp_test_pkt_size = response_221_bye_size; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_two_packet_EHLO_auth_last_message_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SMTP Two Packet EHLO Message Auth Last Test...............N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/smtp_test/netx_smtp_two_packet_EHLO_message_test.c b/test/regression/smtp_test/netx_smtp_two_packet_EHLO_message_test.c new file mode 100644 index 00000000..3b771b05 --- /dev/null +++ b/test/regression/smtp_test/netx_smtp_two_packet_EHLO_message_test.c @@ -0,0 +1,666 @@ +/* This NetX tests the SMTP client for handling a server 250 reply to EHLO which has multiple + 250 parameters. It is supposed to parse the entire message over one or more packets for + the last 250 code. The last 250 code is followed by a space after the 250 code. The previous + 250 codes should have hyphens after them as per the SMTP protocol in RFC 2821*/ + + +#include "tx_api.h" +#include "nx_api.h" + + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_smtp_client.h" +#else +#include "nx_smtp_client.h" +#endif + +#define DEMO_STACK_SIZE 2048 +#define SERVER_IPADR IP_ADDRESS(10, 2, 41, 1) +#define CLIENT_IPADR IP_ADDRESS(10, 2, 41, 10) + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_client; +static TX_THREAD thread_server; + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static NX_IP server_ip; + + +static NX_PACKET_POOL server_packet_pool; +static NX_TCP_SOCKET server_socket; +static NX_SMTP_CLIENT smtp_client; + +#define SUBJECT_LINE "NetX Duo SMTP Client Demo" +#define MAIL_BODY ".NetX Duo SMTP client is a simple SMTP client implementation \r\n" \ + ".that allow embedded devices to send email to an SMTP server. \r\n" \ + "This feature is intended to allow a device to send simple status\r\n " \ + "reports using the most universal Internet application email.\r\n" \ + "The rest of this narrative is merely to supply this most interesting quote: \r\n" \ + "Perhaps the most vivid recollection of my youth is that of the local wheelmen, \r\n" \ + "led by my father, stopping at our home to eat pone, sip mint juleps, and flog \r\n" \ + "the field hands. This more than anything cultivated my life-long aversion \r\n" \ + "to bicycles. ~~ Tennessee Williams.\r\n\r\n" \ + "Nothing compares to the simple pleasure of a bike ride. --John F. Kennedy, (surely you've heard of him?)\r\n\r\n" \ + "Perhaps the most vivid recollection of my youth is that of being flogged \r\n" \ + "by the local wheelmen, along with the field hands, the postman, and a \r\n" \ + "young Tennessee Williams. This more than anything cultivated my life-long " \ + "aversion to his plays. -Truman Capote\r\n" \ + "When I see an adult on a bicycle, I do not despair for the future of the human race. H.G. Wells \r\n" \ + "during the Second World War, if the United States had retooled its \r\n" \ + "factories for manufacturing bicycles instead of munitions, we'd be one of \r\n" \ + "the healthiest, least oil-dependent, and most environmentally-sound \r\n" \ + "constituents in the Nazi empire today. -Ralph Nader." + + +#define PASSWORD "testpwd" +#define RECIPIENT_ADDRESS "recipient@domain.com" +#define LOCAL_DOMAIN "domain.com" +#define FROM_ADDRESS "recipient@domain.com" +#define USERNAME FROM_ADDRESS +#define SMTP_SERVER_PORT 25 + + +/* This uses one packet for the server's EHLO response to client. Otherwise it sends + two packets for the EHLO response. */ + +/* See the NetX Duo SMTP Client User Guide for how to set the authentication type. */ +#define CLIENT_AUTHENTICATION_TYPE NX_SMTP_CLIENT_AUTH_PLAIN + +#if defined(__PRODUCT_NETXDUO__) +static NXD_ADDRESS server_ip_address; +#ifdef FEATURE_NX_IPV6 +static NXD_ADDRESS address_client; +#endif /* FEATURE_NX_IPV6 */ +#else +static ULONG server_ip_address; +#endif + +static UINT server_complete = NX_FALSE; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG notify_calls = 0; + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req); +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr); + +/* SMTP Tests. */ +static void smtp_test_initialize(); + +/* Send SMTP server response. */ +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number); + + +extern char response_220_greetings_pkt[185]; +extern int response_220_greetings_size; + + +/* These next two are the first and second packets of the EHLO message */ +extern char response_250_ehlo_first_pkt[145]; +extern int response_250_ehlo_first_size; + +extern char response_250_ehlo_last_pkt[10]; +extern int response_250_ehlo_last_size; + +extern char response_334_pkt[6]; +extern int response_334_size; + +extern char response_235_auth_passed_pkt[85]; +extern int response_235_auth_passed_size; + +extern char response_250_sender_ok_pkt[40]; +extern int response_250_sender_ok_size; + +extern char response_250_recipient_ok_pkt[43]; +extern int response_250_recipient_ok_size; + +extern char response_354_enter_mail_pkt[40]; +extern int response_354_enter_mail_size; + +extern char response_250_message_saved_pkt[92]; +extern int response_250_message_saved_size; + +extern char response_221_bye_pkt[80]; +extern int response_221_bye_size; + + +typedef struct SMTP_TEST_STRUCT +{ + char *smtp_test_pkt_data; + int smtp_test_pkt_size; +} SMTP_TEST; + + +#define MSG_COUNT 10 + +static SMTP_TEST smtp_test[MSG_COUNT]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_two_packet_ehlo_message_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SMTP client thread. */ + tx_thread_create(&thread_client, "thread client", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + tx_thread_create(&thread_server, "thread server", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create server packet pool. */ + status = nx_packet_pool_create(&server_packet_pool, "NetX Main Packet Pool", 1536, pointer, 10*1536); + pointer = pointer + (10*1536); + + /* Check for pool creation error. */ + if (status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&client_ip, "SMTP CLient IP", CLIENT_IPADR, 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&server_ip, "SMTP Server IP", SERVER_IPADR, 0xFFFFFF00UL, &server_packet_pool, _nx_ram_network_driver_1024, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&client_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&server_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + error_counter++; + + /* Enable TCP traffic. */ + status = nx_tcp_enable(&client_ip); + status += nx_tcp_enable(&server_ip); + + /* Check for TCP enable errors. */ + if (status) + error_counter++; + + +#ifdef FEATURE_NX_IPV6 + /* Enable IPv6 traffic. */ + status += nxd_ipv6_enable(&client_ip); + status += nxd_ipv6_enable(&server_ip); + + /* Enable ICMP processing for both IP instances. */ + status += nxd_icmp_enable(&client_ip); + status += nxd_icmp_enable(&server_ip); + + /* Check enable status. */ + if (status) + error_counter++; + + /* Set source and destination address with global address. */ + server_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + server_ip_address.nxd_ip_address.v6[0] = 0x20010DB8; + server_ip_address.nxd_ip_address.v6[1] = 0x00010001; + server_ip_address.nxd_ip_address.v6[2] = 0x021122FF; + server_ip_address.nxd_ip_address.v6[3] = 0xFE334456; + + address_client.nxd_ip_version = NX_IP_VERSION_V6; + address_client.nxd_ip_address.v6[0] = 0x20010DB8; + address_client.nxd_ip_address.v6[1] = 0x00010001; + address_client.nxd_ip_address.v6[2] = 0x021122FF; + address_client.nxd_ip_address.v6[3] = 0xFE334499; + + status = nxd_ipv6_address_set(&client_ip, 0, &server_ip_address, 64, NX_NULL); + status = nxd_ipv6_address_set(&server_ip, 0, &address_client, 64, NX_NULL); + +#endif /* FEATURE_NX_IPV6 */ + + /* The demo client username and password is the authentication + data used when the server attempts to authentication the client. */ + +#if defined(__PRODUCT_NETXDUO__) + server_ip_address.nxd_ip_version = NX_IP_VERSION_V4; + server_ip_address.nxd_ip_address.v4 = SERVER_IPADR; + + status = nxd_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + &server_ip_address, SMTP_SERVER_PORT); +#else + server_ip_address = SERVER_IPADR; + + status = nx_smtp_client_create(&smtp_client, &client_ip, &client_packet_pool, + USERNAME, + PASSWORD, + FROM_ADDRESS, + LOCAL_DOMAIN, CLIENT_AUTHENTICATION_TYPE, + server_ip_address, SMTP_SERVER_PORT); +#endif + + if (status != NX_SUCCESS) + { + error_counter++; + } + + return; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +ULONG actual_status; +UINT wait_timeout = 300; + + + printf("NetX Test: SMTP Two Packet EHLO Message Test........................."); + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&client_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Let the server get set up first. */ + tx_thread_sleep(20); + + /* The SMTP test initialize. */ + smtp_test_initialize(); + + + /* Create a mail instance with the above text message and recipient info. */ + status = nx_smtp_mail_send(&smtp_client, RECIPIENT_ADDRESS, NX_SMTP_MAIL_PRIORITY_NORMAL, + SUBJECT_LINE, MAIL_BODY, strlen(MAIL_BODY)); + + /* Create a mail instance with the above text message and recipient info. */ + + /* Check for errors. */ + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Give the server time to disconnect. */ + while(wait_timeout) + { + + if (server_complete) + break; + + tx_thread_sleep(20); + + wait_timeout -= 20; + } + + /* Release threadx resources used by client. */ + status = nx_smtp_client_delete(&smtp_client); + + /* Return the test result. */ + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +/* This thread task simulates SMTP server response to client requests. */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *my_packet; +ULONG port; +ULONG peer_address; +UINT i; +UCHAR *work_ptr; +ULONG actual_status; + + /* Check for earlier errors. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + +#ifdef FEATURE_NX_IPV6 + /* Sleep 5 seconds to finish DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); +#endif /* FEATURE_NX_IPV6 */ + + /* Ensure the IP instance has been initialized. */ + status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100); + + /* Check status...*/ + if(status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create a TCP socket act as the SMTP server. */ + status = nx_tcp_socket_create(&server_ip, &server_socket, "Socket 1", + NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, + 8000, NX_NULL, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Register the receive notify function. */ + status = nx_tcp_socket_receive_notify(&server_socket, receive_packet_function); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Bind the TCP socket to the SMTP port. */ + status = nx_tcp_server_socket_listen(&server_ip, SMTP_SERVER_PORT, &server_socket, 5, NX_NULL); + + /* Check status. */ + if (status) + { + error_counter++; + } + + status = nx_tcp_server_socket_accept(&server_socket, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Act as the SMTP server to receive the SMTP Client query and send the SMTP response. */ + for (i = 0; i < MSG_COUNT; i++ ) + { + + if (i == 0) + { + /* This is the greeting, we don't wait to hear from client...*/ + } + else + { + /* Receive a TCP packet. */ + status = nx_tcp_socket_receive(&server_socket, &my_packet, NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status) + { + + if (i == 2) + { + + /* The Client should be muted; it is waiting for the + second part of the EHLO message. */ + + /* But we still want to send the next part of the EHLO message. */ + } + else + { + /* If this is not the EHLO message, this is an error. */ + error_counter++; + continue; + } + } + else if (i == 2) + { + + /* The server should not receive a packet. The Client is not supposed to respond yet. */ + error_counter++; + continue; + } + + else if (i == 3) + { + + /* The server should not receive another EHLO message. */ + if (!memcmp(my_packet -> nx_packet_prepend_ptr, "EHLO", 4)) + { + + error_counter++; + continue; + } + } + + /* Get the SMTP client TCP port. */ + status = nx_tcp_socket_peer_info_get(&server_socket, &peer_address, &port); + + /* Check status. */ + if (status) + { + error_counter++; + } + + + if (i == 8) + { + /* Look for 0x0D 0x0A 0x2E 0x0d 0x0A indiating end of mail message. */ + work_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length - 5; + + if ((*work_ptr == 0x0D) && + (*(work_ptr + 1) == 0x0A) && + (*(work_ptr + 2) == 0x2E) && + (*(work_ptr + 3) == 0x0D) && + (*(work_ptr + 4) == 0x0A)) + + { + + /* Done iwth message, wait for QUIT command from client. */ + } + else + { + + /* Stay in this state. */ + + i--; + nx_packet_release(my_packet); + continue; + } + } + if (my_packet) + { + + /* Release the packet. */ + nx_packet_release(my_packet); + } + } + /* Send the SMTP response packet. */ + status = nx_smtp_response_packet_send(&server_socket, port, i); + + /* Check status. */ + if (status) + { + error_counter++; + } + + } + + /* Wait for Client process last message. */ + tx_thread_sleep(20); + + /* Unlisten and Unbind the TCP socket. */ + + status = nx_tcp_server_socket_unaccept(&server_socket); + status += nx_tcp_server_socket_unlisten(&server_ip, SMTP_SERVER_PORT); + + /* Check status. */ + if (status) + { + error_counter++; + } + + /* Delete the TCP socket. */ + status = nx_tcp_socket_delete(&server_socket); + + /* Check status. */ + if (status) + { + error_counter++; + } + + server_complete = NX_TRUE; + +} + +static void receive_packet_function(NX_TCP_SOCKET *socket_ptr) +{ + + if (socket_ptr == &server_socket) + notify_calls++; +} + +static UINT nx_smtp_response_packet_send(NX_TCP_SOCKET *server_socket, UINT port, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&server_packet_pool, &response_packet, NX_TCP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return status; + } + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + smtp_test[packet_number].smtp_test_pkt_data, + smtp_test[packet_number].smtp_test_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = smtp_test[packet_number].smtp_test_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + + /* Send the TCP packet with the correct port. */ + status = nx_tcp_socket_send(server_socket, response_packet, 100); + + /* Check the status. */ + if (status) + { + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + +static void smtp_test_initialize() +{ + smtp_test[0].smtp_test_pkt_data = &response_220_greetings_pkt[0]; + smtp_test[0].smtp_test_pkt_size = response_220_greetings_size; + smtp_test[1].smtp_test_pkt_data = &response_250_ehlo_first_pkt[0]; + smtp_test[1].smtp_test_pkt_size = response_250_ehlo_first_size; + smtp_test[2].smtp_test_pkt_data = &response_250_ehlo_last_pkt[0]; + smtp_test[2].smtp_test_pkt_size = response_250_ehlo_last_size; + smtp_test[3].smtp_test_pkt_data = &response_334_pkt[0]; + smtp_test[3].smtp_test_pkt_size = response_334_size; + smtp_test[4].smtp_test_pkt_data = &response_235_auth_passed_pkt[0]; + smtp_test[4].smtp_test_pkt_size = response_235_auth_passed_size; + + smtp_test[5].smtp_test_pkt_data = &response_250_sender_ok_pkt[0]; + smtp_test[5].smtp_test_pkt_size = response_250_sender_ok_size; + smtp_test[6].smtp_test_pkt_data = &response_250_recipient_ok_pkt[0]; + smtp_test[6].smtp_test_pkt_size = response_250_recipient_ok_size; + smtp_test[7].smtp_test_pkt_data = &response_354_enter_mail_pkt[0]; + smtp_test[7].smtp_test_pkt_size = response_354_enter_mail_size; + + smtp_test[8].smtp_test_pkt_data = &response_250_message_saved_pkt[0]; + smtp_test[8].smtp_test_pkt_size = response_250_message_saved_size; + + smtp_test[9].smtp_test_pkt_data = &response_221_bye_pkt[0]; + smtp_test[9].smtp_test_pkt_size = response_221_bye_size; + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_smtp_two_packet_ehlo_message_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SMTP Two Packet EHLO Message Test.........................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/smtp_test/smtp_server_packets.c b/test/regression/smtp_test/smtp_server_packets.c new file mode 100644 index 00000000..af021d4e --- /dev/null +++ b/test/regression/smtp_test/smtp_server_packets.c @@ -0,0 +1,299 @@ +/* Frame (239 bytes) */ +char response_220_greetings_pkt[185] = { +0x32, 0x32, /* ...v..22 */ +0x30, 0x2d, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, /* 0-expres */ +0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, /* slogic.c */ +0x6f, 0x6d, 0x20, 0x45, 0x53, 0x4d, 0x54, 0x50, /* om ESMTP */ +0x20, 0x4d, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, /* MDaemon */ +0x20, 0x31, 0x33, 0x2e, 0x30, 0x2e, 0x33, 0x3b, /* 13.0.3; */ +0x20, 0x53, 0x61, 0x74, 0x2c, 0x20, 0x32, 0x33, /* Sat, 23 */ +0x20, 0x4d, 0x61, 0x72, 0x20, 0x32, 0x30, 0x31, /* Mar 201 */ +0x33, 0x20, 0x32, 0x32, 0x3a, 0x35, 0x38, 0x3a, /* 3 22:58: */ +0x31, 0x35, 0x20, 0x2d, 0x30, 0x37, 0x30, 0x30, /* 15 -0700 */ +0x0d, 0x0a, 0x32, 0x32, 0x30, 0x2d, 0x41, 0x6c, /* ..220-Al */ +0x6c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, /* l transa */ +0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x61, /* ctions a */ +0x6e, 0x64, 0x20, 0x49, 0x50, 0x20, 0x61, 0x64, /* nd IP ad */ +0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x20, /* dresses */ +0x61, 0x72, 0x65, 0x20, 0x6c, 0x6f, 0x67, 0x67, /* are logg */ +0x65, 0x64, 0x2e, 0x0d, 0x0a, 0x32, 0x32, 0x30, /* ed...220 */ +0x2d, 0x2a, 0x0d, 0x0a, 0x32, 0x32, 0x30, 0x20, /* -*..220 */ +0x55, 0x6e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, /* Unauthor */ +0x69, 0x7a, 0x65, 0x64, 0x20, 0x72, 0x65, 0x6c, /* ized rel */ +0x61, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, /* aying is */ +0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x6c, /* strictl */ +0x79, 0x20, 0x70, 0x72, 0x6f, 0x68, 0x69, 0x62, /* y prohib */ +0x69, 0x74, 0x65, 0x64, 0x2e, 0x0d, 0x0a /* ited... */ +}; + +int response_220_greetings_size = 185; + +/* Frame (80 bytes) */ +char response_221_bye_pkt[80] = { +0x32, 0x32, /* .%^...22 */ +0x31, 0x20, 0x53, 0x65, 0x65, 0x20, 0x79, 0x61, /* 1 See ya */ +0x20, 0x69, 0x6e, 0x20, 0x63, 0x79, 0x62, 0x65, /* in cybe */ +0x72, 0x73, 0x70, 0x61, 0x63, 0x65, 0x0d, 0x0a /* rspace.. */ +}; + +int response_221_bye_size = 80; + +/* Frame (85 bytes with all headers) */ +char response_235_auth_passed_pkt[31] = { + +0x32, 0x33, /* .p.K..23 */ +0x35, 0x20, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, /* 5 Authen */ +0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, /* tication */ +0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, /* success */ +0x66, 0x75, 0x6c, 0x0d, 0x0a /* ful.. */ +}; + +int response_235_auth_passed_size = 31; + +/* Frame (199 bytes with ETH, IP and TCP headers) */ +char response_250_ehlo_first_pkt[145] = { + +0x32, 0x35, /* .25 */ +0x30, 0x2d, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, /* 0-expres */ +0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, /* slogic.c */ +0x6f, 0x6d, 0x20, 0x48, 0x65, 0x6c, 0x6c, 0x6f, /* om Hello */ +0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x63, /* testrec */ +0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, 0x65, /* ipient@e */ +0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, 0x6f, /* xpresslo */ +0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, /* gic.com, */ +0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, /* pleased */ +0x20, 0x74, 0x6f, 0x20, 0x6d, 0x65, 0x65, 0x74, /* to meet */ +0x20, 0x79, 0x6f, 0x75, 0x0d, 0x0a, 0x32, 0x35, /* you..25 */ +0x30, 0x2d, 0x45, 0x54, 0x52, 0x4e, 0x0d, 0x0a, /* 0-ETRN.. */ +0x32, 0x35, 0x30, 0x2d, 0x41, 0x55, 0x54, 0x48, /* 250-AUTH */ +0x20, 0x4c, 0x4f, 0x47, 0x49, 0x4e, 0x20, 0x43, /* LOGIN C */ +0x52, 0x41, 0x4d, 0x2d, 0x4d, 0x44, 0x35, 0x20, /* RAM-MD5 */ +0x50, 0x4c, 0x41, 0x49, 0x4e, 0x0d, 0x0a, 0x32, /* PLAIN..2 */ +0x35, 0x30, 0x2d, 0x38, 0x42, 0x49, 0x54, 0x4d, /* 50-8BITM */ +0x49, 0x4d, 0x45, 0x0d, 0x0a, 0x32, 0x35, 0x30, /* IME..250 */ +0x2D, 0x53, 0x49, 0x5a, 0x45, 0x0d, 0x0a /* SIZE.. */ +}; + +int response_250_ehlo_first_size = 145; + +/* Frame (199 bytes with ETH, IP and TCP headers) */ +char response_250_ehlo_last_pkt[10] = { + +0x32, 0x35, 0x30, /* 250 */ +0x20, 0x53, 0x49, 0x5a, 0x45, 0x0d, 0x0a /* [sp]SIZE.. */ +}; + +int response_250_ehlo_last_size = 10; + +/************************************************************************/ + + +/* Frame (199 bytes with ETH, IP and TCP headers) */ +char response_250_ehlo_first_no_auth_pkt[145] = { + +0x32, 0x35, /* .25 */ +0x30, 0x2d, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, /* 0-expres */ +0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, /* slogic.c */ +0x6f, 0x6d, 0x20, 0x48, 0x65, 0x6c, 0x6c, 0x6f, /* om Hello */ +0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x63, /* testrec */ +0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, 0x65, /* ipient@e */ +0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, 0x6f, /* xpresslo */ +0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, /* gic.com, */ +0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, /* pleased */ +0x20, 0x74, 0x6f, 0x20, 0x6d, 0x65, 0x65, 0x74, /* to meet */ +0x20, 0x79, 0x6f, 0x75, 0x0d, 0x0a, 0x32, 0x35, /* you..25 */ +0x30, 0x2d, 0x45, 0x54, 0x52, 0x4e, 0x0d, 0x0a, /* 0-ETRN.. */ +0x32, 0x35, 0x30, 0x2d, 0x45, 0x55, 0x54, 0x48, /* 250-DUTH */ +0x20, 0x4d, 0x4f, 0x47, 0x49, 0x4e, 0x20, 0x43, /* MOGIN C */ +0x52, 0x41, 0x4d, 0x2d, 0x4d, 0x44, 0x35, 0x20, /* RAM-MD5 */ +0x51, 0x4c, 0x41, 0x49, 0x4e, 0x0d, 0x0a, 0x32, /* QLAIN..2 */ +0x35, 0x30, 0x2d, 0x38, 0x42, 0x49, 0x54, 0x4d, /* 50-8BITM */ +0x49, 0x4d, 0x45, 0x0d, 0x0a, 0x32, 0x35, 0x30, /* IME..250 */ +0x2D, 0x53, 0x49, 0x5a, 0x45, 0x0d, 0x0a /* SIZE.. */ +}; + +int response_250_ehlo_first_no_auth_size = 145; + + +/************************************************************************/ + + +/* Frame (199 bytes with ETH, IP and TCP headers) */ +char response_250_ehlo_auth_no_type_pkt[145] = { + +0x32, 0x35, /* .25 */ +0x30, 0x2d, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, /* 0-expres */ +0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, /* slogic.c */ +0x6f, 0x6d, 0x20, 0x48, 0x65, 0x6c, 0x6c, 0x6f, /* om Hello */ +0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x63, /* testrec */ +0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, 0x65, /* ipient@e */ +0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, 0x6f, /* xpresslo */ +0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, /* gic.com, */ +0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, /* pleased */ +0x20, 0x74, 0x6f, 0x20, 0x6d, 0x65, 0x65, 0x74, /* to meet */ +0x20, 0x79, 0x6f, 0x75, 0x0d, 0x0a, 0x32, 0x35, /* you..25 */ +0x30, 0x2d, 0x45, 0x54, 0x52, 0x4e, 0x0d, 0x0a, /* 0-ETRN.. */ +0x32, 0x35, 0x30, 0x2d, 0x41, 0x55, 0x54, 0x48, /* 250-AUTH */ +0x20, 0x4d, 0x4f, 0x47, 0x49, 0x4e, 0x20, 0x43, /* MOGIN C */ +0x52, 0x41, 0x4d, 0x2d, 0x4d, 0x44, 0x35, 0x20, /* RAM-MD5 */ +0x51, 0x4c, 0x41, 0x49, 0x4e, 0x0d, 0x0a, 0x32, /* QLAIN..2 */ +0x35, 0x30, 0x2d, 0x38, 0x42, 0x49, 0x54, 0x4d, /* 50-8BITM */ +0x49, 0x4d, 0x45, 0x0d, 0x0a, 0x32, 0x35, 0x30, /* IME..250 */ +0x20, 0x53, 0x49, 0x5a, 0x45, 0x0d, 0x0a /* SIZE.. */ +}; + +int response_250_ehlo_auth_no_type_size = 145; + +/* Frame (199 bytes with ETH, IP and TCP headers) */ +char response_250_ehlo_last_with_auth_pkt[42] = { + +0x32, 0x35, 0x30, 0x2d, 0x41, 0x55, 0x54, 0x48, /* 250-AUTH */ +0x20, 0x4c, 0x4f, 0x47, 0x49, 0x4e, 0x20, 0x43, /* LOGIN C */ +0x52, 0x41, 0x4d, 0x2d, 0x4d, 0x44, 0x35, 0x20, /* RAM-MD5 */ +0x50, 0x4c, 0x41, 0x49, 0x4e, 0x0d, 0x0a, 0x20, /* PLAIN.. */ +0x32, 0x35, 0x30, 0x20, 0x53, 0x49, 0x5a, 0x45, /* 250 SIZE */ +0x0d, 0x0a /* .. */ +}; + +int response_250_ehlo_last_with_auth_size = 42; +/************************************************************************/ + +/* Frame (199 bytes with ETH, IP and TCP headers) */ +char response_250_ehlo_notlast_pkt[10] = { + +0x32, 0x35, 0x30, /* 250 */ +0x2d, 0x53, 0x49, 0x5a, 0x45, 0x0d, 0x0a /* [sp]SIZE.. */ +}; + +int response_250_ehlo_notlast_size = 10; + +/* Frame (199 bytes with ETH, IP and TCP headers) */ +char response_250_ehlo_pkt[145] = { + +0x32, 0x35, /* ...L..25 */ +0x30, 0x2d, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, /* 0-expres */ +0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, /* slogic.c */ +0x6f, 0x6d, 0x20, 0x48, 0x65, 0x6c, 0x6c, 0x6f, /* om Hello */ +0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x63, /* testrec */ +0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, 0x65, /* ipient@e */ +0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, 0x6f, /* xpresslo */ +0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, /* gic.com, */ +0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, /* pleased */ +0x20, 0x74, 0x6f, 0x20, 0x6d, 0x65, 0x65, 0x74, /* to meet */ +0x20, 0x79, 0x6f, 0x75, 0x0d, 0x0a, 0x32, 0x35, /* you..25 */ +0x30, 0x2d, 0x45, 0x54, 0x52, 0x4e, 0x0d, 0x0a, /* 0-ETRN.. */ +0x32, 0x35, 0x30, 0x2d, 0x41, 0x55, 0x54, 0x48, /* 250-AUTH */ +0x20, 0x4c, 0x4f, 0x47, 0x49, 0x4e, 0x20, 0x43, /* LOGIN C */ +0x52, 0x41, 0x4d, 0x2d, 0x4d, 0x44, 0x35, 0x20, /* RAM-MD5 */ +0x50, 0x4c, 0x41, 0x49, 0x4e, 0x0d, 0x0a, 0x32, /* PLAIN..2 */ +0x35, 0x30, 0x2d, 0x38, 0x42, 0x49, 0x54, 0x4d, /* 50-8BITM */ +0x49, 0x4d, 0x45, 0x0d, 0x0a, 0x32, 0x35, 0x30, /* IME..250 */ +0x20, 0x53, 0x49, 0x5a, 0x45, 0x0d, 0x0a /* SIZE.. */ +}; + +int response_250_ehlo_size = 145; + +/* Frame (199 bytes with ETH, IP and TCP headers) */ +char response_250_ehlo_noauth_pkt[145] = { + +0x32, 0x35, /* ...L..25 */ +0x30, 0x2d, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, /* 0-expres */ +0x73, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x2e, 0x63, /* slogic.c */ +0x6f, 0x6d, 0x20, 0x48, 0x65, 0x6c, 0x6c, 0x6f, /* om Hello */ +0x20, 0x74, 0x65, 0x73, 0x74, 0x72, 0x65, 0x63, /* testrec */ +0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x40, 0x65, /* ipient@e */ +0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x6c, 0x6f, /* xpresslo */ +0x67, 0x69, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, /* gic.com, */ +0x20, 0x70, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, /* pleased */ +0x20, 0x74, 0x6f, 0x20, 0x6d, 0x65, 0x65, 0x74, /* to meet */ +0x20, 0x79, 0x6f, 0x75, 0x0d, 0x0a, 0x32, 0x35, /* you..25 */ +0x30, 0x2d, 0x45, 0x54, 0x52, 0x4e, 0x0d, 0x0a, /* 0-ETRN.. */ +0x32, 0x35, 0x30, 0x2d, 0x44, 0x55, 0x54, 0x48, /* 250-CUTH */ +0x20, 0x4E, 0x4f, 0x47, 0x49, 0x4e, 0x20, 0x43, /* NOGIN C */ +0x52, 0x41, 0x4d, 0x2d, 0x4d, 0x44, 0x35, 0x20, /* RAM-MD5 */ +0x52, 0x4c, 0x41, 0x49, 0x4e, 0x0d, 0x0a, 0x32, /* SLAIN..2 */ +0x35, 0x30, 0x2d, 0x38, 0x42, 0x49, 0x54, 0x4d, /* 50-8BITM */ +0x49, 0x4d, 0x45, 0x0d, 0x0a, 0x32, 0x35, 0x30, /* IME..250 */ +0x20, 0x53, 0x49, 0x5a, 0x45, 0x0d, 0x0a /* SIZE.. */ +}; + +int response_250_ehlo_noauth_size = 145; + +/* Frame (92 bytes) */ +char response_250_message_saved_pkt[38] = { +0x32, 0x35, /* .+....25 */ +0x30, 0x20, 0x4f, 0x6b, 0x2c, 0x20, 0x6d, 0x65, /* 0 Ok, me */ +0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x61, /* ssage sa */ +0x76, 0x65, 0x64, 0x20, 0x3c, 0x4d, 0x65, 0x73, /* ved .. */ +}; + +int response_250_message_saved_size = 38; + +/* Frame (97 bytes) */ +char response_250_recipient_ok_pkt[43] = { + +0x32, 0x35, /* .,.N..25 */ +0x30, 0x20, 0x3c, 0x72, 0x65, 0x63, 0x69, 0x70, /* 0 , Recip */ +0x69, 0x65, 0x6e, 0x74, 0x20, 0x6f, 0x6b, 0x0d, /* ient ok. */ +0x0a /* . */ +}; + +int response_250_recipient_ok_size = 43; + +/* Frame (94 bytes all headers) */ +char response_250_sender_ok_pkt[40] = { +0x32, 0x35, /* .ME9..25 */ +0x30, 0x20, 0x3c, 0x72, 0x65, 0x63, 0x69, 0x70, /* 0 , Sende */ +0x72, 0x20, 0x6f, 0x6b, 0x0d, 0x0a /* r ok.. */ +}; + +int response_250_sender_ok_size = 40; + +/* Frame (72 bytes) */ +char response_334_password_pkt[72] = { +0x33, 0x33, /* ......33 */ +0x34, 0x20, 0x55, 0x47, 0x46, 0x7a, 0x63, 0x33, /* 4 UGFzc3 */ +0x64, 0x76, 0x63, 0x6d, 0x51, 0x36, 0x0d, 0x0a /* dvcmQ6.. */ +}; + +int response_334_password_size = 18; + +/* Frame (72 bytes) */ +char response_334_username_pkt[18] = { +0x33, 0x33, /* ......33 */ +0x34, 0x20, 0x56, 0x58, 0x4e, 0x6c, 0x63, 0x6d, /* 4 VXNlcm */ +0x35, 0x68, 0x62, 0x57, 0x55, 0x36, 0x0d, 0x0a /* 5hbWU6.. */ +}; + +int response_334_username_size = 18; + +/* Frame (94 bytes) */ +char response_354_enter_mail_pkt[40] = { + +0x33, 0x35, /* 35 */ +0x34, 0x20, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x20, /* 4 Enter */ +0x6d, 0x61, 0x69, 0x6c, 0x2c, 0x20, 0x65, 0x6e, /* mail, en */ +0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x3c, /* d with < */ +0x43, 0x52, 0x4c, 0x46, 0x3e, 0x2e, 0x3c, 0x43, /* CRLF>... */ +}; + +int response_354_enter_mail_size = 40; + +/* Frame (60 bytes with all headers) */ +char response_334_pkt[6] = +{ +0x33, 0x33, 0x34, 0x20, 0x0d, 0x0a /* 334 */ +}; + + +int response_334_size = 6; + diff --git a/test/regression/smtp_test/smtp_test_files.mk b/test/regression/smtp_test/smtp_test_files.mk new file mode 100644 index 00000000..2f86999c --- /dev/null +++ b/test/regression/smtp_test/smtp_test_files.mk @@ -0,0 +1,15 @@ +SMTP_TEST_LIB_SRCS = \ + netx_smtp_basic_function_test.c \ + smtp_250_ehlo_first_pkt.c \ + smtp_250_ehlo_last_pkt.c \ + smtp_250_ehlo_ok_pkt.c \ + smtp_220_greetings_ok.c \ + smtp_334_pkt.c \ + smtp_235_auth_passed.c \ + smtp_250_sender_ok.c \ + smtp_250_recipient_ok.c \ + smtp_354_enter_mail_pkt.c \ + smtp_250_message_saved.c \ + smtp_221_bye_pkt.c \ + +SMTP_TEST_LIB_OBJS = $(SMTP_TEST_LIB_SRCS:.c=.obj) diff --git a/test/regression/snmp_test/GetSet_IPv4v6Address.c b/test/regression/snmp_test/GetSet_IPv4v6Address.c new file mode 100644 index 00000000..3ce585e4 --- /dev/null +++ b/test/regression/snmp_test/GetSet_IPv4v6Address.c @@ -0,0 +1,57 @@ +/* SNMP_TESTING_GetSet_IPv4Addresses_LargeIntegers.pcap */ + +/* Frame 420 Set IPv4 address request 241.254.3.129 (89 bytes) */ + const unsigned char set_ipv4_address_request_pkt[47] = { +0x30, 0x2d, 0x02, 0x01, 0x00, 0x04, /* .X0-.... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x1f, 0x02, 0x01, 0x7a, 0x02, 0x01, 0x00, /* ....z... */ +0x02, 0x01, 0x00, 0x30, 0x14, 0x30, 0x12, 0x06, /* ...0.0.. */ +0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, /* .+...... */ +0x01, 0x03, 0x00, 0x40, 0x04, 0xf1, 0xfe, 0x03, /* ...@.... */ +0x81 /* . */ +}; + + int set_ipv4_address_request_size = 47; + +/* Frame 430 Get Request (84 bytes) */ + const unsigned char get_ipv4_address_request_pkt[42] = { +0x30, 0x28, 0x02, 0x01, 0x00, 0x04, /* .S0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x1b, 0x02, 0x01, 0x7b, 0x02, 0x01, 0x00, 0x02, /* ...{.... */ +0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, 0x01, /* +....... */ +0x03, 0x00, 0x05, 0x00 /* .... */ +}; + + + int get_ipv4_address_request_size = 42; + +/* SNMP Testing_GetSet_IPv6_Addresses.pcapng */ + +/* Frame 88 set IPv6 address 2001:0db7:0:f101:abcd:0064:0: 0207 (102 bytes) */ + const unsigned char set_ipv6_address_request_pkt[60] = { +0x30, 0x3a, 0x02, 0x01, 0x00, 0x04, /* .e0:.... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x2c, 0x02, 0x02, 0x00, 0x80, 0x02, 0x01, /* .,...... */ +0x00, 0x02, 0x01, 0x00, 0x30, 0x20, 0x30, 0x1e, /* ....0 0. */ +0x06, 0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x03, /* ..+..... */ +0x01, 0x01, 0x03, 0x01, 0x04, 0x10, 0x20, 0x01, /* ...... . */ +0x0d, 0xb7, 0x00, 0x00, 0xf1, 0x01, 0xab, 0xcd, /* ........ */ +0x00, 0x64, 0x00, 0x00, 0x02, 0x07 /* .d.... */ +}; + +int set_ipv6_address_request_size = 60; + +/* Frame 183 Get IPv6 address request (85 bytes) */ + const unsigned char get_ipv6_address_request_pkt[43] = { +0x30, 0x29, 0x02, 0x01, 0x00, 0x04, /* .T0).... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x1c, 0x02, 0x02, 0x00, 0x81, 0x02, 0x01, 0x00, /* ........ */ +0x02, 0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, /* ...0.0.. */ +0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, /* .+...... */ +0x01, 0x03, 0x01, 0x05, 0x00 /* ..... */ +}; + +int get_ipv6_address_request_size = 43; + + diff --git a/test/regression/snmp_test/GetSet_Integers_Large_and_Neg_Numbers.c b/test/regression/snmp_test/GetSet_Integers_Large_and_Neg_Numbers.c new file mode 100644 index 00000000..281e1d67 --- /dev/null +++ b/test/regression/snmp_test/GetSet_Integers_Large_and_Neg_Numbers.c @@ -0,0 +1,79 @@ +/* Get_Integers_Large_and_Neg_Numbers.c */ + +/* Set 255 1.3.6.1.2.1.4.1.0 Frame 28223 (85 bytes) */ +const unsigned char set_request_integer_255_pkt[43] = { +0x30, 0x29, 0x02, 0x01, 0x00, 0x04, /* .T0).... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x1b, 0x02, 0x01, 0x69, 0x02, 0x01, 0x00, /* ....i... */ +0x02, 0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, /* ...0.0.. */ +0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, 0x01, /* .+...... */ +0x00, 0x02, 0x02, 0x00, 0xff /* ..... */ +}; + +int set_request_integer_255_size = 43; + + +/* /* Get request 1.3.6.1.2.1.4.1.0 Frame 28256 Frame(82 bytes) */ +const unsigned char get_request_integer_255_pkt[40] = { +0x30, 0x26, 0x02, 0x01, 0x00, 0x04, /* .Q0&.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x19, 0x02, 0x01, 0x6a, 0x02, 0x01, 0x00, 0x02, /* ...j.... */ +0x01, 0x00, 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x08, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, 0x01, 0x00, /* +....... */ +0x05, 0x00 /* .. */ +}; + +int get_request_integer_255_size = 40; + +/* Set request neg 255 1.3.6.1.2.1.4.1.0 Frame 29094(85 bytes) */ +const unsigned char set_request_integer_neg255_pkt[43] = { +0x30, 0x29, 0x02, 0x01, 0x00, 0x04, /* .T0).... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x1b, 0x02, 0x01, 0x70, 0x02, 0x01, 0x00, /* ....p... */ +0x02, 0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, /* ...0.0.. */ +0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, 0x01, /* .+...... */ +0x00, 0x02, 0x02, 0xff, 0x01 /* ..... */ +}; + +int set_request_integer_neg255_size = 43; + + +/* Get request 1.3.6.1.2.1.4.1.0 Frame 29127 (82 bytes) */ +const unsigned char get_request_integer_neg255_pkt[40] = { +0x30, 0x26, 0x02, 0x01, 0x00, 0x04, /* .Q0&.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x19, 0x02, 0x01, 0x71, 0x02, 0x01, 0x00, 0x02, /* ...q.... */ +0x01, 0x00, 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x08, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, 0x01, 0x00, /* +....... */ +0x05, 0x00 /* .. */ +}; + + +int get_request_integer_neg255_size = 40; + + + +/* Set request -2345325 1.3.6.1.2.1.4.1.0 Frame 29488 (86 bytes) */ +unsigned char set_request_integer_neg2345345_pkt[44] = { +0x30, 0x2a, 0x02, 0x01, 0x00, 0x04, /* .U0*.... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x1c, 0x02, 0x01, 0x72, 0x02, 0x01, 0x00, /* ....r... */ +0x02, 0x01, 0x00, 0x30, 0x11, 0x30, 0x0f, 0x06, /* ...0.0.. */ +0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, 0x01, /* .+...... */ +0x00, 0x02, 0x03, 0xdc, 0x36, 0x7f /* ....6. */ +}; + +int set_request_integer_neg2345345_size = 44; + +/* Get request -2345325 1.3.6.1.2.1.4.1.0 Frame 29567 (82 bytes) */ +const unsigned char get_request_integer_neg2345345_pkt[40] = { +0x30, 0x26, 0x02, 0x01, 0x00, 0x04, /* .Q0&.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x19, 0x02, 0x01, 0x73, 0x02, 0x01, 0x00, 0x02, /* ...s.... */ +0x01, 0x00, 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x08, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, 0x01, 0x00, /* +....... */ +0x05, 0x00 /* .. */ +}; + +int get_request_integer_neg2345345_size = 40; + diff --git a/test/regression/snmp_test/GetSet_OctetStrings.c b/test/regression/snmp_test/GetSet_OctetStrings.c new file mode 100644 index 00000000..9ccdcd94 --- /dev/null +++ b/test/regression/snmp_test/GetSet_OctetStrings.c @@ -0,0 +1,58 @@ +/* SNMP_Testing_GET_SET_OctetStrings.pcap */ + +/* Frame 162 */ +const unsigned char set_request_octet_string_pkt[47] = { +0x30, 0x2d, 0x02, 0x01, 0x00, 0x04, /* .X0-.... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x1f, 0x02, 0x01, 0x74, 0x02, 0x01, 0x00, /* ....t... */ +0x02, 0x01, 0x00, 0x30, 0x14, 0x30, 0x12, 0x06, /* ...0.0.. */ +0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, /* .+...... */ +0x01, 0x02, 0x00, 0x04, 0x04, 0xff, 0x00, 0xf1, /* ........ */ +0xf2 /* . */ +}; + +int set_request_octet_string_size = 47; + + + +/* Frame (258) */ +const unsigned char get_request_octet_string_pkt[42] = { +0x30, 0x28, 0x02, 0x01, 0x00, 0x04, /* .S0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x1b, 0x02, 0x01, 0x75, 0x02, 0x01, 0x00, 0x02, /* ...u.... */ +0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, 0x01, /* +....... */ +0x02, 0x00, 0x05, 0x00 /* .... */ +}; + +int get_request_octet_string_size = 42; + + + +/* Frame 518 (88 bytes) */ +const unsigned char set_request_octet_string_leading_zero_pkt[64] = { +0x30, 0x2c, 0x02, 0x01, 0x00, 0x04, /* .W0,.... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x1e, 0x02, 0x01, 0x76, 0x02, 0x01, 0x00, /* ....v... */ +0x02, 0x01, 0x00, 0x30, 0x13, 0x30, 0x11, 0x06, /* ...0.0.. */ +0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, /* .+...... */ +0x01, 0x02, 0x00, 0x04, 0x03, 0x00, 0xf1, 0xf2 /* ........ */ +}; + + +int set_request_octet_string_leading_zero_size = 46; + + + +/* Frame 607(84 bytes) */ +const unsigned char get_request_octet_string_leading_zero_pkt[42] = { +0x30, 0x28, 0x02, 0x01, 0x00, 0x04, /* .S0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x1b, 0x02, 0x01, 0x77, 0x02, 0x01, 0x00, 0x02, /* ...w.... */ +0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, 0x01, /* +....... */ +0x02, 0x00, 0x05, 0x00 /* .... */ +}; + +int get_request_octet_string_leading_zero_size = 42; + diff --git a/test/regression/snmp_test/Get_Miscellaneous_Data_type.c b/test/regression/snmp_test/Get_Miscellaneous_Data_type.c new file mode 100644 index 00000000..5137cd82 --- /dev/null +++ b/test/regression/snmp_test/Get_Miscellaneous_Data_type.c @@ -0,0 +1,137 @@ +/* SNMP_TEsting_getset_counter32.pcapng */ + +/* set request counter 32 Frame 50 (89 bytes) */ +const unsigned char set_request_counter32_pkt[47] = { +0x30, 0x2d, 0x02, 0x01, 0x01, 0x04, /* .X0-.... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x1f, 0x02, 0x01, 0x6e, 0x02, 0x01, 0x00, /* ....n... */ +0x02, 0x01, 0x00, 0x30, 0x14, 0x30, 0x12, 0x06, /* ...0.0.. */ +0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, /* .+...... */ +0x01, 0x0a, 0x00, 0x41, 0x04, 0x01, 0xd2, 0x08, /* ...A.... */ +0xa5 /* . */ +}; + +int set_request_counter32_size = 47; + + +/* Get request counter 32 Frame 239 (84 bytes) */ + const unsigned char get_request_counter32_pkt[42] = { +0x30, 0x28, 0x02, 0x01, 0x01, 0x04, /* .S0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x1b, 0x02, 0x01, 0x6f, 0x02, 0x01, 0x00, 0x02, /* ...o.... */ +0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, /* +....... */ +0x0a, 0x00, 0x05, 0x00 /* .... */ +}; + +int get_request_counter32_size= 42; + +/* SNMP_TEsting_GetSet_Counter64.pcapng */ + +/* Set Counter64 Frame 186(90 bytes) */ +const unsigned char set_request_counter64_pkt[48] = { +0x30, 0x2e, 0x02, 0x01, 0x01, 0x04, /* .Y0..... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x20, 0x02, 0x01, 0x6a, 0x02, 0x01, 0x00, /* . ..j... */ +0x02, 0x01, 0x00, 0x30, 0x15, 0x30, 0x13, 0x06, /* ...0.0.. */ +0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, /* .+...... */ +0x01, 0x0b, 0x00, 0x46, 0x05, 0x00, 0xb6, 0x0b, /* ...F.... */ +0x60, 0xd7 /* `. */ +}; + +int set_request_counter64_size = 48; + + + +/* Get request counter 64 Frame 187(84 bytes) */ +const unsigned char get_request_counter64_pkt[42] = { +0x30, 0x28, 0x02, 0x01, 0x01, 0x04, /* .S0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x1b, 0x02, 0x01, 0x6b, 0x02, 0x01, 0x00, 0x02, /* ...k.... */ +0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, /* +....... */ +0x0b, 0x00, 0x05, 0x00 /* .... */ +}; + + +int get_request_counter64_size = 42; + +const unsigned char set_request_counter64_5bytes_pkt[49] = { +0x30, 0x2f, 0x02, 0x01, 0x01, 0x04, /* .Z0/.... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x21, 0x02, 0x01, 0x72, 0x02, 0x01, 0x00, /* .!..r... */ +0x02, 0x01, 0x00, 0x30, 0x16, 0x30, 0x14, 0x06, /* ...0.0.. */ +0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, /* .+...... */ +0x01, 0x0b, 0x00, 0x46, 0x06, 0x00, 0xd2, 0x42, /* ...F...B */ +0x39, 0x88, 0xd7 /* 9.. */ +}; + +int set_request_counter64_5bytes_size = 49; + +const unsigned char get_request_counter64_5bytes_pkt[42] = { +0x30, 0x28, 0x02, 0x01, 0x01, 0x04, /* .S0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x1b, 0x02, 0x01, 0x73, 0x02, 0x01, 0x00, 0x02, /* ...s.... */ +0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, /* +....... */ +0x0b, 0x00, 0x05, 0x00 /* .... */ +}; + +int get_request_counter64_5bytes_size = 42; + +/* SNMP_TESTING_GetSet_timertic.pcapng */ + +/* Set request timertic Frame 832 (89 bytes) */ +const unsigned char set_request_timertic_pkt[47] = { +0x30, 0x2d, 0x02, 0x01, 0x01, 0x04, /* .X0-.... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x1f, 0x02, 0x01, 0x56, 0x02, 0x01, 0x00, /* ....V... */ +0x02, 0x01, 0x00, 0x30, 0x14, 0x30, 0x12, 0x06, /* ...0.0.. */ +0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, /* .+...... */ +0x01, 0x09, 0x00, 0x43, 0x04, 0x01, 0xd2, 0x08, /* ...C.... */ +0xa5 /* . */ +}; + +int set_request_timertic_size = 47; + + +/* Get request timertic Frame 1740 (84 bytes) */ +const unsigned char get_request_timertic_pkt[42] = { +0x30, 0x28, 0x02, 0x01, 0x01, 0x04, /* .S0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x1b, 0x02, 0x01, 0x57, 0x02, 0x01, 0x00, 0x02, /* ...W.... */ +0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, /* +....... */ +0x09, 0x00, 0x05, 0x00 /* .... */ +}; + +int get_request_timertic_size = 42; + +/* SNMP_TESTING_GetSet_String.pcapng */ + +/* Set request string Frame 74(95 bytes) */ +const unsigned char set_request_string_pkt[53] = { +0x30, 0x33, 0x02, 0x01, 0x01, 0x04, /* .^03.... */ +0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, /* .private */ +0xa3, 0x25, 0x02, 0x01, 0x70, 0x02, 0x01, 0x00, /* .%..p... */ +0x02, 0x01, 0x00, 0x30, 0x1a, 0x30, 0x18, 0x06, /* ...0.0.. */ +0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, /* .+...... */ +0x00, 0x04, 0x0c, 0x6d, 0x79, 0x20, 0x73, 0x79, /* ...my sy */ +0x73, 0x74, 0x65, 0x6d, 0x20, 0x69, 0x64 /* stem id */ +}; + +int set_request_string_size = 53; + + +/* Get request string Frame 184(82 bytes) */ +const unsigned char get_request_string_pkt[40] = { +0x30, 0x26, 0x02, 0x01, 0x01, 0x04, /* .Q0&.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x19, 0x02, 0x01, 0x71, 0x02, 0x01, 0x00, 0x02, /* ...q.... */ +0x01, 0x00, 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x08, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00, /* +....... */ +0x05, 0x00 /* .. */ +}; + +int get_request_string_size = 40; + diff --git a/test/regression/snmp_test/get_snmp_v3_request.c b/test/regression/snmp_test/get_snmp_v3_request.c new file mode 100644 index 00000000..db685cab --- /dev/null +++ b/test/regression/snmp_test/get_snmp_v3_request.c @@ -0,0 +1,94 @@ +/* Frame (101 bytes) */ +const unsigned char get_v3_request_packet[101] = { +0x00, 0xcf, 0x54, 0x85, 0xc3, 0x01, 0xe0, 0x69, /* ..T....i */ +0x95, 0x6f, 0x7e, 0xed, 0x08, 0x00, 0x45, 0x00, /* .o~...E. */ +0x00, 0x57, 0x38, 0xb3, 0x00, 0x00, 0x80, 0x11, /* .W8..... */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0x59, 0xc0, 0x02, /* .....Y.. */ +0x02, 0x42, 0xea, 0x38, 0x00, 0xa1, 0x00, 0x43, /* .B.8...C */ +0x84, 0xf4, 0x30, 0x39, 0x02, 0x01, 0x03, 0x30, /* ..09...0 */ +0x0e, 0x02, 0x01, 0x0a, 0x02, 0x03, 0x00, 0xff, /* ........ */ +0xf0, 0x04, 0x01, 0x04, 0x02, 0x01, 0x03, 0x04, /* ........ */ +0x10, 0x30, 0x0e, 0x04, 0x00, 0x02, 0x01, 0x00, /* .0...... */ +0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, /* ........ */ +0x00, 0x30, 0x12, 0x04, 0x00, 0x04, 0x00, 0xa0, /* .0...... */ +0x0c, 0x02, 0x02, 0x00, 0xb4, 0x02, 0x01, 0x00, /* ........ */ +0x02, 0x01, 0x00, 0x30, 0x00 /* ...0. */ +}; + +int v3_request_size = 101; + +const unsigned char v3_report_packet[147] = { +0xe0, 0x69, 0x95, 0x6f, 0x7e, 0xed, 0x00, 0xcf, /* .i.o~... */ +0x54, 0x85, 0xc3, 0x01, 0x08, 0x00, 0x45, 0x00, /* T.....E. */ +0x00, 0x85, 0x00, 0x28, 0x40, 0x00, 0x80, 0x11, /* ...(@... */ +0x75, 0xa0, 0xc0, 0x02, 0x02, 0x42, 0xc0, 0x02, /* u....B.. */ +0x02, 0x59, 0x00, 0xa1, 0xea, 0x38, 0x00, 0x71, /* .Y...8.q */ +0x3e, 0x53, 0x30, 0x82, 0x00, 0x65, 0x02, 0x01, /* >S0..e.. */ +0x03, 0x30, 0x82, 0x00, 0x0d, 0x02, 0x01, 0x0a, /* .0...... */ +0x02, 0x02, 0x01, 0xf0, 0x04, 0x01, 0x00, 0x02, /* ........ */ +0x01, 0x03, 0x04, 0x1d, 0x30, 0x82, 0x00, 0x19, /* ....0... */ +0x04, 0x0b, 0x80, 0x00, 0x0d, 0xfe, 0x03, 0x00, /* ........ */ +0x77, 0x23, 0x23, 0x46, 0x69, 0x02, 0x01, 0x00, /* w##Fi... */ +0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, /* ........ */ +0x00, 0x30, 0x82, 0x00, 0x2e, 0x04, 0x0b, 0x80, /* .0...... */ +0x00, 0x0d, 0xfe, 0x03, 0x00, 0x77, 0x23, 0x23, /* .....w## */ +0x46, 0x69, 0x04, 0x00, 0xa8, 0x1d, 0x02, 0x02, /* Fi...... */ +0x00, 0xb4, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, /* ........ */ +0x30, 0x11, 0x30, 0x0f, 0x06, 0x0a, 0x2b, 0x06, /* 0.0...+. */ +0x01, 0x06, 0x03, 0x0f, 0x01, 0x01, 0x04, 0x00, /* ........ */ +0x41, 0x01, 0x01 /* A.. */ +}; + +int v3_report_size = 147; + +const unsigned char get_v3_next_request_packet[141] = { +0x00, 0xcf, 0x54, 0x85, 0xc3, 0x01, 0xe0, 0x69, /* ..T....i */ +0x95, 0x6f, 0x7e, 0xed, 0x08, 0x00, 0x45, 0x00, /* .o~...E. */ +0x00, 0x7f, 0x38, 0xb4, 0x00, 0x00, 0x80, 0x11, /* ..8..... */ +0x00, 0x00, 0xc0, 0x02, 0x02, 0x59, 0xc0, 0x02, /* .....Y.. */ +0x02, 0x42, 0xea, 0x38, 0x00, 0xa1, 0x00, 0x6b, /* .B.8...k */ +0x85, 0x1c, 0x30, 0x61, 0x02, 0x01, 0x03, 0x30, /* ..0a...0 */ +0x0e, 0x02, 0x01, 0x0b, 0x02, 0x03, 0x00, 0xff, /* ........ */ +0xf0, 0x04, 0x01, 0x04, 0x02, 0x01, 0x03, 0x04, /* ........ */ +0x20, 0x30, 0x1e, 0x04, 0x0b, 0x80, 0x00, 0x0d, /* 0...... */ +0xfe, 0x03, 0x00, 0x77, 0x23, 0x23, 0x46, 0x69, /* ...w##Fi */ +0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x04, 0x05, /* ........ */ +0x6a, 0x61, 0x6e, 0x65, 0x74, 0x04, 0x00, 0x04, /* janet... */ +0x00, 0x30, 0x2a, 0x04, 0x0b, 0x80, 0x00, 0x0d, /* .0*..... */ +0xfe, 0x03, 0x00, 0x77, 0x23, 0x23, 0x46, 0x69, /* ...w##Fi */ +0x04, 0x00, 0xa1, 0x19, 0x02, 0x02, 0x00, 0xb5, /* ........ */ +0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x0d, /* ......0. */ +0x30, 0x0b, 0x06, 0x07, 0x2b, 0x06, 0x01, 0x02, /* 0...+... */ +0x01, 0x01, 0x03, 0x05, 0x00 /* ..... */ +}; + +int v3_next_request_size = 141; + +const unsigned char v3_response_packet[154] = { +0xe0, 0x69, 0x95, 0x6f, 0x7e, 0xed, 0x00, 0xcf, /* .i.o~... */ +0x54, 0x85, 0xc3, 0x01, 0x08, 0x00, 0x45, 0x00, /* T.....E. */ +0x00, 0x8c, 0x00, 0x2e, 0x40, 0x00, 0x80, 0x11, /* ....@... */ +0x75, 0x93, 0xc0, 0x02, 0x02, 0x42, 0xc0, 0x02, /* u....B.. */ +0x02, 0x59, 0x00, 0xa1, 0xea, 0x38, 0x00, 0x78, /* .Y...8.x */ +0x44, 0x29, 0x30, 0x82, 0x00, 0x6c, 0x02, 0x01, /* D)0..l.. */ +0x03, 0x30, 0x82, 0x00, 0x0d, 0x02, 0x01, 0x0b, /* .0...... */ +0x02, 0x02, 0x01, 0xf0, 0x04, 0x01, 0x00, 0x02, /* ........ */ +0x01, 0x03, 0x04, 0x22, 0x30, 0x82, 0x00, 0x1e, /* ..."0... */ +0x04, 0x0b, 0x80, 0x00, 0x0d, 0xfe, 0x03, 0x00, /* ........ */ +0x77, 0x23, 0x23, 0x46, 0x69, 0x02, 0x01, 0x00, /* w##Fi... */ +0x02, 0x01, 0x00, 0x04, 0x05, 0x6a, 0x61, 0x6e, /* .....jan */ +0x65, 0x74, 0x04, 0x00, 0x04, 0x00, 0x30, 0x82, /* et....0. */ +0x00, 0x30, 0x04, 0x0b, 0x80, 0x00, 0x0d, 0xfe, /* .0...... */ +0x03, 0x00, 0x77, 0x23, 0x23, 0x46, 0x69, 0x04, /* ..w##Fi. */ +0x00, 0xa2, 0x1f, 0x02, 0x02, 0x00, 0xb5, 0x02, /* ........ */ +0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x82, 0x00, /* .....0.. */ +0x11, 0x30, 0x82, 0x00, 0x0d, 0x06, 0x08, 0x2b, /* .0.....+ */ +0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x43, /* .......C */ +0x01, 0x01 /* .. */ +}; + +int v3_response_size = 154; + + + + diff --git a/test/regression/snmp_test/netx_snmp_abnormal_packet_test.c b/test/regression/snmp_test/netx_snmp_abnormal_packet_test.c new file mode 100644 index 00000000..2645860a --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_abnormal_packet_test.c @@ -0,0 +1,489 @@ +/* This tests processing abornal packet. + */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#define DEMO_STACK_SIZE 4096 + +#if !defined(NX_DISABLE_IPV4) + +static NX_SNMP_SECURITY_KEY my_privacy_key; +static NX_SNMP_SECURITY_KEY my_authentication_key; + +static UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + + +static UINT query_response_complete = NX_FALSE; /* to synchronize when the agent sends the SNMP trap */ +#define QUERY_COUNT 4 + +/* To show byte by byte comparison of pre-recorded response with SNMP agent, define this option. +#define VERBOSE +*/ + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +static unsigned char test_get_request_pkt_v1[] = { +0x30, 0x28, 0x02, 0x01, 0x00, 0x04, /* ..0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x1b, 0x02, 0x01, 0x29, 0x02, 0x01, 0x00, 0x02, /* ...).... */ +0x01, 0x00, 0x30, 0x10, 0x30, 0x1e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, /* +....... */ +0x02, 0x00, 0x05, 0x00 /* .... */ +}; + +static unsigned char test_get_request_pkt_v3[] = { +0x30, 0x73, 0x02, 0x01, 0x03, 0x30, 0x11, 0x02, 0x04, 0x14, 0xa2, 0xd6, 0x5e, 0x02, 0x03, 0x00, +0xff, 0xe3, 0x04, 0x01, 0x04, 0x02, 0x01, 0x03, 0x04, 0x26, 0x30, 0x24, 0x04, 0x11, 0x80, 0x00, +0x1f, 0x88, 0x80, 0xb1, 0x98, 0x19, 0x38, 0x12, 0x6f, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x02, +0x01, 0x06, 0x02, 0x01, 0x00, 0x04, 0x05, 0x75, 0x73, 0x65, 0x72, 0x31, 0x04, 0x00, 0x04, 0x00, +0x30, 0x33, 0x04, 0x11, 0x80, 0x00, 0x1f, 0x88, 0x80, 0xb1, 0x98, 0x19, 0x38, 0x12, 0x6f, 0x40, +0x60, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x1c, 0x02, 0x04, 0x4c, 0x1f, 0xe2, 0x4d, 0x02, +0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x30, 0x1e, 0x06, 0x0a, +0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, +0x02, 0x00, 0x05, 0x00 +}; + +static unsigned char test_get_request_pkt_v3_1[] = { +0x30, 0x73, 0x02, 0x01, 0x03, 0x30, 0x11, 0x02, 0x04, 0x14, 0xa2, 0xd6, 0x5e, 0x02, 0x03, 0x00, +0xff, 0xe3, 0x04, 0x01, 0x07, 0x02, 0x01, 0x03, 0x04, 0x00, 0x30, 0x24, 0x04, 0x11, 0x80, 0x00, +0x1f, 0x88, 0x80, 0xb1, 0x98, 0x19, 0x38, 0x12, 0x6f, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x02, +0x01, 0x06, 0x02, 0x01, 0x00, 0x04, 0x05, 0x75, 0x73, 0x65, 0x72, 0x31, 0x04, 0x00, 0x04, 0x00, +0x30, 0x33, 0x04, 0x11, 0x80, 0x00, 0x1f, 0x88, 0x80, 0xb1, 0x98, 0x19, 0x38, 0x12, 0x6f, 0x40, +0x60, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x1c, 0x02, 0x04, 0x4c, 0x1f, 0xe2, 0x4d, 0x02, +0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x30, 0x1e, 0x06, 0x0a, +0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, +0x02, 0x00, 0x05, 0x00 +}; + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + +static UCHAR context_engine[] = {0x80, 0x00, 0x1f, 0x88, 0x80, 0xb1, 0x98, 0x19, 0x38, 0x12, 0x6f, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00}; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + status = tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + status += tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + /* Check for IP create errors. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 15000); + pointer = pointer + 10000; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer , 2048, 1); + + pointer += 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer += 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "public", &agent_ip, pointer, 4096, &pool_0, + v3_mib2_username_processing, v3_mib2_get_processing, + v3_mib2_getnext_processing, v3_mib2_set_processing); + pointer = pointer + 4096; + + if (status) + { + error_counter++; + } + + status = nx_snmp_agent_context_engine_set(&my_agent, context_engine, sizeof(context_engine)); + + status += nx_snmp_agent_v3_context_boots_set(&my_agent, 6); + + if (status) + { + error_counter++; + } + + return; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_SNMP_TRAP_OBJECT trap_list[7]; +NX_SNMP_OBJECT_DATA trap_data0; +NX_SNMP_OBJECT_DATA trap_data1; +UINT counter = 133; + + + printf("NetX Test: SNMP Abnormal Packet Test................................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + while (!query_response_complete) + { + tx_thread_sleep(20); + } + + trap_list[0].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.1.0"; + trap_list[0].nx_snmp_object_data = &trap_data0; + trap_data0.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data0.nx_snmp_object_data_msw = counter++; + + trap_list[1].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.7.0"; + trap_list[1].nx_snmp_object_data = &trap_data1; + trap_data1.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data1.nx_snmp_object_data_msw = counter++; + + /* Null terminate the list. */ + trap_list[2].nx_snmp_object_string_ptr = NX_NULL; + trap_list[2].nx_snmp_object_data = NX_NULL; + + my_agent.nx_snmp_agent_interface_index = 500; + status = nx_snmp_agent_trap_send(&my_agent, SNMP_MANAGER_ADDRESS, (UCHAR *)"trap", (UCHAR *) "1.3.6.1.2.1.1.3.0", NX_SNMP_TRAP_COLDSTART, 0, tx_time_get(), &trap_list[0]); + + if (status == NX_SUCCESS) + { + error_counter++; + } + +#ifndef NX_DISABLE_ERROR_CHECKING + status = nx_snmp_agent_set_interface(&my_agent, 200); + if (status == NX_SUCCESS) + { + error_counter++; + } +#endif + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +UINT i; +USHORT request_id = 1; + + + /* Let the agent get set up first! */ + tx_thread_sleep(30); + + + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the UDP socket to an IP port. */ + status |= nx_udp_socket_bind(&snmp_manager_socket, 0, 100); + + /* Check status. */ + if (status) + { + + error_counter++; + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + + return; + } + + /* Load the test data. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent.. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + if (i == 1) + { + my_agent.nx_snmp_agent_v3_message_security_options = 0x02; + nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)("privpassword"), &my_privacy_key); + nx_snmp_agent_privacy_key_use(&my_agent, &my_privacy_key); + } + + if (i == 2) + { + my_agent.nx_snmp_agent_v3_message_security_options = 0x01; + nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)("authpassword"), &my_authentication_key); + nx_snmp_agent_authenticate_key_use(&my_agent, &my_authentication_key); + } + + if (i == 3) + { + my_agent.nx_snmp_agent_v3_security_authentication_size = 0x0C; + } + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + error_counter++; + break; + } + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + request_id++; + } + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *query_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &query_packet, NX_UDP_PACKET, 100); + + /* Check status. */ + if (status) + { + return status; + } + + + memset(query_packet -> nx_packet_prepend_ptr, 0, (query_packet -> nx_packet_data_end - query_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(query_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + query_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + query_packet -> nx_packet_append_ptr = query_packet -> nx_packet_prepend_ptr + query_packet -> nx_packet_length; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, query_packet, SNMP_AGENT_ADDRESS, 161); + + /* Check the status. */ + if (status) + nx_packet_release(query_packet); + + return status; +} + + +static void snmp_test_initialize() +{ + + /* Contact - no security*/ + snmp_query[0].snmp_query_pkt_data = test_get_request_pkt_v3; + snmp_query[0].snmp_query_pkt_size = sizeof(test_get_request_pkt_v3); + snmp_query[1].snmp_query_pkt_data = test_get_request_pkt_v1; + snmp_query[1].snmp_query_pkt_size = sizeof(test_get_request_pkt_v1); + snmp_query[2].snmp_query_pkt_data = test_get_request_pkt_v1; + snmp_query[2].snmp_query_pkt_size = sizeof(test_get_request_pkt_v1); + snmp_query[3].snmp_query_pkt_data = test_get_request_pkt_v3_1; + snmp_query[3].snmp_query_pkt_size = sizeof(test_get_request_pkt_v3_1); +} + + +/* Define the application's GET processing routine. */ + +UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + error_counter++; + + /* Return the status. */ + return(NX_SUCCESS); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + + /* Return the status. */ + return(NX_SUCCESS); +} + + +/* Define the application's SET processing routine. */ + +UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + + /* Return the status. */ + return(NX_SUCCESS); +} + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + return(NX_SUCCESS); + +} + +/* Define the application's update routine. */ + +VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_abnormal_packet_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP Abnormal Packet Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/snmp_test/netx_snmp_basic_v2_test.c b/test/regression/snmp_test/netx_snmp_basic_v2_test.c new file mode 100644 index 00000000..a45d297e --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_basic_v2_test.c @@ -0,0 +1,668 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + three requests, Get, Get Next, and Get Bulk, and the SNMP agent responds. A successful + result means the Agent received and sent the expected number of messages, and no + internal SNMP errors were encountered. + + The MIB database is defined in demo_snmp_helper.h */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "small_mib_helper.h" // was demo_snmp_helper.h in the old MIB + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +extern MIB_ENTRY mib2_mib[]; + +static UINT v2query_response_complete = NX_FALSE; + +static UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +#define QUERY_COUNT 3 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT v2_my_agent; +static NX_PACKET_POOL v2_pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; + +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char simple_get_query_pkt[82]; +extern int simple_get_query_size; +extern char simple_get_next_query_pkt[82]; +extern int simple_get_next_query_size; +#if 1 +extern char simple_get_bulk_query_pkt[76]; +extern int simple_get_bulk_query_size; +#endif + + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_basic_v2_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&v2_pool_0, "NetX Main Packet Pool", 1000, pointer, 4096); + pointer = pointer + 4096; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&v2_my_agent, "SNMP Agent", &agent_ip, pointer, 4096, &v2_pool_0, + v2_mib2_username_processing, v2_mib2_get_processing, + v2_mib2_getnext_processing, v2_mib2_set_processing); + + if (status) + { + error_counter++; + } + + return; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + printf("NetX Test: SNMP Basic V2 Test........................................"); + + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&v2_my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Wait for the 'manager' to finish querying the Agent. */ + while (v2query_response_complete == NX_FALSE) + { + tx_thread_sleep(100); + } + + /* Check for correct internal counters of SNMP processing. */ + if ((v2_my_agent.nx_snmp_agent_get_requests != 1) || + (v2_my_agent.nx_snmp_agent_getnext_requests != 1) || + (v2_my_agent.nx_snmp_agent_getbulk_requests != 1) || + //(v2_my_agent.nx_snmp_agent_total_get_variables != 8) || + (v2_my_agent.nx_snmp_agent_packets_received != 3) || + (v2_my_agent.nx_snmp_agent_packets_sent != 3) || + (v2_my_agent.nx_snmp_agent_getresponse_sent != 3)) + { + error_counter++; + + printf("ERROR1!\n"); + test_control_return(1); + } + + /* Check for errors processing the requests. */ + if (v2_my_agent.nx_snmp_agent_invalid_packets || + v2_my_agent.nx_snmp_agent_internal_errors || + v2_my_agent.nx_snmp_agent_allocation_errors || + v2_my_agent.nx_snmp_agent_request_errors || + v2_my_agent.nx_snmp_agent_too_big_errors || + v2_my_agent.nx_snmp_agent_username_errors || + v2_my_agent.nx_snmp_agent_unknown_requests || + v2_my_agent.nx_snmp_agent_no_such_name_errors) + { + + error_counter++; + + printf("ERROR2!\n"); + test_control_return(1); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; + +} + +/* SNMP Manager thread */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT port; +UINT i; +USHORT request_id = 1; + + /* Let the agent get set up first! */ + tx_thread_sleep(50); + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&snmp_manager_socket, 161, 200); + + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + + printf("ERROR3!\n"); + test_control_return(1); + //break; + } + + /* Get the SNMP agent UDP port. */ + status = nx_udp_packet_info_extract(agent_packet, NX_NULL ,NX_NULL, &port, NX_NULL); + + /* Check status. */ + + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + + printf("ERROR4!\n"); + test_control_return(1); + //break; + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Indicate the test is complete. */ + v2query_response_complete = NX_TRUE; + + /* Unbind the UDP socket. */ + nx_udp_socket_unbind(&snmp_manager_socket); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&snmp_manager_socket); + + return; +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&v2_pool_0, &response_packet, NX_UDP_PACKET, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + return(1); + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, response_packet, IP_ADDRESS(10, 0, 0, 10), 161); + + /* Check the status. */ + if (status) + { + + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + + +static void snmp_test_initialize() +{ + + snmp_query[0].snmp_query_pkt_data = &simple_get_query_pkt[0]; + snmp_query[0].snmp_query_pkt_size = simple_get_query_size; + + + snmp_query[1].snmp_query_pkt_data = &simple_get_next_query_pkt[0]; + snmp_query[1].snmp_query_pkt_size = simple_get_next_query_size; +#if 1 + snmp_query[2].snmp_query_pkt_data = &simple_get_bulk_query_pkt[0]; + snmp_query[2].snmp_query_pkt_size = simple_get_bulk_query_size; +#endif +} + + +/* Define the application's GET processing routine. */ + +UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + if (mib2_mib[i].object_get_octet_callback) + { + + /* Call the get octet function (has a length input). */ + status = (mib2_mib[i].object_get_octet_callback)(mib2_mib[i].object_value_ptr, object_data, mib2_mib[i].length); + } + else if (mib2_mib[i].object_get_callback) + { + + /* Call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + error_counter++; + + printf("ERROR5!\n"); + test_control_return(1); + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + //return(NX_SNMP_ERROR_NOSUCHNAME); + + printf("ERROR6!\n"); + test_control_return(1); + } + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Call either the get octet or get callback, depending what is registered in the table entry. */ + if (mib2_mib[i].object_get_octet_callback) + { + + /* Call the get octet function (has a length input). */ + status = (mib2_mib[i].object_get_octet_callback)(mib2_mib[i].object_value_ptr, object_data, mib2_mib[i].length); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else if (mib2_mib[i].object_get_callback) + { + + /* Call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + error_counter++; + + printf("ERROR7!\n"); + test_control_return(1); + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v2_mib2_variable_update(&agent_ip, &v2_my_agent); + + return NX_SUCCESS; + +} + +extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + sysUpTime = tx_time_get(); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_basic_v2_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP Basic V2 Test........................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/snmp_test/netx_snmp_no_security_function_test.c b/test/regression/snmp_test/netx_snmp_no_security_function_test.c new file mode 100644 index 00000000..8eac7c5f --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_no_security_function_test.c @@ -0,0 +1,827 @@ +// JLC THIS TEST IS BADLY DONE, TEST IT PROPERLY, NOT BYTE BY BYTE! + +/* This NetX test is a simple contact between agent and browser with no security. Note that + NX_SNMP_FUNCTION_TESTING must be defined in nxd_snmp.c or else timer tick data (boot time, SysTimerTick, will not match the + 'pre-recorded' data that the NetX SNMP Agent responses re compared with, and the test will fail. + */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" + + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define VERBOSE // jlc disable +#define DEMO_STACK_SIZE 2048 + +UCHAR *current_object_requested; +UINT aquery_response_complete = NX_FALSE; /* to synchronize when the agent sends the SNMP trap */ + +#define NX_SNMP_ID_OFFSET 17 /* Size of top snmp header, version, public string */ + /* data header, and request id block; assumes public string is 'public' */ +#define QUERY_COUNT 2 +#define RESPONSE_COUNT 2 + + +UCHAR asysDescr[] = "NetX SNMP Agent"; /* sysDescr:OctetString RO */ +UCHAR asysObjectID[] = "1.3.6.1.2.1.1"; /* sysObjectID:ObjectID RO */ +LONG asysUpTime = 0; /* sysUpTime:TimeTicks RO */ +UCHAR asysContact[128] = "NetX sysContact Name"; /* sysContact:OctetString RW */ +UCHAR asysName[128] = "NetX sysName"; /* sysName:OctetString RW */ + +/* This is for SNMPv3 discovery/synchronization. */ +ULONG ausmStatsUnknownEngineIDs = 0; /* usmStatsUnknownEngineIDs:Counter RO */ +ULONG ausmStatsNotInTimeWindows = 0; /* usmStatsNotInTimeWindows:Counter RO */ +ULONG ausmStatsUnsupportedSec = 01; +ULONG ausmStatsUnknownUsername = 0; + +/* Define application MIB data structure. Actual application structures would certainly vary. */ + +typedef struct NOSEC_MIB_ENTRY_STRUCT +{ + + UCHAR *object_name; + void *object_value_ptr; + UINT (*object_get_callback)(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data); + UINT (*object_set_callback)(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data); +} NOSEC_MIB_ENTRY; + +/* Define the actual MIB-2. */ + +static NOSEC_MIB_ENTRY mib2_mib[] = { + + /* OBJECT ID OBJECT VARIABLE GET ROUTINE SET ROUTINE */ + + {(UCHAR *) "1.3.6.1.2.1.1.1.0", asysDescr, nx_snmp_object_string_get, NX_NULL}, + {(UCHAR *) "1.3.6.1.2.1.1.2.0", asysObjectID, nx_snmp_object_id_get, NX_NULL}, + {(UCHAR *) "1.3.6.1.2.1.1.3.0", &asysUpTime, nx_snmp_object_timetics_get, NX_NULL}, + {(UCHAR *) "1.3.6.1.2.1.1.4.0", asysContact, nx_snmp_object_string_get, nx_snmp_object_string_set}, + {(UCHAR *) "1.3.6.1.2.1.1.5.0", asysName, nx_snmp_object_string_get, nx_snmp_object_string_set}, + + /* Subset of usm variable bindings for SNMPv3 discovery messages and synchronization: */ + {(UCHAR *) "1.3.6.1.6.3.15.1.1.1.0", &ausmStatsUnsupportedSec, nx_snmp_object_counter_get, nx_snmp_object_counter_set}, + {(UCHAR *) "1.3.6.1.6.3.15.1.1.2.0", &ausmStatsNotInTimeWindows, nx_snmp_object_counter_get, nx_snmp_object_counter_set}, + {(UCHAR *) "1.3.6.1.6.3.15.1.1.3.0", &ausmStatsUnknownUsername, nx_snmp_object_counter_get, nx_snmp_object_counter_set}, + {(UCHAR *) "1.3.6.1.6.3.15.1.1.4.0", &ausmStatsUnknownEngineIDs, nx_snmp_object_counter_get, nx_snmp_object_counter_set}, + {(UCHAR *) "1.3.6.1.7", (UCHAR *) "1.3.6.1.7", nx_snmp_object_end_of_mib, NX_NULL}, + {NX_NULL, NX_NULL, NX_NULL, NX_NULL} +}; + +/* To show byte by byte comparison of pre-recorded response with SNMP agent, define this option. +#define VERBOSE +*/ + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT my_nosec_agent; +static NX_PACKET_POOL nosec_pool; +static NX_IP agent_ip; +static NX_IP manager_ip; +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + + +UCHAR acontext_engine_id[] = {0x80, 0x00, 0x0d, 0xfe, 0x03, 0x00, 0x77, 0x23, 0x23, 0x46, 0x69}; +UINT acontext_engine_size = 11; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); +static UINT check_valid_response(NX_PACKET *agent_packet, UINT packet_number, UINT *valid); + + +static UINT nosec_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT nosec_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT nosec_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT nosec_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID nosec_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char get_v3_request_packet[101]; +extern int v3_request_size; +extern char get_v3_next_request_packet[141]; +extern int v3_next_request_size; +extern char v3_report_packet[147]; +extern int v3_report_size; +extern char v3_response_packet[154]; +extern int v3_response_size; + + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + +typedef struct SNMP_RESPONSE_STRUCT +{ + char *snmp_response_pkt_data; + int snmp_response_pkt_size; +} SNMP_RESPONSE; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; +static SNMP_RESPONSE snmp_response[RESPONSE_COUNT]; + +#define SNMP_START_OFFSET (14 + 20 + 8) // ethernet, ip and udp headers + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_security_no_security_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + status = tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + status += tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + printf("NetX Test: SNMP No Security Function Test............................"); + + /* Check for IP create errors. */ + /* Check for IP create errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&nosec_pool, "NetX Main Packet Pool", 1000, pointer, 4096); + pointer = pointer + 4096; + + /* Check for IP create errors. */ + if (status) + { + +#ifdef VERBOSE + printf("\npacket create error 0x%x \n", status); +#endif + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create an IP instance. */ + status = nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &nosec_pool, _nx_ram_network_driver_1500, pointer , 2048, 1); + + pointer += 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &nosec_pool, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer += 2048; + + /* Check for IP create errors. */ + if (status) + { + +#ifdef VERBOSE + printf("\nIP create error 0x%x \n", status); +#endif + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_nosec_agent, "public", &agent_ip, pointer, 4096, &nosec_pool, + nosec_mib2_username_processing, nosec_mib2_get_processing, + nosec_mib2_getnext_processing, nosec_mib2_set_processing); + pointer = pointer + 4096; + + if (status) + { + +#ifdef VERBOSE + printf("\nagent create error 0x%x \n", status); +#endif + printf("ERROR!\n"); + test_control_return(1); + } + + if (my_nosec_agent.nx_snmp_agent_v3_enabled == NX_TRUE) + { + ULONG boot_count; + + /* Make sure boot time and engine boot ID match the pre-recorded data. */ + boot_count = 0x1; + status = nx_snmp_agent_context_engine_set(&my_nosec_agent, acontext_engine_id, acontext_engine_size); + status |= nx_snmp_agent_v3_context_boots_set(&my_nosec_agent, boot_count); + + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + } + else + { + +#ifdef VERBOSE + printf("\n agent not enabled for V3 \n"); +#endif + printf("ERROR!\n"); + test_control_return(1); + } + +} + +/* Define the SNMP Agent thread. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + tx_thread_sleep(20); + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_nosec_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + while (!aquery_response_complete) + { + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + } + + // tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +/* SNMP Manager thread */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT port; +UINT i; +USHORT request_id = 1; +UINT valid = NX_TRUE; + + /* Let the agent get set up first! */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the UDP socket to the IP port. */ + status |= nx_udp_socket_bind(&snmp_manager_socket, 0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + +#ifdef VERBOSE + printf("\n UDP socket create error 0x%x \n", status); +#endif + error_counter++; + + /* Indicate the query response is complete. */ + aquery_response_complete = NX_TRUE; + + return; + } + + /* Load the test data. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent.. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + +#ifdef VERBOSE + printf("\n%d query packet send error 0x%x \n",i, status); +#endif + /* Check status. */ + if (status) + { + error_counter++; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, NX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + +#ifdef VERBOSE + printf("\n%d socket receive error 0x%x \n",i, status); +#endif + error_counter++; + break; + } + + /* Get the SNMP agent UDP port. */ + status = nx_udp_packet_info_extract(agent_packet, NX_NULL ,NX_NULL, &port, NX_NULL); + + /* Check status. */ + if (status) + { + +#ifdef VERBOSE + printf("\n%d packet extract error 0x%x \n",i, status); +#endif + error_counter++; + break; + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Indicate the query response is complete. */ + aquery_response_complete = NX_TRUE; + +} + + +/* Determines if we got a valid response using known SNMP query and response data. */ +UINT check_valid_response(NX_PACKET *agent_packet, UINT packet_number, UINT *valid) +{ + +UINT data_size; +UCHAR *work_ptr; +UINT j; + + + work_ptr = (UCHAR *)(&snmp_response[packet_number].snmp_response_pkt_data[0] + SNMP_START_OFFSET); + + data_size = snmp_response[packet_number].snmp_response_pkt_size - SNMP_START_OFFSET; + + if (data_size == 0) + { + return 1; /* Invalid data */ + } + + for (j = 0; j < data_size; j++) + { + + /* For each test , initialize outcome as successful test. */ + *valid = NX_TRUE; + +#ifdef VERBOSE + printf("%d. 0%x 0%x ", j, *(agent_packet -> nx_packet_prepend_ptr + j), work_ptr[j]); +#endif + + /* It is unlikely this logic is needed as long as NX_SNMP_FUNCTION_TESTING is defined, + and the sysUpTime is always updated to 1. */ + + if (*(agent_packet -> nx_packet_prepend_ptr + j) != work_ptr[j]) + { + + /* There is no way to match certain variables such as 'engine boot time' with system time of the pre-recorded + data. Ignore this data */ + + if (packet_number == 1) + { + + /* Case 1: the 'work' packet timer tick data is two bytes */ + if (j == 109) + { + + /* Determine if the time value is 1 byte or 2 bytes. */ + if ((work_ptr[j] == 2) && (*(agent_packet -> nx_packet_prepend_ptr+j) == 1)) + { + /* 2 bytes. Skip an extra byte. We do this by bumping the work pointer by one. */ + work_ptr = (UCHAR *)(&snmp_response[packet_number].snmp_response_pkt_data[0] + SNMP_START_OFFSET + 1); + } + + /* For either cast, skip the time value. */ + j++; +#ifdef VERBOSE + printf("Packet %d skipping %d'th element for comparison\n", packet_number, j); +#endif + + continue; + } + /* Case 2: both have same length of timer tick data, but different value. */ + else if (j == 110) + { + + /* Just skip over the current index. */ +#ifdef VERBOSE + printf("Packet %d skipping timer tick data at %d'th index for comparison\n", packet_number, j); +#endif + + /* Are they both two bytes long? */ + if (work_ptr[j-1] == 2) + { + + /* Yes. Skip an extra index in addition + to the current one. */ +#ifdef VERBOSE + printf("Packet %d two byte timer tick: skip one more index to %d'th index\n", packet_number, j); +#endif + + j++; + } + + continue; + } + else + { + + /* Else invalid or unexpected data. */ + return(1); + } + } + else + { + + /* Else invalid or unexpected data. */ + return(1); + } + } +#ifdef VERBOSE + printf("\n"); +#endif + + } + + return NX_SUCCESS; + +} + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *query_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&nosec_pool, &query_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + +#ifdef VERBOSE + printf("\n packet allocate error 0x%x \n", status); +#endif + return status; + } + + /* Write the SNMP query messages into the packet payload! */ + snmp_query[packet_number].snmp_query_pkt_data += SNMP_START_OFFSET; + memcpy(query_packet -> nx_packet_prepend_ptr, snmp_query[packet_number].snmp_query_pkt_data, snmp_query[packet_number].snmp_query_pkt_size - SNMP_START_OFFSET); + + /* Adjust the write pointer. */ + query_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size - SNMP_START_OFFSET; + query_packet -> nx_packet_append_ptr = query_packet -> nx_packet_prepend_ptr + query_packet -> nx_packet_length; + + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, query_packet, IP_ADDRESS(10, 0, 0, 10), 161); + + /* Check the status. */ + if (status) + { + +#ifdef VERBOSE + printf("\n socket send error 0x%x \n", status); +#endif + nx_packet_release(query_packet); + } + return status; +} + + +static void snmp_test_initialize() +{ + + /* Contact - no security*/ + snmp_query[0].snmp_query_pkt_data = &get_v3_request_packet[0]; + snmp_query[0].snmp_query_pkt_size = v3_request_size; + snmp_query[1].snmp_query_pkt_data = &get_v3_next_request_packet[0]; + snmp_query[1].snmp_query_pkt_size = v3_next_request_size; + + snmp_response[0].snmp_response_pkt_data = &v3_report_packet[0]; + snmp_response[0].snmp_response_pkt_size = v3_report_size; + snmp_response[1].snmp_response_pkt_data = &v3_response_packet[0]; + snmp_response[1].snmp_response_pkt_size = v3_response_size; + +} + + +/* Define the application's GET processing routine. */ +UINT nosec_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT nosec_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT nosec_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT nosec_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + nosec_mib2_variable_update(&agent_ip, &my_nosec_agent); + + return NX_SUCCESS; + +} + + +/* Define the application's update routine. */ + +VOID nosec_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + + /* Update the snmp parameters. */ + asysUpTime = 1; /* This is necessary to compare pre-recorded data with SNMP agent response! */ +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_security_no_security_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP No Security Function Test............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_setget_integers_test.c b/test/regression/snmp_test/netx_snmp_setget_integers_test.c new file mode 100644 index 00000000..aab54a81 --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_setget_integers_test.c @@ -0,0 +1,668 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + a set request for an OID that specifies an IPv4 address. Then it sends a GET request + for the same OID and compares it to what it just set it to. It sends another SET + and GET request for an IPv6 address and compares the IPv6 retrieved from the MIB + to be correct if NETX Duo is in use only. + + The MIB database is defined in snmp_demo_helper.h. The SNMP browser queries are + provided in GetSetIPv4v6Address.c. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +extern MIB_ENTRY mib2_mib[]; + + +static UINT v2query_response_complete = NX_FALSE; + +static UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT v2_my_agent; +static NX_PACKET_POOL v2_pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; + +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + +INT integer_data[] = {255, -255, -2345345, 1234}; +#define QUERY_COUNT 7 + + + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char set_request_integer_255_pkt[43]; +extern int set_request_integer_255_size; +extern char get_request_integer_255_pkt[40]; +extern int get_request_integer_255_size; + +extern char set_request_integer_neg255_pkt[43]; +extern int set_request_integer_neg255_size; +extern char get_request_integer_neg255_pkt[40]; +extern int get_request_integer_neg255_size; + +extern char set_request_integer_neg2345345_pkt[44]; +extern int set_request_integer_neg2345345_size; +extern char get_request_integer_neg2345345_pkt[40]; +extern int get_request_integer_neg2345345_size; + +extern char get_request_v1_1234_packet[]; +extern int get_request_v1_1234_packet_size; + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_setget_integers_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&v2_pool_0, "NetX Main Packet Pool", 1000, pointer, 4096); + pointer = pointer + 4096; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&v2_my_agent, "SNMP Agent", &agent_ip, pointer, 4096, &v2_pool_0, + v2_mib2_username_processing, v2_mib2_get_processing, + v2_mib2_getnext_processing, v2_mib2_set_processing); + + if (status) + { + error_counter++; + } + + return; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + printf("NetX Test: SNMP Set Get Integer Test................................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&v2_my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Wait for the 'manager' to finish querying the Agent. */ + while (v2query_response_complete == NX_FALSE) + { + tx_thread_sleep(100); + } + + /* Check for correct internal counters of SNMP processing. */ + if ((v2_my_agent.nx_snmp_agent_get_requests != 4) || + (v2_my_agent.nx_snmp_agent_set_requests != 3) || + (v2_my_agent.nx_snmp_agent_total_get_variables != 4) || + (v2_my_agent.nx_snmp_agent_packets_received != 7) || + (v2_my_agent.nx_snmp_agent_packets_sent != 7) || + (v2_my_agent.nx_snmp_agent_getresponse_sent != 7)) + + { + error_counter++; + } + + /* Check for errors processing the requests. */ + if (v2_my_agent.nx_snmp_agent_invalid_packets || + v2_my_agent.nx_snmp_agent_internal_errors || + v2_my_agent.nx_snmp_agent_allocation_errors || + v2_my_agent.nx_snmp_agent_request_errors || + v2_my_agent.nx_snmp_agent_too_big_errors || + v2_my_agent.nx_snmp_agent_username_errors || + v2_my_agent.nx_snmp_agent_unknown_requests || + v2_my_agent.nx_snmp_agent_no_such_name_errors) + { + + error_counter++; + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; + +} + +/* SNMP Manager thread */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT port; +UINT i; +USHORT request_id = 1; + + /* Let the agent get set up first! */ + tx_thread_sleep(50); + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&snmp_manager_socket, 161, 200); + + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Get the SNMP agent UDP port. */ + status = nx_udp_packet_info_extract(agent_packet, NX_NULL ,NX_NULL, &port, NX_NULL); + + /* Check status. */ + + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Indicate the test is complete. */ + v2query_response_complete = NX_TRUE; + + /* Unbind the UDP socket. */ + nx_udp_socket_unbind(&snmp_manager_socket); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&snmp_manager_socket); + + return; +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&v2_pool_0, &response_packet, NX_UDP_PACKET, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + return(1); + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the UDP packet to the SNMP Agent with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, response_packet, SNMP_AGENT_ADDRESS, 161); + + /* Check the status. */ + if (status) + { + + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + + +static void snmp_test_initialize() +{ + + snmp_query[0].snmp_query_pkt_data = &set_request_integer_255_pkt[0]; + snmp_query[0].snmp_query_pkt_size = set_request_integer_255_size; + + + snmp_query[1].snmp_query_pkt_data = &get_request_integer_255_pkt[0]; + snmp_query[1].snmp_query_pkt_size = get_request_integer_255_size; + + snmp_query[2].snmp_query_pkt_data = &set_request_integer_neg255_pkt[0]; + snmp_query[2].snmp_query_pkt_size = set_request_integer_neg255_size; + + snmp_query[3].snmp_query_pkt_data = &get_request_integer_neg255_pkt[0]; + snmp_query[3].snmp_query_pkt_size = get_request_integer_neg255_size; + + snmp_query[4].snmp_query_pkt_data = &set_request_integer_neg2345345_pkt[0]; + snmp_query[4].snmp_query_pkt_size = set_request_integer_neg2345345_size; + + snmp_query[5].snmp_query_pkt_data = &get_request_integer_neg2345345_pkt[0]; + snmp_query[5].snmp_query_pkt_size = get_request_integer_neg2345345_size; + + snmp_query[6].snmp_query_pkt_data = &get_request_v1_1234_packet[0]; + snmp_query[6].snmp_query_pkt_size = get_request_v1_1234_packet_size; + +} + + +/* Define the application's GET processing routine. */ + +UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; +static UINT get_request_count = 0; + + /* Increment the get request count. */ + get_request_count++; + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + error_counter++; + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + error_counter++; + } + + + /* Check for correct (expected) value. */ + if (integer_data[get_request_count - 1] != (INT)object_data -> nx_snmp_object_data_msw) + { + error_counter++; + + } + + /* Return the status of the get handler (not necessarily the data checking). */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v2_mib2_variable_update(&agent_ip, &v2_my_agent); + + return NX_SUCCESS; + +} + +extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + sysUpTime = tx_time_get(); +} + + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_setget_integers_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP Set Get Integer Test.................................N/A\n"); + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_setget_ip_address_test.c b/test/regression/snmp_test/netx_snmp_setget_ip_address_test.c new file mode 100644 index 00000000..1ad3dd31 --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_setget_ip_address_test.c @@ -0,0 +1,721 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + a set request for an OID that specifies an IPv4 address. Then it sends a GET request + for the same OID and compares it to what it just set it to. It sends another SET + and GET request for an IPv6 address and compares the IPv6 retrieved from the MIB + to be correct if NETX Duo is in use only. + + The MIB database is defined in snmp_demo_helper.h. The SNMP browser queries are + provided in GetSetIPv4v6Address.c. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + + +#define DEMO_STACK_SIZE 2048 + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +extern MIB_ENTRY mib2_mib[]; + + +static UINT v2query_response_complete = NX_FALSE; + +static UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +#ifdef __PRODUCT_NETXDUO__ +#ifdef FEATURE_NX_IPV6 +#define QUERY_COUNT 4 +#else +#define QUERY_COUNT 2 +#endif /* FEATURE_NX_IPV6 */ +#else +#define QUERY_COUNT 2 +#endif /* __PRODUCT_NETXDUO__ */ + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT v2_my_agent; +static NX_PACKET_POOL v2_pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; + +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + +#define OID_IPV4_ADDRESS "1.3.6.1.2.1.3.1.1.3.0" +#define GET_IP_ADDRESS IP_ADDRESS(241,254,3,129) + +#ifdef __PRODUCT_NETXDUO__ +#define OID_IPV6_ADDRESS "1.3.6.1.2.1.3.1.1.3.1" + +const unsigned char test_ipv6_address[16] = { + 0x20, 0x01, 0x0d, 0xb7, 0x00, 0x00, 0xf1, 0x01, + 0xab, 0xcd, 0x00, 0x64, 0x00, 0x00, 0x02, 0x07 +}; +#endif + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + + + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char set_ipv4_address_request_pkt[47]; +extern int set_ipv4_address_request_size; +extern char get_ipv4_address_request_pkt[42]; +extern int get_ipv4_address_request_size; + +#ifdef __PRODUCT_NETXDUO__ +#ifdef FEATURE_NX_IPV6 +extern char set_ipv6_address_request_pkt[60]; +extern int set_ipv6_address_request_size; +extern char get_ipv6_address_request_pkt[43]; +extern int get_ipv6_address_request_size; +#endif +#endif + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_setget_ip_address_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&v2_pool_0, "NetX Main Packet Pool", 1000, pointer, 4096); + pointer = pointer + 4096; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&v2_my_agent, "SNMP Agent", &agent_ip, pointer, 4096, &v2_pool_0, + v2_mib2_username_processing, v2_mib2_get_processing, + v2_mib2_getnext_processing, v2_mib2_set_processing); + + if (status) + { + error_counter++; + } + + return; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + printf("NetX Test: SNMP Set Get IP Address Test.............................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&v2_my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Wait for the 'manager' to finish querying the Agent. */ + while (v2query_response_complete == NX_FALSE) + { + tx_thread_sleep(100); + } + + /* Check for correct internal counters of SNMP processing. */ +#ifdef __PRODUCT_NETXDUO__ +#ifdef FEATURE_NX_IPV6 + if ((v2_my_agent.nx_snmp_agent_get_requests != 2) || + (v2_my_agent.nx_snmp_agent_set_requests != 2) || + (v2_my_agent.nx_snmp_agent_total_get_variables != 2) || + (v2_my_agent.nx_snmp_agent_packets_received != 4) || + (v2_my_agent.nx_snmp_agent_packets_sent != 4) || + (v2_my_agent.nx_snmp_agent_getresponse_sent != 4)) +#else + if ((v2_my_agent.nx_snmp_agent_get_requests != 1) || + (v2_my_agent.nx_snmp_agent_set_requests != 1) || + (v2_my_agent.nx_snmp_agent_total_get_variables != 1) || + (v2_my_agent.nx_snmp_agent_packets_received != 2) || + (v2_my_agent.nx_snmp_agent_packets_sent != 2) || + (v2_my_agent.nx_snmp_agent_getresponse_sent != 2)) +#endif /* FEATURE_NX_IPV6 */ +#else + if ((v2_my_agent.nx_snmp_agent_get_requests != 1) || + (v2_my_agent.nx_snmp_agent_set_requests != 1) || + (v2_my_agent.nx_snmp_agent_total_get_variables != 1) || + (v2_my_agent.nx_snmp_agent_packets_received != 2) || + (v2_my_agent.nx_snmp_agent_packets_sent != 2) || + (v2_my_agent.nx_snmp_agent_getresponse_sent != 2)) + +#endif /* __PRODUCT_NETXDUO__ */ + { + error_counter++; + } + + /* Check for errors processing the requests. */ + if (v2_my_agent.nx_snmp_agent_invalid_packets || + v2_my_agent.nx_snmp_agent_internal_errors || + v2_my_agent.nx_snmp_agent_allocation_errors || + v2_my_agent.nx_snmp_agent_request_errors || + v2_my_agent.nx_snmp_agent_too_big_errors || + v2_my_agent.nx_snmp_agent_username_errors || + v2_my_agent.nx_snmp_agent_unknown_requests || + v2_my_agent.nx_snmp_agent_no_such_name_errors) + { + + error_counter++; + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; + +} + +/* SNMP Manager thread */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT port; +UINT i; +USHORT request_id = 1; + + /* Let the agent get set up first! */ + tx_thread_sleep(50); + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&snmp_manager_socket, 161, 200); + + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Get the SNMP agent UDP port. */ + status = nx_udp_packet_info_extract(agent_packet, NX_NULL ,NX_NULL, &port, NX_NULL); + + /* Check status. */ + + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Indicate the test is complete. */ + v2query_response_complete = NX_TRUE; + + /* Unbind the UDP socket. */ + nx_udp_socket_unbind(&snmp_manager_socket); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&snmp_manager_socket); + + return; +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&v2_pool_0, &response_packet, NX_UDP_PACKET, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + return(1); + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the UDP packet to the SNMP Agent with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, response_packet, SNMP_AGENT_ADDRESS, 161); + + /* Check the status. */ + if (status) + { + + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + + +static void snmp_test_initialize() +{ + + snmp_query[0].snmp_query_pkt_data = &set_ipv4_address_request_pkt[0]; + snmp_query[0].snmp_query_pkt_size = set_ipv4_address_request_size; + + + snmp_query[1].snmp_query_pkt_data = &get_ipv4_address_request_pkt[0]; + snmp_query[1].snmp_query_pkt_size = get_ipv4_address_request_size; + +#ifdef __PRODUCT_NETXDUO__ +#ifdef FEATURE_NX_IPV6 + snmp_query[2].snmp_query_pkt_data = &set_ipv6_address_request_pkt[0]; + snmp_query[2].snmp_query_pkt_size = set_ipv6_address_request_size; + + snmp_query[3].snmp_query_pkt_data = &get_ipv6_address_request_pkt[0]; + snmp_query[3].snmp_query_pkt_size = get_ipv6_address_request_size; +#endif +#endif +} + + +/* Define the application's GET processing routine. */ + +UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; +UINT temp; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + error_counter++; + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. Octet strings (as opposed to null terminated strings) + require a different get function. */ + + if (mib2_mib[i].object_get_octet_callback) + { + + /* Call the get octet function (has a length input). */ + status = (mib2_mib[i].object_get_octet_callback)(mib2_mib[i].object_value_ptr, object_data, mib2_mib[i].length); + } + else if (mib2_mib[i].object_get_callback) + { + + /* Call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + error_counter++; + } + + temp = memcmp(object_requested, OID_IPV4_ADDRESS, strlen(OID_IPV4_ADDRESS)); + if (temp == 0) + { + + if ((ULONG)object_data -> nx_snmp_object_data_msw != GET_IP_ADDRESS) + { + error_counter++; + } + } + +#ifdef __PRODUCT_NETXDUO__ +#ifdef FEATURE_NX_IPV6 + temp = memcmp(object_requested, OID_IPV6_ADDRESS, strlen(OID_IPV6_ADDRESS)); + if (temp == 0) + { + + UINT i = 0; + + for (i = 0; i< object_data ->nx_snmp_object_octet_string_size; i++) + { + if (object_data -> nx_snmp_object_octet_string[i] != test_ipv6_address[i]) + { + error_counter++; + break; + } + } + } + +#endif +#endif + + /* Return the status of the get handler (not necessarily the data checking). */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v2_mib2_variable_update(&agent_ip, &v2_my_agent); + + return NX_SUCCESS; + +} + +extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + sysUpTime = tx_time_get(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_setget_ip_address_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP Set Get IP Address Test..............................N/A\n"); + test_control_return(3); +} +#endif + + diff --git a/test/regression/snmp_test/netx_snmp_setget_misc_test.c b/test/regression/snmp_test/netx_snmp_setget_misc_test.c new file mode 100644 index 00000000..d83aca4e --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_setget_misc_test.c @@ -0,0 +1,734 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + a set request for an OID that specifies an IPv4 address. Then it sends a GET request + for the same OID and compares it to what it just set it to. It sends another SET + and GET request for an IPv6 address and compares the IPv6 retrieved from the MIB + to be correct if NETX Duo is in use only. + + The MIB database is defined in snmp_demo_helper.h. The SNMP browser queries are + provided in GetSetIPv4v6Address.c. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + + +#define DEMO_STACK_SIZE 2048 + +extern MIB_ENTRY mib2_mib[]; + + +static UINT v2query_response_complete = NX_FALSE; + +static UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT v2_my_agent; +static NX_PACKET_POOL v2_pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; + +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + /* counter32, counter64 msb counter 64 lsb, timertic */ +//ULONG test_data[] = {30541989, 30541989}; +#define COUNTER32_VAL 30541989 +#define COUNTER64_VAL 3054198999 +#define COUNTER64_VAL0 0xD2 // part of number stored in msw +#define COUNTER64_VAL1 0x423988D7 // part of number stored in lsw +#define TIMERTIC_VAL 30541989 +#define STRING_TEST "my system id" +#define QUERY_COUNT 10 + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char set_request_counter32_pkt[47]; +extern int set_request_counter32_size; +extern char get_request_counter32_pkt[42]; +extern int get_request_counter32_size; + +extern char set_request_counter64_pkt[48]; +extern int set_request_counter64_size; +extern char get_request_counter64_pkt[42]; +extern int get_request_counter64_size; + +extern char set_request_counter64_5bytes_pkt[49]; +extern int set_request_counter64_5bytes_size; +extern char get_request_counter64_5bytes_pkt[42]; +extern int get_request_counter64_5bytes_size; + +extern char set_request_timertic_pkt[47]; +extern int set_request_timertic_size; +extern char get_request_timertic_pkt[42]; +extern int get_request_timertic_size; + + +extern char set_request_string_pkt[53]; +extern int set_request_string_size; +extern char get_request_string_pkt[40]; +extern int get_request_string_size; + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_setget_misc_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&v2_pool_0, "NetX Main Packet Pool", 1000, pointer, 4096); + pointer = pointer + 4096; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&v2_my_agent, "SNMP Agent", &agent_ip, pointer, 4096, &v2_pool_0, + v2_mib2_username_processing, v2_mib2_get_processing, + v2_mib2_getnext_processing, v2_mib2_set_processing); + + if (status) + { + error_counter++; + } + + return; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + printf("NetX Test: SNMP Set Get Miscellaneous Data Type Test................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&v2_my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Wait for the 'manager' to finish querying the Agent. */ + while (v2query_response_complete == NX_FALSE) + { + tx_thread_sleep(100); + } + + /* Check for correct internal counters of SNMP processing. */ + if ((v2_my_agent.nx_snmp_agent_get_requests != 5) || + (v2_my_agent.nx_snmp_agent_set_requests != 5) || + (v2_my_agent.nx_snmp_agent_total_get_variables != 5) || + (v2_my_agent.nx_snmp_agent_packets_received != 10) || + (v2_my_agent.nx_snmp_agent_packets_sent != 10) || + (v2_my_agent.nx_snmp_agent_getresponse_sent != 10)) + + { + error_counter++; + } + + /* Check for errors processing the requests. */ + if (v2_my_agent.nx_snmp_agent_invalid_packets || + v2_my_agent.nx_snmp_agent_internal_errors || + v2_my_agent.nx_snmp_agent_allocation_errors || + v2_my_agent.nx_snmp_agent_request_errors || + v2_my_agent.nx_snmp_agent_too_big_errors || + v2_my_agent.nx_snmp_agent_username_errors || + v2_my_agent.nx_snmp_agent_unknown_requests || + v2_my_agent.nx_snmp_agent_no_such_name_errors) + { + + error_counter++; + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; + +} + +/* SNMP Manager thread */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT port; +UINT i; +USHORT request_id = 1; + + /* Let the agent get set up first! */ + tx_thread_sleep(50); + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&snmp_manager_socket, 161, 200); + + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Get the SNMP agent UDP port. */ + status = nx_udp_packet_info_extract(agent_packet, NX_NULL ,NX_NULL, &port, NX_NULL); + + /* Check status. */ + + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Indicate the test is complete. */ + v2query_response_complete = NX_TRUE; + + /* Unbind the UDP socket. */ + nx_udp_socket_unbind(&snmp_manager_socket); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&snmp_manager_socket); + + return; +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&v2_pool_0, &response_packet, NX_UDP_PACKET, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + return(1); + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the UDP packet to the SNMP Agent with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, response_packet, SNMP_AGENT_ADDRESS, 161); + + /* Check the status. */ + if (status) + { + + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + + +static void snmp_test_initialize() +{ + + snmp_query[0].snmp_query_pkt_data = &set_request_counter32_pkt[0]; + snmp_query[0].snmp_query_pkt_size = set_request_counter32_size; + + snmp_query[1].snmp_query_pkt_data = &get_request_counter32_pkt[0]; + snmp_query[1].snmp_query_pkt_size = get_request_counter32_size; + + + snmp_query[2].snmp_query_pkt_data = &set_request_counter64_pkt[0]; + snmp_query[2].snmp_query_pkt_size = set_request_counter64_size; + + snmp_query[3].snmp_query_pkt_data = &get_request_counter64_pkt[0]; + snmp_query[3].snmp_query_pkt_size = get_request_counter64_size; + + + snmp_query[4].snmp_query_pkt_data = &set_request_counter64_5bytes_pkt[0]; + snmp_query[4].snmp_query_pkt_size = set_request_counter64_5bytes_size; + + snmp_query[5].snmp_query_pkt_data = &get_request_counter64_5bytes_pkt[0]; + snmp_query[5].snmp_query_pkt_size = get_request_counter64_5bytes_size; + + + snmp_query[6].snmp_query_pkt_data = &set_request_timertic_pkt[0]; + snmp_query[6].snmp_query_pkt_size = set_request_timertic_size; + + snmp_query[7].snmp_query_pkt_data = &get_request_timertic_pkt[0]; + snmp_query[7].snmp_query_pkt_size = get_request_timertic_size; + + + snmp_query[8].snmp_query_pkt_data = &set_request_string_pkt[0]; + snmp_query[8].snmp_query_pkt_size = set_request_string_size; + + snmp_query[9].snmp_query_pkt_data = &get_request_string_pkt[0]; + snmp_query[9].snmp_query_pkt_size = get_request_string_size; + +} + + +/* Define the application's GET processing routine. */ + +UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; +UINT length = 0; +static UINT get_request_count = 0; + + /* Increment the get request count. */ + get_request_count++; + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + error_counter++; + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + if (mib2_mib[i].object_get_octet_callback) + { + + /* Yes, call the get octet function. */ + status = (mib2_mib[i].object_get_octet_callback)(mib2_mib[i].object_value_ptr, object_data, length); + } + /* Determine if the entry has a get function. */ + else if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + error_counter++; + } + + + /* Check for correct (expected) value. */ + if (get_request_count == 1) + { + if (COUNTER32_VAL != (INT)object_data -> nx_snmp_object_data_msw) + { + error_counter++; + } + } + else if (get_request_count == 2) + { + if (COUNTER64_VAL != (ULONG)object_data -> nx_snmp_object_data_lsw) + { + error_counter++; + } + } + else if (get_request_count == 3) + { + if ((COUNTER64_VAL0 != (ULONG)object_data -> nx_snmp_object_data_msw) || + (COUNTER64_VAL1 != (ULONG)object_data -> nx_snmp_object_data_lsw)) + { + error_counter++; + } + } + + if (get_request_count == 4) + { + if (TIMERTIC_VAL != (INT)object_data -> nx_snmp_object_data_msw) + { + error_counter++; + } + } + else if (get_request_count == 5) + { + if (memcmp(object_data -> nx_snmp_object_octet_string, STRING_TEST, strlen(STRING_TEST))) + { + error_counter++; + } + } + + /* Return the status of the get handler (not necessarily the data checking). */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v2_mib2_variable_update(&agent_ip, &v2_my_agent); + + return NX_SUCCESS; + +} + +extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + sysUpTime = tx_time_get(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_setget_misc_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP Set Get Miscellaneous Data Type Test.................N/A\n"); + test_control_return(3); +} +#endif + + diff --git a/test/regression/snmp_test/netx_snmp_setget_octet_strings_test.c b/test/regression/snmp_test/netx_snmp_setget_octet_strings_test.c new file mode 100644 index 00000000..4f3df041 --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_setget_octet_strings_test.c @@ -0,0 +1,681 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + a set request for an OID that specifies an IPv4 address. Then it sends a GET request + for the same OID and compares it to what it just set it to. It sends another SET + and GET request for an IPv6 address and compares the IPv6 retrieved from the MIB + to be correct if NETX Duo is in use only. + + The MIB database is defined in snmp_demo_helper.h. The SNMP browser queries are + provided in GetSetIPv4v6Address.c. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 2048 + +extern MIB_ENTRY mib2_mib[]; + + +static UINT v2query_response_complete = NX_FALSE; + +static UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + + +#define QUERY_COUNT 4 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT v2_my_agent; +static NX_PACKET_POOL v2_pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; + +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + +#define OID_OCTETSTRING_ADDRESS "1.3.6.1.2.1.3.1.1.2.0" + + +const unsigned char test_first_string[4] = {0xff, 0x00, 0xf1, 0xf2}; +const unsigned char test_second_string[3] = {0x00, 0xf1, 0xf2}; + + + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char set_request_octet_string_pkt[47]; +extern int set_request_octet_string_size; +extern char get_request_octet_string_pkt[42]; +extern int get_request_octet_string_size; + +extern char set_request_octet_string_leading_zero_pkt[46]; +extern int set_request_octet_string_leading_zero_size; +extern char get_request_octet_string_leading_zero_pkt[42]; +extern int get_request_octet_string_leading_zero_size; + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_setget_octet_strings_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&v2_pool_0, "NetX Main Packet Pool", 1000, pointer, 4096); + pointer = pointer + 4096; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&v2_my_agent, "SNMP Agent", &agent_ip, pointer, 4096, &v2_pool_0, + v2_mib2_username_processing, v2_mib2_get_processing, + v2_mib2_getnext_processing, v2_mib2_set_processing); + + if (status) + { + error_counter++; + } + + return; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + printf("NetX Test: SNMP Set Get Octet String Test............................"); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&v2_my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Wait for the 'manager' to finish querying the Agent. */ + while (v2query_response_complete == NX_FALSE) + { + tx_thread_sleep(100); + } + + /* Check for correct internal counters of SNMP processing. */ + if ((v2_my_agent.nx_snmp_agent_get_requests != 2) || + (v2_my_agent.nx_snmp_agent_set_requests != 2) || + (v2_my_agent.nx_snmp_agent_total_get_variables != 2) || + (v2_my_agent.nx_snmp_agent_packets_received != 4) || + (v2_my_agent.nx_snmp_agent_packets_sent != 4) || + (v2_my_agent.nx_snmp_agent_getresponse_sent != 4)) + { + error_counter++; + } + + /* Check for errors processing the requests. */ + if (v2_my_agent.nx_snmp_agent_invalid_packets || + v2_my_agent.nx_snmp_agent_internal_errors || + v2_my_agent.nx_snmp_agent_allocation_errors || + v2_my_agent.nx_snmp_agent_request_errors || + v2_my_agent.nx_snmp_agent_too_big_errors || + v2_my_agent.nx_snmp_agent_username_errors || + v2_my_agent.nx_snmp_agent_unknown_requests || + v2_my_agent.nx_snmp_agent_no_such_name_errors) + { + + error_counter++; + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; + +} + +/* SNMP Manager thread */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT port; +UINT i; +USHORT request_id = 1; + + /* Let the agent get set up first! */ + tx_thread_sleep(50); + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&snmp_manager_socket, 161, 200); + + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Get the SNMP agent UDP port. */ + status = nx_udp_packet_info_extract(agent_packet, NX_NULL ,NX_NULL, &port, NX_NULL); + + /* Check status. */ + + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Indicate the test is complete. */ + v2query_response_complete = NX_TRUE; + + /* Unbind the UDP socket. */ + nx_udp_socket_unbind(&snmp_manager_socket); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&snmp_manager_socket); + + return; +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&v2_pool_0, &response_packet, NX_UDP_PACKET, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + return(1); + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the UDP packet to the SNMP Agent with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, response_packet, SNMP_AGENT_ADDRESS, 161); + + /* Check the status. */ + if (status) + { + + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + + +static void snmp_test_initialize() +{ + + snmp_query[0].snmp_query_pkt_data = &set_request_octet_string_pkt[0]; + snmp_query[0].snmp_query_pkt_size = set_request_octet_string_size; + + + snmp_query[1].snmp_query_pkt_data = &get_request_octet_string_pkt[0]; + snmp_query[1].snmp_query_pkt_size = get_request_octet_string_size; + + snmp_query[2].snmp_query_pkt_data = &set_request_octet_string_leading_zero_pkt[0]; + snmp_query[2].snmp_query_pkt_size = set_request_octet_string_leading_zero_size; + + snmp_query[3].snmp_query_pkt_data = &get_request_octet_string_leading_zero_pkt[0]; + snmp_query[3].snmp_query_pkt_size = get_request_octet_string_leading_zero_size; +} + + +/* Define the application's GET processing routine. */ + +UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; +static UINT get_query_count = 0; + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + error_counter++; + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + /* Determine if the entry has a get function. Octet strings (as opposed to null terminated strings) + require a different get function. */ + + if (mib2_mib[i].object_get_octet_callback) + { + + /* Call the get octet function (has a length input). */ + status = (mib2_mib[i].object_get_octet_callback)(mib2_mib[i].object_value_ptr, object_data, mib2_mib[i].length); + } + else if (mib2_mib[i].object_get_callback) + { + + /* Call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + error_counter++; + } + + get_query_count++; + + if ((object_data -> nx_snmp_object_octet_string_size == 0) || (object_data -> nx_snmp_object_octet_string_size > NX_SNMP_MAX_OCTET_STRING)) + { + error_counter++; + return NX_SNMP_ERROR_TOOBIG; + } + + if (get_query_count == 1) + { + + for (i = 0; i < object_data -> nx_snmp_object_octet_string_size; i++) + { + if (test_first_string[i] != object_data-> nx_snmp_object_octet_string[i]) + { + error_counter++; + break; + } + } + } + else if (get_query_count == 2) + { + + for (i = 0; i < object_data -> nx_snmp_object_octet_string_size; i++) + { + if (test_second_string[i] != object_data-> nx_snmp_object_octet_string[i]) + { + error_counter++; + break; + } + } + } + + + /* Return the status of the get handler (not necessarily the data checking). */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + if (mib2_mib[i].object_set_callback) + { + + /* Call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v2_mib2_variable_update(&agent_ip, &v2_my_agent); + + return NX_SUCCESS; + +} + +extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + sysUpTime = tx_time_get(); +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_setget_octet_strings_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP Set Get Octet String Test............................N/A\n"); + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_v1_buffer_overwrite_test.c b/test/regression/snmp_test/netx_snmp_v1_buffer_overwrite_test.c new file mode 100644 index 00000000..26d8a7cd --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v1_buffer_overwrite_test.c @@ -0,0 +1,504 @@ +/* This NetX test concentrates on the basic SNMPv1 operation. The 'manager' sends + a request for an unknown item ("oid"). The SNMP agent should not responds, but + set an internal error and be able to respond to the next request. + + The MIB database is defined in demo_snmp_helper.h */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_FRAGMENTATION) + +#define DEMO_STACK_SIZE 4096 + +extern MIB_ENTRY mib2_mib[]; + +static UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; + +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10, 128, 16, 17) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG snmp_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Inject SNMP manager query. */ +static VOID packet_inject(UCHAR *data_ptr, UINT data_size); + + +extern unsigned char v1_buffer_overwrite_packet1[1514]; +extern int v1_buffer_overwrite_packet1_size; +extern unsigned char v1_buffer_overwrite_packet2[54]; +extern int v1_buffer_overwrite_packet2_size; +extern unsigned char v1_buffer_overwrite_packet3[54]; +extern int v1_buffer_overwrite_packet3_size; +extern unsigned char v1_buffer_overwrite_packet4[]; +extern int v1_buffer_overwrite_packet4_size; + +#define QUERY_COUNT 4 + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v1_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, (sizeof(NX_PACKET) + 1536) * 10); + pointer = pointer + (sizeof(NX_PACKET) + 1536) * 10; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + status = nx_ip_fragment_enable(&agent_ip); + if (status) + { + error_counter++; + } +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *packet_ptr; + + printf("NetX Test: SNMP V1 Buffer Overwrite Test............................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "SNMP Agent", &agent_ip, snmp_stack, sizeof(snmp_stack), &pool_0, + mib2_username_processing, mib2_get_processing, + mib2_getnext_processing, mib2_set_processing); + + if (status) + { + error_counter++; + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Inject the SNMP manager query packet. */ + packet_inject(snmp_query[i].snmp_query_pkt_data, snmp_query[i].snmp_query_pkt_size); + } + + /* Wait for processing snmp packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if (nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + /* Make sure the buffer is not overwrote. */ + if (memcmp(mib2_mib[0].object_name, "1.3.6.1.2.1.1.1.0", sizeof("1.3.6.1.2.1.1.1.0") - 1) != 0) + { + error_counter++; + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static VOID packet_inject(UCHAR *data_ptr, UINT data_size) +{ +UINT status; +NX_PACKET *my_packet; + + status = nx_packet_allocate(&pool_0, &my_packet, NX_RECEIVE_PACKET, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Make sure IP header is 4-byte aligned. */ + my_packet -> nx_packet_prepend_ptr += 2; + my_packet -> nx_packet_append_ptr += 2; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(my_packet, data_ptr, data_size, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Skip the MAC header. */ + my_packet -> nx_packet_length -= 14; + my_packet -> nx_packet_prepend_ptr += 14; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&agent_ip, my_packet); +} + +static void snmp_test_initialize() +{ + snmp_query[0].snmp_query_pkt_data = &v1_buffer_overwrite_packet1[0]; + snmp_query[0].snmp_query_pkt_size = v1_buffer_overwrite_packet1_size; + + snmp_query[1].snmp_query_pkt_data = &v1_buffer_overwrite_packet2[0]; + snmp_query[1].snmp_query_pkt_size = v1_buffer_overwrite_packet2_size; + + snmp_query[2].snmp_query_pkt_data = &v1_buffer_overwrite_packet3[0]; + snmp_query[2].snmp_query_pkt_size = v1_buffer_overwrite_packet3_size; + + snmp_query[3].snmp_query_pkt_data = &v1_buffer_overwrite_packet4[0]; + snmp_query[3].snmp_query_pkt_size = v1_buffer_overwrite_packet4_size; +} + + +/* Define the application's GET processing routine. */ + +UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* If the object data type is string. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_ANS1_OCTET_STRING) + { + + /* Check the string length of the object value. */ + if (object_data -> nx_snmp_object_octet_string_size > mib2_mib[i].length) + { + return(NX_SNMP_ERROR_TOOBIG); + } + } + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +/* Define the application's update routine. */ + +VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v1_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V1 Buffer Overwrite Test.............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_v1_object_id_buffer_overwrite_test.c b/test/regression/snmp_test/netx_snmp_v1_object_id_buffer_overwrite_test.c new file mode 100644 index 00000000..a0c14bde --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v1_object_id_buffer_overwrite_test.c @@ -0,0 +1,426 @@ +/* This NetX test concentrates on the basic SNMPv1 operation. The 'manager' sends + a request for an unknown item ("oid"). The SNMP agent should not responds, but + set an internal error and be able to respond to the next request. + + The MIB database is defined in demo_snmp_helper.h */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_FRAGMENTATION) + +#define DEMO_STACK_SIZE 4096 + +extern MIB_ENTRY mib2_mib[]; + +static UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; + +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10, 128, 16, 17) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG snmp_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Inject SNMP manager query. */ +static VOID packet_inject(UCHAR *data_ptr, UINT data_size); + + +extern unsigned char v1_object_id_buffer_overwrite_packet[1422]; +extern int v1_object_id_buffer_overwrite_packet_size; + +#define QUERY_COUNT 1 + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v1_object_id_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, (sizeof(NX_PACKET) + 1536) * 10); + pointer = pointer + (sizeof(NX_PACKET) + 1536) * 10; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + status = nx_ip_fragment_enable(&agent_ip); + if (status) + { + error_counter++; + } +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *packet_ptr; + + printf("NetX Test: SNMP V1 Object ID Buffer Overwrite Test..................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "SNMP Agent", &agent_ip, snmp_stack, sizeof(snmp_stack), &pool_0, + mib2_username_processing, mib2_get_processing, + mib2_getnext_processing, mib2_set_processing); + + if (status) + { + error_counter++; + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Inject the SNMP manager query packet. */ + packet_inject(snmp_query[i].snmp_query_pkt_data, snmp_query[i].snmp_query_pkt_size); + } + + /* Wait for processing snmp packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if (nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static VOID packet_inject(UCHAR *data_ptr, UINT data_size) +{ +UINT status; +NX_PACKET *my_packet; + + status = nx_packet_allocate(&pool_0, &my_packet, NX_RECEIVE_PACKET, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Make sure IP header is 4-byte aligned. */ + my_packet -> nx_packet_prepend_ptr += 2; + my_packet -> nx_packet_append_ptr += 2; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(my_packet, data_ptr, data_size, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Skip the MAC header. */ + my_packet -> nx_packet_length -= 14; + my_packet -> nx_packet_prepend_ptr += 14; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&agent_ip, my_packet); +} + +static void snmp_test_initialize() +{ + snmp_query[0].snmp_query_pkt_data = &v1_object_id_buffer_overwrite_packet[0]; + snmp_query[0].snmp_query_pkt_size = v1_object_id_buffer_overwrite_packet_size; +} + + +/* Define the application's GET processing routine. */ + +UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + + + NX_PARAMETER_NOT_USED(agent_ptr); + NX_PARAMETER_NOT_USED(object_requested); + NX_PARAMETER_NOT_USED(object_data); + return(NX_SUCCESS); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +/* Define the application's update routine. */ + +VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v1_object_id_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V1 Object ID Buffer Overwrite Test...................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_v1_packet_double_release_test.c b/test/regression/snmp_test/netx_snmp_v1_packet_double_release_test.c new file mode 100644 index 00000000..ccedec0b --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v1_packet_double_release_test.c @@ -0,0 +1,461 @@ +/* This NetX test concentrates on the basic SNMPv1 operation. The 'manager' sends + a request for an unknown item ("oid"). The SNMP agent should not responds, but + set an internal error and be able to respond to the next request. + + The MIB database is defined in demo_snmp_helper.h */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +extern MIB_ENTRY mib2_mib[]; + +static UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; + +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10, 128, 16, 17) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG snmp_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Inject SNMP manager query. */ +static VOID packet_inject(UCHAR *data_ptr, UINT data_size); + +extern unsigned char v1_double_release_packet[1421]; +extern int v1_double_release_packet_size; + +#define QUERY_COUNT 1 + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v1_packet_double_release_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, (sizeof(NX_PACKET) + 1536) * 10); + pointer = pointer + (sizeof(NX_PACKET) + 1536) * 10; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *packet_ptr; + + printf("NetX Test: SNMP V1 Packet Double Release Test........................"); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "SNMP Agent", &agent_ip, snmp_stack, sizeof(snmp_stack), &pool_0, + mib2_username_processing, mib2_get_processing, + mib2_getnext_processing, mib2_set_processing); + + if (status) + { + error_counter++; + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Inject the SNMP manager query packet. */ + packet_inject(snmp_query[i].snmp_query_pkt_data, snmp_query[i].snmp_query_pkt_size); + } + + /* Wait for processing snmp packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Check if there is invalid packet release. */ + if (pool_0.nx_packet_pool_invalid_releases) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static VOID packet_inject(UCHAR *data_ptr, UINT data_size) +{ +UINT status; +NX_PACKET *my_packet; + + status = nx_packet_allocate(&pool_0, &my_packet, NX_RECEIVE_PACKET, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Make sure IP header is 4-byte aligned. */ + my_packet -> nx_packet_prepend_ptr += 2; + my_packet -> nx_packet_append_ptr += 2; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(my_packet, data_ptr, data_size, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Skip the MAC header. */ + my_packet -> nx_packet_length -= 14; + my_packet -> nx_packet_prepend_ptr += 14; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&agent_ip, my_packet); +} + +static void snmp_test_initialize() +{ + snmp_query[0].snmp_query_pkt_data = &v1_double_release_packet[0]; + snmp_query[0].snmp_query_pkt_size = v1_double_release_packet_size; +} + + +/* Define the application's GET processing routine. */ + +UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +/* Define the application's update routine. */ + +VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v1_packet_double_release_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V1 Packet Double Release Test........................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_v2_buffer_overwrite_test.c b/test/regression/snmp_test/netx_snmp_v2_buffer_overwrite_test.c new file mode 100644 index 00000000..dc3a91df --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v2_buffer_overwrite_test.c @@ -0,0 +1,477 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + a request for an unknown item ("oid"). The SNMP agent should not responds, but + set an internal error and be able to respond to the next request. + + The MIB database is defined in demo_snmp_helper.h */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_FRAGMENTATION) + +#define DEMO_STACK_SIZE 4096 + +extern MIB_ENTRY mib2_mib[]; + +static UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; + +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10, 128, 16, 17) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG snmp_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Inject SNMP manager query. */ +static VOID packet_inject(UCHAR *data_ptr, UINT data_size); + + +extern unsigned char v2_buffer_overwrite_packet1[1514]; +extern int v2_buffer_overwrite_packet1_size; +extern unsigned char v2_buffer_overwrite_packet2[54]; +extern int v2_buffer_overwrite_packet2_size; + +#define QUERY_COUNT 2 + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v2_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, (sizeof(NX_PACKET) + 1536) * 10); + pointer = pointer + (sizeof(NX_PACKET) + 1536) * 10; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + status = nx_ip_fragment_enable(&agent_ip); + if (status) + { + error_counter++; + } +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *packet_ptr; + + printf("NetX Test: SNMP V2 Buffer Overwrite Test............................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "SNMP Agent", &agent_ip, snmp_stack, sizeof(snmp_stack), &pool_0, + mib2_username_processing, mib2_get_processing, + mib2_getnext_processing, mib2_set_processing); + + if (status) + { + error_counter++; + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Inject the SNMP manager query packet. */ + packet_inject(snmp_query[i].snmp_query_pkt_data, snmp_query[i].snmp_query_pkt_size); + } + + /* Wait for processing snmp packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if (nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + +} + +static VOID packet_inject(UCHAR *data_ptr, UINT data_size) +{ +UINT status; +NX_PACKET *my_packet; + + status = nx_packet_allocate(&pool_0, &my_packet, NX_RECEIVE_PACKET, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Make sure IP header is 4-byte aligned. */ + my_packet -> nx_packet_prepend_ptr += 2; + my_packet -> nx_packet_append_ptr += 2; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(my_packet, data_ptr, data_size, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Skip the MAC header. */ + my_packet -> nx_packet_length -= 14; + my_packet -> nx_packet_prepend_ptr += 14; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&agent_ip, my_packet); +} + +static void snmp_test_initialize() +{ + snmp_query[0].snmp_query_pkt_data = &v2_buffer_overwrite_packet1[0]; + snmp_query[0].snmp_query_pkt_size = v2_buffer_overwrite_packet1_size; + + snmp_query[1].snmp_query_pkt_data = &v2_buffer_overwrite_packet2[0]; + snmp_query[1].snmp_query_pkt_size = v2_buffer_overwrite_packet2_size; +} + + +/* Define the application's GET processing routine. */ + +UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +/* Define the application's update routine. */ + +VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v2_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V2 Buffer Overwrite Test.............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_v2_get_bulk_request_test.c b/test/regression/snmp_test/netx_snmp_v2_get_bulk_request_test.c new file mode 100644 index 00000000..af45837f --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v2_get_bulk_request_test.c @@ -0,0 +1,616 @@ +// JLC THIS TEST IS OBSOLETE. Several other tests do the exact same thing. REMOVE IT. Removed +// references to "v3" and handshake protocol. This is a V2 query and there is no handshaking +// + +/* This NetX test concentrates on the SNMPv2 get bulk request. The first exchange is to 'contact' + the SNMP agent. Then the manager makes a bulk request. The test is successful if the internal + statistics show the correct number of variables requested, requests received, and bulk responses + sent, and there are no internal errors. This does not require packet chaining. + */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +extern MIB_ENTRY mib2_mib[]; + + +static UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + + +UINT query_response_complete = NX_FALSE; /* to synchronize when the agent sends the SNMP trap */ +#define QUERY_COUNT 1 + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char get_next_request_packet[39]; +extern int get_next_request_size; +extern char get_bulk_request_packet[40]; +extern int get_bulk_request_size; + + + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v2_get_bulk_request_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + status = tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + status += tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 10*1000); + pointer = pointer + 10*1000; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer , 2048, 1); + + pointer += 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer += 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "public", &agent_ip, pointer, 4096, &pool_0, + v2_mib2_username_processing, v2_mib2_get_processing, + v2_mib2_getnext_processing, v2_mib2_set_processing); + pointer = pointer + 4096; + + + if (status) + { + error_counter++; + } + + return; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + printf("NetX Test: SNMP V2 Get Bulk Request Test............................."); + tx_thread_sleep(20); + + if (error_counter) + { + printf("ERROR0!\n"); + test_control_return(1); + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + while (!query_response_complete) + { + tx_thread_sleep(100); + } + + tx_thread_sleep(50); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT i; +USHORT request_id = 1; + + + /* Let the agent get set up first! */ + tx_thread_sleep(50); + + + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the UDP socket to an IP port. */ + status |= nx_udp_socket_bind(&snmp_manager_socket, 0, 100); + + /* Check status. */ + if (status) + { + + error_counter++; + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + + return; + } + + /* Load the test data. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent.. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + error_counter++; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, NX_WAIT_FOREVER); + + /* Check status. We should only get one response. */ + if (status) + { + error_counter++; + break; + } + + /* Check for errors on discovery/report exchange. */ + if (i == 0) + { + if ((my_agent.nx_snmp_agent_total_get_variables != 1) || (my_agent.nx_snmp_agent_getnext_requests != 1)) + { + error_counter++; + + break; + } + /* Allow variability in size due to unpredictable variables (timer). */ + if ((agent_packet -> nx_packet_length <= 47) || (agent_packet -> nx_packet_length >= 56)) + { + error_counter++; + break; + } + } + + /* Check for errors on the completion of get bulk request. */ + if (i == 1) + { + if ((my_agent.nx_snmp_agent_getbulk_requests != 1) || (my_agent.nx_snmp_agent_getresponse_sent !=2) || + (my_agent.nx_snmp_agent_total_get_variables != 6)) + { + error_counter++; + break; + } + + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Check for other general errors. */ + if (my_agent.nx_snmp_agent_request_errors || my_agent.nx_snmp_agent_internal_errors) + { + + error_counter++; + } + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *query_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &query_packet, NX_UDP_PACKET, 100); + + /* Check status. */ + if (status) + { + return status; + } + + + memset(query_packet -> nx_packet_prepend_ptr, 0, (query_packet -> nx_packet_data_end - query_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(query_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + query_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + query_packet -> nx_packet_append_ptr = query_packet -> nx_packet_prepend_ptr + query_packet -> nx_packet_length; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, query_packet, IP_ADDRESS(10, 0, 0, 10), 161); + + /* Check the status. */ + if (status) + nx_packet_release(query_packet); + + return status; +} + + +static void snmp_test_initialize() +{ + + /* Contact - no security*/ + snmp_query[0].snmp_query_pkt_data = &get_next_request_packet[0]; + snmp_query[0].snmp_query_pkt_size = get_next_request_size; + //snmp_query[1].snmp_query_pkt_data = &get_bulk_request_packet[0]; + //snmp_query[1].snmp_query_pkt_size = get_bulk_request_size; + + +} + + +/* Define the application's GET processing routine. */ + +UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v2_mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +//extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + //sysUpTime = tx_time_get(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v2_get_bulk_request_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V2 Get Bulk Request Test.............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/snmp_test/netx_snmp_v2_send_trap_test.c b/test/regression/snmp_test/netx_snmp_v2_send_trap_test.c new file mode 100644 index 00000000..34cd7000 --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v2_send_trap_test.c @@ -0,0 +1,670 @@ +/* This SNMP Agent test sends a V2 trap with a non null trap list. A successful result is the correction + number of messages/packets sent and no internal errors. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + + +extern MIB_ENTRY mib2_mib[]; + +static UINT v2query_response_complete = NX_FALSE; + +static UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +#define QUERY_COUNT 1 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT v2_my_agent; +static NX_PACKET_POOL v2_pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; + +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char simple_get_query_pkt[82]; +extern int simple_get_query_size; + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v2_send_trap_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&v2_pool_0, "NetX Main Packet Pool", 1000, pointer, 4096); + pointer = pointer + 4096; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&v2_my_agent, "SNMP Agent", &agent_ip, pointer, 4096, &v2_pool_0, + v2_mib2_username_processing, v2_mib2_get_processing, + v2_mib2_getnext_processing, v2_mib2_set_processing); + + if (status) + { + error_counter++; + } + + return; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_SNMP_TRAP_OBJECT trap_list[7]; +NX_SNMP_OBJECT_DATA trap_data0; +NX_SNMP_OBJECT_DATA trap_data1; +NX_SNMP_OBJECT_DATA trap_data2; +NX_SNMP_OBJECT_DATA trap_data3; +NX_SNMP_OBJECT_DATA trap_data4; +NX_SNMP_OBJECT_DATA trap_data5; +UINT counter = 133; + + + printf("NetX Test: SNMP V2 Send Trap Test...................................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&v2_my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Wait for the 'manager' to finish querying the Agent. */ + while (v2query_response_complete == NX_FALSE) + { + tx_thread_sleep(100); + } + + + /* Now send the traps. */ + /* Send trap to indicate the link is up. */ + trap_list[0].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.1.0"; + trap_list[0].nx_snmp_object_data = &trap_data0; + trap_data0.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data0.nx_snmp_object_data_msw = counter++; + + trap_list[1].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.7.0"; + trap_list[1].nx_snmp_object_data = &trap_data1; + trap_data1.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data1.nx_snmp_object_data_msw = counter++; + + /* Null terminate the list. */ + trap_list[2].nx_snmp_object_string_ptr = NX_NULL; + trap_list[2].nx_snmp_object_data = NX_NULL; +#if 1 + trap_list[2].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.8.0"; + trap_list[2].nx_snmp_object_data = &trap_data2; + trap_data2.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data2.nx_snmp_object_data_msw = tx_time_get(); + + trap_list[3].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.9.0"; + trap_list[3].nx_snmp_object_data = &trap_data3; + trap_data3.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data3.nx_snmp_object_data_msw = counter++; + + trap_list[4].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.10.0.1"; + trap_list[4].nx_snmp_object_data = &trap_data4; + trap_data4.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data4.nx_snmp_object_data_msw = tx_time_get(); + + + trap_list[5].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.10.0.2"; + trap_list[5].nx_snmp_object_data = &trap_data5; + trap_data5.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data5.nx_snmp_object_data_msw = counter++; + + /* Null terminate the list. */ + trap_list[6].nx_snmp_object_string_ptr = NX_NULL; + trap_list[6].nx_snmp_object_data = NX_NULL; +#endif + + status = nx_snmp_agent_trapv2_send(&v2_my_agent, SNMP_MANAGER_ADDRESS, (UCHAR *)"trap", NX_SNMP_TRAP_COLDSTART, tx_time_get(), &trap_list[0]); + + if (status) + { + error_counter++; + } + + + /* Check for correct internal counters of SNMP processing. */ + if ((v2_my_agent.nx_snmp_agent_get_requests != 1) || + (v2_my_agent.nx_snmp_agent_total_get_variables != 1) || + (v2_my_agent.nx_snmp_agent_packets_received != 1) || + (v2_my_agent.nx_snmp_agent_packets_sent != 2) || + (v2_my_agent.nx_snmp_agent_getresponse_sent != 1) || + (v2_my_agent.nx_snmp_agent_traps_sent != 1)) + { + error_counter++; + } + + + /* Check for errors processing the request and sending the trap. */ + if (v2_my_agent.nx_snmp_agent_invalid_packets || + v2_my_agent.nx_snmp_agent_internal_errors || + v2_my_agent.nx_snmp_agent_allocation_errors || + v2_my_agent.nx_snmp_agent_request_errors || + v2_my_agent.nx_snmp_agent_too_big_errors || + v2_my_agent.nx_snmp_agent_username_errors || + v2_my_agent.nx_snmp_agent_unknown_requests) + { + + error_counter++; + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; + +} + +/* SNMP Manager thread */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT port; +UINT i; +USHORT request_id = 1; + + /* Let the agent get set up first! */ + tx_thread_sleep(50); + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&snmp_manager_socket, 161, 200); + + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Get the SNMP agent UDP port. */ + status = nx_udp_packet_info_extract(agent_packet, NX_NULL ,NX_NULL, &port, NX_NULL); + + /* Check status. */ + + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Indicate the test is complete. */ + v2query_response_complete = NX_TRUE; + + /* Unbind the UDP socket. */ + nx_udp_socket_unbind(&snmp_manager_socket); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&snmp_manager_socket); + + return; +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&v2_pool_0, &response_packet, NX_UDP_PACKET, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + return(1); + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, response_packet, IP_ADDRESS(10, 0, 0, 10), 161); + + /* Check the status. */ + if (status) + { + + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + + +static void snmp_test_initialize() +{ + + snmp_query[0].snmp_query_pkt_data = &simple_get_query_pkt[0]; + snmp_query[0].snmp_query_pkt_size = simple_get_query_size; + +} + + +/* Define the application's GET processing routine. */ + +UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v2_mib2_variable_update(&agent_ip, &v2_my_agent); + + return NX_SUCCESS; + +} + +extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + sysUpTime = tx_time_get(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v2_send_trap_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V2 Send Trap Test....................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/snmp_test/netx_snmp_v2_unknown_oid_test.c b/test/regression/snmp_test/netx_snmp_v2_unknown_oid_test.c new file mode 100644 index 00000000..0af1e812 --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v2_unknown_oid_test.c @@ -0,0 +1,634 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + a request for an unknown item ("oid"). The SNMP agent should not responds, but + set an internal error and be able to respond to the next request. + + The MIB database is defined in demo_snmp_helper.h */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +extern MIB_ENTRY mib2_mib[]; + +static UINT v2query_response_complete = NX_FALSE; + +static UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +#define QUERY_COUNT 2 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT v2_my_agent; +static NX_PACKET_POOL v2_pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; + +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + + +extern char simple_get_query_unknown_oid_pkt[82]; +extern int simple_get_query_unknown_oid_size; +extern char simple_get_query_pkt[82]; +extern int simple_get_query_size; + + + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v2_unknown_oid_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&v2_pool_0, "NetX Main Packet Pool", 1000, pointer, 4096); + pointer = pointer + 4096; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &v2_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&v2_my_agent, "SNMP Agent", &agent_ip, pointer, 4096, &v2_pool_0, + v2_mib2_username_processing, v2_mib2_get_processing, + v2_mib2_getnext_processing, v2_mib2_set_processing); + + if (status) + { + error_counter++; + } + + return; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + printf("NetX Test: SNMP V2 Unknown OID Test.................................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&v2_my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Wait for the 'manager' to finish querying the Agent. */ + while (v2query_response_complete == NX_FALSE) + { + tx_thread_sleep(100); + } + + /* Check for correct internal counters of SNMP processing. */ + if ((v2_my_agent.nx_snmp_agent_get_requests != 1) || + (v2_my_agent.nx_snmp_agent_total_get_variables != 2) || + (v2_my_agent.nx_snmp_agent_packets_received != 2) || + (v2_my_agent.nx_snmp_agent_packets_sent != 2) || + (v2_my_agent.nx_snmp_agent_getresponse_sent != 2)) + { + error_counter++; + } + + /* Check for errors processing the requests. */ + if (v2_my_agent.nx_snmp_agent_invalid_packets || + v2_my_agent.nx_snmp_agent_internal_errors || + v2_my_agent.nx_snmp_agent_allocation_errors || + (v2_my_agent.nx_snmp_agent_request_errors != 1) || + v2_my_agent.nx_snmp_agent_too_big_errors || + v2_my_agent.nx_snmp_agent_username_errors || + v2_my_agent.nx_snmp_agent_unknown_requests) + { + + error_counter++; + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; + +} + +/* SNMP Manager thread */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT port; +UINT i; +USHORT request_id = 1; + + /* Let the agent get set up first! */ + tx_thread_sleep(50); + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&snmp_manager_socket, 161, 200); + + + /* Check status. */ + if (status) + { + error_counter++; + v2query_response_complete = NX_TRUE; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 200); + + /* Check status for known OIDs. */ + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* The first request is for an unknown OID. */ + else if (i == 0) + { + if ((v2_my_agent.nx_snmp_agent_no_such_name_errors != 1) && + (v2_my_agent.nx_snmp_agent_request_errors != 1)) + { + + /* The SNMP agent should increase it's counter of unknown OIDs. */ + error_counter++; + } + } + + /* Get the SNMP agent UDP port. */ + status = nx_udp_packet_info_extract(agent_packet, NX_NULL ,NX_NULL, &port, NX_NULL); + + /* Check status. */ + + if (status) + { + + error_counter++; + v2query_response_complete = NX_TRUE; + break; + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Indicate the test is complete. */ + v2query_response_complete = NX_TRUE; + + /* Unbind the UDP socket. */ + nx_udp_socket_unbind(&snmp_manager_socket); + + /* Delete the UDP socket. */ + nx_udp_socket_delete(&snmp_manager_socket); + + return; +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&v2_pool_0, &response_packet, NX_UDP_PACKET, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + return(1); + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, response_packet, IP_ADDRESS(10, 0, 0, 10), 161); + + /* Check the status. */ + if (status) + { + + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + + +static void snmp_test_initialize() +{ + + snmp_query[0].snmp_query_pkt_data = &simple_get_query_unknown_oid_pkt[0]; + + snmp_query[0].snmp_query_pkt_size = simple_get_query_unknown_oid_size; + + + snmp_query[1].snmp_query_pkt_data = &simple_get_query_pkt[0]; + snmp_query[1].snmp_query_pkt_size = simple_get_query_size; + + // snmp_query[2].snmp_query_pkt_data = &simple_get_bulk_query_pkt[0]; + // snmp_query[2].snmp_query_pkt_size = simple_get_bulk_query_size; + +} + + +/* Define the application's GET processing routine. */ + +UINT v2_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v2_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v2_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v2_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v2_mib2_variable_update(&agent_ip, &v2_my_agent); + + return NX_SUCCESS; + +} + +/* Define the application's update routine. */ + +VOID v2_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + return;; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v2_unknown_oid_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V2 Unknown OID Test..................................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_v3_buffer_overwrite_test.c b/test/regression/snmp_test/netx_snmp_v3_buffer_overwrite_test.c new file mode 100644 index 00000000..8afe0f6d --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v3_buffer_overwrite_test.c @@ -0,0 +1,520 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + a request for an unknown item ("oid"). The SNMP agent should not responds, but + set an internal error and be able to respond to the next request. + + The MIB database is defined in demo_snmp_helper.h */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_FRAGMENTATION) + +#define DEMO_STACK_SIZE 4096 + +extern MIB_ENTRY mib2_mib[]; + +//NX_SNMP_SECURITY_KEY my_authentication_key; + +NX_SNMP_SECURITY_KEY my_privacy_key; + +static UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +static UCHAR context_engine_id[] = {0x80, 0x00, 0x0d, 0xfe, 0x03, 0x00, 0x11, 0x23, 0x23, 0x44, 0x55}; +static UINT context_engine_size = 11; +static UCHAR context_name[] = {0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c}; +static UINT context_name_size = 7; + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; + +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10, 128, 16, 17) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG snmp_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Inject SNMP manager query. */ +static VOID packet_inject(UCHAR *data_ptr, UINT data_size); + + +extern unsigned char v3_buffer_overwrite_packet1[1514]; +extern int v3_buffer_overwrite_packet1_size; +extern unsigned char v3_buffer_overwrite_packet2[54]; +extern int v3_buffer_overwrite_packet2_size; + +#define QUERY_COUNT 2 + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, (sizeof(NX_PACKET) + 1536) * 10); + pointer = pointer + (sizeof(NX_PACKET) + 1536) * 10; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + status = nx_ip_fragment_enable(&agent_ip); + if (status) + { + error_counter++; + } +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *packet_ptr; + + printf("NetX Test: SNMP V3 Buffer Overwrite Test............................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "SNMP Agent", &agent_ip, snmp_stack, sizeof(snmp_stack), &pool_0, + mib2_username_processing, mib2_get_processing, + mib2_getnext_processing, mib2_set_processing); + + if (status) + { + error_counter++; + } + +#ifdef AUTHENTICATION_REQUIRED + /* Create an authentication key. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)"authpassword", &my_authentication_key); + if (status) + { + error_counter++; + } + + /* Use the authentication key. */ + status = nx_snmp_agent_authenticate_key_use(&my_agent, &my_authentication_key); + if (status) + { + error_counter++; + } +#endif + + /* Create a privacy key. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)"privpassword", &my_privacy_key); + if (status) + { + error_counter++; + } + +#if 0 + /* Use the privacy key. */ + status = nx_snmp_agent_privacy_key_use(&my_agent, &my_privacy_key); + if (status) + { + error_counter++; + } +#endif + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Inject the SNMP manager query packet. */ + packet_inject(snmp_query[i].snmp_query_pkt_data, snmp_query[i].snmp_query_pkt_size); + } + + /* Wait for processing snmp packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if (nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +static VOID packet_inject(UCHAR *data_ptr, UINT data_size) +{ +UINT status; +NX_PACKET *my_packet; + + status = nx_packet_allocate(&pool_0, &my_packet, NX_RECEIVE_PACKET, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Make sure IP header is 4-byte aligned. */ + my_packet -> nx_packet_prepend_ptr += 2; + my_packet -> nx_packet_append_ptr += 2; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(my_packet, data_ptr, data_size, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Skip the MAC header. */ + my_packet -> nx_packet_length -= 14; + my_packet -> nx_packet_prepend_ptr += 14; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&agent_ip, my_packet); +} + +static void snmp_test_initialize() +{ + snmp_query[0].snmp_query_pkt_data = &v3_buffer_overwrite_packet1[0]; + snmp_query[0].snmp_query_pkt_size = v3_buffer_overwrite_packet1_size; + + snmp_query[1].snmp_query_pkt_data = &v3_buffer_overwrite_packet2[0]; + snmp_query[1].snmp_query_pkt_size = v3_buffer_overwrite_packet2_size; +} + + +/* Define the application's GET processing routine. */ + +UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +/* Define the application's update routine. */ + +VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V3 Buffer Overwrite Test.............................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_v3_decrypt_pdu_buffer_overwrite_test.c b/test/regression/snmp_test/netx_snmp_v3_decrypt_pdu_buffer_overwrite_test.c new file mode 100644 index 00000000..b0f5873c --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v3_decrypt_pdu_buffer_overwrite_test.c @@ -0,0 +1,524 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + a request for an unknown item ("oid"). The SNMP agent should not responds, but + set an internal error and be able to respond to the next request. + + The MIB database is defined in demo_snmp_helper.h */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_FRAGMENTATION) + +#define DEMO_STACK_SIZE 4096 + +extern MIB_ENTRY mib2_mib[]; + +//NX_SNMP_SECURITY_KEY my_authentication_key; + +NX_SNMP_SECURITY_KEY my_privacy_key; + +static UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +static UCHAR context_engine_id[] = {0x80, 0x00, 0x0d, 0xfe, 0x03, 0x00, 0x11, 0x23, 0x23, 0x44, 0x55}; +static UINT context_engine_size = 11; +static UCHAR context_name[] = {0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c}; +static UINT context_name_size = 7; + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; + +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10, 128, 16, 17) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG snmp_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Inject SNMP manager query. */ +static VOID packet_inject(UCHAR *data_ptr, UINT data_size); + + +extern unsigned char v3_decrypt_pdu_buffer_overwrite_packet1[1514]; +extern int v3_decrypt_pdu_buffer_overwrite_packet1_size; +extern unsigned char v3_decrypt_pdu_buffer_overwrite_packet2[54]; +extern int v3_decrypt_pdu_buffer_overwrite_packet2_size; + +#define QUERY_COUNT 2 + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_decrypt_pdu_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, (sizeof(NX_PACKET) + 1536) * 10); + pointer = pointer + (sizeof(NX_PACKET) + 1536) * 10; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + status = nx_ip_fragment_enable(&agent_ip); + if (status) + { + error_counter++; + } +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *packet_ptr; + + printf("NetX Test: SNMP V3 Decrypt PDU Buffer Overwrite Test................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "SNMP Agent", &agent_ip, snmp_stack, sizeof(snmp_stack), &pool_0, + mib2_username_processing, mib2_get_processing, + mib2_getnext_processing, mib2_set_processing); + + if (status) + { + error_counter++; + } + + status = nx_snmp_agent_context_engine_set(&my_agent, context_engine_id, context_engine_size); + if (status != NX_SUCCESS) + { + error_counter++; + } + +#ifdef AUTHENTICATION_REQUIRED + /* Create an authentication key. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)"authpassword", &my_authentication_key); + if (status) + { + error_counter++; + } + + /* Use the authentication key. */ + status = nx_snmp_agent_authenticate_key_use(&my_agent, &my_authentication_key); + if (status) + { + error_counter++; + } +#endif + + /* Create a privacy key. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)"privpassword", &my_privacy_key); + if (status) + { + error_counter++; + } + + /* Use the privacy key. */ + status = nx_snmp_agent_privacy_key_use(&my_agent, &my_privacy_key); + if (status) + { + error_counter++; + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Inject the SNMP manager query packet. */ + packet_inject(snmp_query[i].snmp_query_pkt_data, snmp_query[i].snmp_query_pkt_size); + } + + /* Wait for processing snmp packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if ((nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT)) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +static VOID packet_inject(UCHAR *data_ptr, UINT data_size) +{ +UINT status; +NX_PACKET *my_packet; + + status = nx_packet_allocate(&pool_0, &my_packet, NX_RECEIVE_PACKET, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Make sure IP header is 4-byte aligned. */ + my_packet -> nx_packet_prepend_ptr += 2; + my_packet -> nx_packet_append_ptr += 2; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(my_packet, data_ptr, data_size, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Skip the MAC header. */ + my_packet -> nx_packet_length -= 14; + my_packet -> nx_packet_prepend_ptr += 14; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&agent_ip, my_packet); +} + +static void snmp_test_initialize() +{ + snmp_query[0].snmp_query_pkt_data = &v3_decrypt_pdu_buffer_overwrite_packet1[0]; + snmp_query[0].snmp_query_pkt_size = v3_decrypt_pdu_buffer_overwrite_packet1_size; + + snmp_query[1].snmp_query_pkt_data = &v3_decrypt_pdu_buffer_overwrite_packet2[0]; + snmp_query[1].snmp_query_pkt_size = v3_decrypt_pdu_buffer_overwrite_packet2_size; +} + + +/* Define the application's GET processing routine. */ + +UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +/* Define the application's update routine. */ + +VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_decrypt_pdu_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V3 Decrypt PDU Buffer Overwrite Test.................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_v3_encrypt_pdu_buffer_overwrite_test.c b/test/regression/snmp_test/netx_snmp_v3_encrypt_pdu_buffer_overwrite_test.c new file mode 100644 index 00000000..4e176c8e --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v3_encrypt_pdu_buffer_overwrite_test.c @@ -0,0 +1,517 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + a request for an unknown item ("oid"). The SNMP agent should not responds, but + set an internal error and be able to respond to the next request. + + The MIB database is defined in demo_snmp_helper.h */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +extern MIB_ENTRY mib2_mib[]; + //NX_SNMP_SECURITY_KEY my_authentication_key; + +NX_SNMP_SECURITY_KEY my_privacy_key; + +static UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +static UCHAR context_engine_id[] = {0x80, 0x00, 0x03, 0x10, 0x01, 0xc0, 0xa8, 0x64, 0xaf, 0x44, 0x55}; +static UINT context_engine_size = 11; +static UCHAR context_name[] = {0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c}; +static UINT context_name_size = 7; + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; + +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10, 128, 16, 17) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG snmp_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Inject SNMP manager query. */ +static VOID packet_inject(UCHAR *data_ptr, UINT data_size); + + +extern unsigned char v3_encrypt_pdu_buffer_overwrite_packet1[1063]; +extern int v3_encrypt_pdu_buffer_overwrite_packet1_size; + +#define QUERY_COUNT 1 + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_encrypt_pdu_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, (sizeof(NX_PACKET) + 1536) * 10); + pointer = pointer + (sizeof(NX_PACKET) + 1536) * 10; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *packet_ptr; + + printf("NetX Test: SNMP V3 Encrypt PDU Buffer Overwrite Test................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "SNMP Agent", &agent_ip, snmp_stack, sizeof(snmp_stack), &pool_0, + mib2_username_processing, mib2_get_processing, + mib2_getnext_processing, mib2_set_processing); + + if (status) + { + error_counter++; + } + +#ifdef AUTHENTICATION_REQUIRED + status = nx_snmp_agent_v3_context_boots_set(&my_agent, 1); + if (status) + { + error_counter++; + } + + status = nx_snmp_agent_context_engine_set(&my_agent, context_engine_id, context_engine_size); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create an authentication key. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)"authpassword", &my_authentication_key); + if (status) + { + error_counter++; + } + + /* Use the authentication key. */ + status = nx_snmp_agent_authenticate_key_use(&my_agent, &my_authentication_key); + if (status) + { + error_counter++; + } +#endif + + /* Create a privacy key. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)"privpassword", &my_privacy_key); + if (status) + { + error_counter++; + } + + /* Use the privacy key. */ + status = nx_snmp_agent_privacy_key_use(&my_agent, &my_privacy_key); + if (status) + { + error_counter++; + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Inject the SNMP manager query packet. */ + packet_inject(snmp_query[i].snmp_query_pkt_data, snmp_query[i].snmp_query_pkt_size); + } + + /* Wait for processing snmp packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if ((nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT)) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +static VOID packet_inject(UCHAR *data_ptr, UINT data_size) +{ +UINT status; +NX_PACKET *my_packet; + + status = nx_packet_allocate(&pool_0, &my_packet, NX_RECEIVE_PACKET, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Make sure IP header is 4-byte aligned. */ + my_packet -> nx_packet_prepend_ptr += 2; + my_packet -> nx_packet_append_ptr += 2; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(my_packet, data_ptr, data_size, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Skip the MAC header. */ + my_packet -> nx_packet_length -= 14; + my_packet -> nx_packet_prepend_ptr += 14; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&agent_ip, my_packet); +} + +static void snmp_test_initialize() +{ + snmp_query[0].snmp_query_pkt_data = &v3_encrypt_pdu_buffer_overwrite_packet1[0]; + snmp_query[0].snmp_query_pkt_size = v3_encrypt_pdu_buffer_overwrite_packet1_size; +} + + +/* Define the application's GET processing routine. */ + +UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +/* Define the application's update routine. */ + +VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_encrypt_pdu_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V3 Encrypt PDU Buffer Overwrite Test.................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_v3_encrypt_pdu_padding_buffer_overwrite_test.c b/test/regression/snmp_test/netx_snmp_v3_encrypt_pdu_padding_buffer_overwrite_test.c new file mode 100644 index 00000000..8f4429ce --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v3_encrypt_pdu_padding_buffer_overwrite_test.c @@ -0,0 +1,525 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + a request for an unknown item ("oid"). The SNMP agent should not responds, but + set an internal error and be able to respond to the next request. + + The MIB database is defined in demo_snmp_helper.h */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_FRAGMENTATION) + +#define DEMO_STACK_SIZE 4096 + +extern MIB_ENTRY mib2_mib[]; + +NX_SNMP_SECURITY_KEY my_authentication_key; + +NX_SNMP_SECURITY_KEY my_privacy_key; + +static UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +static UCHAR context_engine_id[] = {0x80, 0x00, 0x03, 0x10, 0x01, 0xc0, 0xa8, 0x64, 0xaf, 0x44, 0x55}; +static UINT context_engine_size = 11; +static UCHAR context_name[] = {0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c}; +static UINT context_name_size = 7; + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_PACKET_POOL pool_1; +static NX_IP agent_ip; + +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10, 128, 16, 17) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG snmp_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Inject SNMP manager query. */ +static VOID packet_inject(UCHAR *data_ptr, UINT data_size); + + +extern unsigned char v3_encrypt_pdu_padding_buffer_overwrite_packet1[165]; +extern int v3_encrypt_pdu_padding_buffer_overwrite_packet1_size; + +#define QUERY_COUNT 1 + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_encrypt_pdu_padding_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, (sizeof(NX_PACKET) + 1536) * 10); + pointer = pointer + (sizeof(NX_PACKET) + 1536) * 10; + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_1, "SNMP Packet Pool", 176, pointer, (sizeof(NX_PACKET) + 176) * 10); + pointer = pointer + (sizeof(NX_PACKET) + 176) * 10; + + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + status = nx_ip_fragment_enable(&agent_ip); + if (status) + { + error_counter++; + } +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *packet_ptr; + + printf("NetX Test: SNMP V3 Encrypt PDU Padding Buffer Overwrite Test........."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "SNMP Agent", &agent_ip, snmp_stack, sizeof(snmp_stack), &pool_1, + mib2_username_processing, mib2_get_processing, + mib2_getnext_processing, mib2_set_processing); + + if (status) + { + error_counter++; + } + + status = nx_snmp_agent_v3_context_boots_set(&my_agent, 1); + + if (status) + { + error_counter++; + } + /* Create an authentication key. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)"authpassword", &my_authentication_key); + if (status) + { + error_counter++; + } + + /* Use the authentication key. */ + status = nx_snmp_agent_authenticate_key_use(&my_agent, &my_authentication_key); + if (status) + { + error_counter++; + } + + /* Create a privacy key. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)"privpassword", &my_privacy_key); + if (status) + { + error_counter++; + } + + /* Use the privacy key. */ + status = nx_snmp_agent_privacy_key_use(&my_agent, &my_privacy_key); + if (status) + { + error_counter++; + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + my_agent.nx_snmp_agent_v3_context_engine_size = 6; + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Inject the SNMP manager query packet. */ + packet_inject(snmp_query[i].snmp_query_pkt_data, snmp_query[i].snmp_query_pkt_size); + } + + /* Wait for processing snmp packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_1.nx_packet_pool_available) + { + if ((nx_packet_allocate(&pool_1, &packet_ptr, 0, NX_NO_WAIT)) || + (packet_ptr -> nx_packet_pool_owner != &pool_1)) + { + error_counter++; + break; + } + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +static VOID packet_inject(UCHAR *data_ptr, UINT data_size) +{ +UINT status; +NX_PACKET *my_packet; + + status = nx_packet_allocate(&pool_0, &my_packet, NX_RECEIVE_PACKET, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Make sure IP header is 4-byte aligned. */ + my_packet -> nx_packet_prepend_ptr += 2; + my_packet -> nx_packet_append_ptr += 2; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(my_packet, data_ptr, data_size, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Skip the MAC header. */ + my_packet -> nx_packet_length -= 14; + my_packet -> nx_packet_prepend_ptr += 14; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&agent_ip, my_packet); +} + +static void snmp_test_initialize() +{ + snmp_query[0].snmp_query_pkt_data = &v3_encrypt_pdu_padding_buffer_overwrite_packet1[0]; + snmp_query[0].snmp_query_pkt_size = v3_encrypt_pdu_padding_buffer_overwrite_packet1_size; +} + + +/* Define the application's GET processing routine. */ + +UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +/* Define the application's update routine. */ + +VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_encrypt_pdu_padding_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V3 Encrypt PDU Padding Buffer Overwrite Test.........N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/netx_snmp_v3_md5_failed_security_test.c b/test/regression/snmp_test/netx_snmp_v3_md5_failed_security_test.c new file mode 100644 index 00000000..41d97529 --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v3_md5_failed_security_test.c @@ -0,0 +1,660 @@ +/* This NetX test concentrates on the SNMPv3 operation with MD5 security. The test uses a different authentiation and + encryption password than is received from the SNMP Manager. The test is successful if the SNMP Agent rejects the SNMP + manager response, sets an authentication error to notify the calling application authentication failed, and does not send a + response back to the SNMP Manager. + */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#define DEMO_STACK_SIZE 4096 + +#if !defined(NX_DISABLE_IPV4) + +extern MIB_ENTRY mib2_mib[]; + +static NX_SNMP_SECURITY_KEY my_authentication_key; +static NX_SNMP_SECURITY_KEY my_privacy_key; + +static UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + + +static UINT query_response_complete = NX_FALSE; /* to synchronize when the agent sends the SNMP trap */ +#define QUERY_COUNT 2 + +/* To show byte by byte comparison of pre-recorded response with SNMP agent, define this option. +#define VERBOSE +*/ + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char get_request_priv_pkt[59]; +extern int get_request_priv_size; +extern char getnext_request_priv_pkt[127]; +extern int getnext_request_priv_size; + + + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_md5_failed_security_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + status = tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + status += tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + /* Check for IP create errors. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1000, pointer, 10000); + pointer = pointer + 10000; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer , 2048, 1); + + pointer += 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer += 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "public", &agent_ip, pointer, 4096, &pool_0, + v3_mib2_username_processing, v3_mib2_get_processing, + v3_mib2_getnext_processing, v3_mib2_set_processing); + pointer = pointer + 4096; + + + if (status) + { + error_counter++; + } + + + /* Create an authentication key using MD5 and register it with the agent. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)("authpassword2"), &my_authentication_key); + + /* Register the authentication key with the agent. */ + status |= nx_snmp_agent_authenticate_key_use(&my_agent, &my_authentication_key); + + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a privacy key and register it with the SNMP agent. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)("privpassword2"), &my_privacy_key); + + status |= nx_snmp_agent_privacy_key_use(&my_agent, &my_privacy_key); + + if (status |= NX_SUCCESS) + { + error_counter++; + } + + return; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + printf("NetX Test: SNMP V3 with Failed MD5 Security Test....................."); + tx_thread_sleep(20); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Initialize our boot up count to 1. */ + status = nx_snmp_agent_v3_context_boots_set(&my_agent, 1); + + if (status) + { + error_counter++; + } + + /* Reset the system clock so we can reasonably fit in the 150 second Time Window. */ + tx_time_set(0); + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + while (!query_response_complete) + { + tx_thread_sleep(100); + } + + tx_thread_sleep(50); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT i; +USHORT request_id = 1; + + + /* Let the agent get set up first! */ + tx_thread_sleep(50); + + + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the UDP socket to an IP port. */ + status |= nx_udp_socket_bind(&snmp_manager_socket, 0, 100); + + /* Check status. */ + if (status) + { + + error_counter++; + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + + return; + } + + /* Load the test data. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent.. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + error_counter++; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 100); + + /* Check status. We should only get one response. */ + if (status && (i == 0)) + { + error_counter++; + break; + } + + /* Check for errors on discovery/report exchange. */ + if (i == 0) + { + if ((my_agent.nx_snmp_agent_reports_sent != 1) || (my_agent.nx_snmp_agent_unknown_engineid_count != 1)) + { + error_counter++; + break; + } + /* Allow variability in size due to unpredictable variables (timer). */ + if ((agent_packet -> nx_packet_length <= 105) || (agent_packet -> nx_packet_length >= 109)) + { + error_counter++; + break; + } + } + + /* Check for errors on the completion of V3 handshake. */ + if (i == 1) + { + /* When authentication fails, SNMP should set an authentication error and send another report. */ + if ((my_agent.nx_snmp_agent_authentication_errors == 0) || (my_agent.nx_snmp_agent_reports_sent > 1)) + { + error_counter++; + break; + } + + } + + if (status == NX_SUCCESS) + { + + /* Release the packet. */ + nx_packet_release(agent_packet); + } + + request_id++; + } + + /* Check for other general errors. */ + if (my_agent.nx_snmp_agent_request_errors || my_agent.nx_snmp_agent_internal_errors) + { + + error_counter++; + } + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *query_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &query_packet, NX_UDP_PACKET, 100); + + /* Check status. */ + if (status) + { + return status; + } + + + memset(query_packet -> nx_packet_prepend_ptr, 0, (query_packet -> nx_packet_data_end - query_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(query_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + query_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + query_packet -> nx_packet_append_ptr = query_packet -> nx_packet_prepend_ptr + query_packet -> nx_packet_length; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, query_packet, IP_ADDRESS(10, 0, 0, 10), 161); + + /* Check the status. */ + if (status) + nx_packet_release(query_packet); + + return status; +} + + +static void snmp_test_initialize() +{ + + /* Contact - no security*/ + snmp_query[0].snmp_query_pkt_data = &get_request_priv_pkt[0]; + snmp_query[0].snmp_query_pkt_size = get_request_priv_size; + snmp_query[1].snmp_query_pkt_data = &getnext_request_priv_pkt[0]; + snmp_query[1].snmp_query_pkt_size = getnext_request_priv_size; + + +} + + +/* Define the application's GET processing routine. */ + +UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v3_mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + sysUpTime = tx_time_get(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_md5_failed_security_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V3 with Failed MD5 Security Test.....................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/snmp_test/netx_snmp_v3_md5_security_extended_test.c b/test/regression/snmp_test/netx_snmp_v3_md5_security_extended_test.c new file mode 100644 index 00000000..2234f652 --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v3_md5_security_extended_test.c @@ -0,0 +1,668 @@ +/* This NetX test concentrates on the SNMPv3 operation with MD5 security. The test examines the response packet length + and internal statistics of processing a v3 response to pass the test. + */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#define DEMO_STACK_SIZE 4096 + +#if !defined(NX_DISABLE_IPV4) + +extern MIB_ENTRY mib2_mib[]; + +static NX_SNMP_SECURITY_KEY my_authentication_key; +static NX_SNMP_SECURITY_KEY my_privacy_key; + +static UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + + +static UINT query_response_complete = NX_FALSE; /* to synchronize when the agent sends the SNMP trap */ +#define QUERY_COUNT 2 + +/* To show byte by byte comparison of pre-recorded response with SNMP agent, define this option. +#define VERBOSE +*/ + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char get_request_priv_pkt[59]; +extern int get_request_priv_size; +extern char getnext_request_priv_pkt[127]; +extern int getnext_request_priv_size; + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_md5_security_extended_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + status = tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + status += tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + /* Check for IP create errors. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 15000); + pointer = pointer + 10000; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer , 2048, 1); + + pointer += 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer += 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "public", &agent_ip, pointer, 4096, &pool_0, + v3_mib2_username_processing, v3_mib2_get_processing, + v3_mib2_getnext_processing, v3_mib2_set_processing); + pointer = pointer + 4096; + + if (status) + { + error_counter++; + } + + status = nx_snmp_agent_v3_context_boots_set(&my_agent, 1); + + if (status) + { + error_counter++; + } + /* Create an authentication key using MD5 and register it with the agent. */ + status = nx_snmp_agent_md5_key_create_extended(&my_agent, (UCHAR *)("authpassword"), 12, &my_authentication_key); + + /* Register the authentication key with the agent. */ + status |= nx_snmp_agent_authenticate_key_use(&my_agent, &my_authentication_key); + + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a privacy key and register it with the SNMP agent. */ + status = nx_snmp_agent_md5_key_create_extended(&my_agent, (UCHAR *)("privpassword"), 12, &my_privacy_key); + + status |= nx_snmp_agent_privacy_key_use(&my_agent, &my_privacy_key); + + if (status |= NX_SUCCESS) + { + error_counter++; + } + + return; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + printf("NetX Test: SNMP V3 with MD5 Security Extended Test..................."); + tx_thread_sleep(20); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + while (!query_response_complete) + { + tx_thread_sleep(20); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT i; +USHORT request_id = 1; + + + /* Let the agent get set up first! */ + tx_thread_sleep(30); + + + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the UDP socket to an IP port. */ + status |= nx_udp_socket_bind(&snmp_manager_socket, 0, 100); + + /* Check status. */ + if (status) + { + + error_counter++; + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + + return; + } + + /* Load the test data. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent.. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + error_counter++; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 100); + + /* Check status. */ + if (status) + { + error_counter++; + break; + } + + /* Check for errors on discovery/report exchange. */ + if (i == 0) + { + if ((my_agent.nx_snmp_agent_reports_sent != 1) || (my_agent.nx_snmp_agent_unknown_engineid_count != 1)) + { + error_counter++; + break; + } + /* Allow variability in size due to unpredictable variables (timer). */ + if ((agent_packet -> nx_packet_length <= 105) || (agent_packet -> nx_packet_length >= 109)) + { + error_counter++; + break; + } + } + + /* Check for errors on the completion of V3 handshake. */ + if (i == 1) + { + if ((my_agent.nx_snmp_agent_getresponse_sent != 1) ||(my_agent.nx_snmp_agent_getnext_requests != 1)) + { + error_counter++; + break; + } + + if ((agent_packet -> nx_packet_length <= 136) || (agent_packet -> nx_packet_length >= 140)) + { + error_counter++; + break; + } + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Check for general errors. */ + if (my_agent.nx_snmp_agent_request_errors || my_agent.nx_snmp_agent_internal_errors) + { + + error_counter++; + } + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *query_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &query_packet, NX_UDP_PACKET, 100); + + /* Check status. */ + if (status) + { + return status; + } + + + memset(query_packet -> nx_packet_prepend_ptr, 0, (query_packet -> nx_packet_data_end - query_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(query_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + query_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + query_packet -> nx_packet_append_ptr = query_packet -> nx_packet_prepend_ptr + query_packet -> nx_packet_length; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, query_packet, SNMP_AGENT_ADDRESS, 161); + + /* Check the status. */ + if (status) + nx_packet_release(query_packet); + + return status; +} + + +static void snmp_test_initialize() +{ + + /* Contact - no security*/ + snmp_query[0].snmp_query_pkt_data = &get_request_priv_pkt[0]; + snmp_query[0].snmp_query_pkt_size = get_request_priv_size; + snmp_query[1].snmp_query_pkt_data = &getnext_request_priv_pkt[0]; + snmp_query[1].snmp_query_pkt_size = getnext_request_priv_size; + + +} + + +/* Define the application's GET processing routine. */ + +UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; +UINT object_requested_length; +UINT object_name_length; + + + /* Get the object requested length. */ + _nx_utility_string_length_check(object_requested, &object_requested_length, NX_SNMP_MAX_OCTET_STRING); + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* Get the object name length. */ + _nx_utility_string_length_check(mib2_mib[i].object_name, &object_name_length, NX_SNMP_MAX_OCTET_STRING); + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare_extended(object_requested, object_requested_length, mib2_mib[i].object_name, object_name_length); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; +UINT object_requested_length; +UINT object_name_length; +UINT object_value_length; + + + /* Get the object requested length. */ + _nx_utility_string_length_check(object_requested, &object_requested_length, NX_SNMP_MAX_OCTET_STRING); + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* Get the object name length. */ + _nx_utility_string_length_check(mib2_mib[i].object_name, &object_name_length, NX_SNMP_MAX_OCTET_STRING); + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare_extended(object_requested, object_requested_length, mib2_mib[i].object_name, object_name_length); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy_extended(mib2_mib[i].object_name, object_name_length, object_requested, NX_SNMP_MAX_OCTET_STRING + 1); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Get the object name length. */ + _nx_utility_string_length_check(mib2_mib[i].object_value_ptr, &object_value_length, NX_SNMP_MAX_OCTET_STRING); + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy_extended(mib2_mib[i].object_value_ptr, object_value_length, object_requested, NX_SNMP_MAX_OCTET_STRING + 1); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; +UINT object_requested_length; +UINT object_name_length; + + + /* Get the object requested length. */ + _nx_utility_string_length_check(object_requested, &object_requested_length, NX_MAX_STRING_LENGTH); + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* Get the object name length. */ + _nx_utility_string_length_check(mib2_mib[i].object_name, &object_name_length, NX_MAX_STRING_LENGTH); + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare_extended(object_requested, object_requested_length, mib2_mib[i].object_name, object_name_length); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v3_mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + // sysUpTime = tx_time_get(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_md5_security_extended_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V3 with MD5 Security Extended Test...................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/snmp_test/netx_snmp_v3_md5_security_test.c b/test/regression/snmp_test/netx_snmp_v3_md5_security_test.c new file mode 100644 index 00000000..5faa5e3b --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v3_md5_security_test.c @@ -0,0 +1,641 @@ +/* This NetX test concentrates on the SNMPv3 operation with MD5 security. The test examines the response packet length + and internal statistics of processing a v3 response to pass the test. + */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#define DEMO_STACK_SIZE 4096 + +#if !defined(NX_DISABLE_IPV4) + +extern MIB_ENTRY mib2_mib[]; + +static NX_SNMP_SECURITY_KEY my_authentication_key; +static NX_SNMP_SECURITY_KEY my_privacy_key; + +static UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + + +static UINT query_response_complete = NX_FALSE; /* to synchronize when the agent sends the SNMP trap */ +#define QUERY_COUNT 2 + +/* To show byte by byte comparison of pre-recorded response with SNMP agent, define this option. +#define VERBOSE +*/ + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter = 0; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char get_request_priv_pkt[59]; +extern int get_request_priv_size; +extern char getnext_request_priv_pkt[127]; +extern int getnext_request_priv_size; + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_md5_security_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + status = tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + status += tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + /* Check for IP create errors. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1500, pointer, 15000); + pointer = pointer + 10000; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer , 2048, 1); + + pointer += 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer += 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "public", &agent_ip, pointer, 4096, &pool_0, + v3_mib2_username_processing, v3_mib2_get_processing, + v3_mib2_getnext_processing, v3_mib2_set_processing); + pointer = pointer + 4096; + + if (status) + { + error_counter++; + } + + status = nx_snmp_agent_v3_context_boots_set(&my_agent, 1); + + if (status) + { + error_counter++; + } + /* Create an authentication key using MD5 and register it with the agent. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)("authpassword"), &my_authentication_key); + + /* Register the authentication key with the agent. */ + status |= nx_snmp_agent_authenticate_key_use(&my_agent, &my_authentication_key); + + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Create a privacy key and register it with the SNMP agent. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)("privpassword"), &my_privacy_key); + + status |= nx_snmp_agent_privacy_key_use(&my_agent, &my_privacy_key); + + if (status |= NX_SUCCESS) + { + error_counter++; + } + + return; + +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + printf("NetX Test: SNMP V3 with MD5 Security Test............................"); + tx_thread_sleep(20); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + while (!query_response_complete) + { + tx_thread_sleep(20); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT i; +USHORT request_id = 1; + + + /* Let the agent get set up first! */ + tx_thread_sleep(30); + + + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the UDP socket to an IP port. */ + status |= nx_udp_socket_bind(&snmp_manager_socket, 0, 100); + + /* Check status. */ + if (status) + { + + error_counter++; + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + + return; + } + + /* Load the test data. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent.. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + error_counter++; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 100); + + /* Check status. */ + if (status) + { + error_counter++; + break; + } + + /* Check for errors on discovery/report exchange. */ + if (i == 0) + { + if ((my_agent.nx_snmp_agent_reports_sent != 1) || (my_agent.nx_snmp_agent_unknown_engineid_count != 1)) + { + error_counter++; + break; + } + /* Allow variability in size due to unpredictable variables (timer). */ + if ((agent_packet -> nx_packet_length <= 105) || (agent_packet -> nx_packet_length >= 109)) + { + error_counter++; + break; + } + } + + /* Check for errors on the completion of V3 handshake. */ + if (i == 1) + { + if ((my_agent.nx_snmp_agent_getresponse_sent != 1) ||(my_agent.nx_snmp_agent_getnext_requests != 1)) + { + error_counter++; + break; + } + + if ((agent_packet -> nx_packet_length <= 136) || (agent_packet -> nx_packet_length >= 140)) + { + error_counter++; + break; + } + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Check for general errors. */ + if (my_agent.nx_snmp_agent_request_errors || my_agent.nx_snmp_agent_internal_errors) + { + + error_counter++; + } + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *query_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &query_packet, NX_UDP_PACKET, 100); + + /* Check status. */ + if (status) + { + return status; + } + + + memset(query_packet -> nx_packet_prepend_ptr, 0, (query_packet -> nx_packet_data_end - query_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(query_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + query_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + query_packet -> nx_packet_append_ptr = query_packet -> nx_packet_prepend_ptr + query_packet -> nx_packet_length; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, query_packet, SNMP_AGENT_ADDRESS, 161); + + /* Check the status. */ + if (status) + nx_packet_release(query_packet); + + return status; +} + + +static void snmp_test_initialize() +{ + + /* Contact - no security*/ + snmp_query[0].snmp_query_pkt_data = &get_request_priv_pkt[0]; + snmp_query[0].snmp_query_pkt_size = get_request_priv_size; + snmp_query[1].snmp_query_pkt_data = &getnext_request_priv_pkt[0]; + snmp_query[1].snmp_query_pkt_size = getnext_request_priv_size; + + +} + + +/* Define the application's GET processing routine. */ + +UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v3_mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + // sysUpTime = tx_time_get(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_md5_security_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V3 with MD5 Security Test............................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/snmp_test/netx_snmp_v3_no_security_function_test.c b/test/regression/snmp_test/netx_snmp_v3_no_security_function_test.c new file mode 100644 index 00000000..0ed15cab --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v3_no_security_function_test.c @@ -0,0 +1,660 @@ +/* This NetX test concentrates on the SNMPv3 operation with no security. The test examines the response packet length + and internal statistics of processing a v3 response to pass the test. + */ + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + + +extern MIB_ENTRY mib2_mib[]; + +static UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + + +static UINT query_response_complete = NX_FALSE; /* to synchronize when the agent sends the SNMP trap */ +#define QUERY_COUNT 2 + +/* To show byte by byte comparison of pre-recorded response with SNMP agent, define this option. +#define VERBOSE +*/ + + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; +static NX_UDP_SOCKET snmp_manager_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + + +static UCHAR context_engine_id[] = {0x80, 0x00, 0x0d, 0xfe, 0x03, 0x00, 0x77, 0x23, 0x23, 0x46, 0x69}; +static UINT context_engine_size = 11; + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern char v3_nosec_getrequest_pkt[58]; +extern int v3_nosec_getrequest_size; +extern char v3_nosec_getnext_request_pkt[98]; +extern int v3_nosec_getnext_request_size; + + + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_no_security_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + status = tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + status += tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + pointer = pointer + DEMO_STACK_SIZE; + + /* Check for IP create errors. */ + /* Check for IP create errors. */ + if (status) + { + error_counter++; + test_control_return(1); + } + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1000, pointer, 8192); + pointer = pointer + 8192; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Create an IP instance. */ + status = nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer , 2048, 1); + + pointer += 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, pointer, 2048, 1); + + pointer += 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "public", &agent_ip, pointer, 4096, &pool_0, + v3_mib2_username_processing, v3_mib2_get_processing, + v3_mib2_getnext_processing, v3_mib2_set_processing); + pointer = pointer + 4096; + + + if (status) + { + error_counter++; + } + + return; +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +ULONG boot_count = 0x1; +UINT version = NX_SNMP_VERSION_3; +UINT i; + + + printf("NetX Test: SNMP V3 No Security Test.................................."); + tx_thread_sleep(20); + + if (error_counter) + { + error_counter++; + } + + /* Make sure boot time and engine boot ID match the pre-recorded data. */ + status = nx_snmp_agent_context_engine_set(&my_agent, context_engine_id, context_engine_size); + status |= nx_snmp_agent_v3_context_boots_set(&my_agent, boot_count); + + if (status) + { + error_counter++; + + } + + /* Otherwise, store the context engine. */ + for (i = 0; i < context_engine_size; i++) + { + + /* Check each byte of the context engine. */ + if (my_agent.nx_snmp_agent_v3_context_engine[i] != context_engine_id[i]) + { + error_counter++; + } + } + + /* Check the context engine length. */ + if (my_agent.nx_snmp_agent_v3_context_engine_size != context_engine_size) + { + error_counter++; + } + + if (my_agent.nx_snmp_agent_v3_context_engine_boots != boot_count) + { + error_counter++; + } + + /* Reset the system clock so we can reasonably fit in the 150 second Time Window. */ + tx_time_set(0); + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + while (!query_response_complete) + tx_thread_sleep(50); + + /* Verify that we are receiving SNMPv3 packets. */ + status = nx_snmp_agent_current_version_get(&my_agent, &version); + + if (status || (version != NX_SNMP_VERSION_3)) + { + error_counter++; + } + + if (error_counter ) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + + +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT i; +USHORT request_id = 1; + + /* Let the agent get set up first! */ + tx_thread_sleep(100); + + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Bind the UDP socket to the IP port. */ + status |= nx_udp_socket_bind(&snmp_manager_socket, 161, 100); + + /* Check status. */ + if (status) + { + + error_counter++; + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + + error_counter++; + } + + /* Load the test data. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent.. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + error_counter++; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 100); + + /* Check status. */ + if (status) + { + error_counter++; + break; + } + + /* Check for errors on discovery/report exchange. */ + if (i == 0) + { + if ((my_agent.nx_snmp_agent_reports_sent != 1) || (my_agent.nx_snmp_agent_unknown_engineid_count != 1)) + { + error_counter++; + break; + } + + /* Allow variability for size of certain timer variables (unpredictable). */ + if ((agent_packet -> nx_packet_length < 108) || (agent_packet -> nx_packet_length > 112)) + { + error_counter++; + break; + } + } + + /* Check for errors on the completion of V3 handshake. */ + if (i == 1) + { + if ((my_agent.nx_snmp_agent_getresponse_sent != 1) ||(my_agent.nx_snmp_agent_getnext_requests != 1)) + { + error_counter++; + break; + } + + /* Allow variability for size of certain timer variables (unpredictable). */ + if ((agent_packet -> nx_packet_length < 110) || (agent_packet -> nx_packet_length > 114)) + { + error_counter++; + break; + } + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + request_id++; + } + + /* Check for general errors. */ + if (my_agent.nx_snmp_agent_request_errors || my_agent.nx_snmp_agent_internal_errors) + { + + error_counter++; + } + + /* Indicate the query response is complete. */ + query_response_complete = NX_TRUE; + +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *query_packet; + + /* Allocate a response packet. */ + status = nx_packet_allocate(&pool_0, &query_packet, NX_UDP_PACKET, 100); + + /* Check status. */ + if (status) + { + return status; + } + + memset(query_packet -> nx_packet_prepend_ptr, 0, (query_packet -> nx_packet_data_end - query_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(query_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + query_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + query_packet -> nx_packet_append_ptr = query_packet -> nx_packet_prepend_ptr + query_packet -> nx_packet_length; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, query_packet, IP_ADDRESS(10, 0, 0, 10), 161); + + /* Check the status. */ + if (status) + nx_packet_release(query_packet); + + return status; +} + + +static void snmp_test_initialize() +{ + + /* Contact - no security*/ + snmp_query[0].snmp_query_pkt_data = &v3_nosec_getrequest_pkt[0]; + snmp_query[0].snmp_query_pkt_size = v3_nosec_getrequest_size; + snmp_query[1].snmp_query_pkt_data = &v3_nosec_getnext_request_pkt[0]; + snmp_query[1].snmp_query_pkt_size = v3_nosec_getnext_request_size; + +} + + +/* Define the application's GET processing routine. */ + +UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v3_mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + //sysUpTime = tx_time_get(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_no_security_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V3 No Security Test..................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/snmp_test/netx_snmp_v3_nosec_traplist_test.c b/test/regression/snmp_test/netx_snmp_v3_nosec_traplist_test.c new file mode 100644 index 00000000..73b0aa6d --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v3_nosec_traplist_test.c @@ -0,0 +1,895 @@ +/* This SNMP Agent test sends a V3 trap with a non null trap list. A successful result is the correction + number of messages/packets sent, no internal errors and successful search of all the items in the trap list + sent to the SNMP Agent. */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + + +extern MIB_ENTRY mib2_mib[]; + +static UINT v3query_response_complete = NX_FALSE; +static UINT v3_trap_test_complete = NX_FALSE; + +static UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +#define QUERY_COUNT 2 +#define OID_COUNT 7 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static TX_THREAD thread_manager; +static NX_SNMP_AGENT v3_my_agent; +static NX_PACKET_POOL v3_pool_0; +static NX_IP agent_ip; +static NX_IP manager_ip; + +static NX_UDP_SOCKET snmp_manager_socket; +static NX_UDP_SOCKET snmp_manager_trap_socket; + +#define SNMP_MANAGER_ADDRESS IP_ADDRESS(10,0,0,1) +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10,0,0,10) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + + +/* Send SNMP manager query. */ +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT request_id, UINT packet_number); + +extern unsigned char trap_v3_nosec_get_request_pkt[58]; +extern int trap_v3_nosec_get_request_size; +extern unsigned char trap_v3_nosec_get_next_request_pkt[94]; +extern int trap_v3_nosec_get_next_request_size; +extern unsigned char trap_v3_nosec_pkt[218]; +extern int trap_v3_nosec_size; + +typedef struct SNMP_QUERY_STRUCT +{ + unsigned char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_nosec_traplist_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create the SNMP Manager thread. */ + tx_thread_create(&thread_manager, "Manager thread", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&v3_pool_0, "NetX Main Packet Pool", 1000, pointer, 10000); + pointer = pointer + 10000; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &v3_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Create another IP instance. */ + status += nx_ip_create(&manager_ip, "Manager IP", SNMP_MANAGER_ADDRESS, 0xFFFFFF00UL, &v3_pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ARP and supply ARP cache memory for IP Instance 1. */ + status += nx_arp_enable(&manager_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + status += nx_udp_enable(&manager_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&v3_my_agent, "SNMP Agent", &agent_ip, pointer, 4096, &v3_pool_0, + v3_mib2_username_processing, v3_mib2_get_processing, + v3_mib2_getnext_processing, v3_mib2_set_processing); + + if (status) + { + error_counter++; + } + + return; +} + + + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +NX_SNMP_TRAP_OBJECT trap_list[7]; +NX_SNMP_OBJECT_DATA trap_data0; +NX_SNMP_OBJECT_DATA trap_data1; +NX_SNMP_OBJECT_DATA trap_data2; +NX_SNMP_OBJECT_DATA trap_data3; +NX_SNMP_OBJECT_DATA trap_data4; +NX_SNMP_OBJECT_DATA trap_data5; +UINT counter = 99; + + + printf("NetX Test: SNMP V3 No Security Trap List Test........................"); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Reset the system clock so we can reasonably fit in the 150 second Time Window. */ + tx_time_set(0); + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&v3_my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Wait for the 'manager' to finish querying the Agent. */ + while (v3query_response_complete == NX_FALSE) + { + tx_thread_sleep(50); + } + + /* Now send the trap. */ + trap_list[0].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.1.0"; + trap_list[0].nx_snmp_object_data = &trap_data0; + trap_data0.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data0.nx_snmp_object_data_msw = counter++; + + trap_list[1].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.7.0"; + trap_list[1].nx_snmp_object_data = &trap_data1; + trap_data1.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data1.nx_snmp_object_data_msw = counter++; + + trap_list[2].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.8.0"; + trap_list[2].nx_snmp_object_data = &trap_data2; + trap_data2.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data2.nx_snmp_object_data_msw = tx_time_get(); + + trap_list[3].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.9.0"; + trap_list[3].nx_snmp_object_data = &trap_data3; + trap_data3.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data3.nx_snmp_object_data_msw = counter++; + + trap_list[4].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.10.0"; + trap_list[4].nx_snmp_object_data = &trap_data4; + trap_data4.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data4.nx_snmp_object_data_msw = tx_time_get(); + + + trap_list[5].nx_snmp_object_string_ptr = (UCHAR *) "1.3.6.1.2.1.2.2.1.10.0.2"; + trap_list[5].nx_snmp_object_data = &trap_data5; + trap_data5.nx_snmp_object_data_type = NX_SNMP_INTEGER; + trap_data5.nx_snmp_object_data_msw = counter++; + + /* Null terminate the list. */ + trap_list[6].nx_snmp_object_string_ptr = NX_NULL; + trap_list[6].nx_snmp_object_data = NX_NULL; + + status = nx_snmp_agent_trapv3_send(&v3_my_agent, SNMP_MANAGER_ADDRESS, (UCHAR *)"trap", NX_SNMP_TRAP_COLDSTART, tx_time_get(), &trap_list[0]); + + if (status) + { + error_counter++; + } + + /* Check for correct internal counters of SNMP processing. */ + if ((v3_my_agent.nx_snmp_agent_reports_sent != 1) || + (v3_my_agent.nx_snmp_agent_total_get_variables != 2) || + (v3_my_agent.nx_snmp_agent_packets_received != 2) || + (v3_my_agent.nx_snmp_agent_packets_sent != 3) || + (v3_my_agent.nx_snmp_agent_getresponse_sent != 1) || + (v3_my_agent.nx_snmp_agent_traps_sent != 1)) + { + error_counter++; + } + + /* Check for errors processing the request and sending the trap. */ + if (v3_my_agent.nx_snmp_agent_invalid_packets || + v3_my_agent.nx_snmp_agent_internal_errors || + v3_my_agent.nx_snmp_agent_allocation_errors || + v3_my_agent.nx_snmp_agent_request_errors || + v3_my_agent.nx_snmp_agent_too_big_errors || + v3_my_agent.nx_snmp_agent_username_errors || + v3_my_agent.nx_snmp_agent_unknown_requests) + { + + error_counter++; + } + + while (v3_trap_test_complete == NX_FALSE) + { + tx_thread_sleep(50); + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; + +} + +/* SNMP Manager thread */ +static void thread_1_entry(ULONG thread_input) +{ + +NX_PACKET *agent_packet; +UINT i; +USHORT request_id = 1; +UINT oids_found = 0; +UCHAR *work_ptr; + + /* Let the agent get set up first! */ + tx_thread_sleep(50); + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&manager_ip, &snmp_manager_socket, "Manager Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + v3query_response_complete = NX_TRUE; + return; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&snmp_manager_socket, 161, 200); + + + /* Check status. */ + if (status) + { + error_counter++; + v3query_response_complete = NX_TRUE; + return; + } + + /* Create a UDP socket act as the DNS server. */ + status = nx_udp_socket_create(&manager_ip, &snmp_manager_trap_socket, "Manager Trap Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + /* Check status. */ + if (status) + { + error_counter++; + v3query_response_complete = NX_TRUE; + return; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&snmp_manager_trap_socket, 162, 200); + + + /* Check status. */ + if (status) + { + error_counter++; + v3query_response_complete = NX_TRUE; + return; + } + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Send the SNMP manager query packet. */ + status = nx_snmp_query_packet_send(&snmp_manager_socket, request_id, i); + + /* Check status. */ + if (status) + { + + error_counter++; + v3query_response_complete = NX_TRUE; + break; + } + + /* Receive the SNMP agent response. */ + status = nx_udp_socket_receive(&snmp_manager_socket, &agent_packet, 400); + + /* Check status. */ + if (status) + { + + error_counter++; + v3query_response_complete = NX_TRUE; + break; + } + + /* Release the packet. */ + nx_packet_release(agent_packet); + + tx_thread_sleep(100); + + request_id++; + } + + /* Indicate the handshake is complete. */ + v3query_response_complete = NX_TRUE; + + /* Check for errors, ending the test. */ + if (error_counter) + { + return; + } + + /* Receive the SNMP agent trap */ + status = nx_udp_socket_receive(&snmp_manager_trap_socket, &agent_packet, 400); + + /* Check received packet status. */ + if (status) + { + + error_counter++; + } + else + { + + /* Got a packet, now compare it for correct content. */ + work_ptr = agent_packet -> nx_packet_prepend_ptr + 80; /* Move past all the SNMP global headers etc to the data section. */ + + /* Search for the correct trap items in the list. */ + while ((work_ptr < agent_packet -> nx_packet_prepend_ptr + agent_packet -> nx_packet_length) && (oids_found <= OID_COUNT)) + { + + if ((oids_found == 0) && + (*work_ptr == 0x06) && + (*(work_ptr + 1) == 0x01) && + (*(work_ptr + 2) == 0x02) && + (*(work_ptr + 3) == 0x01) && + (*(work_ptr + 4) == 0x01) && + (*(work_ptr + 5) == 0x03) && + (*(work_ptr + 6) == 0x00) && + (*(work_ptr + 7) == 0x43) && + (*(work_ptr + 8) == 0x02)) + /* This OID data is the system time, it is variable so skip it. */ + { + oids_found++; + /* Skip over this OID and value to the next OID */ + work_ptr += 11; + + continue; + } + + + else if ((oids_found == 1) && + (*work_ptr == 0x06) && + (*(work_ptr + 1) == 0x01) && + (*(work_ptr + 2) == 0x06) && + (*(work_ptr + 3) == 0x03) && + (*(work_ptr + 4) == 0x01) && + (*(work_ptr + 5) == 0x01) && + (*(work_ptr + 6) == 0x04) && + (*(work_ptr + 7) == 0x01) && + (*(work_ptr + 8) == 0x00) && + (*(work_ptr + 9) == 0x06) && + (*(work_ptr + 10) == 0x0a) && + (*(work_ptr + 11) == 0x2b) && + (*(work_ptr + 12) == 0x06) && + (*(work_ptr + 13) == 0x01) && + (*(work_ptr + 14) == 0x06) && + (*(work_ptr + 15) == 0x03)) + + /* This OID's data is another OID, no need to check past the base of the OID 1.3.6.1.6.3, + common to all OIDs. The rest depends on the MIB. */ + { + oids_found++; + + work_ptr += 20; /* Skip past the OID and its data which itself is an OID */ + + continue; + } + + + else if ((oids_found == 2) && + (*work_ptr == 0x06) && + (*(work_ptr + 1) == 0x01) && + (*(work_ptr + 2) == 0x02) && + (*(work_ptr + 3) == 0x01) && + (*(work_ptr + 4) == 0x02) && + (*(work_ptr + 5) == 0x02) && + (*(work_ptr + 6) == 0x01) && + (*(work_ptr + 7) == 0x01) && + (*(work_ptr + 8) == 0x00) && + (*(work_ptr + 9) == 0x02) && + (*(work_ptr + 10) == 0x01) && + (*(work_ptr + 11) == 0x63)) + /* This is a preset counter field so we know the data size and the data set to 99. */ + { + oids_found++; + + work_ptr += 11; /* Skip past the OID and its data */ + + continue; + + } + + + else if ((oids_found == 3) && + (*work_ptr == 0x06) && + (*(work_ptr + 1) == 0x01) && + (*(work_ptr + 2) == 0x02) && + (*(work_ptr + 3) == 0x01) && + (*(work_ptr + 4) == 0x02) && + (*(work_ptr + 5) == 0x02) && + (*(work_ptr + 6) == 0x01) && + (*(work_ptr + 7) == 0x07) && + (*(work_ptr + 8) == 0x00) && + (*(work_ptr + 9) == 0x02) && + (*(work_ptr + 10) == 0x01) && + (*(work_ptr + 11) == 0x64)) + /* This is the preset counter field so we know the data size and the data is incremented by 1. */ + { + oids_found++; + + work_ptr += 11; /* Skip past the OID and its data */ + + continue; + } + + + else if ((oids_found == 4) && + (*work_ptr == 0x06) && + (*(work_ptr + 1) == 0x01) && + (*(work_ptr + 2) == 0x02) && + (*(work_ptr + 3) == 0x01) && + (*(work_ptr + 4) == 0x02) && + (*(work_ptr + 5) == 0x02) && + (*(work_ptr + 6) == 0x01) && + (*(work_ptr + 7) == 0x08) && + (*(work_ptr + 8) == 0x00) && + (*(work_ptr + 9) == 0x02) && + (*(work_ptr + 10) == 0x02)) + /* This should be a two byte data field and timer data (timer ticks) is variable so leave it off */ + { + oids_found++; + + work_ptr += 11; /* Skip past the OID and its data */ + + continue; + + } + + + else if ((oids_found == 5) && + (*work_ptr == 0x06) && + (*(work_ptr + 1) == 0x01) && + (*(work_ptr + 2) == 0x02) && + (*(work_ptr + 3) == 0x01) && + (*(work_ptr + 4) == 0x02) && + (*(work_ptr + 5) == 0x02) && + (*(work_ptr + 6) == 0x01) && + (*(work_ptr + 7) == 0x09) && + (*(work_ptr + 8) == 0x00) && + (*(work_ptr + 9) == 0x02) && + (*(work_ptr + 10) == 0x01) && + (*(work_ptr + 11) == 0x65)) + /* This is the preset counter field so we know the data size and the data is incremented by 1. */ + { + oids_found++; + + work_ptr += 11; /* Skip past the OID and its data */ + + continue; + } + + else if ((oids_found == 6) && + (*work_ptr == 0x06) && + (*(work_ptr + 1) == 0x01) && + (*(work_ptr + 2) == 0x02) && + (*(work_ptr + 3) == 0x01) && + (*(work_ptr + 4) == 0x02) && + (*(work_ptr + 5) == 0x02) && + (*(work_ptr + 6) == 0x01) && + (*(work_ptr + 7) == 0x0a) && + (*(work_ptr + 8) == 0x00) && + (*(work_ptr + 9) == 0x02) && + (*(work_ptr + 10) == 0x02)) + /* This should be a two byte data field and timer data (timer ticks) is variable so leave it off */ + { + oids_found++; + + break; + } + + work_ptr++; + } + } + + if (oids_found != OID_COUNT) + { + + error_counter++; + } + + /* Indicate the test is complete. */ + v3_trap_test_complete = NX_TRUE; + + /* Unbind the UDP socket. */ + status = nx_udp_socket_unbind(&snmp_manager_socket); + + /* Delete the UDP socket. */ + status |= nx_udp_socket_delete(&snmp_manager_socket); + + if (status) + { + error_counter++; + } + + return; +} + + +static UINT nx_snmp_query_packet_send(NX_UDP_SOCKET *snmp_manager_socket, UINT snmp_request_id, UINT packet_number) +{ +UINT status; +NX_PACKET *response_packet; + + + /* Allocate a response packet. */ + status = nx_packet_allocate(&v3_pool_0, &response_packet, NX_UDP_PACKET, 200); + + /* Check status. */ + if (status) + { + + error_counter++; + return(1); + } + + memset(response_packet -> nx_packet_prepend_ptr, 0, (response_packet -> nx_packet_data_end - response_packet -> nx_packet_prepend_ptr)); + + /* Write the SMTP response messages into the packet payload! */ + memcpy(response_packet -> nx_packet_prepend_ptr, + snmp_query[packet_number].snmp_query_pkt_data, + snmp_query[packet_number].snmp_query_pkt_size); + + /* Adjust the write pointer. */ + response_packet -> nx_packet_length = snmp_query[packet_number].snmp_query_pkt_size; + response_packet -> nx_packet_append_ptr = response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length; + + /* Send the UDP packet with the correct port. */ + status = nx_udp_socket_send(snmp_manager_socket, response_packet, IP_ADDRESS(10, 0, 0, 10), 161); + + /* Check the status. */ + if (status) + { + + error_counter++; + nx_packet_release(response_packet); + } + + return status; +} + + +static void snmp_test_initialize() +{ + + snmp_query[0].snmp_query_pkt_data = &trap_v3_nosec_get_request_pkt[0]; + snmp_query[0].snmp_query_pkt_size = trap_v3_nosec_get_request_size; + snmp_query[1].snmp_query_pkt_data = &trap_v3_nosec_get_next_request_pkt[0]; + snmp_query[1].snmp_query_pkt_size = trap_v3_nosec_get_next_request_size; + +} + + +/* Define the application's GET processing routine. */ + +UINT v3_mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT v3_mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT v3_mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT v3_mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + v3_mib2_variable_update(&agent_ip, &v3_my_agent); + + return NX_SUCCESS; + +} + +extern ULONG sysUpTime; +/* Define the application's update routine. */ + +VOID v3_mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + sysUpTime = tx_time_get(); +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_nosec_traplist_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V3 No Security Trap List Test........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/snmp_test/netx_snmp_v3_object_id_buffer_overwrite_test.c b/test/regression/snmp_test/netx_snmp_v3_object_id_buffer_overwrite_test.c new file mode 100644 index 00000000..6c08c555 --- /dev/null +++ b/test/regression/snmp_test/netx_snmp_v3_object_id_buffer_overwrite_test.c @@ -0,0 +1,517 @@ +/* This NetX test concentrates on the basic SNMPv2 operation. The 'manager' sends + a request for an unknown item ("oid"). The SNMP agent should not responds, but + set an internal error and be able to respond to the next request. + + The MIB database is defined in demo_snmp_helper.h */ + + +#include "tx_api.h" +#include "nx_api.h" +#if defined(__PRODUCT_NETXDUO__) +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif +#include "nx_udp.h" +#include "small_mib_helper.h" + +extern void test_control_return(UINT); + +#if !defined(NX_DISABLE_IPV4) + +#define DEMO_STACK_SIZE 4096 + +extern MIB_ENTRY mib2_mib[]; + //NX_SNMP_SECURITY_KEY my_authentication_key; + +NX_SNMP_SECURITY_KEY my_privacy_key; + +static UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +static UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +static VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); + +static UCHAR context_engine_id[] = {0x80, 0x00, 0x03, 0x10, 0x01, 0xc0, 0xa8, 0x64, 0xaf, 0x44, 0x55}; +static UINT context_engine_size = 11; +static UCHAR context_name[] = {0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c}; +static UINT context_name_size = 7; + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_agent; +static NX_SNMP_AGENT my_agent; +static NX_PACKET_POOL pool_0; +static NX_IP agent_ip; + +#define SNMP_AGENT_ADDRESS IP_ADDRESS(10, 128, 16, 17) + + +/* Define the counters used in the demo application... */ + +static UINT status; +static ULONG error_counter; +static ULONG snmp_stack[DEMO_STACK_SIZE / sizeof(ULONG)]; + + +/* Define thread prototypes. */ + +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +static void snmp_test_initialize(); + +/* Inject SNMP manager query. */ +static VOID packet_inject(UCHAR *data_ptr, UINT data_size); + + +extern unsigned char v3_object_id_buffer_overwrite_packet1[1514]; +extern int v3_object_id_buffer_overwrite_packet1_size; + +#define QUERY_COUNT 1 + +typedef struct SNMP_QUERY_STRUCT +{ + char *snmp_query_pkt_data; + int snmp_query_pkt_size; +} SNMP_QUERY; + + +static SNMP_QUERY snmp_query[QUERY_COUNT]; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_object_id_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + +CHAR *pointer; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + /* Create the SNMP agent thread. */ + tx_thread_create(&thread_agent, "Agent thread", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, (sizeof(NX_PACKET) + 1536) * 10); + pointer = pointer + (sizeof(NX_PACKET) + 1536) * 10; + + /* Create an IP instance. */ + status += nx_ip_create(&agent_ip, "Agent IP", SNMP_AGENT_ADDRESS, 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Check for IP create errors. */ + if (status) + { + error_counter++; + } + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&agent_ip, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Check for ARP enable errors. */ + if (status) + { + error_counter++; + } + + /* Enable UDP traffic. */ + status = nx_udp_enable(&agent_ip); + + /* Check for UDP enable errors. */ + if (status) + { + error_counter++; + } +} + +/* Define the test threads. */ + +static void thread_0_entry(ULONG thread_input) +{ + +UINT status; +UINT i; +NX_PACKET *packet_ptr; + + printf("NetX Test: SNMP V3 Object ID Buffer OverWrite Test..................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Create an SNMP agent instance. */ + status = nx_snmp_agent_create(&my_agent, "SNMP Agent", &agent_ip, snmp_stack, sizeof(snmp_stack), &pool_0, + mib2_username_processing, mib2_get_processing, + mib2_getnext_processing, mib2_set_processing); + + if (status) + { + error_counter++; + } + +#ifdef AUTHENTICATION_REQUIRED + status = nx_snmp_agent_v3_context_boots_set(&my_agent, 1); + if (status) + { + error_counter++; + } + + status = nx_snmp_agent_context_engine_set(&my_agent, context_engine_id, context_engine_size); + if (status != NX_SUCCESS) + { + error_counter++; + } + + /* Create an authentication key. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)"authpassword", &my_authentication_key); + if (status) + { + error_counter++; + } + + /* Use the authentication key. */ + status = nx_snmp_agent_authenticate_key_use(&my_agent, &my_authentication_key); + if (status) + { + error_counter++; + } +#endif + + /* Create a privacy key. */ + status = nx_snmp_agent_md5_key_create(&my_agent, (UCHAR *)"privpassword", &my_privacy_key); + if (status) + { + error_counter++; + } + + /* Use the privacy key. */ + status = nx_snmp_agent_privacy_key_use(&my_agent, &my_privacy_key); + if (status) + { + error_counter++; + } + + /* Start the SNMP instance. */ + status = nx_snmp_agent_start(&my_agent); + + /* Return the test result. */ + if (status) + { + error_counter++; + } + + /* Load the test data up. */ + snmp_test_initialize(); + + /* Send SNMP queries to the agent. */ + for (i = 0; i < QUERY_COUNT; i++ ) + { + + /* Inject the SNMP manager query packet. */ + packet_inject(snmp_query[i].snmp_query_pkt_data, snmp_query[i].snmp_query_pkt_size); + } + + /* Wait for processing snmp packet. */ + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* Make sure the packet pool is not corrupted. */ + while (pool_0.nx_packet_pool_available) + { + if ((nx_packet_allocate(&pool_0, &packet_ptr, 0, NX_NO_WAIT)) || + (packet_ptr -> nx_packet_pool_owner != &pool_0)) + { + error_counter++; + break; + } + } + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +static VOID packet_inject(UCHAR *data_ptr, UINT data_size) +{ +UINT status; +NX_PACKET *my_packet; + + status = nx_packet_allocate(&pool_0, &my_packet, NX_RECEIVE_PACKET, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Make sure IP header is 4-byte aligned. */ + my_packet -> nx_packet_prepend_ptr += 2; + my_packet -> nx_packet_append_ptr += 2; + + /* Fill in the packet with data. Skip the MAC header. */ + status = nx_packet_data_append(my_packet, data_ptr, data_size, &pool_0, NX_NO_WAIT); + + /* Check status */ + if(status) + error_counter ++; + + /* Skip the MAC header. */ + my_packet -> nx_packet_length -= 14; + my_packet -> nx_packet_prepend_ptr += 14; + + /* Directly receive the TCP packet. */ + _nx_ip_packet_deferred_receive(&agent_ip, my_packet); +} + +static void snmp_test_initialize() +{ + snmp_query[0].snmp_query_pkt_data = &v3_object_id_buffer_overwrite_packet1[0]; + snmp_query[0].snmp_query_pkt_size = v3_object_id_buffer_overwrite_packet1_size; +} + + +/* Define the application's GET processing routine. */ + +UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's GETNEXT processing routine. */ + +UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the next entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Is the next entry the mib greater? */ + if (status == NX_SNMP_NEXT_ENTRY) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SNMP_NEXT_ENTRY) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Copy the new name into the object. */ + nx_snmp_object_copy(mib2_mib[i].object_name, object_requested); + + /* Determine if the entry has a get function. */ + if (mib2_mib[i].object_get_callback) + { + + /* Yes, call the get function. */ + status = (mib2_mib[i].object_get_callback)(mib2_mib[i].object_value_ptr, object_data); + + /* Determine if the object data indicates an end-of-mib condition. */ + if (object_data -> nx_snmp_object_data_type == NX_SNMP_END_OF_MIB_VIEW) + { + + /* Copy the name supplied in the mib table. */ + nx_snmp_object_copy(mib2_mib[i].object_value_ptr, object_requested); + } + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + /* Return the status. */ + return(status); +} + + +/* Define the application's SET processing routine. */ + +UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data) +{ + +UINT i; +UINT status; + + + /* Loop through the sample MIB to see if we have information for the supplied variable. */ + i = 0; + status = NX_SNMP_ERROR; + while (mib2_mib[i].object_name) + { + + /* See if we have found the matching entry. */ + status = nx_snmp_object_compare(object_requested, mib2_mib[i].object_name); + + /* Was it found? */ + if (status == NX_SUCCESS) + { + + /* Yes it was found. */ + break; + } + + /* Move to the next index. */ + i++; + } + + /* Determine if a not found condition is present. */ + if (status != NX_SUCCESS) + { + + /* The object was not found - return an error. */ + return(NX_SNMP_ERROR_NOSUCHNAME); + } + + + /* Determine if the entry has a set function. */ + if (mib2_mib[i].object_set_callback) + { + + /* Yes, call the set function. */ + status = (mib2_mib[i].object_set_callback)(mib2_mib[i].object_value_ptr, object_data); + } + else + { + + /* No get function, return no access. */ + status = NX_SNMP_ERROR_NOACCESS; + } + + + /* Return the status. */ + return(status); +} + +/* Create an error code if matching user not found. */ +#define USER_NOT_FOUND 1 + +/* Define the username callback routine routine. Usernames should be + associated with permissions (public or private string) and what version + of SNMP the user is configured for. The username callback should verify + the incoming username MIB access permissions. */ +UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username) +{ + + mib2_variable_update(&agent_ip, &my_agent); + + return NX_SUCCESS; + +} + +/* Define the application's update routine. */ + +VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) +{ + + /* Update the snmp parameters. */ + return; +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_snmp_v3_object_id_buffer_overwrite_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: SNMP V3 Object ID Buffer OverWrite Test...................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/snmp_test/small_mib_helper.c b/test/regression/snmp_test/small_mib_helper.c new file mode 100644 index 00000000..7a898ab1 --- /dev/null +++ b/test/regression/snmp_test/small_mib_helper.c @@ -0,0 +1,116 @@ + +/* Determine if a C++ compiler is being used. If so, ensure that standard + C is used to process the API information. */ + +#ifdef __cplusplus + +/* Yes, C++ compiler is present. Use standard C. */ +extern "C" { +#endif + +#include "small_mib_helper.h" + +/* Define function prototypes. */ + +UINT mib2_get_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +UINT mib2_getnext_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +UINT mib2_set_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *object_requested, NX_SNMP_OBJECT_DATA *object_data); +UINT mib2_username_processing(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +//UINT mib2_username_processing_public(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +//UINT mib2_username_processing_admin(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +//UINT mib2_username_processing_view(NX_SNMP_AGENT *agent_ptr, UCHAR *username); +//VOID mib2_variable_update(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); +//VOID mib2_variable_update_public(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr); +//VOID mib2_variable_update_view(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) ; +//VOID mib2_variable_update_admin(NX_IP *ip_ptr, NX_SNMP_AGENT *agent_ptr) ; + + +/* Define the MIB-2 "system" group. */ + +UCHAR sysDescr[] = "NetX SNMP Agent"; /* sysDescr:OctetString RO */ +UCHAR sysObjectID[] = "1.3.6.1.2.1.1"; /* sysObjectID:ObjectID RO */ +ULONG sysUpTime = 0; /* sysUpTime:TimeTicks RO */ +UCHAR sysContact[128] = "NetX sysContact Name"; /* sysContact:OctetString RW */ +UCHAR sysName[128] = "NetX sysName"; /* sysName:OctetString RW */ +UCHAR sysLocation[128] = "NetX sysLocation"; /* sysLocation:OctetString RW */ +ULONG sysServices = 1; /* sysServices:Integer RW */ + +ULONG ipForwarding = 0; /* ipForwarding:Integer RW */ +ULONG ipDefaultTTL = NX_IP_TIME_TO_LIVE; /* ipDefaultTTL:Integer RW */ + +/* Define the MIB-2 "interfaces" group, assuming one interface. Update of these variables could be added to the + underlying application driver, but for now simple defaults are used. */ +ULONG ifLastChange = 2048; /* ifLastChange:TimeTicks RO */ +ULONG ifInOctets = 155; /* ifInOctets:Counter RO */ +ULONG64 ifInUcastPkts = 0; /* ifInUcastPkts:Counter RO */ + +UCHAR ifDescr[] = "NetX Physical Interface"; /* ifDescr:OctetString RO */ +#if 0 +ULONG ifNumber = 1; /* ifNumber:Integer RO */ +ULONG ifIndex = 1; /* ifIndex:Integer RO */ +ULONG ifType = 1; /* ifType:Integer RO */ +ULONG ifMtu = 2048; /* ifMTU:Integer RO */ +ULONG ifSpeed = 1000000; /* ifSpeed:Guage RO */ +UCHAR ifPhysAddress[] = {0x00,0x04,0xac,0xe3,0x1d,0xc5};/* ifPhysAddress:OctetString RO */ +ULONG ifAdminStatus = IFADMINSTATUS_UP; /* ifAdminStatus:Integer RW */ +ULONG ifOperStatus = 1; /* ifOperStatus:Integer RO */ +ULONG ifInNUcastPkts = 0; /* ifInNUcastPkts:Counter RO */ +ULONG ifInDiscards = 0; /* ifInDiscards:Counter RO */ +ULONG ifInErrors = 0; /* ifInErrors:Counter RO */ +ULONG ifInUnknownProtos = 0; /* ifInUnknownProtos:Counter RO */ +ULONG ifOutOctets = 0; /* ifOutOctets:Counter RO */ +ULONG ifOutUcastPkts = 0; /* ifOutUcastPkts:Counter RO */ +ULONG ifOutNUcastPkts = 0; /* ifOutNUcastPkts:Counter RO */ +ULONG ifOutDiscards = 0; /* ifOutDiscards:Counter RO */ +ULONG ifOutErrors = 0; /* ifOutErrors:Counter RO */ +ULONG ifOutQLen = 0; /* ifOutQLen:Guage RO */ +UCHAR ifSpecific[] = "1.3.6.1.2.1.1"; /* ifSpecific:ObjectID RO */ +#endif +/* Define the MIB-2 "address translation" group, assuming one address translation. */ + +//ULONG atIfIndex = 1; /* atIfIndex:Integer RW */ +UCHAR atPhysAddress[] = {0x00,0x04,0xac,0xe3,0x1d,0xc5};/* atPhysAddress:OctetString RW */ +ULONG atNetworkAddress = 0; /* atNetworkAddress:NetworkAddr RW */ +UCHAR atIPv6NetworkAddress[16]; /* atNetworkAddress:NetworkAddr IPv6 RW */ + + +/* Define the MIB-2 "ip" group. */ +//ULONG ipForwarding = 0; /* ipForwarding:Integer RW */ +ULONG oid_var = 1234U; + + +/* Define the actual MIB-2. */ + +MIB_ENTRY mib2_mib[] = { + + /* OBJECT ID OBJECT VARIABLE LENGTH OF OBJECT VARIABLE GET ROUTINE/ GET_OCTET_ROUTINE SET ROUTINE LENGTH */ +#if 1 + {(UCHAR *) "1.3.6.1.2.1.1.1.0", sysDescr, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, sizeof(sysDescr)}, + {(UCHAR *) "1.3.6.1.2.1.1.2.0", sysObjectID, nx_snmp_object_id_get, NX_NULL, NX_NULL, sizeof(sysObjectID)}, + {(UCHAR *) "1.3.6.1.2.1.1.3.0", &sysUpTime, nx_snmp_object_timetics_get, NX_NULL, NX_NULL, sizeof(sysUpTime)}, + {(UCHAR *) "1.3.6.1.2.1.1.4.0", sysContact, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, sizeof(sysContact)}, + {(UCHAR *) "1.3.6.1.2.1.1.5.0", sysName, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, sizeof(sysName)}, + {(UCHAR *) "1.3.6.1.2.1.1.6.0", sysLocation, nx_snmp_object_string_get, NX_NULL, nx_snmp_object_string_set, sizeof(sysLocation)}, + {(UCHAR *) "1.3.6.1.2.1.1.7.0", &sysServices, nx_snmp_object_integer_get, NX_NULL, NX_NULL, sizeof(sysServices)}, +#endif + {(UCHAR *) "1.3.6.1.2.1.3.1.1.3.0", &atNetworkAddress, nx_snmp_object_ip_address_get, NX_NULL, nx_snmp_object_ip_address_set, sizeof(atNetworkAddress)}, +#ifdef FEATURE_NX_IPV6 + /* Either GET method should work. IPv6 addresses are handled as octet strings and accept any IPv6 address format e.g. addresses with '::'s are accepted as is. */ + {(UCHAR *) "1.3.6.1.2.1.3.1.1.3.1", &atIPv6NetworkAddress, nx_snmp_object_ipv6_address_get, NX_NULL, nx_snmp_object_ipv6_address_set, sizeof(atIPv6NetworkAddress)}, + {(UCHAR *) "1.3.6.1.2.1.3.1.1.3.2", &atIPv6NetworkAddress, NX_NULL, nx_snmp_object_octet_string_get, nx_snmp_object_octet_string_set, sizeof(atIPv6NetworkAddress)}, +#endif + + {(UCHAR *) "1.3.6.1.2.1.2.2.1.2.0", ifDescr, nx_snmp_object_string_get, NX_NULL, NX_NULL, sizeof(ifDescr)}, + {(UCHAR *) "1.3.6.1.2.1.3.1.1.2.0", &atPhysAddress, NX_NULL, nx_snmp_object_octet_string_get, nx_snmp_object_octet_string_set, sizeof(atPhysAddress)}, + {(UCHAR *) "1.3.6.1.2.1.2.2.1.9.0", &ifLastChange, nx_snmp_object_timetics_get, NX_NULL, nx_snmp_object_timetics_set, sizeof(ifLastChange)}, + {(UCHAR *) "1.3.6.1.2.1.2.2.1.10.0", &ifInOctets, nx_snmp_object_counter_get, NX_NULL, nx_snmp_object_counter_set, sizeof(ifInOctets)}, + {(UCHAR *) "1.3.6.1.2.1.2.2.1.11.0", &ifInUcastPkts, nx_snmp_object_counter64_get, NX_NULL, nx_snmp_object_counter64_set, sizeof(ifInUcastPkts)}, + + {(UCHAR *) "1.3.6.1.2.1.4.1.0", &ipForwarding, nx_snmp_object_integer_get, NX_NULL, nx_snmp_object_integer_set, sizeof(ipForwarding)}, + {(UCHAR *) "1.3.6.1.2.1.4.2.0", &ipDefaultTTL, nx_snmp_object_integer_get, NX_NULL, NX_NULL, sizeof(ipDefaultTTL)}, + {(UCHAR *) "1.3.6.1.4.1.51000.1.4.0", &oid_var, nx_snmp_object_integer_get, NX_NULL, NX_NULL, sizeof(oid_var)}, + + {(UCHAR *) "1.3.6.1.7", (UCHAR *) "1.3.6.1.7", nx_snmp_object_end_of_mib, NX_NULL, NX_NULL, sizeof("1.3.6.1.7") - 1}, + {NX_NULL, NX_NULL, NX_NULL, NX_NULL, NX_NULL, 0} + +}; diff --git a/test/regression/snmp_test/small_mib_helper.h b/test/regression/snmp_test/small_mib_helper.h new file mode 100644 index 00000000..ad6126ba --- /dev/null +++ b/test/regression/snmp_test/small_mib_helper.h @@ -0,0 +1,40 @@ +/* This is an include file for the NetX SNMP demo programs for setting up the MIB for + user callback functions. It is not part of the official release of NetX SNMP Agent. */ + +#ifndef SMALL_MIB_HELPER_H +#define SMALL_MIB_HELPER_H + +/* Determine if a C++ compiler is being used. If so, ensure that standard + C is used to process the API information. */ + +#ifdef __cplusplus + +/* Yes, C++ compiler is present. Use standard C. */ +extern "C" { + +#endif + +/* Include necessary digest and encryption files. */ + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_snmp.h" +#else +#include "nx_snmp.h" +#endif + +/* Define application MIB data structure. Actual application structures would certainly vary. */ + +typedef struct MIB_ENTRY_STRUCT +{ + + UCHAR *object_name; + void *object_value_ptr; + UINT (*object_get_callback)(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data); + UINT (*object_get_octet_callback)(VOID *source_ptr, NX_SNMP_OBJECT_DATA *object_data, UINT length); + UINT (*object_set_callback)(VOID *destination_ptr, NX_SNMP_OBJECT_DATA *object_data); + UINT length; +} MIB_ENTRY; + +#endif /* SMALL_MIB_HELPER_H */ diff --git a/test/regression/snmp_test/snmp_manager_packets.c b/test/regression/snmp_test/snmp_manager_packets.c new file mode 100644 index 00000000..a5fcb0db --- /dev/null +++ b/test/regression/snmp_test/snmp_manager_packets.c @@ -0,0 +1,1980 @@ +/* Frame (83 bytes) SNMPv2 GET REQUEST + community: public + data: get-request (0) +*/ +const unsigned char simple_get_query_pkt[42] = { +0x30, 0x28, 0x02, 0x01, 0x01, 0x04, /* ..0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x1b, 0x02, 0x01, 0x29, 0x02, 0x01, 0x00, 0x02, /* ...).... */ +0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, /* +....... */ +0x02, 0x00, 0x05, 0x00 /* .... */ +}; + +int simple_get_query_size = 42; + + +/* Frame (81 bytes) SNMPv2 GET NEXT REQUEST + community: public + data: get-next request (1) +*/ +const unsigned char simple_get_next_query_pkt[42] = { +0x30, 0x28, 0x02, 0x01, 0x01, 0x04, /* ..0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa1, /* .public. */ +0x1b, 0x02, 0x01, 0x2b, 0x02, 0x01, 0x00, 0x02, /* ...+.... */ +0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, /* +....... */ +0x01, 0x00, 0x05, 0x00 /* .... */ +}; + +int simple_get_next_query_size = 42; + + +/* Frame (76 bytes) SNMPv2 GET BULK REQUEST + community: public + data: getBulkRequest (5) + getBulkRequest +*/ + +const unsigned char simple_get_bulk_query_pkt[42] = { +0x30, 0x28, 0x02, 0x01, 0x01, 0x04, /* ..0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa5, /* .public. */ +0x1b, 0x02, 0x01, 0x2c, 0x02, 0x01, 0x00, 0x02, /* ...,.... */ +0x01, 0x0a, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, /* +....... */ +0x02, 0x00, 0x05, 0x00 /* .... */ +}; + +int simple_get_bulk_query_size = 42; + +/* Frame (83 bytes) SNMPv2 GET REQUEST for unknown item + community: public + data: get-request (0) +*/ +const unsigned char simple_get_query_unknown_oid_pkt[42] = { +0x30, 0x28, 0x02, 0x01, 0x01, 0x04, /* ..0(.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, /* .public. */ +0x1b, 0x02, 0x01, 0x29, 0x02, 0x01, 0x00, 0x02, /* ...).... */ +0x01, 0x00, 0x30, 0x10, 0x30, 0x0e, 0x06, 0x0a, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x018, 0x02, 0x01, /* +....... */ +0x02, 0x00, 0x05, 0x00 /* .... */ +}; + +int simple_get_query_unknown_oid_size = 42; + +const unsigned char simple_send_trap_pkt[76] = { +0x30, 0x82, 0x00, 0x48, 0x02, 0x01, /* 9.0..H.. */ +0x01, 0x04, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, /* ...publi */ +0x63, 0xa7, 0x3b, 0x02, 0x01, 0x13, 0x02, 0x01, /* c.;..... */ +0x00, 0x02, 0x01, 0x00, 0x30, 0x82, 0x00, 0x2e, /* ....0... */ +0x30, 0x82, 0x00, 0x0e, 0x06, 0x08, 0x2b, 0x06, /* 0.....+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x43, 0x02, /* ......C. */ +0x07, 0x97, 0x30, 0x82, 0x00, 0x18, 0x06, 0x0a, /* ..0..... */ +0x2b, 0x06, 0x01, 0x06, 0x03, 0x01, 0x01, 0x04, /* +....... */ +0x01, 0x00, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x06, /* ....+... */ +0x03, 0x01, 0x01, 0x05, 0x01, 0x00 /* ...... */ +}; + +int simple_send_trap_size = 76; + +/***************** SNMP V3 No security handshake ************/ +const unsigned char v3_nosec_getrequest_pkt[58] = { +0x30, 0x38, 0x02, 0x01, 0x03, 0x30, /* ..08...0 */ +0x0e, 0x02, 0x01, 0x1c, 0x02, 0x03, 0x00, 0xff, /* ........ */ +0xf0, 0x04, 0x01, 0x04, 0x02, 0x01, 0x03, 0x04, /* ........ */ +0x10, 0x30, 0x0e, 0x04, 0x00, 0x02, 0x01, 0x00, /* .0...... */ +0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, /* ........ */ +0x00, 0x30, 0x11, 0x04, 0x00, 0x04, 0x00, 0xa0, /* .0...... */ +0x0b, 0x02, 0x01, 0x71, 0x02, 0x01, 0x00, 0x02, /* ...q.... */ +0x01, 0x00, 0x30, 0x00 /* ..0. */ +}; + +int v3_nosec_getrequest_size = 58; + +/* Frame (140 bytes) */ +const unsigned char v3_nosec_getnext_request_pkt[98] = { +0x30, 0x60, 0x02, 0x01, 0x03, 0x30, /* ..0`...0 */ +0x0e, 0x02, 0x01, 0x1d, 0x02, 0x03, 0x00, 0xff, /* ........ */ +0xf0, 0x04, 0x01, 0x04, 0x02, 0x01, 0x03, 0x04, /* ........ */ +0x20, 0x30, 0x1e, 0x04, 0x0b, 0x80, 0x00, 0x0d, /* 0...... */ +0xfe, 0x03, 0x00, 0x77, 0x23, 0x23, 0x46, 0x69, /* ...w##Fi */ +0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x04, 0x05, /* ........ */ +0x6a, 0x61, 0x6e, 0x65, 0x74, 0x04, 0x00, 0x04, /* janet... */ +0x00, 0x30, 0x29, 0x04, 0x0b, 0x80, 0x00, 0x0d, /* .0)..... */ +0xfe, 0x03, 0x00, 0x77, 0x23, 0x23, 0x46, 0x69, /* ...w##Fi */ +0x04, 0x00, 0xa1, 0x18, 0x02, 0x01, 0x72, 0x02, /* ......r. */ +0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x30, /* .....0.0 */ +0x0b, 0x06, 0x07, 0x2b, 0x06, 0x01, 0x02, 0x01, /* ...+.... */ +0x01, 0x03, 0x05, 0x00 /* .... */ +}; + +int v3_nosec_getnext_request_size = 98; + +/*********v3 with auth/priv function test********************/ + +unsigned char get_request_priv_pkt[59] = { +0x30, 0x39, 0x02, 0x01, 0x03, 0x30, /* ..09...0 */ +0x0e, 0x02, 0x01, 0x04, 0x02, 0x03, 0x00, 0xff, /* ........ */ +0xf0, 0x04, 0x01, 0x04, 0x02, 0x01, 0x03, 0x04, /* ........ */ +0x10, 0x30, 0x0e, 0x04, 0x00, 0x02, 0x01, 0x00, /* .0...... */ +0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, /* ........ */ +0x00, 0x30, 0x12, 0x04, 0x00, 0x04, 0x00, 0xa0, /* .0...... */ +0x0c, 0x02, 0x02, 0x00, 0x9b, 0x02, 0x01, 0x00, /* ........ */ +0x02, 0x01, 0x00, 0x30, 0x00 /* ...0. */ +}; + +int get_request_priv_size = 59; + + +unsigned char getnext_request_priv_pkt[123] = { +0x30, 0x79, 0x02, 0x01, 0x03, 0x30, /* .40y...0 */ +0x0e, 0x02, 0x01, 0x06, 0x02, 0x03, 0x00, 0xff, /* ........ */ +0xf0, 0x04, 0x01, 0x07, 0x02, 0x01, 0x03, 0x04, /* ........ */ +0x32, 0x30, 0x30, 0x04, 0x09, 0x80, 0x00, 0x03, /* 200..... */ +0x10, 0x01, 0xc0, 0xa8, 0x64, 0xaf, 0x02, 0x01, /* ....d... */ +0x01, 0x02, 0x01, 0x0d, 0x04, 0x05, 0x6a, 0x61, /* ......ja */ +0x6e, 0x65, 0x74, 0x04, 0x0c, 0x9d, 0x1d, 0xbe, /* net..... */ +0x6b, 0xee, 0x12, 0x22, 0xcb, 0x90, 0xe8, 0x41, /* k.."...A */ +0xfc, 0x04, 0x08, 0x00, 0x00, 0x00, 0xc8, 0x00, /* ........ */ +0x00, 0x00, 0x22, 0x04, 0x30, 0x0a, 0x5a, 0x42, /* ..".0.ZB */ +0xe6, 0x83, 0xe2, 0x86, 0x36, 0x60, 0xdc, 0x19, /* ....6`.. */ +0x36, 0x8a, 0x2d, 0xd6, 0x8e, 0xee, 0x68, 0xe9, /* 6.-...h. */ +0x08, 0xa8, 0xb3, 0xea, 0x61, 0x1d, 0xf1, 0xa3, /* ....a... */ +0x19, 0xc8, 0xda, 0x90, 0x70, 0x25, 0x74, 0x84, /* ....p%t. */ +0x97, 0x48, 0xcb, 0x9a, 0x6b, 0x22, 0xd3, 0x45, /* .H..k".E */ +0xee, 0x72, 0x52, 0x38, 0x03 /* .rR8. */ +}; + +int getnext_request_priv_size = 123; + + +/************************************************************/ + +//unsigned char trap_v3_nosec_get_request_pkt[100] = { +unsigned char trap_v3_nosec_get_request_pkt[58] = { +0x30, 0x38, 0x02, 0x01, 0x03, 0x30, /* ..08...0 */ +0x0e, 0x02, 0x01, 0x04, 0x02, 0x03, 0x00, 0xff, /* ........ */ +0xf0, 0x04, 0x01, 0x04, 0x02, 0x01, 0x03, 0x04, /* ........ */ +0x10, 0x30, 0x0e, 0x04, 0x00, 0x02, 0x01, 0x00, /* .0...... */ +0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, /* ........ */ +0x00, 0x30, 0x11, 0x04, 0x00, 0x04, 0x00, 0xa0, /* .0...... */ +0x0b, 0x02, 0x01, 0x26, 0x02, 0x01, 0x00, 0x02, /* ...&.... */ +0x01, 0x00, 0x30, 0x00 /* ..0. */ +}; + +int trap_v3_nosec_get_request_size = 58; + +/* Frame (136 bytes) */ +unsigned char trap_v3_nosec_get_next_request_pkt[94] = { +0x30, 0x5c, 0x02, 0x01, 0x03, 0x30, /* ..0\...0 */ +0x0e, 0x02, 0x01, 0x05, 0x02, 0x03, 0x00, 0xff, /* ........ */ +0xf0, 0x04, 0x01, 0x04, 0x02, 0x01, 0x03, 0x04, /* ........ */ +0x1e, 0x30, 0x1c, 0x04, 0x09, 0x80, 0x00, 0x03, /* .0...... */ +0x10, 0x01, 0xc0, 0xa8, 0x64, 0xaf, 0x02, 0x01, /* ....d... */ +0x00, 0x02, 0x01, 0x00, 0x04, 0x05, 0x6a, 0x61, /* ......ja */ +0x6e, 0x65, 0x74, 0x04, 0x00, 0x04, 0x00, 0x30, /* net....0 */ +0x27, 0x04, 0x09, 0x80, 0x00, 0x03, 0x10, 0x01, /* '....... */ +0xc0, 0xa8, 0x64, 0xaf, 0x04, 0x00, 0xa1, 0x18, /* ..d..... */ +0x02, 0x01, 0x27, 0x02, 0x01, 0x00, 0x02, 0x01, /* ..'..... */ +0x00, 0x30, 0x0d, 0x30, 0x0b, 0x06, 0x07, 0x2b, /* .0.0...+ */ +0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x05, 0x00 /* ........ */ +}; + +int trap_v3_nosec_get_next_request_size = 94; + +/* Frame (260 bytes) */ +unsigned char trap_v3_nosec_pkt[218] = { +0x30, 0x82, 0x00, 0xd6, 0x02, 0x01, /* ..0..... */ +0x03, 0x30, 0x0d, 0x02, 0x01, 0x00, 0x02, 0x02, /* .0...... */ +0x01, 0xf0, 0x04, 0x01, 0x00, 0x02, 0x01, 0x03, /* ........ */ +0x04, 0x1f, 0x30, 0x1d, 0x04, 0x09, 0x80, 0x00, /* ..0..... */ +0x03, 0x10, 0x01, 0xc0, 0xa8, 0x64, 0xaf, 0x02, /* .....d.. */ +0x01, 0x01, 0x02, 0x01, 0x03, 0x04, 0x06, 0x70, /* .......p */ +0x75, 0x62, 0x6c, 0x69, 0x63, 0x04, 0x00, 0x04, /* ublic... */ +0x00, 0x30, 0x82, 0x00, 0x9f, 0x04, 0x09, 0x80, /* .0...... */ +0x00, 0x03, 0x10, 0x01, 0xc0, 0xa8, 0x64, 0xaf, /* ......d. */ +0x04, 0x00, 0xa7, 0x82, 0x00, 0x8e, 0x02, 0x01, /* ........ */ +0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, /* .......0 */ +0x82, 0x00, 0x81, 0x30, 0x0e, 0x06, 0x08, 0x2b, /* ...0...+ */ +0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x43, /* .......C */ +0x02, 0x01, 0x41, 0x30, 0x18, 0x06, 0x0a, 0x2b, /* ..A0...+ */ +0x06, 0x01, 0x06, 0x03, 0x01, 0x01, 0x04, 0x01, /* ........ */ +0x00, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x06, 0x03, /* ...+.... */ +0x01, 0x01, 0x05, 0x04, 0x00, 0x30, 0x0f, 0x06, /* .....0.. */ +0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, 0x02, /* .+...... */ +0x01, 0x01, 0x00, 0x02, 0x01, 0x63, 0x30, 0x0f, /* .....c0. */ +0x06, 0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x02, /* ..+..... */ +0x02, 0x01, 0x07, 0x00, 0x02, 0x01, 0x64, 0x30, /* ......d0 */ +0x10, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, /* ...+.... */ +0x02, 0x02, 0x01, 0x08, 0x00, 0x02, 0x02, 0x01, /* ........ */ +0x41, 0x30, 0x0f, 0x06, 0x0a, 0x2b, 0x06, 0x01, /* A0...+.. */ +0x02, 0x01, 0x02, 0x02, 0x01, 0x09, 0x00, 0x02, /* ........ */ +0x01, 0x65, 0x30, 0x10, 0x06, 0x0a, 0x2b, 0x06, /* .e0...+. */ +0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x0a, 0x00, /* ........ */ +0x02, 0x02, 0x01, 0x41 /* ...A */ +}; + +int trap_v3_nosec_size = 218; + +/************************************************************/ + +unsigned char get_next_request_packet[39] = { +0x30, 0x25, 0x02, 0x01, 0x01, 0x04, /* ..0%.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x65, 0xa1, /* .publie. */ +0x18, 0x02, 0x01, 0x20, 0x02, 0x01, 0x00, 0x02, /* ... .... */ +0x01, 0x00, 0x30, 0x0d, 0x30, 0x0b, 0x06, 0x07, /* ..0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x05, /* +....... */ +0x00 /* . */ +}; +int get_next_request_size = 39; + +unsigned char get_bulk_request_packet[40] = { +0x30, 0x26, 0x02, 0x01, 0x01, 0x04, /* ..0&.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x65, 0xa5, /* .publie. */ +0x19, 0x02, 0x01, 0x21, 0x02, 0x01, 0x00, 0x02, /* ...!.... */ +0x01, 0x64, 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x08, /* .d0.0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x0b, 0x1e, 0x00, /* +....... */ +0x05, 0x00 /* .. */ +}; + +int get_bulk_request_size = 40; + + +/************************************************************/ + +unsigned char get_next_request_v1_packet[293] = { +0x30, 0x82, 0x01, 0x21, 0x02, 0x01, /* ."0..!.. */ +0x00, 0x04, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, /* ...publi */ +0x63, 0xa1, 0x82, 0x01, 0x12, 0x02, 0x02, 0x17, /* c....... */ +0x61, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, /* a......0 */ +0x82, 0x01, 0x04, 0x30, 0x0b, 0x06, 0x07, 0x2b, /* ...0...+ */ +0x06, 0x01, 0x02, 0x01, 0x04, 0x01, 0x05, 0x00, /* ........ */ +0x30, 0x0b, 0x06, 0x07, 0x2b, 0x06, 0x01, 0x02, /* 0...+... */ +0x01, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0b, 0x06, /* .....0.. */ +0x07, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, 0x03, /* .+...... */ +0x05, 0x00, 0x30, 0x0b, 0x06, 0x07, 0x2b, 0x06, /* ..0...+. */ +0x01, 0x02, 0x01, 0x04, 0x04, 0x05, 0x00, 0x30, /* .......0 */ +0x0b, 0x06, 0x07, 0x2b, 0x06, 0x01, 0x02, 0x01, /* ...+.... */ +0x04, 0x05, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x07, /* ....0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, 0x06, 0x05, /* +....... */ +0x00, 0x30, 0x0b, 0x06, 0x07, 0x2b, 0x06, 0x01, /* .0...+.. */ +0x02, 0x01, 0x04, 0x07, 0x05, 0x00, 0x30, 0x0b, /* ......0. */ +0x06, 0x07, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, /* ..+..... */ +0x08, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x07, 0x2b, /* ...0...+ */ +0x06, 0x01, 0x02, 0x01, 0x04, 0x09, 0x05, 0x00, /* ........ */ +0x30, 0x0b, 0x06, 0x07, 0x2b, 0x06, 0x01, 0x02, /* 0...+... */ +0x01, 0x04, 0x0a, 0x05, 0x00, 0x30, 0x0b, 0x06, /* .....0.. */ +0x07, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, 0x0b, /* .+...... */ +0x05, 0x00, 0x30, 0x0b, 0x06, 0x07, 0x2b, 0x06, /* ..0...+. */ +0x01, 0x02, 0x01, 0x04, 0x0c, 0x05, 0x00, 0x30, /* .......0 */ +0x0b, 0x06, 0x07, 0x2b, 0x06, 0x01, 0x02, 0x01, /* ...+.... */ +0x04, 0x0d, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x07, /* ....0... */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, 0x0e, 0x05, /* +....... */ +0x00, 0x30, 0x0b, 0x06, 0x07, 0x2b, 0x06, 0x01, /* .0...+.. */ +0x02, 0x01, 0x04, 0x0f, 0x05, 0x00, 0x30, 0x0b, /* ......0. */ +0x06, 0x07, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, /* ..+..... */ +0x10, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x07, 0x2b, /* ...0...+ */ +0x06, 0x01, 0x02, 0x01, 0x04, 0x11, 0x05, 0x00, /* ........ */ +0x30, 0x0b, 0x06, 0x07, 0x2b, 0x06, 0x01, 0x02, /* 0...+... */ +0x01, 0x04, 0x12, 0x05, 0x00, 0x30, 0x0b, 0x06, /* .....0.. */ +0x07, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x04, 0x13, /* .+...... */ +0x05, 0x00, 0x30, 0x0b, 0x06, 0x07, 0x2b, 0x06, /* ..0...+. */ +0x01, 0x02, 0x01, 0x04, 0x17, 0x05, 0x00 /* ....... */ +}; + +int get_next_request_v1_size = 293; + + +/* Frame (83 bytes) */ +unsigned char getbulk_request_v2_packet[41] = { +0x30, 0x27, 0x02, 0x01, 0x01, 0x04, /* ..0'.... */ +0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa5, /* .public. */ +0x1a, 0x02, 0x02, 0x00, 0xb4, 0x02, 0x01, 0x00, /* ........ */ +0x02, 0x01, 0x1e, 0x30, 0x0e, 0x30, 0x0c, 0x06, /* ...0.0.. */ +0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x0b, 0x0f, /* .+...... */ +0x00, 0x05, 0x00 /* ... */ +}; + +int getbulk_request_v2_size = 41; + +/* Get request 1.3.6.1.4.1.51000.1.4.0 */ +unsigned char get_request_v1_1234_packet[] = { +0x30, 0x2c, 0x02, 0x01, 0x00, 0x04, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0xa0, 0x1f, 0x02, +0x04, 0x48, 0xcc, 0x8f, 0xd9, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x11, 0x30, 0x0f, 0x06, +0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x83, 0x8e, 0x38, 0x01, 0x04, 0x00, 0x05, 0x00, +}; + +int get_request_v1_1234_packet_size = sizeof(get_request_v1_1234_packet); + + + +/* Frame (1514 bytes) */ +unsigned char v1_buffer_overwrite_packet1[1514] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x05, 0xdc, 0x6f, 0x35, 0x20, 0x00, 0x80, 0x11, /* ..o5 ... */ +0xaa, 0x5f, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0xf2, 0xaa, 0x00, 0xa1, 0x05, 0xdc, /* ........ */ +0x2f, 0x3c, 0x30, 0x40, 0x02, 0x01, 0x00, 0x04, /* /<0@.... */ +0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, /* .usernam */ +0x65, 0xa0, 0x00, 0x02, 0x1b, 0x00, 0x00, 0x00, /* e....... */ +0xc0, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* .AAAAAAA */ +0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* AAAAAAAA */ +0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* AAAAAAAA */ +0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x84, /* ......0. */ +0x01, 0xff, 0xff, 0xff, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0e, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x05, 0x00, /* ........ */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82 /* .. */ +}; + +int v1_buffer_overwrite_packet1_size = sizeof(v1_buffer_overwrite_packet1); + +/* Frame (54 bytes) */ +unsigned char v1_buffer_overwrite_packet2[54] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x00, 0x28, 0x6f, 0x35, 0x00, 0xb9, 0x80, 0x11, /* .(o5.... */ +0xcf, 0x5a, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x01, 0x06, 0x82, 0x00, 0x08 /* ...... */ +}; + +int v1_buffer_overwrite_packet2_size = sizeof(v1_buffer_overwrite_packet2); + +/* Frame (1421 bytes) */ /* MSRC 81075, _nx_snmp_utility_object_id_set(). */ +unsigned char v1_buffer_overwrite_packet3[1421] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x05, 0x7f, 0x6a, 0x35, 0x00, 0x00, 0x80, 0x11, /* ..j5.... */ +0xcf, 0xbc, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0xef, 0x9e, 0x00, 0xa1, 0x05, 0x6b, /* .......k */ +0xdf, 0x2c, 0x30, 0x40, 0x02, 0x01, 0x00, 0x04, /* ..0@.... */ +0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, /* .usernam */ +0x65, 0xa3, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, /* e....... */ +0xc0, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, /* .......0 */ +0x84, 0x00, 0x00, 0x05, 0x40, 0x30, 0x16, 0x06, /* ....@0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x0d, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x07, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x30, 0x07, 0x06, 0x02, /* ....0... */ +0x2b, 0x06, 0x06, 0x00, 0x40 /* +...@ */ +}; + +int v1_buffer_overwrite_packet3_size = sizeof(v1_buffer_overwrite_packet3); + +unsigned char v1_buffer_overwrite_packet4[] = { +0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x00, 0x15, 0x5d, 0x64, 0x68, 0x04, 0x08, 0x00, 0x45, 0x00, +0x01, 0x59, 0x41, 0x92, 0x00, 0x00, 0x80, 0x11, 0xfc, 0x85, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, +0x10, 0x11, 0xcd, 0x85, 0x00, 0xa1, 0x01, 0x45, 0x00, 0x00, 0x30, 0x40, 0x02, 0x01, 0x00, 0x04, +0x82, 0x00, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0xa3, 0x00, 0x02, 0x04, 0x00, +0x00, 0x00, 0xc0, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x84, 0x00, 0x00, 0x02, 0x00, 0x30, +0x84, 0x00, 0x00, 0x01, 0x02, 0x06, 0x82, 0x00, 0x0a, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x03, 0x01, +0x01, 0x02, 0x00, 0x04, 0x82, 0x00, 0xf0, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, +0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x30, 0x0e, 0x06, 0x82, 0x00, 0x0a, 0x2b, 0x06, 0x01, +0x02, 0x01, 0x03, 0x01, 0x01, 0x02, 0x00, +}; + +int v1_buffer_overwrite_packet4_size = sizeof(v1_buffer_overwrite_packet4); + + +/* Frame (1421 bytes) */ +unsigned char v1_double_release_packet[1421] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x05, 0x7f, 0x6a, 0x35, 0x00, 0x00, 0x80, 0x11, /* ..j5.... */ +0xcf, 0xbc, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0xef, 0x9e, 0x00, 0xa1, 0x05, 0x6b, /* .......k */ +0xdf, 0x2b, 0x30, 0x40, 0x02, 0x01, 0x00, 0x04, /* ..0@.... */ +0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, /* .usernam */ +0x65, 0xa3, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, /* e....... */ +0xc0, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, /* .......0 */ +0x84, 0x00, 0x00, 0x05, 0x40, 0x30, 0x16, 0x06, /* ....@0.. */ +0x02, 0x2b, 0x06, 0x07, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x0d, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x07, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x30, 0x07, 0x06, 0x02, /* ....0... */ +0x2b, 0x06, 0x06, 0x00, 0x40 /* +...@ */ +}; + +int v1_double_release_packet_size = sizeof(v1_double_release_packet); + +/* Frame (1421 bytes) */ /* _nx_snmp_utility_object_id_set(). */ +unsigned char v1_object_id_buffer_overwrite_packet[1422] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x05, 0x80, 0x6a, 0x35, 0x00, 0x00, 0x80, 0x11, /* ..j5.... */ +0xcf, 0xbb, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0xef, 0x9e, 0x00, 0xa1, 0x05, 0x6b, /* .......k */ +0xdf, 0x2b, 0x30, 0x40, 0x02, 0x01, 0x00, 0x04, /* ..0@.... */ +0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, /* .usernam */ +0x65, 0xa3, 0x00, 0x02, 0x04, 0x00, 0x00, 0x00, /* e....... */ +0xc0, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, /* .......0 */ +0x84, 0x00, 0x00, 0x05, 0x40, 0x30, 0x16, 0x06, /* ....@0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x16, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x10, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, /* ........ */ +0x00, 0x01, 0x02, 0x03, 0x04, 0x30, 0x0d, 0x06, /* .....0.. */ +0x02, 0x2b, 0x06, 0x06, 0x07, 0x2b, 0x06, 0x01, /* .+...+.. */ +0x02, 0x03, 0x04, 0x05, 0x30, 0x07, 0x06, 0x02, /* ....0... */ +0x2b, 0x06, 0x06, 0x00, 0x40, 0x00 /* +...@ */ +}; + +int v1_object_id_buffer_overwrite_packet_size = sizeof(v1_object_id_buffer_overwrite_packet); + +/* Frame (1514 bytes) */ +unsigned char v2_buffer_overwrite_packet1[1514] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x05, 0xdc, 0x6f, 0x32, 0x20, 0x00, 0x80, 0x11, /* ..o2 ... */ +0xaa, 0x62, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0xd1, 0xbe, 0x00, 0xa1, 0x05, 0xdc, /* ........ */ +0x4e, 0x28, 0x30, 0x40, 0x02, 0x01, 0x02, 0x04, /* N(0@.... */ +0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, /* .usernam */ +0x65, 0xa0, 0x00, 0x02, 0x1b, 0x00, 0x00, 0x00, /* e....... */ +0xc0, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* .AAAAAAA */ +0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* AAAAAAAA */ +0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* AAAAAAAA */ +0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x84, /* ......0. */ +0x01, 0xff, 0xff, 0xff, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0e, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x05, 0x00, /* ........ */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82 /* .. */ +}; + +int v2_buffer_overwrite_packet1_size = sizeof(v2_buffer_overwrite_packet1); + +/* Frame (54 bytes) */ +unsigned char v2_buffer_overwrite_packet2[54] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x00, 0x28, 0x6f, 0x32, 0x00, 0xb9, 0x80, 0x11, /* .(o2.... */ +0xcf, 0x5d, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x01, 0x06, 0x82, 0x00, 0x08 /* ...... */ +}; + +int v2_buffer_overwrite_packet2_size = sizeof(v2_buffer_overwrite_packet2); + +/* Frame (1514 bytes) */ +unsigned char v3_buffer_overwrite_packet1[1514] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x05, 0xdc, 0x04, 0xf6, 0x20, 0x00, 0x80, 0x11, /* .... ... */ +0x14, 0x9f, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0xed, 0x5f, 0x00, 0xa1, 0x05, 0xdc, /* ..._.... */ +0xb2, 0xa7, 0x30, 0x40, 0x02, 0x01, 0x03, 0x30, /* ..0@...0 */ +0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0xc0, 0x02, /* @....... */ +0x04, 0x00, 0x00, 0x00, 0xc1, 0x04, 0x01, 0x00, /* ........ */ +0x02, 0x04, 0x00, 0x00, 0x00, 0x03, 0x04, 0x01, /* ........ */ +0x30, 0x43, 0x04, 0x09, 0x80, 0x00, 0x03, 0x10, /* 0C...... */ +0x01, 0xc0, 0xa8, 0x64, 0xaf, 0x02, 0x04, 0x00, /* ...d.... */ +0x00, 0x00, 0xc4, 0x02, 0x04, 0x00, 0x00, 0x00, /* ........ */ +0xc5, 0x04, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, /* ...usern */ +0x61, 0x6d, 0x65, 0x04, 0x02, 0x78, 0x33, 0x04, /* ame..x3. */ +0x02, 0x78, 0x34, 0x30, 0x41, 0x04, 0x02, 0x78, /* .x40A..x */ +0x35, 0x04, 0x02, 0x78, 0x36, 0xa0, 0x00, 0x02, /* 5..x6... */ +0x1f, 0x00, 0x00, 0x00, 0xc6, 0x41, 0x41, 0x41, /* .....AAA */ +0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* AAAAAAAA */ +0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* AAAAAAAA */ +0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* AAAAAAAA */ +0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x30, 0x84, /* ......0. */ +0x01, 0xff, 0xff, 0xff, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0e, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x05, 0x00, /* ........ */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82 /* .. */ +}; + +int v3_buffer_overwrite_packet1_size = sizeof(v3_buffer_overwrite_packet1); + +/* Frame (54 bytes) */ +unsigned char v3_buffer_overwrite_packet2[54] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x00, 0x28, 0x04, 0xf6, 0x00, 0xb9, 0x80, 0x11, /* .(o2.... */ +0x39, 0x9a, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x01, 0x06, 0x82, 0x00, 0x08 /* ...... */ +}; + +int v3_buffer_overwrite_packet2_size = sizeof(v3_buffer_overwrite_packet2); + +/* Frame (1514 bytes) */ +unsigned char v3_decrypt_pdu_buffer_overwrite_packet1[1514] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x05, 0xdc, 0x6f, 0x37, 0x20, 0x00, 0x80, 0x11, /* ..o7 ... */ +0xaa, 0x5d, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0xfc, 0xed, 0x00, 0xa1, 0x05, 0xdc, /* ........ */ +0x5c, 0x9e, 0x30, 0x40, 0x02, 0x01, 0x03, 0x30, /* \.0@...0 */ +0x41, 0x02, 0x04, 0x00, 0x00, 0x00, 0xa2, 0x02, /* A....... */ +0x04, 0x00, 0x00, 0x00, 0xa3, 0x04, 0x01, 0x02, /* ........ */ +0x02, 0x04, 0x00, 0x00, 0x00, 0x03, 0x04, 0xcc, /* ........ */ +0x30, 0x44, 0x04, 0x00, 0x02, 0x04, 0x00, 0x00, /* 0D...... */ +0x00, 0xa5, 0x02, 0x04, 0x00, 0x00, 0x00, 0xa6, /* ........ */ +0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x82, /* ........ */ +0x05, 0xa0, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* ..zzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a /* zz */ +}; + +int v3_decrypt_pdu_buffer_overwrite_packet1_size = sizeof(v3_decrypt_pdu_buffer_overwrite_packet1); + +/* Frame (54 bytes) */ +unsigned char v3_decrypt_pdu_buffer_overwrite_packet2[54] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x00, 0x28, 0x6f, 0x37, 0x00, 0xb9, 0x80, 0x11, /* .(o7.... */ +0xcf, 0x58, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* ..zzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, /* zzzzzzzz */ +0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a /* zzzzzz */ +}; + +int v3_decrypt_pdu_buffer_overwrite_packet2_size = sizeof(v3_decrypt_pdu_buffer_overwrite_packet2); + +/* Frame (165 bytes) */ +unsigned char v3_encrypt_pdu_buffer_overwrite_packet1[187] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x00, 0xad, 0x04, 0xfb, 0x00, 0x00, 0x80, 0x11, /* ........ */ +0x39, 0xc9, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0xf8, 0x7e, 0x00, 0xa1, 0x00, 0x99, /* ...~.... */ +0x42, 0xd1, 0x30, 0x40, 0x02, 0x01, 0x03, 0x30, /* .&0@...0 */ +0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0xc0, 0x02, /* @....... */ +0x04, 0x00, 0x00, 0x00, 0xc1, 0x04, 0x01, 0x02, /* ........ */ +0x02, 0x04, 0x00, 0x00, 0x00, 0x03, 0x04, 0x01, /* ........ */ +0x30, 0x43, 0x04, 0x09, 0x80, 0x00, 0x03, 0x10, /* 0C...... */ +0x01, 0xc0, 0xa8, 0x64, 0xaf, 0x02, 0x04, 0x00, /* ...d.... */ +0x00, 0x00, 0xc4, 0x02, 0x04, 0x00, 0x00, 0x00, /* ........ */ +0xc5, 0x04, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, /* ...usern */ +0x61, 0x6d, 0x65, 0x04, 0x02, 0x78, 0x33, 0x04, /* ame..x3. */ +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x01, 0x04, 0x10, 0x0a, 0xe5, 0x7e, 0x60, 0x3a, /* .....~`: */ +0xe5, 0x40, 0x4f, 0x94, 0x31, 0x9c, 0x18, 0x6f, /* .@O.1..o */ +0x10, 0x7d, 0x61, 0x04, 0x02, 0x78, 0x35, 0x04, /* .}a..x5. */ +0x02, 0x78, 0x36, 0xa0, 0x00, 0x02, 0x04, 0x00, /* .x6..... */ +0x00, 0x00, 0xc6, 0x02, 0x01, 0x00, 0x02, 0x01, /* ........ */ +0x00, 0x30, 0x84, 0x01, 0xff, 0xff, 0xff, 0x30, /* .0.....0 */ +0x84, 0x00, 0x00, 0x00, 0x0e, 0x06, 0x82, 0x00, /* ........ */ +0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, /* .+...... */ +0x00, 0xaa, 0x00 /* ... */ +}; + +int v3_encrypt_pdu_buffer_overwrite_packet1_size = sizeof(v3_encrypt_pdu_buffer_overwrite_packet1); + +/* Frame (165 bytes) */ +unsigned char v3_encrypt_pdu_padding_buffer_overwrite_packet1[165] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x00, 0x97, 0x6a, 0x34, 0x00, 0x00, 0x80, 0x11, /* ..j4.... */ +0xd4, 0xa5, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0xc8, 0xcb, 0x00, 0xa1, 0x00, 0x83, /* ........ */ +0x2c, 0xa9, 0x30, 0x79, 0x02, 0x01, 0x03, 0x30, /* .40y...0 */ +0x0e, 0x02, 0x01, 0x06, 0x02, 0x03, 0x00, 0xff, /* ........ */ +0xf0, 0x04, 0x01, 0x07, 0x02, 0x01, 0x03, 0x04, /* ........ */ +0x32, 0x30, 0x30, 0x04, 0x09, 0x80, 0x00, 0x03, /* 200..... */ +0x10, 0x01, 0xc0, 0xa8, 0x64, 0xaf, 0x02, 0x01, /* ....d... */ +0x01, 0x02, 0x01, 0x0d, 0x04, 0x05, 0x6a, 0x61, /* ......ja */ +0x6e, 0x65, 0x74, 0x04, 0x0c, 0x9d, 0x1d, 0xbe, /* net..... */ +0x6b, 0xee, 0x12, 0x22, 0xcb, 0x90, 0xe8, 0x41, /* k.."...A */ +0xfc, 0x04, 0x08, 0x00, 0x00, 0x00, 0xc8, 0x00, /* ........ */ +0x00, 0x00, 0x22, 0x04, 0x30, 0x0a, 0x5a, 0x42, /* ..".0.ZB */ +0xe6, 0x83, 0xe2, 0x86, 0x36, 0x60, 0xdc, 0x19, /* ....6`.. */ +0x36, 0x8a, 0x2d, 0xd6, 0x8e, 0xee, 0x68, 0xe9, /* 6.-...h. */ +0x08, 0xa8, 0xb3, 0xea, 0x61, 0x1d, 0xf1, 0xa3, /* ....a... */ +0x19, 0xc8, 0xda, 0x90, 0x70, 0x25, 0x74, 0x84, /* ....p%t. */ +0x97, 0x48, 0xcb, 0x9a, 0x6b, 0x22, 0xd3, 0x45, /* .H..k".E */ +0xee, 0x72, 0x52, 0x38, 0x03 /* .rR8. */ +}; + +int v3_encrypt_pdu_padding_buffer_overwrite_packet1_size = sizeof(v3_encrypt_pdu_padding_buffer_overwrite_packet1); + +/* Frame (165 bytes) */ +unsigned char v3_object_id_buffer_overwrite_packet1[1514] = { +0x00, 0x00, 0x5e, 0x00, 0x01, 0x02, 0xc8, 0xd9, /* ..^..... */ +0xd2, 0x24, 0x23, 0x53, 0x08, 0x00, 0x45, 0x00, /* .$#S..E. */ +0x05, 0xdc, 0x50, 0x9e, 0x20, 0x00, 0x80, 0x11, /* ..P. ... */ +0xc8, 0xf6, 0x0a, 0xac, 0xd6, 0x3f, 0x0a, 0x80, /* .....?.. */ +0x10, 0x11, 0xd2, 0x5c, 0x00, 0xa1, 0x05, 0xdc, /* ...\.... */ +0xcb, 0x49, 0x30, 0x40, 0x02, 0x01, 0x03, 0x30, /* .I0@...0 */ +0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0xc0, 0x02, /* @....... */ +0x04, 0x00, 0x00, 0x00, 0xc1, 0x04, 0x01, 0x02, /* ........ */ +0x02, 0x04, 0x00, 0x00, 0x00, 0x03, 0x04, 0x01, /* ........ */ +0x30, 0x43, 0x04, 0x09, 0x80, 0x00, 0x03, 0x10, /* 0C...... */ +0x01, 0xc0, 0xa8, 0x64, 0xaf, 0x02, 0x04, 0x00, /* ...d.... */ +0x00, 0x00, 0xc4, 0x02, 0x25, 0x00, 0x00, 0x00, /* ....%... */ +0xc5, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* .AAAAAAA */ +0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* AAAAAAAA */ +0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* AAAAAAAA */ +0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, /* AAAAAAAA */ +0x41, 0x41, 0x04, 0x08, 0x75, 0x73, 0x65, 0x72, /* AA..user */ +0x6e, 0x61, 0x6d, 0x65, 0x04, 0x02, 0x78, 0x33, /* name..x3 */ +0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ +0x00, 0x01, 0x04, 0x08, 0xbc, 0x50, 0x68, 0x68, /* .....Phh */ +0x15, 0xb3, 0x2c, 0x9d, 0x04, 0x02, 0x78, 0x35, /* ..,...x5 */ +0x04, 0x02, 0x78, 0x36, 0xa0, 0x00, 0x02, 0x04, /* ..x6.... */ +0x00, 0x00, 0x00, 0xc6, 0x02, 0x01, 0x00, 0x02, /* ........ */ +0x01, 0x00, 0x30, 0x84, 0x01, 0xff, 0xff, 0xff, /* ..0..... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, /* ....+... */ +0x01, 0x01, 0x03, 0x00, 0x30, 0x84, 0x00, 0x00, /* ....0... */ +0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, 0x2b, 0x06, /* ......+. */ +0x01, 0x02, 0x01, 0x01, 0x03, 0x00, 0x30, 0x84, /* ......0. */ +0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, 0x00, 0x08, /* ........ */ +0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x03, 0x00, /* +....... */ +0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x82, /* 0....... */ +0x00, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, /* ..+..... */ +0x03, 0x00, 0x30, 0x84, 0x00, 0x00, 0x00, 0x0c, /* ..0..... */ +0x06, 0x82 /* .. */ +}; + +int v3_object_id_buffer_overwrite_packet1_size = sizeof(v3_object_id_buffer_overwrite_packet1); + diff --git a/test/regression/sntp_test/netx_sntp_client_broadcast_basic_test.c b/test/regression/sntp_test/netx_sntp_client_broadcast_basic_test.c new file mode 100644 index 00000000..62175ad5 --- /dev/null +++ b/test/regression/sntp_test/netx_sntp_client_broadcast_basic_test.c @@ -0,0 +1,334 @@ +#include "nx_api.h" +#include "nx_ip.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_sntp_client.h" +#else +#include "nx_sntp_client.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define SNTP packet size. */ +#define NX_SNTP_CLIENT_PACKET_SIZE (NX_UDP_PACKET + 100) + +/* Define SNTP packet pool size. */ +#define NX_SNTP_CLIENT_PACKET_POOL_SIZE (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET))) + +/* NTP server reply. */ + +static char pkt_data[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0c, + 0x29, 0x1e, 0xaa, 0x4f, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, + 0xbb, 0xce, 0xc0, 0xa8, 0x7e, 0x82, 0xc0, 0xa8, + 0x7e, 0xff, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, + 0x02, 0xb2, 0x25, 0x02, 0x06, 0xec, 0x00, 0x00, + 0x07, 0xdd, 0x00, 0x00, 0x06, 0x6e, 0x89, 0xbd, + 0x04, 0x0a, 0xd6, 0x4b, 0xd7, 0xeb, 0xb3, 0x25, + 0xe0, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xd6, 0x4b, 0xd8, 0x5a, 0xab, 0x25, + 0x19, 0x86 }; + +static UINT pkt_size = 90; + +static ULONG expected_seconds = 0xd64bd85a; +static ULONG expected_milliseconds = 0x2a7; +static ULONG tolerance_milliseconds = 200; + +extern void _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Set up client thread and network resources. */ + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD sntp_client_thread; +static NX_SNTP_CLIENT sntp_client; + + +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,168,126,42) +#define SERVER_IP_ADDRESS IP_ADDRESS(192,168,126,130) +#define SERVER_IP_ADDRESS_2 SERVER_IP_ADDRESS + +/* Set up the SNTP network and address index; */ +static UINT iface_index; + +static UINT error_counter; + +/* Set up client thread entry point. */ +static void sntp_client_thread_entry(ULONG info); + +static void inject_sntp_server_reply(); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_broadcast_basic_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + error_counter = 0; + + free_memory_pointer = (UCHAR *)first_unused_memory; + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "SNTP Client Packet Pool", + NX_SNTP_CLIENT_PACKET_SIZE, free_memory_pointer, + NX_SNTP_CLIENT_PACKET_POOL_SIZE); + free_memory_pointer = free_memory_pointer + NX_SNTP_CLIENT_PACKET_POOL_SIZE; + + /* Check for errors. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create Client IP instances */ + status = nx_ip_create(&client_ip, "SNTP IP Instance", CLIENT_IP_ADDRESS, + 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1500, + free_memory_pointer, 2048, 1); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory. */ + status = nx_arp_enable(&client_ip, (void **) free_memory_pointer, 2048); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + + /* Enable UDP for client. */ + status = nx_udp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create the client thread */ + status = tx_thread_create(&sntp_client_thread, "SNTP Client Thread", sntp_client_thread_entry, + (ULONG)(&sntp_client), free_memory_pointer, 2048, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for errors */ + if (status != TX_SUCCESS) + error_counter++; + + /* set the SNTP network interface to the primary interface. */ + iface_index = 0; + + /* Create the SNTP Client to run in broadcast mode.. */ + status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool, + NX_NULL, + NX_NULL, + NX_NULL /* no random_number_generator callback */); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_resume(&sntp_client_thread); + + return; +} + +/* Define size of buffer to display client's local time. */ +#define BUFSIZE 50 + +/* Define the client thread. */ +void sntp_client_thread_entry(ULONG info) +{ + +UINT status; +UINT spin; +UINT server_status; +CHAR buffer[BUFSIZE]; +ULONG base_seconds; +ULONG base_fraction; +ULONG seconds, milliseconds, microseconds, fraction; + + printf("NetX Test: NETX SNTP Client Broadcast Basic Test....................."); + + /* Give other threads (IP instance) a chance to initialize. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Use the IPv4 service to initialize the Client and set IPv4 SNTP broadcast address. */ + status = nx_sntp_client_initialize_broadcast(&sntp_client, NX_NULL, SERVER_IP_ADDRESS); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Set the base time which is approximately the number of seconds since the turn of the last century. */ + base_seconds = 0xd2c96b90; /* Jan 24, 2012 UTC */ + base_fraction = 0xa132db1e; + + /* Apply to the SNTP Client local time. */ + status = nx_sntp_client_set_local_time(&sntp_client, base_seconds, base_fraction); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_run_broadcast(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + inject_sntp_server_reply(); + + spin = NX_TRUE; + + /* Now check periodically for time changes. */ + while(spin) + { + + /* First verify we have a valid SNTP service running. */ + status = nx_sntp_client_receiving_updates(&sntp_client, &server_status); + + if ((status == NX_SUCCESS) && (server_status == NX_TRUE)) + { + + /* Server status is good. Now get the Client local time. */ + + /* Call extended function to display the local time in years, months, date format. */ + status = nx_sntp_client_get_local_time_extended(&sntp_client, &seconds, &fraction, &buffer[0], sizeof(buffer)); + + /* Convert fraction to microseconds. */ + nx_sntp_client_utility_fraction_to_usecs(fraction, µseconds); + + milliseconds = ((microseconds + 500) / 1000); + + if (status == NX_SUCCESS) + { + if (!((seconds == expected_seconds) && (milliseconds > (expected_milliseconds - tolerance_milliseconds)) && + (milliseconds < (expected_milliseconds + tolerance_milliseconds)))) + { + error_counter++; + break; + } + } + else + { + error_counter++; + break; + } + + /* Display the local time in years, months, date format. */ + status = nx_sntp_client_get_local_time(&sntp_client, &seconds, &fraction, &buffer[0]); + + /* Convert fraction to microseconds. */ + nx_sntp_client_utility_fraction_to_usecs(fraction, µseconds); + + milliseconds = ((microseconds + 500) / 1000); + + if (status == NX_SUCCESS) + { + if ((seconds == expected_seconds) && (milliseconds > (expected_milliseconds - tolerance_milliseconds)) && + (milliseconds < (expected_milliseconds + tolerance_milliseconds))) + { + break; + } + else + { + error_counter++; + break; + } + } + + } + else + { + + /* Wait a short bit to check again. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + } + } + + /* We can stop the SNTP service if for example we think the SNTP service has stopped. */ + status = nx_sntp_client_stop(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_delete(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + + +void inject_sntp_server_reply() +{ + +UINT status; +NX_PACKET *my_packet; + + /* Now, this packet is a received one, allocate the packet and let the IP stack receives it. */ + /* Allocate a packet. */ + status = nx_packet_allocate(client_ip.nx_ip_default_packet_pool, &my_packet, 0, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + my_packet -> nx_packet_length = pkt_size - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + + _nx_ip_packet_deferred_receive(&client_ip, my_packet); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_broadcast_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NETX SNTP Client Broadcast Basic Test.....................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/sntp_test/netx_sntp_client_ipv6_broadcast_basic_test.c b/test/regression/sntp_test/netx_sntp_client_ipv6_broadcast_basic_test.c new file mode 100644 index 00000000..897162aa --- /dev/null +++ b/test/regression/sntp_test/netx_sntp_client_ipv6_broadcast_basic_test.c @@ -0,0 +1,339 @@ +#include "nx_api.h" +#include "nx_ip.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_sntp_client.h" +#else +#include "nx_sntp_client.h" +#endif +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_IPV4) + +/* Define SNTP packet size. */ +#define NX_SNTP_CLIENT_PACKET_SIZE (NX_UDP_PACKET + 100) + +/* Define SNTP packet pool size. */ +#define NX_SNTP_CLIENT_PACKET_POOL_SIZE (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET))) + +/* NTP server reply. */ + +static char pkt_data[110] = { + 0x33, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, + 0x29, 0x1e, 0xaa, 0x4f, 0x86, 0xdd, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x11, 0x40, 0xfe, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, + 0x29, 0xff, 0xfe, 0x1e, 0xaa, 0x4f, 0xff, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7b, + 0x00, 0x7b, 0x00, 0x38, 0x7d, 0x9b, 0x25, 0x02, + 0x06, 0xec, 0x00, 0x00, 0x07, 0xe9, 0x00, 0x00, + 0x03, 0x09, 0x89, 0xbd, 0x04, 0x0a, 0xd6, 0x4f, + 0xad, 0x4d, 0x78, 0xae, 0xb7, 0xbc, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x4f, + 0xad, 0x57, 0x70, 0x86, 0x42, 0x10 }; + + +static UINT pkt_size = 110; + +static ULONG expected_seconds = 0xd64fad57; +static ULONG expected_milliseconds = 0x1c2; +static ULONG tolerance_milliseconds = 200; + +extern void _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Set up client thread and network resources. */ + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD sntp_client_thread; +static NX_SNTP_CLIENT sntp_client; + + +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,168,126,42) + +/* Set up the SNTP network and address index; */ +static UINT iface_index; + +static UINT error_counter; + +/* Set up client thread entry point. */ +static void sntp_client_thread_entry(ULONG info); + +static void inject_sntp_server_reply(); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_ipv6_broadcast_basic_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + error_counter = 0; + + free_memory_pointer = (UCHAR *)first_unused_memory; + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "SNTP Client Packet Pool", + NX_SNTP_CLIENT_PACKET_SIZE, free_memory_pointer, + NX_SNTP_CLIENT_PACKET_POOL_SIZE); + free_memory_pointer = free_memory_pointer + NX_SNTP_CLIENT_PACKET_POOL_SIZE; + + /* Check for errors. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create Client IP instances */ + status = nx_ip_create(&client_ip, "SNTP IP Instance", CLIENT_IP_ADDRESS, + 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1500, + free_memory_pointer, 2048, 1); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory. */ + status = nx_arp_enable(&client_ip, (void **) free_memory_pointer, 2048); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + + /* Enable UDP for client. */ + status = nx_udp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create the client thread */ + status = tx_thread_create(&sntp_client_thread, "SNTP Client Thread", sntp_client_thread_entry, + (ULONG)(&sntp_client), free_memory_pointer, 2048, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for errors */ + if (status != TX_SUCCESS) + error_counter++; + + /* set the SNTP network interface to the primary interface. */ + iface_index = 0; + + /* Create the SNTP Client to run in broadcast mode.. */ + status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool, + NX_NULL, + NX_NULL, + NX_NULL /* no random_number_generator callback */); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_resume(&sntp_client_thread); + + return; +} + +/* Define size of buffer to display client's local time. */ +#define BUFSIZE 50 + +/* Define the client thread. */ +void sntp_client_thread_entry(ULONG info) +{ + +UINT status; +UINT spin; +UINT server_status; +CHAR buffer[BUFSIZE]; +ULONG base_seconds; +ULONG base_fraction; +ULONG seconds, milliseconds, microseconds, fraction; +NXD_ADDRESS sntp_server_address; +NXD_ADDRESS client_ip_address; + + printf("NetX Test: NETX SNTP Client IPv6 Broadcast Basic Test................"); + + /* Give other threads (IP instance) a chance to initialize. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Set up IPv6 services. */ + status = nxd_ipv6_enable(&client_ip); + + status += nxd_icmp_enable(&client_ip); + + if (status != NX_SUCCESS) + error_counter++; + + client_ip_address.nxd_ip_address.v6[0] = 0xfe800000; + client_ip_address.nxd_ip_address.v6[1] = 0x00000000; + client_ip_address.nxd_ip_address.v6[2] = 0x020c29ff; + client_ip_address.nxd_ip_address.v6[3] = 0xfe6a2e7b; + client_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + + /* Set the IPv6 server address. */ + sntp_server_address.nxd_ip_address.v6[0] = 0xfe800000; + sntp_server_address.nxd_ip_address.v6[1] = 0x00000000; + sntp_server_address.nxd_ip_address.v6[2] = 0x020c29ff; + sntp_server_address.nxd_ip_address.v6[3] = 0xfe1eaa4f; + sntp_server_address.nxd_ip_version = NX_IP_VERSION_V6; + + + status = nxd_ipv6_address_set(&client_ip, 0, &client_ip_address, 64, NX_NULL); + + /* Check for link local address set error. */ + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_sleep(4 * NX_IP_PERIODIC_RATE); + + status = nxd_sntp_client_initialize_broadcast(&sntp_client, &sntp_server_address, NX_NULL); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Set the base time which is approximately the number of seconds since the turn of the last century. */ + base_seconds = 0xd2c96b90; /* Jan 24, 2012 UTC */ + base_fraction = 0xa132db1e; + + /* Apply to the SNTP Client local time. */ + status = nx_sntp_client_set_local_time(&sntp_client, base_seconds, base_fraction); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_run_broadcast(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + inject_sntp_server_reply(); + + spin = NX_TRUE; + + /* Now check periodically for time changes. */ + while(spin) + { + + /* First verify we have a valid SNTP service running. */ + status = nx_sntp_client_receiving_updates(&sntp_client, &server_status); + + if ((status == NX_SUCCESS) && (server_status == NX_TRUE)) + { + + /* Server status is good. Now get the Client local time. */ + + /* Display the local time in years, months, date format. */ + status = nx_sntp_client_get_local_time(&sntp_client, &seconds, &fraction, &buffer[0]); + + /* Convert fraction to microseconds. */ + nx_sntp_client_utility_fraction_to_usecs(fraction, µseconds); + + milliseconds = ((microseconds + 500) / 1000); + + if (status == NX_SUCCESS) + { + if ((seconds == expected_seconds) && (milliseconds > (expected_milliseconds - tolerance_milliseconds)) && + (milliseconds < (expected_milliseconds + tolerance_milliseconds))) + { + break; + } + else + { + error_counter++; + break; + } + } + + } + else + { + + /* Wait a short bit to check again. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + } + } + + /* We can stop the SNTP service if for example we think the SNTP service has stopped. */ + status = nx_sntp_client_stop(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_delete(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + + +void inject_sntp_server_reply() +{ + +UINT status; +NX_PACKET *my_packet; + + /* Now, this packet is a received one, allocate the packet and let the IP stack receives it. */ + /* Allocate a packet. */ + status = nx_packet_allocate(client_ip.nx_ip_default_packet_pool, &my_packet, 0, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + my_packet -> nx_packet_length = pkt_size - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + + _nx_ip_packet_deferred_receive(&client_ip, my_packet); + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_ipv6_broadcast_basic_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NETX SNTP Client IPv6 Broadcast Basic Test................N/A\n"); + test_control_return(3); + +} +#endif + diff --git a/test/regression/sntp_test/netx_sntp_client_ipv6_unicast_basic_test.c b/test/regression/sntp_test/netx_sntp_client_ipv6_unicast_basic_test.c new file mode 100644 index 00000000..790c287a --- /dev/null +++ b/test/regression/sntp_test/netx_sntp_client_ipv6_unicast_basic_test.c @@ -0,0 +1,339 @@ +#include "nx_api.h" +#include "nx_ip.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_sntp_client.h" +#else +#include "nx_sntp_client.h" +#endif +extern void test_control_return(UINT status); +#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_IPV4) + +/* Define SNTP packet size. */ +#define NX_SNTP_CLIENT_PACKET_SIZE (NX_UDP_PACKET + 100) + +/* Define SNTP packet pool size. */ +#define NX_SNTP_CLIENT_PACKET_POOL_SIZE (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET))) + +/* NTP server reply. */ + + +static char pkt_data[110] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x00, 0x0c, + 0x29, 0x1e, 0xaa, 0x4f, 0x86, 0xdd, 0x60, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x11, 0x40, 0xfe, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, + 0x29, 0xff, 0xfe, 0x1e, 0xaa, 0x4f, 0xfe, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, + 0x29, 0xff, 0xfe, 0x6a, 0x2e, 0x7b, 0x00, 0x7b, + 0x00, 0x7b, 0x00, 0x38, 0x6a, 0x24, 0x1c, 0x02, + 0x00, 0xec, 0x00, 0x00, 0x07, 0xd9, 0x00, 0x00, + 0x06, 0xdf, 0x89, 0xbd, 0x04, 0x0a, 0xd6, 0x4f, + 0xa9, 0x4b, 0x78, 0x72, 0x04, 0xf2, 0xd2, 0xc9, + 0x6b, 0x90, 0xa1, 0x32, 0xdb, 0x1e, 0xd6, 0x4f, + 0xac, 0xd8, 0x9e, 0x7d, 0xc4, 0x3a, 0xd6, 0x4f, + 0xac, 0xd8, 0x9e, 0x82, 0xf1, 0x51 }; + +static UINT pkt_size = 110; + +static ULONG expected_seconds = 0xd64facd8; +static ULONG expected_milliseconds = 0x275; +static ULONG tolerance_milliseconds = 200; + +extern void _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Set up client thread and network resources. */ + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD sntp_client_thread; +static NX_SNTP_CLIENT sntp_client; + + +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,168,126,42) + +/* Set up the SNTP network and address index; */ +static UINT iface_index; + +static UINT error_counter; + +/* Set up client thread entry point. */ +static void sntp_client_thread_entry(ULONG info); + +static void inject_sntp_server_reply(); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_ipv6_unicast_basic_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + error_counter = 0; + + free_memory_pointer = (UCHAR *)first_unused_memory; + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "SNTP Client Packet Pool", + NX_SNTP_CLIENT_PACKET_SIZE, free_memory_pointer, + NX_SNTP_CLIENT_PACKET_POOL_SIZE); + free_memory_pointer = free_memory_pointer + NX_SNTP_CLIENT_PACKET_POOL_SIZE; + + /* Check for errors. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create Client IP instances */ + status = nx_ip_create(&client_ip, "SNTP IP Instance", CLIENT_IP_ADDRESS, + 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1500, + free_memory_pointer, 2048, 1); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory. */ + status = nx_arp_enable(&client_ip, (void **) free_memory_pointer, 2048); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + + /* Enable UDP for client. */ + status = nx_udp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create the client thread */ + status = tx_thread_create(&sntp_client_thread, "SNTP Client Thread", sntp_client_thread_entry, + (ULONG)(&sntp_client), free_memory_pointer, 2048, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for errors */ + if (status != TX_SUCCESS) + error_counter++; + + /* set the SNTP network interface to the primary interface. */ + iface_index = 0; + + /* Create the SNTP Client to run in broadcast mode.. */ + status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool, + NX_NULL, + NX_NULL, + NX_NULL /* no random_number_generator callback */); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_resume(&sntp_client_thread); + + return; +} + +/* Define size of buffer to display client's local time. */ +#define BUFSIZE 50 + +/* Define the client thread. */ +void sntp_client_thread_entry(ULONG info) +{ + +UINT status; +UINT spin; +UINT server_status; +CHAR buffer[BUFSIZE]; +ULONG base_seconds; +ULONG base_fraction; +ULONG seconds, milliseconds, microseconds, fraction; +NXD_ADDRESS sntp_server_address; +NXD_ADDRESS client_ip_address; + + printf("NetX Test: NETX SNTP Client IPv6 Unicast Basic Test.................."); + + /* Give other threads (IP instance) a chance to initialize. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Set up IPv6 services. */ + status = nxd_ipv6_enable(&client_ip); + + status += nxd_icmp_enable(&client_ip); + + if (status != NX_SUCCESS) + error_counter++; + + client_ip_address.nxd_ip_address.v6[0] = 0xfe800000; + client_ip_address.nxd_ip_address.v6[1] = 0x00000000; + client_ip_address.nxd_ip_address.v6[2] = 0x020c29ff; + client_ip_address.nxd_ip_address.v6[3] = 0xfe6a2e7b; + client_ip_address.nxd_ip_version = NX_IP_VERSION_V6; + + /* Set the IPv6 server address. */ + sntp_server_address.nxd_ip_address.v6[0] = 0xfe800000; + sntp_server_address.nxd_ip_address.v6[1] = 0x00000000; + sntp_server_address.nxd_ip_address.v6[2] = 0x020c29ff; + sntp_server_address.nxd_ip_address.v6[3] = 0xfe1eaa4f; + sntp_server_address.nxd_ip_version = NX_IP_VERSION_V6; + + + status = nxd_ipv6_address_set(&client_ip, 0, &client_ip_address, 64, NX_NULL); + + /* Check for link local address set error. */ + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_sleep(4 * NX_IP_PERIODIC_RATE); + + /* Use the IPv4 service to initialize the Client and set the IPv4 SNTP server. */ + status = nxd_sntp_client_initialize_unicast(&sntp_client, &sntp_server_address); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Set the base time which is approximately the number of seconds since the turn of the last century. */ + base_seconds = 0xd2c96b90; /* Jan 24, 2012 UTC */ + base_fraction = 0xa132db1e; + + /* Apply to the SNTP Client local time. */ + status = nx_sntp_client_set_local_time(&sntp_client, base_seconds, base_fraction); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_run_unicast(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + inject_sntp_server_reply(); + + spin = NX_TRUE; + + /* Now check periodically for time changes. */ + while(spin) + { + + /* First verify we have a valid SNTP service running. */ + status = nx_sntp_client_receiving_updates(&sntp_client, &server_status); + + if ((status == NX_SUCCESS) && (server_status == NX_TRUE)) + { + + /* Server status is good. Now get the Client local time. */ + + /* Display the local time in years, months, date format. */ + status = nx_sntp_client_get_local_time(&sntp_client, &seconds, &fraction, &buffer[0]); + + /* Convert fraction to microseconds. */ + nx_sntp_client_utility_fraction_to_usecs(fraction, µseconds); + + milliseconds = ((microseconds + 500) / 1000); + + if (status == NX_SUCCESS) + { + if ((seconds == expected_seconds) && (milliseconds > (expected_milliseconds - tolerance_milliseconds)) && + (milliseconds < (expected_milliseconds + tolerance_milliseconds))) + { + break; + } + else + { + error_counter++; + break; + } + } + + } + else + { + + /* Wait a short bit to check again. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + } + } + + /* We can stop the SNTP service if for example we think the SNTP service has stopped. */ + status = nx_sntp_client_stop(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_delete(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + + +void inject_sntp_server_reply() +{ + +UINT status; +NX_PACKET *my_packet; + + /* Now, this packet is a received one, allocate the packet and let the IP stack receives it. */ + /* Allocate a packet. */ + status = nx_packet_allocate(client_ip.nx_ip_default_packet_pool, &my_packet, 0, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + my_packet -> nx_packet_length = pkt_size - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + + _nx_ip_packet_deferred_receive(&client_ip, my_packet); + +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_ipv6_unicast_basic_test_application_define(void *first_unused_memory) +#endif +{ + printf("NetX Test: NETX SNTP Client IPv6 Unicast Basic Test..................N/A\n"); + test_control_return(3); + +} +#endif diff --git a/test/regression/sntp_test/netx_sntp_client_kod_test.c b/test/regression/sntp_test/netx_sntp_client_kod_test.c new file mode 100644 index 00000000..a9b03587 --- /dev/null +++ b/test/regression/sntp_test/netx_sntp_client_kod_test.c @@ -0,0 +1,269 @@ +#include "nx_api.h" +#include "nx_ip.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_sntp_client.h" +#else +#include "nx_sntp_client.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define SNTP packet size. */ +#define NX_SNTP_CLIENT_PACKET_SIZE (NX_UDP_PACKET + 100) + +/* Define SNTP packet pool size. */ +#define NX_SNTP_CLIENT_PACKET_POOL_SIZE (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET))) + +/* NTP server KOD packet("DENY"). */ +static char pkt_data[90] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x00, 0x0c, + 0x29, 0x1e, 0xaa, 0x4f, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, + 0xbc, 0xa3, 0xc0, 0xa8, 0x7e, 0x82, 0xc0, 0xa8, + 0x7e, 0x2a, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, + 0x7f, 0xa0, 0x1c, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, + 0x4e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 }; + +static UINT pkt_size = 90; + +extern void _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Set up client thread and network resources. */ + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD sntp_client_thread; +static NX_SNTP_CLIENT sntp_client; + + +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,168,126,42) +#define SERVER_IP_ADDRESS IP_ADDRESS(192,168,126,130) +#define SERVER_IP_ADDRESS_2 SERVER_IP_ADDRESS + +/* Set up the SNTP network and address index; */ +static UINT iface_index; + +static UINT error_counter; + +/* Set up client thread entry point. */ +static void sntp_client_thread_entry(ULONG info); + +static void inject_sntp_server_reply(); + +static UINT kiss_of_death_test(NX_SNTP_CLIENT* client_ptr, UINT code); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_kod_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + error_counter = 0; + + free_memory_pointer = (UCHAR *)first_unused_memory; + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "SNTP Client Packet Pool", + NX_SNTP_CLIENT_PACKET_SIZE, free_memory_pointer, + NX_SNTP_CLIENT_PACKET_POOL_SIZE); + free_memory_pointer = free_memory_pointer + NX_SNTP_CLIENT_PACKET_POOL_SIZE; + + /* Check for errors. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create Client IP instances */ + status = nx_ip_create(&client_ip, "SNTP IP Instance", CLIENT_IP_ADDRESS, + 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1500, + free_memory_pointer, 2048, 1); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory. */ + status = nx_arp_enable(&client_ip, (void **) free_memory_pointer, 2048); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + + /* Enable UDP for client. */ + status = nx_udp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create the client thread */ + status = tx_thread_create(&sntp_client_thread, "SNTP Client Thread", sntp_client_thread_entry, + (ULONG)(&sntp_client), free_memory_pointer, 2048, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for errors */ + if (status != TX_SUCCESS) + error_counter++; + + /* set the SNTP network interface to the primary interface. */ + iface_index = 0; + + /* Create the SNTP Client to run in broadcast mode.. */ + status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool, + NX_NULL, + kiss_of_death_test, + NX_NULL /* no random_number_generator callback */); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_resume(&sntp_client_thread); + + return; +} + + +static UINT kiss_of_death_test(NX_SNTP_CLIENT* client_ptr, UINT code) +{ + if (code != NX_SNTP_KOD_DENY) + { + error_counter++; + } + + return(1); +} + +/* Define the client thread. */ +void sntp_client_thread_entry(ULONG info) +{ + +UINT status; +ULONG base_seconds; +ULONG base_fraction; + + printf("NetX Test: NETX SNTP Client KOD Test................................."); + + /* Give other threads (IP instance) a chance to initialize. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Use the IPv4 service to initialize the Client and set the IPv4 SNTP server. */ + status = nx_sntp_client_initialize_unicast(&sntp_client, SERVER_IP_ADDRESS); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Set the base time which is approximately the number of seconds since the turn of the last century. */ + base_seconds = 0xd2c96b90; /* Jan 24, 2012 UTC */ + base_fraction = 0xa132db1e; + + /* Apply to the SNTP Client local time. */ + status = nx_sntp_client_set_local_time(&sntp_client, base_seconds, base_fraction); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_run_unicast(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + inject_sntp_server_reply(); + + tx_thread_sleep(NX_IP_PERIODIC_RATE); + + /* We can stop the SNTP service if for example we think the SNTP service has stopped. */ + status = nx_sntp_client_stop(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_delete(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + + +void inject_sntp_server_reply() +{ + +UINT status; +NX_PACKET *my_packet; + + /* Now, this packet is a received one, allocate the packet and let the IP stack receives it. */ + /* Allocate a packet. */ + status = nx_packet_allocate(client_ip.nx_ip_default_packet_pool, &my_packet, 0, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + my_packet -> nx_packet_length = pkt_size - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + + _nx_ip_packet_deferred_receive(&client_ip, my_packet); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_kod_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NETX SNTP Client KOD Test.................................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/sntp_test/netx_sntp_client_packet_chain_test.c b/test/regression/sntp_test/netx_sntp_client_packet_chain_test.c new file mode 100644 index 00000000..0abb3503 --- /dev/null +++ b/test/regression/sntp_test/netx_sntp_client_packet_chain_test.c @@ -0,0 +1,389 @@ +#include "nx_api.h" +#include "nx_ip.h" + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) && defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_PACKET_CHAIN) + +#include "nxd_sntp_client.h" + +/* Define SNTP packet size. */ +#define NX_SNTP_CLIENT_PACKET_SIZE (NX_UDP_PACKET + 100) + +/* Define SNTP packet pool size. */ +#define NX_SNTP_CLIENT_PACKET_POOL_SIZE (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET))) + +/* NTP server reply. */ +static char pkt_data[90] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x00, 0x0c, + 0x29, 0x1e, 0xaa, 0x4f, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, + 0xbc, 0xa3, 0xc0, 0xa8, 0x7e, 0x82, 0xc0, 0xa8, + 0x7e, 0x2a, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, + 0x7f, 0xa0, 0x1c, 0x02, 0x00, 0xec, 0x00, 0x00, + 0x07, 0xdd, 0x00, 0x00, 0x06, 0x6e, 0x89, 0xbd, + 0x04, 0x0a, 0xd6, 0x4b, 0xd7, 0xeb, 0xb3, 0x25, + 0xe0, 0x52, 0xd2, 0xc9, 0x6b, 0x90, 0xa1, 0x32, + 0xdb, 0x1e, 0xd6, 0x4b, 0xd8, 0x5b, 0x20, 0x27, + 0x62, 0xa4, 0xd6, 0x4b, 0xd8, 0x5b, 0x20, 0x2c, + 0x4b, 0x46 }; + +static UINT pkt_size = 90; + +static ULONG expected_seconds = 0xd64bd85b; +static ULONG expected_milliseconds = 0x88; +static ULONG tolerance_milliseconds = 200; + +extern void _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Set up client thread and network resources. */ + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD sntp_client_thread; +static NX_SNTP_CLIENT sntp_client; + + +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,168,126,42) +#define SERVER_IP_ADDRESS IP_ADDRESS(192,168,126,130) +#define SERVER_IP_ADDRESS_2 SERVER_IP_ADDRESS + +/* Set up the SNTP network and address index; */ +static UINT iface_index; + +static UINT error_counter; + +/* Set up client thread entry point. */ +static void sntp_client_thread_entry(ULONG info); + +static void inject_sntp_server_reply(); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_packet_chain_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + error_counter = 0; + + free_memory_pointer = (UCHAR *)first_unused_memory; + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "SNTP Client Packet Pool", + NX_SNTP_CLIENT_PACKET_SIZE, free_memory_pointer, + NX_SNTP_CLIENT_PACKET_POOL_SIZE); + free_memory_pointer = free_memory_pointer + NX_SNTP_CLIENT_PACKET_POOL_SIZE; + + /* Check for errors. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create Client IP instances */ + status = nx_ip_create(&client_ip, "SNTP IP Instance", CLIENT_IP_ADDRESS, + 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1500, + free_memory_pointer, 2048, 1); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory. */ + status = nx_arp_enable(&client_ip, (void **) free_memory_pointer, 2048); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + + /* Enable UDP for client. */ + status = nx_udp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create the client thread */ + status = tx_thread_create(&sntp_client_thread, "SNTP Client Thread", sntp_client_thread_entry, + (ULONG)(&sntp_client), free_memory_pointer, 2048, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for errors */ + if (status != TX_SUCCESS) + error_counter++; + + /* set the SNTP network interface to the primary interface. */ + iface_index = 0; + + /* Create the SNTP Client to run in broadcast mode.. */ + status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool, + NX_NULL, + NX_NULL, + NX_NULL /* no random_number_generator callback */); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_resume(&sntp_client_thread); + + return; +} + +/* Define size of buffer to display client's local time. */ +#define BUFSIZE 50 + +/* Define the client thread. */ +void sntp_client_thread_entry(ULONG info) +{ + +UINT status; +UINT spin; +UINT server_status; +CHAR buffer[BUFSIZE]; +ULONG base_seconds; +ULONG base_fraction; +ULONG seconds, milliseconds, microseconds, fraction; +ULONG expected_fraction; +NX_PACKET *packet_ptr; + + printf("NetX Test: NETX SNTP Client Packet Chain Test........................"); + + status = nx_sntp_client_delete(&sntp_client); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create the SNTP Client to run in broadcast mode.. */ + status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool, + NX_NULL, + NX_NULL, + NX_NULL /* no random_number_generator callback */); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Give other threads (IP instance) a chance to initialize. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Use the IPv4 service to initialize the Client and set the IPv4 SNTP server. */ + status = nx_sntp_client_initialize_unicast(&sntp_client, SERVER_IP_ADDRESS); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Set the base time which is approximately the number of seconds since the turn of the last century. */ + base_seconds = 0xd2c96b90; /* Jan 24, 2012 UTC */ + base_fraction = 0xa132db1e; + + /* Apply to the SNTP Client local time. */ + status = nx_sntp_client_set_local_time(&sntp_client, base_seconds, base_fraction); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_run_unicast(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + inject_sntp_server_reply(); + + spin = NX_TRUE; + + /* Now check periodically for time changes. */ + while(spin) + { + + /* First verify we have a valid SNTP service running. */ + status = nx_sntp_client_receiving_updates(&sntp_client, &server_status); + + if ((status == NX_SUCCESS) && (server_status == NX_TRUE)) + { + + /* Server status is good. Now get the Client local time. */ + + /* Display the local time in years, months, date format. */ + status = nx_sntp_client_get_local_time(&sntp_client, &seconds, &fraction, &buffer[0]); + + /* Convert fraction to microseconds. */ + nx_sntp_client_utility_fraction_to_usecs(fraction, µseconds); + + milliseconds = ((microseconds + 500) / 1000); + + if (status == NX_SUCCESS) + { + if ((seconds == expected_seconds) && ((INT)milliseconds > (INT)(expected_milliseconds - tolerance_milliseconds)) && + (milliseconds < (expected_milliseconds + tolerance_milliseconds))) + { + + /* Get extended local time. */ + status = nx_sntp_client_get_local_time_extended(&sntp_client, &seconds, &fraction, &buffer[0], sizeof(buffer)); + if (status == NX_SUCCESS) + { + + /* Convert fraction to microseconds. */ + nx_sntp_client_utility_fraction_to_usecs(fraction, µseconds); + + /* Compare microseconds with milliseconds. */ + if (((microseconds + 500) / 1000) != milliseconds) + { + error_counter++; + } + + /* Convert microseconds to fraction. */ + nx_sntp_client_utility_usecs_to_fraction(microseconds, &expected_fraction); + + /* Compare expected_fraction with fraction. */ + if (expected_fraction != fraction) + { + error_counter++; + } + } + else + { + error_counter++; + } + break; + } + else + { + error_counter++; + break; + } + } + + } + else + { + + /* Wait a short bit to check again. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + } + } + + /* We can stop the SNTP service if for example we think the SNTP service has stopped. */ + status = nx_sntp_client_stop(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_delete(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + /* Make sure the packet pool is not corrupted. */ + while (client_packet_pool.nx_packet_pool_available) + { + if (nx_packet_allocate(&client_packet_pool, &packet_ptr, 0, NX_NO_WAIT) || + (packet_ptr -> nx_packet_pool_owner != &client_packet_pool)) + { + + error_counter++; + break; + } + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + + +void inject_sntp_server_reply() +{ + +UINT status; +NX_PACKET *my_packet; + + /* First, fill data in packet chain by setting the offset of header to the end of packet. */ + /* Now, this packet is a received one, allocate the packet and let the IP stack receives it. */ + /* Allocate a packet. */ + status = nx_packet_allocate(&client_packet_pool, &my_packet, + client_packet_pool.nx_packet_pool_payload_size - 28, /* 20 (IPv4) + UDP (8)*/ + 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + if (nx_packet_data_append(my_packet, pkt_data + 14, pkt_size - 14, + &client_packet_pool, 5 * NX_IP_PERIODIC_RATE)) + { + error_counter++; + return; + } + + _nx_ip_packet_deferred_receive(&client_ip, my_packet); + + + /* Now, this packet is a received one, allocate the packet and let the IP stack receives it. */ + /* Allocate a packet. */ + status = nx_packet_allocate(client_ip.nx_ip_default_packet_pool, &my_packet, 0, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + my_packet -> nx_packet_length = pkt_size - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + + _nx_ip_packet_deferred_receive(&client_ip, my_packet); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_packet_chain_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NETX SNTP Client Packet Chain Test........................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/sntp_test/netx_sntp_client_seconds_to_date_test.c b/test/regression/sntp_test/netx_sntp_client_seconds_to_date_test.c new file mode 100644 index 00000000..e40d20eb --- /dev/null +++ b/test/regression/sntp_test/netx_sntp_client_seconds_to_date_test.c @@ -0,0 +1,130 @@ +#include +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_sntp_client.h" +#else +#include "nx_sntp_client.h" +#endif + +extern void test_control_return(UINT status); + +#ifdef __linux__ +#define LOOP 1000 +#define NTP_UTC_DIFF 2208988800 +#define START_YEAR 2015 +#define START_UTC 1420075385 +#define SECONDS_TEN_YEARS 315360000 + + +extern UINT _nx_sntp_client_utility_convert_seconds_to_date(NX_SNTP_TIME *current_NTP_time_ptr, + UINT current_year, + NX_SNTP_DATE_TIME *current_date_time_ptr); +static TX_THREAD sntp_client_thread; + +static UINT error_counter; + +/* Set up client thread entry point. */ +static void sntp_client_thread_entry(ULONG info); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_seconds_to_date_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + error_counter = 0; + + free_memory_pointer = (UCHAR *)first_unused_memory; + + /* Create the client thread */ + status = tx_thread_create(&sntp_client_thread, "SNTP Client Thread", sntp_client_thread_entry, + NX_NULL, free_memory_pointer, 2048, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for errors */ + if (status != TX_SUCCESS) + error_counter++; +} + + +/* Define the client thread. */ +void sntp_client_thread_entry(ULONG info) +{ + +UINT status; +UINT i; +NX_SNTP_TIME sntp_time; +NX_SNTP_DATE_TIME date_time; +time_t utc; +struct tm *tm_value; + + printf("NetX Test: NETX SNTP Client Seconds To Date Test....................."); + + srand(time(0)); + sntp_time.fraction = 0; + for (i = 0; i < LOOP; i++) + { + if (i == 0) + { + sntp_time.seconds = 3818415600; /* Bug verification. */ + utc = sntp_time.seconds - NTP_UTC_DIFF; + } + else + { + utc = (rand() % SECONDS_TEN_YEARS) + START_UTC; + sntp_time.seconds = NTP_UTC_DIFF + utc; + } + + /* Convert time by by gmtime and SNTP utility. */ + tm_value = gmtime(&utc); + _nx_sntp_client_utility_convert_seconds_to_date(&sntp_time, + START_YEAR, + &date_time); + + /* Compare result. */ + if (((tm_value -> tm_year + 1900) != date_time.year) || + ((tm_value -> tm_mon + 1) != date_time.month) || + (tm_value -> tm_mday != date_time.day) || + (tm_value -> tm_hour != date_time.hour) || + (tm_value -> tm_min != date_time.minute) || + (tm_value -> tm_sec != date_time.second) || + (date_time.millisecond != 0)) + { + error_counter++; + break; + } + } + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_seconds_to_date_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NETX SNTP Client Seconds To Date Test.....................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/sntp_test/netx_sntp_client_unicast_basic_test.c b/test/regression/sntp_test/netx_sntp_client_unicast_basic_test.c new file mode 100644 index 00000000..d3b08f0d --- /dev/null +++ b/test/regression/sntp_test/netx_sntp_client_unicast_basic_test.c @@ -0,0 +1,355 @@ +#include "nx_api.h" +#include "nx_ip.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_sntp_client.h" +#else +#include "nx_sntp_client.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define SNTP packet size. */ +#define NX_SNTP_CLIENT_PACKET_SIZE (NX_UDP_PACKET + 100) + +/* Define SNTP packet pool size. */ +#define NX_SNTP_CLIENT_PACKET_POOL_SIZE (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET))) + +/* NTP server reply. */ +static char pkt_data[90] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x00, 0x0c, + 0x29, 0x1e, 0xaa, 0x4f, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, + 0xbc, 0xa3, 0xc0, 0xa8, 0x7e, 0x82, 0xc0, 0xa8, + 0x7e, 0x2a, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, + 0x7f, 0xa0, 0x1c, 0x02, 0x00, 0xec, 0x00, 0x00, + 0x07, 0xdd, 0x00, 0x00, 0x06, 0x6e, 0x89, 0xbd, + 0x04, 0x0a, 0xd6, 0x4b, 0xd7, 0xeb, 0xb3, 0x25, + 0xe0, 0x52, 0xd2, 0xc9, 0x6b, 0x90, 0xa1, 0x32, + 0xdb, 0x1e, 0xd6, 0x4b, 0xd8, 0x5b, 0x20, 0x27, + 0x62, 0xa4, 0xd6, 0x4b, 0xd8, 0x5b, 0x20, 0x2c, + 0x4b, 0x46 }; + +static UINT pkt_size = 90; + +static ULONG expected_seconds = 0xd64bd85b; +static ULONG expected_milliseconds = 0x88; +static ULONG tolerance_milliseconds = 200; + +extern void _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Set up client thread and network resources. */ + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD sntp_client_thread; +static NX_SNTP_CLIENT sntp_client; + + +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,168,126,42) +#define SERVER_IP_ADDRESS IP_ADDRESS(192,168,126,130) +#define SERVER_IP_ADDRESS_2 SERVER_IP_ADDRESS + +/* Set up the SNTP network and address index; */ +static UINT iface_index; + +static UINT error_counter; + +/* Set up client thread entry point. */ +static void sntp_client_thread_entry(ULONG info); + +static void inject_sntp_server_reply(); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_unicast_basic_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + error_counter = 0; + + free_memory_pointer = (UCHAR *)first_unused_memory; + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "SNTP Client Packet Pool", + NX_SNTP_CLIENT_PACKET_SIZE, free_memory_pointer, + NX_SNTP_CLIENT_PACKET_POOL_SIZE); + free_memory_pointer = free_memory_pointer + NX_SNTP_CLIENT_PACKET_POOL_SIZE; + + /* Check for errors. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create Client IP instances */ + status = nx_ip_create(&client_ip, "SNTP IP Instance", CLIENT_IP_ADDRESS, + 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1500, + free_memory_pointer, 2048, 1); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory. */ + status = nx_arp_enable(&client_ip, (void **) free_memory_pointer, 2048); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + + /* Enable UDP for client. */ + status = nx_udp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create the client thread */ + status = tx_thread_create(&sntp_client_thread, "SNTP Client Thread", sntp_client_thread_entry, + (ULONG)(&sntp_client), free_memory_pointer, 2048, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for errors */ + if (status != TX_SUCCESS) + error_counter++; + + /* set the SNTP network interface to the primary interface. */ + iface_index = 0; + + /* Create the SNTP Client to run in broadcast mode.. */ + status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool, + NX_NULL, + NX_NULL, + NX_NULL /* no random_number_generator callback */); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_resume(&sntp_client_thread); + + return; +} + +/* Define size of buffer to display client's local time. */ +#define BUFSIZE 50 + +/* Define the client thread. */ +void sntp_client_thread_entry(ULONG info) +{ + +UINT status; +UINT spin; +UINT server_status; +CHAR buffer[BUFSIZE]; +ULONG base_seconds; +ULONG base_fraction; +ULONG seconds, milliseconds, microseconds, fraction; +ULONG expected_fraction; + + printf("NetX Test: NETX SNTP Client Unicast Basic Test......................."); + + status = nx_sntp_client_delete(&sntp_client); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create the SNTP Client to run in broadcast mode.. */ + status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool, + NX_NULL, + NX_NULL, + NX_NULL /* no random_number_generator callback */); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Give other threads (IP instance) a chance to initialize. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Use the IPv4 service to initialize the Client and set the IPv4 SNTP server. */ + status = nx_sntp_client_initialize_unicast(&sntp_client, SERVER_IP_ADDRESS); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Set the base time which is approximately the number of seconds since the turn of the last century. */ + base_seconds = 0xd2c96b90; /* Jan 24, 2012 UTC */ + base_fraction = 0xa132db1e; + + /* Apply to the SNTP Client local time. */ + status = nx_sntp_client_set_local_time(&sntp_client, base_seconds, base_fraction); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_run_unicast(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + inject_sntp_server_reply(); + + spin = NX_TRUE; + + /* Now check periodically for time changes. */ + while(spin) + { + + /* First verify we have a valid SNTP service running. */ + status = nx_sntp_client_receiving_updates(&sntp_client, &server_status); + + if ((status == NX_SUCCESS) && (server_status == NX_TRUE)) + { + + /* Server status is good. Now get the Client local time. */ + + /* Display the local time in years, months, date format. */ + status = nx_sntp_client_get_local_time(&sntp_client, &seconds, &fraction, &buffer[0]); + + /* Convert fraction to microseconds. */ + nx_sntp_client_utility_fraction_to_usecs(fraction, µseconds); + + milliseconds = ((microseconds + 500) / 1000); + + if (status == NX_SUCCESS) + { + if ((seconds == expected_seconds) && ((INT)milliseconds > (INT)(expected_milliseconds - tolerance_milliseconds)) && + (milliseconds < (expected_milliseconds + tolerance_milliseconds))) + { + + /* Get extended local time. */ + status = nx_sntp_client_get_local_time_extended(&sntp_client, &seconds, &fraction, &buffer[0], sizeof(buffer)); + if (status == NX_SUCCESS) + { + + /* Convert fraction to microseconds. */ + nx_sntp_client_utility_fraction_to_usecs(fraction, µseconds); + + /* Compare microseconds with milliseconds. */ + if (((microseconds + 500) / 1000) != milliseconds) + { + error_counter++; + } + + /* Convert microseconds to fraction. */ + nx_sntp_client_utility_usecs_to_fraction(microseconds, &expected_fraction); + + /* Compare expected_fraction with fraction. */ + if (expected_fraction != fraction) + { + error_counter++; + } + } + else + { + error_counter++; + } + break; + } + else + { + error_counter++; + break; + } + } + + } + else + { + + /* Wait a short bit to check again. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + } + } + + /* We can stop the SNTP service if for example we think the SNTP service has stopped. */ + status = nx_sntp_client_stop(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_delete(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + + +void inject_sntp_server_reply() +{ + +UINT status; +NX_PACKET *my_packet; + + /* Now, this packet is a received one, allocate the packet and let the IP stack receives it. */ + /* Allocate a packet. */ + status = nx_packet_allocate(client_ip.nx_ip_default_packet_pool, &my_packet, 0, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + my_packet -> nx_packet_length = pkt_size - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + + _nx_ip_packet_deferred_receive(&client_ip, my_packet); + +} +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_unicast_basic_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NETX SNTP Client Unicast Basic Test.......................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/sntp_test/netx_sntp_client_unicast_display_date_test.c b/test/regression/sntp_test/netx_sntp_client_unicast_display_date_test.c new file mode 100644 index 00000000..16b44e1d --- /dev/null +++ b/test/regression/sntp_test/netx_sntp_client_unicast_display_date_test.c @@ -0,0 +1,361 @@ +#include "nx_api.h" +#include "nx_ip.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_sntp_client.h" +#else +#include "nx_sntp_client.h" +#endif + +extern void test_control_return(UINT status); +#if !defined(NX_DISABLE_IPV4) +/* Define SNTP packet size. */ +#define NX_SNTP_CLIENT_PACKET_SIZE (NX_UDP_PACKET + 100) + +/* Define SNTP packet pool size. */ +#define NX_SNTP_CLIENT_PACKET_POOL_SIZE (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET))) + +/* NTP server reply. */ +static char pkt_data[90] = { + + /* Ethernet header */ + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x00, 0x0c, + 0x29, 0x1e, 0xaa, 0x4f, 0x08, 0x00, + + /* IP layer */ + 0x45, 0x00, 0x00, 0x4c, + 0x00, 0x00, 0x40, 0x00, + 0x40, 0x11, 0xbc, 0xa3, + 0xc0, 0xa8, 0x7e, 0x82, + 0xc0, 0xa8, 0x7e, 0x2a, + + /* UDP header */ + 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, 0x28, 0x3f, + + /* SNTP data */ + 0x1c, // flags was 28 which= server mode 4 and version 3 + 0x2, // stratum + 0x3, // poll interval + 0xf9, // clock precision + 0x0, 0x0,0x4,0x23, // root delay + 0x0, 0x0,0x8,0xf3, // root dispersion + 0x82,0x95,0x11,0x8, // ref ID + + /* for March 30, 2017, 16:14:23.665 */ + 0xdc,0x87,0xab,0xc1, 0x16,0xe4,0xbc,0x59, // ref timestamp + + 0xdc,0x87,0xad,0x5f, 0xa7,0x00,0x68,0x0, // origin timestamp + + 0xdc,0x87,0xad,0x5f, 0xa7,0xc9,0xfd,0x90, // receive timestamp + + 0xdc,0x87,0xad,0x5f, 0xa7,0xcc,0x42,0x36 +}; + +static UINT pkt_size = 90; + + +extern void _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Set up client thread and network resources. */ + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD sntp_client_thread; +static NX_SNTP_CLIENT sntp_client; + + +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,168,126,42) +#define SERVER_IP_ADDRESS IP_ADDRESS(192,168,126,130) +#define SERVER_IP_ADDRESS_2 SERVER_IP_ADDRESS + +/* Set up the SNTP network and address index; */ +static UINT iface_index; + +static UINT error_counter; + +/* Set up client thread entry point. */ +static void sntp_client_thread_entry(ULONG info); + +static void inject_sntp_server_reply(); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_unicast_display_date_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + error_counter = 0; + + free_memory_pointer = (UCHAR *)first_unused_memory; + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "SNTP Client Packet Pool", + NX_SNTP_CLIENT_PACKET_SIZE, free_memory_pointer, + NX_SNTP_CLIENT_PACKET_POOL_SIZE); + free_memory_pointer = free_memory_pointer + NX_SNTP_CLIENT_PACKET_POOL_SIZE; + + /* Check for errors. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create Client IP instances */ + status = nx_ip_create(&client_ip, "SNTP IP Instance", CLIENT_IP_ADDRESS, + 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1500, + free_memory_pointer, 2048, 1); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory. */ + status = nx_arp_enable(&client_ip, (void **) free_memory_pointer, 2048); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + + /* Enable UDP for client. */ + status = nx_udp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Create the client thread */ + status = tx_thread_create(&sntp_client_thread, "SNTP Client Thread", sntp_client_thread_entry, + (ULONG)(&sntp_client), free_memory_pointer, 2048, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for errors */ + if (status != TX_SUCCESS) + error_counter++; + + /* set the SNTP network interface to the primary interface. */ + iface_index = 0; + + /* Create the SNTP Client to run in broadcast mode.. */ + status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool, + NX_NULL, + NX_NULL, + NX_NULL /* no random_number_generator callback */); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_resume(&sntp_client_thread); + + return; +} + +/* Define size of buffer to display client's local time. */ +#define BUFSIZE 50 + +/* If 1000 ticks per second, the precision should be 1ms. */ +#if (NX_IP_PERIODIC_RATE == 1000) +#define EXPECTED_DATE0 "Mar 30, 2017 16:14:23.655 UTC " +#define EXPECTED_DATE1 "Mar 30, 2017 16:14:23.656 UTC " +#define EXPECTED_DATE2 "Mar 30, 2017 16:14:23.657 UTC " +#define EXPECTED_DATE3 "Mar 30, 2017 16:14:23.658 UTC " +#define EXPECTED_DATE4 "Mar 30, 2017 16:14:23.659 UTC " +#define EXPECTED_DATE5 "Mar 30, 2017 16:14:23.660 UTC " +#define EXPECTED_DATE6 "Mar 30, 2017 16:14:23.661 UTC " +#else +#define EXPECTED_DATE0 "Mar 30, 2017 16:14:23.655 UTC " +#define EXPECTED_DATE1 "Mar 30, 2017 16:14:23.665 UTC " +#define EXPECTED_DATE2 "Mar 30, 2017 16:14:23.675 UTC " +#define EXPECTED_DATE3 "Mar 30, 2017 16:14:23.685 UTC " +#define EXPECTED_DATE4 "Mar 30, 2017 16:14:23.695 UTC " +#define EXPECTED_DATE5 "Mar 30, 2017 16:14:23.705 UTC " +#define EXPECTED_DATE6 "Mar 30, 2017 16:14:23.715 UTC " +#endif + +/* Define the client thread. */ +void sntp_client_thread_entry(ULONG info) +{ + +UINT status; +UINT server_status; +CHAR buffer[BUFSIZE]; +ULONG base_seconds; +ULONG base_fraction; +ULONG seconds, milliseconds; +UINT loops; +UINT display_done = NX_FALSE; + + + printf("NetX Test: NETX SNTP Client Unicast Display Date Test................"); + + /* Give other threads (IP instance) a chance to initialize. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + + /* Use the IPv4 service to initialize the Client and set the IPv4 SNTP server. */ + status = nx_sntp_client_initialize_unicast(&sntp_client, SERVER_IP_ADDRESS); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Set the base time which is quite old but should suffice. */ + base_seconds = 0xd2c96b90; /* Jan 24, 2012 UTC */ + base_fraction = 0xa132db1e; + + + /* Apply to the SNTP Client local time. */ + status = nx_sntp_client_set_local_time(&sntp_client, base_seconds, base_fraction); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_run_unicast(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + inject_sntp_server_reply(); + loops = 0; + do + { + + /* First verify we have a valid SNTP service running. */ + status = nx_sntp_client_receiving_updates(&sntp_client, &server_status); + + if ((status == NX_SUCCESS) && (server_status == NX_TRUE)) + { + + /* Server status is good. Now get the Client local time. */ + + /* Display the local time in years, months, date format. */ + status = nx_sntp_client_get_local_time(&sntp_client, &seconds, &milliseconds, &buffer[0]); + + if (status == NX_SUCCESS) + { + + status = nx_sntp_client_utility_display_date_time(&sntp_client, &buffer[0], BUFSIZE); + + if (status != NX_SUCCESS) + { + error_counter++; + } + else + { + if (!memcmp(&buffer[0], EXPECTED_DATE0, strlen(EXPECTED_DATE0)) || + !memcmp(&buffer[0], EXPECTED_DATE1, strlen(EXPECTED_DATE0)) || + !memcmp(&buffer[0], EXPECTED_DATE2, strlen(EXPECTED_DATE0)) || + !memcmp(&buffer[0], EXPECTED_DATE3, strlen(EXPECTED_DATE0)) || + !memcmp(&buffer[0], EXPECTED_DATE4, strlen(EXPECTED_DATE0)) || + !memcmp(&buffer[0], EXPECTED_DATE5, strlen(EXPECTED_DATE0)) || + !memcmp(&buffer[0], EXPECTED_DATE6, strlen(EXPECTED_DATE0))) + { + + display_done = NX_TRUE; + break; + } + else + { +printf("date: %s.\n", buffer); + error_counter++; + } + } + } + + } + else + { + + /* Wait a short bit to check again. */ + tx_thread_sleep(1 * NX_IP_PERIODIC_RATE); + } + + loops++; + + } while((loops < 4) && (display_done == NX_FALSE)); + + /* We can stop the SNTP service if for example we think the SNTP service has stopped. */ + status = nx_sntp_client_stop(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + status = nx_sntp_client_delete(&sntp_client); + + if (status != NX_SUCCESS) + error_counter++; + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + + +void inject_sntp_server_reply() +{ + +UINT status; +NX_PACKET *my_packet; + + /* Now, this packet is a received one, allocate the packet and let the IP stack receives it. */ + /* Allocate a packet. */ + status = nx_packet_allocate(client_ip.nx_ip_default_packet_pool, &my_packet, 0, 5 * NX_IP_PERIODIC_RATE); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + my_packet -> nx_packet_length = pkt_size - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + + _nx_ip_packet_deferred_receive(&client_ip, my_packet); + +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_client_unicast_display_date_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NETX SNTP Client Unicast Display Date Test................N/A\n"); + + test_control_return(3); +} +#endif diff --git a/test/regression/sntp_test/netx_sntp_forward_unicast_update_test.c b/test/regression/sntp_test/netx_sntp_forward_unicast_update_test.c new file mode 100644 index 00000000..16582cf2 --- /dev/null +++ b/test/regression/sntp_test/netx_sntp_forward_unicast_update_test.c @@ -0,0 +1,322 @@ +/* + netx_sntp_forward_unicast_update_test.c + + This demonstrates the time update notify feature in NetX SNTP Client. The Client + connects to the SNTP server in unicast mode (simulated server) and sends a unicast + request. If a valid reply is received, the time update notify callback should be called + for a successful completion. + + */ + + +#include +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_sntp_client.h" +#else +#include "nx_sntp_client.h" +#endif + +extern void test_control_return(UINT result); + +#if !defined(NX_DISABLE_IPV4) + +/* Define SNTP packet size. */ +#define NX_SNTP_CLIENT_PACKET_SIZE (NX_UDP_PACKET + 100) + +/* Define SNTP packet pool size. */ +#define NX_SNTP_CLIENT_PACKET_POOL_SIZE (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET))) + +/* Set up generic network driver for demo program. */ +void _nx_ram_network_driver(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Application defined services of the NetX SNTP Client. */ + +UINT leap_second_handler(NX_SNTP_CLIENT *client_ptr, UINT leap_indicator); +VOID client_time_update_notify(NX_SNTP_TIME_MESSAGE *time_update_ptr, NX_SNTP_TIME *local_time); +static void inject_sntp_server_reply(char *pkt_data, UINT size); + +static UINT time_updates_received = 0; +static UINT error_counter = 0; + + +/* Set up client thread and network resources. */ + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD demo_client_thread; +static NX_SNTP_CLIENT demo_client; + +/* NTP server reply. */ +static char broadcast_data_1[90] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x00, 0x0c, + 0x29, 0x1e, 0xaa, 0x4f, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, + 0xbc, 0xa3, 0xc0, 0xa8, 0x7e, 0x82, 0xc0, 0xa8, + 0x7e, 0x2a, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, + 0x7f, 0xa0, 0x1c, 0x02, 0x00, 0xec, 0x00, 0x00, + 0x07, 0xdd, 0x00, 0x00, 0x06, 0x6e, + 0x89, 0xbd, 0x04, 0x0a, + 0xd6, 0x4b, 0xd7, 0xeb, + 0xb3, 0x25, 0xe0, 0x52, + 0xd2, 0xc9, 0x6b, 0x90, + 0xa1, 0x32, 0xdb, 0x1e, + 0xd6, 0x4b, 0xd8, 0x5b, + 0x20, 0x27, 0x62, 0xa4, + 0xd6, 0x4b, 0xd8, 0x5b, + 0x20, 0x2c, 0x4b, 0x46 + }; + + +static UINT pkt1_size = 90; + + + +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,168,126,42) +#define SERVER_IP_ADDRESS IP_ADDRESS(192,168,126,130) + + +/* Set up client thread entry point. */ +void demo_client_thread_entry(ULONG info); + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_forward_unicast_update_test_application_define(void *first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + + free_memory_pointer = (UCHAR *)first_unused_memory; + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "SNTP Client Packet Pool", + NX_SNTP_CLIENT_PACKET_SIZE, free_memory_pointer, + NX_SNTP_CLIENT_PACKET_POOL_SIZE); + + /* Check for errors. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + NX_SNTP_CLIENT_PACKET_POOL_SIZE; + + /* Create Client IP instances */ + status = nx_ip_create(&client_ip, "SNTP IP Instance", CLIENT_IP_ADDRESS, + 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver, //_nx_ram_network_driver, + free_memory_pointer, 2048, 1); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + free_memory_pointer = free_memory_pointer + 2048; + + /* Enable ARP and supply ARP cache memory. */ + status = nx_arp_enable(&client_ip, (void **) free_memory_pointer, 2048); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 2048; + + /* Enable UDP for client. */ + status = nx_udp_enable(&client_ip); + status |= nx_icmp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + /* Create the client thread */ + status = tx_thread_create(&demo_client_thread, "SNTP Client Thread", demo_client_thread_entry, + (ULONG)(&demo_client), free_memory_pointer, 2048, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + + /* Check for errors */ + if (status != TX_SUCCESS) + { + + error_counter++; + } + + /* Update pointer to unallocated (free) memory. */ + free_memory_pointer = free_memory_pointer + 2048; + + /* Create the SNTP Client to run in broadcast mode.. */ + status = nx_sntp_client_create(&demo_client, &client_ip, 0, &client_packet_pool, + leap_second_handler, + NULL,/* no kiss of death handler */ + NULL /* no random_number_generator callback */); + + /* Check for error. */ + if (status != NX_SUCCESS) + { + + error_counter++; + } + + tx_thread_resume(&demo_client_thread); + + return; +} + + +/* Define the client thread. */ +void demo_client_thread_entry(ULONG info) +{ + +UINT status; + + + printf("NetX Test: NETX SNTP Client Time Update Notify Test.................."); + + if (error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give other threads (IP instance) a chance to initialize. */ + tx_thread_sleep(20); + + status = nx_sntp_client_set_time_update_notify(&demo_client, client_time_update_notify); + + if (status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Set up client time updates. */ + + /* Initialize the Client for unicast mode to poll the SNTP server once an hour. */ + /* Use the IPv4 service to set up the Client and set the IPv4 SNTP server. */ + status = nx_sntp_client_initialize_unicast(&demo_client, SERVER_IP_ADDRESS); + + + /* Check for error. */ + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_sntp_client_run_unicast(&demo_client); + + if (status != NX_SUCCESS) + { + + printf("ERROR!\n"); + test_control_return(1); + } + + /* Receive the server response. */ + inject_sntp_server_reply(broadcast_data_1, pkt1_size); + + tx_thread_sleep(100); + + /* To return resources to NetX and ThreadX stop the SNTP client and delete the client instance. */ + status = nx_sntp_client_delete(&demo_client); + + if (status != NX_SUCCESS) + { + printf("ERROR!\n"); + test_control_return(1); + } + + if (error_counter || (time_updates_received != 1)) + { + printf("ERROR!\n"); + test_control_return(1); + } + + + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* This application defined handler for handling an impending leap second is not + required by the SNTP Client. The default handler below only logs the event for + every time stamp received with the leap indicator set. */ + +UINT leap_second_handler(NX_SNTP_CLIENT *client_ptr, UINT leap_indicator) +{ + + /* Handle the leap second handler... */ + + return NX_SUCCESS; +} + +void inject_sntp_server_reply(char *pkt_data, UINT size) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Allocate the packet and let the client IP stack receive it. */ + status = nx_packet_allocate(client_ip.nx_ip_default_packet_pool, &my_packet, 0, 500); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Load the data simulating the server reply */ + my_packet -> nx_packet_length = size - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + + /* Send to the Client stack*/ + _nx_ip_packet_deferred_receive(&client_ip, my_packet); + +} + +VOID client_time_update_notify(NX_SNTP_TIME_MESSAGE *time_update_ptr, NX_SNTP_TIME *local_time) +{ + + time_updates_received++; + return; +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_forward_unicast_update_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NETX SNTP Client Time Update Notify Test..................N/A\n"); + + test_control_return(3); +} +#endif \ No newline at end of file diff --git a/test/regression/sntp_test/netx_sntp_request_unicast_test.c b/test/regression/sntp_test/netx_sntp_request_unicast_test.c new file mode 100644 index 00000000..083299a9 --- /dev/null +++ b/test/regression/sntp_test/netx_sntp_request_unicast_test.c @@ -0,0 +1,419 @@ +/* + netx_sntp_request_unicast_rest.c + + This test tests that the nx_sntp_client_request_unicast_time service sends an asynchronous unicast + SNTP request independently of the SNTP CLient periodic polling of the SNTP server. It also verifies + that the SNTP Client when it receives the server response correctly updates the local clock. + + Note that for this test to work correctly, the following configuration option must be defined in the + preprocessor options: + + #define NX_SNTP_CLIENT_MIN_TIME_ADJUSTMENT 1000 +*/ + +#include "nx_api.h" +#include "nx_ip.h" +#include +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_sntp_client.h" +#else +#include "nx_sntp_client.h" +#endif + +extern void test_control_return(UINT status); + +#if !defined(NX_DISABLE_IPV4) + +/* Define SNTP packet size. */ +#define NX_SNTP_CLIENT_PACKET_SIZE (NX_UDP_PACKET + 100) + +/* Define SNTP packet pool size. */ +#ifdef __PRODUCT_NETXDUO__ +#define NX_SNTP_CLIENT_PACKET_POOL_SIZE (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET) + NX_PACKET_ALIGNMENT)) +#else +#define NX_SNTP_CLIENT_PACKET_POOL_SIZE (4 * (NX_SNTP_CLIENT_PACKET_SIZE + sizeof(NX_PACKET))) +#endif + +/* NTP server reply. */ +static char pkt_data[90] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x00, 0x0c, + 0x29, 0x1e, 0xaa, 0x4f, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, + 0xbc, 0xa3, 0xc0, 0xa8, 0x7e, 0x82, 0xc0, 0xa8, + 0x7e, 0x2a, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, + /* checksum*/ + 0x7f, 0xa0, +/* start of NTP word */ + /* stratum*//* peer_clock_precision*/ + 0x1c, 0x02, 0x00, 0xec, + /* root delay*/ + 0x00, 0x00, 0x07, 0xdd, + /* clock dispersion */ + 0x00, 0x00, 0x06, 0x6e, + 0x89, 0xbd, 0x04, 0x0a, + 0xd6, 0x4b, 0xd7, 0xeb, + 0xb3, 0x25, 0xe0, 0x52, + 0xd2, 0xc9, 0x6b, 0x90, + 0xa1, 0x32, 0xdb, 0x1e, + 0xd6, 0x4b, 0xd8, 0x5b, + 0x20, 0x27, 0x62, 0xa4, + /* seconds */ + 0xd6, 0x4b, 0xd8, 0x5b, + /* fraction */ + 0x20, 0x2c, 0x4b, 0x46 }; + +static UINT pkt_size = 90; + + +static char pkt_data_asynch[90] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x57, 0x00, 0x0c, + 0x29, 0x1e, 0xaa, 0x4f, 0x08, 0x00, 0x45, 0x00, + 0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11, + 0xbc, 0xa3, 0xc0, 0xa8, 0x7e, 0x82, 0xc0, 0xa8, + 0x7e, 0x2a, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x38, + /* checksum*/ + 0x7f, 0x9f, + /* stratum*//* peer_clock_precision*/ + 0x1c, 0x02, 0x00, 0xec, + /* root delay*/ + 0x00, 0x00, 0x07, 0xdd, + /* clock dispersion */ + 0x00, 0x00, 0x06, 0x6e, + 0x89, 0xbd, 0x04, 0x0a, + 0xd6, 0x4b, 0xd7, 0xeb, + 0xb3, 0x25, 0xe0, 0x52, + 0xd2, 0xc9, 0x6b, 0x90, + 0xa1, 0x32, 0xdb, 0x1e, + 0xd6, 0x4b, 0xd8, 0x5b, + 0x20, 0x27, 0x62, 0xa4, + /* seconds */ + 0xd6, 0x4b, 0xd8, 0x5c, + /* fraction */ + 0x20, 0x2c, 0x4b, 0x46 +}; + +static UINT pkt_size_asynch = 90; + + +static ULONG expected_seconds_asynch = 0xd64bd85c; +static ULONG expected_milliseconds_asynch = 0x88; +static ULONG tolerance_milliseconds_asynch = 20; + +static UINT send_unicast = NX_FALSE; +static UINT asynch_unicast_processed = NX_FALSE; + +extern void _nx_ram_network_driver_1500(NX_IP_DRIVER *driver_req_ptr); + +/* Set up client thread and network resources. */ + +static NX_PACKET_POOL client_packet_pool; +static NX_IP client_ip; +static TX_THREAD sntp_client_thread; +static TX_THREAD sntp_server_thread; +static NX_SNTP_CLIENT sntp_client; +static NX_SNTP_CLIENT sntp_server; + +#define CLIENT_IP_ADDRESS IP_ADDRESS(192,168,126,42) +#define SERVER_IP_ADDRESS IP_ADDRESS(192,168,126,130) +#define SERVER_IP_ADDRESS_2 SERVER_IP_ADDRESS + +/* Set up the SNTP network and address index; */ +static UINT iface_index; + +static UINT error_counter; + +/* Set up client thread entry point. */ +static void sntp_client_thread_entry(ULONG info); +static void sntp_server_thread_entry(ULONG info); +static void inject_sntp_server_reply(char *pkt_data, UINT size); + + +/* Define what the initial system looks like. */ +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_request_unicast_test_application_define(void * first_unused_memory) +#endif +{ + +UINT status; +UCHAR *free_memory_pointer; + + error_counter = 0; + + free_memory_pointer = (UCHAR *)first_unused_memory; + + /* Create client packet pool. */ + status = nx_packet_pool_create(&client_packet_pool, "SNTP Client Packet Pool", + NX_SNTP_CLIENT_PACKET_SIZE, free_memory_pointer, + NX_SNTP_CLIENT_PACKET_POOL_SIZE); + free_memory_pointer = free_memory_pointer + NX_SNTP_CLIENT_PACKET_POOL_SIZE; + + /* Check for errors. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + /* Create Client IP instances */ + status = nx_ip_create(&client_ip, "SNTP IP Instance", CLIENT_IP_ADDRESS, + 0xFFFFFF00UL, &client_packet_pool, _nx_ram_network_driver_1500, + free_memory_pointer, 2048, 1); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + /* Enable ARP and supply ARP cache memory. */ + status = nx_arp_enable(&client_ip, (void **) free_memory_pointer, 2048); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + + /* Enable UDP for client. */ + status = nx_udp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + status = nx_icmp_enable(&client_ip); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + + /* Create the server thread */ + status = tx_thread_create(&sntp_server_thread, "SNTP Server Thread", sntp_server_thread_entry, + (ULONG)(&sntp_server), free_memory_pointer, 2048, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for errors */ + if (status != TX_SUCCESS) + error_counter++; + + /* Create the client thread */ + status = tx_thread_create(&sntp_client_thread, "SNTP Client Thread", sntp_client_thread_entry, + (ULONG)(&sntp_client), free_memory_pointer, 2048, + 4, 4, TX_NO_TIME_SLICE, TX_DONT_START); + free_memory_pointer = free_memory_pointer + 2048; + + /* Check for errors */ + if (status != TX_SUCCESS) + error_counter++; + + /* set the SNTP network interface to the primary interface. */ + iface_index = 0; + + /* Create the SNTP Client to run in broadcast mode.. */ + status = nx_sntp_client_create(&sntp_client, &client_ip, iface_index, &client_packet_pool, + NX_NULL, + NX_NULL, + NX_NULL /* no random_number_generator callback */); + + /* Check for error. */ + if (status != NX_SUCCESS) + error_counter++; + + tx_thread_resume(&sntp_client_thread); + + return; +} + +/* Define size of buffer to display client's local time. */ +#define BUFSIZE 50 + +/* Define the client thread. */ +void sntp_client_thread_entry(ULONG info) +{ + +UINT status; +UINT server_status; +CHAR buffer[BUFSIZE]; +ULONG base_seconds; +ULONG base_fraction; +ULONG seconds, milliseconds, microseconds, fraction; + + printf("NetX Test: NETX SNTP Client Request Unicast Test....................."); + + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + + /* Give other threads (IP instance) a chance to initialize. */ + tx_thread_sleep(100); + + /* Use the IPv4 service to initialize the Client and set the IPv4 SNTP server. */ + status = nx_sntp_client_initialize_unicast(&sntp_client, SERVER_IP_ADDRESS); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + /* Set the base time which is approximately the number of seconds since the turn of the last century. */ + base_seconds = 0xd2c96b90; /* Jan 24, 2012 UTC */ + base_fraction = 0xa132db1e; + + /* Apply to the SNTP Client local time. */ + status = nx_sntp_client_set_local_time(&sntp_client, base_seconds, base_fraction); + + /* Check for error. */ + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + status = nx_sntp_client_run_unicast(&sntp_client); + + if(status) + { + printf("ERROR!\n"); + test_control_return(1); + } + + inject_sntp_server_reply(&pkt_data[0], pkt_size); + + /* Set the 'server' thread to wait for next unicast request. */ + tx_thread_resume(&sntp_server_thread); + + do + { + + /* First verify we have a valid SNTP service running. */ + status = nx_sntp_client_receiving_updates(&sntp_client, &server_status); + + tx_thread_sleep(100); + + } while (status != NX_SUCCESS); + + /* Server status is good. */ + + /* Tell the server it's ok to 'respond'to next unicast request. */ + send_unicast = NX_TRUE; + + /* Request a unicast update independently of the SNTP Client thread - wait option 5 seconds. */ + status = nx_sntp_client_request_unicast_time(&sntp_client, 500); + + if (status == NX_SUCCESS) + { + + asynch_unicast_processed = NX_TRUE; + + status = nx_sntp_client_get_local_time(&sntp_client, &seconds, &fraction, &buffer[0]); + + /* Convert fraction to microseconds. */ + nx_sntp_client_utility_fraction_to_usecs(fraction, µseconds); + + milliseconds = ((microseconds + 500) / 1000); + + if (status) + { + + error_counter++; + } + else if ( + (seconds != expected_seconds_asynch) || + (milliseconds < (expected_milliseconds_asynch - tolerance_milliseconds_asynch)) || + (milliseconds > (expected_milliseconds_asynch + tolerance_milliseconds_asynch)) + ) + { + + error_counter++; + } + } + + nx_sntp_client_stop(&sntp_client); + + nx_sntp_client_delete(&sntp_client); + + if(error_counter) + { + printf("ERROR!\n"); + test_control_return(1); + } + else + { + printf("SUCCESS!\n"); + test_control_return(0); + } + + return; +} + +/* This should emulate a SNTP server. */ +void sntp_server_thread_entry(ULONG info) +{ + + + /* Wait for next unicast request (should be the asynchronous request). */ + while(!send_unicast) + tx_thread_sleep(10); + + /* Keep sending till the asynch unicast server message is processed. */ + while(!asynch_unicast_processed) + { + + inject_sntp_server_reply(&pkt_data_asynch[0], pkt_size_asynch); + tx_thread_sleep(10); + } +} + + +void inject_sntp_server_reply(char *pkt_data, UINT size) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Allocate the packet and let the client IP stack receive it. */ + status = nx_packet_allocate(client_ip.nx_ip_default_packet_pool, &my_packet, 0, 500); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + /* Load the data simulating the server reply */ + my_packet -> nx_packet_length = size - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + + /* Send to the Client stack*/ + _nx_ip_packet_deferred_receive(&client_ip, my_packet); + +} + +#else + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_sntp_request_unicast_test_application_define(void *first_unused_memory) +#endif +{ + + /* Print out test information banner. */ + printf("NetX Test: NETX SNTP Client Request Unicast Test.....................N/A\n"); + + test_control_return(3); +} +#endif + diff --git a/test/regression/tahi_test/netx_tahi.h b/test/regression/tahi_test/netx_tahi.h new file mode 100644 index 00000000..a4b2f0ba --- /dev/null +++ b/test/regression/tahi_test/netx_tahi.h @@ -0,0 +1,95 @@ +#ifndef _NETX_TAHI_H_ +#define _NETX_TAHI_H_ + + +#include "tx_api.h" +#include "nx_api.h" +#ifdef __PRODUCT_NETXDUO__ +#include "nxd_dhcpv6_client.h" +#endif +#endif + +#define TITLE 1 /* This entry contains the name of the test. */ +#define INJECT 2 /* This entry contains packet that needs to be injected into the system.*/ +#define CHECK 3 /* This entry contains packet that needs to be matched. */ +#define WAIT 4 /* This entry is to place a wait. */ +#define DUMP 5 /* This entry flushes the incoming packet queue. */ +#define CLEANUP 6 /* This is a marker, indicating the beginning sequeuence of cleanup procedure. */ + +#define N_CHECK 7 /* This entry contains packet that do not want to be received. */ + +#ifdef NX_IPSEC_ENABLE +#define D_CHECK 8 /* This entry contains packet that needs to be matched after decryption. */ +#define ASSEMBLE 9 /* This entry contains packet that needs to be assembled. */ +#define AD_CHECK 10 /* This entry contains packet that needs to be assembled and be matched after decryption. */ +#define TD_CHECK 11 /* This entry contains packet that needs to be matched after decryption which is tunneled. */ +#endif + +#define DHCPV6_CONFIRM 12 +#define DHCPV6_RELEASE 13 +#define DHCPV6_REBOOT 14 +#define DHCPV6_INFO_REQUEST 15 +#define DHCPV6_DNS 16 + +#define CLEAN_HOP_LIMIT 20 /* This is a marker, indicating the hop limit should be initial to 0xff. */ +#define NS_UNSPEC 21 /* This is a marker, indicating the NS is being check. */ +#define CHECK_V6REQUEST 22 /* This is a marker, indicating the ping6_request has been send. */ +#define REBOOT 23 /* This is a marker, indicating the reboot process. */ + + +#define NS 31 /* NS packet. */ +#define NA 32 /* NA packet. */ +#define RS 33 /* RS packet. */ +#define ER 34 /* ECHO REPLY packet. */ +#define RELEASE 35 /* DHCPV6 RELEASE packet. */ +#define DECLINE 36 /* DHCPV6 DECLINE packet. */ +#define REQUEST 37 /* DHCPV6 DECLINE packet. */ +#define ANY 38 /* ANY packet. */ + + + +/* Define the protocol value for pmtu.p2 or icmp.p2 ping6 process. */ +#define PMTU 0 +#define ICMP 1 + +typedef struct TAHI_TEST_SEQ_struct +{ + /* The command. Only INJECT and CHECK carries valid pkt_data and pkt_size. */ + int command; + + /* Only INJECT and CHECK carries valid pkt_data and pkt_size. */ + /* For TITLE, pkt_data carries a const string, which is used as the name of the test case. */ + char *pkt_data; + int pkt_size; + + /* Used for CHECK and WAIT. */ + /* WAIT command: wait this amount of time. */ + /* CHECK command: during the timeout period, check any incoming packets against the pkt_data in this entry. */ + int timeout; + + /*Used in D_CHECK to lookup the sa */ + /* Next layer protocol*/ + UCHAR protocol; + + /* Used when the next layer protocol is UDP*/ + ULONG src_port; + ULONG dst_port; + + /*Used when the next layer protocol is ICMP or ICMPv6*/ + UINT option; +} TAHI_TEST_SEQ; + +typedef struct TAHI_TEST_SUITE_struct +{ + TAHI_TEST_SEQ *test_case; + int test_case_size; +} TAHI_TEST_SUITE; + + +void netx_tahi_run_test_case(NX_IP *ip_0, TAHI_TEST_SEQ *test_case, int test_case_size); +#ifdef __PRODUCT_NETXDUO__ +void netx_tahi_set_dhcpv6(NX_DHCPV6 *dhcpv6_client_ptr); +#endif +void netx_tahi_set_dhcpv6_reboot(void (*dhcpv6_reboot)()); +void netx_tahi_set_dhcpv6_info_request(void (*dhcpv6_info_request)()); +void netx_tahi_set_dhcpv6_dns(void (*dhcpv6_dns)()); diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_002.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_002.c new file mode 100644 index 00000000..630731e0 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_002.c @@ -0,0 +1,164 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_001[]; +extern TAHI_TEST_SEQ tahi_dhcpv6_01_002[]; +extern int tahi_dhcpv6_01_001_size; +extern int tahi_dhcpv6_01_002_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_002_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_001[0], tahi_dhcpv6_01_001_size); + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_002[0], tahi_dhcpv6_01_002_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_003.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_003.c new file mode 100644 index 00000000..161914cc --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_003.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_003[]; +extern int tahi_dhcpv6_01_003_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_003_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_003[0], tahi_dhcpv6_01_003_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_004.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_004.c new file mode 100644 index 00000000..a98342f2 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_004.c @@ -0,0 +1,165 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_004[]; +extern int tahi_dhcpv6_01_004_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_004_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_004[0], tahi_dhcpv6_01_004_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif + diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_005.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_005.c new file mode 100644 index 00000000..c792acab --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_005.c @@ -0,0 +1,165 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_005[]; +extern int tahi_dhcpv6_01_005_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_005_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_005[0], tahi_dhcpv6_01_005_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif + diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_006.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_006.c new file mode 100644 index 00000000..9c0b378f --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_006.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_006[]; +extern int tahi_dhcpv6_01_006_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_006_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_006[0], tahi_dhcpv6_01_006_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_007.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_007.c new file mode 100644 index 00000000..1b27f6f2 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_007.c @@ -0,0 +1,175 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_007[]; +extern int tahi_dhcpv6_01_007_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_007_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_007[0], tahi_dhcpv6_01_007_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_007_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: TAHI dhcpv6 01-007 TEST.......................N/A!\n"); + test_control_return(3); +} +#endif +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_008.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_008.c new file mode 100644 index 00000000..15f5317f --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_008.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_008[]; +extern int tahi_dhcpv6_01_008_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_008_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_008[0], tahi_dhcpv6_01_008_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_009.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_009.c new file mode 100644 index 00000000..ebc74078 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_009.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_009[]; +extern int tahi_dhcpv6_01_009_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_009_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_009[0], tahi_dhcpv6_01_009_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_010.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_010.c new file mode 100644 index 00000000..a5b2afb3 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_010.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_010[]; +extern int tahi_dhcpv6_01_010_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_010_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_010[0], tahi_dhcpv6_01_010_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_011.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_011.c new file mode 100644 index 00000000..f80404cd --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_011.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_011[]; +extern int tahi_dhcpv6_01_011_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_011_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_011[0], tahi_dhcpv6_01_011_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_012.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_012.c new file mode 100644 index 00000000..805647c2 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_012.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_012[]; +extern int tahi_dhcpv6_01_012_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_012_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_012[0], tahi_dhcpv6_01_012_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_013.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_013.c new file mode 100644 index 00000000..cb71c845 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_013.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_013[]; +extern int tahi_dhcpv6_01_013_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_013_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_013[0], tahi_dhcpv6_01_013_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_014.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_014.c new file mode 100644 index 00000000..8d2ea0a6 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_014.c @@ -0,0 +1,229 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_reboot(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_014[]; +extern int tahi_dhcpv6_01_014_size; + +static CHAR *pointer; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_014_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_reboot(my_dhcpv6_reboot); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_014[0], tahi_dhcpv6_01_014_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +void my_dhcpv6_reboot() +{ + +NXD_ADDRESS ipv6_address; +UINT status; + + + nx_dhcpv6_client_delete(&dhcp_client); + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + status = nx_dhcpv6_request_solicit(&dhcp_client); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_019.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_019.c new file mode 100644 index 00000000..62abe383 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_019.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_019[]; +extern int tahi_dhcpv6_01_019_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_019_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_019[0], tahi_dhcpv6_01_019_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_020.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_020.c new file mode 100644 index 00000000..976c0a1a --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_020.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_020[]; +extern int tahi_dhcpv6_01_020_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_020_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_020[0], tahi_dhcpv6_01_020_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_021.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_021.c new file mode 100644 index 00000000..95aeb263 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_021.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_021[]; +extern int tahi_dhcpv6_01_021_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_021_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_021[0], tahi_dhcpv6_01_021_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_022.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_022.c new file mode 100644 index 00000000..3cef6e50 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_022.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_022[]; +extern int tahi_dhcpv6_01_022_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_022_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_022[0], tahi_dhcpv6_01_022_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_023.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_023.c new file mode 100644 index 00000000..dcafa5b6 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_023.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_023[]; +extern int tahi_dhcpv6_01_023_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_023_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_023[0], tahi_dhcpv6_01_023_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_024.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_024.c new file mode 100644 index 00000000..ebbc8cee --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_024.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_024[]; +extern int tahi_dhcpv6_01_024_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_024_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_024[0], tahi_dhcpv6_01_024_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_025.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_025.c new file mode 100644 index 00000000..532f728d --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_025.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_025[]; +extern int tahi_dhcpv6_01_025_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_025_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_025[0], tahi_dhcpv6_01_025_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_026.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_026.c new file mode 100644 index 00000000..836b2e7e --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_026.c @@ -0,0 +1,165 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_026[]; +extern int tahi_dhcpv6_01_026_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_026_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_026[0], tahi_dhcpv6_01_026_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif + diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_027.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_027.c new file mode 100644 index 00000000..962ca3a0 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_027.c @@ -0,0 +1,165 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_027[]; +extern int tahi_dhcpv6_01_027_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_027_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_027[0], tahi_dhcpv6_01_027_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif + diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_028.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_028.c new file mode 100644 index 00000000..7d4bd6c3 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_028.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_028[]; +extern int tahi_dhcpv6_01_028_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_028_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_028[0], tahi_dhcpv6_01_028_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_029.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_029.c new file mode 100644 index 00000000..39ed185f --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_029.c @@ -0,0 +1,175 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_029[]; +extern int tahi_dhcpv6_01_029_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_029_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_029[0], tahi_dhcpv6_01_029_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_029_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: TAHI dhcpv6 01-029 TEST.......................N/A!\n"); + test_control_return(3); +} +#endif +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_030.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_030.c new file mode 100644 index 00000000..3b852a0a --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_030.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_030[]; +extern int tahi_dhcpv6_01_030_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_030_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_030[0], tahi_dhcpv6_01_030_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_031.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_031.c new file mode 100644 index 00000000..971fd9a3 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_031.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_031[]; +extern int tahi_dhcpv6_01_031_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_031_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_031[0], tahi_dhcpv6_01_031_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_032.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_032.c new file mode 100644 index 00000000..f5dd59b4 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_032.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_032[]; +extern int tahi_dhcpv6_01_032_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_032_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_032[0], tahi_dhcpv6_01_032_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_033.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_033.c new file mode 100644 index 00000000..d616f34d --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_033.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_033[]; +extern int tahi_dhcpv6_01_033_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_033_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_033[0], tahi_dhcpv6_01_033_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_034.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_034.c new file mode 100644 index 00000000..b522121e --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_034.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_034[]; +extern int tahi_dhcpv6_01_034_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_034_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_034[0], tahi_dhcpv6_01_034_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_035.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_035.c new file mode 100644 index 00000000..111d8cb8 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_035.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_035[]; +extern int tahi_dhcpv6_01_035_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_035_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_035[0], tahi_dhcpv6_01_035_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_036.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_036.c new file mode 100644 index 00000000..a6e14f66 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_036.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_036[]; +extern int tahi_dhcpv6_01_036_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_036_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_036[0], tahi_dhcpv6_01_036_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_037.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_037.c new file mode 100644 index 00000000..31af0942 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_037.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_037[]; +extern int tahi_dhcpv6_01_037_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_037_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_037[0], tahi_dhcpv6_01_037_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_038.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_038.c new file mode 100644 index 00000000..098f649f --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_038.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_038[]; +extern int tahi_dhcpv6_01_038_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_038_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_038[0], tahi_dhcpv6_01_038_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_039.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_039.c new file mode 100644 index 00000000..e714af7b --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_039.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_039[]; +extern int tahi_dhcpv6_01_039_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_039_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_039[0], tahi_dhcpv6_01_039_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_040.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_040.c new file mode 100644 index 00000000..4697cdac --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_040.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_040[]; +extern int tahi_dhcpv6_01_040_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_040_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_040[0], tahi_dhcpv6_01_040_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_041.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_041.c new file mode 100644 index 00000000..9f9afec2 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_041.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_041[]; +extern int tahi_dhcpv6_01_041_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_041_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_041[0], tahi_dhcpv6_01_041_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_042.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_042.c new file mode 100644 index 00000000..051860bb --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_042.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_042[]; +extern int tahi_dhcpv6_01_042_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_042_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_042[0], tahi_dhcpv6_01_042_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_043.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_043.c new file mode 100644 index 00000000..430712b9 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_043.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_043[]; +extern int tahi_dhcpv6_01_043_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_043_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_043[0], tahi_dhcpv6_01_043_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_044.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_044.c new file mode 100644 index 00000000..c622621c --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_044.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_044[]; +extern int tahi_dhcpv6_01_044_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_044_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_044[0], tahi_dhcpv6_01_044_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_045.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_045.c new file mode 100644 index 00000000..e9a1a333 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_045.c @@ -0,0 +1,177 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_045[]; +extern int tahi_dhcpv6_01_045_size; + +static void my_icmpv6_ra_flag_callback(NX_IP *ip_ptr, UINT ra_flag); + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_045_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Set icmpv6 ra flag. */ + status = nxd_icmpv6_ra_flag_callback_set(&ip_0, my_icmpv6_ra_flag_callback); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_045[0], tahi_dhcpv6_01_045_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +static void my_icmpv6_ra_flag_callback(NX_IP *ip_ptr, UINT ra_flag) +{ + ; +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_046.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_046.c new file mode 100644 index 00000000..54546dee --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_046.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_046[]; +extern int tahi_dhcpv6_01_046_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_046_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_046[0], tahi_dhcpv6_01_046_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_047.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_047.c new file mode 100644 index 00000000..f835b4a4 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_047.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_047[]; +extern int tahi_dhcpv6_01_047_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_047_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_047[0], tahi_dhcpv6_01_047_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_048.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_048.c new file mode 100644 index 00000000..d5232397 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_048.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_048[]; +extern int tahi_dhcpv6_01_048_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_048_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_048[0], tahi_dhcpv6_01_048_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_049.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_049.c new file mode 100644 index 00000000..6ccbd255 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_049.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_049[]; +extern int tahi_dhcpv6_01_049_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_049_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_049[0], tahi_dhcpv6_01_049_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_050.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_050.c new file mode 100644 index 00000000..03f50529 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_050.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_050[]; +extern int tahi_dhcpv6_01_050_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_050_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_050[0], tahi_dhcpv6_01_050_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_051.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_051.c new file mode 100644 index 00000000..0fe125c9 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_051.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_051[]; +extern int tahi_dhcpv6_01_051_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_051_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_051[0], tahi_dhcpv6_01_051_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_052.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_052.c new file mode 100644 index 00000000..f57f15d8 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_052.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_052[]; +extern int tahi_dhcpv6_01_052_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_052_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_052[0], tahi_dhcpv6_01_052_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_053.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_053.c new file mode 100644 index 00000000..e57cea95 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_053.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_053[]; +extern int tahi_dhcpv6_01_053_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_053_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_053[0], tahi_dhcpv6_01_053_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_054.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_054.c new file mode 100644 index 00000000..f441c048 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_054.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_054[]; +extern int tahi_dhcpv6_01_054_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_054_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_054[0], tahi_dhcpv6_01_054_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_055.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_055.c new file mode 100644 index 00000000..7ab7da19 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_055.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_055[]; +extern int tahi_dhcpv6_01_055_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_055_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_055[0], tahi_dhcpv6_01_055_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_056.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_056.c new file mode 100644 index 00000000..558936b4 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_056.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_056[]; +extern int tahi_dhcpv6_01_056_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_056_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_056[0], tahi_dhcpv6_01_056_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_057.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_057.c new file mode 100644 index 00000000..e4bee39e --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_057.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_057[]; +extern int tahi_dhcpv6_01_057_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_057_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_057[0], tahi_dhcpv6_01_057_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_058.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_058.c new file mode 100644 index 00000000..45d38fbc --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_058.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_058[]; +extern int tahi_dhcpv6_01_058_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_058_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_058[0], tahi_dhcpv6_01_058_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_059.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_059.c new file mode 100644 index 00000000..e0342c8c --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_059.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_059[]; +extern int tahi_dhcpv6_01_059_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_059_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_059[0], tahi_dhcpv6_01_059_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_060.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_060.c new file mode 100644 index 00000000..c3553779 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_060.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_060[]; +extern int tahi_dhcpv6_01_060_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_060_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_060[0], tahi_dhcpv6_01_060_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_060_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: TAHI dhcpv6 01-060 TEST.......................N/A!\n"); + test_control_return(3); +} +#endif +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_061.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_061.c new file mode 100644 index 00000000..70c3469e --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_061.c @@ -0,0 +1,174 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_061[]; +extern int tahi_dhcpv6_01_061_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_061_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_061[0], tahi_dhcpv6_01_061_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_061_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: TAHI dhcpv6 01-061 TEST.......................N/A!\n"); + test_control_return(3); +} +#endif +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_062.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_062.c new file mode 100644 index 00000000..256cf047 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_062.c @@ -0,0 +1,175 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_062[]; +extern int tahi_dhcpv6_01_062_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_062_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_062[0], tahi_dhcpv6_01_062_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_062_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: TAHI dhcpv6 01-062 TEST.......................N/A!\n"); + test_control_return(3); +} +#endif +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_063.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_063.c new file mode 100644 index 00000000..779b23af --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_063.c @@ -0,0 +1,175 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_063[]; +extern int tahi_dhcpv6_01_063_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_063_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_063[0], tahi_dhcpv6_01_063_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_063_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: TAHI dhcpv6 01-063 TEST.......................N/A!\n"); + test_control_return(3); +} +#endif +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_064.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_064.c new file mode 100644 index 00000000..4d7aa12e --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_064.c @@ -0,0 +1,175 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_064[]; +extern int tahi_dhcpv6_01_064_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_064_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_064[0], tahi_dhcpv6_01_064_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_064_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: TAHI dhcpv6 01-064 TEST.......................N/A!\n"); + test_control_return(3); +} +#endif +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_065.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_065.c new file mode 100644 index 00000000..8a751c33 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_065.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_065[]; +extern int tahi_dhcpv6_01_065_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_065_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_065[0], tahi_dhcpv6_01_065_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_066.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_066.c new file mode 100644 index 00000000..f61fcf28 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_066.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_066[]; +extern int tahi_dhcpv6_01_066_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_066_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_066[0], tahi_dhcpv6_01_066_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_067.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_067.c new file mode 100644 index 00000000..469483c3 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_067.c @@ -0,0 +1,175 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +extern void test_control_return(UINT status); +#if (NX_DHCPV6_MAX_IA_ADDRESS >= 2) /* This test case works OK when NX_DHCPV6_MAX_IA_ADDRESS is 2, default is 1. */ +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_067[]; +extern int tahi_dhcpv6_01_067_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_067_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_067[0], tahi_dhcpv6_01_067_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_067_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: TAHI dhcpv6 01-067 TEST.......................N/A!\n"); + test_control_return(3); +} +#endif +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_068.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_068.c new file mode 100644 index 00000000..c00a3192 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_068.c @@ -0,0 +1,339 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static ULONG original_xid; +static UCHAR original_cid[18]; +static UINT renew_count; + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_068[]; +extern int tahi_dhcpv6_01_068_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_068_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + renew_count = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_068[0], tahi_dhcpv6_01_068_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + else if((message_type == NX_DHCPV6_MESSAGE_TYPE_RENEW) && (renew_count == 0)) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x66915200 + message_type; + renew_count++; + } + else if((message_type == NX_DHCPV6_MESSAGE_TYPE_RENEW) || + (message_type == NX_DHCPV6_MESSAGE_TYPE_REBIND)) + { + + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0xa4e49600 + message_type; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_069.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_069.c new file mode 100644 index 00000000..75513a92 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_069.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_069[]; +extern int tahi_dhcpv6_01_069_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_069_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_069[0], tahi_dhcpv6_01_069_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_070.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_070.c new file mode 100644 index 00000000..d5d58b31 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_070.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_070[]; +extern int tahi_dhcpv6_01_070_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_070_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_070[0], tahi_dhcpv6_01_070_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_071.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_071.c new file mode 100644 index 00000000..098f48c3 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_071.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_071[]; +extern int tahi_dhcpv6_01_071_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_071_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_071[0], tahi_dhcpv6_01_071_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_072.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_072.c new file mode 100644 index 00000000..f6e054d5 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_072.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_072[]; +extern int tahi_dhcpv6_01_072_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_072_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_072[0], tahi_dhcpv6_01_072_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_073.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_073.c new file mode 100644 index 00000000..db60a848 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_073.c @@ -0,0 +1,331 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_073[]; +extern int tahi_dhcpv6_01_073_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; +static UINT solicit_count; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_073_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + solicit_count = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_073[0], tahi_dhcpv6_01_073_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if((message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) && (solicit_count == 0)) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + solicit_count++; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x66915201; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_074.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_074.c new file mode 100644 index 00000000..2a87aa2e --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_074.c @@ -0,0 +1,340 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_074[]; +extern int tahi_dhcpv6_01_074_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; +static UINT confirm_count; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_074_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + confirm_count = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_074[0], tahi_dhcpv6_01_074_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if((message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT)) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + if(confirm_count == 0) + { + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else + { + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0xa4e49601; + } + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_CONFIRM) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x66915200 + message_type; + confirm_count++; + } + + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_075.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_075.c new file mode 100644 index 00000000..5f65aa43 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_075.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_075[]; +extern int tahi_dhcpv6_01_075_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_075_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_075[0], tahi_dhcpv6_01_075_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_076.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_076.c new file mode 100644 index 00000000..f15aa770 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_076.c @@ -0,0 +1,332 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_076[]; +extern int tahi_dhcpv6_01_076_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; +static UINT renew_count; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_076_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + renew_count = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_076[0], tahi_dhcpv6_01_076_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + if(renew_count == 0) + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + else + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0xa4e49603; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_RENEW) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x66915200 + message_type; + renew_count++; + } + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_077.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_077.c new file mode 100644 index 00000000..a5d5fc93 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_077.c @@ -0,0 +1,333 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_077[]; +extern int tahi_dhcpv6_01_077_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; +static UINT renew_count; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_077_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + renew_count = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_077[0], tahi_dhcpv6_01_077_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + if(renew_count == 0) + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + else + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0xa4e49603; + } + else if((message_type == NX_DHCPV6_MESSAGE_TYPE_RENEW) || + (message_type == NX_DHCPV6_MESSAGE_TYPE_REBIND)) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x66915200 + message_type; + renew_count++; + } + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_078.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_078.c new file mode 100644 index 00000000..9c7b877d --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_078.c @@ -0,0 +1,164 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_078[]; +extern int tahi_dhcpv6_01_078_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_078_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_078[0], tahi_dhcpv6_01_078_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_079.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_079.c new file mode 100644 index 00000000..a3ebc952 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_079.c @@ -0,0 +1,164 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_079[]; +extern int tahi_dhcpv6_01_079_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_079_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_079[0], tahi_dhcpv6_01_079_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_080.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_080.c new file mode 100644 index 00000000..fa5eabe7 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_080.c @@ -0,0 +1,167 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_080[]; +extern int tahi_dhcpv6_01_080_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_080_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_080[0], tahi_dhcpv6_01_080_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_081.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_081.c new file mode 100644 index 00000000..ccc73fd0 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_081.c @@ -0,0 +1,175 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_081[]; +extern int tahi_dhcpv6_01_081_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_081_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_081[0], tahi_dhcpv6_01_081_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_081_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: TAHI dhcpv6 01-081 TEST.......................N/A!\n"); + test_control_return(3); +} +#endif +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_082.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_082.c new file mode 100644 index 00000000..f7bd3a9b --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_082.c @@ -0,0 +1,318 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_082[]; +extern int tahi_dhcpv6_01_082_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_082_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_082[0], tahi_dhcpv6_01_082_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0xa4e49601; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + if(message_type != NX_DHCPV6_MESSAGE_TYPE_DECLINE) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + } + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_083.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_083.c new file mode 100644 index 00000000..33b77aca --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_083.c @@ -0,0 +1,164 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_083[]; +extern int tahi_dhcpv6_01_083_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_083_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_083[0], tahi_dhcpv6_01_083_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_084.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_084.c new file mode 100644 index 00000000..85e98beb --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_084.c @@ -0,0 +1,314 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_084[]; +extern int tahi_dhcpv6_01_084_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_084_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_084[0], tahi_dhcpv6_01_084_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_085.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_085.c new file mode 100644 index 00000000..262b9a19 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_085.c @@ -0,0 +1,311 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_085[]; +extern int tahi_dhcpv6_01_085_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_085_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_085[0], tahi_dhcpv6_01_085_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the cid. */ + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_086.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_086.c new file mode 100644 index 00000000..e2355c80 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_086.c @@ -0,0 +1,164 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_086[]; +extern int tahi_dhcpv6_01_086_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_086_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_086[0], tahi_dhcpv6_01_086_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_087.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_087.c new file mode 100644 index 00000000..3344be89 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_087.c @@ -0,0 +1,325 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_087[]; +extern int tahi_dhcpv6_01_087_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_087_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_087[0], tahi_dhcpv6_01_087_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + if(message_type != NX_DHCPV6_MESSAGE_TYPE_REPLY) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + } + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_088.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_088.c new file mode 100644 index 00000000..6d12efbb --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_088.c @@ -0,0 +1,164 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_088[]; +extern int tahi_dhcpv6_01_088_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_088_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_088[0], tahi_dhcpv6_01_088_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_089.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_089.c new file mode 100644 index 00000000..5db5f8e7 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_089.c @@ -0,0 +1,164 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_089[]; +extern int tahi_dhcpv6_01_089_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_089_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_089[0], tahi_dhcpv6_01_089_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_090.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_090.c new file mode 100644 index 00000000..48a33001 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_090.c @@ -0,0 +1,324 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_090[]; +extern int tahi_dhcpv6_01_090_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_090_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_090[0], tahi_dhcpv6_01_090_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + if(message_type != NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + } + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_091.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_091.c new file mode 100644 index 00000000..e79817f2 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_091.c @@ -0,0 +1,324 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_091[]; +extern int tahi_dhcpv6_01_091_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_091_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_091[0], tahi_dhcpv6_01_091_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + if(message_type != NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + } + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_092.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_092.c new file mode 100644 index 00000000..480d2fdf --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_092.c @@ -0,0 +1,324 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_092[]; +extern int tahi_dhcpv6_01_092_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_092_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_092[0], tahi_dhcpv6_01_092_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + if(message_type != NX_DHCPV6_MESSAGE_TYPE_CONFIRM) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + } + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_093.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_093.c new file mode 100644 index 00000000..d7a9041d --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_093.c @@ -0,0 +1,324 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_093[]; +extern int tahi_dhcpv6_01_093_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_093_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_093[0], tahi_dhcpv6_01_093_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + if(message_type != NX_DHCPV6_MESSAGE_TYPE_RENEW) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + } + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_094.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_094.c new file mode 100644 index 00000000..65655de8 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_094.c @@ -0,0 +1,324 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_094[]; +extern int tahi_dhcpv6_01_094_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_094_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_094[0], tahi_dhcpv6_01_094_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + if(message_type != NX_DHCPV6_MESSAGE_TYPE_REBIND) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + } + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_095.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_095.c new file mode 100644 index 00000000..c09410a8 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_095.c @@ -0,0 +1,324 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_095[]; +extern int tahi_dhcpv6_01_095_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_095_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_095[0], tahi_dhcpv6_01_095_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + if(message_type != NX_DHCPV6_MESSAGE_TYPE_DECLINE) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + } + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_096.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_096.c new file mode 100644 index 00000000..ffe10425 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_096.c @@ -0,0 +1,324 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_096[]; +extern int tahi_dhcpv6_01_096_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_096_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_096[0], tahi_dhcpv6_01_096_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + if(message_type != NX_DHCPV6_MESSAGE_TYPE_RELEASE) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + } + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_097.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_097.c new file mode 100644 index 00000000..e110530c --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_097.c @@ -0,0 +1,325 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_097[]; +extern int tahi_dhcpv6_01_097_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_097_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_097[0], tahi_dhcpv6_01_097_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + /* 12 reley-forw. */ + if(message_type != 12) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + } + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_098.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_098.c new file mode 100644 index 00000000..3b82bcd1 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_098.c @@ -0,0 +1,325 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_098[]; +extern int tahi_dhcpv6_01_098_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_098_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_098[0], tahi_dhcpv6_01_098_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + /* 12 reley-reply. */ + if(message_type != 13) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + } + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_099.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_099.c new file mode 100644 index 00000000..8f46f203 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_01_099.c @@ -0,0 +1,324 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_01_099[]; +extern int tahi_dhcpv6_01_099_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_01_099_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_01_099[0], tahi_dhcpv6_01_099_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + if(message_type != NX_DHCPV6_MESSAGE_TYPE_INFORM_REQUEST) + { + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + } + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_002.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_002.c new file mode 100644 index 00000000..67c59ba9 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_002.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_002[]; +extern int tahi_dhcpv6_04_002_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_002_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_002[0], tahi_dhcpv6_04_002_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_003.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_003.c new file mode 100644 index 00000000..e7682ff2 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_003.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_003[]; +extern int tahi_dhcpv6_04_003_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_003_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_003[0], tahi_dhcpv6_04_003_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_004.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_004.c new file mode 100644 index 00000000..90c6a1e7 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_004.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_004[]; +extern int tahi_dhcpv6_04_004_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_004_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_004[0], tahi_dhcpv6_04_004_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_005.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_005.c new file mode 100644 index 00000000..35fd1645 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_005.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_005[]; +extern int tahi_dhcpv6_04_005_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_005_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_005[0], tahi_dhcpv6_04_005_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_006.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_006.c new file mode 100644 index 00000000..e4aa1a33 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_006.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_006[]; +extern int tahi_dhcpv6_04_006_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_006_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_006[0], tahi_dhcpv6_04_006_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_007.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_007.c new file mode 100644 index 00000000..6f8eddff --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_007.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_007[]; +extern int tahi_dhcpv6_04_007_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_007_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_007[0], tahi_dhcpv6_04_007_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_008.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_008.c new file mode 100644 index 00000000..d275ddf1 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_008.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_008[]; +extern int tahi_dhcpv6_04_008_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_008_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_008[0], tahi_dhcpv6_04_008_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_009.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_009.c new file mode 100644 index 00000000..25684a7c --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_009.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_009[]; +extern int tahi_dhcpv6_04_009_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_009_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_009[0], tahi_dhcpv6_04_009_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_010.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_010.c new file mode 100644 index 00000000..a03fd355 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_010.c @@ -0,0 +1,437 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" +#include "nxd_dns.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; +static NX_DNS dns_client; + +static ULONG error_counter; +static ULONG confirm_counter; + +static CHAR *pointer; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_dns(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_010[]; +extern int tahi_dhcpv6_04_010_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_010_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + confirm_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a DNS instance for the Client. */ + status = nx_dns_create(&dns_client, &ip_0, (UCHAR *)"DNS Client"); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + netx_tahi_set_dhcpv6_dns(my_dhcpv6_dns); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_010[0], tahi_dhcpv6_04_010_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +void my_dhcpv6_dns() +{ + +UINT status; +NXD_ADDRESS dns_ipv6_server_address; +NXD_ADDRESS host_ipv6_address; + + + /* Get the dns server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_ipv6_server_address); + + /* Yes, get the address of DNS server. */ + if (status == NX_SUCCESS) + { + /* Add the address. */ + status = nxd_dns_server_add(&dns_client, &dns_ipv6_server_address); + + } + + /* Send the DNS query to get the ipv6 address of the .*/ + status = nxd_dns_host_by_name_get(&dns_client, (UCHAR *)"dhcpv6.test.example.com", &host_ipv6_address, 1, NX_IP_VERSION_V6); +} + + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_CONFIRM) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x66915200 + message_type; + + confirm_counter = 1; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + /* dst port 53, dns */ + else if((src_dst_port & 0x0000FFFF) == 0x00000035) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + + if(confirm_counter == 0) + { + /* Modify the transmit ID to be the same with the packet captured by wireshark. */ + *(USHORT *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0xf907; + } + else if(confirm_counter == 1) + { + /* Modify the transmit ID to be the same with the packet captured by wireshark. */ + *(USHORT *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x9d14; + } + + /* Modify the UDP source port to be the same value 30000(0x7530) with the packet captured by wireshark. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + udp_header_ptr -> nx_udp_header_word_0 = ((udp_header_ptr -> nx_udp_header_word_0 & 0x0000FFFF) | 0x75300000); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_012.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_012.c new file mode 100644 index 00000000..0d3b3036 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_012.c @@ -0,0 +1,164 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_012[]; +extern int tahi_dhcpv6_04_012_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_012_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_012[0], tahi_dhcpv6_04_012_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_013.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_013.c new file mode 100644 index 00000000..7a7694d0 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_013.c @@ -0,0 +1,164 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_013[]; +extern int tahi_dhcpv6_04_013_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_013_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_013[0], tahi_dhcpv6_04_013_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_014.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_014.c new file mode 100644 index 00000000..471b2b44 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_014.c @@ -0,0 +1,164 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_014[]; +extern int tahi_dhcpv6_04_014_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_014_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_014[0], tahi_dhcpv6_04_014_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_015.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_015.c new file mode 100644 index 00000000..34ca1bf1 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_015.c @@ -0,0 +1,164 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_015[]; +extern int tahi_dhcpv6_04_015_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_015_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_015[0], tahi_dhcpv6_04_015_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_016.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_016.c new file mode 100644 index 00000000..7ce00379 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_016.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_016[]; +extern int tahi_dhcpv6_04_016_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_016_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_016[0], tahi_dhcpv6_04_016_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_017.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_017.c new file mode 100644 index 00000000..9282ea43 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_017.c @@ -0,0 +1,166 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_017[]; +extern int tahi_dhcpv6_04_017_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_017_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_017[0], tahi_dhcpv6_04_017_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_018.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_018.c new file mode 100644 index 00000000..aa9032ec --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_018.c @@ -0,0 +1,178 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_018[]; +extern int tahi_dhcpv6_04_018_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_018_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_018[0], tahi_dhcpv6_04_018_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_018_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: TAHI dhcpv6 04-018 TEST.......................N/A!\n"); + test_control_return(3); +} +#endif +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_019.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_019.c new file mode 100644 index 00000000..5cc97cf6 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_019.c @@ -0,0 +1,178 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + +extern void test_control_return(UINT status); +#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_019[]; +extern int tahi_dhcpv6_04_019_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_019_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6(&dhcp_client); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_019[0], tahi_dhcpv6_04_019_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +#else +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_019_define(void * first_unused_memory) +#endif +{ + printf("NetX Test: TAHI dhcpv6 04-019 TEST.......................N/A!\n"); + test_control_return(3); +} +#endif +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_020.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_020.c new file mode 100644 index 00000000..335547f6 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_020.c @@ -0,0 +1,417 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" +#include "nxd_dns.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; +static NX_DNS dns_client; + +static ULONG error_counter; + +static CHAR *pointer; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_dns(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_020[]; +extern int tahi_dhcpv6_04_020_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_020_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a DNS instance for the Client. */ + status = nx_dns_create(&dns_client, &ip_0, (UCHAR *)"DNS Client"); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_dns(my_dhcpv6_dns); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_020[0], tahi_dhcpv6_04_020_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +void my_dhcpv6_dns() +{ + +UINT status; +NXD_ADDRESS dns_ipv6_server_address; +NXD_ADDRESS host_ipv6_address; + + + /* Get the dns server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_ipv6_server_address); + + /* Yes, get the address of DNS server. */ + if (status == NX_SUCCESS) + { + /* Add the address. */ + status = nxd_dns_server_add(&dns_client, &dns_ipv6_server_address); + + } + + /* Send the DNS query to get the ipv6 address of the .*/ + status = nxd_dns_host_by_name_get(&dns_client, (UCHAR *)"dhcpv6.test.example.com", &host_ipv6_address, 0, NX_IP_VERSION_V6); +} + + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + /* dst port 53, dns */ + else if((src_dst_port & 0x0000FFFF) == 0x00000035) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Modify the transmit ID to be the same with the packet captured by wireshark. */ + *(USHORT *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0xd12a; + + /* Modify the UDP source port to be the same value 30000(0x7530) with the packet captured by wireshark. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + udp_header_ptr -> nx_udp_header_word_0 = ((udp_header_ptr -> nx_udp_header_word_0 & 0x0000FFFF) | 0x75300000); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_021.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_021.c new file mode 100644 index 00000000..5eeeb264 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_021.c @@ -0,0 +1,417 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" +#include "nxd_dns.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; +static NX_DNS dns_client; + +static ULONG error_counter; + +static CHAR *pointer; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_dns(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_021[]; +extern int tahi_dhcpv6_04_021_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_021_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a DNS instance for the Client. */ + status = nx_dns_create(&dns_client, &ip_0, (UCHAR *)"DNS Client"); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_dns(my_dhcpv6_dns); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_021[0], tahi_dhcpv6_04_021_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +void my_dhcpv6_dns() +{ + +UINT status; +NXD_ADDRESS dns_ipv6_server_address; +NXD_ADDRESS host_ipv6_address; + + + /* Get the dns server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_ipv6_server_address); + + /* Yes, get the address of DNS server. */ + if (status == NX_SUCCESS) + { + /* Add the address. */ + status = nxd_dns_server_add(&dns_client, &dns_ipv6_server_address); + + } + + /* Send the DNS query to get the ipv6 address of the .*/ + status = nxd_dns_host_by_name_get(&dns_client, (UCHAR *)"dhcpv6.test.example.com", &host_ipv6_address, 0, NX_IP_VERSION_V6); +} + + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + /* dst port 53, dns */ + else if((src_dst_port & 0x0000FFFF) == 0x00000035) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Modify the transmit ID to be the same with the packet captured by wireshark. */ + *(USHORT *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0xa213; + + /* Modify the UDP source port to be the same value 30000(0x7530) with the packet captured by wireshark. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + udp_header_ptr -> nx_udp_header_word_0 = ((udp_header_ptr -> nx_udp_header_word_0 & 0x0000FFFF) | 0x75300000); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_022.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_022.c new file mode 100644 index 00000000..fa732398 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_022.c @@ -0,0 +1,434 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" +#include "nxd_dns.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; +static NX_DNS dns_client; + +static ULONG error_counter; +static ULONG renew_counter; + +static CHAR *pointer; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_dns(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_022[]; +extern int tahi_dhcpv6_04_022_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_022_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + renew_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a DNS instance for the Client. */ + status = nx_dns_create(&dns_client, &ip_0, (UCHAR *)"DNS Client"); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_dns(my_dhcpv6_dns); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_022[0], tahi_dhcpv6_04_022_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +void my_dhcpv6_dns() +{ + +UINT status; +NXD_ADDRESS dns_ipv6_server_address; +NXD_ADDRESS host_ipv6_address; + + + /* Get the dns server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_ipv6_server_address); + + /* Yes, get the address of DNS server. */ + if (status == NX_SUCCESS) + { + /* Add the address. */ + status = nxd_dns_server_add(&dns_client, &dns_ipv6_server_address); + + } + + /* Send the DNS query to get the ipv6 address of the .*/ + status = nxd_dns_host_by_name_get(&dns_client, (UCHAR *)"dhcpv6.test.example.com", &host_ipv6_address, 1, NX_IP_VERSION_V6); +} + + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_RENEW) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x66915200 + message_type; + renew_counter = 1; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + /* dst port 53, dns */ + else if((src_dst_port & 0x0000FFFF) == 0x00000035) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + if(renew_counter == 0) + { + /* Modify the transmit ID to be the same with the packet captured by wireshark. */ + *(USHORT *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x4d19; + } + else if(renew_counter == 1) + { + /* Modify the transmit ID to be the same with the packet captured by wireshark. */ + *(USHORT *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x2139; + } + + /* Modify the UDP source port to be the same value 30000(0x7530) with the packet captured by wireshark. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + udp_header_ptr -> nx_udp_header_word_0 = ((udp_header_ptr -> nx_udp_header_word_0 & 0x0000FFFF) | 0x75300000); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_026.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_026.c new file mode 100644 index 00000000..745c2828 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_026.c @@ -0,0 +1,163 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_026[]; +extern int tahi_dhcpv6_04_026_size; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_026_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_026[0], tahi_dhcpv6_04_026_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_027.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_027.c new file mode 100644 index 00000000..c9f702bb --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_04_027.c @@ -0,0 +1,229 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_reboot(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_04_027[]; +extern int tahi_dhcpv6_04_027_size; + +static CHAR *pointer; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_04_027_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_reboot(my_dhcpv6_reboot); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + status = nx_dhcpv6_request_solicit(&dhcp_client); + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_04_027[0], tahi_dhcpv6_04_027_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +void my_dhcpv6_reboot() +{ + +NXD_ADDRESS ipv6_address; +UINT status; + + + nx_dhcpv6_client_delete(&dhcp_client); + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + status = nx_dhcpv6_request_solicit(&dhcp_client); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_002.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_002.c new file mode 100644 index 00000000..5d15fe46 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_002.c @@ -0,0 +1,418 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" +#include "nxd_dns.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; +static NX_DNS dns_client; + +static ULONG error_counter; + +static CHAR *pointer; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_dns(); +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_002[]; +extern int tahi_dhcpv6_07_002_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_002_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a DNS instance for the Client. */ + status = nx_dns_create(&dns_client, &ip_0, (UCHAR *)"DNS Client"); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_dns(my_dhcpv6_dns); + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_002[0], tahi_dhcpv6_07_002_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +void my_dhcpv6_dns() +{ + +UINT status; +NXD_ADDRESS dns_ipv6_server_address; +NXD_ADDRESS host_ipv6_address; + + + /* Get the dns server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_ipv6_server_address); + + /* Yes, get the address of DNS server. */ + if (status == NX_SUCCESS) + { + /* Add the address. */ + status = nxd_dns_server_add(&dns_client, &dns_ipv6_server_address); + + } + + /* Send the DNS query to get the ipv6 address of the .*/ + status = nxd_dns_host_by_name_get(&dns_client, (UCHAR *)"dhcpv6.test.example.com", &host_ipv6_address, 0, NX_IP_VERSION_V6); +} + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_INFORM_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e0b; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + /* dst port 53, dns */ + else if((src_dst_port & 0x0000FFFF) == 0x00000035) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Modify the transmit ID to be the same with the packet captured by wireshark. */ + *(USHORT *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x5515; + + /* Modify the UDP source port to be the same value 30000(0x7530) with the packet captured by wireshark. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + udp_header_ptr -> nx_udp_header_word_0 = ((udp_header_ptr -> nx_udp_header_word_0 & 0x0000FFFF) | 0x75300000); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + /* Modify the UDP source port to be the same value 30000(0x7530) with the packet captured by wireshark. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + udp_header_ptr -> nx_udp_header_word_0 = ((udp_header_ptr -> nx_udp_header_word_0 & 0x0000FFFF) | 0x75300000); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_003.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_003.c new file mode 100644 index 00000000..67d4741c --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_003.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_003[]; +extern int tahi_dhcpv6_07_003_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_003_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_003[0], tahi_dhcpv6_07_003_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_004.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_004.c new file mode 100644 index 00000000..0297e8fe --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_004.c @@ -0,0 +1,414 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" +#include "nxd_dns.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; +static NX_DNS dns_client; + +static ULONG error_counter; + +static CHAR *pointer; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_dns(); +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_004[]; +extern int tahi_dhcpv6_07_004_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_004_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a DNS instance for the Client. */ + status = nx_dns_create(&dns_client, &ip_0, (UCHAR *)"DNS Client"); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_dns(my_dhcpv6_dns); + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_004[0], tahi_dhcpv6_07_004_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +void my_dhcpv6_dns() +{ + +UINT status; +NXD_ADDRESS dns_ipv6_server_address; +NXD_ADDRESS host_ipv6_address; + + + /* Get the dns server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_ipv6_server_address); + + /* Yes, get the address of DNS server. */ + if (status == NX_SUCCESS) + { + /* Add the address. */ + status = nxd_dns_server_add(&dns_client, &dns_ipv6_server_address); + + } + + /* Send the DNS query to get the ipv6 address of the .*/ + status = nxd_dns_host_by_name_get(&dns_client, (UCHAR *)"dhcpv6.test.example.com", &host_ipv6_address, 0, NX_IP_VERSION_V6); +} + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_INFORM_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e0b; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + /* dst port 53, dns */ + else if((src_dst_port & 0x0000FFFF) == 0x00000035) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Modify the transmit ID to be the same with the packet captured by wireshark. */ + *(USHORT *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0xa113; + + /* Modify the UDP source port to be the same value 30000(0x7530) with the packet captured by wireshark. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + udp_header_ptr -> nx_udp_header_word_0 = ((udp_header_ptr -> nx_udp_header_word_0 & 0x0000FFFF) | 0x75300000); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_005.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_005.c new file mode 100644 index 00000000..a81c55af --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_005.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_005[]; +extern int tahi_dhcpv6_07_005_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_005_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_005[0], tahi_dhcpv6_07_005_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_006.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_006.c new file mode 100644 index 00000000..11b012ec --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_006.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_006[]; +extern int tahi_dhcpv6_07_006_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_006_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_006[0], tahi_dhcpv6_07_006_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_007.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_007.c new file mode 100644 index 00000000..1b7dfd32 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_007.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_007[]; +extern int tahi_dhcpv6_07_007_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_007_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_007[0], tahi_dhcpv6_07_007_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_008.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_008.c new file mode 100644 index 00000000..7891000a --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_008.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_008[]; +extern int tahi_dhcpv6_07_008_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_008_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_008[0], tahi_dhcpv6_07_008_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_009.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_009.c new file mode 100644 index 00000000..0cc446f6 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_009.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_009[]; +extern int tahi_dhcpv6_07_009_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_009_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_009[0], tahi_dhcpv6_07_009_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_010.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_010.c new file mode 100644 index 00000000..4a1defdc --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_010.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_010[]; +extern int tahi_dhcpv6_07_010_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_010_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_010[0], tahi_dhcpv6_07_010_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_011.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_011.c new file mode 100644 index 00000000..97de9030 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_011.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_011[]; +extern int tahi_dhcpv6_07_011_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_011_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_011[0], tahi_dhcpv6_07_011_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_012.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_012.c new file mode 100644 index 00000000..c19aeb5b --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_012.c @@ -0,0 +1,414 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" +#include "nxd_dns.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; +static NX_DNS dns_client; + +static ULONG error_counter; + +static CHAR *pointer; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_dns(); +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_012[]; +extern int tahi_dhcpv6_07_012_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_012_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a DNS instance for the Client. */ + status = nx_dns_create(&dns_client, &ip_0, (UCHAR *)"DNS Client"); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_dns(my_dhcpv6_dns); + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_012[0], tahi_dhcpv6_07_012_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +void my_dhcpv6_dns() +{ + +UINT status; +NXD_ADDRESS dns_ipv6_server_address; +NXD_ADDRESS host_ipv6_address; + + + /* Get the dns server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_ipv6_server_address); + + /* Yes, get the address of DNS server. */ + if (status == NX_SUCCESS) + { + /* Add the address. */ + status = nxd_dns_server_add(&dns_client, &dns_ipv6_server_address); + + } + + /* Send the DNS query to get the ipv6 address of the .*/ + status = nxd_dns_host_by_name_get(&dns_client, (UCHAR *)"dhcpv6.test.example.com", &host_ipv6_address, 0, NX_IP_VERSION_V6); +} + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_INFORM_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e0b; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + /* dst port 53, dns */ + else if((src_dst_port & 0x0000FFFF) == 0x00000035) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Modify the transmit ID to be the same with the packet captured by wireshark. */ + *(USHORT *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x910b; + + /* Modify the UDP source port to be the same value 30000(0x7530) with the packet captured by wireshark. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + udp_header_ptr -> nx_udp_header_word_0 = ((udp_header_ptr -> nx_udp_header_word_0 & 0x0000FFFF) | 0x75300000); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_013.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_013.c new file mode 100644 index 00000000..45fc0d34 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_013.c @@ -0,0 +1,414 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" +#include "nxd_dns.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; +static NX_DNS dns_client; + +static ULONG error_counter; + +static CHAR *pointer; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_dns(); +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_013[]; +extern int tahi_dhcpv6_07_013_size; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_013_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a DNS instance for the Client. */ + status = nx_dns_create(&dns_client, &ip_0, (UCHAR *)"DNS Client"); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_dns(my_dhcpv6_dns); + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_013[0], tahi_dhcpv6_07_013_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + +void my_dhcpv6_dns() +{ + +UINT status; +NXD_ADDRESS dns_ipv6_server_address; +NXD_ADDRESS host_ipv6_address; + + + /* Get the dns server address. */ + status = nx_dhcpv6_get_DNS_server_address(&dhcp_client, 0, &dns_ipv6_server_address); + + /* Yes, get the address of DNS server. */ + if (status == NX_SUCCESS) + { + /* Add the address. */ + status = nxd_dns_server_add(&dns_client, &dns_ipv6_server_address); + + } + + /* Send the DNS query to get the ipv6 address of the .*/ + status = nxd_dns_host_by_name_get(&dns_client, (UCHAR *)"dhcpv6.test.example.com", &host_ipv6_address, 0, NX_IP_VERSION_V6); +} + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_INFORM_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e0b; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + /* dst port 53, dns */ + else if((src_dst_port & 0x0000FFFF) == 0x00000035) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Modify the transmit ID to be the same with the packet captured by wireshark. */ + *(USHORT *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x4d19; + + /* Modify the UDP source port to be the same value 30000(0x7530) with the packet captured by wireshark. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + udp_header_ptr -> nx_udp_header_word_0 = ((udp_header_ptr -> nx_udp_header_word_0 & 0x0000FFFF) | 0x75300000); + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_014.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_014.c new file mode 100644 index 00000000..e42c896d --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_014.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_014[]; +extern int tahi_dhcpv6_07_014_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_014_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_014[0], tahi_dhcpv6_07_014_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_015.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_015.c new file mode 100644 index 00000000..75b77a97 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_015.c @@ -0,0 +1,323 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +static void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_015[]; +extern int tahi_dhcpv6_07_015_size; + +static UCHAR original_cid[18]; + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_015_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = my_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = my_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_015[0], tahi_dhcpv6_07_015_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + + +UINT my_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_INFORM_REQUEST) + { + /* Modify the xid to be the same with Tahi test packet. */ + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e0b; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + + return NX_TRUE; + +} + +void my_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0 + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_016.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_016.c new file mode 100644 index 00000000..513a1acb --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_016.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_016[]; +extern int tahi_dhcpv6_07_016_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_016_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_016[0], tahi_dhcpv6_07_016_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_017.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_017.c new file mode 100644 index 00000000..88a410c0 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_017.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_017[]; +extern int tahi_dhcpv6_07_017_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_017_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_017[0], tahi_dhcpv6_07_017_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_018.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_018.c new file mode 100644 index 00000000..c978e4f6 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_018.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_018[]; +extern int tahi_dhcpv6_07_018_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_018_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_018[0], tahi_dhcpv6_07_018_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_019.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_019.c new file mode 100644 index 00000000..9b98945e --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_019.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_019[]; +extern int tahi_dhcpv6_07_019_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_019_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_019[0], tahi_dhcpv6_07_019_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_020.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_020.c new file mode 100644 index 00000000..499cc706 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_020.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_020[]; +extern int tahi_dhcpv6_07_020_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_020_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_020[0], tahi_dhcpv6_07_020_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_021.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_021.c new file mode 100644 index 00000000..dc559422 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_021.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_021[]; +extern int tahi_dhcpv6_07_021_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_021_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_021[0], tahi_dhcpv6_07_021_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_022.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_022.c new file mode 100644 index 00000000..1850fbd5 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_022.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_022[]; +extern int tahi_dhcpv6_07_022_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_022_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_022[0], tahi_dhcpv6_07_022_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_023.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_023.c new file mode 100644 index 00000000..e96417d7 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_023.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_023[]; +extern int tahi_dhcpv6_07_023_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_023_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_023[0], tahi_dhcpv6_07_023_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_024.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_024.c new file mode 100644 index 00000000..20020013 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_024.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_024[]; +extern int tahi_dhcpv6_07_024_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_024_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_024[0], tahi_dhcpv6_07_024_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_025.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_025.c new file mode 100644 index 00000000..f8f74e59 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_025.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_025[]; +extern int tahi_dhcpv6_07_025_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_025_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_025[0], tahi_dhcpv6_07_025_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_026.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_026.c new file mode 100644 index 00000000..3886bfc9 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_026.c @@ -0,0 +1,176 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_026[]; +extern int tahi_dhcpv6_07_026_size; + + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_026_define(void * first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_026[0], tahi_dhcpv6_07_026_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_027.c b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_027.c new file mode 100644 index 00000000..90c5b0cb --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_dhcpv6_test_07_027.c @@ -0,0 +1,238 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_udp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nxd_dhcpv6_client.h" + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define DHCPV6_IANA_ID 0xC0DEDBAD + +static TX_THREAD dhcpv6_client_thread; +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_DHCPV6 dhcp_client; + +static ULONG error_counter; + +static void dhcpv6_client_thread_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +extern UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr); +extern void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr); + +static void my_dhcpv6_info_request(); +static void my_dhcpv6_reboot(); + +extern TAHI_TEST_SEQ tahi_dhcpv6_07_027[]; +extern int tahi_dhcpv6_07_027_size; + +CHAR *pointer; +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_dhcpv6_test_07_027_define(void * first_unused_memory) +#endif +{ +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + if(status) + error_counter++; + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + if(status) + error_counter++; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + if(status) + error_counter++; + + status = nx_udp_enable(&ip_0); + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + if(status) + error_counter++; + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create the main thread. */ + tx_thread_create(&dhcpv6_client_thread, "dhcpv6 client thread", dhcpv6_client_thread_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + +} + +void dhcpv6_client_thread_entry(ULONG thread_input) +{ +NXD_ADDRESS ipv6_address; +UINT status; + + status = nxd_ipv6_address_set(&ip_0, 0, NX_NULL, 10, NX_NULL); + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + netx_tahi_set_dhcpv6_info_request(my_dhcpv6_info_request); + + netx_tahi_set_dhcpv6_reboot(my_dhcpv6_reboot); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + + advanced_packet_process_callback = tahi_dhcpv6_packet_process; + ip_0.nx_ip_udp_packet_receive = tahi_dhcpv6_udp_packet_receive; + + netx_tahi_run_test_case(&ip_0, &tahi_dhcpv6_07_027[0], tahi_dhcpv6_07_027_size); + + nx_dhcpv6_client_delete(&dhcp_client); + + test_control_return(0xdeadbeef); +} + + +void my_dhcpv6_info_request() +{ + nx_dhcpv6_request_inform_request(&dhcp_client); +} + +void my_dhcpv6_reboot() +{ + +NXD_ADDRESS ipv6_address; +UINT status; + + + nx_dhcpv6_client_delete(&dhcp_client); + + /* Create a DHCPv6 Client. */ + status = nx_dhcpv6_client_create(&dhcp_client, &ip_0, "DHCPv6 Client", &pool_0, pointer, 2048, NX_NULL, NX_NULL); + pointer += 2048; + if(status) + error_counter++; + + /* Create a Link Layer Plus Time DUID for the DHCPv6 Client. Set time ID field + to NULL; the DHCPv6 Client API will supply one. */ + status = nx_dhcpv6_create_client_duid(&dhcp_client, NX_DHCPV6_DUID_TYPE_LINK_TIME, + NX_DHCPV6_HW_TYPE_IEEE_802, 0); + if(status) + error_counter++; + + /* Create the DHCPv6 client's Identity Association (IA-NA) now. */ + status = nx_dhcpv6_create_client_iana(&dhcp_client, DHCPV6_IANA_ID, 0xFFFFFFFF, 0xFFFFFFFF); + if(status) + error_counter++; + + memset(&ipv6_address,0x0, sizeof(NXD_ADDRESS)); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6 ; + + /* Create an IA address option. */ + if((ipv6_address.nxd_ip_address.v6[0] != 0) || + (ipv6_address.nxd_ip_address.v6[1] != 0) || + (ipv6_address.nxd_ip_address.v6[2] != 0) || + (ipv6_address.nxd_ip_address.v6[3] != 0)) + { + + status = nx_dhcpv6_create_client_ia(&dhcp_client, &ipv6_address, 0xFFFFFFFF, + 0xFFFFFFFF); + + if (status != NX_SUCCESS) + { + return; + } + } + + /* Set the list of desired options to enabled. */ + nx_dhcpv6_request_option_timezone(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_DNS_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_time_server(&dhcp_client, NX_TRUE); + nx_dhcpv6_request_option_domain_name(&dhcp_client, NX_TRUE); + + /* Wait to finish the DAD. */ + tx_thread_sleep(5 * NX_IP_PERIODIC_RATE); + + /* Start the NetX DHCPv6 Client. */ + status = nx_dhcpv6_start(&dhcp_client); + if(status) + error_counter++; +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_run_test_case.c b/test/regression/tahi_test/netx_tahi_run_test_case.c new file mode 100644 index 00000000..ea6e54c6 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_run_test_case.c @@ -0,0 +1,1165 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_udp.h" +#include "nxd_dhcpv6_client.h" +#ifdef NX_IPSEC_ENABLE +#include "nx_ipsec.h" +#endif + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define MAX_PACKET_SIZE 1600 + +/* Define the ThreadX and NetX object control blocks... */ + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static ULONG original_xid; +static UCHAR original_cid[18]; + +/* Define thread prototypes. */ +extern void test_control_return(UINT status); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static UINT in_cleanup_process; +static TX_MUTEX pkt_capture_mutex; +static TX_SEMAPHORE pkt_count_sem; +static int pkt_capture_flag = 0; +static UCHAR packet_data[MAX_PACKET_SIZE]; +#ifdef NX_IPSEC_ENABLE +static NX_PACKET *assemble_pkt; +static UCHAR assemble_pkt_data[MAX_PACKET_SIZE]; +static UINT fragment_cnt = 0; +#endif + + +static NX_PACKET *incoming_pkts = NX_NULL; +static NX_PACKET *incoming_pkts_tail = NX_NULL; + +static NX_DHCPV6 *tahi_dhcpv6_client_ptr; +static void (*tahi_dhcpv6_reboot)(); +static void (*tahi_dhcpv6_info_request)(); +static void (*tahi_dhcpv6_dns)(); + +static void perform_check(char *pkt_data, int pkt_size, int timeout) +{ +UINT status; +NX_PACKET *current_pkt; +ULONG start_time, current_time, time_remaining; +ULONG bytes_copied; + + /* Compute the amount of time to wait for. */ + start_time = current_time = tx_time_get(); + + /* timeout value is expressed in terms of seconds. Convert it to ticks. */ + time_remaining = timeout - (current_time - start_time); + + + while(time_remaining > 0) + { + /* Wait for a packet. */ + status = tx_semaphore_get(&pkt_count_sem, time_remaining); + + if(status == NX_SUCCESS) + { + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + current_pkt = incoming_pkts; + if(incoming_pkts) + { + incoming_pkts = incoming_pkts -> nx_packet_queue_next; + } + else + { + incoming_pkts_tail = NX_NULL; + } + tx_mutex_put(&pkt_capture_mutex); + + if(current_pkt) + { + + /* A packet has been queued. Examine the content of the packet. */ + status = nx_packet_data_retrieve(current_pkt, packet_data, &bytes_copied); + + if((status != NX_SUCCESS) || + ((UINT)(pkt_size - 14) != bytes_copied) || + (memcmp(pkt_data + 14, packet_data, bytes_copied) != 0)) + { + /* Not a match. */ + + /* Compute new timeout value. */ + current_time = tx_time_get(); + time_remaining = timeout - (current_time - start_time); + if(time_remaining > 0x80000000) + { + /* Underflow */ + time_remaining = 0; + error_counter = 1; + } + nx_packet_release(current_pkt); + continue; + } + else + { + /* Packet is a match. Get out of this CHECK state. */ + time_remaining = 0; + nx_packet_release(current_pkt); + continue; + } + } + } + else + { + /* Timeout */ + error_counter = 1; + time_remaining = 0; + } + } +} + +static void perform_null_check(int pkt_data, int pkt_size, int timeout) +{ +UINT status; +NX_PACKET *current_pkt; +ULONG start_time, current_time, time_remaining; +NX_UDP_HEADER *udp_header_ptr; +ULONG dst_port; + + + + /* Compute the amount of time to wait for. */ + start_time = current_time = tx_time_get(); + + /* timeout value is expressed in terms of seconds. Convert it to ticks. */ + time_remaining = timeout - (current_time - start_time); + + while(time_remaining > 0) + { + /* Wait for a packet. */ + status = tx_semaphore_get(&pkt_count_sem, time_remaining); + + /* Did not receive any packet. */ + if (status != NX_SUCCESS) + break; + + /* Compute the amount of time to wait for. */ + current_time = tx_time_get(); + + /* Compute remaining ticks. */ + time_remaining = timeout - (current_time - start_time); + if(time_remaining > 0x80000000) + { + /* Underflow */ + time_remaining = 0; + } + + /* Receive a packet. */ + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + current_pkt = incoming_pkts; + if(incoming_pkts) + { + incoming_pkts = incoming_pkts -> nx_packet_queue_next; + } + else + { + incoming_pkts_tail = NX_NULL; + } + tx_mutex_put(&pkt_capture_mutex); + + if (!current_pkt) + continue; + + /* Check this is a IPV6 packet. */ +/* + if (*(current_pkt -> nx_packet_prepend_ptr - 2) != 0x86 || + *(current_pkt -> nx_packet_prepend_ptr - 1) != 0xdd) + continue;*/ + + + /* Check next header ia a ICMPv6 header. */ + if (*(current_pkt -> nx_packet_prepend_ptr + 6) != 0x3a) + continue; + + /* Get destination UDP port */ + udp_header_ptr = (NX_UDP_HEADER*)(current_pkt-> nx_packet_prepend_ptr + 40); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + + switch(pkt_data) + { + case NA: + if (*(current_pkt -> nx_packet_prepend_ptr + 40) == 0x88) + { + error_counter = 1; + time_remaining = 0; + nx_packet_release(current_pkt); + } + break; + + case NS: + if (*(current_pkt -> nx_packet_prepend_ptr + 40) == 0x87) + { + if (pkt_size == NS_UNSPEC) + { + CHECK_UNSPECIFIED_ADDRESS((ULONG *)(current_pkt -> nx_packet_prepend_ptr + 8)); + break; + } + error_counter = 1; + time_remaining = 0; + nx_packet_release(current_pkt); + } + break; + + case RS: + if (*(current_pkt -> nx_packet_prepend_ptr + 40) == 0x85) + { + error_counter = 1; + time_remaining = 0; + nx_packet_release(current_pkt); + } + break; + + case ER: + if (*(current_pkt -> nx_packet_prepend_ptr + 40) == 0x81) + { + error_counter = 1; + time_remaining = 0; + nx_packet_release(current_pkt); + } + break; + case RELEASE: + if ((((dst_port & 0x0000FFFF) == 0x00000222) || ((dst_port & 0x0000FFFF) == 0x00000223)) && + (*(current_pkt -> nx_packet_prepend_ptr + 48) == 0x08)) + { + error_counter = 1; + time_remaining = 0; + nx_packet_release(current_pkt); + } + break; + case DECLINE: + if ((((dst_port & 0x0000FFFF) == 0x00000222) || ((dst_port & 0x0000FFFF) == 0x00000223)) && + (*(current_pkt -> nx_packet_prepend_ptr + 48) == 0x09)) + { + error_counter = 1; + time_remaining = 0; + nx_packet_release(current_pkt); + } + break; + case REQUEST: + if ((((dst_port & 0x0000FFFF) == 0x00000222) || ((dst_port & 0x0000FFFF) == 0x00000223)) && + (*(current_pkt -> nx_packet_prepend_ptr + 48) == 0x03)) + { + error_counter = 1; + time_remaining = 0; + nx_packet_release(current_pkt); + } + break; + + case ANY: + if(((dst_port & 0x0000FFFF) == 0x00000222) || ((dst_port & 0x0000FFFF) == 0x00000223)) + { + error_counter = 1; + time_remaining = 0; + nx_packet_release(current_pkt); + } + break; + + + + default: + break; + } + } +} + +#ifdef NX_IPSEC_ENABLE +static void perform_decrypt_check(NX_IP *ip_ptr, char *pkt_data, int pkt_size, int timeout, int is_tunneled, + UCHAR protocol, ULONG src_port, ULONG dst_port, UINT option) +{ + UINT status; + NX_PACKET *current_pkt; + ULONG start_time, current_time, time_remaining; + NX_IPSEC_SA *egress_sa_ptr; + UCHAR *iv_ptr_cur, *iv_ptr_data; + UCHAR *input_payload_ptr_cur, *input_payload_ptr_data; + UINT input_payload_size; + NX_IPV6_HEADER *ipv6_header; + NXD_ADDRESS src_addr, dest_addr; + ULONG data_offset; + UINT icv_size, iv_size; /* in bytes */ + NX_IPSEC_SA *cur_sa_ptr; + NX_IPSEC_ESP_HEADER *esp_header_ptr; + + /* Compute the amount of time to wait for. */ + start_time = current_time = tx_time_get(); + + /* timeout value is expressed in terms of seconds. Convert it to ticks. */ + time_remaining = timeout - (current_time - start_time); + + + while(time_remaining > 0) + { + /* Wait for a packet. */ + status = tx_semaphore_get(&pkt_count_sem, time_remaining); + + if(status == NX_SUCCESS) + { + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + current_pkt = incoming_pkts; + if(incoming_pkts) + { + incoming_pkts = incoming_pkts -> nx_packet_queue_next; + } + else + { + incoming_pkts_tail = NX_NULL; + } + tx_mutex_put(&pkt_capture_mutex); + + if(current_pkt) + { + + /* A packet has been queued. Examine the header of the packet. + Include IPv6 header and ESP header in transport mode. */ + if(((UINT)(pkt_size - 14) != current_pkt -> nx_packet_length) || + (memcmp(pkt_data + 14, current_pkt -> nx_packet_prepend_ptr, 40) != 0)) + { + /* Not a match. */ + + /* Compute new timeout value. */ + current_time = tx_time_get(); + time_remaining = timeout - (current_time - start_time); + if(time_remaining > 0x80000000) + { + /* Underflow */ + time_remaining = 0; + error_counter = 1; + } + nx_packet_release(current_pkt); + continue; + } + else + { + + /* Get SA. */ + ipv6_header = (NX_IPV6_HEADER*)(current_pkt -> nx_packet_prepend_ptr); + + src_addr.nxd_ip_version = NX_IP_VERSION_V6; + dest_addr.nxd_ip_version = NX_IP_VERSION_V6; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ipv6_header -> nx_ip_header_destination_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ipv6_header -> nx_ip_header_source_ip); + + COPY_IPV6_ADDRESS(ipv6_header -> nx_ip_header_source_ip, + src_addr.nxd_ip_address.v6); + + + COPY_IPV6_ADDRESS(ipv6_header -> nx_ip_header_destination_ip, + dest_addr.nxd_ip_address.v6); + + /* Get SA. */ + if (is_tunneled == NX_TRUE) + { + cur_sa_ptr = ip_ptr -> nx_ip_ipsec_egress_sa_ptr; + status = NX_IPSEC_TRAFFIC_BYPASS; + + esp_header_ptr = (NX_IPSEC_ESP_HEADER*)(current_pkt -> nx_packet_prepend_ptr + 40); + + if (cur_sa_ptr != NX_NULL) + { + do + { + + /* Determine if the SA has been found based on traffic selection. */ + if (CHECK_IPV6_ADDRESSES_SAME(dest_addr.nxd_ip_address.v6, + cur_sa_ptr -> nx_ipsec_tunnel_exit_address.nxd_ip_address.v6) && + esp_header_ptr -> nx_ipsec_esp_spi == cur_sa_ptr -> nx_ipsec_sa_spi) + { + + status = NX_IPSEC_TRAFFIC_PROTECT; + egress_sa_ptr = cur_sa_ptr; + break; + } + else + { + + /* Move to the next entry in the SA list. */ + cur_sa_ptr = cur_sa_ptr -> nx_ipsec_sa_created_next; + } + } while (cur_sa_ptr != ip_ptr -> nx_ip_ipsec_egress_sa_ptr); + } + } + else + { + status = _nx_ipsec_sa_egress_lookup(ip_ptr, &src_addr, &dest_addr, + protocol, src_port, dst_port, + &data_offset, &egress_sa_ptr, option); + } + + if (status != NX_IPSEC_TRAFFIC_PROTECT) + { + nx_packet_release(current_pkt); + continue; + } + + /* Packet is a match. Decrypt packets. */ + icv_size = egress_sa_ptr -> nx_ipsec_sa_integrity_method -> nx_crypto_ICV_size_in_bits >> 3; + iv_size = egress_sa_ptr -> nx_ipsec_sa_encryption_method -> nx_crypto_IV_size_in_bits >> 3; + iv_ptr_data = (UCHAR *)pkt_data + 14 + 40 + sizeof(NX_IPSEC_ESP_HEADER); + iv_ptr_cur = current_pkt -> nx_packet_prepend_ptr + 40 + sizeof(NX_IPSEC_ESP_HEADER); + input_payload_size = pkt_size - 14 - 40 - sizeof(NX_IPSEC_ESP_HEADER) - icv_size - iv_size; + input_payload_ptr_data = iv_ptr_data + iv_size; + input_payload_ptr_cur = iv_ptr_cur + iv_size; + + status = _nx_ipsec_cryption_process(egress_sa_ptr, egress_sa_ptr -> nx_ipsec_sa_encryption_method, NX_CRYPTO_DECRYPT, + (CHAR) egress_sa_ptr -> nx_ipsec_sa_encryption_method -> nx_crypto_algorithm, + egress_sa_ptr -> nx_ipsec_sa_encrypt_key_string, + egress_sa_ptr -> nx_ipsec_sa_encrypt_key_len_in_bits, + iv_ptr_data, (egress_sa_ptr -> nx_ipsec_sa_encryption_method -> nx_crypto_IV_size_in_bits >> 3), + egress_sa_ptr -> nx_ipsec_sa_encryption_method -> nx_crypto_block_size_in_bytes, + input_payload_ptr_data, input_payload_size, + input_payload_ptr_data, input_payload_size, current_pkt); + + if (status != NX_SUCCESS) + { + nx_packet_release(current_pkt); + continue; + } + + status = _nx_ipsec_cryption_process(egress_sa_ptr, egress_sa_ptr -> nx_ipsec_sa_encryption_method, NX_CRYPTO_DECRYPT, + (CHAR) egress_sa_ptr -> nx_ipsec_sa_encryption_method -> nx_crypto_algorithm, + egress_sa_ptr -> nx_ipsec_sa_encrypt_key_string, + egress_sa_ptr -> nx_ipsec_sa_encrypt_key_len_in_bits, + iv_ptr_cur, iv_size, + egress_sa_ptr -> nx_ipsec_sa_encryption_method -> nx_crypto_block_size_in_bytes, + input_payload_ptr_cur, input_payload_size, + input_payload_ptr_cur, input_payload_size, current_pkt); + + if (status != NX_SUCCESS) + { + nx_packet_release(current_pkt); + continue; + } + + if (memcmp(input_payload_ptr_cur, input_payload_ptr_data, input_payload_size) == 0) + { + time_remaining = 0; + } + + nx_packet_release(current_pkt); + continue; + } + } + } + else + { + /* Timeout */ + if(pkt_data != NX_NULL) + { + /* We expect a packet. */ + + + error_counter = 1; + } + time_remaining = 0; + } + } +} + + + + +static void perform_assemble(NX_IP *ip_ptr, char *pkt_data, int pkt_size, int timeout, int is_last) +{ + UINT status; + NX_PACKET *current_pkt; + ULONG start_time, current_time, time_remaining; + + /* Compute the amount of time to wait for. */ + start_time = current_time = tx_time_get(); + + /* timeout value is expressed in terms of seconds. Convert it to ticks. */ + time_remaining = timeout - (current_time - start_time); + + + while(time_remaining > 0) + { + /* Wait for a packet. */ + status = tx_semaphore_get(&pkt_count_sem, time_remaining); + + if(status == NX_SUCCESS) + { + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + current_pkt = incoming_pkts; + if(incoming_pkts) + { + incoming_pkts = incoming_pkts -> nx_packet_queue_next; + } + else + { + incoming_pkts_tail = NX_NULL; + } + tx_mutex_put(&pkt_capture_mutex); + + if(current_pkt) + { + + /* A packet has been queued. Examine the header of the packet. + Include IPv6 header and Fragmentation header in transport mode. */ + if(((UINT)(pkt_size - 14) != current_pkt -> nx_packet_length) || + (memcmp(pkt_data + 14, current_pkt -> nx_packet_prepend_ptr, 40) != 0)) + { + /* Not a match. */ + + /* Compute new timeout value. */ + current_time = tx_time_get(); + time_remaining = timeout - (current_time - start_time); + if(time_remaining > 0x80000000) + { + /* Underflow */ + time_remaining = 0; + error_counter = 1; + } + nx_packet_release(current_pkt); + continue; + } + else + { + /* Packet is a match. Assemble packet. */ + + if (fragment_cnt == 0) + { + /* Allocate a packet. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &assemble_pkt, 0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + nx_packet_release(current_pkt); + continue; + } + + memcpy(assemble_pkt_data, pkt_data, 54); + + /* Copy IPv6 header. */ + memcpy(assemble_pkt -> nx_packet_append_ptr, current_pkt -> nx_packet_prepend_ptr, 40); + assemble_pkt -> nx_packet_append_ptr += 40; + + /* Initial packet length to IPv6 header length. */ + assemble_pkt -> nx_packet_length = 40; + } + + memcpy(assemble_pkt_data + (assemble_pkt -> nx_packet_length + 14), pkt_data + 62, pkt_size - 62); + + /* Append packet data. */ + memcpy(assemble_pkt -> nx_packet_append_ptr, current_pkt -> nx_packet_prepend_ptr + 48, current_pkt -> nx_packet_length - 48); + assemble_pkt -> nx_packet_append_ptr += current_pkt -> nx_packet_length - 48; + + /* Increase packet length by data. */ + assemble_pkt -> nx_packet_length += current_pkt -> nx_packet_length - 48; + + fragment_cnt++; + + /* Put assembled packet to incoming packet chain. */ + if (is_last == NX_TRUE) + { + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + + if(incoming_pkts == NX_NULL) + { + incoming_pkts = assemble_pkt; + } + else + { + incoming_pkts_tail -> nx_packet_queue_next = assemble_pkt; + } + incoming_pkts_tail = assemble_pkt; + + assemble_pkt -> nx_packet_queue_next = NX_NULL; + + tx_mutex_put(&pkt_capture_mutex); + + tx_semaphore_put(&pkt_count_sem); + + fragment_cnt = 0; + + } + + time_remaining = 0; + nx_packet_release(current_pkt); + continue; + } + } + } + else + { + /* Timeout */ + if(pkt_data != NX_NULL) + { + /* We expect a packet. */ + + + error_counter = 1; + } + time_remaining = 0; + } + } +} +#endif + +static void inject_packet(NX_IP *ip_ptr, char *pkt_data, int pkt_size) +{ + +UINT status; +NX_PACKET *my_packet; + + /* Now, this packet is a received one, allocate the packet and let the IP stack receives it. */ + /* Allocate a packet. */ + status = nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &my_packet, 0, NX_WAIT_FOREVER); + + /* Check status. */ + if (status != NX_SUCCESS) + { + error_counter++; + return; + } + + my_packet -> nx_packet_length = pkt_size - 14; + memcpy(my_packet -> nx_packet_prepend_ptr + 16, pkt_data + 14, my_packet -> nx_packet_length); + my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + my_packet -> nx_packet_length; + + my_packet -> nx_packet_prepend_ptr += 16; + my_packet -> nx_packet_append_ptr += 16; + + _nx_ip_packet_deferred_receive(ip_ptr, my_packet); + +} + +static void dump_packets(void) +{ + + NX_PACKET *tmp_pkt; + + tmp_pkt = incoming_pkts; + + while(tmp_pkt) + { + tx_semaphore_get(&pkt_count_sem, 0); + incoming_pkts = tmp_pkt -> nx_packet_queue_next; + nx_packet_release(tmp_pkt); + tmp_pkt = incoming_pkts; + } + incoming_pkts = NX_NULL; + +} + +/* Make sure the packet initial is right. */ +static void clean_hop_limit(NX_IP *ip_ptr) +{ + + /* Add by wangyang for the simulation TAHI test in VS. */ + ip_ptr -> nx_ipv6_hop_limit = 0xff; +} + +/* Do ping6 process. */ +static void perform_check_v6request(NX_IP *ip_ptr, UCHAR flag, UINT length, char *pkt_data, int pkt_size, int timeout) +{ + + /* Define the variable for ping6 process. */ + NXD_ADDRESS ping6add1; + CHAR ping6data1[1452]= "12"; + NX_PACKET *my_packet; + int i; + + /* flag = 0 means pmtu.p2 ping6 test. */ + /* flag = 1 means icmp.p2 ping6 test. */ + if (flag == 0) + { + ping6add1.nxd_ip_version = NX_IP_VERSION_V6; + ping6add1.nxd_ip_address.v6[0] = 0xFF1E0000; + ping6add1.nxd_ip_address.v6[1] = 0x00000000; + ping6add1.nxd_ip_address.v6[2] = 0x00000000; + ping6add1.nxd_ip_address.v6[3] = 0x00010002; + + for(i = 0; i < 1452; i++) + ping6data1[i] = '0'; + } + else + { + ping6add1.nxd_ip_version = NX_IP_VERSION_V6; + ping6add1.nxd_ip_address.v6[0] = 0xfe800000; + ping6add1.nxd_ip_address.v6[1] = 0x00000000; + ping6add1.nxd_ip_address.v6[2] = 0x020000ff; + ping6add1.nxd_ip_address.v6[3] = 0xfe000100; + } + + /* used for icmp.p2 test and do ping6 process. */ + nxd_icmp_ping(ip_ptr, &ping6add1, ping6data1, length, &my_packet, 0); + + /* Invoke the check function to check the ping6 request packet. */ + perform_check(pkt_data, pkt_size, timeout); +} + +/* Reboot process. */ +static void perform_reboot(NX_IP *ip_ptr) +{ + +static NXD_ADDRESS ipv6_address_1; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + nx_ip_fragment_disable(ip_ptr); + + if(ip_ptr -> nx_ipv6_address[0].nxd_ipv6_address[0]) + nxd_ipv6_address_delete(ip_ptr, 0); + if(ip_ptr -> nx_ipv6_address[1].nxd_ipv6_address[0]) + nxd_ipv6_address_delete(ip_ptr, 1); + + ip_ptr -> nx_ipv6_packet_receive = NULL; + + /* nx_ipv6_hop_limit make sure the after reboot process the limit is back to the 0xff. */ + ip_ptr -> nx_ipv6_hop_limit = 0xff; + + /* nx_ip_packet_id affects the fragment identifier. */ + ip_ptr -> nx_ip_packet_id = NX_INIT_PACKET_ID; + + /* nx_ip_icmp_sequence affects the ping6 request sequence. */ + ip_ptr -> nx_ip_icmp_sequence = 0; + + /* Enable IPv6 */ + nxd_ipv6_enable(ip_ptr); + + /* Enable ICMPv6 */ + nxd_icmp_enable(ip_ptr); + + nx_ip_fragment_enable(ip_ptr); + + nxd_ipv6_address_set(ip_ptr, 0, &ipv6_address_1,64, NX_NULL); +} + +static void dhcpv6_confirm() +{ + nx_dhcpv6_request_confirm(tahi_dhcpv6_client_ptr); +} + +static void dhcpv6_release() +{ + nx_dhcpv6_request_release(tahi_dhcpv6_client_ptr); +} + +void netx_tahi_set_dhcpv6(NX_DHCPV6 *dhcpv6_client_ptr) +{ + tahi_dhcpv6_client_ptr = dhcpv6_client_ptr; +} + +void netx_tahi_set_dhcpv6_dns(void (*dhcpv6_dns)()) +{ + tahi_dhcpv6_dns = dhcpv6_dns; +} + +void netx_tahi_set_dhcpv6_reboot(void (*dhcpv6_reboot)()) +{ + tahi_dhcpv6_reboot = dhcpv6_reboot; +} + +void netx_tahi_set_dhcpv6_info_request(void (*dhcpv6_info_request)()) +{ + tahi_dhcpv6_info_request = dhcpv6_info_request; +} + +extern ULONG test_control_successful_tests; +extern ULONG test_control_failed_tests; +static int steps; +void netx_tahi_run_test_case(NX_IP *ip_ptr, TAHI_TEST_SEQ *test_case, int test_case_size) +{ + + int i; + + /* Init the semaphore and mutex. */ + tx_mutex_create(&pkt_capture_mutex, "TAHI PKT CAPTURE", 0); + tx_semaphore_create(&pkt_count_sem, "TAHI_PKT COUNT SEM", 0); + + /* Set the flag to queue up packets. */ + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + pkt_capture_flag = 1; + tx_mutex_put(&pkt_capture_mutex); + + packet_process_callback = packet_process; + + in_cleanup_process = 0; + error_counter = 0; + for(steps = 0; steps < test_case_size; steps++) + { + + /* If error has occured, skip all the test steps and start the cleanup process. */ + if(error_counter && !in_cleanup_process) + { + if(test_case[steps].command != CLEANUP) + continue; + } + + switch(test_case[steps].command) + { + case CLEANUP: + /* This is a marker. Nothing needs to be done here. */ + in_cleanup_process = 1; + continue; + + case TITLE: + printf("NetX Test: TAHI %s TEST", test_case[steps].pkt_data); + + /* Align the output. */ + for (i = test_case[steps].pkt_size; i <= 47; i++) + printf("."); + break; + case INJECT: + inject_packet(ip_ptr, test_case[steps].pkt_data, test_case[steps].pkt_size); + break; + case WAIT: + tx_thread_sleep(test_case[steps].timeout * NX_IP_PERIODIC_RATE); + break; + case CHECK: + perform_check(test_case[steps].pkt_data, test_case[steps].pkt_size, test_case[steps].timeout* NX_IP_PERIODIC_RATE + 2); + break; + case N_CHECK: + perform_null_check((int)test_case[steps].pkt_data, test_case[steps].pkt_size, test_case[steps].timeout* NX_IP_PERIODIC_RATE); + break; + case DUMP: + dump_packets(); + break; + case CLEAN_HOP_LIMIT: + clean_hop_limit(ip_ptr); + break; + case CHECK_V6REQUEST: + perform_check_v6request(ip_ptr,test_case[steps].protocol, test_case[steps].option, test_case[steps].pkt_data, test_case[steps].pkt_size, test_case[steps].timeout* NX_IP_PERIODIC_RATE + 2); + break; + case REBOOT: + perform_reboot(ip_ptr); + break; + case DHCPV6_REBOOT: + perform_reboot(ip_ptr); + tahi_dhcpv6_reboot(); + break; + case DHCPV6_INFO_REQUEST: + tahi_dhcpv6_info_request(); + break; + case DHCPV6_DNS: + tahi_dhcpv6_dns(); + break; + case DHCPV6_CONFIRM: + dhcpv6_confirm(); + break; + case DHCPV6_RELEASE: + dhcpv6_release(); + break; +#ifdef NX_IPSEC_ENABLE + case D_CHECK: + perform_decrypt_check(ip_ptr, test_case[steps].pkt_data, test_case[steps].pkt_size, test_case[steps].timeout* NX_IP_PERIODIC_RATE + 2, NX_FALSE, + test_case[steps].protocol, test_case[steps].src_port, test_case[steps].dst_port, test_case[steps].option); + break; + case ASSEMBLE: + perform_assemble(ip_ptr, test_case[steps].pkt_data, test_case[steps].pkt_size, test_case[steps].timeout* NX_IP_PERIODIC_RATE + 2, NX_FALSE); + break; + case AD_CHECK: + perform_assemble(ip_ptr, test_case[steps].pkt_data, test_case[steps].pkt_size, test_case[steps].timeout* NX_IP_PERIODIC_RATE + 2, NX_TRUE); + perform_decrypt_check(ip_ptr, (CHAR *)assemble_pkt_data, assemble_pkt -> nx_packet_length + 14, test_case[steps].timeout* NX_IP_PERIODIC_RATE + 2, NX_FALSE, + (UCHAR)test_case[steps].protocol, test_case[steps].src_port, test_case[steps].dst_port, test_case[steps].option); + break; + case TD_CHECK: + perform_decrypt_check(ip_ptr, test_case[steps].pkt_data, test_case[steps].pkt_size, test_case[steps].timeout* NX_IP_PERIODIC_RATE + 2, NX_TRUE, + test_case[steps].protocol, test_case[steps].src_port, test_case[steps].dst_port, test_case[steps].option); + break; +#endif + default: + break; + } + } + /* Set the flag to queue up packets. */ + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + pkt_capture_flag = 0; + tx_mutex_put(&pkt_capture_mutex); + dump_packets(); + /* Check for earlier error. */ + if(error_counter) + { + printf("ERROR!\n"); + test_control_failed_tests++; + } + else + { + printf("SUCCESS!\n"); + test_control_successful_tests++; + } + + tx_mutex_delete(&pkt_capture_mutex); + tx_semaphore_delete(&pkt_count_sem); +} + +static UINT packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + + tx_mutex_get(&pkt_capture_mutex, TX_WAIT_FOREVER); + if(pkt_capture_flag == 0) + { + nx_packet_release(packet_ptr); + tx_mutex_put(&pkt_capture_mutex); + return NX_NULL; + } + + if(incoming_pkts == NX_NULL) + { + incoming_pkts = packet_ptr; + } + else + { + incoming_pkts_tail -> nx_packet_queue_next = packet_ptr; + } + incoming_pkts_tail = packet_ptr; + + packet_ptr -> nx_packet_queue_next = NX_NULL; + + tx_mutex_put(&pkt_capture_mutex); + + tx_semaphore_put(&pkt_count_sem); + + return NX_NULL; +} + +UINT tahi_dhcpv6_packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr) +{ +NX_UDP_HEADER *udp_header_ptr; +ULONG src_dst_port; +ULONG message_type; +NX_IPV6_HEADER *ip_header; +ULONG checksum; +ULONG *ip_src_addr, *ip_dest_addr; +UCHAR cid[18] = {0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x01, + 0xac, 0x7d, 0x87, 0x3a, 0x00, 0x11, 0x22, 0x33, + 0x44, 0x56}; + + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr + 40); + src_dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(src_dst_port); + + + /* From port 546(client) to 547(server). Check if this is a DHCPv6 packet sent from client to server*/ + if(src_dst_port == 0x02220223) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + /* Get message type. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + + if(message_type == NX_DHCPV6_MESSAGE_TYPE_SOLICIT) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e01; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x900e0803; + } + else if((message_type == NX_DHCPV6_MESSAGE_TYPE_CONFIRM) || + (message_type == NX_DHCPV6_MESSAGE_TYPE_RENEW) || + (message_type == NX_DHCPV6_MESSAGE_TYPE_REBIND) || + (message_type == NX_DHCPV6_MESSAGE_TYPE_RELEASE) || + (message_type == NX_DHCPV6_MESSAGE_TYPE_DECLINE)) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x66915200 + message_type; + } + else if(message_type == NX_DHCPV6_MESSAGE_TYPE_INFORM_REQUEST) + { + /* Record original xid, modify the xid to be the same with Tahi test packet. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 9, 3, &original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0x12f03e0b; + } + + /* Record original cid, modify the cid to be the same with Tahi test packet. */ + memcpy(original_cid, (packet_ptr -> nx_packet_prepend_ptr + 12), 18); + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + } + /* dst port 53, dns */ + else if((src_dst_port & 0x0000FFFF) == 0x00000035) + { + packet_ptr -> nx_packet_prepend_ptr += 40; + packet_ptr -> nx_packet_length -= 40; + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr = &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the transmit ID to be the same with the packet captured by wireshark. */ + *(USHORT *)(packet_ptr -> nx_packet_prepend_ptr + 8) = 0xf907; + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + packet_ptr -> nx_packet_prepend_ptr -= 40; + packet_ptr -> nx_packet_length += 40; + + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_source_ip); + NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header -> nx_ip_header_destination_ip); + + } + + return NX_TRUE; + +} + +void tahi_dhcpv6_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr) +{ + +ULONG *ip_src_addr, *ip_dest_addr; +ULONG dst_port; +NX_UDP_HEADER *udp_header_ptr; +ULONG checksum; +NX_IPV6_HEADER *ip_header; +ULONG message_type; + + udp_header_ptr = (NX_UDP_HEADER*)(packet_ptr -> nx_packet_prepend_ptr); + dst_port = udp_header_ptr -> nx_udp_header_word_0; + NX_CHANGE_ULONG_ENDIAN(dst_port); + + /* Check if this is a DHCPv6 packet sent to client. */ + if((dst_port & 0x0000FFFF) == 0x00000222) + { + + /* Get IP address for checksum computing. */ + ip_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header); + ip_src_addr = &(ip_header -> nx_ip_header_source_ip[0]); + ip_dest_addr= &(ip_header -> nx_ip_header_destination_ip[0]); + + + /* Modify the xid and cid. */ + _nx_dhcpv6_utility_get_data(packet_ptr -> nx_packet_prepend_ptr + 8, 1, &message_type); + NX_CHANGE_ULONG_ENDIAN(original_xid); + *(ULONG *)(packet_ptr -> nx_packet_prepend_ptr + 8) = original_xid + message_type; + memcpy(packet_ptr -> nx_packet_prepend_ptr + 12, original_cid, 18); + + + /* Compute the checksum. */ + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + /* Yes, we need to compute the UDP checksum. */ + checksum = _nx_ip_checksum_compute(packet_ptr, + NX_PROTOCOL_UDP, + packet_ptr -> nx_packet_length, + ip_src_addr, + ip_dest_addr); + checksum = ~checksum & NX_LOWER_16_MASK; + + /* If the computed checksum is zero, it is transmitted as all ones. */ + /* RFC 768, page 2. */ + if(checksum == 0) + checksum = 0xFFFF; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 & 0xFFFF0000; + + udp_header_ptr -> nx_udp_header_word_1 = udp_header_ptr -> nx_udp_header_word_1 | checksum; + + NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_1); + } + + _nx_udp_packet_receive(ip_ptr, packet_ptr); + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_1.c b/test/regression/tahi_test/netx_tahi_test_1.c new file mode 100644 index 00000000..49d01ffc --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_1.c @@ -0,0 +1,305 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_01_001[]; +extern TAHI_TEST_SEQ tahi_01_002[]; +extern TAHI_TEST_SEQ tahi_01_003[]; +extern TAHI_TEST_SEQ tahi_01_004[]; +extern TAHI_TEST_SEQ tahi_01_005[]; +extern TAHI_TEST_SEQ tahi_01_006[]; +extern TAHI_TEST_SEQ tahi_01_007[]; +extern TAHI_TEST_SEQ tahi_01_008[]; +extern TAHI_TEST_SEQ tahi_01_009[]; +extern TAHI_TEST_SEQ tahi_01_010[]; +extern TAHI_TEST_SEQ tahi_01_011[]; +extern TAHI_TEST_SEQ tahi_01_012[]; +extern TAHI_TEST_SEQ tahi_01_013[]; +extern TAHI_TEST_SEQ tahi_01_014[]; +extern TAHI_TEST_SEQ tahi_01_015[]; +extern TAHI_TEST_SEQ tahi_01_016[]; +extern TAHI_TEST_SEQ tahi_01_017[]; +extern TAHI_TEST_SEQ tahi_01_018[]; +extern TAHI_TEST_SEQ tahi_01_019[]; +extern TAHI_TEST_SEQ tahi_01_020[]; +extern TAHI_TEST_SEQ tahi_01_021[]; +extern TAHI_TEST_SEQ tahi_01_022[]; +extern TAHI_TEST_SEQ tahi_01_023[]; +extern TAHI_TEST_SEQ tahi_01_024[]; +extern TAHI_TEST_SEQ tahi_01_025[]; +extern TAHI_TEST_SEQ tahi_01_026[]; +extern TAHI_TEST_SEQ tahi_01_027[]; +extern TAHI_TEST_SEQ tahi_01_028[]; +extern TAHI_TEST_SEQ tahi_01_029[]; +extern TAHI_TEST_SEQ tahi_01_030[]; +extern TAHI_TEST_SEQ tahi_01_031[]; +extern TAHI_TEST_SEQ tahi_01_032[]; +extern TAHI_TEST_SEQ tahi_01_033[]; +extern TAHI_TEST_SEQ tahi_01_034[]; +extern TAHI_TEST_SEQ tahi_01_035[]; +extern TAHI_TEST_SEQ tahi_01_036[]; +extern TAHI_TEST_SEQ tahi_01_037[]; +extern TAHI_TEST_SEQ tahi_01_038[]; +extern TAHI_TEST_SEQ tahi_01_039[]; +extern TAHI_TEST_SEQ tahi_01_040[]; +extern TAHI_TEST_SEQ tahi_01_041[]; +extern TAHI_TEST_SEQ tahi_01_042[]; +extern TAHI_TEST_SEQ tahi_01_043[]; +extern TAHI_TEST_SEQ tahi_01_044[]; +extern TAHI_TEST_SEQ tahi_01_045[]; +extern TAHI_TEST_SEQ tahi_01_046[]; +extern TAHI_TEST_SEQ tahi_01_047[]; +extern TAHI_TEST_SEQ tahi_01_048[]; +extern TAHI_TEST_SEQ tahi_01_049[]; +extern TAHI_TEST_SEQ tahi_01_050[]; +extern TAHI_TEST_SEQ tahi_01_051[]; +extern TAHI_TEST_SEQ tahi_01_052[]; +extern TAHI_TEST_SEQ tahi_01_053[]; +extern TAHI_TEST_SEQ tahi_01_054[]; + +extern int tahi_01_001_size; +extern int tahi_01_002_size; +extern int tahi_01_003_size; +extern int tahi_01_004_size; +extern int tahi_01_005_size; +extern int tahi_01_006_size; +extern int tahi_01_007_size; +extern int tahi_01_008_size; +extern int tahi_01_009_size; +extern int tahi_01_010_size; +extern int tahi_01_011_size; +extern int tahi_01_012_size; +extern int tahi_01_013_size; +extern int tahi_01_014_size; +extern int tahi_01_015_size; +extern int tahi_01_016_size; +extern int tahi_01_017_size; +extern int tahi_01_018_size; +extern int tahi_01_019_size; +extern int tahi_01_020_size; +extern int tahi_01_021_size; +extern int tahi_01_022_size; +extern int tahi_01_023_size; +extern int tahi_01_024_size; +extern int tahi_01_025_size; +extern int tahi_01_026_size; +extern int tahi_01_027_size; +extern int tahi_01_028_size; +extern int tahi_01_029_size; +extern int tahi_01_030_size; +extern int tahi_01_031_size; +extern int tahi_01_032_size; +extern int tahi_01_033_size; +extern int tahi_01_034_size; +extern int tahi_01_035_size; +extern int tahi_01_036_size; +extern int tahi_01_037_size; +extern int tahi_01_038_size; +extern int tahi_01_039_size; +extern int tahi_01_040_size; +extern int tahi_01_041_size; +extern int tahi_01_042_size; +extern int tahi_01_043_size; +extern int tahi_01_044_size; +extern int tahi_01_045_size; +extern int tahi_01_046_size; +extern int tahi_01_047_size; +extern int tahi_01_048_size; +extern int tahi_01_049_size; +extern int tahi_01_050_size; +extern int tahi_01_051_size; +extern int tahi_01_052_size; +extern int tahi_01_053_size; +extern int tahi_01_054_size; + +static TAHI_TEST_SUITE test_suite[54]; +static void build_test_suite(void) +{ + +#if 1 + test_suite[0].test_case = &tahi_01_001[0]; test_suite[0].test_case_size = tahi_01_001_size; + test_suite[1].test_case = &tahi_01_002[0]; test_suite[1].test_case_size = tahi_01_002_size; + test_suite[2].test_case = &tahi_01_003[0]; test_suite[2].test_case_size = tahi_01_003_size; + test_suite[3].test_case = &tahi_01_004[0]; test_suite[3].test_case_size = tahi_01_004_size; + test_suite[4].test_case = &tahi_01_005[0]; test_suite[4].test_case_size = tahi_01_005_size; + test_suite[5].test_case = &tahi_01_006[0]; test_suite[5].test_case_size = tahi_01_006_size; + test_suite[6].test_case = &tahi_01_007[0]; test_suite[6].test_case_size = tahi_01_007_size; + test_suite[7].test_case = &tahi_01_008[0]; test_suite[7].test_case_size = tahi_01_008_size; + test_suite[8].test_case = &tahi_01_009[0]; test_suite[8].test_case_size = tahi_01_009_size; + test_suite[9].test_case = &tahi_01_010[0]; test_suite[9].test_case_size = tahi_01_010_size; + test_suite[10].test_case = &tahi_01_011[0]; test_suite[10].test_case_size = tahi_01_011_size; + test_suite[11].test_case = &tahi_01_012[0]; test_suite[11].test_case_size = tahi_01_012_size; +#endif + test_suite[12].test_case = &tahi_01_013[0]; test_suite[12].test_case_size = tahi_01_013_size; + test_suite[13].test_case = &tahi_01_014[0]; test_suite[13].test_case_size = tahi_01_014_size; + test_suite[14].test_case = &tahi_01_015[0]; test_suite[14].test_case_size = tahi_01_015_size; + test_suite[15].test_case = &tahi_01_016[0]; test_suite[15].test_case_size = tahi_01_016_size; + test_suite[16].test_case = &tahi_01_017[0]; test_suite[16].test_case_size = tahi_01_017_size; + test_suite[17].test_case = &tahi_01_018[0]; test_suite[17].test_case_size = tahi_01_018_size; + test_suite[18].test_case = &tahi_01_019[0]; test_suite[18].test_case_size = tahi_01_019_size; + test_suite[19].test_case = &tahi_01_020[0]; test_suite[19].test_case_size = tahi_01_020_size; + test_suite[20].test_case = &tahi_01_021[0]; test_suite[20].test_case_size = tahi_01_021_size; + test_suite[21].test_case = &tahi_01_022[0]; test_suite[21].test_case_size = tahi_01_022_size; + test_suite[22].test_case = &tahi_01_023[0]; test_suite[22].test_case_size = tahi_01_023_size; + test_suite[23].test_case = &tahi_01_024[0]; test_suite[23].test_case_size = tahi_01_024_size; + test_suite[24].test_case = &tahi_01_025[0]; test_suite[24].test_case_size = tahi_01_025_size; + test_suite[25].test_case = &tahi_01_026[0]; test_suite[25].test_case_size = tahi_01_026_size; + test_suite[26].test_case = &tahi_01_027[0]; test_suite[26].test_case_size = tahi_01_027_size; + test_suite[27].test_case = &tahi_01_028[0]; test_suite[27].test_case_size = tahi_01_028_size; + test_suite[28].test_case = &tahi_01_029[0]; test_suite[28].test_case_size = tahi_01_029_size; + test_suite[29].test_case = &tahi_01_030[0]; test_suite[29].test_case_size = tahi_01_030_size; + test_suite[30].test_case = &tahi_01_031[0]; test_suite[30].test_case_size = tahi_01_031_size; + test_suite[31].test_case = &tahi_01_032[0]; test_suite[31].test_case_size = tahi_01_032_size; + test_suite[32].test_case = &tahi_01_033[0]; test_suite[32].test_case_size = tahi_01_033_size; + test_suite[33].test_case = &tahi_01_034[0]; test_suite[33].test_case_size = tahi_01_034_size; + test_suite[34].test_case = &tahi_01_035[0]; test_suite[34].test_case_size = tahi_01_035_size; + test_suite[35].test_case = &tahi_01_036[0]; test_suite[35].test_case_size = tahi_01_036_size; + test_suite[36].test_case = &tahi_01_037[0]; test_suite[36].test_case_size = tahi_01_037_size; + test_suite[37].test_case = &tahi_01_038[0]; test_suite[37].test_case_size = tahi_01_038_size; + test_suite[38].test_case = &tahi_01_039[0]; test_suite[38].test_case_size = tahi_01_039_size; + test_suite[39].test_case = &tahi_01_040[0]; test_suite[39].test_case_size = tahi_01_040_size; + test_suite[40].test_case = &tahi_01_041[0]; test_suite[40].test_case_size = tahi_01_041_size; + test_suite[41].test_case = &tahi_01_042[0]; test_suite[41].test_case_size = tahi_01_042_size; + test_suite[42].test_case = &tahi_01_043[0]; test_suite[42].test_case_size = tahi_01_043_size; + test_suite[43].test_case = &tahi_01_044[0]; test_suite[43].test_case_size = tahi_01_044_size; + test_suite[44].test_case = &tahi_01_045[0]; test_suite[44].test_case_size = tahi_01_045_size; + test_suite[45].test_case = &tahi_01_046[0]; test_suite[45].test_case_size = tahi_01_046_size; + test_suite[46].test_case = &tahi_01_047[0]; test_suite[46].test_case_size = tahi_01_047_size; + test_suite[47].test_case = &tahi_01_048[0]; test_suite[47].test_case_size = tahi_01_048_size; + test_suite[48].test_case = &tahi_01_049[0]; test_suite[48].test_case_size = tahi_01_049_size; + test_suite[49].test_case = &tahi_01_050[0]; test_suite[49].test_case_size = tahi_01_050_size; + test_suite[50].test_case = &tahi_01_051[0]; test_suite[50].test_case_size = tahi_01_051_size; + test_suite[51].test_case = &tahi_01_052[0]; test_suite[51].test_case_size = tahi_01_052_size; + test_suite[52].test_case = &tahi_01_053[0]; test_suite[52].test_case_size = tahi_01_053_size; + test_suite[53].test_case = &tahi_01_054[0]; test_suite[53].test_case_size = tahi_01_054_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_1_define(void *first_unused_memory) +#endif +{ +CHAR *pointer; +UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_2_01.c b/test/regression/tahi_test/netx_tahi_test_2_01.c new file mode 100644 index 00000000..4a3408d9 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_2_01.c @@ -0,0 +1,525 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_02_001[]; +extern TAHI_TEST_SEQ tahi_02_002[]; +extern TAHI_TEST_SEQ tahi_02_003[]; +extern TAHI_TEST_SEQ tahi_02_004[]; +extern TAHI_TEST_SEQ tahi_02_005[]; +extern TAHI_TEST_SEQ tahi_02_006[]; +extern TAHI_TEST_SEQ tahi_02_007[]; +extern TAHI_TEST_SEQ tahi_02_008[]; +extern TAHI_TEST_SEQ tahi_02_009[]; +extern TAHI_TEST_SEQ tahi_02_010[]; +extern TAHI_TEST_SEQ tahi_02_011[]; +extern TAHI_TEST_SEQ tahi_02_012[]; +extern TAHI_TEST_SEQ tahi_02_013[]; +extern TAHI_TEST_SEQ tahi_02_014[]; +extern TAHI_TEST_SEQ tahi_02_015[]; +extern TAHI_TEST_SEQ tahi_02_016[]; +extern TAHI_TEST_SEQ tahi_02_017[]; +extern TAHI_TEST_SEQ tahi_02_018[]; +extern TAHI_TEST_SEQ tahi_02_019[]; +extern TAHI_TEST_SEQ tahi_02_020[]; +extern TAHI_TEST_SEQ tahi_02_021[]; +extern TAHI_TEST_SEQ tahi_02_022[]; +extern TAHI_TEST_SEQ tahi_02_023[]; +extern TAHI_TEST_SEQ tahi_02_024[]; +extern TAHI_TEST_SEQ tahi_02_025[]; +extern TAHI_TEST_SEQ tahi_02_026[]; +extern TAHI_TEST_SEQ tahi_02_027[]; +extern TAHI_TEST_SEQ tahi_02_028[]; +extern TAHI_TEST_SEQ tahi_02_029[]; +extern TAHI_TEST_SEQ tahi_02_030[]; +extern TAHI_TEST_SEQ tahi_02_031[]; +extern TAHI_TEST_SEQ tahi_02_032[]; +extern TAHI_TEST_SEQ tahi_02_033[]; +extern TAHI_TEST_SEQ tahi_02_034[]; +extern TAHI_TEST_SEQ tahi_02_035[]; +extern TAHI_TEST_SEQ tahi_02_036[]; +extern TAHI_TEST_SEQ tahi_02_037[]; +extern TAHI_TEST_SEQ tahi_02_038[]; +extern TAHI_TEST_SEQ tahi_02_039[]; +extern TAHI_TEST_SEQ tahi_02_040[]; +extern TAHI_TEST_SEQ tahi_02_041[]; +extern TAHI_TEST_SEQ tahi_02_042[]; +extern TAHI_TEST_SEQ tahi_02_043[]; +extern TAHI_TEST_SEQ tahi_02_044[]; +extern TAHI_TEST_SEQ tahi_02_045[]; +extern TAHI_TEST_SEQ tahi_02_046[]; +extern TAHI_TEST_SEQ tahi_02_047[]; +extern TAHI_TEST_SEQ tahi_02_048[]; +extern TAHI_TEST_SEQ tahi_02_049[]; +extern TAHI_TEST_SEQ tahi_02_050[]; +extern TAHI_TEST_SEQ tahi_02_051[]; +extern TAHI_TEST_SEQ tahi_02_052[]; +extern TAHI_TEST_SEQ tahi_02_053[]; +extern TAHI_TEST_SEQ tahi_02_054[]; +extern TAHI_TEST_SEQ tahi_02_055[]; +extern TAHI_TEST_SEQ tahi_02_056[]; +extern TAHI_TEST_SEQ tahi_02_057[]; +extern TAHI_TEST_SEQ tahi_02_058[]; +extern TAHI_TEST_SEQ tahi_02_059[]; +extern TAHI_TEST_SEQ tahi_02_060[]; +extern TAHI_TEST_SEQ tahi_02_061[]; +extern TAHI_TEST_SEQ tahi_02_062[]; +extern TAHI_TEST_SEQ tahi_02_063[]; +extern TAHI_TEST_SEQ tahi_02_064[]; +extern TAHI_TEST_SEQ tahi_02_065[]; +extern TAHI_TEST_SEQ tahi_02_066[]; +extern TAHI_TEST_SEQ tahi_02_067[]; +extern TAHI_TEST_SEQ tahi_02_068[]; +extern TAHI_TEST_SEQ tahi_02_069[]; +extern TAHI_TEST_SEQ tahi_02_070[]; +extern TAHI_TEST_SEQ tahi_02_071[]; +extern TAHI_TEST_SEQ tahi_02_072[]; +extern TAHI_TEST_SEQ tahi_02_073[]; +extern TAHI_TEST_SEQ tahi_02_074[]; +extern TAHI_TEST_SEQ tahi_02_075[]; +extern TAHI_TEST_SEQ tahi_02_076[]; +extern TAHI_TEST_SEQ tahi_02_077[]; +extern TAHI_TEST_SEQ tahi_02_078[]; +extern TAHI_TEST_SEQ tahi_02_079[]; +extern TAHI_TEST_SEQ tahi_02_080[]; +extern TAHI_TEST_SEQ tahi_02_081[]; +extern TAHI_TEST_SEQ tahi_02_082[]; +extern TAHI_TEST_SEQ tahi_02_083[]; +extern TAHI_TEST_SEQ tahi_02_084[]; +extern TAHI_TEST_SEQ tahi_02_085[]; +extern TAHI_TEST_SEQ tahi_02_086[]; +extern TAHI_TEST_SEQ tahi_02_087[]; +extern TAHI_TEST_SEQ tahi_02_088[]; +extern TAHI_TEST_SEQ tahi_02_089[]; +extern TAHI_TEST_SEQ tahi_02_090[]; +extern TAHI_TEST_SEQ tahi_02_091[]; +extern TAHI_TEST_SEQ tahi_02_092[]; +extern TAHI_TEST_SEQ tahi_02_093[]; +extern TAHI_TEST_SEQ tahi_02_094[]; +extern TAHI_TEST_SEQ tahi_02_095[]; +extern TAHI_TEST_SEQ tahi_02_096[]; +extern TAHI_TEST_SEQ tahi_02_097[]; +extern TAHI_TEST_SEQ tahi_02_098[]; +extern TAHI_TEST_SEQ tahi_02_099[]; + +extern TAHI_TEST_SEQ tahi_02_100[]; +extern TAHI_TEST_SEQ tahi_02_101[]; +extern TAHI_TEST_SEQ tahi_02_102[]; +extern TAHI_TEST_SEQ tahi_02_103[]; +extern TAHI_TEST_SEQ tahi_02_104[]; +extern TAHI_TEST_SEQ tahi_02_105[]; +extern TAHI_TEST_SEQ tahi_02_106[]; +extern TAHI_TEST_SEQ tahi_02_107[]; +extern TAHI_TEST_SEQ tahi_02_108[]; +extern TAHI_TEST_SEQ tahi_02_109[]; +extern TAHI_TEST_SEQ tahi_02_110[]; +extern TAHI_TEST_SEQ tahi_02_111[]; +extern TAHI_TEST_SEQ tahi_02_112[]; +extern TAHI_TEST_SEQ tahi_02_113[]; +extern TAHI_TEST_SEQ tahi_02_114[]; +extern TAHI_TEST_SEQ tahi_02_115[]; +extern TAHI_TEST_SEQ tahi_02_116[]; +extern TAHI_TEST_SEQ tahi_02_117[]; +extern TAHI_TEST_SEQ tahi_02_118[]; +extern TAHI_TEST_SEQ tahi_02_119[]; +extern TAHI_TEST_SEQ tahi_02_120[]; +extern TAHI_TEST_SEQ tahi_02_121[]; +extern TAHI_TEST_SEQ tahi_02_122[]; +extern TAHI_TEST_SEQ tahi_02_123[]; +extern TAHI_TEST_SEQ tahi_02_124[]; +extern TAHI_TEST_SEQ tahi_02_125[]; +extern TAHI_TEST_SEQ tahi_02_126[]; + +extern int tahi_02_001_size; +extern int tahi_02_002_size; +extern int tahi_02_003_size; +extern int tahi_02_004_size; +extern int tahi_02_005_size; +extern int tahi_02_006_size; +extern int tahi_02_007_size; +extern int tahi_02_008_size; +extern int tahi_02_009_size; +extern int tahi_02_010_size; +extern int tahi_02_011_size; +extern int tahi_02_012_size; +extern int tahi_02_013_size; +extern int tahi_02_014_size; +extern int tahi_02_015_size; +extern int tahi_02_016_size; +extern int tahi_02_017_size; +extern int tahi_02_018_size; +extern int tahi_02_019_size; +extern int tahi_02_020_size; +extern int tahi_02_021_size; +extern int tahi_02_022_size; +extern int tahi_02_023_size; +extern int tahi_02_024_size; +extern int tahi_02_025_size; +extern int tahi_02_026_size; +extern int tahi_02_027_size; +extern int tahi_02_028_size; +extern int tahi_02_029_size; +extern int tahi_02_030_size; +extern int tahi_02_031_size; +extern int tahi_02_032_size; +extern int tahi_02_033_size; +extern int tahi_02_034_size; +extern int tahi_02_035_size; +extern int tahi_02_036_size; +extern int tahi_02_037_size; +extern int tahi_02_038_size; +extern int tahi_02_039_size; +extern int tahi_02_040_size; +extern int tahi_02_041_size; +extern int tahi_02_042_size; +extern int tahi_02_043_size; +extern int tahi_02_044_size; +extern int tahi_02_045_size; +extern int tahi_02_046_size; +extern int tahi_02_047_size; +extern int tahi_02_048_size; +extern int tahi_02_049_size; +extern int tahi_02_050_size; +extern int tahi_02_051_size; +extern int tahi_02_052_size; +extern int tahi_02_053_size; +extern int tahi_02_054_size; +extern int tahi_02_055_size; +extern int tahi_02_056_size; +extern int tahi_02_057_size; +extern int tahi_02_058_size; +extern int tahi_02_059_size; +extern int tahi_02_060_size; +extern int tahi_02_061_size; +extern int tahi_02_062_size; +extern int tahi_02_063_size; +extern int tahi_02_064_size; +extern int tahi_02_065_size; +extern int tahi_02_066_size; +extern int tahi_02_067_size; +extern int tahi_02_068_size; +extern int tahi_02_069_size; +extern int tahi_02_070_size; +extern int tahi_02_071_size; +extern int tahi_02_072_size; +extern int tahi_02_073_size; +extern int tahi_02_074_size; +extern int tahi_02_075_size; +extern int tahi_02_076_size; +extern int tahi_02_077_size; +extern int tahi_02_078_size; +extern int tahi_02_079_size; +extern int tahi_02_080_size; +extern int tahi_02_081_size; +extern int tahi_02_082_size; +extern int tahi_02_083_size; +extern int tahi_02_084_size; +extern int tahi_02_085_size; +extern int tahi_02_086_size; +extern int tahi_02_087_size; +extern int tahi_02_088_size; +extern int tahi_02_089_size; +extern int tahi_02_090_size; +extern int tahi_02_091_size; +extern int tahi_02_092_size; +extern int tahi_02_093_size; +extern int tahi_02_094_size; +extern int tahi_02_095_size; +extern int tahi_02_096_size; +extern int tahi_02_097_size; +extern int tahi_02_098_size; +extern int tahi_02_099_size; + +extern int tahi_02_100_size; +extern int tahi_02_101_size; +extern int tahi_02_102_size; +extern int tahi_02_103_size; +extern int tahi_02_104_size; +extern int tahi_02_105_size; +extern int tahi_02_106_size; +extern int tahi_02_107_size; +extern int tahi_02_108_size; +extern int tahi_02_109_size; +extern int tahi_02_110_size; +extern int tahi_02_111_size; +extern int tahi_02_112_size; +extern int tahi_02_113_size; +extern int tahi_02_114_size; +extern int tahi_02_115_size; +extern int tahi_02_116_size; +extern int tahi_02_117_size; +extern int tahi_02_118_size; +extern int tahi_02_119_size; +extern int tahi_02_120_size; +extern int tahi_02_121_size; +extern int tahi_02_122_size; +extern int tahi_02_123_size; +extern int tahi_02_124_size; +extern int tahi_02_125_size; +extern int tahi_02_126_size; + +static TAHI_TEST_SUITE test_suite[126]; +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_02_001[0]; test_suite[0].test_case_size = tahi_02_001_size; + test_suite[1].test_case = &tahi_02_002[0]; test_suite[1].test_case_size = tahi_02_002_size; + test_suite[2].test_case = &tahi_02_003[0]; test_suite[2].test_case_size = tahi_02_003_size; + test_suite[3].test_case = &tahi_02_004[0]; test_suite[3].test_case_size = tahi_02_004_size; + test_suite[4].test_case = &tahi_02_005[0]; test_suite[4].test_case_size = tahi_02_005_size; + test_suite[5].test_case = &tahi_02_006[0]; test_suite[5].test_case_size = tahi_02_006_size; + test_suite[6].test_case = &tahi_02_007[0]; test_suite[6].test_case_size = tahi_02_007_size; + test_suite[7].test_case = &tahi_02_008[0]; test_suite[7].test_case_size = tahi_02_008_size; + test_suite[8].test_case = &tahi_02_009[0]; test_suite[8].test_case_size = tahi_02_009_size; + test_suite[9].test_case = &tahi_02_010[0]; test_suite[9].test_case_size = tahi_02_010_size; + test_suite[10].test_case = &tahi_02_011[0]; test_suite[10].test_case_size = tahi_02_011_size; + test_suite[11].test_case = &tahi_02_012[0]; test_suite[11].test_case_size = tahi_02_012_size; + test_suite[12].test_case = &tahi_02_013[0]; test_suite[12].test_case_size = tahi_02_013_size; + test_suite[13].test_case = &tahi_02_014[0]; test_suite[13].test_case_size = tahi_02_014_size; + test_suite[14].test_case = &tahi_02_015[0]; test_suite[14].test_case_size = tahi_02_015_size; + test_suite[15].test_case = &tahi_02_016[0]; test_suite[15].test_case_size = tahi_02_016_size; + test_suite[16].test_case = &tahi_02_017[0]; test_suite[16].test_case_size = tahi_02_017_size; + test_suite[17].test_case = &tahi_02_018[0]; test_suite[17].test_case_size = tahi_02_018_size; + test_suite[18].test_case = &tahi_02_019[0]; test_suite[18].test_case_size = tahi_02_019_size; + test_suite[19].test_case = &tahi_02_020[0]; test_suite[19].test_case_size = tahi_02_020_size; + test_suite[20].test_case = &tahi_02_021[0]; test_suite[20].test_case_size = tahi_02_021_size; + test_suite[21].test_case = &tahi_02_022[0]; test_suite[21].test_case_size = tahi_02_022_size; + test_suite[22].test_case = &tahi_02_023[0]; test_suite[22].test_case_size = tahi_02_023_size; + test_suite[23].test_case = &tahi_02_024[0]; test_suite[23].test_case_size = tahi_02_024_size; + test_suite[24].test_case = &tahi_02_025[0]; test_suite[24].test_case_size = tahi_02_025_size; + test_suite[25].test_case = &tahi_02_026[0]; test_suite[25].test_case_size = tahi_02_026_size; + test_suite[26].test_case = &tahi_02_027[0]; test_suite[26].test_case_size = tahi_02_027_size; + test_suite[27].test_case = &tahi_02_028[0]; test_suite[27].test_case_size = tahi_02_028_size; + test_suite[28].test_case = &tahi_02_029[0]; test_suite[28].test_case_size = tahi_02_029_size; + test_suite[29].test_case = &tahi_02_030[0]; test_suite[29].test_case_size = tahi_02_030_size; + test_suite[30].test_case = &tahi_02_031[0]; test_suite[30].test_case_size = tahi_02_031_size; + test_suite[31].test_case = &tahi_02_032[0]; test_suite[31].test_case_size = tahi_02_032_size; + test_suite[32].test_case = &tahi_02_033[0]; test_suite[32].test_case_size = tahi_02_033_size; + test_suite[33].test_case = &tahi_02_034[0]; test_suite[33].test_case_size = tahi_02_034_size; + test_suite[34].test_case = &tahi_02_035[0]; test_suite[34].test_case_size = tahi_02_035_size; + test_suite[35].test_case = &tahi_02_036[0]; test_suite[35].test_case_size = tahi_02_036_size; + test_suite[36].test_case = &tahi_02_037[0]; test_suite[36].test_case_size = tahi_02_037_size; + test_suite[37].test_case = &tahi_02_038[0]; test_suite[37].test_case_size = tahi_02_038_size; + test_suite[38].test_case = &tahi_02_039[0]; test_suite[38].test_case_size = tahi_02_039_size; + test_suite[39].test_case = &tahi_02_040[0]; test_suite[39].test_case_size = tahi_02_040_size; + test_suite[40].test_case = &tahi_02_041[0]; test_suite[40].test_case_size = tahi_02_041_size; + test_suite[41].test_case = &tahi_02_042[0]; test_suite[41].test_case_size = tahi_02_042_size; + test_suite[42].test_case = &tahi_02_043[0]; test_suite[42].test_case_size = tahi_02_043_size; + test_suite[43].test_case = &tahi_02_044[0]; test_suite[43].test_case_size = tahi_02_044_size; + test_suite[44].test_case = &tahi_02_045[0]; test_suite[44].test_case_size = tahi_02_045_size; + test_suite[45].test_case = &tahi_02_046[0]; test_suite[45].test_case_size = tahi_02_046_size; + test_suite[46].test_case = &tahi_02_047[0]; test_suite[46].test_case_size = tahi_02_047_size; + test_suite[47].test_case = &tahi_02_048[0]; test_suite[47].test_case_size = tahi_02_048_size; + test_suite[48].test_case = &tahi_02_049[0]; test_suite[48].test_case_size = tahi_02_049_size; + test_suite[49].test_case = &tahi_02_050[0]; test_suite[49].test_case_size = tahi_02_050_size; + test_suite[50].test_case = &tahi_02_051[0]; test_suite[50].test_case_size = tahi_02_051_size; + test_suite[51].test_case = &tahi_02_052[0]; test_suite[51].test_case_size = tahi_02_052_size; + test_suite[52].test_case = &tahi_02_053[0]; test_suite[52].test_case_size = tahi_02_053_size; + test_suite[53].test_case = &tahi_02_054[0]; test_suite[53].test_case_size = tahi_02_054_size; + test_suite[54].test_case = &tahi_02_055[0]; test_suite[54].test_case_size = tahi_02_055_size; + test_suite[55].test_case = &tahi_02_056[0]; test_suite[55].test_case_size = tahi_02_056_size; + test_suite[56].test_case = &tahi_02_057[0]; test_suite[56].test_case_size = tahi_02_057_size; + test_suite[57].test_case = &tahi_02_058[0]; test_suite[57].test_case_size = tahi_02_058_size; + test_suite[58].test_case = &tahi_02_059[0]; test_suite[58].test_case_size = tahi_02_059_size; + test_suite[59].test_case = &tahi_02_060[0]; test_suite[59].test_case_size = tahi_02_060_size; + test_suite[60].test_case = &tahi_02_061[0]; test_suite[60].test_case_size = tahi_02_061_size; + test_suite[61].test_case = &tahi_02_062[0]; test_suite[61].test_case_size = tahi_02_062_size; + test_suite[62].test_case = &tahi_02_063[0]; test_suite[62].test_case_size = tahi_02_063_size; + test_suite[63].test_case = &tahi_02_064[0]; test_suite[63].test_case_size = tahi_02_064_size; + test_suite[64].test_case = &tahi_02_065[0]; test_suite[64].test_case_size = tahi_02_065_size; + test_suite[65].test_case = &tahi_02_066[0]; test_suite[65].test_case_size = tahi_02_066_size; + test_suite[66].test_case = &tahi_02_067[0]; test_suite[66].test_case_size = tahi_02_067_size; + test_suite[67].test_case = &tahi_02_068[0]; test_suite[67].test_case_size = tahi_02_068_size; + test_suite[68].test_case = &tahi_02_069[0]; test_suite[68].test_case_size = tahi_02_069_size; + test_suite[69].test_case = &tahi_02_070[0]; test_suite[69].test_case_size = tahi_02_070_size; + test_suite[70].test_case = &tahi_02_071[0]; test_suite[70].test_case_size = tahi_02_071_size; + test_suite[71].test_case = &tahi_02_072[0]; test_suite[71].test_case_size = tahi_02_072_size; + test_suite[72].test_case = &tahi_02_073[0]; test_suite[72].test_case_size = tahi_02_073_size; + test_suite[73].test_case = &tahi_02_074[0]; test_suite[73].test_case_size = tahi_02_074_size; + test_suite[74].test_case = &tahi_02_075[0]; test_suite[74].test_case_size = tahi_02_075_size; + test_suite[75].test_case = &tahi_02_076[0]; test_suite[75].test_case_size = tahi_02_076_size; + test_suite[76].test_case = &tahi_02_077[0]; test_suite[76].test_case_size = tahi_02_077_size; + test_suite[77].test_case = &tahi_02_078[0]; test_suite[77].test_case_size = tahi_02_078_size; + test_suite[78].test_case = &tahi_02_079[0]; test_suite[78].test_case_size = tahi_02_079_size; + test_suite[79].test_case = &tahi_02_080[0]; test_suite[79].test_case_size = tahi_02_080_size; + test_suite[80].test_case = &tahi_02_081[0]; test_suite[80].test_case_size = tahi_02_081_size; + test_suite[81].test_case = &tahi_02_082[0]; test_suite[81].test_case_size = tahi_02_082_size; + test_suite[82].test_case = &tahi_02_083[0]; test_suite[82].test_case_size = tahi_02_083_size; + test_suite[83].test_case = &tahi_02_084[0]; test_suite[83].test_case_size = tahi_02_084_size; + test_suite[84].test_case = &tahi_02_085[0]; test_suite[84].test_case_size = tahi_02_085_size; + test_suite[85].test_case = &tahi_02_086[0]; test_suite[85].test_case_size = tahi_02_086_size; + test_suite[86].test_case = &tahi_02_087[0]; test_suite[86].test_case_size = tahi_02_087_size; + test_suite[87].test_case = &tahi_02_088[0]; test_suite[87].test_case_size = tahi_02_088_size; + test_suite[88].test_case = &tahi_02_089[0]; test_suite[88].test_case_size = tahi_02_089_size; + test_suite[89].test_case = &tahi_02_090[0]; test_suite[89].test_case_size = tahi_02_090_size; + test_suite[90].test_case = &tahi_02_091[0]; test_suite[90].test_case_size = tahi_02_091_size; + test_suite[91].test_case = &tahi_02_092[0]; test_suite[91].test_case_size = tahi_02_092_size; + test_suite[92].test_case = &tahi_02_093[0]; test_suite[92].test_case_size = tahi_02_093_size; + test_suite[93].test_case = &tahi_02_094[0]; test_suite[93].test_case_size = tahi_02_094_size; + test_suite[94].test_case = &tahi_02_095[0]; test_suite[94].test_case_size = tahi_02_095_size; + test_suite[95].test_case = &tahi_02_096[0]; test_suite[95].test_case_size = tahi_02_096_size; + test_suite[96].test_case = &tahi_02_097[0]; test_suite[96].test_case_size = tahi_02_097_size; + test_suite[97].test_case = &tahi_02_098[0]; test_suite[97].test_case_size = tahi_02_098_size; + test_suite[98].test_case = &tahi_02_099[0]; test_suite[98].test_case_size = tahi_02_099_size; + test_suite[99].test_case = &tahi_02_100[0]; test_suite[99].test_case_size = tahi_02_100_size; + test_suite[100].test_case = &tahi_02_101[0]; test_suite[100].test_case_size = tahi_02_101_size; + test_suite[101].test_case = &tahi_02_102[0]; test_suite[101].test_case_size = tahi_02_102_size; + test_suite[102].test_case = &tahi_02_103[0]; test_suite[102].test_case_size = tahi_02_103_size; + test_suite[103].test_case = &tahi_02_104[0]; test_suite[103].test_case_size = tahi_02_104_size; + test_suite[104].test_case = &tahi_02_105[0]; test_suite[104].test_case_size = tahi_02_105_size; + test_suite[105].test_case = &tahi_02_106[0]; test_suite[105].test_case_size = tahi_02_106_size; + test_suite[106].test_case = &tahi_02_107[0]; test_suite[106].test_case_size = tahi_02_107_size; + test_suite[107].test_case = &tahi_02_108[0]; test_suite[107].test_case_size = tahi_02_108_size; + test_suite[108].test_case = &tahi_02_109[0]; test_suite[108].test_case_size = tahi_02_109_size; + test_suite[109].test_case = &tahi_02_110[0]; test_suite[109].test_case_size = tahi_02_110_size; + test_suite[110].test_case = &tahi_02_111[0]; test_suite[110].test_case_size = tahi_02_111_size; + test_suite[111].test_case = &tahi_02_112[0]; test_suite[111].test_case_size = tahi_02_112_size; + test_suite[112].test_case = &tahi_02_113[0]; test_suite[112].test_case_size = tahi_02_113_size; + test_suite[113].test_case = &tahi_02_114[0]; test_suite[113].test_case_size = tahi_02_114_size; + test_suite[114].test_case = &tahi_02_115[0]; test_suite[114].test_case_size = tahi_02_115_size; + test_suite[115].test_case = &tahi_02_116[0]; test_suite[115].test_case_size = tahi_02_116_size; + test_suite[116].test_case = &tahi_02_117[0]; test_suite[116].test_case_size = tahi_02_117_size; + test_suite[117].test_case = &tahi_02_118[0]; test_suite[117].test_case_size = tahi_02_118_size; + test_suite[118].test_case = &tahi_02_119[0]; test_suite[118].test_case_size = tahi_02_119_size; + test_suite[119].test_case = &tahi_02_120[0]; test_suite[119].test_case_size = tahi_02_120_size; + test_suite[120].test_case = &tahi_02_121[0]; test_suite[120].test_case_size = tahi_02_121_size; + test_suite[121].test_case = &tahi_02_122[0]; test_suite[121].test_case_size = tahi_02_122_size; + test_suite[122].test_case = &tahi_02_123[0]; test_suite[122].test_case_size = tahi_02_123_size; + test_suite[123].test_case = &tahi_02_124[0]; test_suite[123].test_case_size = tahi_02_124_size; + test_suite[124].test_case = &tahi_02_125[0]; test_suite[124].test_case_size = tahi_02_125_size; + test_suite[125].test_case = &tahi_02_126[0]; test_suite[125].test_case_size = tahi_02_126_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_2_1_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; + + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_2_02.c b/test/regression/tahi_test/netx_tahi_test_2_02.c new file mode 100644 index 00000000..9934045d --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_2_02.c @@ -0,0 +1,146 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_02_127[]; + + +extern int tahi_02_127_size; + + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_02_127[0]; test_suite[0].test_case_size = tahi_02_127_size; +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_2_2_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64,NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + /* Clear the flags. */ + test_control_return(0xdeadbeef); + +} + + +#endif + diff --git a/test/regression/tahi_test/netx_tahi_test_2_03.c b/test/regression/tahi_test/netx_tahi_test_2_03.c new file mode 100644 index 00000000..81950654 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_2_03.c @@ -0,0 +1,145 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_02_128[]; + +extern int tahi_02_128_size; + + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_02_128[0]; test_suite[0].test_case_size = tahi_02_128_size; + +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_2_3_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64,NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + /* Clear the flags. */ + test_control_return(0xdeadbeef); + +} + + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_2_04.c b/test/regression/tahi_test/netx_tahi_test_2_04.c new file mode 100644 index 00000000..1c637062 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_2_04.c @@ -0,0 +1,145 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_02_129[]; + +extern int tahi_02_129_size; + + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_02_129[0]; test_suite[0].test_case_size = tahi_02_129_size; + +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_2_4_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + /* Clear the flags. */ + test_control_return(0xdeadbeef); + +} + + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_2_05.c b/test/regression/tahi_test/netx_tahi_test_2_05.c new file mode 100644 index 00000000..51b69ce3 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_2_05.c @@ -0,0 +1,145 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_02_130[]; + +extern int tahi_02_130_size; + + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_02_130[0]; test_suite[0].test_case_size = tahi_02_130_size; + +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_2_5_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + /* Clear the flags. */ + test_control_return(0xdeadbeef); + +} + + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_2_06.c b/test/regression/tahi_test/netx_tahi_test_2_06.c new file mode 100644 index 00000000..f6996502 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_2_06.c @@ -0,0 +1,145 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_02_131[]; + +extern int tahi_02_131_size; + + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_02_131[0]; test_suite[0].test_case_size = tahi_02_131_size; + +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_2_6_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + /* Clear the flags. */ + test_control_return(0xdeadbeef); + +} + + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_2_07.c b/test/regression/tahi_test/netx_tahi_test_2_07.c new file mode 100644 index 00000000..8dc5312a --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_2_07.c @@ -0,0 +1,145 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_02_132[]; + +extern int tahi_02_132_size; + + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_02_132[0]; test_suite[0].test_case_size = tahi_02_132_size; + +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_2_7_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + /* Clear the flags. */ + test_control_return(0xdeadbeef); + +} + + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_2_08.c b/test/regression/tahi_test/netx_tahi_test_2_08.c new file mode 100644 index 00000000..4847345d --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_2_08.c @@ -0,0 +1,145 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_02_133[]; + +extern int tahi_02_133_size; + + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_02_133[0]; test_suite[0].test_case_size = tahi_02_133_size; + +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_2_8_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + /* Clear the flags. */ + test_control_return(0xdeadbeef); + +} + + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_2_09.c b/test/regression/tahi_test/netx_tahi_test_2_09.c new file mode 100644 index 00000000..eab3df75 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_2_09.c @@ -0,0 +1,145 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_02_134[]; + +extern int tahi_02_134_size; + + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_02_134[0]; test_suite[0].test_case_size = tahi_02_134_size; + +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_2_9_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + /* Clear the flags. */ + test_control_return(0xdeadbeef); + +} + + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_2_10.c b/test/regression/tahi_test/netx_tahi_test_2_10.c new file mode 100644 index 00000000..a37f2b7a --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_2_10.c @@ -0,0 +1,240 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_02_135[]; +extern TAHI_TEST_SEQ tahi_02_136[]; +extern TAHI_TEST_SEQ tahi_02_137[]; +extern TAHI_TEST_SEQ tahi_02_138[]; +extern TAHI_TEST_SEQ tahi_02_139[]; +extern TAHI_TEST_SEQ tahi_02_140[]; +extern TAHI_TEST_SEQ tahi_02_141[]; +extern TAHI_TEST_SEQ tahi_02_142[]; +extern TAHI_TEST_SEQ tahi_02_143[]; +extern TAHI_TEST_SEQ tahi_02_144[]; +extern TAHI_TEST_SEQ tahi_02_145[]; +extern TAHI_TEST_SEQ tahi_02_146[]; +extern TAHI_TEST_SEQ tahi_02_147[]; +extern TAHI_TEST_SEQ tahi_02_148[]; +extern TAHI_TEST_SEQ tahi_02_149[]; +extern TAHI_TEST_SEQ tahi_02_150[]; +extern TAHI_TEST_SEQ tahi_02_151[]; +extern TAHI_TEST_SEQ tahi_02_152[]; +extern TAHI_TEST_SEQ tahi_02_153[]; +extern TAHI_TEST_SEQ tahi_02_154[]; +extern TAHI_TEST_SEQ tahi_02_155[]; +extern TAHI_TEST_SEQ tahi_02_156[]; +extern TAHI_TEST_SEQ tahi_02_157[]; +extern TAHI_TEST_SEQ tahi_02_158[]; +extern TAHI_TEST_SEQ tahi_02_159[]; +extern TAHI_TEST_SEQ tahi_02_160[]; +extern TAHI_TEST_SEQ tahi_02_161[]; +extern TAHI_TEST_SEQ tahi_02_162[]; +extern TAHI_TEST_SEQ tahi_02_163[]; +extern TAHI_TEST_SEQ tahi_02_164[]; +extern TAHI_TEST_SEQ tahi_02_165[]; +extern TAHI_TEST_SEQ tahi_02_166[]; +extern TAHI_TEST_SEQ tahi_02_167[]; + +extern int tahi_02_135_size; +extern int tahi_02_136_size; +extern int tahi_02_137_size; +extern int tahi_02_138_size; +extern int tahi_02_139_size; +extern int tahi_02_140_size; +extern int tahi_02_141_size; +extern int tahi_02_142_size; +extern int tahi_02_143_size; +extern int tahi_02_144_size; +extern int tahi_02_145_size; +extern int tahi_02_146_size; +extern int tahi_02_147_size; +extern int tahi_02_148_size; +extern int tahi_02_149_size; +extern int tahi_02_150_size; +extern int tahi_02_151_size; +extern int tahi_02_152_size; +extern int tahi_02_153_size; +extern int tahi_02_154_size; +extern int tahi_02_155_size; +extern int tahi_02_156_size; +extern int tahi_02_157_size; +extern int tahi_02_158_size; +extern int tahi_02_159_size; +extern int tahi_02_160_size; +extern int tahi_02_161_size; +extern int tahi_02_162_size; +extern int tahi_02_163_size; +extern int tahi_02_164_size; +extern int tahi_02_165_size; +extern int tahi_02_166_size; +extern int tahi_02_167_size; + + +static TAHI_TEST_SUITE test_suite[33]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_02_135[0]; test_suite[0].test_case_size = tahi_02_135_size; + test_suite[1].test_case = &tahi_02_136[0]; test_suite[1].test_case_size = tahi_02_136_size; + test_suite[2].test_case = &tahi_02_137[0]; test_suite[2].test_case_size = tahi_02_137_size; + test_suite[3].test_case = &tahi_02_138[0]; test_suite[3].test_case_size = tahi_02_138_size; + test_suite[4].test_case = &tahi_02_139[0]; test_suite[4].test_case_size = tahi_02_139_size; + test_suite[5].test_case = &tahi_02_140[0]; test_suite[5].test_case_size = tahi_02_140_size; + test_suite[6].test_case = &tahi_02_141[0]; test_suite[6].test_case_size = tahi_02_141_size; + test_suite[7].test_case = &tahi_02_142[0]; test_suite[7].test_case_size = tahi_02_142_size; + test_suite[8].test_case = &tahi_02_143[0]; test_suite[8].test_case_size = tahi_02_143_size; + test_suite[9].test_case = &tahi_02_144[0]; test_suite[9].test_case_size = tahi_02_144_size; + test_suite[10].test_case = &tahi_02_145[0]; test_suite[10].test_case_size = tahi_02_145_size; + test_suite[11].test_case = &tahi_02_146[0]; test_suite[11].test_case_size = tahi_02_146_size; + test_suite[12].test_case = &tahi_02_147[0]; test_suite[12].test_case_size = tahi_02_147_size; /* line:620 */ + test_suite[13].test_case = &tahi_02_148[0]; test_suite[13].test_case_size = tahi_02_148_size; + test_suite[14].test_case = &tahi_02_149[0]; test_suite[14].test_case_size = tahi_02_149_size; + test_suite[15].test_case = &tahi_02_150[0]; test_suite[15].test_case_size = tahi_02_150_size; + test_suite[16].test_case = &tahi_02_151[0]; test_suite[16].test_case_size = tahi_02_151_size; /* line:102 */ + test_suite[17].test_case = &tahi_02_152[0]; test_suite[17].test_case_size = tahi_02_152_size; + test_suite[18].test_case = &tahi_02_153[0]; test_suite[18].test_case_size = tahi_02_153_size; + test_suite[19].test_case = &tahi_02_154[0]; test_suite[19].test_case_size = tahi_02_154_size; + test_suite[20].test_case = &tahi_02_155[0]; test_suite[20].test_case_size = tahi_02_155_size; + test_suite[21].test_case = &tahi_02_156[0]; test_suite[21].test_case_size = tahi_02_156_size; + test_suite[22].test_case = &tahi_02_157[0]; test_suite[22].test_case_size = tahi_02_157_size; + test_suite[23].test_case = &tahi_02_158[0]; test_suite[23].test_case_size = tahi_02_158_size; + test_suite[24].test_case = &tahi_02_159[0]; test_suite[24].test_case_size = tahi_02_159_size; + test_suite[25].test_case = &tahi_02_160[0]; test_suite[25].test_case_size = tahi_02_160_size; + test_suite[26].test_case = &tahi_02_161[0]; test_suite[26].test_case_size = tahi_02_161_size; + test_suite[27].test_case = &tahi_02_162[0]; test_suite[27].test_case_size = tahi_02_162_size; + test_suite[28].test_case = &tahi_02_163[0]; test_suite[28].test_case_size = tahi_02_163_size; + test_suite[29].test_case = &tahi_02_164[0]; test_suite[29].test_case_size = tahi_02_164_size; + test_suite[30].test_case = &tahi_02_165[0]; test_suite[30].test_case_size = tahi_02_165_size; + test_suite[31].test_case = &tahi_02_166[0]; test_suite[31].test_case_size = tahi_02_166_size; + test_suite[32].test_case = &tahi_02_167[0]; test_suite[32].test_case_size = tahi_02_167_size; //line:142 +} + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_2_10_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; + + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + /* Clear the flags. */ + test_control_return(0xdeadbeef); + +} + + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_2_11.c b/test/regression/tahi_test/netx_tahi_test_2_11.c new file mode 100644 index 00000000..c1748701 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_2_11.c @@ -0,0 +1,348 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_02_168[]; +extern TAHI_TEST_SEQ tahi_02_169[]; +extern TAHI_TEST_SEQ tahi_02_170[]; +extern TAHI_TEST_SEQ tahi_02_171[]; +extern TAHI_TEST_SEQ tahi_02_172[]; +extern TAHI_TEST_SEQ tahi_02_173[]; +extern TAHI_TEST_SEQ tahi_02_174[]; +extern TAHI_TEST_SEQ tahi_02_175[]; +extern TAHI_TEST_SEQ tahi_02_176[]; +extern TAHI_TEST_SEQ tahi_02_177[]; +extern TAHI_TEST_SEQ tahi_02_178[]; +extern TAHI_TEST_SEQ tahi_02_179[]; +extern TAHI_TEST_SEQ tahi_02_180[]; +extern TAHI_TEST_SEQ tahi_02_181[]; +extern TAHI_TEST_SEQ tahi_02_182[]; +extern TAHI_TEST_SEQ tahi_02_183[]; +extern TAHI_TEST_SEQ tahi_02_184[]; +extern TAHI_TEST_SEQ tahi_02_185[]; +extern TAHI_TEST_SEQ tahi_02_186[]; +extern TAHI_TEST_SEQ tahi_02_187[]; +extern TAHI_TEST_SEQ tahi_02_188[]; +extern TAHI_TEST_SEQ tahi_02_189[]; +extern TAHI_TEST_SEQ tahi_02_190[]; +extern TAHI_TEST_SEQ tahi_02_191[]; +extern TAHI_TEST_SEQ tahi_02_192[]; +extern TAHI_TEST_SEQ tahi_02_193[]; +extern TAHI_TEST_SEQ tahi_02_194[]; +extern TAHI_TEST_SEQ tahi_02_195[]; +extern TAHI_TEST_SEQ tahi_02_196[]; +extern TAHI_TEST_SEQ tahi_02_197[]; +extern TAHI_TEST_SEQ tahi_02_198[]; +extern TAHI_TEST_SEQ tahi_02_199[]; +extern TAHI_TEST_SEQ tahi_02_200[]; +extern TAHI_TEST_SEQ tahi_02_201[]; +extern TAHI_TEST_SEQ tahi_02_202[]; +extern TAHI_TEST_SEQ tahi_02_203[]; +extern TAHI_TEST_SEQ tahi_02_204[]; +extern TAHI_TEST_SEQ tahi_02_205[]; +extern TAHI_TEST_SEQ tahi_02_206[]; +extern TAHI_TEST_SEQ tahi_02_207[]; +extern TAHI_TEST_SEQ tahi_02_208[]; +extern TAHI_TEST_SEQ tahi_02_209[]; +extern TAHI_TEST_SEQ tahi_02_210[]; +extern TAHI_TEST_SEQ tahi_02_211[]; +extern TAHI_TEST_SEQ tahi_02_212[]; +extern TAHI_TEST_SEQ tahi_02_213[]; +extern TAHI_TEST_SEQ tahi_02_214[]; +extern TAHI_TEST_SEQ tahi_02_215[]; +extern TAHI_TEST_SEQ tahi_02_216[]; +extern TAHI_TEST_SEQ tahi_02_217[]; +extern TAHI_TEST_SEQ tahi_02_218[]; +extern TAHI_TEST_SEQ tahi_02_219[]; +extern TAHI_TEST_SEQ tahi_02_220[]; +extern TAHI_TEST_SEQ tahi_02_221[]; +extern TAHI_TEST_SEQ tahi_02_222[]; +extern TAHI_TEST_SEQ tahi_02_223[]; +extern TAHI_TEST_SEQ tahi_02_224[]; +extern TAHI_TEST_SEQ tahi_02_225[]; +extern TAHI_TEST_SEQ tahi_02_226[]; +extern TAHI_TEST_SEQ tahi_02_227[]; +extern TAHI_TEST_SEQ tahi_02_228[]; +extern TAHI_TEST_SEQ tahi_02_229[]; + +extern TAHI_TEST_SEQ tahi_02_230[]; +extern TAHI_TEST_SEQ tahi_02_231[]; +extern TAHI_TEST_SEQ tahi_02_232[]; +extern TAHI_TEST_SEQ tahi_02_233[]; +extern TAHI_TEST_SEQ tahi_02_234[]; +extern TAHI_TEST_SEQ tahi_02_235[]; +extern TAHI_TEST_SEQ tahi_02_236[]; + +extern int tahi_02_168_size; +extern int tahi_02_169_size; +extern int tahi_02_170_size; +extern int tahi_02_171_size; +extern int tahi_02_172_size; +extern int tahi_02_173_size; +extern int tahi_02_174_size; +extern int tahi_02_175_size; +extern int tahi_02_176_size; +extern int tahi_02_177_size; +extern int tahi_02_178_size; +extern int tahi_02_179_size; +extern int tahi_02_180_size; +extern int tahi_02_181_size; +extern int tahi_02_182_size; +extern int tahi_02_183_size; +extern int tahi_02_184_size; +extern int tahi_02_185_size; +extern int tahi_02_186_size; +extern int tahi_02_187_size; +extern int tahi_02_188_size; +extern int tahi_02_189_size; +extern int tahi_02_190_size; +extern int tahi_02_191_size; +extern int tahi_02_192_size; +extern int tahi_02_193_size; +extern int tahi_02_194_size; +extern int tahi_02_195_size; +extern int tahi_02_196_size; +extern int tahi_02_197_size; +extern int tahi_02_198_size; +extern int tahi_02_199_size; +extern int tahi_02_200_size; +extern int tahi_02_201_size; +extern int tahi_02_202_size; +extern int tahi_02_203_size; +extern int tahi_02_204_size; +extern int tahi_02_205_size; +extern int tahi_02_206_size; +extern int tahi_02_207_size; +extern int tahi_02_208_size; +extern int tahi_02_209_size; +extern int tahi_02_210_size; +extern int tahi_02_211_size; +extern int tahi_02_212_size; +extern int tahi_02_213_size; +extern int tahi_02_214_size; +extern int tahi_02_215_size; +extern int tahi_02_216_size; +extern int tahi_02_217_size; +extern int tahi_02_218_size; +extern int tahi_02_219_size; + +extern int tahi_02_220_size; +extern int tahi_02_221_size; +extern int tahi_02_222_size; +extern int tahi_02_223_size; +extern int tahi_02_224_size; +extern int tahi_02_225_size; +extern int tahi_02_226_size; +extern int tahi_02_227_size; +extern int tahi_02_228_size; +extern int tahi_02_229_size; + +extern int tahi_02_230_size; +extern int tahi_02_231_size; +extern int tahi_02_232_size; +extern int tahi_02_233_size; +extern int tahi_02_234_size; +extern int tahi_02_235_size; +extern int tahi_02_236_size; + +static TAHI_TEST_SUITE test_suite[69]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_02_168[0]; test_suite[0].test_case_size = tahi_02_168_size; + test_suite[1].test_case = &tahi_02_169[0]; test_suite[1].test_case_size = tahi_02_169_size; + test_suite[2].test_case = &tahi_02_170[0]; test_suite[2].test_case_size = tahi_02_170_size; + test_suite[3].test_case = &tahi_02_171[0]; test_suite[3].test_case_size = tahi_02_171_size; + test_suite[4].test_case = &tahi_02_172[0]; test_suite[4].test_case_size = tahi_02_172_size; + test_suite[5].test_case = &tahi_02_173[0]; test_suite[5].test_case_size = tahi_02_173_size; + test_suite[6].test_case = &tahi_02_174[0]; test_suite[6].test_case_size = tahi_02_174_size; + test_suite[7].test_case = &tahi_02_175[0]; test_suite[7].test_case_size = tahi_02_175_size; + test_suite[8].test_case = &tahi_02_176[0]; test_suite[8].test_case_size = tahi_02_176_size; + test_suite[9].test_case = &tahi_02_177[0]; test_suite[9].test_case_size = tahi_02_177_size; + test_suite[10].test_case = &tahi_02_178[0]; test_suite[10].test_case_size = tahi_02_178_size; + test_suite[11].test_case = &tahi_02_179[0]; test_suite[11].test_case_size = tahi_02_179_size; + test_suite[12].test_case = &tahi_02_180[0]; test_suite[12].test_case_size = tahi_02_180_size; + test_suite[13].test_case = &tahi_02_181[0]; test_suite[13].test_case_size = tahi_02_181_size; + test_suite[14].test_case = &tahi_02_182[0]; test_suite[14].test_case_size = tahi_02_182_size; + test_suite[15].test_case = &tahi_02_183[0]; test_suite[15].test_case_size = tahi_02_183_size; + test_suite[16].test_case = &tahi_02_184[0]; test_suite[16].test_case_size = tahi_02_184_size; + test_suite[17].test_case = &tahi_02_185[0]; test_suite[17].test_case_size = tahi_02_185_size; + test_suite[18].test_case = &tahi_02_186[0]; test_suite[18].test_case_size = tahi_02_186_size; + test_suite[19].test_case = &tahi_02_187[0]; test_suite[19].test_case_size = tahi_02_187_size; + test_suite[20].test_case = &tahi_02_188[0]; test_suite[20].test_case_size = tahi_02_188_size; + test_suite[21].test_case = &tahi_02_189[0]; test_suite[21].test_case_size = tahi_02_189_size; + test_suite[22].test_case = &tahi_02_190[0]; test_suite[22].test_case_size = tahi_02_190_size; + test_suite[23].test_case = &tahi_02_191[0]; test_suite[23].test_case_size = tahi_02_191_size; + test_suite[24].test_case = &tahi_02_192[0]; test_suite[24].test_case_size = tahi_02_192_size; + test_suite[25].test_case = &tahi_02_193[0]; test_suite[25].test_case_size = tahi_02_193_size; + test_suite[26].test_case = &tahi_02_194[0]; test_suite[26].test_case_size = tahi_02_194_size; + test_suite[27].test_case = &tahi_02_195[0]; test_suite[27].test_case_size = tahi_02_195_size; + test_suite[28].test_case = &tahi_02_196[0]; test_suite[28].test_case_size = tahi_02_196_size; + test_suite[29].test_case = &tahi_02_197[0]; test_suite[29].test_case_size = tahi_02_197_size; + test_suite[30].test_case = &tahi_02_198[0]; test_suite[30].test_case_size = tahi_02_198_size; + test_suite[31].test_case = &tahi_02_199[0]; test_suite[31].test_case_size = tahi_02_199_size; + test_suite[32].test_case = &tahi_02_200[0]; test_suite[32].test_case_size = tahi_02_200_size; + test_suite[33].test_case = &tahi_02_201[0]; test_suite[33].test_case_size = tahi_02_201_size; + test_suite[34].test_case = &tahi_02_202[0]; test_suite[34].test_case_size = tahi_02_202_size; + test_suite[35].test_case = &tahi_02_203[0]; test_suite[35].test_case_size = tahi_02_203_size; + test_suite[36].test_case = &tahi_02_204[0]; test_suite[36].test_case_size = tahi_02_204_size; + test_suite[37].test_case = &tahi_02_205[0]; test_suite[37].test_case_size = tahi_02_205_size; + test_suite[38].test_case = &tahi_02_206[0]; test_suite[38].test_case_size = tahi_02_206_size; + test_suite[39].test_case = &tahi_02_207[0]; test_suite[39].test_case_size = tahi_02_207_size; + test_suite[40].test_case = &tahi_02_208[0]; test_suite[40].test_case_size = tahi_02_208_size; + test_suite[41].test_case = &tahi_02_209[0]; test_suite[41].test_case_size = tahi_02_209_size; + test_suite[42].test_case = &tahi_02_210[0]; test_suite[42].test_case_size = tahi_02_210_size; + test_suite[43].test_case = &tahi_02_211[0]; test_suite[43].test_case_size = tahi_02_211_size; + test_suite[44].test_case = &tahi_02_212[0]; test_suite[44].test_case_size = tahi_02_212_size; + test_suite[45].test_case = &tahi_02_213[0]; test_suite[45].test_case_size = tahi_02_213_size; + test_suite[46].test_case = &tahi_02_214[0]; test_suite[46].test_case_size = tahi_02_214_size; + test_suite[47].test_case = &tahi_02_215[0]; test_suite[47].test_case_size = tahi_02_215_size; + test_suite[48].test_case = &tahi_02_216[0]; test_suite[48].test_case_size = tahi_02_216_size; + test_suite[49].test_case = &tahi_02_217[0]; test_suite[49].test_case_size = tahi_02_217_size; + test_suite[50].test_case = &tahi_02_218[0]; test_suite[50].test_case_size = tahi_02_218_size; + test_suite[51].test_case = &tahi_02_219[0]; test_suite[51].test_case_size = tahi_02_219_size; + test_suite[52].test_case = &tahi_02_220[0]; test_suite[52].test_case_size = tahi_02_220_size; + test_suite[53].test_case = &tahi_02_221[0]; test_suite[53].test_case_size = tahi_02_221_size; + test_suite[54].test_case = &tahi_02_222[0]; test_suite[54].test_case_size = tahi_02_222_size; + test_suite[55].test_case = &tahi_02_223[0]; test_suite[55].test_case_size = tahi_02_223_size; + test_suite[56].test_case = &tahi_02_224[0]; test_suite[56].test_case_size = tahi_02_224_size; + test_suite[57].test_case = &tahi_02_225[0]; test_suite[57].test_case_size = tahi_02_225_size; + test_suite[58].test_case = &tahi_02_226[0]; test_suite[58].test_case_size = tahi_02_226_size; + test_suite[59].test_case = &tahi_02_227[0]; test_suite[59].test_case_size = tahi_02_227_size; + test_suite[60].test_case = &tahi_02_228[0]; test_suite[60].test_case_size = tahi_02_228_size; + test_suite[61].test_case = &tahi_02_229[0]; test_suite[61].test_case_size = tahi_02_229_size; + test_suite[62].test_case = &tahi_02_230[0]; test_suite[62].test_case_size = tahi_02_230_size; + test_suite[63].test_case = &tahi_02_231[0]; test_suite[63].test_case_size = tahi_02_231_size; + test_suite[64].test_case = &tahi_02_232[0]; test_suite[64].test_case_size = tahi_02_232_size; + test_suite[65].test_case = &tahi_02_233[0]; test_suite[65].test_case_size = tahi_02_233_size; + test_suite[66].test_case = &tahi_02_234[0]; test_suite[66].test_case_size = tahi_02_234_size; + test_suite[67].test_case = &tahi_02_235[0]; test_suite[67].test_case_size = tahi_02_235_size; + test_suite[68].test_case = &tahi_02_236[0]; test_suite[68].test_case_size = tahi_02_236_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_2_11_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_01.c b/test/regression/tahi_test/netx_tahi_test_3_01.c new file mode 100644 index 00000000..4f77948a --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_01.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_001[]; + +extern int tahi_03_001_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_001[0];test_suite[0].test_case_size = tahi_03_001_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_1_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_02.c b/test/regression/tahi_test/netx_tahi_test_3_02.c new file mode 100644 index 00000000..243beb8b --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_02.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_002[]; + +extern int tahi_03_002_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_002[0];test_suite[0].test_case_size = tahi_03_002_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_2_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_03.c b/test/regression/tahi_test/netx_tahi_test_3_03.c new file mode 100644 index 00000000..4c18fe60 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_03.c @@ -0,0 +1,134 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_003[]; + +extern int tahi_03_003_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_003[0];test_suite[0].test_case_size = tahi_03_003_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_3_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + +} + + +static void thread_0_entry(ULONG thread_input) +{ + + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + netx_tahi_run_test_case(&ip_0, test_suite[0].test_case, test_suite[0].test_case_size); + + test_control_return(0xdeadbeef); +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_04.c b/test/regression/tahi_test/netx_tahi_test_3_04.c new file mode 100644 index 00000000..17b7312d --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_04.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_004[]; + +extern int tahi_03_004_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_004[0];test_suite[0].test_case_size = tahi_03_004_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_4_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_05.c b/test/regression/tahi_test/netx_tahi_test_3_05.c new file mode 100644 index 00000000..c83737f2 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_05.c @@ -0,0 +1,134 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_005[]; + +extern int tahi_03_005_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_005[0];test_suite[0].test_case_size = tahi_03_005_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_5_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + netx_tahi_run_test_case(&ip_0, test_suite[0].test_case, test_suite[0].test_case_size); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_06.c b/test/regression/tahi_test/netx_tahi_test_3_06.c new file mode 100644 index 00000000..8ee174ba --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_06.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_006[]; + +extern int tahi_03_006_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_006[0];test_suite[0].test_case_size = tahi_03_006_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_6_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_07.c b/test/regression/tahi_test/netx_tahi_test_3_07.c new file mode 100644 index 00000000..27bc8903 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_07.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_007[]; + +extern int tahi_03_007_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_007[0];test_suite[0].test_case_size = tahi_03_007_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_7_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_08.c b/test/regression/tahi_test/netx_tahi_test_3_08.c new file mode 100644 index 00000000..3b51c4d3 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_08.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_008[]; + +extern int tahi_03_008_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_008[0];test_suite[0].test_case_size = tahi_03_008_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_8_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_09.c b/test/regression/tahi_test/netx_tahi_test_3_09.c new file mode 100644 index 00000000..894dd97d --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_09.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_009[]; + +extern int tahi_03_009_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_009[0];test_suite[0].test_case_size = tahi_03_009_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_9_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_10.c b/test/regression/tahi_test/netx_tahi_test_3_10.c new file mode 100644 index 00000000..7458d544 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_10.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_010[]; + +extern int tahi_03_010_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_010[0];test_suite[0].test_case_size = tahi_03_010_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_10_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_11.c b/test/regression/tahi_test/netx_tahi_test_3_11.c new file mode 100644 index 00000000..8c38fee1 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_11.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_011[]; + +extern int tahi_03_011_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_011[0];test_suite[0].test_case_size = tahi_03_011_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_11_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_12.c b/test/regression/tahi_test/netx_tahi_test_3_12.c new file mode 100644 index 00000000..0ad915cf --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_12.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_012[]; + +extern int tahi_03_012_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_012[0];test_suite[0].test_case_size = tahi_03_012_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_12_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_13.c b/test/regression/tahi_test/netx_tahi_test_3_13.c new file mode 100644 index 00000000..378f4136 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_13.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_013[]; + +extern int tahi_03_013_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_013[0];test_suite[0].test_case_size = tahi_03_013_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_13_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_14.c b/test/regression/tahi_test/netx_tahi_test_3_14.c new file mode 100644 index 00000000..5e5071ab --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_14.c @@ -0,0 +1,134 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_014[]; + +extern int tahi_03_014_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_014[0];test_suite[0].test_case_size = tahi_03_014_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_14_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + netx_tahi_run_test_case(&ip_0, test_suite[0].test_case, test_suite[0].test_case_size); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_15.c b/test/regression/tahi_test/netx_tahi_test_3_15.c new file mode 100644 index 00000000..60c2fdc8 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_15.c @@ -0,0 +1,134 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_015[]; + +extern int tahi_03_015_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_015[0];test_suite[0].test_case_size = tahi_03_015_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_15_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + netx_tahi_run_test_case(&ip_0, test_suite[0].test_case, test_suite[0].test_case_size); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_16.c b/test/regression/tahi_test/netx_tahi_test_3_16.c new file mode 100644 index 00000000..eafe8225 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_16.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_016[]; + +extern int tahi_03_016_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_016[0];test_suite[0].test_case_size = tahi_03_016_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_16_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_17.c b/test/regression/tahi_test/netx_tahi_test_3_17.c new file mode 100644 index 00000000..0f14d9c0 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_17.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_017[]; + +extern int tahi_03_017_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_017[0];test_suite[0].test_case_size = tahi_03_017_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_17_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_18.c b/test/regression/tahi_test/netx_tahi_test_3_18.c new file mode 100644 index 00000000..42b55e9d --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_18.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_018[]; + +extern int tahi_03_018_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_018[0];test_suite[0].test_case_size = tahi_03_018_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_18_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_19.c b/test/regression/tahi_test/netx_tahi_test_3_19.c new file mode 100644 index 00000000..58d2786d --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_19.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_019[]; + +extern int tahi_03_019_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_019[0];test_suite[0].test_case_size = tahi_03_019_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_19_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_20.c b/test/regression/tahi_test/netx_tahi_test_3_20.c new file mode 100644 index 00000000..41cd922b --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_20.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_020[]; + +extern int tahi_03_020_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_020[0];test_suite[0].test_case_size = tahi_03_020_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_20_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_21.c b/test/regression/tahi_test/netx_tahi_test_3_21.c new file mode 100644 index 00000000..e4ad9526 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_21.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_021[]; + +extern int tahi_03_021_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_021[0];test_suite[0].test_case_size = tahi_03_021_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_21_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64,NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_22.c b/test/regression/tahi_test/netx_tahi_test_3_22.c new file mode 100644 index 00000000..21a1b751 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_22.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_022[]; + +extern int tahi_03_022_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_022[0];test_suite[0].test_case_size = tahi_03_022_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_22_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_23.c b/test/regression/tahi_test/netx_tahi_test_3_23.c new file mode 100644 index 00000000..1e22d972 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_23.c @@ -0,0 +1,134 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_023[]; + +extern int tahi_03_023_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_023[0];test_suite[0].test_case_size = tahi_03_023_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_23_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64,NX_NULL); + netx_tahi_run_test_case(&ip_0, test_suite[0].test_case, test_suite[0].test_case_size); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_24.c b/test/regression/tahi_test/netx_tahi_test_3_24.c new file mode 100644 index 00000000..39bbc823 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_24.c @@ -0,0 +1,134 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_024[]; + +extern int tahi_03_024_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_024[0];test_suite[0].test_case_size = tahi_03_024_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_24_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + + nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + netx_tahi_run_test_case(&ip_0, test_suite[0].test_case, test_suite[0].test_case_size); + + test_control_return(0xdeadbeef); +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_25.c b/test/regression/tahi_test/netx_tahi_test_3_25.c new file mode 100644 index 00000000..a7adbb77 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_25.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_025[]; + +extern int tahi_03_025_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_025[0];test_suite[0].test_case_size = tahi_03_025_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_25_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64,NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_26.c b/test/regression/tahi_test/netx_tahi_test_3_26.c new file mode 100644 index 00000000..c87c2e42 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_26.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_026[]; + +extern int tahi_03_026_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_026[0];test_suite[0].test_case_size = tahi_03_026_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_26_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_27.c b/test/regression/tahi_test/netx_tahi_test_3_27.c new file mode 100644 index 00000000..34858e64 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_27.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_027[]; + +extern int tahi_03_027_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_027[0];test_suite[0].test_case_size = tahi_03_027_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_27_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_28.c b/test/regression/tahi_test/netx_tahi_test_3_28.c new file mode 100644 index 00000000..8b782f10 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_28.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_028[]; + +extern int tahi_03_028_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_028[0];test_suite[0].test_case_size = tahi_03_028_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_28_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_29.c b/test/regression/tahi_test/netx_tahi_test_3_29.c new file mode 100644 index 00000000..0e709366 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_29.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_029[]; + +extern int tahi_03_029_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_029[0];test_suite[0].test_case_size = tahi_03_029_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_29_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_30.c b/test/regression/tahi_test/netx_tahi_test_3_30.c new file mode 100644 index 00000000..34b7afa4 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_30.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_030[]; + +extern int tahi_03_030_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_030[0];test_suite[0].test_case_size = tahi_03_030_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_30_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_31.c b/test/regression/tahi_test/netx_tahi_test_3_31.c new file mode 100644 index 00000000..f13867f5 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_31.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_031[]; + +extern int tahi_03_031_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_031[0];test_suite[0].test_case_size = tahi_03_031_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_31_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_32.c b/test/regression/tahi_test/netx_tahi_test_3_32.c new file mode 100644 index 00000000..481bbf08 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_32.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_032[]; + +extern int tahi_03_032_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_032[0];test_suite[0].test_case_size = tahi_03_032_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_32_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_33.c b/test/regression/tahi_test/netx_tahi_test_3_33.c new file mode 100644 index 00000000..5df8c945 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_33.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_033[]; + +extern int tahi_03_033_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_033[0];test_suite[0].test_case_size = tahi_03_033_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_33_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_34.c b/test/regression/tahi_test/netx_tahi_test_3_34.c new file mode 100644 index 00000000..389ec470 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_34.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_034[]; + +extern int tahi_03_034_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_034[0];test_suite[0].test_case_size = tahi_03_034_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_34_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_35.c b/test/regression/tahi_test/netx_tahi_test_3_35.c new file mode 100644 index 00000000..72d7038c --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_35.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_035[]; + +extern int tahi_03_035_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_035[0];test_suite[0].test_case_size = tahi_03_035_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_35_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_36.c b/test/regression/tahi_test/netx_tahi_test_3_36.c new file mode 100644 index 00000000..ff87d14f --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_36.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_036[]; + +extern int tahi_03_036_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_036[0];test_suite[0].test_case_size = tahi_03_036_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_36_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_37.c b/test/regression/tahi_test/netx_tahi_test_3_37.c new file mode 100644 index 00000000..9b9ea1f3 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_37.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_037[]; + +extern int tahi_03_037_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_037[0];test_suite[0].test_case_size = tahi_03_037_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_37_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_38.c b/test/regression/tahi_test/netx_tahi_test_3_38.c new file mode 100644 index 00000000..5a4cba71 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_38.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_038[]; + +extern int tahi_03_038_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_038[0];test_suite[0].test_case_size = tahi_03_038_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_38_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_39.c b/test/regression/tahi_test/netx_tahi_test_3_39.c new file mode 100644 index 00000000..380b4980 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_39.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_039[]; + +extern int tahi_03_039_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_039[0];test_suite[0].test_case_size = tahi_03_039_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_39_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_40.c b/test/regression/tahi_test/netx_tahi_test_3_40.c new file mode 100644 index 00000000..2261a1c8 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_40.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_040[]; + +extern int tahi_03_040_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_040[0];test_suite[0].test_case_size = tahi_03_040_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_40_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_41.c b/test/regression/tahi_test/netx_tahi_test_3_41.c new file mode 100644 index 00000000..ff53aa97 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_41.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_041[]; + +extern int tahi_03_041_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_041[0];test_suite[0].test_case_size = tahi_03_041_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_41_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_42.c b/test/regression/tahi_test/netx_tahi_test_3_42.c new file mode 100644 index 00000000..94199e20 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_42.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_042[]; + +extern int tahi_03_042_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_042[0];test_suite[0].test_case_size = tahi_03_042_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_42_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_43.c b/test/regression/tahi_test/netx_tahi_test_3_43.c new file mode 100644 index 00000000..c5444738 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_43.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_043[]; + +extern int tahi_03_043_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_043[0];test_suite[0].test_case_size = tahi_03_043_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_43_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_44.c b/test/regression/tahi_test/netx_tahi_test_3_44.c new file mode 100644 index 00000000..3b5c7085 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_44.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_044[]; + +extern int tahi_03_044_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_044[0];test_suite[0].test_case_size = tahi_03_044_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_44_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_3_45.c b/test/regression/tahi_test/netx_tahi_test_3_45.c new file mode 100644 index 00000000..a7f74972 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_3_45.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_03_045[]; + +extern int tahi_03_045_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_03_045[0];test_suite[0].test_case_size = tahi_03_045_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_3_45_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_10.c b/test/regression/tahi_test/netx_tahi_test_4_10.c new file mode 100644 index 00000000..af66b9b3 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_10.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_010[]; + +extern int tahi_04_010_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_010[0];test_suite[0].test_case_size = tahi_04_010_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_10_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_11.c b/test/regression/tahi_test/netx_tahi_test_4_11.c new file mode 100644 index 00000000..06f32e44 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_11.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_011[]; + +extern int tahi_04_011_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_011[0];test_suite[0].test_case_size = tahi_04_011_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_11_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_12.c b/test/regression/tahi_test/netx_tahi_test_4_12.c new file mode 100644 index 00000000..f928c0f1 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_12.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_012[]; + +extern int tahi_04_012_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_012[0];test_suite[0].test_case_size = tahi_04_012_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_12_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_13.c b/test/regression/tahi_test/netx_tahi_test_4_13.c new file mode 100644 index 00000000..adb744df --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_13.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_013[]; + +extern int tahi_04_013_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_013[0];test_suite[0].test_case_size = tahi_04_013_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_13_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_14.c b/test/regression/tahi_test/netx_tahi_test_4_14.c new file mode 100644 index 00000000..a30335d9 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_14.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_014[]; + +extern int tahi_04_014_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_014[0];test_suite[0].test_case_size = tahi_04_014_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_14_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_15.c b/test/regression/tahi_test/netx_tahi_test_4_15.c new file mode 100644 index 00000000..0b396aea --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_15.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_015[]; + +extern int tahi_04_015_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_015[0];test_suite[0].test_case_size = tahi_04_015_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_15_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", (1536 + NX_IPSEC_MAX_HEADER_SIZE), pointer, (1536 + NX_IPSEC_MAX_HEADER_SIZE) * 16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_16.c b/test/regression/tahi_test/netx_tahi_test_4_16.c new file mode 100644 index 00000000..e0520ae2 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_16.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_016[]; + +extern int tahi_04_016_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_016[0];test_suite[0].test_case_size = tahi_04_016_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_16_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", (1536 + NX_IPSEC_MAX_HEADER_SIZE), pointer, (1536 + NX_IPSEC_MAX_HEADER_SIZE)*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_2.c b/test/regression/tahi_test/netx_tahi_test_4_2.c new file mode 100644 index 00000000..ce54b5e2 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_2.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_002[]; + +extern int tahi_04_002_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_002[0];test_suite[0].test_case_size = tahi_04_002_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_2_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_3.c b/test/regression/tahi_test/netx_tahi_test_4_3.c new file mode 100644 index 00000000..f04f322b --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_3.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_003[]; + +extern int tahi_04_003_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_003[0];test_suite[0].test_case_size = tahi_04_003_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_3_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_4.c b/test/regression/tahi_test/netx_tahi_test_4_4.c new file mode 100644 index 00000000..8a6d638a --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_4.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_004[]; + +extern int tahi_04_004_size; + +static TAHI_TEST_SUITE test_suite[15]; +static void build_test_suite(void) +{ + test_suite[2].test_case = &tahi_04_004[0];test_suite[2].test_case_size = tahi_04_004_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_4_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_5.c b/test/regression/tahi_test/netx_tahi_test_4_5.c new file mode 100644 index 00000000..c4705505 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_5.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_005[]; + +extern int tahi_04_005_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_005[0];test_suite[0].test_case_size = tahi_04_005_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_5_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_6.c b/test/regression/tahi_test/netx_tahi_test_4_6.c new file mode 100644 index 00000000..95ccba40 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_6.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_006[]; + +extern int tahi_04_006_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_006[0];test_suite[0].test_case_size = tahi_04_006_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_6_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_7.c b/test/regression/tahi_test/netx_tahi_test_4_7.c new file mode 100644 index 00000000..5ca40c49 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_7.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_007[]; + +extern int tahi_04_007_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_007[0];test_suite[0].test_case_size = tahi_04_007_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_7_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_8.c b/test/regression/tahi_test/netx_tahi_test_4_8.c new file mode 100644 index 00000000..263fb63e --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_8.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_008[]; + +extern int tahi_04_008_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_008[0];test_suite[0].test_case_size = tahi_04_008_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_8_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_4_9.c b/test/regression/tahi_test/netx_tahi_test_4_9.c new file mode 100644 index 00000000..3f0a5be6 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_4_9.c @@ -0,0 +1,150 @@ +#include "tx_api.h" +#include "nx_api.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) && defined(NX_ENABLE_IPV6_PATH_MTU_DISCOVERY) +#include "netx_tahi.h" +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_04_009[]; + +extern int tahi_04_009_size; + +static TAHI_TEST_SUITE test_suite[1]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_04_009[0];test_suite[0].test_case_size = tahi_04_009_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_4_9_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += _nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_5.c b/test/regression/tahi_test/netx_tahi_test_5.c new file mode 100644 index 00000000..7ae4010c --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_5.c @@ -0,0 +1,208 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" +#if defined(FEATURE_NX_IPV6) && defined(NX_TAHI_ENABLE) +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; + +static NXD_ADDRESS ipv6_address_1; + + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); + +/* Define the test threads. */ + +extern TAHI_TEST_SEQ tahi_05_002[]; +extern TAHI_TEST_SEQ tahi_05_003[]; +extern TAHI_TEST_SEQ tahi_05_004[]; +extern TAHI_TEST_SEQ tahi_05_005[]; +extern TAHI_TEST_SEQ tahi_05_006[]; +extern TAHI_TEST_SEQ tahi_05_007[]; +extern TAHI_TEST_SEQ tahi_05_008[]; +extern TAHI_TEST_SEQ tahi_05_009[]; +extern TAHI_TEST_SEQ tahi_05_010[]; +extern TAHI_TEST_SEQ tahi_05_012[]; +extern TAHI_TEST_SEQ tahi_05_013[]; +extern TAHI_TEST_SEQ tahi_05_014[]; +extern TAHI_TEST_SEQ tahi_05_015[]; +extern TAHI_TEST_SEQ tahi_05_017[]; +extern TAHI_TEST_SEQ tahi_05_018[]; +extern TAHI_TEST_SEQ tahi_05_020[]; +extern TAHI_TEST_SEQ tahi_05_021[]; +extern TAHI_TEST_SEQ tahi_05_022[]; +extern TAHI_TEST_SEQ tahi_05_024[]; +extern TAHI_TEST_SEQ tahi_05_025[]; + +extern int tahi_05_002_size; +extern int tahi_05_003_size; +extern int tahi_05_004_size; +extern int tahi_05_005_size; +extern int tahi_05_006_size; +extern int tahi_05_007_size; +extern int tahi_05_008_size; +extern int tahi_05_009_size; +extern int tahi_05_010_size; +extern int tahi_05_012_size; +extern int tahi_05_013_size; +extern int tahi_05_014_size; +extern int tahi_05_015_size; +extern int tahi_05_017_size; +extern int tahi_05_018_size; +extern int tahi_05_020_size; +extern int tahi_05_021_size; +extern int tahi_05_022_size; +extern int tahi_05_024_size; +extern int tahi_05_025_size; + + +static TAHI_TEST_SUITE test_suite[20]; +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_05_002[0];test_suite[0].test_case_size = tahi_05_002_size; + test_suite[1].test_case = &tahi_05_003[0];test_suite[1].test_case_size = tahi_05_003_size; + test_suite[2].test_case = &tahi_05_004[0];test_suite[2].test_case_size = tahi_05_004_size; + test_suite[3].test_case = &tahi_05_005[0];test_suite[3].test_case_size = tahi_05_005_size; + test_suite[4].test_case = &tahi_05_006[0];test_suite[4].test_case_size = tahi_05_006_size; + test_suite[5].test_case = &tahi_05_007[0];test_suite[5].test_case_size = tahi_05_007_size; + test_suite[6].test_case = &tahi_05_008[0];test_suite[6].test_case_size = tahi_05_008_size; + test_suite[7].test_case = &tahi_05_009[0];test_suite[7].test_case_size = tahi_05_009_size; + test_suite[8].test_case = &tahi_05_010[0];test_suite[8].test_case_size = tahi_05_010_size; + test_suite[9].test_case = &tahi_05_012[0];test_suite[9].test_case_size = tahi_05_012_size; + test_suite[10].test_case = &tahi_05_013[0];test_suite[10].test_case_size = tahi_05_013_size; + test_suite[11].test_case = &tahi_05_014[0];test_suite[11].test_case_size = tahi_05_014_size; + test_suite[12].test_case = &tahi_05_015[0];test_suite[12].test_case_size = tahi_05_015_size; + test_suite[13].test_case = &tahi_05_017[0];test_suite[13].test_case_size = tahi_05_017_size; + test_suite[14].test_case = &tahi_05_018[0];test_suite[14].test_case_size = tahi_05_018_size; + test_suite[15].test_case = &tahi_05_020[0];test_suite[15].test_case_size = tahi_05_020_size; + test_suite[16].test_case = &tahi_05_021[0];test_suite[16].test_case_size = tahi_05_021_size; + test_suite[17].test_case = &tahi_05_022[0];test_suite[17].test_case_size = tahi_05_022_size; + test_suite[18].test_case = &tahi_05_024[0];test_suite[18].test_case_size = tahi_05_024_size; + test_suite[19].test_case = &tahi_05_025[0];test_suite[19].test_case_size = tahi_05_025_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_5_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + /* Enable IPv6 */ + status = nxd_ipv6_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status = nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_udp_enable(&ip_0); + + /* Check fragment enable status. */ + if(status) + error_counter++; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1,64, NX_NULL); + + if(status) + error_counter++; +} + + +static void thread_0_entry(ULONG thread_input) +{ + int num_suite; + int i; + + + num_suite = sizeof(test_suite) / sizeof(TAHI_TEST_SUITE); + + for(i = 0; i < num_suite; i++) + { + if(test_suite[i].test_case) + netx_tahi_run_test_case(&ip_0, test_suite[i].test_case, test_suite[i].test_case_size); + } + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_ipsec.c b/test/regression/tahi_test/netx_tahi_test_ipsec.c new file mode 100644 index 00000000..292704c5 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_ipsec.c @@ -0,0 +1,625 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" + +#if defined FEATURE_NX_IPV6 && defined NX_IPSEC_ENABLE && defined NX_TAHI_ENABLE + +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_ipsec.h" +#include "nx_crypto.h" +#include "nx_crypto_3des.h" +#include "nx_crypto_aes.h" +#include "nx_crypto_des.h" +#include "nx_crypto_dh.h" +#include "nx_crypto_hmac_md5.h" +#include "nx_crypto_hmac_sha1.h" +#include "nx_crypto_md5.h" +#include "nx_crypto_null.h" +#include "nx_crypto_sha1.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define IPSEC_MAX_END_NODE 10 +#define IPSEC_SA_LIFETIME 5000 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; + +/* Define IPSEC related data. */ + +static NX_IPSEC_SELECTOR ingress_selectors[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SELECTOR egress_selectors[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SA ingress_sa[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SA egress_sa[IPSEC_MAX_END_NODE]; +static UCHAR ingress_hmac_sha1[IPSEC_MAX_END_NODE][20]; +static UCHAR ingress_3des_cbc[IPSEC_MAX_END_NODE][24]; +static UCHAR ingress_aes_cbc[IPSEC_MAX_END_NODE][32]; +static UCHAR egress_hmac_sha1[IPSEC_MAX_END_NODE][20]; +static UCHAR egress_3des_cbc[IPSEC_MAX_END_NODE][24]; +static UCHAR egress_aes_cbc[IPSEC_MAX_END_NODE][32]; +static UCHAR egress_aes_xcbc_mac[32]; +static UCHAR ingress_aes_xcbc_mac[32]; +static ULONG egress_spi[IPSEC_MAX_END_NODE]; +static ULONG ingress_spi[IPSEC_MAX_END_NODE]; +static UCHAR ingress_aes_ctr[32]; +static UCHAR egress_aes_ctr[32]; + +/* Define the Crypto Method */ + +static NX_CRYPTO_3DES egress_3des[IPSEC_MAX_END_NODE]; +static NX_CRYPTO_3DES ingress_3des[IPSEC_MAX_END_NODE]; +static NX_SHA1_HMAC metadata_egress_hmac_sha1[IPSEC_MAX_END_NODE]; +static NX_SHA1_HMAC metadata_ingress_hmac_sha1[IPSEC_MAX_END_NODE]; + + +/* 3DES, encrypt */ +static NX_CRYPTO_METHOD crypto_method_t_des = +{ + NX_CRYPTO_ENCRYPTION_3DES_CBC, /* 3DES-CBC crypto algorithm */ + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, /* Key size in bits */ + NX_CRYPTO_3DES_IV_LEN_IN_BITS, /* IV size in bits */ + 0, /* ICV size in bits, not used */ + (NX_CRYPTO_3DES_BLOCK_SIZE_IN_BITS>>3), /* Block size in bytes */ + sizeof(NX_CRYPTO_3DES), /* 768 */ /* Metadata size in bytes */ + _nx_ipsec_crypto_method_3des_init, /* 3DES-CBC initialization routine. */ + NX_NULL, /* 3DES-CBC cleanup routine, not used */ + _nx_ipsec_crypto_method_3des_operation /* 3DES-CBC operation */ +}; + +/* HMAC SHA1 */ +static NX_CRYPTO_METHOD crypto_method_hmac_sha1 = +{ + NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_96, /* HMAC SHA1 algorithm */ + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, /* Key size in bits */ + 0, /* IV size in bits, not used */ + NX_CRYPTO_AUTHENTICATION_ICV_TRUNC_BITS, /* Transmitted ICV size in bits */ + 0, /* Block size in bytes, not used */ + 0, /* Metadata size in bytes */ + NX_NULL, /* Initialization routine, not used */ + NX_NULL, /* Cleanup routine, not used */ + _nx_ipsec_crypto_method_hmac_sha1_operation /* HMAC SHA1 operation */ +}; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void init_para(); +static UINT clean_sa(); +static VOID sa_timeout_process(NX_IP *ip_ptr, NX_IPSEC_SA *sa); + +static UINT create_sa(UINT index, UCHAR sa_mode, + NX_CRYPTO_METHOD* sa_encryption_method_ingress, NX_CRYPTO_METHOD* sa_encryption_method_egress, + UCHAR *sa_encryption_key_ingress, UCHAR *sa_encryption_key_egress, + UINT sa_encryption_key_len_in_bits, + NX_CRYPTO_METHOD* sa_integrity_method, + UCHAR *sa_integrity_key_ingress, UCHAR *sa_integrity_key_egress, + UINT sa_integrity_key_len_in_bits, + VOID *crypto_metadata_area_ingress, VOID *crypto_metadata_area_egress, ULONG crypto_metadata_size, + VOID *authentication_metadata_area_ingress, VOID *authentication_metadata_area_egress, ULONG authentication_metadata_size); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_ipsec_001[]; +extern TAHI_TEST_SEQ tahi_ipsec_002[]; +extern TAHI_TEST_SEQ tahi_ipsec_003[]; +extern TAHI_TEST_SEQ tahi_ipsec_004[]; +extern TAHI_TEST_SEQ tahi_ipsec_005[]; + +extern int tahi_ipsec_001_size; +extern int tahi_ipsec_002_size; +extern int tahi_ipsec_003_size; +extern int tahi_ipsec_004_size; +extern int tahi_ipsec_005_size; + +static TAHI_TEST_SUITE test_suite[10]; + +static void build_test_suite(void) +{ + test_suite[0].test_case = &tahi_ipsec_001[0]; test_suite[0].test_case_size = tahi_ipsec_001_size; + test_suite[1].test_case = &tahi_ipsec_002[0]; test_suite[1].test_case_size = tahi_ipsec_002_size; + test_suite[2].test_case = &tahi_ipsec_003[0]; test_suite[2].test_case_size = tahi_ipsec_003_size; + test_suite[3].test_case = &tahi_ipsec_004[0]; test_suite[3].test_case_size = tahi_ipsec_004_size; + test_suite[4].test_case = &tahi_ipsec_005[0]; test_suite[4].test_case_size = tahi_ipsec_005_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_ipsec_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + + /* Check IP create status. */ + if(status) + error_counter++; + + pointer = pointer + 2048; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Enable IPv6 */ + status += nx_ipsec_enable(&ip_0); + + /* Enable UDP */ + status += nx_udp_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + + /* Set ipv6 version and address. */ + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x3ffe0501; + ipv6_address_2.nxd_ip_address.v6[1] = 0xffff0000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_2.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_2, 64, NX_NULL); + + /* Check fragment enable status. */ + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + + init_para(); + + netx_tahi_run_test_case(&ip_0, test_suite[0].test_case, test_suite[0].test_case_size); + + + create_sa(0,NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des,&crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + create_sa(1,NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des,&crypto_method_t_des, + ingress_3des_cbc[1], egress_3des_cbc[1], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[1], egress_hmac_sha1[1], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[1], &egress_3des[1], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[1], &metadata_egress_hmac_sha1[1], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[1].test_case, test_suite[1].test_case_size); + + + clean_sa(); + create_sa(2,NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des,&crypto_method_t_des, + ingress_3des_cbc[2], egress_3des_cbc[2], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[2], egress_hmac_sha1[2], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[2], &egress_3des[2], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[2], &metadata_egress_hmac_sha1[2], sizeof(NX_SHA1_HMAC)); + create_sa(3,NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des,&crypto_method_t_des, + ingress_3des_cbc[3], egress_3des_cbc[3], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[3], egress_hmac_sha1[3], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[3], &egress_3des[3], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[3], &metadata_egress_hmac_sha1[3], sizeof(NX_SHA1_HMAC)); + + netx_tahi_run_test_case(&ip_0, test_suite[2].test_case, test_suite[2].test_case_size); + + + clean_sa(); + create_sa(0,NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des,&crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[3].test_case, test_suite[3].test_case_size); + +#if 0 + clean_sa(); + create_sa(0,NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des,&crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[4].test_case, test_suite[4].test_case_size); +#endif + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +/* Initialize parameters for IPSec. */ +static void init_para() +{ + UINT i; + + /* Setup addresses of selectors. */ + for(i = 0; i < IPSEC_MAX_END_NODE; i++) + { + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x3ffe0501; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0xffff0000; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x021122ff; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0xfe334456; + memcpy(&egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&ingress_selectors[i].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[i].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + + ingress_selectors[i].nx_ipsec_selector_next_layer_protocol_id = NX_NULL; + egress_selectors[i].nx_ipsec_selector_next_layer_protocol_id = NX_NULL; + ingress_selectors[i].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_PROTECT; + egress_selectors[i].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_PROTECT; + } + + /*Setup destination IP address. */ + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x3ffe0501; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0001; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000001; + memcpy(&egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&ingress_selectors[0].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[0].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000002; + memcpy(&egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[1].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[1].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[2].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[2].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[3].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[3].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + /* Used by test case 8-2 */ + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_BYPASS; + egress_selectors[4].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_BYPASS; + + /* Used by test case 9-2 */ + + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_DROP; + egress_selectors[5].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_DROP; + + /* Used by test case 22 */ + memcpy(&egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[6].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[6].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + /* Used by test case 23 */ + memcpy(&egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0002; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + memcpy(&egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0xFFFFFFFF; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0xFFFFFFFF; + memcpy(&ingress_selectors[7].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[7].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end, sizeof(NXD_ADDRESS)); + + /* Used by test case 24-1 */ + memcpy(&egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0002; + memcpy(&egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[8].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[8].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + /* Used by test case 24-2 */ + memcpy(&egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000002; + memcpy(&egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[9].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[9].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + + /* Setup SPI. */ + ingress_spi[0] = 0x1000; + egress_spi[0] = 0x2000; + ingress_spi[1] = 0x3000; + egress_spi[1] = 0x4000; + ingress_spi[2] = 0x1000; + egress_spi[2] = 0x2000; + ingress_spi[3] = 0x1000; + egress_spi[3] = 0x3000; + ingress_spi[4] = 0x1000; + egress_spi[4] = 0x2000; + ingress_spi[5] = 0x1000; + egress_spi[5] = 0x2000; + ingress_spi[6] = 0x1000; + egress_spi[6] = 0x2000; + ingress_spi[7] = 0x1000; + egress_spi[7] = 0x2000; + ingress_spi[8] = 0x1000; + egress_spi[8] = 0x2000; + ingress_spi[9] = 0x3000; + egress_spi[9] = 0x4000; + + /* Setup encryption key. */ + memcpy(&ingress_3des_cbc[0], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[0], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[0], "ipv6readylogo3descbcout1", 24); + memcpy(&egress_hmac_sha1[0], "ipv6readylogsha1out1", 20); + + memcpy(&ingress_3des_cbc[1], "ipv6readylogo3descbcin02", 24); + memcpy(&ingress_hmac_sha1[1], "ipv6readylogsha1in02", 20); + memcpy(&egress_3des_cbc[1], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[1], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_3des_cbc[2], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[2], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[2], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[2], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_3des_cbc[3], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[3], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[3], "ipv6readylogo3descbcout3", 24); + memcpy(&egress_hmac_sha1[3], "ipv6readylogsha1out3", 20); + + memcpy(&ingress_aes_cbc[0], "ipv6readaescin01", 16); + memcpy(&egress_aes_cbc[0], "ipv6readaescout1", 16); + + memcpy(&ingress_aes_ctr, "ipv6readylogaescin01", 20); + memcpy(&egress_aes_ctr, "ipv6readylogaescout1", 20); + + memcpy(&ingress_3des_cbc[9], "ipv6readylogo3descbcin02", 24); + memcpy(&ingress_hmac_sha1[9], "ipv6readylogsha1in02", 20); + memcpy(&egress_3des_cbc[9], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[9], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_aes_xcbc_mac, "ipv6readaesxin01", 16); + memcpy(&egress_aes_xcbc_mac, "ipv6readaesxout1", 16); + + /* Setup selectors. */ + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 128; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 128; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + egress_selectors[2].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 129; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 129; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 128; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 128; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + egress_selectors[3].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 1; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 1; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 4; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 4; + +} + + +/* Clean SA for IPSec. */ +static UINT clean_sa() +{ + + UINT status = 0, i; + + for(i = 0; i < IPSEC_MAX_END_NODE; i++) + { + if(ingress_sa[i].nx_ipsec_sa_id) + status = _nxe_ipsec_sa_delete(&ingress_sa[i]); + if(egress_sa[i].nx_ipsec_sa_id) + status += _nxe_ipsec_sa_delete(&egress_sa[i]); + + } + + return status; +} + +static VOID sa_timeout_process(NX_IP *ip_ptr, NX_IPSEC_SA *sa) +{ + nx_ipsec_sa_update(sa, sa->nx_ipsec_sa_spi, NX_IPSEC_SA_MATURE, IPSEC_SA_LIFETIME, (IPSEC_SA_LIFETIME - 3), + sa->nx_ipsec_sa_encrypt_key_string, sa->nx_ipsec_sa_encryption_method -> nx_crypto_key_size_in_bits, + sa->nx_ipsec_sa_integrity_key_string, sa->nx_ipsec_sa_integrity_method -> nx_crypto_key_size_in_bits); + return; +} + +/* Create SA for IPSec. */ +UINT create_sa(UINT index, UCHAR sa_mode, + NX_CRYPTO_METHOD* sa_encryption_method_ingress, NX_CRYPTO_METHOD* sa_encryption_method_egress, + UCHAR *sa_encryption_key_ingress, UCHAR *sa_encryption_key_egress, + UINT sa_encryption_key_len_in_bits, + NX_CRYPTO_METHOD* sa_integrity_method, + UCHAR *sa_integrity_key_ingress, UCHAR *sa_integrity_key_egress, + UINT sa_integrity_key_len_in_bits, + VOID *crypto_metadata_area_ingress, VOID *crypto_metadata_area_egress, ULONG crypto_metadata_size, + VOID *authentication_metadata_area_ingress, VOID *authentication_metadata_area_egress, ULONG authentication_metadata_size) +{ + + UINT status; + + status = _nx_ipsec_sa_create(&ip_0, &ingress_sa[index], sa_mode, NX_PROTOCOL_NEXT_HEADER_ENCAP_SECURITY, + NX_IPSEC_MANUAL_KEY, NX_IPSEC_SA_INGRESS, &ingress_selectors[index], IPSEC_SA_LIFETIME, + (IPSEC_SA_LIFETIME) - 3, sa_timeout_process, 0, ingress_spi[index], + sa_encryption_method_ingress, crypto_metadata_area_ingress, crypto_metadata_size, + sa_encryption_key_ingress, sa_encryption_key_len_in_bits, + sa_integrity_method, authentication_metadata_area_ingress, authentication_metadata_size, + sa_integrity_key_ingress, sa_integrity_key_len_in_bits); + + if (status) + error_counter++; + + status += _nx_ipsec_sa_create(&ip_0, &egress_sa[index], sa_mode, NX_PROTOCOL_NEXT_HEADER_ENCAP_SECURITY, + NX_IPSEC_MANUAL_KEY, NX_IPSEC_SA_EGRESS, &egress_selectors[index], IPSEC_SA_LIFETIME, + (IPSEC_SA_LIFETIME) - 3, sa_timeout_process, 0, egress_spi[index], + sa_encryption_method_egress, crypto_metadata_area_egress, crypto_metadata_size, + sa_encryption_key_egress, sa_encryption_key_len_in_bits, + sa_integrity_method, authentication_metadata_area_egress, authentication_metadata_size, + sa_integrity_key_egress, sa_integrity_key_len_in_bits); + if (status) + error_counter++; + + return status; +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_ipsec_2.c b/test/regression/tahi_test/netx_tahi_test_ipsec_2.c new file mode 100644 index 00000000..f154b5c6 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_ipsec_2.c @@ -0,0 +1,899 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" + +#if defined FEATURE_NX_IPV6 && defined NX_IPSEC_ENABLE && defined NX_TAHI_ENABLE + +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_ipsec.h" +#include "nx_crypto.h" +#include "nx_crypto_3des.h" +#include "nx_crypto_aes.h" +#include "nx_crypto_des.h" +#include "nx_crypto_dh.h" +#include "nx_crypto_hmac_md5.h" +#include "nx_crypto_hmac_sha1.h" +#include "nx_crypto_md5.h" +#include "nx_crypto_null.h" +#include "nx_crypto_sha1.h" + + + + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define IPSEC_MAX_END_NODE 10 +#define IPSEC_SA_LIFETIME 5000 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; + + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; + +static NXD_ADDRESS tunnel_entry_address; +static NXD_ADDRESS tunnel_exit_address; + +/* Define IPSEC related data. */ + +static NX_IPSEC_SELECTOR ingress_selectors[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SELECTOR egress_selectors[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SA ingress_sa[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SA egress_sa[IPSEC_MAX_END_NODE]; +static UCHAR ingress_hmac_sha1[IPSEC_MAX_END_NODE][20]; +static UCHAR ingress_3des_cbc[IPSEC_MAX_END_NODE][24]; +static UCHAR ingress_aes_cbc[IPSEC_MAX_END_NODE][32]; +static UCHAR egress_hmac_sha1[IPSEC_MAX_END_NODE][20]; +static UCHAR egress_3des_cbc[IPSEC_MAX_END_NODE][24]; +static UCHAR egress_aes_cbc[IPSEC_MAX_END_NODE][32]; +static UCHAR egress_aes_xcbc_mac[32]; +static UCHAR ingress_aes_xcbc_mac[32]; +static ULONG egress_spi[IPSEC_MAX_END_NODE]; +static ULONG ingress_spi[IPSEC_MAX_END_NODE]; +static UCHAR ingress_aes_ctr[32]; +static UCHAR egress_aes_ctr[32]; + +/* Define the Crypto Method */ + +static NX_CRYPTO_3DES egress_3des[IPSEC_MAX_END_NODE]; +static NX_CRYPTO_3DES ingress_3des[IPSEC_MAX_END_NODE]; + +static NX_CRYPTO_AES egress_aes[IPSEC_MAX_END_NODE]; +static NX_CRYPTO_AES ingress_aes[IPSEC_MAX_END_NODE]; +static NX_CRYPTO_AES egress_aes_xcbc; +static NX_CRYPTO_AES ingress_aes_xcbc; + +static NX_SHA1_HMAC metadata_egress_hmac_sha1[IPSEC_MAX_END_NODE]; +static NX_SHA1_HMAC metadata_ingress_hmac_sha1[IPSEC_MAX_END_NODE]; + +/* NULL encrypt */ +static NX_CRYPTO_METHOD crypto_method_null = +{ + NX_CRYPTO_ENCRYPTION_NULL, /* Name of the crypto algorithm */ + 0, /* Key size in bits, not used */ + 0, /* IV size in bits, not used */ + 0, /* ICV size in bits, not used */ + 4, /* Block size in bytes */ + 0, /* Metadata size in bytes */ + NX_NULL, /* Initialization routine, not used */ + NX_NULL, /* Cleanup routine, not used */ + _nx_ipsec_crypto_method_null_operation /* NULL operation */ +}; + + +/* 3DES, encrypt */ +static NX_CRYPTO_METHOD crypto_method_t_des = +{ + NX_CRYPTO_ENCRYPTION_3DES_CBC, /* 3DES-CBC crypto algorithm */ + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, /* Key size in bits */ + NX_CRYPTO_3DES_IV_LEN_IN_BITS, /* IV size in bits */ + 0, /* ICV size in bits, not used */ + (NX_CRYPTO_3DES_BLOCK_SIZE_IN_BITS>>3), /* Block size in bytes */ + sizeof(NX_CRYPTO_3DES), /* 768 */ /* Metadata size in bytes */ + _nx_ipsec_crypto_method_3des_init, /* 3DES-CBC initialization routine. */ + NX_NULL, /* 3DES-CBC cleanup routine, not used */ + _nx_ipsec_crypto_method_3des_operation /* 3DES-CBC operation */ +}; + +/* AES-CBC. */ +static NX_CRYPTO_METHOD crypto_method_aes_cbc = +{ + NX_CRYPTO_ENCRYPTION_AES_CBC, /* AES crypto algorithm */ + NX_CRYPTO_AES_128_KEY_LEN_IN_BITS, /* Key size in bits */ + NX_CRYPTO_AES_IV_LEN_IN_BITS, /* IV size in bits */ + 0, /* ICV size in bits, not used. */ + (NX_CRYPTO_AES_BLOCK_SIZE_IN_BITS >> 3), /* Block size in bytes. */ + sizeof(NX_CRYPTO_AES), /* 262 */ /* Metadata size in bytes */ + _nx_ipsec_crypto_method_aes_init, /* AES-CBC initialization routine. */ + NX_NULL, /* AES-CBC cleanup routine, not used. */ + _nx_ipsec_crypto_method_aes_operation /* AES-CBC operation */ + +}; + +/* AES-CTR. */ +static NX_CRYPTO_METHOD crypto_method_aes_ctr = +{ + NX_CRYPTO_ENCRYPTION_AES_CTR, /* AES crypto algorithm */ + NX_CRYPTO_AES_128_KEY_LEN_IN_BITS, /* Key size in bits */ + NX_CRYPTO_AES_CTR_IV_LEN_IN_BITS, /* IV size in bits */ + 0, /* ICV size in bits, not used. */ + (NX_CRYPTO_AES_BLOCK_SIZE_IN_BITS >> 3), /* Block size in bytes. */ + sizeof(NX_CRYPTO_AES), /* 262 */ /* Metadata size in bytes */ + _nx_ipsec_crypto_method_aes_init, /* AES-CBC initialization routine. */ + NX_NULL, /* AES-CBC cleanup routine, not used. */ + _nx_ipsec_crypto_method_aes_operation /* AES-CBC operation */ +}; + +/* HMAC SHA1 */ +static NX_CRYPTO_METHOD crypto_method_hmac_sha1 = +{ + NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_96, /* HMAC SHA1 algorithm */ + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, /* Key size in bits */ + 0, /* IV size in bits, not used */ + NX_CRYPTO_AUTHENTICATION_ICV_TRUNC_BITS, /* Transmitted ICV size in bits */ + 0, /* Block size in bytes, not used */ + 0, /* Metadata size in bytes */ + NX_NULL, /* Initialization routine, not used */ + NX_NULL, /* Cleanup routine, not used */ + _nx_ipsec_crypto_method_hmac_sha1_operation /* HMAC SHA1 operation */ +}; + +/* AES_XCBC_96 */ +static NX_CRYPTO_METHOD crypto_method_aes_xcbc_mac = +{ + NX_CRYPTO_AUTHENTICATION_AES_XCBC_MAC_96, /* AES_XCBC_MAC algorithm */ + NX_CRYPTO_AES_XCBC_MAC_KEY_LEN_IN_BITS, /* Key size in bits */ + 0, /* IV size in bits, not used */ + NX_CRYPTO_AUTHENTICATION_ICV_TRUNC_BITS, /* Transmitted ICV size in bits */ + 0, /* Block size in bytes, not used */ + sizeof(NX_CRYPTO_AES), /* 262 */ /* Metadata size in bytes */ + NX_NULL, /* Initialization routine, not used */ + NX_NULL, /* Cleanup routine, not used */ + _nx_ipsec_crypto_method_aes_xcbc_mac_operation /* AES_XCBC_MAC operation */ +}; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void init_para(); +static UINT clean_sa(); +static VOID sa_timeout_process(NX_IP *ip_ptr, NX_IPSEC_SA *sa); + +static UINT create_sa(UINT index, UCHAR sa_mode, + NX_CRYPTO_METHOD* sa_encryption_method_ingress, NX_CRYPTO_METHOD* sa_encryption_method_egress, + UCHAR *sa_encryption_key_ingress, UCHAR *sa_encryption_key_egress, + UINT sa_encryption_key_len_in_bits, + NX_CRYPTO_METHOD* sa_integrity_method, + UCHAR *sa_integrity_key_ingress, UCHAR *sa_integrity_key_egress, + UINT sa_integrity_key_len_in_bits, + VOID *crypto_metadata_area_ingress, VOID *crypto_metadata_area_egress, ULONG crypto_metadata_size, + VOID *authentication_metadata_area_ingress, VOID *authentication_metadata_area_egress, ULONG authentication_metadata_size); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_ipsec_006[]; +extern TAHI_TEST_SEQ tahi_ipsec_007[]; +extern TAHI_TEST_SEQ tahi_ipsec_008[]; +/* +extern TAHI_TEST_SEQ tahi_ipsec_008_02[]; +*/ +extern TAHI_TEST_SEQ tahi_ipsec_009[]; +extern TAHI_TEST_SEQ tahi_ipsec_009_02[]; +extern TAHI_TEST_SEQ tahi_ipsec_010[]; +extern TAHI_TEST_SEQ tahi_ipsec_011[]; +extern TAHI_TEST_SEQ tahi_ipsec_012[]; +extern TAHI_TEST_SEQ tahi_ipsec_013[]; +extern TAHI_TEST_SEQ tahi_ipsec_014[]; +extern TAHI_TEST_SEQ tahi_ipsec_015[]; +extern TAHI_TEST_SEQ tahi_ipsec_016[]; +extern TAHI_TEST_SEQ tahi_ipsec_017[]; +extern TAHI_TEST_SEQ tahi_ipsec_018[]; +extern TAHI_TEST_SEQ tahi_ipsec_019[]; +extern TAHI_TEST_SEQ tahi_ipsec_020[]; +extern TAHI_TEST_SEQ tahi_ipsec_021[]; +extern TAHI_TEST_SEQ tahi_ipsec_022[]; +extern TAHI_TEST_SEQ tahi_ipsec_023[]; +extern TAHI_TEST_SEQ tahi_ipsec_024[]; +extern TAHI_TEST_SEQ tahi_ipsec_025[]; +extern TAHI_TEST_SEQ tahi_ipsec_026[]; + +extern int tahi_ipsec_006_size; +extern int tahi_ipsec_007_size; +extern int tahi_ipsec_008_size; +//extern int tahi_ipsec_008_02_size; +extern int tahi_ipsec_009_size; +extern int tahi_ipsec_009_02_size; +extern int tahi_ipsec_010_size; +extern int tahi_ipsec_011_size; +extern int tahi_ipsec_012_size; +extern int tahi_ipsec_013_size; +extern int tahi_ipsec_014_size; +extern int tahi_ipsec_015_size; +extern int tahi_ipsec_016_size; +extern int tahi_ipsec_017_size; +extern int tahi_ipsec_018_size; +extern int tahi_ipsec_019_size; +extern int tahi_ipsec_020_size; +extern int tahi_ipsec_021_size; +extern int tahi_ipsec_022_size; +extern int tahi_ipsec_023_size; +extern int tahi_ipsec_024_size; +extern int tahi_ipsec_025_size; +extern int tahi_ipsec_026_size; + +static TAHI_TEST_SUITE test_suite[30]; + +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_ipsec_006[0]; test_suite[0].test_case_size = tahi_ipsec_006_size; + test_suite[1].test_case = &tahi_ipsec_007[0]; test_suite[1].test_case_size = tahi_ipsec_007_size; + test_suite[2].test_case = &tahi_ipsec_008[0]; test_suite[2].test_case_size = tahi_ipsec_008_size; +// test_suite[3].test_case = &tahi_ipsec_008_02[0]; test_suite[3].test_case_size = tahi_ipsec_008_02_size; + test_suite[4].test_case = &tahi_ipsec_009[0]; test_suite[4].test_case_size = tahi_ipsec_009_size; + test_suite[5].test_case = &tahi_ipsec_009_02[0]; test_suite[5].test_case_size = tahi_ipsec_009_02_size; + test_suite[6].test_case = &tahi_ipsec_010[0]; test_suite[6].test_case_size = tahi_ipsec_010_size; + // test_suite[7].test_case = &tahi_ipsec_011[0]; test_suite[7].test_case_size = tahi_ipsec_011_size; + test_suite[8].test_case = &tahi_ipsec_012[0]; test_suite[8].test_case_size = tahi_ipsec_012_size; + test_suite[9].test_case = &tahi_ipsec_013[0]; test_suite[9].test_case_size = tahi_ipsec_013_size; + test_suite[10].test_case = &tahi_ipsec_014[0]; test_suite[10].test_case_size = tahi_ipsec_014_size; + test_suite[11].test_case = &tahi_ipsec_015[0]; test_suite[11].test_case_size = tahi_ipsec_015_size; + test_suite[12].test_case = &tahi_ipsec_016[0]; test_suite[12].test_case_size = tahi_ipsec_016_size; + test_suite[13].test_case = &tahi_ipsec_017[0]; test_suite[13].test_case_size = tahi_ipsec_017_size; + test_suite[14].test_case = &tahi_ipsec_018[0]; test_suite[14].test_case_size = tahi_ipsec_018_size; + test_suite[15].test_case = &tahi_ipsec_019[0]; test_suite[15].test_case_size = tahi_ipsec_019_size; +// test_suite[16].test_case = &tahi_ipsec_020[0]; test_suite[16].test_case_size = tahi_ipsec_020_size; +// test_suite[17].test_case = &tahi_ipsec_021[0]; test_suite[17].test_case_size = tahi_ipsec_021_size; + test_suite[18].test_case = &tahi_ipsec_022[0]; test_suite[18].test_case_size = tahi_ipsec_022_size; + test_suite[19].test_case = &tahi_ipsec_023[0]; test_suite[19].test_case_size = tahi_ipsec_023_size; + test_suite[20].test_case = &tahi_ipsec_024[0]; test_suite[20].test_case_size = tahi_ipsec_024_size; + test_suite[21].test_case = &tahi_ipsec_025[0]; test_suite[21].test_case_size = tahi_ipsec_025_size; + test_suite[22].test_case = &tahi_ipsec_026[0]; test_suite[22].test_case_size = tahi_ipsec_026_size; + +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_ipsec_2_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pointer, 1536*16); + pointer = pointer + 1536*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Enable IPv6 */ + status += nx_ipsec_enable(&ip_0); + + /* Enable UDP */ + status += nx_udp_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + + /* Set ipv6 version and address. */ + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x3ffe0501; + ipv6_address_2.nxd_ip_address.v6[1] = 0xffff0000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_2.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_2, 64, NX_NULL); + + /* Check fragment enable status. */ + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ +UINT status = 0; + + init_para(); + + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + netx_tahi_run_test_case(&ip_0, test_suite[0].test_case, test_suite[0].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[1].test_case, test_suite[1].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[2].test_case, test_suite[2].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[4].test_case, test_suite[4].test_case_size); + + clean_sa(); + create_sa(5, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[5].test_case, test_suite[5].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[6].test_case, test_suite[6].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[8].test_case, test_suite[8].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[9].test_case, test_suite[8].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[10].test_case, test_suite[10].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_aes_xcbc_mac, + ingress_aes_xcbc_mac, egress_aes_xcbc_mac, + NX_CRYPTO_AES_128_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &ingress_aes_xcbc, &egress_aes_xcbc, sizeof(NX_CRYPTO_AES)); + netx_tahi_run_test_case(&ip_0, test_suite[11].test_case, test_suite[11].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_null, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + 0, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + NX_NULL, NX_NULL, 0); + netx_tahi_run_test_case(&ip_0, test_suite[12].test_case, test_suite[12].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_aes_cbc, &crypto_method_aes_cbc, + ingress_aes_cbc[0], egress_aes_cbc[0], + NX_CRYPTO_AES_128_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_aes[0], &egress_aes[0], sizeof(NX_CRYPTO_AES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[13].test_case, test_suite[13].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_aes_ctr, &crypto_method_aes_ctr, + ingress_aes_ctr, egress_aes_ctr, + NX_CRYPTO_AES_128_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_aes[0], &egress_aes[0], sizeof(NX_CRYPTO_AES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[14].test_case, test_suite[14].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_null, &crypto_method_null, + ingress_3des_cbc[0], egress_3des_cbc[0], + 0, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + NX_NULL, NX_NULL, 0, + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[15].test_case, test_suite[15].test_case_size); + + +//----------------------------Tunnel Mode test-------------------------------// + + clean_sa(); + create_sa(6, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + //Setup the tunnel source and destination address on IPSEC_TUNNEL_MODE + tunnel_entry_address.nxd_ip_version = NX_IP_VERSION_V6; + tunnel_entry_address.nxd_ip_address.v6[0] = 0x3ffe0501; + tunnel_entry_address.nxd_ip_address.v6[1] = 0xffff0000; + tunnel_entry_address.nxd_ip_address.v6[2] = 0x021122ff; + tunnel_entry_address.nxd_ip_address.v6[3] = 0xfe334456; + + tunnel_exit_address.nxd_ip_version = NX_IP_VERSION_V6; + tunnel_exit_address.nxd_ip_address.v6[0] = 0x3ffe0501; + tunnel_exit_address.nxd_ip_address.v6[1] = 0xffff0001; + tunnel_exit_address.nxd_ip_address.v6[2] = 0x00000000; + tunnel_exit_address.nxd_ip_address.v6[3] = 0x00000001; + + status += _nx_ipsec_sa_tunnel_create(&egress_sa[6], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + netx_tahi_run_test_case(&ip_0, test_suite[18].test_case, test_suite[18].test_case_size); + + + tunnel_entry_address.nxd_ip_version = NX_IP_VERSION_V6; + tunnel_entry_address.nxd_ip_address.v6[0] = 0x3ffe0501; + tunnel_entry_address.nxd_ip_address.v6[1] = 0xffff0000; + tunnel_entry_address.nxd_ip_address.v6[2] = 0x021122ff; + tunnel_entry_address.nxd_ip_address.v6[3] = 0xfe334456; + + tunnel_exit_address.nxd_ip_version = NX_IP_VERSION_V6; + tunnel_exit_address.nxd_ip_address.v6[0] = 0x3ffe0501; + tunnel_exit_address.nxd_ip_address.v6[1] = 0xffff0001; + tunnel_exit_address.nxd_ip_address.v6[2] = 0x00000000; + tunnel_exit_address.nxd_ip_address.v6[3] = 0x0000000e; + + clean_sa(); + create_sa(7, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + status += _nx_ipsec_sa_tunnel_create(&egress_sa[7], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + netx_tahi_run_test_case(&ip_0, test_suite[19].test_case, test_suite[19].test_case_size); + + clean_sa(); + create_sa(8, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + create_sa(9, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[9], egress_3des_cbc[9], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[9], egress_hmac_sha1[9], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[9], &egress_3des[9], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + status += _nx_ipsec_sa_tunnel_create(&egress_sa[8], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + status += _nx_ipsec_sa_tunnel_create(&egress_sa[9], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + netx_tahi_run_test_case(&ip_0, test_suite[20].test_case, test_suite[20].test_case_size); + + clean_sa(); + create_sa(7, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + + status += _nx_ipsec_sa_tunnel_create(&egress_sa[7], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + netx_tahi_run_test_case(&ip_0, test_suite[21].test_case, test_suite[21].test_case_size); + + clean_sa(); + create_sa(7, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + status += _nx_ipsec_sa_tunnel_create(&egress_sa[7], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + netx_tahi_run_test_case(&ip_0, test_suite[22].test_case, test_suite[22].test_case_size); + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +/* Initialize parameters for IPSec. */ +static void init_para() +{ + UINT i; + + /* Setup addresses of selectors. */ + for(i = 0; i < IPSEC_MAX_END_NODE; i++) + { + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x3ffe0501; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0xffff0000; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x021122ff; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0xfe334456; + memcpy(&egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&ingress_selectors[i].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[i].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + + + ingress_selectors[i].nx_ipsec_selector_next_layer_protocol_id = NX_NULL; + egress_selectors[i].nx_ipsec_selector_next_layer_protocol_id = NX_NULL; + ingress_selectors[i].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_PROTECT; + egress_selectors[i].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_PROTECT; + } + + /*Setup destination IP address. */ + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x3ffe0501; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0001; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000001; + memcpy(&egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&ingress_selectors[0].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[0].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000002; + memcpy(&egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[1].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[1].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[2].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[2].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[3].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[3].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + /* Used by test case 8-2 */ + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_BYPASS; + egress_selectors[4].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_BYPASS; + + /* Used by test case 9-2 */ + + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_DROP; + egress_selectors[5].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_DROP; + + /* Used by test case 22 */ + memcpy(&egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[6].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[6].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + /* Used by test case 23 */ + memcpy(&egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0002; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + memcpy(&egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0xFFFFFFFF; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0xFFFFFFFF; + memcpy(&ingress_selectors[7].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[7].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end, sizeof(NXD_ADDRESS)); + + /* Used by test case 24-1 */ + memcpy(&egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0002; + memcpy(&egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[8].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[8].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + /* Used by test case 24-2 */ + memcpy(&egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000002; + memcpy(&egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[9].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[9].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + + /* Setup SPI. */ + ingress_spi[0] = 0x1000; + egress_spi[0] = 0x2000; + ingress_spi[1] = 0x3000; + egress_spi[1] = 0x4000; + ingress_spi[2] = 0x1000; + egress_spi[2] = 0x2000; + ingress_spi[3] = 0x1000; + egress_spi[3] = 0x3000; + ingress_spi[4] = 0x1000; + egress_spi[4] = 0x2000; + ingress_spi[5] = 0x1000; + egress_spi[5] = 0x2000; + ingress_spi[6] = 0x1000; + egress_spi[6] = 0x2000; + ingress_spi[7] = 0x1000; + egress_spi[7] = 0x2000; + ingress_spi[8] = 0x1000; + egress_spi[8] = 0x2000; + ingress_spi[9] = 0x3000; + egress_spi[9] = 0x4000; + + /* Setup encryption key. */ + memcpy(&ingress_3des_cbc[0], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[0], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[0], "ipv6readylogo3descbcout1", 24); + memcpy(&egress_hmac_sha1[0], "ipv6readylogsha1out1", 20); + + memcpy(&ingress_3des_cbc[1], "ipv6readylogo3descbcin02", 24); + memcpy(&ingress_hmac_sha1[1], "ipv6readylogsha1in02", 20); + memcpy(&egress_3des_cbc[1], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[1], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_3des_cbc[2], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[2], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[2], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[2], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_3des_cbc[3], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[3], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[3], "ipv6readylogo3descbcout3", 24); + memcpy(&egress_hmac_sha1[3], "ipv6readylogsha1out3", 20); + + memcpy(&ingress_aes_cbc[0], "ipv6readaescin01", 16); + memcpy(&egress_aes_cbc[0], "ipv6readaescout1", 16); + + memcpy(&ingress_aes_ctr, "ipv6readylogaescin01", 20); + memcpy(&egress_aes_ctr, "ipv6readylogaescout1", 20); + + memcpy(&ingress_3des_cbc[9], "ipv6readylogo3descbcin02", 24); + memcpy(&ingress_hmac_sha1[9], "ipv6readylogsha1in02", 20); + memcpy(&egress_3des_cbc[9], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[9], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_aes_xcbc_mac, "ipv6readaesxin01", 16); + memcpy(&egress_aes_xcbc_mac, "ipv6readaesxout1", 16); + + /* Setup selectors. */ + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 128; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 128; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + egress_selectors[2].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 129; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 129; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 128; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 128; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + egress_selectors[3].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 1; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 1; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 4; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 4; + +} + + +/* Clean SA for IPSec. */ +static UINT clean_sa() +{ + + UINT status = 0, i; + + for(i = 0; i < IPSEC_MAX_END_NODE; i++) + { + if(ingress_sa[i].nx_ipsec_sa_id) + status = nx_ipsec_sa_delete(&ingress_sa[i]); + if(egress_sa[i].nx_ipsec_sa_id) + status += nx_ipsec_sa_delete(&egress_sa[i]); + + } + + return status; +} + +static VOID sa_timeout_process(NX_IP *ip_ptr, NX_IPSEC_SA *sa) +{ + nx_ipsec_sa_update(sa, sa->nx_ipsec_sa_spi, NX_IPSEC_SA_MATURE, IPSEC_SA_LIFETIME, (IPSEC_SA_LIFETIME - 3), + sa->nx_ipsec_sa_encrypt_key_string, sa->nx_ipsec_sa_encryption_method -> nx_crypto_key_size_in_bits, + sa->nx_ipsec_sa_integrity_key_string, sa->nx_ipsec_sa_integrity_method -> nx_crypto_key_size_in_bits); + return; +} + +/* Create SA for IPSec. */ +UINT create_sa(UINT index, UCHAR sa_mode, + NX_CRYPTO_METHOD* sa_encryption_method_ingress, NX_CRYPTO_METHOD* sa_encryption_method_egress, + UCHAR *sa_encryption_key_ingress, UCHAR *sa_encryption_key_egress, + UINT sa_encryption_key_len_in_bits, + NX_CRYPTO_METHOD* sa_integrity_method, + UCHAR *sa_integrity_key_ingress, UCHAR *sa_integrity_key_egress, + UINT sa_integrity_key_len_in_bits, + VOID *crypto_metadata_area_ingress, VOID *crypto_metadata_area_egress, ULONG crypto_metadata_size, + VOID *authentication_metadata_area_ingress, VOID *authentication_metadata_area_egress, ULONG authentication_metadata_size) +{ + + UINT status; + + status = _nx_ipsec_sa_create(&ip_0, &ingress_sa[index], sa_mode, NX_PROTOCOL_NEXT_HEADER_ENCAP_SECURITY, + NX_IPSEC_MANUAL_KEY, NX_IPSEC_SA_INGRESS, &ingress_selectors[index], IPSEC_SA_LIFETIME, + (IPSEC_SA_LIFETIME) - 3, sa_timeout_process, 0, ingress_spi[index], + sa_encryption_method_ingress, crypto_metadata_area_ingress, crypto_metadata_size, + sa_encryption_key_ingress, sa_encryption_key_len_in_bits, + sa_integrity_method, authentication_metadata_area_ingress, authentication_metadata_size, + sa_integrity_key_ingress, sa_integrity_key_len_in_bits); + + if (status) + error_counter++; + + status += _nx_ipsec_sa_create(&ip_0, &egress_sa[index], sa_mode, NX_PROTOCOL_NEXT_HEADER_ENCAP_SECURITY, + NX_IPSEC_MANUAL_KEY, NX_IPSEC_SA_EGRESS, &egress_selectors[index], IPSEC_SA_LIFETIME, + (IPSEC_SA_LIFETIME) - 3, sa_timeout_process, 0, egress_spi[index], + sa_encryption_method_egress, crypto_metadata_area_egress, crypto_metadata_size, + sa_encryption_key_egress, sa_encryption_key_len_in_bits, + sa_integrity_method, authentication_metadata_area_egress, authentication_metadata_size, + sa_integrity_key_egress, sa_integrity_key_len_in_bits); + if (status) + error_counter++; + + return status; +} + +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_ipsec_udp.c b/test/regression/tahi_test/netx_tahi_test_ipsec_udp.c new file mode 100644 index 00000000..674d27c8 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_ipsec_udp.c @@ -0,0 +1,671 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" + +#if defined FEATURE_NX_IPV6 && defined NX_IPSEC_ENABLE && defined NX_TAHI_ENABLE + +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_ipsec.h" +#include "nx_crypto.h" +#include "nx_crypto_3des.h" +#include "nx_crypto_aes.h" +#include "nx_crypto_des.h" +#include "nx_crypto_dh.h" +#include "nx_crypto_hmac_md5.h" +#include "nx_crypto_hmac_sha1.h" +#include "nx_crypto_md5.h" +#include "nx_crypto_null.h" +#include "nx_crypto_sha1.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define IPSEC_MAX_END_NODE 10 +#define IPSEC_SA_LIFETIME 5000 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_UDP_SOCKET socket_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; + +/* Define IPSEC related data. */ + +static NX_IPSEC_SELECTOR ingress_selectors[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SELECTOR egress_selectors[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SA ingress_sa[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SA egress_sa[IPSEC_MAX_END_NODE]; +static UCHAR ingress_hmac_sha1[IPSEC_MAX_END_NODE][20]; +static UCHAR ingress_3des_cbc[IPSEC_MAX_END_NODE][24]; +static UCHAR ingress_aes_cbc[IPSEC_MAX_END_NODE][32]; +static UCHAR egress_hmac_sha1[IPSEC_MAX_END_NODE][20]; +static UCHAR egress_3des_cbc[IPSEC_MAX_END_NODE][24]; +static UCHAR egress_aes_cbc[IPSEC_MAX_END_NODE][32]; +static UCHAR egress_aes_xcbc_mac[32]; +static UCHAR ingress_aes_xcbc_mac[32]; +static ULONG egress_spi[IPSEC_MAX_END_NODE]; +static ULONG ingress_spi[IPSEC_MAX_END_NODE]; +static UCHAR ingress_aes_ctr[32]; +static UCHAR egress_aes_ctr[32]; + +/* Define the Crypto Method */ + +static NX_CRYPTO_3DES egress_3des[IPSEC_MAX_END_NODE]; +static NX_CRYPTO_3DES ingress_3des[IPSEC_MAX_END_NODE]; +static NX_SHA1_HMAC metadata_egress_hmac_sha1[IPSEC_MAX_END_NODE]; +static NX_SHA1_HMAC metadata_ingress_hmac_sha1[IPSEC_MAX_END_NODE]; + + +/* 3DES, encrypt */ +static NX_CRYPTO_METHOD crypto_method_t_des = +{ + NX_CRYPTO_ENCRYPTION_3DES_CBC, /* 3DES-CBC crypto algorithm */ + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, /* Key size in bits */ + NX_CRYPTO_3DES_IV_LEN_IN_BITS, /* IV size in bits */ + 0, /* ICV size in bits, not used */ + (NX_CRYPTO_3DES_BLOCK_SIZE_IN_BITS>>3), /* Block size in bytes */ + sizeof(NX_CRYPTO_3DES), /* 768 */ /* Metadata size in bytes */ + _nx_ipsec_crypto_method_3des_init, /* 3DES-CBC initialization routine. */ + NX_NULL, /* 3DES-CBC cleanup routine, not used */ + _nx_ipsec_crypto_method_3des_operation /* 3DES-CBC operation */ +}; + +/* HMAC SHA1 */ +static NX_CRYPTO_METHOD crypto_method_hmac_sha1 = +{ + NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_96, /* HMAC SHA1 algorithm */ + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, /* Key size in bits */ + 0, /* IV size in bits, not used */ + NX_CRYPTO_AUTHENTICATION_ICV_TRUNC_BITS, /* Transmitted ICV size in bits */ + 0, /* Block size in bytes, not used */ + 0, /* Metadata size in bytes */ + NX_NULL, /* Initialization routine, not used */ + NX_NULL, /* Cleanup routine, not used */ + _nx_ipsec_crypto_method_hmac_sha1_operation /* HMAC SHA1 operation */ +}; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void init_para(); +static UINT clean_sa(); +static VOID sa_timeout_process(NX_IP *ip_ptr, NX_IPSEC_SA *sa); + +static UINT create_sa(UINT index, UCHAR sa_mode, + NX_CRYPTO_METHOD* sa_encryption_method_ingress, NX_CRYPTO_METHOD* sa_encryption_method_egress, + UCHAR *sa_encryption_key_ingress, UCHAR *sa_encryption_key_egress, + UINT sa_encryption_key_len_in_bits, + NX_CRYPTO_METHOD* sa_integrity_method, + UCHAR *sa_integrity_key_ingress, UCHAR *sa_integrity_key_egress, + UINT sa_integrity_key_len_in_bits, + VOID *crypto_metadata_area_ingress, VOID *crypto_metadata_area_egress, ULONG crypto_metadata_size, + VOID *authentication_metadata_area_ingress, VOID *authentication_metadata_area_egress, ULONG authentication_metadata_size); +extern UINT _nxd_udp_socket_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr, NXD_ADDRESS *ip_address, UINT port); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_ipsec_udp_001[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_002[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_004[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_005[]; + +extern int tahi_ipsec_udp_001_size; +extern int tahi_ipsec_udp_002_size; +extern int tahi_ipsec_udp_004_size; +extern int tahi_ipsec_udp_005_size; + +static TAHI_TEST_SUITE test_suite[10]; + +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_ipsec_udp_001[0]; test_suite[0].test_case_size = tahi_ipsec_udp_001_size; + test_suite[1].test_case = &tahi_ipsec_udp_002[0]; test_suite[1].test_case_size = tahi_ipsec_udp_002_size; + /* + test_suite[2].test_case = &tahi_ipsec_udp_003[0]; test_suite[2].test_case_size = tahi_ipsec_udp_003_size; + */ + test_suite[3].test_case = &tahi_ipsec_udp_004[0]; test_suite[3].test_case_size = tahi_ipsec_udp_004_size; + test_suite[4].test_case = &tahi_ipsec_udp_005[0]; test_suite[4].test_case_size = tahi_ipsec_udp_005_size; +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_ipsec_udp_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create udp process thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1640, pointer, 1640*16); + pointer = pointer + 1640*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Enable IPv6 */ + status += nx_ipsec_enable(&ip_0); + + /* Enable UDP */ + status += nx_udp_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + + /* Set ipv6 version and address. */ + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x3ffe0501; + ipv6_address_2.nxd_ip_address.v6[1] = 0xffff0000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_2.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_2, 64, NX_NULL); + + /* Check fragment enable status. */ + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ + + init_para(); + + netx_tahi_run_test_case(&ip_0, test_suite[0].test_case, test_suite[0].test_case_size); + + create_sa(0,NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des,&crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + create_sa(1,NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des,&crypto_method_t_des, + ingress_3des_cbc[1], egress_3des_cbc[1], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[1], egress_hmac_sha1[1], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[1], &egress_3des[1], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[1], &metadata_egress_hmac_sha1[1], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[1].test_case, test_suite[1].test_case_size); + + clean_sa(); + create_sa(0,NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des,&crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[3].test_case, test_suite[3].test_case_size); + +#if 0 + clean_sa(); + create_sa(0,NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des,&crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[4].test_case, test_suite[4].test_case_size); +#endif + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +/* Initialize parameters for IPSec. */ +static void init_para() +{ + UINT i; + + /* Setup addresses of selectors. */ + for(i = 0; i < IPSEC_MAX_END_NODE; i++) + { + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x3ffe0501; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0xffff0000; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x021122ff; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0xfe334456; + memcpy(&egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&ingress_selectors[i].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[i].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + + ingress_selectors[i].nx_ipsec_selector_next_layer_protocol_id = NX_NULL; + egress_selectors[i].nx_ipsec_selector_next_layer_protocol_id = NX_NULL; + ingress_selectors[i].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_PROTECT; + egress_selectors[i].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_PROTECT; + } + + /*Setup destination IP address. */ + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x3ffe0501; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0001; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000001; + memcpy(&egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&ingress_selectors[0].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[0].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000002; + memcpy(&egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[1].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[1].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[2].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[2].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[3].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[3].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + /* Used by test case 8-2 */ + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_BYPASS; + egress_selectors[4].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_BYPASS; + + /* Used by test case 9-2 */ + + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_DROP; + egress_selectors[5].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_DROP; + + /* Used by test case 22 */ + memcpy(&egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[6].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[6].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + /* Used by test case 23 */ + memcpy(&egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0002; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + memcpy(&egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0xFFFFFFFF; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0xFFFFFFFF; + memcpy(&ingress_selectors[7].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[7].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end, sizeof(NXD_ADDRESS)); + + /* Used by test case 24-1 */ + memcpy(&egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0002; + memcpy(&egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[8].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[8].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + /* Used by test case 24-2 */ + memcpy(&egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000002; + memcpy(&egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[9].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[9].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + + + /* Setup SPI. */ + ingress_spi[0] = 0x1000; + egress_spi[0] = 0x2000; + ingress_spi[1] = 0x3000; + egress_spi[1] = 0x4000; + ingress_spi[2] = 0x1000; + egress_spi[2] = 0x2000; + ingress_spi[3] = 0x1000; + egress_spi[3] = 0x3000; + ingress_spi[4] = 0x1000; + egress_spi[4] = 0x2000; + ingress_spi[5] = 0x1000; + egress_spi[5] = 0x2000; + ingress_spi[6] = 0x1000; + egress_spi[6] = 0x2000; + ingress_spi[7] = 0x1000; + egress_spi[7] = 0x2000; + ingress_spi[8] = 0x1000; + egress_spi[8] = 0x2000; + ingress_spi[9] = 0x3000; + egress_spi[9] = 0x4000; + + /* Setup encryption key. */ + memcpy(&ingress_3des_cbc[0], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[0], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[0], "ipv6readylogo3descbcout1", 24); + memcpy(&egress_hmac_sha1[0], "ipv6readylogsha1out1", 20); + + memcpy(&ingress_3des_cbc[1], "ipv6readylogo3descbcin02", 24); + memcpy(&ingress_hmac_sha1[1], "ipv6readylogsha1in02", 20); + memcpy(&egress_3des_cbc[1], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[1], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_3des_cbc[2], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[2], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[2], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[2], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_3des_cbc[3], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[3], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[3], "ipv6readylogo3descbcout3", 24); + memcpy(&egress_hmac_sha1[3], "ipv6readylogsha1out3", 20); + + + memcpy(&ingress_aes_cbc[0], "ipv6readaescin01", 16); + memcpy(&egress_aes_cbc[0], "ipv6readaescout1", 16); + + memcpy(&ingress_aes_ctr, "ipv6readylogaescin01", 20); + memcpy(&egress_aes_ctr, "ipv6readylogaescout1", 20); + + memcpy(&ingress_3des_cbc[9], "ipv6readylogo3descbcin02", 24); + memcpy(&ingress_hmac_sha1[9], "ipv6readylogsha1in02", 20); + memcpy(&egress_3des_cbc[9], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[9], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_aes_xcbc_mac, "ipv6readaesxin01", 16); + memcpy(&egress_aes_xcbc_mac, "ipv6readaesxout1", 16); + + /* Setup selectors. */ + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 128; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 128; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + egress_selectors[2].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 129; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 129; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 128; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 128; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + egress_selectors[3].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 1; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 1; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 4; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 4; + +} + + +/* Clean SA for IPSec. */ +static UINT clean_sa() +{ + + UINT status = 0, i; + + for(i = 0; i < IPSEC_MAX_END_NODE; i++) + { + if(ingress_sa[i].nx_ipsec_sa_id) + status = nx_ipsec_sa_delete(&ingress_sa[i]); + if(egress_sa[i].nx_ipsec_sa_id) + status += nx_ipsec_sa_delete(&egress_sa[i]); + + } + + return status; +} + +static VOID sa_timeout_process(NX_IP *ip_ptr, NX_IPSEC_SA *sa) +{ + + nx_ipsec_sa_update(sa, sa->nx_ipsec_sa_spi, NX_IPSEC_SA_MATURE, IPSEC_SA_LIFETIME, (IPSEC_SA_LIFETIME - 3), + sa->nx_ipsec_sa_encrypt_key_string, sa->nx_ipsec_sa_encryption_method -> nx_crypto_key_size_in_bits, + sa->nx_ipsec_sa_integrity_key_string, sa->nx_ipsec_sa_integrity_method -> nx_crypto_key_size_in_bits); + + return; +} + +/* Create SA for IPSec. */ +UINT create_sa(UINT index, UCHAR sa_mode, + NX_CRYPTO_METHOD* sa_encryption_method_ingress, NX_CRYPTO_METHOD* sa_encryption_method_egress, + UCHAR *sa_encryption_key_ingress, UCHAR *sa_encryption_key_egress, + UINT sa_encryption_key_len_in_bits, + NX_CRYPTO_METHOD* sa_integrity_method, + UCHAR *sa_integrity_key_ingress, UCHAR *sa_integrity_key_egress, + UINT sa_integrity_key_len_in_bits, + VOID *crypto_metadata_area_ingress, VOID *crypto_metadata_area_egress, ULONG crypto_metadata_size, + VOID *authentication_metadata_area_ingress, VOID *authentication_metadata_area_egress, ULONG authentication_metadata_size) +{ + + UINT status; + + status = _nx_ipsec_sa_create(&ip_0, &ingress_sa[index], sa_mode, NX_PROTOCOL_NEXT_HEADER_ENCAP_SECURITY, + NX_IPSEC_MANUAL_KEY, NX_IPSEC_SA_INGRESS, &ingress_selectors[index], IPSEC_SA_LIFETIME, + (IPSEC_SA_LIFETIME) - 3, sa_timeout_process, 0, ingress_spi[index], + sa_encryption_method_ingress, crypto_metadata_area_ingress, crypto_metadata_size, + sa_encryption_key_ingress, sa_encryption_key_len_in_bits, + sa_integrity_method, authentication_metadata_area_ingress, authentication_metadata_size, + sa_integrity_key_ingress, sa_integrity_key_len_in_bits); + + if (status) + error_counter++; + + status += _nx_ipsec_sa_create(&ip_0, &egress_sa[index], sa_mode, NX_PROTOCOL_NEXT_HEADER_ENCAP_SECURITY, + NX_IPSEC_MANUAL_KEY, NX_IPSEC_SA_EGRESS, &egress_selectors[index], IPSEC_SA_LIFETIME, + (IPSEC_SA_LIFETIME) - 3, sa_timeout_process, 0, egress_spi[index], + sa_encryption_method_egress, crypto_metadata_area_egress, crypto_metadata_size, + sa_encryption_key_egress, sa_encryption_key_len_in_bits, + sa_integrity_method, authentication_metadata_area_egress, authentication_metadata_size, + sa_integrity_key_egress, sa_integrity_key_len_in_bits); + if (status) + error_counter++; + + return status; +} + + +/* Process udp packet. */ +static void thread_1_entry(ULONG thread_input) +{ + + NX_PACKET *tx_packet, *rx_packet; + UINT status; + NX_IPV6_HEADER *ipv6_header; + NXD_ADDRESS ipv6_address; /* Destination Addresses. */ + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + if (status) + { + error_counter++; + return; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 7, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + while(1) + { + status = nx_udp_socket_receive(&socket_0, &rx_packet, TX_WAIT_FOREVER); + if (status == NX_SUCCESS) + { + status = nx_packet_allocate(&pool_0, &tx_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + break; + } + + status = nx_packet_data_append(tx_packet, rx_packet -> nx_packet_prepend_ptr, rx_packet -> nx_packet_length, &pool_0, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + nx_packet_release(rx_packet); + break; + } + + ipv6_header = (NX_IPV6_HEADER*)(rx_packet -> nx_packet_ip_header); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + memcpy(ipv6_address.nxd_ip_address.v6, ipv6_header -> nx_ip_header_source_ip, (sizeof(ULONG) << 2)); + + status = _nxd_udp_socket_send(&socket_0, tx_packet, &ipv6_address, 100 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + nx_packet_release(tx_packet); + } + + nx_packet_release(rx_packet); + } + } +} +#endif diff --git a/test/regression/tahi_test/netx_tahi_test_ipsec_udp_2.c b/test/regression/tahi_test/netx_tahi_test_ipsec_udp_2.c new file mode 100644 index 00000000..5881dbe0 --- /dev/null +++ b/test/regression/tahi_test/netx_tahi_test_ipsec_udp_2.c @@ -0,0 +1,968 @@ +#include "tx_api.h" +#include "nx_api.h" +#include "netx_tahi.h" + +#if defined FEATURE_NX_IPV6 && defined NX_IPSEC_ENABLE && defined NX_TAHI_ENABLE + +#include "nx_tcp.h" +#include "nx_ip.h" +#include "nx_ipv6.h" +#include "nx_icmpv6.h" +#include "nx_ipsec.h" +#include "nx_crypto.h" +#include "nx_crypto_3des.h" +#include "nx_crypto_aes.h" +#include "nx_crypto_des.h" +#include "nx_crypto_dh.h" +#include "nx_crypto_hmac_md5.h" +#include "nx_crypto_hmac_sha1.h" +#include "nx_crypto_md5.h" +#include "nx_crypto_null.h" +#include "nx_crypto_sha1.h" + +#define DEMO_STACK_SIZE 2048 +#define TEST_INTERFACE 0 +#define IPSEC_MAX_END_NODE 10 +#define IPSEC_SA_LIFETIME 5000 + +/* Define the ThreadX and NetX object control blocks... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; + +static NX_PACKET_POOL pool_0; +static NX_IP ip_0; +static NX_UDP_SOCKET socket_0; + +/* Define the counters used in the demo application... */ + +static ULONG error_counter; +static NXD_ADDRESS ipv6_address_1; +static NXD_ADDRESS ipv6_address_2; + +static NXD_ADDRESS tunnel_entry_address; +static NXD_ADDRESS tunnel_exit_address; + +/* Define IPSEC related data. */ + +static NX_IPSEC_SELECTOR ingress_selectors[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SELECTOR egress_selectors[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SA ingress_sa[IPSEC_MAX_END_NODE]; +static NX_IPSEC_SA egress_sa[IPSEC_MAX_END_NODE]; +static UCHAR ingress_hmac_sha1[IPSEC_MAX_END_NODE][20]; +static UCHAR ingress_3des_cbc[IPSEC_MAX_END_NODE][24]; +static UCHAR ingress_aes_cbc[IPSEC_MAX_END_NODE][32]; +static UCHAR egress_hmac_sha1[IPSEC_MAX_END_NODE][20]; +static UCHAR egress_3des_cbc[IPSEC_MAX_END_NODE][24]; +static UCHAR egress_aes_cbc[IPSEC_MAX_END_NODE][32]; +static UCHAR egress_aes_xcbc_mac[32]; +static UCHAR ingress_aes_xcbc_mac[32]; +static ULONG egress_spi[IPSEC_MAX_END_NODE]; +static ULONG ingress_spi[IPSEC_MAX_END_NODE]; +static UCHAR ingress_aes_ctr[32]; +static UCHAR egress_aes_ctr[32]; + +/* Define the Crypto Method */ + +static NX_CRYPTO_3DES egress_3des[IPSEC_MAX_END_NODE]; +static NX_CRYPTO_3DES ingress_3des[IPSEC_MAX_END_NODE]; + +static NX_CRYPTO_AES egress_aes[IPSEC_MAX_END_NODE]; +static NX_CRYPTO_AES ingress_aes[IPSEC_MAX_END_NODE]; +static NX_CRYPTO_AES egress_aes_xcbc; +static NX_CRYPTO_AES ingress_aes_xcbc; + +static NX_SHA1_HMAC metadata_egress_hmac_sha1[IPSEC_MAX_END_NODE]; +static NX_SHA1_HMAC metadata_ingress_hmac_sha1[IPSEC_MAX_END_NODE]; + +/* NULL encrypt */ +static NX_CRYPTO_METHOD crypto_method_null = +{ + NX_CRYPTO_ENCRYPTION_NULL, /* Name of the crypto algorithm */ + 0, /* Key size in bits, not used */ + 0, /* IV size in bits, not used */ + 0, /* ICV size in bits, not used */ + 4, /* Block size in bytes */ + 0, /* Metadata size in bytes */ + NX_NULL, /* Initialization routine, not used */ + NX_NULL, /* Cleanup routine, not used */ + _nx_ipsec_crypto_method_null_operation /* NULL operation */ +}; + +/* 3DES, encrypt */ +static NX_CRYPTO_METHOD crypto_method_t_des = +{ + NX_CRYPTO_ENCRYPTION_3DES_CBC, /* 3DES-CBC crypto algorithm */ + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, /* Key size in bits */ + NX_CRYPTO_3DES_IV_LEN_IN_BITS, /* IV size in bits */ + 0, /* ICV size in bits, not used */ + (NX_CRYPTO_3DES_BLOCK_SIZE_IN_BITS>>3), /* Block size in bytes */ + sizeof(NX_CRYPTO_3DES), /* 768 */ /* Metadata size in bytes */ + _nx_ipsec_crypto_method_3des_init, /* 3DES-CBC initialization routine. */ + NX_NULL, /* 3DES-CBC cleanup routine, not used */ + _nx_ipsec_crypto_method_3des_operation /* 3DES-CBC operation */ +}; + +/* AES-CBC. */ +static NX_CRYPTO_METHOD crypto_method_aes_cbc = +{ + NX_CRYPTO_ENCRYPTION_AES_CBC, /* AES crypto algorithm */ + NX_CRYPTO_AES_128_KEY_LEN_IN_BITS, /* Key size in bits */ + NX_CRYPTO_AES_IV_LEN_IN_BITS, /* IV size in bits */ + 0, /* ICV size in bits, not used. */ + (NX_CRYPTO_AES_BLOCK_SIZE_IN_BITS >> 3), /* Block size in bytes. */ + sizeof(NX_CRYPTO_AES), /* 262 */ /* Metadata size in bytes */ + _nx_ipsec_crypto_method_aes_init, /* AES-CBC initialization routine. */ + NX_NULL, /* AES-CBC cleanup routine, not used. */ + _nx_ipsec_crypto_method_aes_operation /* AES-CBC operation */ + +}; + +/* AES-CTR. */ +static NX_CRYPTO_METHOD crypto_method_aes_ctr = +{ + NX_CRYPTO_ENCRYPTION_AES_CTR, /* AES crypto algorithm */ + NX_CRYPTO_AES_128_KEY_LEN_IN_BITS, /* Key size in bits */ + NX_CRYPTO_AES_CTR_IV_LEN_IN_BITS, /* IV size in bits */ + 0, /* ICV size in bits, not used. */ + (NX_CRYPTO_AES_BLOCK_SIZE_IN_BITS >> 3), /* Block size in bytes. */ + sizeof(NX_CRYPTO_AES), /* 262 */ /* Metadata size in bytes */ + _nx_ipsec_crypto_method_aes_init, /* AES-CBC initialization routine. */ + NX_NULL, /* AES-CBC cleanup routine, not used. */ + _nx_ipsec_crypto_method_aes_operation /* AES-CBC operation */ +}; + +/* HMAC SHA1 */ +static NX_CRYPTO_METHOD crypto_method_hmac_sha1 = +{ + NX_CRYPTO_AUTHENTICATION_HMAC_SHA1_96, /* HMAC SHA1 algorithm */ + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, /* Key size in bits */ + 0, /* IV size in bits, not used */ + NX_CRYPTO_AUTHENTICATION_ICV_TRUNC_BITS, /* Transmitted ICV size in bits */ + 0, /* Block size in bytes, not used */ + 0, /* Metadata size in bytes */ + NX_NULL, /* Initialization routine, not used */ + NX_NULL, /* Cleanup routine, not used */ + _nx_ipsec_crypto_method_hmac_sha1_operation /* HMAC SHA1 operation */ +}; + +/* AES_XCBC_96 */ +static NX_CRYPTO_METHOD crypto_method_aes_xcbc_mac = +{ + NX_CRYPTO_AUTHENTICATION_AES_XCBC_MAC_96, /* AES_XCBC_MAC algorithm */ + NX_CRYPTO_AES_XCBC_MAC_KEY_LEN_IN_BITS, /* Key size in bits */ + 0, /* IV size in bits, not used */ + NX_CRYPTO_AUTHENTICATION_ICV_TRUNC_BITS, /* Transmitted ICV size in bits */ + 0, /* Block size in bytes, not used */ + sizeof(NX_CRYPTO_AES), /* 262 */ /* Metadata size in bytes */ + NX_NULL, /* Initialization routine, not used */ + NX_NULL, /* Cleanup routine, not used */ + _nx_ipsec_crypto_method_aes_xcbc_mac_operation /* AES_XCBC_MAC operation */ +}; + +/* Define thread prototypes. */ +static void thread_0_entry(ULONG thread_input); +static void thread_1_entry(ULONG thread_input); +extern void test_control_return(UINT status); +extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req); +extern UINT (*packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr); +static void init_para(); +static UINT clean_sa(); +static VOID sa_timeout_process(NX_IP *ip_ptr, NX_IPSEC_SA *sa); + +static UINT create_sa(UINT index, UCHAR sa_mode, + NX_CRYPTO_METHOD* sa_encryption_method_ingress, NX_CRYPTO_METHOD* sa_encryption_method_egress, + UCHAR *sa_encryption_key_ingress, UCHAR *sa_encryption_key_egress, + UINT sa_encryption_key_len_in_bits, + NX_CRYPTO_METHOD* sa_integrity_method, + UCHAR *sa_integrity_key_ingress, UCHAR *sa_integrity_key_egress, + UINT sa_integrity_key_len_in_bits, + VOID *crypto_metadata_area_ingress, VOID *crypto_metadata_area_egress, ULONG crypto_metadata_size, + VOID *authentication_metadata_area_ingress, VOID *authentication_metadata_area_egress, ULONG authentication_metadata_size); +extern UINT _nxd_udp_socket_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr, NXD_ADDRESS *ip_address, UINT port); + +/* Define the test threads. */ +extern TAHI_TEST_SEQ tahi_ipsec_udp_006[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_007[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_008[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_009[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_009_02[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_010[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_011[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_012[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_013[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_014[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_015[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_016[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_017[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_018[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_019[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_020[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_021[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_022[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_023[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_024[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_025[]; +extern TAHI_TEST_SEQ tahi_ipsec_udp_026[]; + +extern int tahi_ipsec_udp_006_size; +extern int tahi_ipsec_udp_007_size; +extern int tahi_ipsec_udp_008_size; +/* +extern int tahi_ipsec_udp_008_02_size; +*/ +extern int tahi_ipsec_udp_009_size; +extern int tahi_ipsec_udp_009_02_size; +extern int tahi_ipsec_udp_010_size; +extern int tahi_ipsec_udp_011_size; +extern int tahi_ipsec_udp_012_size; +extern int tahi_ipsec_udp_013_size; +extern int tahi_ipsec_udp_014_size; +extern int tahi_ipsec_udp_015_size; +extern int tahi_ipsec_udp_016_size; +extern int tahi_ipsec_udp_017_size; +extern int tahi_ipsec_udp_018_size; +extern int tahi_ipsec_udp_019_size; +extern int tahi_ipsec_udp_020_size; +extern int tahi_ipsec_udp_021_size; +extern int tahi_ipsec_udp_022_size; +extern int tahi_ipsec_udp_023_size; +extern int tahi_ipsec_udp_024_size; +extern int tahi_ipsec_udp_025_size; +extern int tahi_ipsec_udp_026_size; + +static TAHI_TEST_SUITE test_suite[30]; + +static void build_test_suite(void) +{ + + test_suite[0].test_case = &tahi_ipsec_udp_006[0]; test_suite[0].test_case_size = tahi_ipsec_udp_006_size; + test_suite[1].test_case = &tahi_ipsec_udp_007[0]; test_suite[1].test_case_size = tahi_ipsec_udp_007_size; + test_suite[2].test_case = &tahi_ipsec_udp_008[0]; test_suite[2].test_case_size = tahi_ipsec_udp_008_size; + // test_suite[3].test_case = &tahi_ipsec_udp_008_02[0]; test_suite[3].test_case_size = tahi_ipsec_udp_008_02_size; + test_suite[4].test_case = &tahi_ipsec_udp_009[0]; test_suite[4].test_case_size = tahi_ipsec_udp_009_size; + test_suite[5].test_case = &tahi_ipsec_udp_009_02[0]; test_suite[5].test_case_size = tahi_ipsec_udp_009_02_size; + test_suite[6].test_case = &tahi_ipsec_udp_010[0]; test_suite[6].test_case_size = tahi_ipsec_udp_010_size; + test_suite[7].test_case = &tahi_ipsec_udp_011[0]; test_suite[7].test_case_size = tahi_ipsec_udp_011_size; + test_suite[8].test_case = &tahi_ipsec_udp_012[0]; test_suite[8].test_case_size = tahi_ipsec_udp_012_size; + test_suite[9].test_case = &tahi_ipsec_udp_013[0]; test_suite[9].test_case_size = tahi_ipsec_udp_013_size; + test_suite[10].test_case = &tahi_ipsec_udp_014[0]; test_suite[10].test_case_size = tahi_ipsec_udp_014_size; + test_suite[11].test_case = &tahi_ipsec_udp_015[0]; test_suite[11].test_case_size = tahi_ipsec_udp_015_size; + test_suite[12].test_case = &tahi_ipsec_udp_016[0]; test_suite[12].test_case_size = tahi_ipsec_udp_016_size; + test_suite[13].test_case = &tahi_ipsec_udp_017[0]; test_suite[13].test_case_size = tahi_ipsec_udp_017_size; + test_suite[14].test_case = &tahi_ipsec_udp_018[0]; test_suite[14].test_case_size = tahi_ipsec_udp_018_size; + test_suite[15].test_case = &tahi_ipsec_udp_019[0]; test_suite[15].test_case_size = tahi_ipsec_udp_019_size; + // test_suite[16].test_case = &tahi_ipsec_udp_020[0]; test_suite[16].test_case_size = tahi_ipsec_udp_020_size; + // test_suite[17].test_case = &tahi_ipsec_udp_021[0]; test_suite[17].test_case_size = tahi_ipsec_udp_021_size; + test_suite[18].test_case = &tahi_ipsec_udp_022[0]; test_suite[18].test_case_size = tahi_ipsec_udp_022_size; + test_suite[19].test_case = &tahi_ipsec_udp_023[0]; test_suite[19].test_case_size = tahi_ipsec_udp_023_size; + test_suite[20].test_case = &tahi_ipsec_udp_024[0]; test_suite[20].test_case_size = tahi_ipsec_udp_024_size; + test_suite[21].test_case = &tahi_ipsec_udp_025[0]; test_suite[21].test_case_size = tahi_ipsec_udp_025_size; + test_suite[22].test_case = &tahi_ipsec_udp_026[0]; test_suite[22].test_case_size = tahi_ipsec_udp_026_size; + +} + + +/* Define what the initial system looks like. */ + +#ifdef CTEST +VOID test_application_define(void *first_unused_memory) +#else +void netx_tahi_test_ipsec_udp_2_define(void *first_unused_memory) +#endif +{ + CHAR *pointer; + UINT status; + + /* Setup the working pointer. */ + pointer = (CHAR *) first_unused_memory; + + error_counter = 0; + memset(&test_suite, 0, sizeof(test_suite)); + + build_test_suite(); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Create udp process thread. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + pointer = pointer + DEMO_STACK_SIZE; + + /* Initialize the NetX system. */ + nx_system_initialize(); + + /* Create a packet pool. */ + status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1600, pointer, 1600*16); + pointer = pointer + 1600*16; + + if(status) + error_counter++; + + /* Create an IP instance. */ + status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1,2,3,4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500, + pointer, 2048, 1); + pointer = pointer + 2048; + + /* Enable ICMP for IP Instance 0 and 1. */ + status = nxd_icmp_enable(&ip_0); + + /* Check ARP enable status. */ + if(status) + error_counter++; + + /* Enable IPv6 */ + status += nxd_ipv6_enable(&ip_0); + + /* Enable IPv6 */ + status += nx_ipsec_enable(&ip_0); + + /* Enable UDP */ + status += nx_udp_enable(&ip_0); + + /* Enable ARP and supply ARP cache memory for IP Instance 0. */ + status += nx_arp_enable(&ip_0, (void *) pointer, 1024); + pointer = pointer + 1024; + + /* Enable fragment processing for IP Instance 0. */ + status = nx_ip_fragment_enable(&ip_0); + + /* Set ipv6 version and address. */ + ipv6_address_1.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_1.nxd_ip_address.v6[0] = 0xfe800000; + ipv6_address_1.nxd_ip_address.v6[1] = 0x00000000; + ipv6_address_1.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_1.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_1, 64, NX_NULL); + + /* Set ipv6 version and address. */ + ipv6_address_2.nxd_ip_version = NX_IP_VERSION_V6; + ipv6_address_2.nxd_ip_address.v6[0] = 0x3ffe0501; + ipv6_address_2.nxd_ip_address.v6[1] = 0xffff0000; + ipv6_address_2.nxd_ip_address.v6[2] = 0x021122ff; + ipv6_address_2.nxd_ip_address.v6[3] = 0xfe334456; + + status += nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_2, 64, NX_NULL); + + /* Check fragment enable status. */ + if(status) + error_counter++; +} + +static void thread_0_entry(ULONG thread_input) +{ +UINT status = 0; + init_para(); + + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + netx_tahi_run_test_case(&ip_0, test_suite[0].test_case, test_suite[0].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[1].test_case, test_suite[1].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[2].test_case, test_suite[2].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[4].test_case, test_suite[4].test_case_size); + + clean_sa(); + create_sa(5, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[5].test_case, test_suite[5].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[6].test_case, test_suite[6].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[7].test_case, test_suite[7].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[8].test_case, test_suite[8].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[9].test_case, test_suite[8].test_case_size); + netx_tahi_run_test_case(&ip_0, test_suite[10].test_case, test_suite[10].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_aes_xcbc_mac, + ingress_aes_xcbc_mac, egress_aes_xcbc_mac, + NX_CRYPTO_AES_128_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &ingress_aes_xcbc, &egress_aes_xcbc, sizeof(NX_CRYPTO_AES)); + netx_tahi_run_test_case(&ip_0, test_suite[11].test_case, test_suite[11].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_null, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + 0, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + NX_NULL, NX_NULL, 0); + netx_tahi_run_test_case(&ip_0, test_suite[12].test_case, test_suite[12].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_aes_cbc, &crypto_method_aes_cbc, + ingress_aes_cbc[0], egress_aes_cbc[0], + NX_CRYPTO_AES_128_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_aes[0], &egress_aes[0], sizeof(NX_CRYPTO_AES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[13].test_case, test_suite[13].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_aes_ctr, &crypto_method_aes_ctr, + ingress_aes_ctr, egress_aes_ctr, + NX_CRYPTO_AES_128_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_aes[0], &egress_aes[0], sizeof(NX_CRYPTO_AES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[14].test_case, test_suite[14].test_case_size); + + clean_sa(); + create_sa(0, NX_IPSEC_TRANSPORT_MODE, + &crypto_method_null, &crypto_method_null, + ingress_3des_cbc[0], egress_3des_cbc[0], + 0, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + NX_NULL, NX_NULL, 0, + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + netx_tahi_run_test_case(&ip_0, test_suite[15].test_case, test_suite[15].test_case_size); + +//----------------------------Tunnel Mode test-------------------------------// + + clean_sa(); + create_sa(6, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + //Setup the tunnel source and destination address on IPSEC_TUNNEL_MODE + tunnel_entry_address.nxd_ip_version = NX_IP_VERSION_V6; + tunnel_entry_address.nxd_ip_address.v6[0] = 0x3ffe0501; + tunnel_entry_address.nxd_ip_address.v6[1] = 0xffff0000; + tunnel_entry_address.nxd_ip_address.v6[2] = 0x021122ff; + tunnel_entry_address.nxd_ip_address.v6[3] = 0xfe334456; + + tunnel_exit_address.nxd_ip_version = NX_IP_VERSION_V6; + tunnel_exit_address.nxd_ip_address.v6[0] = 0x3ffe0501; + tunnel_exit_address.nxd_ip_address.v6[1] = 0xffff0001; + tunnel_exit_address.nxd_ip_address.v6[2] = 0x00000000; + tunnel_exit_address.nxd_ip_address.v6[3] = 0x00000001; + + status += _nx_ipsec_sa_tunnel_create(&egress_sa[6], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + netx_tahi_run_test_case(&ip_0, test_suite[18].test_case, test_suite[18].test_case_size); + + + tunnel_entry_address.nxd_ip_version = NX_IP_VERSION_V6; + tunnel_entry_address.nxd_ip_address.v6[0] = 0x3ffe0501; + tunnel_entry_address.nxd_ip_address.v6[1] = 0xffff0000; + tunnel_entry_address.nxd_ip_address.v6[2] = 0x021122ff; + tunnel_entry_address.nxd_ip_address.v6[3] = 0xfe334456; + + tunnel_exit_address.nxd_ip_version = NX_IP_VERSION_V6; + tunnel_exit_address.nxd_ip_address.v6[0] = 0x3ffe0501; + tunnel_exit_address.nxd_ip_address.v6[1] = 0xffff0001; + tunnel_exit_address.nxd_ip_address.v6[2] = 0x00000000; + tunnel_exit_address.nxd_ip_address.v6[3] = 0x0000000e; + + clean_sa(); + create_sa(7, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + status += _nx_ipsec_sa_tunnel_create(&egress_sa[7], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + netx_tahi_run_test_case(&ip_0, test_suite[19].test_case, test_suite[19].test_case_size); + + clean_sa(); + create_sa(8, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + create_sa(9, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[9], egress_3des_cbc[9], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[9], egress_hmac_sha1[9], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[9], &egress_3des[9], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + status += _nx_ipsec_sa_tunnel_create(&egress_sa[8], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + status += _nx_ipsec_sa_tunnel_create(&egress_sa[9], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + netx_tahi_run_test_case(&ip_0, test_suite[20].test_case, test_suite[20].test_case_size); + + clean_sa(); + create_sa(7, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + + status += _nx_ipsec_sa_tunnel_create(&egress_sa[7], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + netx_tahi_run_test_case(&ip_0, test_suite[21].test_case, test_suite[21].test_case_size); + + + clean_sa(); + create_sa(7, NX_IPSEC_TUNNEL_MODE, + &crypto_method_t_des, &crypto_method_t_des, + ingress_3des_cbc[0], egress_3des_cbc[0], + NX_CRYPTO_3DES_KEY_LEN_IN_BITS, + &crypto_method_hmac_sha1, + ingress_hmac_sha1[0], egress_hmac_sha1[0], + NX_CRYPTO_HMAC_SHA1_KEY_LEN_IN_BITS, + &ingress_3des[0], &egress_3des[0], sizeof(NX_CRYPTO_3DES), + &metadata_ingress_hmac_sha1[0], &metadata_egress_hmac_sha1[0], sizeof(NX_SHA1_HMAC)); + + status += _nx_ipsec_sa_tunnel_create(&egress_sa[7], &tunnel_entry_address, &tunnel_exit_address); + if (status) + error_counter++; + netx_tahi_run_test_case(&ip_0, test_suite[22].test_case, test_suite[22].test_case_size); + + test_control_return(0xdeadbeef); + + /* Clear the flags. */ + +} + +/* Initialize parameters for IPSec. */ +static void init_para() +{ + UINT i; + + /* Setup addresses of selectors. */ + for(i = 0; i < IPSEC_MAX_END_NODE; i++) + { + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[0] = 0x3ffe0501; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[1] = 0xffff0000; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[2] = 0x021122ff; + egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6[3] = 0xfe334456; + memcpy(&egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&ingress_selectors[i].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[i].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[i].nx_ipsec_selector_address.nx_selector_src_address_start, sizeof(NXD_ADDRESS)); + + ingress_selectors[i].nx_ipsec_selector_next_layer_protocol_id = NX_NULL; + egress_selectors[i].nx_ipsec_selector_next_layer_protocol_id = NX_NULL; + ingress_selectors[i].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_PROTECT; + egress_selectors[i].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_PROTECT; + } + + /*Setup destination IP address. */ + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[0] = 0x3ffe0501; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0001; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000001; + memcpy(&egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&ingress_selectors[0].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[0].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000002; + memcpy(&egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[1].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[1].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[1].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[2].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[2].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[2].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + memcpy(&egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[3].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[3].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[3].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + /* Used by test case 8-2 */ + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[4].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_BYPASS; + egress_selectors[4].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_BYPASS; + + /* Used by test case 9-2 */ + + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_address.v6, 0xFF, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6, 0, 16); + memset(&ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6, 0xFF, 16); + egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + egress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_src_address_end.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_version = NX_IP_VERSION_V6; + ingress_selectors[5].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_DROP; + egress_selectors[5].nx_ipsec_selector_policy = NX_IPSEC_TRAFFIC_DROP; + + /* Used by test case 22 */ + memcpy(&egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[6].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[6].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[6].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + /* Used by test case 23 */ + memcpy(&egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0002; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[2] = 0x00000000; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000000; + memcpy(&egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6[2] = 0xFFFFFFFF; + egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end.nxd_ip_address.v6[3] = 0xFFFFFFFF; + memcpy(&ingress_selectors[7].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[7].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[7].nx_ipsec_selector_address.nx_selector_dst_address_end, sizeof(NXD_ADDRESS)); + + + /* Used by test case 24-1 */ + memcpy(&egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[0].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[1] = 0xffff0002; + memcpy(&egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[8].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[8].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + + /* Used by test case 24-2 */ + memcpy(&egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, + &egress_selectors[8].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start.nxd_ip_address.v6[3] = 0x00000002; + memcpy(&egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_end, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[9].nx_ipsec_selector_address.nx_selector_src_address_start, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + memcpy(&ingress_selectors[9].nx_ipsec_selector_address.nx_selector_src_address_end, + &egress_selectors[9].nx_ipsec_selector_address.nx_selector_dst_address_start, sizeof(NXD_ADDRESS)); + + + /* Setup SPI. */ + ingress_spi[0] = 0x1000; + egress_spi[0] = 0x2000; + ingress_spi[1] = 0x3000; + egress_spi[1] = 0x4000; + ingress_spi[2] = 0x1000; + egress_spi[2] = 0x2000; + ingress_spi[3] = 0x1000; + egress_spi[3] = 0x3000; + ingress_spi[4] = 0x1000; + egress_spi[4] = 0x2000; + ingress_spi[5] = 0x1000; + egress_spi[5] = 0x2000; + ingress_spi[6] = 0x1000; + egress_spi[6] = 0x2000; + ingress_spi[7] = 0x1000; + egress_spi[7] = 0x2000; + ingress_spi[8] = 0x1000; + egress_spi[8] = 0x2000; + ingress_spi[9] = 0x3000; + egress_spi[9] = 0x4000; + + /* Setup encryption key. */ + memcpy(&ingress_3des_cbc[0], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[0], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[0], "ipv6readylogo3descbcout1", 24); + memcpy(&egress_hmac_sha1[0], "ipv6readylogsha1out1", 20); + + memcpy(&ingress_3des_cbc[1], "ipv6readylogo3descbcin02", 24); + memcpy(&ingress_hmac_sha1[1], "ipv6readylogsha1in02", 20); + memcpy(&egress_3des_cbc[1], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[1], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_3des_cbc[2], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[2], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[2], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[2], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_3des_cbc[3], "ipv6readylogo3descbcin01", 24); + memcpy(&ingress_hmac_sha1[3], "ipv6readylogsha1in01", 20); + memcpy(&egress_3des_cbc[3], "ipv6readylogo3descbcout3", 24); + memcpy(&egress_hmac_sha1[3], "ipv6readylogsha1out3", 20); + + memcpy(&ingress_aes_cbc[0], "ipv6readaescin01", 16); + memcpy(&egress_aes_cbc[0], "ipv6readaescout1", 16); + + memcpy(&ingress_aes_ctr, "ipv6readylogaescin01", 20); + memcpy(&egress_aes_ctr, "ipv6readylogaescout1", 20); + + memcpy(&ingress_3des_cbc[9], "ipv6readylogo3descbcin02", 24); + memcpy(&ingress_hmac_sha1[9], "ipv6readylogsha1in02", 20); + memcpy(&egress_3des_cbc[9], "ipv6readylogo3descbcout2", 24); + memcpy(&egress_hmac_sha1[9], "ipv6readylogsha1out2", 20); + + memcpy(&ingress_aes_xcbc_mac, "ipv6readaesxin01", 16); + memcpy(&egress_aes_xcbc_mac, "ipv6readaesxout1", 16); + + /* Setup selectors. */ + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 128; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 128; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + ingress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + egress_selectors[2].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 129; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 129; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + egress_selectors[2].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 128; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 128; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 0; + ingress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 0; + + egress_selectors[3].nx_ipsec_selector_next_layer_protocol_id = NX_PROTOCOL_ICMPV6; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_start = 1; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_type_end = 1; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_start = 4; + egress_selectors[3].nx_ipsec_selector_next_layer_protocol.nx_ipsec_selector_icmp.nx_selector_icmp_code_end = 4; + +} + + +/* Clean SA for IPSec. */ +static UINT clean_sa() +{ + + UINT status = 0, i; + + for(i = 0; i < IPSEC_MAX_END_NODE; i++) + { + if(ingress_sa[i].nx_ipsec_sa_id) + status = nx_ipsec_sa_delete(&ingress_sa[i]); + if(egress_sa[i].nx_ipsec_sa_id) + status += nx_ipsec_sa_delete(&egress_sa[i]); + + } + + return status; +} + +static VOID sa_timeout_process(NX_IP *ip_ptr, NX_IPSEC_SA *sa) +{ + + nx_ipsec_sa_update(sa, sa->nx_ipsec_sa_spi, NX_IPSEC_SA_MATURE, IPSEC_SA_LIFETIME, (IPSEC_SA_LIFETIME - 3), + sa->nx_ipsec_sa_encrypt_key_string, sa->nx_ipsec_sa_encryption_method -> nx_crypto_key_size_in_bits, + sa->nx_ipsec_sa_integrity_key_string, sa->nx_ipsec_sa_integrity_method -> nx_crypto_key_size_in_bits); + + return; +} + +/* Create SA for IPSec. */ +UINT create_sa(UINT index, UCHAR sa_mode, + NX_CRYPTO_METHOD* sa_encryption_method_ingress, NX_CRYPTO_METHOD* sa_encryption_method_egress, + UCHAR *sa_encryption_key_ingress, UCHAR *sa_encryption_key_egress, + UINT sa_encryption_key_len_in_bits, + NX_CRYPTO_METHOD* sa_integrity_method, + UCHAR *sa_integrity_key_ingress, UCHAR *sa_integrity_key_egress, + UINT sa_integrity_key_len_in_bits, + VOID *crypto_metadata_area_ingress, VOID *crypto_metadata_area_egress, ULONG crypto_metadata_size, + VOID *authentication_metadata_area_ingress, VOID *authentication_metadata_area_egress, ULONG authentication_metadata_size) +{ + + UINT status; + + status = _nx_ipsec_sa_create(&ip_0, &ingress_sa[index], sa_mode, NX_PROTOCOL_NEXT_HEADER_ENCAP_SECURITY, + NX_IPSEC_MANUAL_KEY, NX_IPSEC_SA_INGRESS, &ingress_selectors[index], IPSEC_SA_LIFETIME, + (IPSEC_SA_LIFETIME) - 3, sa_timeout_process, 0, ingress_spi[index], + sa_encryption_method_ingress, crypto_metadata_area_ingress, crypto_metadata_size, + sa_encryption_key_ingress, sa_encryption_key_len_in_bits, + sa_integrity_method, authentication_metadata_area_ingress, authentication_metadata_size, + sa_integrity_key_ingress, sa_integrity_key_len_in_bits); + + if (status) + error_counter++; + + status += _nx_ipsec_sa_create(&ip_0, &egress_sa[index], sa_mode, NX_PROTOCOL_NEXT_HEADER_ENCAP_SECURITY, + NX_IPSEC_MANUAL_KEY, NX_IPSEC_SA_EGRESS, &egress_selectors[index], IPSEC_SA_LIFETIME, + (IPSEC_SA_LIFETIME) - 3, sa_timeout_process, 0, egress_spi[index], + sa_encryption_method_egress, crypto_metadata_area_egress, crypto_metadata_size, + sa_encryption_key_egress, sa_encryption_key_len_in_bits, + sa_integrity_method, authentication_metadata_area_egress, authentication_metadata_size, + sa_integrity_key_egress, sa_integrity_key_len_in_bits); + if (status) + error_counter++; + + return status; +} + +/* Process udp packet. */ +static void thread_1_entry(ULONG thread_input) +{ + + NX_PACKET *tx_packet, *rx_packet; + UINT status; + NX_IPV6_HEADER *ipv6_header; + NXD_ADDRESS ipv6_address; /* Destination Addresses. */ + + /* Create a UDP socket. */ + status = nx_udp_socket_create(&ip_0, &socket_0, "Socket 0", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5); + + if (status) + { + error_counter++; + return; + } + + /* Bind the UDP socket to the IP port. */ + status = nx_udp_socket_bind(&socket_0, 7, TX_WAIT_FOREVER); + + /* Check status. */ + if (status) + { + error_counter++; + return; + } + + while(1) + { + status = nx_udp_socket_receive(&socket_0, &rx_packet, TX_WAIT_FOREVER); + if (status == NX_SUCCESS) + { + status = nx_packet_allocate(&pool_0, &tx_packet, NX_UDP_PACKET, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + break; + } + + status = nx_packet_data_append(tx_packet, rx_packet -> nx_packet_prepend_ptr, rx_packet -> nx_packet_length, &pool_0, TX_WAIT_FOREVER); + if (status != NX_SUCCESS) + { + nx_packet_release(rx_packet); + break; + } + + ipv6_header = (NX_IPV6_HEADER*)(rx_packet -> nx_packet_ip_header); + ipv6_address.nxd_ip_version = NX_IP_VERSION_V6; + memcpy(ipv6_address.nxd_ip_address.v6, ipv6_header -> nx_ip_header_source_ip, (sizeof(ULONG) << 2)); + + status = _nxd_udp_socket_send(&socket_0, tx_packet, &ipv6_address, 100 * NX_IP_PERIODIC_RATE); + if (status != NX_SUCCESS) + { + nx_packet_release(tx_packet); + } + + nx_packet_release(rx_packet); + } + } +} + +#endif diff --git a/test/regression/tahi_test/tahi.a b/test/regression/tahi_test/tahi.a new file mode 100644 index 0000000000000000000000000000000000000000..eb97f4774d2844d1068232edb22cbbf51edf6c31 GIT binary patch literal 2198906 zcmeEP3z!^Lu|7#An-C!+;T<3h0eJ~wyJz+l5Jy-8A|j$hMTH402*~S(h=__Uu84@J zsHljz;)()_ii(QLor^0fB3@Csihv`osECO8MkV*JK6R!~pYE>N?qpVXH~poyy1J^) zsqz3B-} zm))uq(FZQnbj@W-5#4a5rkn0k3N-6C*K7LInQ9i%`XwRFUa+kSY4PD|HfYW<4{563 zq2>^w-;mC|T+JbR!_}HDzFy5CddHKRKCq9PLv+n*O*br8bBI3osHU&pqUI2N9Wv3K z_iFml?P?Cu12<{G@r%M0CgjsuIzC4{G|?$*KgJyXbOFyIr8>67@c; z>G0KRF40T((S&~H5}kRarnUE~xkTq(q3MmQ)Lf#AkJa>Uv_*97Lz+JOsG3W3>sn3U zxm(R8`q>kj{GD%rRpMj>{dwh5U0s?MU9aX5?Rcc7y|GTz4?WS~$(o*XteQu3 zH0+2lmXPYbY97%m_R)0aGBuCrRZBFz_B1t*=#95&x_GIYM|9a*P4Brw%_I8Ya!nsO zU(F->_}!X5d#{>D^pyuSef?ZDkLWuKG=2X`HIL}NYc&08m6}KNhle%&^D;FLG=HA2 zY4JU3KG9C+Yua;}norbyk*0x1)qJ8uR%?3h6KX!ui?7yn;=yV@(dpM~I(LbhPZZp& z>21fV`9$w|P}9|?srf|Ltyo3qt?qVM0X>Ap+Ue4>ZYCeiP&)b#h| zYCdSQIS*;t;!L#}(Y8-$DqpBJBid(yrpo1NGoq(2)$}a*5gmDxrkDIhZANs`N=;{W zsm+May<5|T+p5io-hQm6EA~*E5sj?S^a=D!^!bA{eGUB*ed8WYcU_}4Bl_|6ntpz+ z+KlMogEjpXI?#f-vo$R_K`kKKwkUqacZBF#>=W4YD(S@ruU5a(0E1)O($O=uLyjyKS^rdq( zePdg-1<_s0HT?uJ5Z!-?rbm~lEr_0k4`|`$Yc(xBS}i2n^Knf*m#c+DhxnR~!aC8* zAJ_ECqt!y9^KQ~~(Gsv3*?YUOd0CYspIa<@p4^~?eo#ktK<8rkn(Yu#u`q*r>CDF}~Yx>rMYD=P@AEfDz zE7X>tMRO0*v>n!o_IyxN&xL9c(IF3LI{JLIi0I_in%1pVi-_KIq^8SHQ;UeMytB|(dRxKua>HDnXJVxn8G)^z7_YBABh%QXG!0kxRu&sT@EWX^Faq{YkB5~5`fXxjH`wS;Kp zahhsZs3k;)U90K&y=n>3OIB%GbB|g=bm~Kz{_6>~gy{T*nl4tLfQSsI7>Ox?aR@)Li zbZki5?fak#={5VP?T9Yz)pW%zYCEFq4%hTGY$y5_wh{gCAWaWFsDlM1r9{tLrRkV$)l#DRO`2YDfm%v*)&fnhx<@S~di^z;F1b}LCA#WzP1j$m zmJ)sWN=?gJR;nF| z&c8#`#a(JgqW37##9I}&~2Ax&fVsvU{$fjv?4dQHDwp>`zt^W!1yRJu%sw8&RG z5p8>`rrp4adXCg|#1gd=(Mu24bQ*L-=RhWU?cJJ&SE`+e-uA!o` zPDJ0iNz=XXCHnP~n*MZx+KK3iM?>0q*7+)=`TMAyi5A|YX}b&5&P3%sH0^bx+L_4f z)pWouYGUtUty)IZdxxgl!)h7P5f5p4$!xWZ=u}_RnXA+?qE}t6X?V3-Ms(@Dny!38EhD=A za7|x?Ez#F+)%3sUo9KS@LG;^Yn${nzmVtIz*rjQwht)1b`#h+r{~omq(JE{sdf}6r zPF$jPA^NYwHND|DwF}YPFW2Zh;Co5>Fz7lE=1$#m*^41K=kJ; zH2v!)wF{^`_byF)-=@k$)yp+K{WMi3I;2ni&!WuL3;x0L;^a==m!I7+WO zQhMF4(n84dT&0DO=etS^AxJgggr&&qWAF#8%2Y7a`9=$a4|$EQCB4A0|#LdbU!@-2jX7a`w5$afL)Erfg*A>TsCcMah^&aS`gV5bALe>ah^&aS`gV5bALe>ah^&i6P`$XNPdz zKD^Ne(`UHuDovlHjP*$yOrPPp>uIt=%2-xtgUL#`?s}T6kTRAP+F-I0uDhNlE2NBN z1shsthj88T^h{Pr8OsW7un>x$9Y|>*6hAwV(n2VHb|9sNQ2gvbN(-U**@2W6Lh-W$ zDJ_KJX9rSR2*uA1P`1tv;ktuR>+C>E7opbKft0bjr41HB@v{RdErjA{2U1!H#m^3; zv=EA)9Y|>*6hAwV(n2VHb|9sNQ2guwW$Ww^t~&^|&JLt>5o(_AEvq1M@flrBQ8vjZtzgj#0@Qo0DW&JLt>5o(V zb_mxUgj#0@Qo0DW&JLt>5o({es-Yeip&qM- zdR&BhEQEU8BXzGieHit>aLyi%_qHP_K(n zuZ2*ri%_qHP_K(nuZ2*ri%_qHP_K(npM_ALi%_41P@juXpM_ALi%_41P@juXpM_AL zi%_41P@juXpM_ALi%_41P@juXpM_ALi%_41P@juXzlBi0i%`FXP``^1ey!`@Whl0O z7omO&p?(*kehZ;~7omO&p?(*kehZ;~7omO&p?(*kehZ;~7omO&p?(*k0Slo47oh+vJC*Sg~3ACGlc86o6#I|zB*5kgpZJtKs?ZU-T+J3zc z-SvzR^12;_yzU4gtUI38oZ5?DaRDmUoEqz{r-hI^r}nHlHP&5E3n6z-?OAhbth=5T zLhhW}v*y%TcRekH+&Q&p&8e~Ocv^F6FMh=Z2w8J#th=5TLhhW}v*y%TcRekH+&Q&p z&8e~OdRhp%b863;Q)Aurv=DOV)Sfk`#=7Ha&8fZk6&E06&8e~OdRhp%b863;Q)Aur zv=DOV)Sfk`#=7fiA>_`fJ!?*lb=T8E$emMr)|?vaj;A%J_TpDufRHt(#=7fiA>_`f zJ!?*lb=T8E$emMr)|?vauBU~NJE!)nIW^W@PYWS;PVHH9YOFh+)|}dlUvU9K)|?va zuBU~NJE!)nIW^W@PYWS;PVHH9YOK4S7DDcv+Oy`=Sa&@wgxoo`XU(ax?s!^rYR{ch zd)Ay9>#nDTkUOXLtT{E-T~7-kcTVkDb84)+o)$vxoZ7SI)L3^tEri@TwP($#vF>Q+w8&8tbm7g^)X^_N+NI)?H5vA$LygS#xTvyPg(8?ws1Q=G0hsJuQUXIkjia zsj=>OT61d8ol|?(oEqz{r-hI^r}nHlHP&5E3n6z-?OAhbth=5TLhhW}v*y%TcRekH z+&Q&p&8e~Ocv^F6&z)0y)|?vauBU~NJE!)nIW^W@PYWS;PVHH9YOK4S7DDcv+Oy`= zSa&@wgxoo`XU(ax9{2REIW^W@W%R4Vcjwf;b)6dPu4go-_T4$PZ(XOxy6YLuseN}& z?OWHWvF>_Cb86q6Q~TC+YOK4S(VW_M=hVJ6r^dSDY0as9cTVkF*Qv4YdRhp%b86qZ zPK|Zf(?ZCdQ~TC+YOK4S7DDcv+PAJ#W8L+%5OU|#zBQ-Dy5nihseN}&?OWHWvF>_W z2)T1=-?~nXb=T8E$emOB)^%#EyPg(8?ws1Uu2W;(^|TOj=hVJ6r^dSDY0as9cTVkF z*Qv4YdRhp%b86qZPK|Zf(?ZCdQ~TC+YOLFy72L-$$Aoa*RhpwFDPz&n1`}<#?s}S| zCMjdl(gqW4xbAwIqb4a6(VBdcGIrFY4d$pBuDi{ee3CMD)Wn9?F(F)cJX^;EQpV0J zw826seoP>xg;4yMKuQat_%VT$7DDl30x2zo;>QG1S_s9D38b_TiXRh5X(1FpCP3Lb zCWPw_Lak#0DP4qG#{^QkHPrf@P0HArmo``k#g7T3v=E9P6G&+x6h9`A(n2VHOdzF& zQ2dxcN(-U*F#*cfF(F)c5NaJ0Na-TfIwp|PMX2>Vo0Kj>tz!Zy-My^!JDZfTxe0Bs z5K0^qTEDZ&(A~>g_pV48J8IGf3!(V$Y$#j5v%_@Vo0Kj> zt$SCbbP;O(&L(9Hp(+j%X3q}S?PzI(*|WoSS83{&l(9Z(gQ?qa-SsqCA!Y2?M;lDt zhU>1UsasOUvO*h7R>F11vvur)GCm)o4d(0+uDhNVLh)lCSz8FjkA0-H5Q-oBNNFJy zKlYK*LMVRh>%llpK;gO_Ep0FXh3l@;1VqYM%4mZLC|q|vO+ciKrHnS1l!fcAr%4$p zV=1EzCS~Ee%0=KJL7DfS4bH zSFueq5HLHAZEBxW?d?efVzV^cG>JfL$Foh7^_sOCnu(n4Z69Rq?a6wL&F*Z|WWC1b zdbVjYTd|p+WojmXu}$gOGSflZG$UJPa%h`oWXntyZPSdSiY&L0| zCXX($xutEI%vNlsX`3dq6`Ob3rpau@W}%j;nT*CZrDw}bO>NVRY?+CwZJLoSGi|j^ zGqPnSv9@VOw#<~)HqAH}n1{1$(~Nz~+*YzpGtLF(!7ba=p4`~mli7;hd9qB+4XD_r z^lX{iQMPGDw#)-xwrNJT%&jWhG$UK)VKCb?BU|P+mTj7mE%Tt5ZJLoSbBoJ1&B&H{ zh|D(4$d|UB} znmiK5?yT9S$s=LxKAUZtJQBw4y4j}5BVp_woNb!iw_#9+-Ho(OllxZe-lT1s+_z$PDlJoU!!ouhecv*-FKyF|eak!`Xq#s2 zTjtiLZJM!fnTH2$(~Nz~-1f9hGxja>V4-cAv2U4MqPA(qzGWUdv`sViEpxlnHci{N zaB<08KQgA_rj%^ac4sdLH)WVQdjXlI;Y!<`y&&9_(Wo6>Q0FC~y^+JT6+JEx6sQ%0*vuwr*+ ztYMiOG_g%7t@fb^odCj38KzFTkZIbHkhVMJ5^l<9)hQP;O*<0Ob_aoQQ%0*!xsYkv zk&w1K20mAZ42 zX);@>J2#movz5AYlW8(rsXI5BCbN~gbCYQ@Td6xYOx>M3+?1XzcjqS4jBL3(H<_l* zGH81;TdCIx$uya*)a!&~n#@+}bwV;tW-ImRLZ-=V#jX>cdiFUdorpbyC(kX>!qaTy za&Cz!CJc-*u@5+A8w1i3Q(9pljEQ}KG20k`mYC8C58Rm82NbidANc6kbL=fCZE+n( zR?#Oh%(j6M3XS=%|Z%Tx%x5u*1n=(vesnw>*Vd(9#q41`RR%1ibruH=49#$;n z+BCTj>g}=A^QMdd+}%uDr|xR3vUhM}?e22n_V{kco6^HDvjA(nu~~qQ(e7w9EAc;ftl_ zXG3@wf5ln*C%5{kTPvwstEpRiQn&V|ZtY9m+Ml|0AZ@GHox0Ua-I_W!FLi8Q>e#&0 z82r>2{L~oy)ENBK82r>2{8W7XRDAtZeEn2>{nW8lQpZ+F9a|-JY?aipRZ_=RNgZ1y zb!?T?u~kyXR!JROHFa#&)Uj1l$5u@pTQzlT)zq<7Q^!_K9a}YZY}M4U^`wriCv|K+ zsblL&9a~T8*m_dO){{E6p474Rq>im8b!@$Nn>x1M)UoxZj;%L! zY`v*t>rEY7U+UQUQpeVpI<~&lvGt{ntuJ+KeW_#XOC4KZ>e%{H$JU=Zw*J(y^{0-l zKXq*VsblL;9b13u*!ok))}K1I{?xGzq>gPMb!-EvV;e{v+d%5r22#g1kUF-3)Ugeu zj%^@0He9ysPR2`Hlkw8lWW2OB882;3#!Fk1@zU00ytFkn-jq23Y`xS`q@4Z9HgyzU z>L|R_QFy7N@KQ&SGOIugDYFXNnye_=nmV?WIRV)wBg2)SlpNF6WR7WT5*^x_M2EH} z(V?yBF(lC;+hmThH6_QiHHi*wO`=0vQ^%H)d9qC%TT151Hg#+%nJ3%Sv87}lwkesX zt*K*6nNN~!YTi=jlVqEkH>-B^ZyQ_+Y|XUImM9{#B|_S4i6SvuB81JBC<3!3Le^}d zYjTMIqB1gO^ou`X7Gck3R!x~L2`{T^j7?%JR<#(L#8|8?t?FPKE8AvE0$VG~ z#wLNSm0fKU{_srXQg3xJ&|BS6>#c52daFBnz17X8-s+;Dx27bJ6;4{it%*eHt!}C6 zt*OIHq*>dh4my!;ZJRpiMB24&>Yx+p4{Z}AptrhZptq*RYwhq>@^wk*>jC;9e;`{f zXZc=`G#p;^zZ=&fq@o7JcOPV4A6^i-+~Qn$As-KK~w zCKl4CEhTH?Tx;E|&f%3+;A#4-c8&kmW+j8CwHY%#^pHbVmiIdJ$Yb^{_pR_&cxAk) z-q+oWhpQ8d87nDD>JRH}gLqaHvJ{7O4z_H`4m8$T3B8RJ`Nt!lqvqS)K|fEKu{WSu z4Er+pVIXR0F}2_N9yN|aC#thwxsLBK*)N>vb$x}8eP;pmL9EZBhkwo^{3r~FY|luPQ@lwutM zVPF>05j~%|+5TGEXe~x0ZpJ|B*I`2g9RC$yNYt;1!;Ar&)PZoacYD*`V(4tU0CsE0 zffr*Jl_8xM+8_U_{rwX@{&iCjSadBUkALR)MMzzAe~nD-f)1j z{z}9@CEDK=qYHme`83Y##hgpcoY%FaIh$F+lo)}zneVM~wi}V=vAeL45AkDtR{v!r zc|-bd3jWl8!1}EIYfx-R|MY_`%b)rm;r6roufsp9eyF}1ZQ3s*Nz_06&T*G;{LoYT zS^6gH)8Zrl8h#&S)jvWL7xNoF%P6hSnC-vu`US;a2NAY(J!1#(28ggAc^P<__kEIg zgB7~>sw-;$bcl7xX1r@5H!S^mkWKB8{{@f(t|gL(AvZ1g z63C{ONN+E56auxDiCiCgC)=0dO4o<3g8Y8eDz)TXAM(xhAzUQ#=}J+B{#5Bt5B=$- zKYjG4pZ*NcA3Uu`f4%T;=!A#pX-nvaN8f2Zbi@Pev>v+RF>|cr33B=y`rBKOKFoZS`EU z;nMzI!Y4RqgsH;O*}az#|1EL?8Ew?xA~W_{S9p?d|66U-Z_ResVyEVBLE4eRMgR7< ze~WLF-?DTZ3V&|OQEaYEC zkko!w{{i&We%eCqH`zZ;Pwm%WMD3^j7O=;krYHXq_-Boe^mKxh^mResMgGD<^KofO z!z^b1AMjg(u%Wqc)^7>Q4e56SH@PNxFUTghB<}~g#i@kR_Z_om+-UqWuFhMc)~rP$otnh97pdikx2u%B6&YYd`4nxhUeA7(zve2n=x z^Ah%ta1P9Ti1{${=`x4?DljoinOEF7>_06VG64kP;?7~oZX$EoatZFJ2eXuU#ht@G zg2rA99nEWLpCz}{IV=tc6S*IJfOFt5;~;K@qYi}KQP@bwwyn6|v^nghi0^pl&0^Yf z=dgnadW|sxH+E6w(z7)G&N*y-&a+;zX%1`hVp0X!o`cwP{EX}MxL+HdTsF;N_48Ej zeT#|X!}ot|{5Q%R(ByWiw%?k=>K~`A;kYZNmYqXh%Z!etW=We5nd9LqW8`o;CDcJQ zPss9bupTV2kbfCLQu|r{0rb><+CuR)**{HB?bl#L?WfIA?eVAS$$td?S>q%9ra3G@ zkbItx=HGRYnM2N?Ic#-9=dk?NZ+OL*-;&=nhea)!u)st0BE>l(=(}c zLf4+-asHqgs0v>$It+jHOHajNt5+p ziG}=Y2$I^*>c0WKG>0pr6Plx?En$4DPn)CJ<4@CP;b!`xd5W~8jVWgTZ@5lKSkrYp ziah|?bF8K%(=!JqH)OvXWRnY$={jMVu_c+V69$$Hv9%Pr?q?q78bSW)y5B))?OSM{ za^_t3>zUY`DY{z1pF0WXNc>5zu-#dk7r)LoU9RWd35?BB=9N9c>AD&1Pqb`qRWBCZ|khD(QXy2k*NV}fbfMO!o^L|PV zSc?gPxCMi{4|Zj2q+v{h~P|t(TET%p8dfufN#~NbtjxK%j&;J8WOMJw=;^wI z!H)FyQsg=Voy%#dBOi2~VSlWjhjq$E&Bz|4F+DrP|`26SNpNzljT{-b|>SIFrJJ8Bs-u_}aOvXRu@xOc$@IS!9 zKW~529shSv0{$y4{PXrV-SL0VB;Y?_;h(p^>5l( zAMJN(GVbr>_`YnX+fUB_yFM}r^|P;4KY9CWQ$IHT8TXHJ+@DP1)9Lo7{QUo#NvNNv zS@n~*zc%$V-|lVUH<~kFZSd>L)n4-WHs$O8V>$73 z&fgQt-(FV!^7hvze^Va+YbOE!JuUq6_BY+}|M(=}zlVi?-u|W){uoS=~+uh1v-u~L;Z^|G4ub%|`ceC)%+g}X-{PXrVt?`myoPm_Kj2|EMvXol&1TeqSf+e?s%09jyF+ zK4-nP$$wYg_MH9KKL2hwK9fJcnh^fmTljxrBjcZ|y~)R?)A{YXIVYY@{Y@x;+gbU` z+h3dg$Hph)`1zlG{pX95fd94@{(1YGR`?e@{%>R9_obZqYJ*=_uJ)$k@#o7q@ho!u z+1koq-u~L;Z^|EkZkYu9x3cih+uwA@|0|P#{}K!Ty!}mg{J%O0_%F8b&)eU0$Ny`S zfd3*3|GfQ8EBrB-BInO7E&OiHnXfkZb>(Vr8qR+rf8PG4JN~y#0{&02@Xy=dbjSbelYsvM3;(?RO?UjqCISD= zEd2BKH?8o;V4V4jeg7-t{>6XL{l{ed6T1FA-^%|ta@Jd${CDMQFFAj<@z1z^zUls> z&cVO${^LBWes15$^^>c;Wc^I}`TsX_;^`c}Cba)|S^3M`Uz`1Z%H#j7Nx*-ug@4}u zraS)Mo&@|$7XEqro9_7EF$wt3vGC8^-?YLXgDGhzfByaMB;ch|3%*ZrWO7eOp)WqlNNs8 z%bBk>_;uxKZyFx||2HR|Me_GAD}QhzfBgUcB;fx~3;(?RO?Uk7o&@~=Vd0;* zziEX(22Ts@;Bv=Kle`p{*PJs=k0I0`g3HU#1;h(p^>5hMM67c_> zg@4}uraS&Wp9K6LvGC8^-*m_S!AZdXw-)|+`WllVc>_5M@@|U;2Hv7-i`u$a~{(oiR_fXD!wZX3| zS9{6&nOgWKMX1h2P(D=Bo{UUAfvz*3Xo$|G($Nv&ix1 zhgSab_SYtVQy%{(CISB+Sor7dZ(8A>JpS1CzozZ|$Gffk|08F;waI^1uJ)40PaFSD z_aBq>X&>J*>T|>1fBa|8dMI-I|Grg!dHZWqe>OfD^^@cM#17+Mspt;qD#S(i*J)@e z^}l{LDO$^{i`92aWr$A(dK=X1pF|6@XQ{=NS0A%jZw>z@_pgnMkM1w*h2yu|-w5>? zj>m4_#wVlw9M6X&`KY)H!!c%V`|0e6x{O$3DeL3yW_!{^ljt_b%K81#* z`0A{07azsqE@6D|m*S%&O7R8IOYt>XUo^fN9HsaI=%x4+ic^ZO&ibP9HQ+DBr{>A= z1<*_JHCbOYzS?{_z5sd=zs=a0(TFRU-@<^*@pEHQ+Dew}l*E0KJG0>x;%$TPVjDKriCAr5skzwUr!S0KJGG>x;%$+ggqx;(MfWL^}wsL#{^df$&FB)HMJ2}1pdJ(_v<@oBXFB)G1{vv)m$ngcxi}x;(MfWKIOPnF{fpcnCDebM-8d&uzx(2Mx(DaTi5ec|}_ zlH+TjeJQ>G{vv*?FC5?Aa(n^wQhaJ3IlemUi^kW0zgT}yljCbbFX0!kzHof|%JJ2p z7xCLqj<3%8!tudh#BYThUjV&?Uz7Dk1^e<@f^VrTChxFB)I1M~*LmUc|3gj<3%8qVYB0 zFXGoH#}_~^;>Y^5_-OuJ!!>qkem)}T?dwOg(3ZQ<{8kOfIQ?D2(Tae|<2jRV?@4|-{QbtGSkkBWozMdPbIU5>AT_NDj&_)GCM1^q1@* zBF7g%FXG4gqVd%R<@f^VMf{#6$5&^4(fAth7x4o)QhWjQB7Uqd8ei>DIlcgTDL!?W z9ABOFMdNG0U&Qa(a(n^wB7Uqd9N*z`d^PAr{GKDnS7&|U_~0+%cZ3{Y0KJGG>x;%$ zd#)T`0KJIck#c->))$Sh0e=y{=gIK}(2Mx7zG!^4qvZGk=tcaVFUMDBebM+D@E7qr zT8=M(Uc`^}MdPczK#nhfUc~Q(a(s2x7m1JN_YL?<^ZW8K+4|Y=Cua%&0RGbWYVeol z?;~yW>P2nvVSN#NXneI7%j0XHeQA6F{KfiWec||CBF7g%FU6;hmE)_kzG!?6_)GPn zUMj~IKriCQ`l9jGUM9yEKriC=ayh;_>x;(MfWL^}adLbC^df$&FC5?Ta(p%DMf~b= ze0A0rjt~AKerx3T0_a8jSYI^0+6i)e0rVn%C(7~FSzk212K+_*hUEAH=tcZkUpT&# zGtZb=DV+uK|A%ztiOS z0_a8jSYJ54SIY6#pcnCjQi`w6`oi(SU&QYWIlcgTDZVD_i^f+wQ;siyUc~P#IlemU zi^kW0zlh)2a(n^wB7Uqd65kw}pZ-_&{G9Y7fbF0lhSTFP|gp1L#G3 zSYHI6aQ?nd9$x^xG`{+)>?YS2sZskg}S z)mdLSKKP6Ecd;B_0KJGG>kG&CRyn>J^df$j$nn)#UpPMai}<}wjxT^-#E6}#rSa9^PyMGY)c!~ty?SRG zd|010zLM2xI2KE$Rod2ozgS=IlE)W7FV+|9i^f;GT#he*Ucz6!TaK^J`oi(OM~<(7 z_NDj&_>1_lzG!@n_sa3rpqJuPSIF_zSzkCl_>1-TJ~_SsdJ#X?7mn}!a(p%DMf^S> z$5&^4;rQS$;&-JSUjV&`AM1<8SNotGUjV&`-&Jyab=DV+uK|A%zYodr1<;H5vA%G8 zSIhC$pcnD`upD2V^@Zbuzlh(69A5yvh#%_<$M+FAz8dr*e%HwH)mdLSKKP6HeN>Jw zfL_Fp^+n^Wjmq%_(2MweOpdS4`oi&DE63MB`%-)X{6+j&UpT&x%kc%!OYx~s$nn)# zUo^f3{KfjaPL3~tUc`^}MdG9RdF}e_`8nxF1U=1fgB#k64|)mz2K3VWz5Gd8A3!hS z!}=ol(D-VflE)W7FO5&#D92Z4ebM+D@E7s>wA_EddK#;{Q2v|HQ~L{CCFHPvKBM(n z{v(3EE2T|))7G|-vYv)n%(C>Q*}L4g!du~${cf+XySLIEvkHY-)~1sB z!+J}^IBhMBJ3iVu*s>)%(7ujuc`1s$1|sZ8-T{2Xl9yqfnx)zy{chj^WU6J7_X2NP z@_vwO=+@Z#kQ4s39|YNa%Y^iUkekq({tt(2zC}X%qsSgR zndyHuWVKCX|1!wt+ahFt0%Y^85Ry+J`)wotGa;LAfslS3d_f^5D;LGlmDey6DYdm)=|O_06`*?e1q z>-=+ ze-5&Fm!AA@fo$HLC;5LMn|I+!{ubFkE%N^!Wb-aN>F^;clU2Ky3$=-|np8?stYfbu9kekq(@jMr@c^8`WFNEB{B*2X4 zrI1x6vOfW`dH0#@PbGWkjs4kVUyb^IHDvRyGTC1M*}R)f@|z)>ca2HDlTvOgqh?;ViMyO3mm1>`35CY}#LHt#Z$ew6G7BmWy9t7k>_H$gV< zCX)S^A)9v%Np6rm8aMcT6LJ9A^miBJrX~LfvUwMf{O=?CLnHrRKsN9Ck^W)G=G{J$ z{{Y#%t4H$R$o|=p|9Z&gT|ClvVQx+TPos%v3&`eOInr+pxp8=e=Z=uob0YiYkj=Ys zWWP7rLvQf!Ci^3z{`(-CciG7PAjnPVP5;k=Y~Dp9{SjpU+{ph0kQIJJ82e)(n|I5| zehp;vt{BOukp1%_|Fa;Qcfm-1F61WkroGogHt%wgewgf!iu~UOSv^0pzZ|l8H;e2) z0NK22Me+#QA07FB9I|{M`7eTO-VGvoJILl;ACi|rZoW8b@2O<}k|>^i$sV%Ve=3m8yEx>(60&*shU8~L zHt*7qd>GlkH1dBQWb>{J=~qK;LcfZ~`*O(UT^G_1k^Rde|5rj*FOTfkLN@QNko{{Q zn|D!24#@tv$p0;n&ATR~zYKB{`c>Tjdm)>5K}dfUXH5Rkn5KGS+a+0 z^7$pQUlaBJ-;m9_8r1&nkekr2f*Hx*g>2rnAo+)6e?sK{Q^@MX$o@gdbxZyY3=V>e?`>){*cYP0%YF{xe2}L|LKs;v;L$XB>Ph$|K~tfr$+WiLpIOull@B|n`iM! zu9N*~k^d_on`iAweBmb{JR%b>1-v-${J5KiBhHRb%C;5NL z{_M#A{~()Zy-EK7p4J=A(be=J+)q zvU#?e{I`T`o~0&vTgc6GqW*V=Tw52lzdPAOHtjzRvU!%7{C&vg*=LdmAe(2ENv3N_ z>fFfxP{`(4WYQlAxe2`)|1prwv&5u-8QH%&@;?!>c~+S8r$IK)29x|>kj=BaB%cSl z_L^usZ-8u`mvUzLN?FBlKxi6P3TSk-+*kMWhMQcWdHie{|AuO1(E%|kj=BHWdC!>=2=sce@*sp zi2Q#K**r^1`oBPKLT~#27vx$HjlZ-R>>-=+KLxUSV`RSsa@~@5fZTv=_P;XOUl{rC z2|0jl`db0HX~{j1&9jsg-+^TRrpW&g$aK-t_#Y0rZpqJw+<y_4)Oj@o-4Wb-T_ z*G?M2*4law@ zTL{@an@0L=Ae(2+NZtvudA5w?-N^o(QUCiuu3NGP**ptI_Wfl4uBg9fKsL{Mk$x5A zCiG_f&xLHB)gt{1$^P=l|D}-4vsk1*0kV1aisVxvn`fm+J{xlFJyAYh4cR;^MfwXM zH=#HEznSd$Stin73fVmSMDn{Kn`fCwz7n!|c8TPVko^@=f1e=x_eJr48nSuTi0p5M z+=Slr|24?wSs>DnL2kT1YVSLc)dwQ`yCIurf5`qPWDmWmKf1QBu8jKs6=d_Q4%t5n zxe2}L|Id)kvo@svC)s~6@}Kh*w0BixzW}m%c82U1LpIOCki0$F@=$mZDxvi~w<^Q;2Nbnm8iZ4}QpA)99vNPidP zCiJHNACdjXBm4Wv9$mZTU$$e!1$*8}BAU7@f zS&+@WaI!xFvbpz7@(UoFd)*`-3)$S;CV35HbFZ4@Qy`Z=9rbq>WOFZ?^yfl0_nt|9 zJ>=SFqWR-6WOHws^!74Gm26SXQF9#`lL>2?qvol%p*>n^&sJ(N?B56ZZ|IL&T1@S) zTXV{($9H?jH+xt%knU(6_2b8v0g4-)iVv4SlPjZ#DGo34MD)-=5I7C-m(J zeS1RRp3t`^^z8|KdqUsd(6=}A?G1fR|d4Sjn<-`>!-H}vfbefvV+zR`aU#~lK_PRrFuRC=2xy?MIeJY8{~E;&!voTrP< z(^co`vh#G^dAjgC{C8;-t}Z=K*Pf?~&(qcC>GJb*{du|oJzasGENu0&6lqNi)o)5YlNYV>qDdb%DxU67uxNKcofr)$#FMd|6P^mJKzx-LCk zn4YdoPnV{rYtz%k>FMgk!zUpGx;{N!pq{Q!PnW2tYt++4>gg)=beVd(PCZ?yo~~3+ zm#U|0)zii5>1y?Kxq7-@JzcP#u2@f(tfy<%(?#p)s`Yf)db(~sUAUgETu+y-r)$^O zwTtI!XkfmsU0>I(uWQ%Wwd?EJ^>yv~x_15Uuy%c2yS}Ge(Y5RA+Vyqq`nq;~UAw-n zU0>I(&&NqVP?{rUSi3$SEBRo_M@v3j^6`=nn7Vd-UAw-nU0>I(uWQ%Wwd?EJ^>yv~ zx^{hCyS}bnU)Qd$YuDGc>+9O}b?y4Pc70vDzOG$g*RHQ?*Vnb{>)Q2o?fSZQeOI(uWQ%Wwd?EJ^>yv~x^{hCyS}bnU)Qd$ zYuDGc>+9O}b?y4Pc70vDzOG$g*RHQ?*Vnb{>)Q2o?fSZQeOI(uWQ%Wwd?EJt?1gV=-RF5+O6o?t?1gV=-RF5+O6o?t?1gV z=-RF5+O6o?t?1gV=-RF5+O6o?t?1gV=-RF5+O6o?t?1gV=-RF5<8DRQZbjE_Mb~ac z*KS4EZbjE_h0peUy65w~IpK%L-3p)b`JB%ueLm~+XcKE!;O`55zY<|X_jqV{)ZKE!;O`6%--<|WvM_RI&F4>2EQKE`~Ud8x#H%m#(bQ42|xM5{+JIjA7(zve2jUii|v^YG9O|-%6yFZIP((jb5K8n%!il{GaqF> z&b)-5o?%?f2bm8uA7wtqe4P32xPBS-!+ePOF!M3y70T>7gIBKOKFWNI`8e~^)*Kh}A?Cx(N12Z^FX0*5FrUl^ znGZ7`Wj@AyocZqCazD(6m=7}_V?NHjv>o@ue31DN^HJtw%*UCR@QiI3AM-)x!^}sS zk1-!-zWWXwAM+vR!_3E+k25bV<$jnCF&}0=%6yD@X-BqaKFEBC`6%--=HtvuJ8@jh zhnNpDA7wtyytFg-!+enWF!NF7W6Z~y@4k%tVLrrsnE4p2ERKFWNYdFiPfAM-)x!^}sSk1-!-zWW~B5Az}B!_3E+k25dr z$^9@NVm{1#l=&F*(q3%Oe31DN^HJtw%*UCR_U5>l4>2ERKFWNYd1)W+hxs7$VdkUE z$C!^Z-~DOa5Az}B!_3E+k25dr%l$APVm{1#l=&F*(td2ue31DN^HJtw%*UCRR&ZR* zhnNpDA7wtyytF^}!+enW5c6T?qs+&cm%7=H`5^Nl=A+EVn2$3rc^n_}A?Cx(N12Z^ zFZtXL^Fijr%tx7zF&}5XdxiU9KE!;O`55zY=A|n4!+ePOF!NF7W6VoEY|ng<`4IC_ z=3~sqnU{JwF6KkbhnbHuA7@_b<9?VAG9P9>%6yFZIP=~6xgX|3%!iqeF&}4M8sL7I z4>2ERKFWNId1)ovGaqC=#C(+b81r%Fr32WH`5^Nl=EKa#n2$3r9msynhnNpDA7wtq zy!3RoXFkY$i1{eY5<9?VA zF&}0=#(bQ4>6zRQ^C9NL%tx7zF)tm=_RI&F4>2EQKE`~UdFc?2i}?`qVdkUE$C;M~ zxgX|(%!iqeG9P0;&V2W0aX-w5m=7}_V?NHjw2J#-KE!;O`6%--=Htvuhq52@LFU8E zN12Z?A7{S%VH_XxA?Cx(N12Z?S1ZnW%^B;~oB+OVt>&kgwRI<*w@$4XTC;AAT5-ZT z=cpBH&(gx$lTHseub`FF&pL6<>1xG^XPt4zNoT_T%(K>=v;yyf?sv|*H7CAO=%1gVHNBLX?+HF1Wb6+7EGw9q_HgP7+ndeX$!?xy zYV2^xiS=8D9o@$?OPNhPBGy!@u7$nu>gQAR2J?6E^2*?95@xB3?yu9z_Gm%4_k^NiL4X028t$r0^!gdU_ z6)$(tl3VfH?XzF29q#X9^{I>MDecb=fsD}9eK_$SmW;pEKKECez4jOIT|s?p7@oMW z$i*v-&%%#-oOQAKZmEnFH!h5Capl#=P+^)SiQgh?d>Qz)&%0@!`?K?Jx6k=-<9wr< z-=?mF_U-&1;P59slYeI>co8H&_prSjfMOATI#V@*jadJcK2@`FM^XF)c`4!uVLfAjN|8 z4d|);EPWY9S>q%BK+tF5ZbI4GtYq*sOk$@0hHpzyEzq-06nh;+*pR#fc*Bx$YHj6~ z^t(Yexg>cn$Y8B!%kWcI)h!u6`C7Rld;A1aCKn{*CqWB)lI^9)vsVXm15G+1pc-kM zKSpk8A90?&8YuScl{FKvZkY_|TP9&Yv#?_iqCdK}IK+II`6%--=Htvuh&Q|z$$XIc z5cBCWhrJJ&n5E1s?i_ZflCjVn5QK|6hb6m-%wcP=qk1q)nOEF7EWL;FV(4h@Nc${> zLDQwfK;&-buw@(&XdZ7C(h<3H*aMschY5kWUFiqHj=n)b$F8kF)Nk4x_EN-mJalF; z?YVQd9=m{T%jU0t!oxIqag9iF14FT+efYiO*rC;T(3O z&cQa#QPY3>=&HqEJ?EZsbI4A|Z|10Yx)td+ZKci}uXe>2TBrSsmKx}*M!Y>Z#zfzCN@Xy>*Y(a?dPcBd%_r3jyY<%{dHE^8$bKJqzt>2J*UA+BuWcsa5*J1JKvbdOIqjSh?`Al?< zn>ELzQ%W6_H3y{Qaf9_>iG}>j2=XHEtT}E2`mFw`{WAWnO0=vuQ2PPv)8?@D_|q^V z|0evi#z*=Z{z&=}L7&#Aj$HqpigRGXg65nPodZ+u$$mF*lWUS`4qWEkkxX;oz>;YW z+~nMlp60+N7bMdh*kDhxy==%Fn3^)zY5#`YQVltCU~fa`z@9Y+_BPTS*u6eGjQxtP z-%gk7wD$bA%*l4=zz5npJZ#MI(VYX6-9+ZVb!yKlEz_?%2i_NR$BA60t>b_&kvZ^d zodbs%2XQML^*Y#1WDZPo^od-j9d0`Z_9rw4#w(o@zD~P6pBQq?fww;}dKMt#Uh@HM z=e~e4T&DUQty6P&dg3FTgV2FkSWIm?CEN0_cgd_d02yc93#R>a7j7-fzYe`LhiE{* z3Y50cA+n4?kbk>5M4CQp+@`Ooc#dy(FP5;RbFR4;Yvu%I%*2bFgK3UHOC9;3b1)ts zR_9@zYREYU`x)op=t7hAE}7?B?~mbT+92AabK@}cQRZXJr^`9>b!O+pxXK_}+;b*< zOWj_K=$Qs0h?NPQGyCyYw!U!G{<=|cuJIOlKB^Le$2TsNBaJw&Ll8*Lb# z$?@6uRx`$zeI2ibo3(-pvF{z)?PpvU%k%tP;`z@B;PK80*B1@LiGM=*QMvLX#4{uF z^RABPXZ>AB?1c9pA)XnTpUXR*pC@zWM~G)e=I7lV&(FVdHPYA*?8O7 z@OqK?_1|;lUx;T$=I8w#&(Gg-Z|?v`GXzL&!2PUM~Ek7d>a)%oMR_D|Lya0Rmb!5r(F3F;+c{8`B2C6 z^T%BI5#pKZ`AP1d6S}_qcrN^|&dz5Fe(m>Pp*?qgpVI#HKfZl98*dk%g8BbLuKWw} z%*gzVbUZ(g<;sr`&s5J(vcB#6ry2ME+CP_U??%r2X5+S>f`9wt<3~DPU%$^)UqU>| z@!9xgT%XEue|z%Vw}0Pc#6Q*VUtiPl`g$~1eF^a-^FIUf^U;py=XbgCBg8W!^E2A< z{5+B?KSDe+GCv>dcz%AHD?dU!GcrHdc04~1=gN-|&y38^$2*>%-{i`V5YLRv&nG&b zpI_(7j}Xs{%+GZl&(E)NKflP8A0eI@nV%awo}UMEbUZ&l&6OV^o*9{+n>(JL zdvoPSh-XIT=ZhWB&rfpYM~G*t=O=l7t69$%XPn=Kue4#E`18NH@M~n}GX=l)=O3Xx_xPI9{`5cp{7*LC zEscCP#g@yy8le5>R6`Btv{2=UCw{CvCP z`T1t9{0Q;P$o$;V@%-GLD?dU!GcrHl>3Dv=kt;t!JTo#scXm8KW4ZDp#4{uF^WBc; z=j*xhBg8Y+^OL+jFrnwCZp($=UD^3e!LR-GHK9HI!!Y`r(*E?nzV^Lrydz{+8$8>Pv_xSzmU3Hr>BY)~|j4HKTqzegFE$9j~u1<*F|s zo@9O5_+`}BRR6yFPdc8TFXqaR5YJT4Pjdg9(DkpIbK!Syc0N<^Yk&PyXs>luk5^LK zpZ?cBf0~WAi%-G)e<4@?g?MIUe(vjdemRuJU(b`_q5_X=dZ?;!`mHpUIVfA)XnTpPzR;KcCK(A0eI@nV$zco}U|YUe&x%atD?o*9{+Uw1q|pU9OTA)cw8pXBdH`~GOg^~0%t|N1u_udk2isxKj)WPREB z$+*9`>HTYcnPelpf1TVvCUkx6+Fbd6IJ+K``Cruj`kK(51}6HO(*E?nzV_Q}ydz{< zYtH<2Lizt#uKWw}O!fQ##Ul8P=ECoh?0lx+*M9#I+G|w>ucWj;{r8{WW#jGQQ!xJ@ z&6R&4o*9{+M?0RMYjWjBh-XIT=l31Y&qs3QM~G)e=I61F=Vv5WeuQ{tWPbk8@%(%^ zSAK+erh0w~p1-foh2P`Z`AosD{rpX6&z+y7v_JjlZ-30j+r_6~{y&r}|3W-7GCzOn zcz&+Rl^-FV8JV9ycRW8I%#|M@o*9{+zjQo5SLVu(5YJT4Pr>uU2Xf)}*X(?z;MabB zAhhS6|5DnY{_}&sW#jGQQ!xMU&y{~6o*9{+zjr)8@5_}RA)XnTpC>w=pDS|ZM~G*t z=O=mmvG0#g)BD%|=y-j-H&=ZL@g(cZ&d;X%*U9?*4|sp)pB=BS_vETCA)aJ?+4yDD z*MH9Y*OiJc0J=+h(fxG@DrNszKbsV-W!A;&yQMP3Cj-3=>h({eh1s*z;>xR!S**8) zf3+N<#O>SoWE>wi?EU_YIzLXvZ{w2@e~#yqrfB%kHW`Iiyox!_s;BhX9zD+EdUG=F=1)R()^`0DKM z>PRM^2J}*VH5f_pjj+C5d=!hjgxfF(sr@?iQhd!e{xt+P5&W{^8)1Jpc9KKPyX5!+ z=%w*BSzi>t+B~`a5$GlS%JXIafb~V=Yqn{>wwWAX19}O+@&c_-i;r>|us$n)P3W`m zvG=d6`lvrej<3P`toTMYm;KAoXT=xBw1wg=DD-v;y&eziq%d?Tzc8lS>^MH+t{dMUnU8~@sp4a0AQ{j=~>TeXP~dTD$C>x<%7 z+gfga1bPX-@;0)6!1|)`HQTgb+g6UR0lkD@c{{By8ehQvS@~^3FX30;UXHK9`l9iT z>>#&ahF*$KEtUQ2tS=g0qfPte9p(5&pqKKicGCKy@zvQsE58lsCH!hT%khn{zDRuG z{AgMB{F(H1K~Lwm2J{ks&!1&kUx!}mzrp$<_)!1lUFG%z=%xIr z<+6XB^+n@rv}wP*n;hQ=^b&q*cdaiPU!DB{Wn!WFYCtdHS9_`)-w5lA#;5j>+pj|} z#n)`(U)yuT@Ec+O1bEm$_^G|*_yXvq{5Dx%6u;Wua{D9DOZb)dk^KYK7mcskrv2K} z7hfL_9{=F9Pou)b(~3fJ(Y@zqegM4`pE^+Xud_ZazHoj7{c3=dr7u4{TW?=Knw0`D&2IzvOZja= zFO9E$kUT$cw9%KJA@?7!K5hK=_-HKdLfe{c+OO5*@im~A@F_o2>x;%0u)iBS$&~*l z^dkNT%keb?{Y3C9A0oFOKrh9o24(*`>x<&oXw!cAS#o?M&`bFxCFzUC*JOXnr@K&o z>(ER1)ee>88)1FX_|#!?`*rB0_?m6}YtP;={6^T{#g1gcPaQ7D7eG(>OIygl$@-%B z)t)1_KLWjkU-<~xKVW^)`0CG<+i#+MDZWM<|MHQ#{i5*&?4Ow*=%x7T&y&a3V13c} z%16oV2hdCLsprf7b=DV+uhFLc^3ig9BhX9xhkAk57mcsU{#p60LoeZ1d!ZcP2ieKZ!a{D#tCH%@Sk^KYK7mcsk zrv2Kna(oTwCH%@S)%qgw(fKEUKT@1JzX;Dyf_^sqYA=)H8-ZTL|K;-hJ!qqELNDP{ zJFYlBG`vH=e(2Mx5k^KYK7mcskrv2Ipa(oTw zCH%@KYJJi80`^ZN7aJ(QP3R^3>O*pT4b~TpuY8i+egM4`pE_Cgud}{re2q5kmtP^r zHv+wsUv-Ms7mcsZ{#p5LKri7}J5`Qvg!M(^Q>V%8*P)li3wE1xdMH-h%1 z_<}b6P1YC1uXaY8_@I~KE1xO*2dpm|U$ag7wX@{-8qiDoNBL~6FB)IK{#pA+6M6~1 z`hUssHCSIXzVceR{Q!C?K6Q@lUuS*M_!@26FRzp18-ZTRuX>f%7mcsZ{#p5LKri7} zgHnobg!M(^Q?HiWuR|}z*KFfoJ8#4A8)5$}{M2jY_yXu9{F*A5~#$R2c+bGzN7mcskrv2Kxg=DD-v;y&ezo_@@r|&)NPOY(;{)>iy)Ni!{@8$C!moU#JiZa=SEqr4ZQ=a%gR;I3 zz0`k$^+oWZ{ztBo+b=^ex;(MWdF1jQ~lMU zm+-5N$nlM^zG!^vBXaw7=%x6YZTxH3Y#4qc?4O07`luXV0KJsoChLphR~wbvAAw%N zulzCDKVW^)_?m6nuU#w0*MMHaul#YXFB)IK{#p5LLNDQ0|AZW0gY`w@8@WzyzYM(; zpSoW5ud}{re2q5kmv4~c8-ZTRull6c7mcsZ{#p5LKri7}`;;8t2M-fFB)I7P5ZUa$?-Ly zm+&ipUh9j-7qEX;ew)xs_|?B4$Jbze(fG#4n5?MmF2w-J@S~n%Y7@n6<*oz_WHVeE8Q`xP?%+HDycuLw?tegv$b^HEI!&f z*s>)%P_FSUFGaD}L4+O2JAgMVc^THrXqNU3((eX70@?WQ1(~`r@_rEOmh3}rKsNq; zkZVYYu|E*P({ zw{u9o2D1594#}9-D)Vg|k}(ZY=36%;p=G!79p8(l>D}>}zAe(Q4kbEX&^DPjP*FiSl{vi2$$mUxeBnObqw>?O{2(tNB z2g#R0Hs9tT`EtnSTN@<5AF}zj2FX`LHs8`9c@(nwb_U7ULpI;SAo>5qcXw6JH@@Bx{`Da9hXN}f4JZ%+a^nuAs&-d-U)~Q{)_BnNK z^}T&>-#+Vi&t2y``_I{D@3r??d!4m+{VcHVeL?&Sz`EB3@e{zhw*~RP1CB80ydI4B z6TrGR1@UhJ>s}PZzXPm$PZ0kBuM_%dMKn}PVNfORhh;wyo5?*-x)0_$E1#8(6B-U-A9 zfOW3~;ySSIjX-=Ius|)LHv#M31;pPDta}j<-vX?A4-mfzSoazr zz5`hI79hS0SoaDbJ_f9N0}#IxSoZ=T{(fLx`%nCXz`B;7_4E%>)LSQ=K||m zZ{jO~b!|8CUSM6zP5feDUAs+O1=h9L#4EtM_L}&cfpx7l@nK+HTTT2ez`9nN_-0^T z8%_L1U|kDM{AOTX`%L^+U|q{hd@r!BT_*lMU|p+B{4QW!n@s#Lu&y;GelM`DEhhd^ zU|ma0{4aoY?J)6=1M6B~;>Uq??Jx1q0P9*`;$HyPwY|ju2DlHUM#rxKu&&)@_439M^piT@T@*TND%1>9(i^_N}Ho%+B! z{yh^oe)$+b8@TP@D}aZ<-;2j)elGxS-Y|~;BH+G*uLah%q>Nt&*0rO=F9p`MqQo}< zH&@5`y$ZPR;MW4{+D^v*4q#o&N&KC_d>DP6+ku+^THd3;Lnr)xU|nm;^zQ)HwUxvV z0qa^x;uFBSHj?S#64hLyGZ;IU|p+7{Byv%Hj((3fOV}Q zaUWRM783sku&yN}{!L(AJ4pPyz`E9t__M&eHjwyFfOV}O@t* zf)Rf&a08uP)IpYzW|Q^(K!D90M@ld41W?>*Afw5use!$?GW)ZfORbp@nyi#o5u3@)xf&ehv8ob ztZRFSzaF^J9Jj|cz+GUK-x_edHV(fISl8Y#{mX%MEe-JzU|l;y{H?&cR)+ZXz`8bu z_#Xl5S{LFLu&!+(ejBi^Wg)%~Sl6x)za3cDq7b)%b?pi9abR6*Lj1$Py0(P)e*@OF zBE*jY>)H_Fp8(diAjJO%u&(_e{y%|rEeG+(fpzT$@vi~vS`Fg=0IX{>h(86aYb}U> z2Uyou5dR^tuB9OUV_;o7LHz#$>sklmF97S>2;%<_Sl2obKMkyF8;CE&TwT{H5bpu* z-ZgIjuLRb$2n>H7u&zBIz6w~^5)fYvtZN5|UjnRa1&Eh{b!`CgHvy}!Kk+KC`t}q5 z17P*#C;oO|_1!1_Ux3vYpSTIEzW2m$0ajmo;=6&>x1RWWfYn!?_(5RxjVJyAVD*J3 zeh;wvz7zilu==tS|1)6qT_^rmzzuY!!$?N_zXNw2{83=_HD~z8fYrC0_*a0{mz?f z@xsN(@15iE>tf)>gJb*^!0JoQ_+JIAzSG2C3#`7-#QT8N_nG(`fz{WUI007QX5vG@ z(Ywd>+W=PIWQM;ISbdR+Ujy7|kK?}%xC^Y~-L1g!L*wwe->DM zV~KweSbbrMe-*g@$Tqi9ZjlzNf^0 z1+2cL#D52@zN5tdKd}0O5?7vq{9qK+_P7LCeLWfe9ANeBB>oy;_0=Sffz>yYct5cE zViF$!R^LnFC1CZXB)%S4eJ6=;1Xf>3;#UK!ZzS=z0jsYg@h!mW+erK-VD)7rz5`f& z7m4ozR$oNoW5DWrNc>J<^))2^eqi-2B>q8Q^%W$3AF%oc5`Pd_ef^04C9wJi68|Ky z`tlK<1XkZY;-3drUp?Yq23FrZ;(rUQzIMc)09M~R;{Ob+zI4R@1z3IOh(8CczHr1N zVD)_?{&QgUbtC>8VD)Vy{xWa`U$fVP5%YtF`lb23FrI;e;inSk%%7$j(%d?e}4wJ4Xp3KUjQCD_}>7luMpD@fYmpM_&)*1KRHhSTfl7x z|32{0!LU%=`Dq!^`A$~2e z`i>BP2eA5z5Pv7I`i2nS4y?WBYEw}be8VD;r7eh0AnZV*2NtiBk;CxF%Wg7}{T ztFHy|2Y}VLg80XP)fa-e2dusm#2*1xUkKu#16JP$;$H$*Uj|}++fm;I;@<#PUj^dd z1XkY!;@<^UUjyRL0;_KU@t**zF9GqN0juu-@m~Y0F97kEfc4uy@o8ZF)=#{95Au_5 z`^3)z)^GL1mjmm!dE(~->$iB~7Xs_Icj9jV)^F{^i@^GAo%kTIeoH5Q8L)mkCw>L6 zehVkQ30S{<6aPbC{nkzV24MZRO}qxI->Ql41lDiQ#PVNQS?L1A4Hqevl0J;z#sor^T`w#`5#-m^Q~`M ztm3bB;I`=Aw;ikUU&4Pi{;Tuf68|mp-$DLc;lD%tS6wv!O`57ngdhLmb(5@W(p62u zs!3TjNvkGpV$vq|ekN^V(k3QtV$voiZDP_UCT(KU;!`*7QZs35wy-8`&7`fFv^A5q zX42M7+L}pQH)-o8ZQZ1;+b1n3g8q^+B@b(6Mk(k_{_OD64-NxNjyE}67TChd|* zyJXTXnY2qL?XpR`Y|<{9w96*#vPrva(k`2{%O>rzNxN*)9yDnWnzRQ^+Jh$TL6i2N zNqf+wJ!sM%G-(f-v@0g?T%r6DzxkmEFY3ZenFOv9g<3*-ff87c0AomEFY3ZenFO zv9g<3*-fnMCNfUSK&d08k=;bbN*OF=w3Oje#!DG6t?VXNb`vYRiIv^N%5Gw1H?gvt zSlLai>?T%r6DzxkmEFY3ZenFOv9g<3*-fnMCRTP6E4zu6-NednVr4h6vYS}hO|0xD zR(2CByNQ+E#L8}BWjC?1n^@URtn4OMb`vYRiIv^N%5Gw1H?gvtSlLai>?T%r6Dzxk zmEFY3ZenFOv9g<3*-fnMCRTP6E4zu6-NednVr4h6vYS}hO|0xDR(2CByNQ+E#L8}B zWjC?1n^@URtn4OMb`vYRiIv^N%5Gw1H?gu?v$9*WvRkvVTeGrTv$9*WvRkvVTeGrT zv$9*WvRkvVTeGrTv$9*WvRkvVTeGrTv$9*WvRkvVTeGrTv$9*WvRkv`Zq3SW&B|`g z%5KfdZq3SW&B|^~-uCjkm-oHC@XfeelUKgH^W~*4Z+&^~TiLBy*{xaGty$TvS=p^w z*{xaGty$TvS=p^w*{xaGty$TvS=p^w*{xaGty$TvS=p^w*{xaGty$TvS=p^w*{xaG zty$TvS=p^w*{xaGty$TvS=p^w*{xaGty$TvS=p^w*{xaGty$TvS=p^w*{xaGty$Tv zS=p^w*{xaGty$TvS=p^w*{xaGty$TvS=p^w*{xaGty$TvS=p^w*{xaGty$TvS=p^w z*{xaGty$TvS=p^y*{xgIty|fxTiLB!*{xgIty|fxTiLB!*{xgIty|fxTiLB!*{xgI zty|fxTiLB!*{xgIty|fxTiLB!*{xgIty|fxTiLB!*{xgIty|fxTiLB!*{xgIty|fx zTiLB!*{$1gw{B&(Ze_P_Ww&l+w{B&(E;_3yt)jJx+Nyf1(HZKZxr*v4x~nL!R(9)F zcI#Gl>sEH_R(9)FcI#Gl>sEH_R(9)FcI#Gl>sEH_R(9)FcI#Gl>sEH_R(9)FcI#Gl z>sEH_R(9)FcI#Gl>yTY%CgPsI>HfFA<90LiS@_&Sw2HaR!mcQ43GWE+2_Fa_3E#J1 z~yd%6Pd?dVr zsi(P*@Kxa*;XUC4;UnSuV81l?5#AEs5k3$;5?+CQ%G^hIOL#|kPxwH11@;FMU-+u< zmT=lz7(Ng_5?;YP*`yP`D!e6}^K_F=_(*sKzOp8r@Rsn7@SgC2@XDnUU-+uU;UnRd%j7=7SA}_S!Uw`f!Yf}b_YuA-yd}IRd?0)zymE!46TT|EBfKYkAbccz9~|&a zJqT|J?+70V9|^BKPwpeUCA=fNCww5h@_dOed{uZ$cu)91_(*u=N-3A{mhg`7p74?I z%Gb($gs%$k2=56W2pTZ zp74S2k?_h@QZC^w;T_>U;UnRd7s`EvuL|!7?+G6W9|_;LSMDRcCA=fNCww4$B)qau z(g|+~?+EV+9|^B~y_8S*s_>5Rp74S2k??&llKTj63GWCW2pM|ewk zNBBVaNOTZp74S2k?_g^DVOk;@Q(1F@R9J!OXNPn zSB1BPcZBzZ4}@11C7tk9;Vt1k;RE3#;gzbCPk2jsM|e;8NO&cY`v_kZ-VxptJ`g?< zzON?t5#AEs5k3$;5?-mxeT27!cZBzZ4}@2iB);%f;Vt1k;RE3#;gw}6m++SGj_{uF zk?_hvxsUKw;T_>U;RE3#;rmwPKEhkVJHiLTN5U(Iag|~!vgb##|gjcSYbi!N0JHmUy2f{1gB=Lo>3U3MT2_Fa_39r1& zrdt)>65bKs6Fw4N`DVF~@Kxa*;XUC4;UnSu8gd`uE#V#E1K}g#m6ywXgtvrug!hCG zgja5m_`+9(w}khE4}_0|S8kMY32zDS2=56W39qcmeT1(H?+EV+9|#`_-}ef+kMNf8 zj_`r-k?_i4xsULc@Q(1F@PY7=@X9MCo$yuR9pOFU1K}g#`;JKYgtvrug!hCGghvPN zfBRj>*4_+$>^{ry)U#u^KX5EM&{{jT79Du={r5))?z_i=`))sKE+62@(R*%NI~pCh z?Vh{ty8Uj%zx$qJw;#Y-&};8MwszawqIJ;o5qAN{Zb^e7Yl0X?x(Wx+cM*UZIG*@b zo>_{8?+3pahsJx#iNh$GA6{MN`~qGCG2TV?)cn_Y7;+}=8~>X9j;T>&Ibpe5Jo?C;Or730icC51plNv-4odO3{7(LoF3m^ocOv@e zBTXbuuS>iOOht}slQ%H!|R!infpl^7>}x$*qZu6^I@D7Z?~^?TWL{%Jl^AKCJt*{0my&#hlK|BU*5D7rX9 z-qL*aWIF%YDSt-($DXME+lar(3LEy9n!fE@@xTcZwg`bbq;M zn#7Bs9oq~sUKk(re zh7S?W{IkLvh?MnwOyA83&#HGV%H?{J!9#U25p@gpo?u*uu8F<_&Viln13)PB`qkI_@6mOt;82_E{E#YSa-N zOs+a^0|P=49rumiz@bGTcP0H+#N!?n9J{^}2k#ryaq+NkLYR`~=j*sF6nae~for_6 z@Pqu9_Q5(5B?lq$0US}WX_I7mHS23m0bxjsKP{)1UY#pg`!82~g<69kf zL+jI2s`IbZaVO_gPSx1cQpZI-Xg?m$5mOx(HrPDUG0Gb<(}4}oWz8j5z80j-{DXot}*|%glFlnLxeN`tndah$$CEK z-^~fns&^zabS~<+lm+UPMRi=ZE#vP6?@L<}Ukw~f+Yp~aI_}b$>bOgej=NOqxR3-( zI$m7`$aD5DQUgb+$uD3oQ`{udC7^6dq=6`+Brcb`oSN77*(2-rFH4J zv+9!>x>V}8rH;G$dVfwj+YX)TxXZ3IO`q#KBTLsRb=}ixq!GeHFOZ7m2oUZaQ1QSD}DTc8&Nd z&_N8@zGdvQP}*_n+fj+0@%^Zm!a8p8`eZA*RO+}^$9)zm#e93`2T6ytZ&$n-WYbSLf#QgUCGMsboY_^&A?fYOcooW2V@Svk3 z9dvah_}r}`|9QT3@04%apLCRf7il2uYD|+JEQ{0LWL1K<-q7+4DHYMUD~tmd#|LZ`x0x zP~VC$CC$(Oru|+#$C^e0*LY(IT{-u3AwJKYr7mQf71CpT0Ps!w)wpt9lb6@0TQWsX zeKOdkQWx@cAr3MQX&=jar@KQz);CdRw^P5#y3b$gLSetbdB3STVz}A5(8_vsp%q6L zS}Ap*RL5zc(Mny&>Ly#O3mqz?3t?BV!giq*8Q|Ap7h0UXhUL0l_8Z+R1^tz1b7|vX-4N5qe~5#1NlYJqtvh0u=CMQUl?<9_585GK0?gmAV;gvO zh(j6g-tn~Vkn^%VWM8(-X91JkRdO_ZM|e;8K=@9vFFdB56VDanAo=!%&pL4!uF$tH zFkTV+0>yysrxeSHZ(lfBF+WXbY!2+#fI*-6Cfccpec_$#$PQ@{$X&^N5b?f%Yt*}G z%jJDT_67d-R0Cm3nxAi9_#MPs(@5YNFBQaOvCum;!R~`azqMQ@4Y4`zRR3M7@7VRc zQ+M3D(Pj~!`l~(&0a$EO8rGr1tiQg`b)7}lsk-Yf=UO+a-(s*g-~?$O+&yu14A|$D zvUCcD^F0_M4mE8Yd@p9DA4)jb6fu1Rh5P_`W_pA({}6FJYv3Q>!y#h+T?r4_7u@F$ zg=f{9-ivxc9)+H1BK{VvTVz}2=`^b2s7}MSVf?+|Lum_Q`gAv>Zi)FVrt4t9l;+Wa zLf>LOkNnwYlR6MyEQR)nciu!}l_*&(?GF?7hf}CyrC3gUUFjNjEQfTQ@pUD}E21kk z5U;D5Am3Q>_I0JB=#UMB@%s$>7G;6oh>qZ3avlDL2q>Z}J?Rbrk_VW{%c+LwDa4C$ z1C9~Yk(ex`D_x2575Nr(67klMhZ4(98cS&P9MhH5-k>^?zROEp$+qkT8GAHTE|^bO zT7P|)y3*vg8f>6ELD~n=HG||16`}XKju&?XQ_K1^gz^2Fm3}DUU{k~)w}C?PeVmyd z;mkioEMEiv4u=A9jrn&aJfsV`&mRiUsyDq|sVj}`MO&yVRoAO4Ro%BzsVkMbl5}Vt zFUfW6W6;^xm6Bq*5`J~1s9ou2WiVTZUFnM1dof^LnxWY`(Pn+ikOE)=HN9V&W7o;p zOX7_78=K3nk(SpxDRmi7m(j_x)RXqjtaq~eF3-{>m=*W_2@!RLCXPH^rZ3@OQ^fR~ zPf-`ix_=wtdAiI{(obcM3(Q}2osh2LK7S}YtKRfp=b|pdwp6=M6X&d3;;j9u*ftE` z3*MHtAg0}CD0NRvU8W&=Be6>xW%oIOY}sa>-6vVEF5~>1N0OAf%!DrUUZ?3|X++=d z^^M>NfEoxqwWBJe6Hyp;65W4ll7oY7_M-l?T7WA~Ev*E|>B+q2YV zJY9x+!8)XUBkOYnNpV#Vb$@Hd~0=?g8RU41G|j%p)GZpQkR+92YoKP zRqBsp4T$M$MEho`%h)+pS}}6szF|wdOn5zz>L%ORE>mz{@UbpacXXMFeZcpOeUw{} zkvw1Jk%a3$;5)^4xwOkz`^?trGR5}$t{z;mKW-Dx{!N=JWcskt-8$lWO~lFjM$$((-xnd$Z!k@3Vq8!Jhq=wEGHb_-ESH1MPu+A+N^IG4Rp{V-!k6Fj_i;Y zf!uv(-iml%z%}-D&QB;4As^P85YRxFlIG{H_xTv&t!X51jW-s=g8K(2N#S?qr)A=_ z(eKRTtcF|a^mYc*I*!PAZ(Vd(}j=}(RF^s9RQK97J=M-#3v9h#zl@Hd43z8#UNJ1 zZ{sMQV-0yJ>3zo%T67=Tt=Dya!_;A^>x92`R4z!?sq19bXQ}IWy3Qu;6I<#!Ix0=_ z%O~L!3h8eXk+xuM@($E>*1Jz^;_MTfl>5Y5UvA1}14pUrSe<8Ub)BO7#BQ9f6L^;f z>=6F9it)a%_g+Z}GQV}Y`ywtF_h_@eC8W1G`|E8sz^+rgJ_GIJ{(iiyC-U<<5q+u> zql$dr*$WnAUzD`^0_&Arzl@CaO0#v`^aj(vJ?iG4VHcbB@lE|cHfbN&QrAgaY~rNU zb;drcT#vIwcAfR^1DiPez$WEBu%)h}om%ZHpG}Z zQ^BR*$3iszo$b``<1Fp-n)NQH{k8P_xcZf^dEGa}2M<&aRO4i^dT?>Mwy2}SnCm#f zE0yT4Pme=5mb#(D?npwsEBXpaFw5@1?^XOpvW0#hGxvE-oPA!C^K_rr((hy1K5*9k zK57N`dEMl79|iVKm)<{np11?;19Q!9-SO2u59loC_59y|SLvGwpAm!Pe%1`x<@L># zr8D4jY}CX-zl*H&eF+DfBBqZ~NWSN?(zg+w=hrcm^i!GR0`qU+A((&Z*I{dDmd?St zc6AQbLH6Rhwgtnt&wd;j_}8}&E4oSg1-(}8!)p5prK5r4z1rz<9^)YSejT55;xHUt z(2(!f!FWadI);eX)l866Y_mIm_v5G)+=q1==rZMg92C~9eO9M!^&;9+tkh*D{WfZw zv`=cO%S?%$xo|#w%Qy#gnf30Iif%I2WvbEp+GSK$b-W~pD5rGxb(v!Oq;B?p97S}QR~FV~ zP@SfNOTUbeUxu;Eq!KrMqOzIwPCCXanoq}Uu6UUkQZIt_QY#(1y-*034@5g}`!#eE)&VHS>a=*?= z`@l(OVjQDylYGC8Q%)R)>p0{4Z7^ODzYTtDp&dvmmJ<$V+2$)a__NnKMqJF$4$JgQabBqZV&_3t)dYt97dzzC{*MZ#$gBE=eLVg|Y zx3W-pmX4^kd_MSnoC9{9_3pD;TXsHGmHVugb{*}{I$mzQu2XEE)s6J~2)s)R={jnM zDEH%dy0-dyM|WA^H@oA}NA9F_`Fnp&@5fQ|_6=2;RIaj_^-gl%WuZB?>h4+VQA)p$ z((i*Z8-wtjR{6%%}AGDE&Up>hG}BitX3AR7)0PL$iOo?DNmDqp$s3 zes#1b;_gWfP49QKah_plJ_srKLhRKw7)6diRf1^>f$VYZmHLz`{nxSQoL^Y zmHl~()eo)X=3DN1+JEYInBDr3@}}jN{EtV!{oSl6|9Yr@oZI;a74$so2hfYQN9SwKg*`j z#zWlg+|xbf{W&bs<`7D6%9j&f#HP_l`n>0lag#j1)3$`W<<@hSZ-{?+&)+~HX(JC2 z)Atdcmp(?tuzVrHqeX3m=RMz0!b9ILc>l(3n}1e#SHiQ}hmLu9_18o=+dq_^Vp06w6S>>nWAIp~&-jwiA`AqxdgrjP5>0JE&!@A~vYAkyb2kVabYry*s z{yLn;=-V29FK}D>y6(q@WTtNu>wfI)>%?5Q+ef&jr+HKRBEzp|erN!_{|&&}*BE{T zxFLOunECdlFA?7itbK?04Zzx0h?~ILH;C^5ZtNc4k5i1UgYN^5L{=I90l=onHZlA7 z&Z@8b<#f#d<8lMpl{PF zxPQG_--UmNxYDb-X#Q8t|HS;Sng4b3f64qe3&W~rWmt8^Trp`AlQuDF6O%SEX%mwc zKR}NB6Ze~(yR2+tzkF;My^7~qfZVi%cZBzZ4}_0|S0J;Dzbd>Xyd%6Pd?0)zoYN?# z+b4WgcuROkcu)91_(*sKX-#_JtHN8tJHn#__rLwFV{2~)KX#wxck0=(+aEX<9cZl` zTZ<07`TqN(1NYry!F{(MHJ1{a}YefygC-I}spOI^P4=@R*=p191-y#lD`_f{+&-f_f zxuoSI*Joh(V~F=!TwpQx;^2L0T4LF>?r<8N!o^?XiIC=pVo${Dz#h4#k-#=R9WzZ-ZcvPAqau*wdxOY_*U zen>LtqEpa@^+Dhhn5a_*J-@W9--&`L$=H*ODazQOHphJBOt~Fra`*SBU`$y>xoHDx z3GWE+2_Fa_3Ezitp7B?Ow}f|u_k<6GkAzoH^~TmDyd}INyeE7hd?ehrQSB64)O%^% z5sHQH2j^u}uc1#mad-h$X~?%lF&;!dC5`9XqK1e^xmAkg#J5G=j2~nBIKpTH;@DWh z!J-_&!Msyj)SiO2D8zF~%SVo8PU$hky9^gN#>0$i?i;d2orKNm@if)AUVK~B9wc51 z#7jFyz1Z(#EhWo^{qau1{zWQnQLF{^8#_Z=)Ev4t?;fIg=R)U-KVHCJYeVPqrN5lr zyCEc7=GwHsOfi2sGboA;WF5Ase{~D*n(Ht3fMd%M+s)*Cy4^~2`pd}X#Z6{**2~MA zDh2wdYYP$EQ0b3Hi>>%8yY(~KzI?kHn{VllXXQ)l!_aSsqfM@SXbqGs^aVg)t$3!8r0R5LUs++w>ke05vK=D99gy^rteEQ*c35+j6yR1 ztoyeSo@FaC(-YjJh^;VG2P|I`|MH%%kMO+bi%|%Mhlu$P5uRrYY$H7D`T2ZJG}2Fl zXVp)PfV}&+5uW#aLkSPr%6NaZuVjU*y(LsWrsrfctNvX1GjSQ;A=5rcpVj`RekFe= zS$fKFwdbT4ofF=(i^(eMC+qn*v1R$Q!kZGF_5A&u@ZC;XLZ_iTC*qa1M$>k*)!m4S z(Y{9fDq!t9#I!YPUm>QgQTqllZH?L&h}VEs_KDvDtg=o_TcgT0F>Q@akyT>a8iyjA z#I!Z4ED}Eqtg=UJY=t5##6QCP98BAx$`Zp}n#VTzW0C>ujJC-S1Bd;aZ0`pkttspKpset}MXebCn#=*Am_l-V;6$J`%nU@0yLUSFWOY%zcG-gwL{9 zmOgb+v>85ilyRk4PJBD&1271F8e!;i=ndI+%;u%V?3nLFJeMF^hREIC`yk>qaDnfa z7viYk2-z{8z{Ouin3Cq_+cA&K@~NvA`)%C%!IgSZpSn-8z@XBO$yzAwn5+etN}syY zr!KVaH!_3RqQzxdHhpefGA{XRlt>o^846YFYDr>U>I}IltBL&Wm6@h|WBI7i5{(>3uBKaG5{ z>L*4(*8N%kZG`7N-%!Fsb|$y}Lg9QqwN-@5$8fb>WQD6OBNWc^t8D|PQ^at!bxZ}~ z0>jnz5ehfu%dx}Fdj8#^Or2|?XL5q0sI;RQ+2lLsMpTUU1>#o$tLzhRcRQNfuJhQ% zLOy$+hip;?Cw=xXk=|On*x2$_b*x}jYXxI@7fPSKEn7c&3NoV<%gKIlUgmg5x`xIk zhg47SefAg+rsR|~p6|2QK)kMIj@YrJ@NHcmE9kQ~Ea<3rwaP)?Lqk-PoEZY zEa$$h>nQ9_Yk_#aMxE&LJotozpse*}<0c*JR+z+(Adg;utxk zawPG}J^V_a!RVZ@wSB5W`Ax^Ab;_@wF2ypwo&EK(sSg|%r8%U!VwO$7wIzh?0<=|- z@@zFtgy-3!`VtN{MO4pY6q5O8-M@|Soo;LU&Z(NQ7mTe4jg%MOMR=C2%}jq#u|J$s zzg>i9r8n&l;mK`(2@l!gT=@!xvwVG|&ypV_AL2I@k`IQrbHZ8vA;Podhv7|3Li3)# zkMO+bk1@|=c8r1|-FzB_SYO(TJ8ym3dVm3F>@zt5Cb|waibpI}9N5tT|@FeV%|9s&|oMn)G4n$qQoi8_E z|8{A`%{X!DRZdGgU+Gh~`g-49TYPPEKz>R)-xm1PrFOpBWFJ=@Fw34mol_}fQ&4@C zbKMY8Pi^AJvePhqU&6tri0NY#lKE%dzm4!LJB`tkag*0%q%ZP(O{C9zzCOb9o-alr zvg|}GUmO4Oo^P0wp7qzjL(H=CWrg$ptXSGIvg)^sfUNTK{?YFI`e{n|Ja#UYuaERu z^~-RzorKEI@V3}iLg6g`5aC(!!*I2=;B<-@uC|w{KwL28!-S3PJJ0ju(Q_&EOcM!8 zJD;h0+QDu_#b{q5eig9x9b)?Ab)_#6mv+8PJ6~;E+WBgZov&8f`OMEi@RuRB(eFW& zc0Ox&Gw)3qsL#HguU^c~mn4OM58}O8FH0)@`B)33KObwsrOmeUZFc?vJJ5Nt$KN)# zBNn#9UGj_V==Wc}>(#k-xOwe-S4Gh!AD?A!Lr<8_zpx$jl3&a++qpf=yjLdeh+}`s z41eHV3t#*>=F#N8jjd1S=up58w88#@Q)^rCdjYB4YBT&*H?;o;e(%7opN#Ssx5J(5 z`3K~uv?FeT9TCHw-80WBdT9@b3C>WKy`qSnjTz8R5+d4BnmDrTK*kOu;b2q5^qXl% zH047f&cx2xNBX?yk8zW{=Wk2+)WhQf%QwV7<{z>dvHsK+g3~EtxY|ah0&#)i%s9(V z=(az9#^!&VkEOtUfn<9p{CEPr#7lYx$oN)K~ z8P_M~*??0?o*j~Q#=PfOpD#aeVpD#xLx!H;Enmn^8LAWaKA}9_@SV6en0=jg!UVjJ z2Bho}`@iQ=^fztQ|B(4=Ut@kZ18d(RegmNP72+nt(Lj_9;yb`q)`^b-_Ytn;yAN1p zo#77vt85d$3s_~DxC5-RN&FsQl||zB0jum0e*m~GvPSIEJpPCLOb`B zjpzF##)wB5SBm9?suqjW5PS>#_&zPyIPNkD%XI_?^HzVv#-+vl5#NY-E@}D5-QIgE z;x%xAkNrX%yl==K@iAQdC4?zye!f5A)z6vbkGNFKPFb!y)~XKL8Lk`K0ZMe_M~4D-AlFVN_bb;O zm%ml=G<2bbg>iqhLKKjn(vG+VcEr>lamnf2IMsJErmI16)MHMGrwAjCA z2j|LJ>H886HbqPyqmax$D}5W`cTc6X7nq((^=rUF>5DvH6Y2AwuaEG&=ZjGYhKGpd zYvW(u^9>Q6?Ea~FV~Kzwu-6B!v(g_`E2Lo^Otr!D;elUDOIAsKAi%b?4rWu&@Ll6;|seG1KV2} zQajt_KusKK7yBBV_Z`eJCzifTJKA30HZX0f#8-p!HnhPLUkly@*8EF5UNqs)$Ldm= z$A3@v5A0)5ow0x5^0u_&EjxC+<#Wr9H-cQ#zL#asEA4pr{SXK@M!GCcy9ROue@^+j0Ll#JP9>e!HLy!)J@U11vdH*V zfzG@TY5pbOzBQ23_7XJt{=D#GMc$w9Dc@V?_bbah{dqmOmJffy_8s-glKC|deh&n` z!=bC$3 ze#akwTXgG1&-wYFj}H%dehM)nF+4;}-^M?FyUg-)7$W>#p~Sex^i4Dp!!y$({IGr; z@$%v22G*pAxMy{rv1&nMxb^(?M@ zhQgV?kMvpX!|?bk^TXRY;Vl0U;koO5@WDIp`TGcG`-jMs@3}TS^nA0PKdWEsy>RPX z3bpA(f^vWI)bHR%RE+jj`Xz8ZkoHYtt_K=QUnJ&wAnkj^=649CuMw{yT>BRBTZpAE z5#I%j73t~y?+0u;n7>1)vd{SM23A=oei&F~o0z{tsIpA_Bfw3OU1ItHsH_tI7;r4I zN$k=*eg;1w88lEw^fUMw;5(5&W!&2*=-}D#GpHVlxE0W%`Cm2v?RG&ma~|3>X#7)b z2OXb-gO1Mu7S68XdH7AgCA=fNCww4$BzzynUdCS)-V)vs-V;6$J`!F*lQ7*r;j6-1 z!aKry!bifhd<|O2i}`hg_k`~l9|XvnQYJs+ebNNOZ%kjp!oyXnfBSp7AesRT}*$+KDl`Ro<1M;zJ0oFi-X3+T8C~o#WH7YM{jL0#=-@=D*3;mh4Lf)#5Y#V zf&KiP`onKDcDu);qwHMcH5^io={+CDYc&>)FXwQ&9 z{kZu{y7YNO{!c__uy^_`MfR?~F}Gc3wTsrH&$U*^d_2CT@)vl1r+%4q;Y9SZi({Om z^&<6z{$p)kjAdzB{x*AW?G4@=ytLsN{oSm2n;w71@{^9gh2D=J{K1Bi5BL2j5(B1k zHNKK{7Px<4{GXQJXZ`ywvh>I8Jo!zZZ$saYfwfX|y`C2&SIb#zBAkQ2HYI50UmTju0{b1|A~IM#J)TB|IxVl~(3IPx(S=-23qU zP5k>#_o8!7J)ip_kv#LNxyJPUob(KjQ3+W#B2)ho9x5x-4`-z39OH)(FEc&Dv+mFQ z8%UVfeq9Nl$415Hqwr?6Kf{|d!uvVlrhd^#ckn&|Vt5zfdC$+u*5N=}UNYsA@Ohpe zMbD*k(MHF*<~xODZ{yIlI$Y~B#KF2`IHrSX-zVM+tbLvMYGAN5{vcYDY*(eN z45PBz0ylInP}<7!ZHWO}O)*;*I%DP6+tHEVuKYTBR0c)Sj?dLaJz_vA=e_>l><=6fE6px=`Y-`voTiKMYX@hN9+&P-h zla_z8ZE>zGF+={&$KSb2-yfx|?DfUJC2f?gjQW@HcRMuh+qPF&oHgfm)Jvl~PNp8~ zdz{~fh`MhZ$4<4CQQvLiUzRP5&)-KlhoG0^@QLYTL^4B^9|&yf5C8IPRh$E4-Jkil z5uTMl=NW3N)KP$)^&82t!rtqn62wjHHi&1pZV@r+;kW-%CyW_kBo6~Os_5d!ep+P&Q(fV zS9dHQJnMF?MN0ev=lX6xnWKZIZ5hREB@p5ZUj$p%eHXq6BX$Oz$F{ClvW}blx1sgP z3|-oMThUp!HEiF#e))Y`(D{D>Tw%KX=~eD zTbnavO*8}BhxUZS6IaK8?K70{Q2R2Rwld})vK2ABE8$t`^K50Vd@(PdSbo~lvgC{5 zLxkr&e*?C%yyx#qcxL%wE6aO+`u;FHD}6sF97WHiP@WSBN?V$-L%X&#wuNg;W81s7 zG{x#Srt#HpOz|2k8V#iQEr2SE%#VI!DtpBA8&g>$R=+X5pZbkyeh)K0kqySD-_>(>CiSsZ4R5W~fo5sZ zTG(v47qEtH73DWJGvPhq1K}g#6};SxtxR}Jct?0o_(1qbcm-9@bo+#_3U3MT2_Fa_ z2|r(KZCBE1ODGn;9~`0_=@@>i6NgbywT67ZGRDL3o07)!{mR;iM>$rC<;1tOT>~3c zA7Q*b$Ic24mg@)(=B?^bqo7~e8w>iC-HLcI0Gb0 zwRI=!se9IKZIg4ftlty6@CVw_?>+m%A3#sZpe$Qkn!n8DCgcbG?s)W(J6Q*5ymhW& z^wXtS?sp>k=p)TQ{#XMA(tgi#60ng{v31@uy@ofqZ<#FnliLr+9Q3q&zkW8xRg~kMm@8QqqMbce_LC~mgcs9D4gxv zfMC#m5RwmucV~o05WcMRl&>bjv*e56LrIU*DPp+VKc)h4!ITe^y~8-qdOl9pSiY?A zri5obe?KQ2MbD*Bo)Za5TU%*sgFx&u7KO27?1BYj9k#aWHnX)=9a~#|=-A@RE zxY@^O+7`53_OsgTHK^x){@T8&e3rJF(pJ-kRDiaxt%iF^7{92*6g2bS`CzM|ivj1_ zAu@AyR08Mfp?R@us|bZ7>)bVn{N}4`{9Ya?0Mqw#%E#~+g=G0c#PYZCFUywTmOsnZ zFqHJ6=VSg2WRhn~=_34&P~mXRlph&q)jz}A2+w=Ip@e6Zzp*>}`C0z1gl9b;Kg?%6 zACl%$D9?!m=b$ZxZ9%`BtN9=zo5a@wHi5a`m6$_I-wD?>fSSJOepjq}=EpUFDoe!l zTZ&P^8cx5Zw#Wj**MNr(ehaY50>keD*0v|6-;%a9u}ky#9ntTJ)P#`H@91Hi-vU`; zpY!~VlCx?H89PrTj?E*Puz6fDzkg8&<0WkvJ>di46;x@SKT$`*d%_38N5a+Cu~XLS z-O9mVC>FjS9H!fd;}YpHCk`>H(va^z#CUF0jpzFh^%05ks1(bI??3c0`0;cRHp_n~ zzNFY%y_X`MOIkj1G;d1RBi;}fIhMo4&GeO!|In2v-v`oE<9hM^hi-;_VJ#4E+y!cd zY#PaO@!yd@!3G3n*)+!fHR+u2xrO}^E^SA{Pn+zy*||CK|ApsN>34Jae(20OvB&u~ z_wRVcZ2yi*^yI5i6O|^b@(dY9(Wk#CR;`Y0oHWcqA; z25lG6k!!w=Y<}8krh~rorgxOxnkc)x&jNgrSIKeTmhg`7p74S2k?;!2Yjj!RtHN8t zcZ!bsS=5PAEGPTHT^;qxipH=URba^1Q5mm@j@m#x%7aoYC%%sQNn~~l!e;5H5js5W zT}sTF$F~XB>(56#m$V4vuB2ayc(27pj!j>QgO4B5QIDd0Z$g-o=I86E`%sx{8VOwE zjU~5UOh>IAD!iY>&&so|Lr1-$kdBJ-U--OsbkSd3_&h#}bvAV#PEL2Aj#|h^cK3{W z(V8lCP`mdkrg>JUvVyABllBp>%ckM(kQ92KYk%hZCPW_NC7AGGurH*|N<%yI{ST&f~l( z937|b>NtDm*Ku}=F7sZe>0)U_Uzho$6NgdIM237_hVhE%GDE~;J1fO*1t_ID-C&(~#c!gH)? zByf#qB{X@{;$pG&dez0G@NXvWlLxY|2>Y9fe2&HBTHJ12hO9Bqtt!speacFw@wU@g zsAVFbXKcb$$WR;qIX0=Rv5uUv$u{I|GT0d8p4)+kX%<*H2kw9SUB}km41VlB%kR{) zW4AwWEIQCyJGK@bc=P@DM+fe^$AbHAKWZ)?;K|W@Zd*GV9k}hDyY9OEZp6R)o@2Kk zc;#zeckTVh)^2+n?ogQcJd{aoQ!6v$Bv)5l7pUS+RUP{JGE{GSDG?4sv(=_$=_x;^6qfd$V3b z`T65V9|3C`30&ii$B$w@h}HUH;qjv@jqHveP7xsZfxWF7zCAd_Vn1w0 z@Ax8fS=jrExBTEoKJ`}SG!grzyGlyXP7qt6Ul$DwBp8z6H7{>w>!C<={;ms*B<@rFq6@>awIE4vx=X z5B_l+tT%6bp8TflbRcJ>p8Vzufmua9t{rSAjNJ`9(-Sz9Vma9l?%J`Q(g?z}U-)A; z<&#|VFz%|}j^a_4!trq{*`hFQ4vc~SQ9c6v~nJ@ohBf5yf zVQ3eBFMIz#K@(lq<^}cNHG#SRFt&5wQg^NThVIp{+4+axefsK=!1ekZaG=pM7a)vY)>NX@J5>MOKUAp784^CZgmYJ@52Bl-HuA_j*wjRdao#`;RJ?{3wDONGC?eTjtzZC8C| z{Ju~1rF5TVGniz&?@z7cec$a)=tJ&$sGx5e_qN#gVb)qY$ChOLV5XZdlW9Hw$Lu8dN>$#B3P^ior zX81OEpR(@U_bKa&Sl_37_KkR7@_kH-QJ;KYz69rw@BI5qu|JgMbFYlr%s8o%nvl zThmD38gKkgTq@>^au&8Yt~+Rx9eA8F6DJ>-55MQ<Ib`-~)%e&0y*ck3skeT#qJ z;9YRP_1C}m{p2#_V|1=1DYq~kqjpbTP7%jMrI3E2i5+8xwA^V=yp@}3HwMJN{T z>&Q1baToz@fJ5A~?)BF6iqd%l^ynv2OAB%2xLI-hms7$-lQFb0rhw65x?M`#+ z;6-)JR7YE9{d^0GKc9|YOb0Be!;b4`o#np?<=?%YIm$Zo=fbLs){}oa2X*BqLq{&> zK&V|%)|ybv;pUg0srsKDA5KKS*=yqd{y1XiKo}1u$QvJA`47%PyWNMPKPWi<@J4gx zU$p6c|4d3-?=>4Z!p-FMs+f7#qMc?>i>d)jX9jjX<4G=|Vkmxay0CoontX z^~5F)&bu@&PE+EwK90QfF$$TNzK!s#^vr)aBfNn~dFi_|!l?}BrEemfYR(LxnoN0y#&%1vE4V#yLcSd-$J3oChC!FQ$BRs2o439CtVEIDC`e{pe zsD51e4cSmaGVR{S)F1NCD_;Zin!NILC48Rpp=xqzR{6KW4~KO@n@Uj|59^lk_ky>j zuM%GkJalkT8;{;!Z9JO)4aiUX8uLE_982FJrb^OwFl{zN={pR61F-fL;wG^64dOe1 zBQ%)a|0rP7!S@08fwepj0IO^>{kwowmWeySLyA1mT~vW@vsykAn-z>$)x_AZ%uWPV^WnC-WUefm{|C)~WA3UNdskxYU5WjD zK@&4EF_VLi)oa;3ch~TJ?dI9PdXP`r!3M%d!YgPFUgsJs@>St2;T_>U;RE6HX*ThN zw}kH$JKHJ9lTs`v`@wk`k80=|`K~E2LY3O<_|J1xl_ADM_ee?O`TkiA#G_0r#d1QM z5O38G9K*Qv3Ax5`m2%H=9l^o87jcl{XBD%vy%h0W((<{_!0_u4ZxIj0_tRB4c;Aqn z?dVrT(a$4HN%QmVY@bKsHH`$W@y2$xgN5vD$-(0OHB%|F9j+FLyfMOMM~E_4-?{KR&C~%oEKAGXNnSL!iC{iDQ;hNGH`X z`wordaSqRI9Mr*_p&G~%uMKf9T=T+dN_-D&ls~@vEP4a?ntQI{p=Z`Ga#Lpf%X)sd z{GsP(`ZoR@b~AO(P5mI8x@D+*?lt#ZvnW#j25vHM`FHD$GWe|fZ^b-@&q}?TeWHzn zvPXQT>j^lI(Y9oM{8l}bwj-wgqIFH|(mZ#fo*(yn;f!R<5yMQcgm8a2uVv$oJ+)z0R-YBX^1u zJ%)GGu>jf019mf1HSZ_t7r$Pvt`5&F8ZjnnxAwAAHJwf1-Ze??Kt$L%r`c%qK+i&ZE{l z4|pzaZsq}ei8!QVoj0VXG5D@f3h8t@-XGRT9xtK?H<2bQJztr99MpsLUN}vO*J3;b z!$ZXMZGK-w{fTYwq*&o#_+vY~o*T`4OI5eiSmR{LH_N@Vxwo63)0jx#gEv z*+i63o4OI0X9JmJ)z7T<-R));IG=U@t(YgUuBoSUp3uahSbbXARt#64R>ga9U1g2o zR|BhT5p$l@LHMlb%heh=QeW);XUC4;UnP{^kc@; zIY&!yM|e;8K=?j9=Z>0#R8SE@vGD!i9Jf#{hE6$gcmY*mXlf3Ec!Qnx8)hsUV{@jRdao#&eKE#pWQj;rZ`k-r8cT$WP~Z^2iXS^Yt6nodxSBJby~-+th#P z8`4(q+wHb5#({Nzqbj;D4drKZ^T(5zfh?8(LgU9TT{j*-zVgKU=AZeEtdw8YoURFV>^JND9on-ezvVYvwpfVz{R#PZzj0^C|MBR%KEj+P$KlYL z`g!edANhrzSb_a&V1ePa3;|FY~WrhaCG4|Bp@ z`$ksz8fe6<_Hom*EIu*MKGO5~L&P*O1S6|{-2CNJ%S1NJpYyQ1{D%l<{q3GeX#wxw zKtNu2Hz(XJUnqZ5r-+m#9}I6I{BWRbyu|YLB|MbBsXyr7%%Af-pG^HA{0=`rFw=8l z%Jh5|pF;O^h~EILvQFFtR@o-zbE_;9b4{emF7bW9Y-BCZ1AtAD zEr!1fxbNT&a4fRL@b>_>MV5%)2duI~?9x2;xDQAMG3r3qMBW0~1oZ52Ff`m|mM!w1 zS>9Oecb4hrVAeIB(V9qe!^GS%akjk0tJ1NAxc0o9HIV~68|`o-;T614iT4R#72Xow z5#AF%60ZIdt7rzM?+EV+9|#`_&szJ~L0YEo2_FdGDZb#h(g-IM3*Qe8v5xSlhUgFB z5~|pcZzp6tbeEJgo^L1YBOYa1DV7u8PB?^d?h^>(?K!S83Cnc^2lG}{Z1}8VcETqS z&m}D%Im95Prx35mn#gNVz9MTPABW*^EzRAQop9Vciv7M~X(v1$op_ivr}F`wkMi0i zVV=3Ezu~jlc8bzYXn#w3vQ-^a$k*JLlXkRye&Z-)$MefOZD%R|8%mpa2(&}vw>aAl zdKD5FJ7IOADyM)MI&pRPREWLcsK-Y4^`oi2$~kU`sJpjuly<^N-Cpa;)DQk~?yq&J zVdM-~+e9dw^Bnb)3x)Gq1C5x~K5ly6%O|GqBmH4NKrqw9m=rNQbbmMh(oQ&CiKhNA znPmHyc0yY}lvUcTN;~0>wG&piqn*(CC4p+Sv=c@L?z{cyf!5lwHFI+Gp4--rMh9-Y z=dQbMzx!Bp;O={l-G1PeuX)|I_a9rk?QPQ|TlN+D(oyf&Em3H1b4hg)>M%Ul_fiAr zrJc~$iTkcS`*y;lkUwF)URy5ePk0Rbx{<6bTpjH(zbbC8@&CNv^Gkn1sl(JxmD)*M zf1}c$5Y^P}PWYp^^^@U`a;A2cNk5kD>`yqhGpFmxTz{Pmf5@}&8wTF*e2KJAvsC`m z^1JPuQU3M)P8r@+uD_+5e^7oFBK(Fy(emSoy!_qz&&dCH^x;#i3SZ8q_Z(rYb2u`PWX*H1eB7qXMDcfBC@cQAG*E;4e6dK^i0K8wcxOFL7vss3ox7u!&zX=ex# zb!^(1vg|l+`y2>l!2D@vV)_s<|E`3)x~s-zcmz8V%jbT(cf*?!o|V3z6YkofLg{%e zhHz%p55wCC&wIY1gopCi`U}~3_>3reE-}vr9^#ISSnl(gy7c0qXt^}&{-wW|l?~dZ zZa__HUm>O+h{`@OZQUyC#5c3%MK+1)FV=K$6S(hSwz0}0~RPfWq5M^Wi>fdJ5G_k?p?nwXMaujij6&264zdX1+%Lt zEB&Qf!aKqT!bid@crnf6*Hu9^n{>igg|~$Fgb##|gs-AZOt(|~woY>35sHQH2d94& zACq*-i9@WqfbX}(cy3gU=lg9jbIPVtEGM)b&_}Bw_|8iqw{nf+TLlNpbp!|VR==%2 zK1>u@-}#5$2MjGAIhr@6&m!IzaFJs@Tnx>9;i6^A<`g^nB>cM`O;e5Q#b4if8EhkK zfp}x-uNAb%EUy%`$GpF^$CQ3slxp+6IWS*L=hNwY!kv$1*poJYkJ9tS?e`@2~(|9YT*o#XkB?G2?phAr;XxPH>{b5raw z`kRN<+GGi|uV>8*sVgZ_ck)T~ovisN^_(`2((h+dH`ID${k2g^S@s6j-w^)}gKJ%D zT5`92LiU(Yo4M(kX9Jlq{}A#1T?r4}pW&Dq?s$6*A2VdLDOA6h%w+Ws&U4gn%hV-r z@*z-_w6(l z)FsokgqQZ3C^{2+4P{d)mJ{DzbE2TVW?0Z(^JGDL%~J*KHKz*NYZhnPYwD%FCW@}O z?zBpT@`-g6u)mb+>}<`1*O}~u{hZItUgP^Ur1R?3UT|i=>Eh=%A)lE4>unQ(p{sDW9pa1db&3Ch8{`Elnp5ytC?GdHDhAr;XxPH!(y~aAiro|}jHK+>c z>Us8(Cc?AqB?vOV89hY?e~rH-3*|I%I)r9KUz`ZM(lqeou* zsLw;Fecbvj?KR^X-sMU2E=a0;+BLQ*`ioqS=xrRd)e>{R@u7q1)7QWN#I|AhUhpn3 z`wH>Z;9x1f7O)Ad@#zZKcW}}Dm^3}V*Q>3P_hUKLHc5Olu-YPt-vHPY+az%lxbNUQ zfaBfc@@|!X4abWa_L}-u+H2fBl#8HUMBM5*U$0jd0$}3{Of`CJ;(DO+apSQ4O`r&as6zr zy(V4nv@}_Q(q4o5kU8OG%~(YBvMF;yuqooTzJyN&;sVph_*dF%!uBfGkIs3s>R0E$ zq55T-Hs;8jgNKOu4<$U5e`$}gwYH0INry^%%=Wd%^dZzU>@iDQX^&ZQ{AZT7nLVb5 zL4f`;z8_7w-pT06W&}7B{~5}rQY&DBvuf_@8Q^O43g5Ois?-Oo0=2;JWxn$4>=ldZBzXb>D z+*=R3tnY`hr{l6SYA?&EZPPBGQdf}&$IYGMUwA7XMJbk({oohl&>`$GxvorQ+aDhp zk8-J`@%;6meMI1)6w8S}KE4lvt?Mu;uWUb-i{F=+x2^|m0~A>g`luENX-Nvn-9Gdf zF7$DY-z9nQzFH2g6I_aJMIv{*R?W{}586e%H6{?!cw?D6Sa5ty3jf~cNFHb%<72?T z&$ka9k4}CsAHu)xjEnqO2-0WF8i!b?N};hx+k@W@L$njeKmDHTKJP}2f3HQRtaESt zJ2*Z5xhwV$?)dTVW~Z`aIrqoE_d9WTsUpP?7QPomz0YpF(o&Zwz`67y96{#=q;4sL1%&M!Yp)=es$5KCZ-z3yoCf_Ez zjK(l-h+XKRmkaEJ&(IH7rpLz>M?YNI@#ABuAKLNW9UsrWet77tkB`Cm^V8|LmpOm- z_Aiw0eu44v(6~>A&dTx8*2<*SgX5bkiNs_7z%7_RADSK?4>{xGp>ljgGnVt`u^ziA z^XFu7dyJ2#XOEAzSEunZ$HzpC8==7w*UItHR?PMuA0e3X`>N?&2Mz0-m*XRvu^b;a zdweYRJE7a)`^&i*k?#d6(RfbCYqt=A2q3t!lhG0(V zkIpX2iSD9Yj*qTGbz&2z)&brz+e2_{exgzF+qdkB3q$C;s>A^TvNCDYidYb!DZn|IP#Q8IyIok^YUd^haq* z!yqSSw0z`qO=8!7QtX!LI4j?SPDFqFZH${{Er@24#P0ov)CI2b-TqT_;G>w_OA2oTf9C?vx}=^5TeIP-VM z96&=H>y_Mdy_WUd8b0X-pjREfh5oJdKWO66?{(b2qmP4i#rG%IsA=61?*-Pn+KBh- z)yR+3U-v<9 zD%Nk7*YbSI+GwvLK4p(0o=aK;a`zD*V?12s_;x7{6eIO*bF+910k1%qlIG{zbS_8X z*EABi#v99Fu{|I*@|_&^DNEml@=go*l)aq~lE$0*Cg?mSpR;@?yA|S{ufKj~|K?`; zPWILed$&$yFzek!nO6$EpR~V}@8oZY4<4uG9o$=3kC+q6N@|{e1iTMvyzLQZ2=tyVpom_Ao;8LydI>0MsP^F$zaGs2H zF6p~AW1e|D`pDlhzcik_lX-2D@XjyrPM&z@BR=xKlli3iOF7^tna+#lJ}Ex4c{0~c znR(^1J|S6C(GW>7Hxcta593=sl}phHt?< zP}lj)dgr+1oX3vJd88pUGUs_O2DljKtVeI2m#%{x&-2D_5@$tZqAMbq#{z_El^l)S z65bKMQ|5Aew1eQeVjLv@y>XKhhv5qSxg6sanaeeqfo6i!7zfFp%l$LddyMO|=5kGR zvLbW2cX}OEi$LxMJqR$wHNH3Y;Git%IwkgZrCR}BssLQ`^XGCON4&K_ys-opTOXO! z>V}oB7^51N*RBKNhd|WQx@jWF4=6PsQ4ov);cP6O=;lU>#4g-uoO!nmA_Z4S93r7=>j1dM})& z#QfU`&&z)(>C;5c3DY-_abEsigfoA4%-1a3`f<-SJgZ(cJXEI|X80E9HLMHTr?d1L z)G>@L7qTWS&Q%|}P8GZ@bvRynqDP1o;)|1Be zaGaT+M?XmOxU)SrB#)>+yofbZrIaY$|A$kT)R5)L*+Odq2Gn7=!AX+(y%5uTU- zP||A}mot3>8RzBSMR=)a+1~-_qrP^4o|W#qur58z)wyJA2EH>(JqwipYTzjKEUWjp zW7XN$vkLC#aIpA(U!S3%gU%y+);aMVhjRw=-Q_IpcX6ig`MmEqe9vdS$3^^%47%s$ z0{-pRlML=niKb(1LwkmP$5DSheeb%3pT{1tS2AFI(;o2>;0JKddiCrP>HZtudvZLb zbGGA1WIGP#vjD+dC5M9565bKs6TVYy3*664DV7u8w(x`#hfx&zwgtv3Vq2h2%l1=> z<;1rw+*ILL>jJg~v{R99IM1iT?2s0LeBzylcwfLZ+7@W@MKOZ5g*^ypAWTW~^KA>q z5N}N*for@}5NpNu=%`f>7XJ3%Vc|jN(L1leH=GmEM;~dTR(#)rd4JQ!&u1Oqa5l(y zfo+^ckh9I3`%jm@K>bh6{Y!sN(|8ztPCt!tp}72ve-kGAH**#u$G3*}SvV2B|8p@; ze7Uvq-|r(xDQ(|0f7f=D@r`tSYfx~%GnUWGQC{khz8|EHv01tm$8@ETex>h&!y3us ze3dkDWa)fN-p9a8bJFuY`~r#mKiT^hcu9_`?!MX0 zCPESdL<|z4mqfE5S?LV)lNZCEc~a}Jp*`Qy@y%GbHSA-X=P z%CSe>F@`2Vk<5(cT8BEh=-{H0lXsjWJQuOZ8ZmV)ku74GW0dm#9HW^dbnlw^FGBgg z!WRR}yJR}&i{#xAv#%iUidcsxeS{}D0t1j@AE6KY5xj7|^YK0c6t9XsJl>oo;9kyN zc4p20j`?pk{&dv7T2w?zuN&WEd!On3ietD(_B)Qd_&j{$#QR))(8Y&be9XniUA!I7 z%>0|BfAUejG#6qQ`~8#CypIvAFv0JiFkhYiNsN4y9SN~J@cSpXqM!I;q)nUqOmWdV z{gV&rn*&{W4#w(sqT7&<-z)2_`{73x70rEKgd2Ma(j*8yzkd>g&;iMWSn}m^T+c>U zcX7{rY{GOOC6|(E2%&#ME{KoS&_5wJa(?)FYJL6KYL=vx`An?UKe@+cER$V#tbdZG zOv?kX)?YRKk~MzoYY(`0|60EiVOK@@z^(|1W#K1Q)Kl zztp9d-Cu-`9&x6nmwf0Hq9J($8v6m9F)XG&pehj=;!9$QQy88jFES- z9Qrr)dxjVD-=OL?}l4a9!%e z2VH!~#YbIy%*DrDd>+25DxLeNOW!Oyw(Jwb<3}<7A)JpN#|`+MGF-9U#_}I5Fu~Wc znNNSulFwgXI6ywihlJQ2_&W9>+(aK~Q*~@q2(@%E+zdxi_#eX#hEq;Q6O$YF7Irwi_kAK-1eS!Qd{v+q6o&(^(qzY2UdR2awLpNzf z`l7T4`?C_`2W%Vr_-%wf0NZju@c9z_TdO{R?xU35-w;eLyFcE4jF(vTeyC?KUEZbU zfqwsC4j|g9a{!qg;U;|$l<7>)0Vq4fJVGdwD%mHL}>YM1_`S__`gX7t@4|4!U+@(I;3B+TqV~06_0v#I_OdpI| zy*Yq-w(`4+i?wYzT@}{ZK-PU-F3bU#3Sk+>p!0P$RdWD7|0i_3F&$g#DSMCRyVQLI zJ;q(KPGxm69ggyK(er#=G|<8Kp>i?nc3gbO#j^h9n8RTm zP879SheP?05W53b`&1nhhmT@{u8-qs>u`o>2x9mvA0Uk6vd z=X#!Ro1lZ6Pfm2hoj^S1_s5Xnw^rleiK-Z4+y}$f)xqoe!U;OKl@s$n=-_LrgEw7k za(h?{5Akik7M|Y#>T*5KzPvj4y!pyX|4EzT4Qpii!#H@xioydne{2J(0~ZCh(Wy&U zO=XtVoI|FdgNr0u)@+N$xwQ@2&b=Jh$g4084*ukWe+9n2pm{r=&h>S0?%*L(BAN}R7{y2C|zhYr6io80feGo2XEksz0Vj0+82W+Z? zhxOik1MT@wDl0k;F3zZUp@JZ7O3=Y!{;hyNCl{R4r`X;k_!o5WuomTF$b!sCu#cd_ z3a>?3iXS$&n0n=19~K0`;VF;1s!R?IMeeV_2TUF<3yT+!##!!Gud zZj5n|ty6Z-xdwLOc{?jGjtR0hOuk<|PFnJQC)Nvx_1cD;XcrsoiCl^I%P~D;7jX;u z%qvHBEXT9_Tyoy0? zfw8V<&OyE>;3U^e-xoj1DyAIFeP~u(jr)5B&Pxz_{(9;2z{~@Z39;nMCAXfxzHZP_ zGcE=lm8^i&8r^ATCSSkoSd{6gVLfvuG~R(X&Z_%pC3_;*-gbAUqwe({#)DGFcvW7O zi*=fWB7I2e!~K%Ui&+o$@hj8OSbpfz5lsY^k8zWvFW1tUm_9%{>FYK{^03UvrOP=T zvwVU~Rri-7z3Tbc09M^!AL(WHr}?Xo-y z{9!^Lt+KVPT6(om!nw-~Ix6@N)|;@?9rOETNbn0fs^t%=t1PU#jyhM*zh=-;vsV-a z9hJO*)RyR|P1hQP^}dF$%c7&Q$$Ky?kRSeRpG5UIb_xB7aqNlrD>~}jEJ>CJsq@Qp zA+0wR=|fTidCK04q!+ytNi%WKQP)66MMK@lA7iGY;sWRKpI#3m%atx}I5m9kr&9#W0R)UmX4i9hIzr)Go7*8rH)azLw~a>t`HwZj<{! zWE(YbI%pV2rA&Gu=%{O5%Z;fA$I;`=bw_^13 zx%G^Hdal^$j%k|l)9E~e=(z`ZuQMlY+kWy6^06#%J#U&$8;2X?5At6ZU41?&X4iH1 z(QGZi!Q=1%vGUnx{k6gOY(&_AXh#&Q$be>D_5c_o@bkpB@=PL>dKV0kR2bM{YsqFcf zo+7>K`dE5f`uzI(MLryhWJcd3uirfrtlvL*>4zQu2@g-Z{#vZp=Cg9`$yta8 z_)&Iu%y&u5Pkjh1^toO;1`{a@Ouq>6 zz{wWz#lRzlF9jCaVLIuEtPnp5SY(6vdjaKL66?@p{dZpo;GVd)=4#-N;Du7=#@Bz( zEt?NXEXL^=b0ZzKA{>=w-h1@?N#Z5$!~GPk4?pJ4A9wL~yt}G(;fGxMQ5PR~@piD% zlymVR7jKqztuensoZ??8qh$V&0M zw!vRVeg~f8KtaA-uIu@i?1jE%6#AAFBE^{vV4EgEsQ_{+YY(r?&WsjKsNB)2tTIlwiVC>>Ioa6Z&}uNExwOV~k=}T_nzGW-_sO(R6 zBmVE1|C4=7%e2?s-=^*XQPMqYie9H-rL*LT!M7Mvd-?yyi zSGCuft?gHJpBrqnvM^~!r|GzQn7717!;sCZWPKYw?@`jX3G01tm_U`0A@GA5zv-{8I6_;t=(!2khel|9-9P^f${IAHo9Q8Ca zFXuIC(xyq9C+|$+(077vk49}j7^2%Y;SbLZ@o&BMou>62c>f7r@|E&HUL5)^`8?OT z;7y7TM*1Rk=fxy{)4mJe&2r3haeRVdfS1mBF3zL97w?|mxHr$$%1|+c?`k;#sx%ilikGpuOb6PT&wOQt_ZrKh-xDdPee8hV0>MoUsS)^|F z=dPHK-?aqE=g(b1M2xIRzSteG3E}io;_#~gu5#yC-|#kgUzg%X+OoxRfQ#0dyLy+t zIY$GLp~d=2!VSpxVqAbK`q$&f>lV#jore2+z7#?%&+E@!jgap^LB4$Ms-Dl-&O&!K zHlcry*I#nk{uw*uZYa;7*C^NLiBGwAR@T4B_2bOW<%E7bGogoVd^??I-Pi|r#`Rj% zfrfROe_WRcJVn1$WAiobj8eXhzO+evare3H1Ypm;#B)^Wivt6^_YcuYE1^0ja7QwG_m;cO;z|2gdI3GXV=G~_9FkPVE<}sgcRwSR_=8cfR_a`BC2Y#D(8D7RN zq_Li;YV$ZqSf|Z<0P^V|x4>9`x91?=mvD}4-s$*JCJNg;BqT_aAoTn;?;7MgAej(L zzFZLN`DhGnUe3gPOfYM+;|uTh+cMQAvFH+PQ?GcNH=jRC(UHi=j-o`IqfAODY9Bp)e`XI6n+B^<^ zRD{sxRWOH1q0K95^U8dr}_4Dfb z-COao%}wHyB8+X?ee6SsCV9cJPwr!n-MBBY4l6vLSLSmeZ}ax5u}$YxA+&j+&0F<0 zZ%;iR38Br)Ymb69Z({#vQJeRaZ;U}ijd_~2C#yfUxo0+imZGE3&nx1JIv4tR1^ql! zB*iw|vo;TMr;e?W_R!{qHgEOYym~g*Lz|b^c?E6Wt~&j^C;ns%B4uNnwx!|!mG0;5 z>EzE+bhKXDyr&o49L|L`EP209)@_nkYunG;Q)Ux7Z|9WJ=RMBob7=EIo45LHUOgMm zojvn&b@wV> zvx#b+N&S;&En9!+*l$V{twEF#FOG*51*Z4$<66O@z&2-y-&Pu1l(ECJ@Z5d;WF4in zIg*Z~EHoKQzJSfL zAK)DMK=7O~ehmJ8fGboUrVI4<12A8m{Qv_J5F$8?@ni7!1AGu4PmJ@^_5%#?5!Trc z@Gkk7c`*dJ1;#q*27nRHaX-Lm_)!*$_5-{Q_xA{-Nf3Jeet=IQ-vP;lSn}l(SkHdr zdT3X^a5%;jY=L&gvxlZ$pE;Cw7}}MG#0$GSyE}1rwzDuh-zyjw6<(2X+oOLQ^8hiv zbCZ2E{Us7_i|ALBLE4RV)UFiRmr`G~8mbfPP@!GPZ9Ii`Wu@DddbXR^L%VYO;RIj! z7HC&&M~~H6VUW5qv@2V>T`8~?lD8|$_Q#$v+aIC7V!o-+uB>#sQqyL~Iv59g|KUDl zVhgk@t7KDyI(Si_*51dDV?9LyUEpYlAIpzx_&9+;y;y=imUCt8p`;g$-AS5>*I>QD zI_$3$*vQD+6=h#)k28;9-pfpASBwaSc4ej8m6~=jR<>Q4@G&@P3+hO8=36Kde!F7C zWc*)di#4-bu_0_tW%DcZ3pqZS?9d^Y&)Wz2rG>y!rMo+FLFBKY9O}zS|d+(RbIY@9V_e#R}ekzGpV` zMOVOoWe>vK(2?lvpN(;pJ=fU&r{R#9T*&y7(O-7{;Cij!FV{eGztg<8zFJz#vh@*q zEk)5930aG=U-;q0)cO1Pm95)g`JqckG!a-n#!ZsGTuW!-xq(a9=jE8?M-}B+{fHlM z&RP0_^b`E!{TBtMr}$U({OtIY-M{89_lx*phkwGuMek%R%Nnd(;j`-bMOnw<@81&J zP?G;#l#_SK^1FcL-4R~^oVa&E%&mK=<2|vN5^%gG)}hJ%u!|f4-UIiCT?%|D=<}V8 z?+-)6SZsF#ZrAqE_wzjeE%4tW|0zulA7rNC&Cgnc9H7r@%$!laf9xpJaWBVQeB8z7 z;a+)upNkK=c(d#`yA01JA$AAnBj&d&NpF$^mkt(~;O{qMKBs<|bjj!YpGlFAG9V## z2h>@(w=8jZ5yYP0&hfkCJLG*)ZdhEZ-T@M8?Kks2Zn*`LeJlCb_CCHKr$hge7T&~v)vK&K*hvNPsrBs6zCzDzLD+2uD!3pzNglD zg1Y1J!^!(!c0C7jwqo}m^gyfUXL_J#i$%WiGJS(}iUhA(GN+|JVq0DmSS9!I3wq#q z-7UP*{0(|wv{CiIGFvpz`KIZC%1F(;Gg1TLpj-q!(CQ$pLl_eLf*xpjBK0o$vif>p zO?x(ri?x04zREQ&VLXs;^rTD=tZg>|rB+gp;$3<4wH{kC-gsT~zPng5({J5)8k{gY zy^?L78J}7udpv8Ur?3tifPvJ5bl(%u1g!_?V@WU5&m_G_H&89&m`(PTVl zmm`o+fH9uKI_6V2CZE0WoC144Xu{_>cB6JV%`3}4^J4kOwb>BpeV|)p`{$@Tf6T?3 zWo+gS@KQqT4$eoc$7asa4HnX*h(9*NeER#4eE!%>f_!|R5@L7YkIfv%OXm2?R9is! zKx>W7h%(}?C%3>@KjIC{hm)+|Fq~&(t!QlK2Hf8zNS7e={IQv{@PQwYOo%04J~mU+ z7EoxDb1qJfZRj?wWR7bIHuCIyTCuSWJ_zJM)7SUkzD-^wTSlQxUOk%?ldiO_^LhJX>`N;6FM3;9f6l#LQ?jT}Cpu=^HnVKKDAm>&H_3Wl zuB9JC-=98~JY~-%=|#^ZX(nEW{Z#UbZKkYSSgtnkT=(GQH~Xaz2YwZf$ycvmT42}7 zw1K($uZ%m*JL68IGlP!LKE`;l2VH!~#YbJdS^A-`laC9}730U?w|TdzJWLnp_d}Vl zPCs;ne6bJ#y_iH1{C?3&>kKXe_h6|L1~uNPY=lr4NWx*x6AIF$6G>#wB^YY^-j1de~1v3}3y znABZmx&x}tEEMSvQs1@JiP)|e1y;4J<4IqxrStLJ0O@5q71Kwqye=olq@N&D8GW`x zvR0MthaX5k#lN!qXFA)JO8&TXlh?a|=0E#Re%Rrk@Nm&P8_Ti|bw1JYMCT*#r~{sh zSl%@;=N9DM63bdu$uDbFg`U4wm1|A=j`u9DLz8ipi-iD4QKzI#z8CcQ4n3W+z@}S1 zu7ab9wW~PS(W_SVjL4YXH!L>VhwD}8oX1@HaTjmL_rd)B`qe}3{ASTnZ^1K4h~0s& zqu!Hfry*^sj*1VymX7LG4DuX|)$K&*Am0;k zl6A{{@uRF3&6Qk@`+Ek`BnUl!uH-!Eiw7hVV#$|xmg?Dy3p%P|V#B$Tjjp4v7rRP) z6OiMeqbiZ~4~N6{{K<6G`Elw}hj>+5mWg$igd%-M>bw1t$%|R#_wl2iAbD|^1)dw? z$MmAW@-c3b^vlW*kREi@BJM@dl%|BBqZ-*-WgWG^KIGDLRAobQe$0ks&{2)R@5F!B zZLB{S68wUWYI&mT(bd;c>)Dcf{rTkSP&1FQ%Ch|p|T!l z*kPlI|3OC$6qbhr}^JDgC zgN_P`ilUwPQC@?NN^V$QNW8W>YCSu)K}R*O&Hme>I%?hZc~*P0(tY@|eIDq!_>#2{ z!R{0pWk&u^+>N?2+i&OAE-Z~d%c`S#c9li%2s&!2e}UcVrRk{3w)Om&ZR?<;nzs;iR1roSOFhqcZFSUoHnD?_s@~t` z(@|@!r#<~T@*vZloUVD25oM8Q!=*|71RZr~IAi~1{8`_&QM0-Jz3Sd^DDQfs>!@XG z1y~=C@Q@t4D+(NENsx)@y6%>|K}Qu%nB%`}$$elznmhpXnG&v#Yv}*Q3_bQES@+o8(W> zQHQzsee82;-=h8zL)2K}W^r5EYg-j*5nQiT3`X z!RkFz_>8k%C<|ispX+jFf{tq5%1-hEzo4TUc4YNDd9t=TYE9e!K}WSOj{hfhuv$9a zM%Phm`!1N|PtZ|^x%lMrvq5y!P3l`9jH4=1VUhf75FOR?Ga+?X z7)Ko+UywH(=K6&bc{|55VH~y9IBKPz4d|oOY)>sH4;%~Pfg|Xsxr_!KHUDmTB=!8- z>!|hobaZ=ji?Ip)d%XUV%l6N}Ws-y$jE?6BKG9f7BLw@XAuBI2VL45UD)J)OgJwz z00UQQoRV{KDK0|#uByRN9<*HneJnZ3bZbcu z1;&aE(K*OBi<7kRNqe1?nIapXm*M`Ngft04&$sdUdE`4FnGj39Tu|%zUI}`ZV&bG8 zq1)k-z1K&gjjm@s{>~UoSc;yN>2b?G7MP|hsE6VyJ^K3nw%4<42Sf?f_@R8GW%>Z? z1PNZXVopnavR^WJF{{)*e$-PWFAlT7b3^>f^dy##ag(H9R(^o=vhpl5a^-P25lBBl zrZW0WPmvz-VXJLi)tTNv{P_ZU_!>i^?Efm!Le1e{3 z-dlqILC>;!kFKj$U(c%P?se@~ zS8luyPwCOu{AsUedH!>9!LmoVwh232>_mR^^}c1o^|@2 zeLTF+A8W@3<3D-G_><{z%dTg6<4u}=i5?XED%uw$^Vt4-oaB$#v00eUUoDS<9vD@Q zw{c!2>=CvyBeFsi*0yn`E)PrGBizn)|k{(y>qIA!-Qfk?5Km`Q`e$O|Z2{u8==(|7?tdV*U(=NRp80 z@Ec_Rg)C5V_b+vN7^^Iva}GMH2)b?G1O*+nm5$ohXU&50S+fv))`(Q*G8%N$oF_bz zdY-XX23FtJV(?iLbkwL|9C%VkebS9Fq_tQF6M064qH$(D&RH_fyfmLIxSrAUR$_lj zuES?KWG((|S{-$h`mEucZ&6@MZKb2O^;xr^eAX-k zpEZ**x)Y};uVEb3@PUT$N$+lSk*XWrpvjx=k>F9CD*~Sx%gT- z*vG%dhtHnN>6%q@{TY8Yl#a@$#CNH6V9lSBwFFDpBkcKr;q`Qox*?2Hj@OOCqp)|y z?%UzslTEayaw$Gp@=0suh-JY!VhL+1$MvkRrqb%3V|o@g{jKUA;l-MMSAw1;)%=## zvp(>(7(7^to|Wlw%dTgwRF4P9}`|rhoEO+JrgQLj>YM^QFs*etj(xr zp&_d8S0vN3@GYt1XT0pWuX(nys}c6D*smo)6!fh1pl1c&Az{unI{U&CzWy{h=laU` z@Z0tC@thYX$NQFD&+^8bH2sqCrpdh--d$%fAMXouuC&p&xJiA7T%Nu0@dN61Va|1& zCu8U_kAC!p@vg^Q{^W};4{uu(%?Hp7;kkjqMi6rUfGXh zNbn1LS1eChCrViLb%Be)cSz7t>*=UZeNPNA4LWLc;%?MslRErnT^G2xNqvU|9aUPL z@fg!l)gkDpna-*iwZb}TTi+r0jB_0|_zub6ob;oDj+*m?N5U7zYpbKy^&PS}Yg~uK z(|w0r&BfaY!FLF`AU0Rl&$_^Zb&Un%sF^OBt!q5<)b2B13$Pmm+PNZ;==uWgXulkMKTTxdp~r54#BY>Z}{Q8uwSnx5%le zhz_`CWF*(kdkuAciv&F^W8S)5Y?WJ~lt67;ZqZg(YoyahchQo>o&_sIO-`MTp_ z?{!<&!+02Lsm(JU_Oa^|Jddw`@EN@@si*37eI>kgOVy9Ivp_D1;E(c52?8<$1r#>MW1xz}{R#AQ0`L41cCOFZP_qb}Yo zV~K0E?vU~zA$AA;SmIr%Xr6|&sbh)w;A@Q~dKCj+r3sAH?L-$LUmcs-Z^HdO!_inI&53NFN@0W%i>b~z62c>{bu)(osXEqc>E3-?veuwGhNM}4`)91ZzV`Q zOLMS1&dA^c4mzwJhpp-Nr5EPIMYamo^=)(=w$}ZhejPdB>#&>8?+c$2b;ioAOO(Y} zyih@qx@)uRh-Krb)VoGtLY0o2AQRJzbTroWDH2Fuw+VnIXdO-;OL`gKCA~;5moyV^ zz;Q_Os)-J#pL>Pp!iXA*cT4-YYBQ->vf5quaI1@ z?2%MYW%_{D9g1`U(M_uKm_9DG)?;-+56jy#zWKGZL$d+&u%-C+$n`Mg&|}d#^ay%b zJ}#9&?$*lQVbH_$cvwyU9bsJ}t4bTTs2+Cv;RMgW`Sq|cr|Zq>dj3X&p4e`@j^hOn zvNefWGvp4lhk^eKltt$X#mLG`SeIx%m!0^}x(}b02?_p(b%~ZIx}I6}b%}dx`bG<QB1T z-=aF~`w#c=@Ii;&D)ta%UE*HP7IV;HgAU7TurzF;IqmhM!=fRt?^~uwhs9@}4Z-f6 zwQgpD4htcd`Y!0O<6pe+h4I?zur>Y8g!%CN1#TK0HuJw%Yd-u1cajCgI&7Ne>?zRk z_5S2#+5e31#=M2YpY8L)nttv5&+3jR4n6vsKPB|*+v(ZcnYi5838@>xeE1k!GQe?= z1eGSoA$8p;8JM0Tfn#fWjg+M8^#uA@(#!ZR=|yW0B+bNINQcwUy|U{P_b$cnO0JA4 zXDfT1vz0I(K0cNh=EDod67i9*s=dU$HGQiDJuI(swx}NV_&a0pU@3Z7rsrurX<76z z=zS}yhk5juR}b@imE?kDkAfc7ZmcfoVO9s_evkV@q=xv(eD4Es97DjU!!rF`!~a7l&EkxgmZ`FA6Ll<0eVJsJz~vQRQc@j6P|$(G&Ic zgWc-<4Q|AJ%Ij!t-BSFk6t1mPu2%LsS1Vy{9mG@WyPfWs^$SCSU)Uc~pu?hJSXH~# zdu#e$33Iv>TN^gG4x8&}*;t<*D|2IgC&ruqnIq9PH}dg|by)e%4TC26v+O!7uD5Z= z5;|6GU5am!d`?$66xr(> ziiA1cFsCaOtJJlOb%VG1bGkMChx8Wb>iWQYv8(*-5X7$NwCJAl*fw6_cDmO)LH%F1 z(^}7Pb8<@0m|_0wqMNVc?fH7f%uGH9>KjMJO@cH4*hr9I}&;>&G4&+8sT zMR+M#J=K>RCN66Ea`PrQq`qYgiOa%Lbg`#qrSh>y-#6JEt9{9Sd)y2}3X)a9as$onF12kuVJ@oIp*GvWpvnFGy8-gx2 z$s3*tx|rq5YUpC?XrDtPKN$GdR8waSfrK%!FeWB7i`2Dk^spxhF~ma8*TYVos)q$X z7(ow3Pephe7YtW1gCR$v%W@qgQ{KAI!|TmpsR=A0sLY9(~Q9 z68cLR6AOMY!afHlcv5c@Zp8Iv`ukbo{icolVC+?XF!lyN7-65o3XF#>j~-Uj4@Ouc zmRC8G<2|~a-iULPXJ2^2*RLkW!(RCwvcS)mvn4y4qO8B#d_M3WsB{IIb18JK# z`*_&p{)0Qr`GFCbu)icdjE7mqEa!L_-v#Fy*RkD?rTBTs$H0_xhrQ0ZLl_SW<6%;@ zNL|ag>Ad7}=wY4Nn!X%@9wx8Otv(~HTI-(aD{lN`U9Skq=%7 zdKegjulmH@kdSjG9A7kgSetFFe!jk{N)MYH zPpZAv9bCh=vZC{D9(_HY*LdE|yl(!R)WZt&yiA|V^wcxo!ou14ay<{ZR^t9o16{1& z>dbC(e*vt62Vh{?o_6jyFiq$8xSrzm#-u>OfBC@g}hMFXK=MI&J>0p5g4|B(o%zRi*lm*Gh}YyO2)@xdq1Z3{1ZP`C^=;@8L7?V=>0O zkL($6d>cOa??fy?==p1`F2i#ikW7drUoN3FZTbgYCgWnzWylIhtv6rcI?U6${C|2WwU@jLJ1SEehl{LrN%ng}eK3}bS$$om zrd|BSZfzS1yQp{}gmD?m2lF5M-om&HIRR-mI#8ywWaBa)yFNjBcD{UEW>Qz$Q0t&_ zU3fTjegpKln0xNYalN;HHZI_g-8VTLB1uBVpN#&p^9R>6S1Is&P%^GJxn7_BE;A11 z`3VpWV~0GC7jJf5k?lc(f7C^b0(H^Ur8BP|*r$JxJL#(8u`H$xh)};O3QX@Kz3Tcy zmtJ&z{eIXd_e0rxm3&3|zoeOX6OPM~*BqA<|4)L&-mB=s7a^a#8|J?lSl-2QjO%eO ziXp~}<+vW_eon;;<$y7-Wb zkGlAni;ufl#{14gC1T3C_>hZ_x_GnLzBp|=9^8f4#r}BUWhxJ|fCVP_e#+`msfGfb1+u76WxG(eVk<7a~6Jl{G#!|ui{~! zjWh{D&mRvwhUYjSnGj39T!w4HF*3Uix!4OPaVOoz+(Q)_PX*6aHq5p-zV z$JjzTwC!wX;v;pGS7m1Dx=AR~x1>JZpOqLtK$C3hcIqXPSLfilA%0~#Cd9&m(IL?;5CB|ZMh<{M6{mvwEE-0eAm>0H;@k9 z(1(JrL+73pIg&)oeJX@Gbt};LA9QH4 z0#aLlPQ759HPe-|ap=>pBi-!0qhDYv7`afd=y6a@zhoSAx?K@W4cc+hP44rcu8vow zLsG{p(?PY4tB?718FtvH^na0FJeGMAj6;%l)S1?BePB%=1^H-8?w+7C>)aEVF`h7| zjG+ZYrKlrFAAg|bQ!CQH1*}a4s@9c zJO6uV+kc+_a#OOM+1$QAj>BGuOh-xZJp^5*U|a?jVT{Uh_4Yc{wCf+{HnVCy=rUx* z^6N6UA5K8GhAuNXce?EB-@I`jO}}K^XL9`;xl|N#`N`Jr>2am4w?5GGbFkHQMe3^5 z6{~dJ)TJ}8AHv*b&JmF%o>@g&bL#Ty!koI{gy?X& zo#Ko^nU0(JHLImVzu-<%DAu9VG^1_~@ZGH3`oK-@?;@-Zw6e4fBY!%qrp+CH98&Q3 z{pj8T$DhVmXlyg9&+-!6u%k!JMGg3YRND`%>7ODWG0a_4bY`7vim*Nq>`(9ubLs`- zfe_yqa=2=9>YbWCDfY}R*0qIv7bkTP>^8t)3)wJZOWNF7nlAJBJ7ch_hAuOyE9p6J zH%^w(apR3k^F0RLN$X0Qe(O1P%7aH=>v|>hr|;D`19WM_rZdYclm}_S!+2XUkErXV zP}Mm`qx+eXo9SE}M*YK8b&_Oat%2xc$yCO7Ngvl(*Gf~L-OJ<3p_W(kLg8$vU+M=hPq5>MYeK20jbbYJ`0v z>|wP*<$dbyJtlynbMxKG?vsToG9!3j0LHdkIDJyBya1AiFpsydH~SXsf05yxfIQYZbl4|SphKgx+y|pp&5m@Z zrZ1MT#w`=;Tn7sKL}sGp8!x@)MzXkAhn9LoUIOsSjR$(ZLFAee%e|D1Yw0nt@m9-H z5WS~LN9rSM*?1ev4_!K0MXT$fSa3p(Px zAm}ntl;CZIxy|*U%LLy9VVzdAEV_WHVDT^4WvbR`P5Q6;_}56Gcw8n;nU)7u)er9N zdrE9%= z_#9KvW!8f(Q`0v=*n5Z?%!a(J4s%S^b4*LqWj^q=7!0nV%WUvB&Ik?oNGp`?*4mGEAj!ut7>0_Z2#-(yyQ2b1ZuE=pE;XQRn z-`~CPka3eW`AgV)Skrd{)*UT!@sYAJ(NSI;I^xB_tvw2R56xVZ`G)Wg6a2#7!vZ}J zgVPBr>ebtOSktdVn4g2h+7R?W@&PSm{rR~9pY@YtTCaQ$>H2yg&rOCE9n@=Z^K+C}){DB|wEAm}YTDNix(r{J2|<@38RRP ziyn3N$ulQTNISzbWuezQfmJGF^CK8H@N=u{&oKXW(UCVWk6h;@x2DA}$F(*qOW)o( zubc4?wkzFz&4`ZS-{&Cum;Yp$nR73B&KqyO{fj&<4!Hk<`6Hj+7=Muey6C+3k)Hn^ zC-;aI+`nGyWX5~a)W6=5=#+0670@rRvw&RQ{8!GONZy;zuWO@!uF0Q*`=1zhO4E!F zPEL+QFS)#5aQ`^vhr;oTr%#+|S3p_W%kLf}Shgr~e8j8|+F2O_W z&q|CRkba8vvT;2_6aScA6j;8Gbka9@y-Yke#J{p}MW)9fQg(mSo=@{%AIohNy%R}e z%o;bhbhdTF{g2=T$Nbmx+GEG#Hg)e)Zd3Od?v1u`kGps~>K5YjTr9S94?29@#oNIylh4J6TpaCw z*{ff0&4FhkzUHMizDka+dG@QWiFO}6aLs{e_cLGivS{~9Uu3~cpMAACy_*MDzvx*9 zu8wv;>qRek!Lwh8{4adbHP7Dtn9HAh!ON~W@T}+KHfsmko5k%$@=aNtIxo&NhMoBF z7>{j2g8!$f4=pxlCvEOtrt&b0(DQBXG9SNt36jsZx!Wf_xd|M`t^n_w_H`47UyO?B z#qJ!7P`*yZkMd30XhKcs<76G1yRT(o73BUH)bJ3H>XyY^mEzQmcRUmqy|9`zPw-l*7=! zs_g%hO~Xypzv@b3;@-cs4brBHSV+t^L4wyjn$yyrTq&8nn9bh+KZ>Jj3W03kxeM^>X^eUO0j^*6d`u7ht6doHe@MKryR*9!cV{~bv-3S~ z9D=-*Z-vKg?7WBm6~|gmiR#Z^b!+-WT1x*)*@y3TLjMXf9r{-ry?<5D&r;}Lh5l9O zU$GTOXxP8{@yinw4*jdpzoHPS{uLJusUSMz4s}i+YMs7Fm#2QtK%KEDuzxbZFU(&R zamTKM5kFPJOPy2mUmr`JqIV)`j6?rQbEDumtPjlA7hVkZNMCz>tq<%r^0QUBKCr8N zZgoAMTVZ{m`B1|8Ks%=LUEqealVr^LT_0G_2UqA{h5l9OUzsYdsDD+ke=O@qW&5xG z{AeEpvh!p6m(tYHW;EG<%lD5h%l^=%b(pNGZXq(=JN^ttBuybs^=Fl^shqyD)g_MhA`Rxsnx&Q{qrmz`d4B8%F0o; zKG174L;ni=fs$X=KMMV;DD1zopU~JC_C{JCxC#1KHT{Y%rGKS7k9NiLXy{+DJ&-XA zuc^r7e<$)VpNw}TI1ctLEKfLIBw_XKTh#Ma8v0kEe--*y?kjEBzdGaRV-N`atI)r) za+LM2Jm0vXe+B-8{#EJzFzQeV=9l(cHd$d(|Mi;1VBaEV%zCnKu?hNDHGLf~rGKTo zA$P?aa_C=${#E`BlNbDLob`eA{3nP0Rp?)Z{+0XA8}_gM^=JYDp??+nS5}U){?)vb zD;I_S6&MlvSD}BkiS1i#g8tQ#{fncgRc)WWtNf04J-_2&eV}O_!u-`n>tEILOWv97 zF4pybb)K7$v$C)&IxV^$~-RHStGrFGpa2 znD$b|7XbM=?vJ8NKf}3sQ{_as>zoL)%nX^c3H&=yw)8ly9G{Q#bcG=Ezjhd#Jsx^Pul?WDgX2@*7Yg@k>Rp-MC70LKlsi1f$4qxs?vv3(qr5N=by^x z52mD#D$>iI3zsutJ++V0zLA$=AH9!b!Qv}dF#S)(?%A3DT;PGiyMRXu17@K~`+I>a z&1f&QA-VE(| zf@gV{YRF<>2ERSOTIFFnUW*BSd(M1y+VcVO@!d*@-GSeppN)@()yTB=JjHvf)1H3_ z`E-z5V5}eUHsm`KC)u9!TiK3ZQG5PTBs>mj5`>=Lo<9N4aX>O5mVCKr*7JwknXlg; zcpYyVp}aju;!3wC=0P)mI<@@me*2e`=#;F2ZsTtk&)4AkXWo*apagS$0f;C4X=d#m zD=8J^9hbEW?)8`wMQwwKD%-1v2{A>V^4iDmN_9>j@;lt=P88AC*OzPQ@}xh)uZ(`# za|w;2Yf74l*T9|Wc(b%imnoT#@oWs|{eShdS zO$1X0|E`=!u_wy-D%qz!-&)uSA+NOFz;~h#2ROH65m)0{d^S0MGL!Nc+kyW*y_mq3HR`DRsqJHu*o`=vJcky=I zi|I$Zc(dpux(^)VSsBj9PwOMMjK5OIhz-6z!hEa;BuGAA9~mMa->rn$9r*glr|{9# z=_mK`66@$AujR{DL2iMuenj>$>-3Y~g!{X!fS#|9oQcZeKtaA-Fzfl<>g=hnkDTM4 zb$#h0($569jo%+%A2=L6?a!7`A6bTR0LrszPdn-b;!tF#tlpP4j&)>{_LSvE__2IZ z+o45Su7#{wD7!DoP()MGOuP>Iv3`3*UMxrZBK_DA=t)0z7hWiN>a{P$kAdH zyJNrIcqjPIv}yg=KB}Qw?S^g~Ko_@R0%M)@I)D+*P3y;Af%~h|kNqI>9WYn2|Kz%P zyHU@d$cAq>PV)O*lkLW`_G6c`-B_Z(0lab(Lc1Z-ZuwEQUrgGCvyioq-#TbFoW1tq zc0*ZS?}_F0&~D`8pP}6-9{*gvcB7u1^bOx`$Kgl1AewL#DA#`%f^F3yRj+S4QF4k zxZO~e@_J$^FSHw>-B`VLqn=&6&Yr#Vb=O;5K>(*br zn^f&O2&p@HW+G(k5fuGoe4J_~U)PYWM|jPbNonTXOP=$_n{WT(1l8!O>lA_@OK@I3B*IVNi6Gdw$2*@fMKJbPKY;n;6-7tJNexG2YFih?dL zZII5#@_qcu%CpQ6Kh9ChwQ!gPOVKR-O5g4|yM;+yY~rbQ{13 z=cctgH{ky2%#U!r;sMZ;AlJ<$u%5l2Wp8)Pji`2ETDvoYcE>Dw*#hm(yu7XASl(e- z{mlA9LQx$p^2WNcDCqJKpNYWoef-MGv&;~`(C*mv<-&{QoR?=EHl^Juu*aajdbP|; zEGzK6hjs@{KnU$l@%+m2wL3NKAS`2lNA!DY5#{}ztY6^z4{wO>b2cSn3$#0QPFE2^ zyHmj&CWZb^_ZgiY?PAch5C3)fPtVCHGZ{T+Cd2fZLc3#SE3`W+-R{)0pRs3lwzmD9 zTe+ASp>mwfRGv%Q5Bp7@Ori)I;?KuMuWg@S`hFvGQ~Z~W!)4dc{7akOC)OFyWcyoB z%EsaD`Y#r)Hx8Gk{y1E=j=69gE={kC&U+u}XYH+9e~^#EG1Y|0``6=quAG0pBhe|} zGD2~m{z>jlSkm&}yZ?+o(AnMnTlzV_u8sbsHh*vxbJd$}a(c(ae(0NS^2S+b4oByF zBH0k{pFCVi{;jn9hWoD`XAk_J!k-}jmGd+O-xum{zrObC>Fc6%jWHPie698&tH1O5 z+P~f)T1xwN(@jfj-)_3;y6D00;ggTw|4lbd-haL?cxmm!Prfzb1)`VFX8M7__Mbej zI#qI*Uq90iCfcVooot`p@wUWJtb6?jBe$7XJS9yOfoq7Ghd5;IVlV#(z z2@5l{KEBplDp~Aec*vU5U=L+C~!p{UADa@r4$&Q>p_mPO~vivo` zk&`9j*8ujN>=6%uhbsLru*eS6-vlhOLaalRdHT0H0tud(^CdR|pNdIcK!2WI+mq9a z#4v)jz+tRK{?ps$%?MY=3~?3Mv7Tr4jw#tOMLVW!*KE1(+R-s{nXWPZ1EYz^ukHTy zls%xH7_H-d&zzI*ojgd4_kYO6M_qi(#m8MNd-KmjJH`A5U3|#J$6S2e#k47G_GY^H zkc*GH__&L=gBJ6h=i-AdKIGzKE zi@8R&^URH8x-x7CiLQ-@FWIv{cSaJSvG}_4hj^c#w{uBNYzP(i#mD;?X`10|EblW< zBqN)S<@xkfUjS?BIF@%ch2QJzq-oyQp)4BR-?Np+QaZ>xMiWyQl=vIj_A`k*vRx_) zy1bT2$;=m7+>*)J#(pDF( zsau3VkdNM)I%hktc#cWg&g+%g&N~E}Y`2cOc(b%i7s&^N=Zf)T@Y|)=sXR;<=(kJE zSEpS{kuMe^pcj)Ug5NH2En1B8)7qsWKCC+J(z>;sH&@Sg-m=?tHSa*ROEqi)y!K5= zXqR9MZcdaU$Y)Uy@h+>sbzNUnhf7-#+NHd{A)mKL|8_$2ds`%&wr8ts8mzx|2_Js> z+6RbOrn$~J(`u$|+X`zRLc3(;Ug`l#_o~};ovUd>ZMkiY`|Xmq*1KqKA&QdFF0oze z*m|(+ztonYT`J*F=r3VS9zOhvc1hW2oAYh7?E_ocPYV5|T)yO+3;m^fdyuBu8lS6a zqiyZmrJ2|MXcF2bwo9JPw*2d`NAit?cFE_A!=YVbyX0)Z6^`RU#Pa@ zx(k1uLVe#xv?Y{I>|yfhHDC8I$H~x&uw3oZD@v|GnUnzaXd-Z2dVt^li4=Q+Wk&dI zrF9SFCD$OXpLGv&&W2rayQFN`&G|O$Lc0{&rIl}&>e;ZH>nzU2CiL&|`b#d`KVz4} z;cMgfHa-LVsx!>#W#3!7T)t*E>UuoORs5f9R}1#m`t9J6=<=f@6wc1O_P6fd+N_*g zpO|4sr@qg?{Qi|qk7S(QdbBY($^Y#BC-^^k|3{+tAMQ`^A8nOUBSe>wYXF3EE7)%K0<7ejxZv<$EzJluOp5FV$x%{bY0f_MB%E zRqC3uc^+Bsa;3SS$$z?EQnqexfMQMiCA@xun`FPGD6n6XBAxW*UUfcm4*#mI-$!~` zzli0BE?v`=V_rYTzpCpGkbb2U@M6;EBC^W+bLl2;LHQxl%lN}GFG4G%NLPj;nH?*z2IHxGmOA~`x_cA%J9^xkD6&ra zoB|fvCgy%6k!51;O%&NB-UlqQN?f)#k+Q&a#v*&fWqT7Pf8D)_!XMs_geLnHUgHY$ znYp*{Fz{87CCdExeuX)019*A&7P_5;W*1_&XZ8>(8(XNZ^EuQp`@(0p-$S?$^(NN_ z9dz*_7aw);F&7_q@pgQm%)igY2VH!~#m8K{S@vRFtu{}@PFBuGtoI1sqVg~cSY?90 zwut$3R>|k@5gZ~D($FEsEZemCE_z?-4u;;{yi@^5s%r&%SXOlUVz)^6WK+F^NihIxFS( zV3Pk^YfR#$U%uDI9h10MHWsjqV>;!1?g_sjGwXazVwL%`;l?DU@Fz{{kI6Q*C)IdN zVm_<6%z@}0JH}6ENc0i*1B!y~vljL5Sbl)t{-VM-NA+ujANwV8EgWWn=Mvl`(~APj zr${ILvhqx*x_%$&Ro5T7^s?(yhpf8(0O?m26_$Gj6D#k}rI$V55b0(7VHxQc7Tp5* zH^7T4yMK_*LKu_i?C!+f+0Mf3e6L^+tb9vkSew0?loj^jr_H5@F^NnxQIBXzWxX<9 z8*MW^NuB=`V{eIP`29{9lhFPlR&`8bUX4kN`JM=468X!lIAVXC-{lUM$6s0`-|SA8 zkM$u#f?pVuu)Ndl&gzdz)bxEZyRdg|mJ21Ouah|TZu{1)EbNL-i^f~FraIX-J~UyU z$k;7H4YWNOM(4j7!$ublAWWIfa2`(ylYROPv3@Ums>%DGn5UhzyR?4RNi==`$6uJJ z^_%AXW55?&VME^f{ad?PM$2t!gPwPjrv5sI%r2Mf6Z_YzZ^J!bXOOLPSXLXu;r^%C z*q;3U0{+4{a2-NjUR4s{VR+gOsU`SwnP78T;#`4kpIws4gD8WON9Q* zSj~`uP=98um^=veXQ)3z{fX})jQ>nl4)#o_Kg&3S^P&C>^=GI*@gaozv#gc~^=BDp zLj8HkbHeyfn1AH=5$eyfS|Ze+Wt_qJpnnGaGw7e8{;a4XLj766oKSy;`ZLs@q5iC> zB0~LH!JJTkhWazqpP~M&s3JoBS;3r8e}?)q)SsdLtf(SF{aL}BP=AK{Gt{4<{;a4X zLj766oKSy;`ZLs@q5iC>B0~LH!JJTkhWazqpP~M&s3JoBS;3r8e}?)q)SsdLtf(SF z{aL}BP=AK{Gt{4<{;a4XLj766oKSy;`ZLs@q5iC>B0~LH!JJTkhWazqpP~M&s3JoB zS;3r8e}?)q)SsdLtf(SF{aL}BP=AK{Gt{4<{;a4XLj766oKSy;`ZLs@q5iC>B0~LH z!JJTkhWazqpP~M&s3JoBS;3r8e}?)q)SsdLtf(SF{aL}BP=AK{Gt{4<{;a4XLj766 zoKSy;`ZLs@q5iC>B0~LH!JJTkhWazqpP~M&s3JoBS;3r8e}?)q)SsdLtf(SF{aL}B zP=AK{Gt{4<{;a4XLj766oKSy;`ZLs@q5iC>B0~LH!JJTkhWazqpP~M&s3JoBS;3r8 ze}?)q)SsdLtf(SF{aL}BP=AK{Gt{4<{;a4XLj766oKSy;`ZLs@q5iC>B0~LH!JJTk zhWazqpP~M&s3JoBS;3r8e}?)q)SsdLtf(SF{aL}BP=AK{Gt{4<{;a4XLj766oKSy; z`ZLs@q5iC>B0~LH!JJTkhWazqpP~M&s3JoBS;3r8e}?)q)SsdLtf(SF{aL}BP=AK{ zGt{4<{;a4XLj766oKSy;`ZLs@q5dqZB0~KT>W5H2g!-YZelVPgOf7Nvvwh||^TOm& zcb`0S;>1jJ(!C#i;_lwQAU}pnK7XRtTZFFbMgfM-NL)AR%cRfU-&(dTYXal+4clB1;ZX8J=$AN7M@F2kmQ$9hRyeurq@QFu1P=VPntUZ%ueUe;piQ2OAHfUJ{v{bKEG{y zGBnWrlkYu0_l|8*G~2zPGq;eRyM4@&o+#%Ly;W zZAByeo`RoT3x`?Yxdb=K^rFD>Dbh*5tUMFS?w@4__*Z#^dsCv75%E#t<@I}!Vy)%5!=y(#_S6#DUfTk_wP*L;^_ z!~d4_le4P%le+Y#{E5E4nttDE$ELO;G=Oa8m^!gC!P{;7|>e8F?Cwf3N{k}_YN`E+oetb?#{=4$R za~&K0x1^tZQ#F55m)?{=(F3dL_g#8Z`ok&o;|I0mzbmi#F2{!dE$Jt5HGfi<-jqMl z&T9I7m)?~Aa0>nS!7cgk$_vkRZ1~@jesXR#e^Qs;lt0mV)%5!=y(#_S6#DTux8%Po zulX*=hW{<;C*M-dpVXx{TrE{rFp3^52!$e3xUx|CaQVhgI_@b?Hs{6J1bEzwgqU(jQKtAMb9- ze^*|3u4BXhmh_W{SMw)z=}q|)VGf{b{HpKLo6;Xnp&xfz^52!$e3xUx|CaQVZZ&^W zm)?{=5$3om`R~%3(jQKtAJ4Vqzbh|1*RkP$OZv&4YW}1yy(xd9`D*%om)?~Aa0>kx zb83A5P3aF@dChk@HvDf%KUu8iPwLW}-hZ^WnttDE$ELO;H+CI4M{;kk|t|69^e z9#PGo)TKA&Pjpc={k}_YN`E+oe*A4M`R~eWzRR)Ue@ptwBdht7y7Z>}i5^u=zwgqU z(jQKtA15vO@5&3$b!_nSu`T)U%4@#MvEhG9`pM&}`IEZzru>P%qndu-r8lKNoI*dotR??ldEvQ^ z4gXuxPaa>*pVXx{E$ELO*_DOa8m^!gC!P{GxfFQ~JXx^y4SDe8F?Cwgi%{k}_YN`E+oe*CnS{CDMr=Q=k0Z%IG-o@)N2F1;y# zqVKJy-*@Rv=?|ySkH4=a|6O^_cR4ovZ%IG7qMARcOK-}b==-bb_g#8Z`ok&o&7ahzH|0nSc`f_2)%;0a zdQ<*HS69>TyY!~?hg0asFKEesSH6`0E$JsOtmaSZ(wp)pdQmm~zDsXPe>jDH{Nk4U zcjZg@-;#dvl4|~>F1;y#qL)_F@4NJ-^oLXE$1iKie^GxfFQ~JXx^y62zE$ELO*_8Oa8m^rTlM6Kly=b{-iFwDSx6Ltft?0=}qYm zr_hgI-;)2Xd@281(oY7}{7GGUQ~pHPR@3jh^rrNOQ|QM()ROnSNK5{^ z@}>N5Nk4gGHGfi<-jqMlk5tp|yY!~?hg0asKiZQ2u6!x~ThdS7RL!5%r8nhI^yX^% zeV5*p{%{KY_{UoE-<2=re@ptw_0{}IU3ydgL~p64-*@Rv=?|ySkAJ)+|6Tb~{nSXIk>#l`rLgOZv%;)%;0adQ<*HKU+<|@6wynA5Nhkr!D#K z%9rxLCH>^4YW}1yy(xd9pR1jDH{0lAl@5-0*za{TrE{rHxa{CDL``QMU$^8RZ6q%OTFf1+Qirr&qzP3aG( z(2sw)CI4OdQvSE3pWIr_pVXx{n-{3%9rxLCH>?#s`-<;^rrlYezTf>-=#ODKb%58{$NY~ zyYi*{Z%IG-t!ne8F?C;FXg z`hAz)l>TrE{rJNz`R~e?^1mhhSH6`0E$JtJR?VN( zr8nhI^wDbieV5*p{%{KY`1Y3kcjZg@-;#dv=hgg4U3ydgM1N6DzwgqU(jQKtAAhVR z|6Tb~{OMRZYL|(wovBPN5(FZA<>U@}>N5 zNk92?HGfi<-jqMlXR7JQx|l{EE9jO z+<)7Sf-?Hl$r=-aLk@Uv__7#2t@K9mim-u$%{a*nrz8Z<22|U6J z5PDYui?2ndzYth_D-vG=9G#Nqe+^(?;Q{ba;lse<+mPko1Uxu3FaK8Hk;3l;7GHzR ze6jEWQGXe-Ti8{}JB`EWZATe*;*2_YvO)EWY}Pe;-(U?-73lP<-tXqgxq? z?>u6t*^&6lBZk@$iSIk&5%B2r{Q2$#7TO!I@zq8AL%`yDi}(nz_}U`=F<|kXMf`SP@s&mV)4&5%3iAD= zz$1l!0a$!jG5;;V;;V}ISAoU%6!8av#n%+^hk?a+6!9@&@fAht5m2_@Tgq2j}!>fkz6@1B>q-=D!G7eDx4t z3@pBPh%W^eUpvH?1B>q*;wJ-(uN>klfCt~4U;kOaBZZ#_EWT@)|0TfUtA_Yhz~Xy` z`1QczYliqRu=tK4elxK6iXnbG@L*Sd{dWP66#hA2@!i7w?*kTJEyTA1i|-ZU-vkz4 zE5siL7T+nve+VqTQiwkaJowi9`hN{PQux!r;=6?T{{dKhl@Na(SbUEVe-T)GjS&AA zu=oxk{u;3O3L)N(wsEjKzy3XeM+)BuSbTRd|NVi*R|jznEWS60&j%J?8^pVT#dikr z9$@j6L3|PLpp#$!(ZC~x9|tVHE13VgfW=n@@za3C_XP1Xfcw3i-j%@OJA&yi02W^n z#Mb~1=JNcn1s*BSHy@f|??Szz%MKztl{aAAJE ze*qpT{O`bGyPx_08(3`h6GzaM#P&Y%DZpZDpZE-5v7Jx+^}u2)pZFZ$!MEktKNonU z@I!&cc0KcVfW=ll@glI;o+o}3u-KX>-VZFc3jZ{)*e+-On}EeuIq`de z#r8PyF9VCMapK85i|uLR2LX$% zY2t4I7TeLp7XXW`XyQ5G!DadN9|1g4_+ntO-OT)t1r}S)#7_Vg+snjH1r}S_qn z+sVYw1{Pb%#8(3kzB9l6%Ya7;zXn)r7c>90z+$VI_z1Ar9wxpXSZoaw|0J;34krE? zV6hcUd=z-_#Qgd<1CJE`Rba8*%ly9uEVg=yhrnWcm-vr?#nvwIp972ST;fjvi>+MZ zJAemI&aeMZz$1nK8CY!BGXK8;i>+GXuKhAGVr!Oo#|~WosX6`AfyGuV)6W7P zJS|Uu0PslR2Lp@kR_1>Qu-IxPo&^@$tHcYyVr!N7k-%a*mG}~1v6V`E8Svoy^6P&$ z@JQkB1s2<-%zpq_Y?TsU1uV8liC+XPwnm9x0W7vdiGKiCY=sgZ0vyP1z2p=5q}U^Y|jz@F0j~|BmN^` zu^mTzJFwV_BmOw>;Klj%KLb2c_#c7Ab{q5mUtqD-M*JmUvAst8|A58T8u8u0Vmpoa zWQ^5_tu*4(fCn$juYX_Qk;2~yEVj#-e9vJwyC@V6inrd>B}4#}L06SZu`*za4mRB)|T(&oTY<&) z3h{3Oi>(#n4+D$s6yiSw7F#LA9|a!#Xny^_1|BK=X<)Hk!u}?+H9o_&&g5yMy`f4=lDih+|-}y+M3Fu-Mul z-VH3aGl=&9i>(aei+~3|o?rjbz$1kp2Q0QLnE$(g#a0FJ(}2bH1o1O~#nuGzmB3;< zg7^i%Vk?698sNd(^XtDBc%<+T0gLSh=6@rw*lHkt3$WN;Abtn1*jgaI5m;;|5dS=| z*h(P21$gj|{QAEJJW}|#fyH(K^Zy>O*eW3Y2(Z{5ApQ$ru{A*aNno)ZK>S%?u@yjk z9C+~4`St$=c%<;Z1Iylh=KpVC*{e?+-4oZpAuoRluv#2bR6##E%D#)BJi*0v;&*eZV7y zp9w5`w^{zVz_M4H_{G4o_nP>Xz_Qnx_y>Vy?=I16cMB6aNmd>=h>VY(09f{l63+n-Zpp9z2;h;z7X!=QP3C_ruF$mc5F^M}TGTA@TLVve%IK zCxK<}Ao0%t%U(g^qrih-&98qm@JQib1(v;g%>P@!vR99ob9=J)j`)v(Wv?Cap99O@ zIpR+M%U(I+JAenjo?ri;fJX}dGqCJkWBz{wmc44kUjdfAXT&FfWv?0W4$LLW-ZA3S zfn~24@mauw59Zf@0PslR2LsFAE#`j+u*(*hS z8Svmk`SrgWc%<<60?Xbd=05-|dzFZ<0+zi;#4iGty+*{Z0G7QJKmdxeM(0S`W$ zU;jseM+(0cSoZEP|4#wSULE2TI2z{V-viuN_?Li(3jaE=?3H2p+kgkZmzVzo;E}?A z3Y`3Yp8l7>sluNEj{YD||9jxR!gm4>75)OS>=ohl{{wh%EHD4Rz$1lEIs@1L!#w@# zfMu@+%by7x{ZXF&4ZwYc9|$~D_?v-cuLR3K40!OzdHEjjNZ|{CW$yy>e><@3RUp0; zSoR(eeOUkxm4^@#_-vi6?% zI$&9APyA!RvUZ;MCxB(GJn;>{gWL1#zZ-a@@Gk<(+I8mt6<}GbPW(Y&S$j_WyTG#6 zocND`W$ife?ZC2DocQCwgOBCc{|xX*;eP~{wcE`9e}QGKHu0B$W$iWb{{xn_*2H%M z%i3w;lkbJ=|8;)7(|`vG-xqkK@HYa>+GUpC2`p=siFX0Z+GFB}1It=t;(1_MJ52m- zz_M1DcpvcKlllF82k=PYCj!gbUFQEDU|Fk6%(WJ>_LlfLz_Qks_=Ui-c9!_%z_M1B z_;tX8zs;}z!@whje*{?8t}_3R1It=f;&%ee+Ee161(vm@#J>P6Ye$LS4=igvi9Y}= zYdeWQ1T1SciGLqh)@Bm_39ziSB>ot%tgR&e8(>*0N&I)fvNn?VbHK9Jk@zlPS=&hb zWnfvWNc=y*$tdT~%$c~p!lweu+Ct{P7qF}qB)%W8tPLdoCSY0XM|>WztnDNIR^ZV; z=GW^2%i27q?**2%cEkyAbUa_b^%&qj@P3?T`sKhwg`W&8Yu%Wx!?tL%UIa7Ad zl$|qW=SW6JI^W#>)Vc~f@Yl$|$a z=S|spQ+D2zoi}CYP1$)3jDZAH{?aZ3O zomo@5Gi!=>W=;9dtRc{uH559thD2x9(CEw>BAr=FMMTU}aYELyR63T5lQSo1PSTvH zSy}5?Ve43F>sWE?Sb6JMf$La_>sXQNSeffsq3c+w>sYbtSh?$1!RuJb>sZn2SlR1X z;psayYSo!N%0qj@_?95rdSQ+eCA?#Qw>{v0x2Wh`4%NHw&9V?0*D~lZ~j2$bD z9V?Cnyb9V?n0E1MlFoE~^i}cCGAot?YKK>~^i}cCGAo zt?YKK>~^i}cCGAot?YKK>~^i}cCGAot?YKK>~^i}cCGAot?YKK>~^i}cCGAot?YKK z>~^i}cCGAot?YKK>~^i}cCGAot?YKK>~^i}cCGAot?YKK>~^i}cCGAot?YKK>~^i} zcCGAot?YKK>~^i}cCGAot?c%!?Dnke_N?sotnBuz?Dnke_N?sotnBuz?Dnke_N?so ztnBuz?Dnke_N?sotnBuz?Dnke_N?sotnBuz?Dnke_H4b|v$ET>vfHz=+q1IUv$ET> zvfFd5y=(4WdoK;XX#;w$$#-qOYxG^K@0xupyFDwrJuACCE4w`_yFDwrJuACCE4w`_ zyFDwrJuACCE4w`_yFDwrJuACCE4w`_yFDwrJuACCE4w`_yFDwrJuACCE4w`_yFDwr zJuACCE4w`_yFDwrJuACCE4w`_yFDwrJuACCE4w`_yFDwrJuACCE4w`_yFDwrJuACC zE4w`_yFDwrJuACCE4w`_yFDwrJuACCE4w`_yZ@iPw}FxDy3WL2o5hxF(>5tnwk*=# zN3p#_XUXw&cUAw;v|O@VV_M?Mlp<+27FVhs7F%O$__O2~kYq1Z+?0pIECnc9W98Vi zx00XB&dD@Y|NY!pD+1c(hpA|2O4r9^T}P#zwg}h?mOq)pSNsfciGDBvX$LsE4#~9c9*T}E?e1Mwz6BdvRk*ZTeq@X zx3XKevRk*ZTeq@Xx3XKevRk*ZTeq@Xx3XKevRk*ZTeq@Xx3XKevRk*ZTeq@Xx3XKe zvRk*ZTeq@Xx3XKevRk*ZTeq@Xx3XKevRk*ZTeq@Xx3XKevRk*~Zr#dm-O6s=%5L4t zZr#dmU36AaT19KMvRhZZ)o4L=(OgA!72Q>oS1Y@9E4y_oyLBtObt}7dE4y_oyLBtO zbt}7dE4y_oyLBtObt}7dE4y_oyLBtObt}7dE4y_oyLBtObt}7dE4y_oyLBtObt}7d zE4y_oyLBtObt}7dE4y_oyLBtObt}7dE4y_oyLBtObt}7dE4y_oyLBtObt}7dE4y_o zyLBtObt}7dE4y_oyLBtObt}7dE4y_oyA3P54J*41E4vLVyA3P54J*41E4vLVyA3P5 z4J*41E4vLVyA3P54J*41E4vLVyA3P54J*41E4vLVyA3P54J*41E4vLVyA3P54J*41 zE4vLVyA3P54J*41E4vLVyA3P54J*41E4vLVyA3P54J*41E4vLVyA3P54J*41E4vLV zyA3<;HmvM6tn4^7|IHmvM6tn4^7|IHmvM6tn4^7|IHmvM6tn4^7|I zHmvM6tn4^7|IHmvM6tn4^7|IHmvM6tn4^7|IHmvM6tn4^7|IHmvM6 ztn4^7|IHmvM6tn4^7|IHmvM6tn4^7|IHmuM#tk5>B&^D~lHmuM#tk5>B z&^D~lHmuM#tkAAlpOmzTmN7u8A<| z1h)nE1rG(+Fn4L{7u*)y70kI+#*YOrU~bBkE4V9|b8se|;2P#2Ogh1B!F|C)!8Q1n znQlQaefgxjf`@{~f*0URH028J3hoOY3$DS3X3`063+@XZ3a;HG^$Ttb?g}0X9t&Q0 zgOn?{E4VLsEV%Zgl1^}2a9{9HaP4NPUvOJ+SMX5qSn$FdrCh;X!F|DF!L=Wgbb{N0 z`+|ppYdmuuHd2IvEYTDl5z!i1@{Gy1=q0u z&D1ZrEx0duD7cnN{es(qyMl*;$ATAblX3-j1@{Gy1=rpp=>)e0_XQ6H*KU{k1-Auv z1rG&}1urZ}xq`cb`+~=UYdI>BwheZfP)wO^L{ z1-Auv1rG&}1uxtyuB+!ovyJQQ5J zU+Nd!7Tgs)6g(EZ@NOwra940&@K|u|J(5mvTX0|SP;l)(l==m?1$PAx1&;+UyjRK< z+!fpxJQiGgpQIDq7Tgy+6kL11)GxR#xGQ)lcr19~??}0VyMp_I$AW8rSJDY?3+@XZ z3amuuHd2IvEYT4lqBwh zeZfP)wU0>sg4=?-f`@{~f)_4Gxq`cb`+~=UYY$60!EM2P!9&5dN2GqiZNXi^L&0Og z3y(^%^G?g~y$Kk>1LFK(U# zzWBJs=QVWkp^sinPPaENZYHPCJ@G_x`te6C@%Td*%;nPzTzK@s%?rut2OoX-;fEeU z`bQqU_|R#bcXihj7dIaS_p8G#NIHk#ykw~dSs6#T4L^pjBLQgQ_slmKvXBZs1^jya zG~JiIG)$u9-6`Sk<3#||z0L;Be@(Xr%CC2XbX@zSkV=5<{(k(LLa%*lF1h1J?X~N1 zt%e`lbuWG_?+ku~0S*u%4-^>3-@66t^%r^2kOxW;>pd{~C8QhuO>^W_asd&n_eT8K zHsuL|$rnE{mwb#70$Scpp#5~M&(0;Anh03aWxm+8(~tganx08BuwnaurCv7?aQoXp z+WLV{y#2njb8}h}%bYyv?BzGu3au>Mf#a@z&}#vXA6eFh^m>>6yv4XPcVB(A!+_z& z)mM{V@2bxhRB|bK+jpAD>(~hfuB$Z%$*E6*HFtM-;TK-Le(vhktW_pa?!T=5?d_ua zx3{P3Z~i~~Q-5;PTb4JVV_;>V-v5nvH^cjP^i6NM`YO_Qk{92@Jaf0d{liZ`|CMhu zoDa*(S5dO9MeZ;4_$%dk_czD%PbC-l@FlL^Br*Mfj&|*p`W)@r@0Tz6TsczT<>X!c zQBL{aXSxjSoq(YIK7XVZ~)qnz?B|IywF2-@%SCzt=*+fOE6t;nB@|4x2T zzI}f6`JZ#o^Y=Oazx-V`akl(3)wKNR_@L#5^*xz8c~^6nldpfFhd}uJ+voGj6($mJ{qM^6pU*vyU#tc7nOda%e))TT{;Tk3`u%@7 z`Ns1-v}}?;z25Hl)9bl%-1t)U{kj|e^m^6bPZ@u9_I&)4PdC}L7QO<)i5i z{IFiklPQfOW|DxgMJo*mMDHz1QVfE&qPd`m8dZUkR8xk9$aTm_L=@7=%&ar>5qf%d2|Of9V>c2mq4m)GW|24RTfEq8nnt5 z>E8pbvP9a4-RzJ1BPpN>9&vx%zX1LEAFzIyV1L}&;p~qy>)U06huJ43tKrRN8(9l) zu4D0~=hgAUvcisI*&GCLff$2KTX0u!U+_@ySa1#U$@B|?Hw3o@cLnza4+W0}*U&8{ zzu*nQL&3Aw+jUVl^Xq!MvCt>Q4|)USOCgoODPTMn32xQEeO?+~0Ba3|eo&^v$Md0n6zzXYo3|J4cP`nDAK5*B)%>8peLVP=`H`HT zGH0G5`a$V!E%FmbKd5~Qg+G;^kK^VCUBE3GKj=E|H3QXUVP5Bg>dRZXu~ui+s63wu z^LOwo%5Ta?BhG3e0j6!zLOgAEZHu3T*9H>rU)M16r%1%|i}H6QUi0{v`A3K^tG|gv zjL!q+@8Mrr{WLsE?_c7J+CM=2R$k?}hA0QV&88PwW>b7GddXD& zzxsAGkB`~r=tnJ=5A|K;^^ed0B0sMBx_rKCm}RQ(ORxEO-Y0Uxd1Jyvvgk)O&p!Q% z8)OVRjAH@mcL29M`hL**tTUctjy}7juT?*42RxeLM_oV4e$;i(kGlRE`B97fr(FyH z^o!Q;GyYY<8-lxn`+|pp!~M$9kD4TV@uO146;cU=e$>CN=tmt@^rL>Sq965@ihk64 z(7q~u)Gy8Qqc+Y|@}uH&x|P?H{;`=v+kZdmZQp8|-a19ca&q0S*OO*`w7Dc_y^QgL z%w_9V+#a~ywu7m->%0&dnX`hzwc+vT~9!1AI*F-y zkm-4%OUX{xV>j>|a2^6@>`ef43j;;|M9=(9@_dTw`z-QvO5)iC+j z*<<-VbaEMgni9WT{&uWM$tOdqrS zCWK@!{ApoPAM@vd;lIT1wtqQ~QC5E0JV_P#@60HFB=Ng#e-8^0%i7 zwzt>!c~~CepWq?#a7|^c|pqOy85{djFP3bG`q-qgO%eyMpO|9<+|_q<;zY2oJ2b z=T|`M*v$A}1+8N_X&jB?##YiF0NIkUlJq8M9Xm;X7<7sb)ADh&#>D#nCqR$9_>X~Z z%GkvGp8(zS=-&a&1;tw4KLV*^5!3&tpml5@{Ta|YmXQ8K(E99?{w!#H)=7T>v_6}p z|8vm#ER+5(LF=b8c;P zCG+W=+feAS;045)as`KTZ)3Txb8j0pX}93M;Gy6eo%2y4m4f3H-g`2Oz4CIZ%U*<-g@X-*H{0a~$}BW9lwbG~USBu^8(1^4TWm>2$=rYZ4RgW{YX zd$VY5>GYgroYOPHQ?Rx_&Pj%I$&TLfoHqH4amIN5a^}qAoN)Asmik1a{G9MPnJE8J z{@?H3FS14=t_c$TB(52W`a}8n5XaAQ{zUmH=TDTMa{fg5Dd$g=pK|_0`6=g5l%I0` zMENP_Pn4f>{zUmH=TDTMa{fg5Dd$g=pK|_0`6=g5l%I0`MENP_Pn4f>{zUmH=g%>h zpTpWS@t;7B%$|uw1U%3+G~O~IFV?Qv(F2Q$h~=WYGF zEx#lAeZFeg$nPG@Z=#dR_|ud4-L{{L5X;JMN&IfhAIvCU*Fo>Ld|fxKJomBT{~q^D z=(=maTn)2)U5CBf_UpQBEz`#=U)OQ(wtQXp?U$=zmapr;cU!)$8`m;@Z1^vGDt23b z6YE&Z))2d@3#EG zjPg?`AA91z2Q$h~Z`mXNCBM&i4IBRNvHa$(<^1VM{BHS^ z{A79gEs5W4`GXndr`X)MC;6BB%5xtZ{_nB;CJeMv`Iq?J@+V2l%Wp~iZp$CcC_lYz zkNlVXKHoKL_+L^!@2UBgxTlwUJZ}dtdULifNZ&ywftO!}RmRTn1xZqTaRlKwlORhK3G_ds_<_ayxw=#fYNI%w4`8UH9~)g?*) zCTP_SN&gn;mgsV%p9HPC9qFe)t1d_Slb}1Idy)Rfphq74pMh50it+yxwCYl%{~2i2 zjYvNaT6H1P{{?8(ZAkyupjDS4{ojJ_i0(o9e*``9=>HkC>K2UuUqGuaLHf@?t8PI0 zMbN4Xkp8!z_1#YT{{pS=a?<|}bVuI3q`w1tYx;YmBJM$T9^5VO_44b^z zrH^pKhChv;LyJGUL zn7ped@2bhWYVxj{ysIYfs>!=*@~)b^t0wQN$-8Fqu9>`RChwZbyJqsPnY?Qz@0!WG zX7a9?yz3_Ky2-n4@~)e_i)WU+;|do2upV8IaKHB4W<0x~=7hARwfc?paPzK;}A3GloGh-1q8C%${d+}p= zXYeC5kr66{1IF?9ZowMy0aoAv(-4UD9!NicbdTY=gvcik;m0uz-EP|9?g8|d?@p4x z?Pb*Rcx!&TT65MJ6ie04pjcmAN)60DgW~tdFo3<~N@q~K>F%qqc1$L6qu~2?U-@@U zlZ5BWU-!*9bIZM+%{B4gt+8Jny_fG_vM$tXYPt01Es}ouxqIw;y(g2ey@yF> zpG(hFLHYi<@df2SmHfu@%o*|#d~*C?e3Bg28V(G@b`1v&a}QKjA?CS2nO6`|Qqo`* z`*%%T%?QS~@H?Abnh5dv7~scvEek;hj8D->uJQ246iwi_&kt*SUYj+Jn00ng{+55y z3(tGuyx^?zUyJXwvoB~f+zi~pkGv%fS9mh;XqY>Ww~W6XwDMvqon9-#&P(&pe8 z^i71>Pr_1_@d7w=o_HXfv zOoxknXG8TXd}n{LmLzXSyn>b&zO(DNk4;Sktm(3Iqn0bZvzN{+uT*_!-z>5KV<06KWk)ZJCIKbmE1^PUm zor1RXHGgZSO*3@mem{9CTX$v_cbG*uo?G|u4H z;4D}2%GU|V8($|-ok4X1O@BMmDKD9x?{wwOe&`5yp*%th{HBhuj_|$c0LoaPBPDadlsRTlO;iGtHsB6s97bqB2^o3iH&IfG*v44xVBHfL+NPPh=AR~8qHvXMx z-#felwY*SYxPo+>Iq5QepUfOs2DK{FkL8PO83;qwn}OxcDfXtt~eB<>X!c z5qiR1mvr{qZM~k?NeF^IFdssu?+gawqo}0s{L8O2O(T6D%V1zGP5yH}g@e%tSsCg* zF#hC}@AvPq@v+d}F#BZegUH)5pku|nUI?&1RAKm-0v)gTPR;}BJ1zWX=~Il)1LjZB zNS3d4`RRDAgZLtSjPWDM@8{Dn%Woo4QTdGTA$~9VT7p8hw88+-2Xsj0@q8l95!BaI ze=E}0RG(9Qjl8G6Mtw{Bf;8QMJ>fm+Ro=MpazFGtxb6)MARpB4eg)Kdluwxt^t<{D z{m#yCathYWQ7-xuk9AMqt54{AcqlheR~3D4Ea_D5TR@vlKEWr&Z*+kVoIol#)B|7e z(l7~FU?9{3nXZZ+I6ykefI=#PP!C)~VfQ0$mLAx_Lt8};{Da`()+P{h+){WJ>6*Am zJrK))3iZI3Fqr(BW&+moLOt*@?qf42U8V;%s_B7iYnAoD^JE$z>Vf3K_Z?w9(CKNF z^uTLnt}WA(uUrv5+1CRL<{~dA-*~=<{?6C)uUw%l2sl02mG93L7T6J;vJdhn~%~FoY&Lk$U!f5xxT*&OQ(H?8eUYY_k+_(JTdA^wsQ! zr*bz`)r!GX4cdUvC9w=u{tUsrHn@L2Fk(ZTQZ9>x^BBAmkS_4wiT4P5Zj@B&z1 zAk@K`&L3|yT{w5!K|0EZLMnk!2k)a1EyT^z!3P)+s_5V^1_Ot-kJxKYLfyKBi`2pS zyz=(*e6jbSeGef{LCXtu@EUGlQxgGex=aUOi8}b)Rro%iN-j|NrgW(3^-3ql7wdGW z8>_5$d-O9+GAOaWSQE_u=X6Z3{AQ?|I$CU$o#~jp-eKsNPDhS9xYyH%u7j_5l_RKQ zSTLlzME)xyPao6q_N>b>8Q{C8g&*}IO^cudUK`-Y_&i|#6pdv0Mfp1tpO>F`MkVnq zzllUedP5hz`Zh7L5(}%BvuU68*m(SEI`@vsN0|H=WVS3L)jt;x8e!zoXKbh11 z933sxF^|rAh@AHCEC1Q|2dN|Hl<)I@AJ;3y^&;eT9t;K(HqZg_-`Q{n;%CRvT-MKS zCf&2U)OXf=c4;DX)OCEneY(EWzX85)I=D&dWqH7NwCZ{OyGhfk4L}>j_j_qP^Yrkq zY`qE$Vtn!beAD(@cX9JwZ z^(Gj`zF<7x`90}-(szT_z9!uSseMbD6Dzx-;kP2l_B&361nvmJlYZpSxU`4`O^=*2b9EAQ`|S{3Vn_0GXjx%TO-%&-nxUUlA>Err7rT&=*RH0hn(L?mw?jSfzsDuavLXe9ZV1m6Y{g2k~X?AI*qwqLD@U z{rk(i7q+j5h%LX-UU=RM=LPf1oJe;9=aI;3+I&mEJur~|1Jb%DLgRHFN$Foix`D_F z(^LOe*&xkwR2E3T7qs?0>0bk_eNDOrTKkT)54*8JoeZFjv_T(7fv<-EP=*2d#d9HtL#hm%^CXK%4f{E*)bGWO-_rE`Xh+Hw3o@_XVF6yY&X|0Z+kG z!YTY{AL8~6+~=j?1%0Q5b}Q5QrlF<_?ba5{)4~x<@gszG>lG|My^QO$WjW4J4%sd~ zH!NH2))o>}v0HzO1$m(DBSyD6_-&-Sf{V0Ux&D*&=Gm=xqJ96d%a!pZv|HC;LvH4z z%k0+mXt!Qt>&v3u$_D~ZojEtIlHIz$>+eu|uXk{BL%h3#EI-<<KatLZ?{T;-Y zwSP1tzKKQ_<@fI|?_Sux9wN51!2zBR=#b1Sb0W<(V7IbwX*XU&cI*0K*sbf{-0FI? zTPGeXpPN{!R z1LAxuxp4I6TQj>Ot~q26<-uSu%kFS%ZpHpRdgp-C-^KYXe2-)TbWGMUdm<7<6}^pl zsC(pr(R&e5q!)6$8%R9R6fl2^MzVZ=Y}AB)`^xNsvNeGtDPPOuy1_5 zn7kzI!*1qR^o%PORer`5UaSxD04uYG&n)3HEBMR;zP$Mr|BNdl!{=5^B*6@0C7L!X3c*L@X%J7|9CNYxOFTi_NDtJq-)|L z=Re+nA7v+R{^M4(k8_d=T3$H+@g=0&)I`9VE)&zms7LP5|Clp>;IF$XIHTz3?Cr_) zNax?&-*sune1AP3m)=bO^)b>T7rg<%8v}~;5nuNShAmT&j#p63#z3+DLql1^$G1Mcgf1`8itW7?;MZON!d zdQ9VIZw7ARr~bmjIxBQb z>IZUg!2ZaR?=H^tM|vM)TyY;`jQ+?ZiF%|HUlY(Lkk}uq4quO~_^rnEr8B94+23Be zENjo>yf(W!o7es~{TArZkM&x9d&&7DE9o(B`%W`?ovc}aMaXX{p86zQ_IG!1Tgmjd z6nQlla`jA`-#iUiCq3uNQ~q_5m%q!>cJ+N~=&{;9EibI^$>duV%g^+{?cWPu(XEe19>^3cx^0rRvZ-lPo@Rq>Y&kg@3gSZ0b!%Ifb(d|v(j{S}?bKSKT@{>%sW6Oyy;?>Nr; zlNZ#}Iqy$}g1jfqdH!>{cTgM8YtRr>Fupt@jiUIvh1%>g`v&+E8AN+l=vE+N2Xg4+!ovw z+!s6+d{Wj7+{ca)NClq)rWyct81T;n;svn4K)7d;=`cO+K+}bLCVNOn`A|qD5Uv>* zq7f~`%~~@s!hld^&A|79fkWFz>@_EO1?gJ2$Tb7Bi^-zAH3JWzeIG`gf|eJq8Cbv# zY-%E4O_xncRQx__)X_68PV1PJe7#3lM_;RQCV%f&d>tKo4FSF0E_C&2{y7~w>gZsq z*BrF4zz@6(DC@}bdL>KB?8K?l4xz^_P$ zW&RY6Wcfw;JBWV-@p<64pJjz$%EZ6Y_Dg(T{dqj`>tLP%{uSLH<5M)Otp1L~=hg4u zU)0evS)z_y^xZ7V3gb_Zjy~)Av}UD66&>CCiq?vLtd=silkaBL@H|Ex9ZUm69sRI% z^lIO(U0$rdKdegw0}%b_(LB zn7r~~;@k(Me=52BJB(LBkUC#sT@Y}qq*OuwPEpYO+vLTG!fJSmHuC^6H z2fhwoWMj0DvF!c^5}#Lo6&r&#M464DHiT=m7hs!5_{a9;)zA1QZj$BC;}-(+&{wz> zMhKmk$4@%z{*L23Kxku7c4%`H%>$74jOV!++Lxrce^2|4^e=(dz9RiAptWyE|0-zh z3(`L9W}e`EQa}?$ah_lk^y|@Kl=)zupwhQ{OAQhG$pC-K!26Kziu;f+>z>1;;{q{+ zb3<@ja940&@KA77yJRT#%SoF>N=nQTL#!7`y^W@;ntZ{+V}RCe?F}r_j=yVY0&AX zu6(CI8g83)ByPQp=rf(9{+leIntp_OO)bUx*R+1RT(SI&KhB5j>tC|3(bL~evo9y# zc)o{_yDv#+*AYRV%fRu+mGA411^Xs<_TAk;fAq^Q&>ySorx|}-|5jS3v{U`@hruzk zj$|cc9YgvI73mRtW)(2pOo2Y{d+XmATZ@{anDu9sF? zeZ=HF<8KG<2ro&~N36Uht>-t8SEPN|jeey|rUs~!`qeL>z|W&t_F14`Rr)ULqJI*D zuSv-#SXu5I&IaBfhTwJu_XUpy7wJkTWj)0UUe~3#XTmA`uv8%7^GtZzOG6r6WFXXq zn9f%>G+nr!f(5gm6;cU=x)9H_ZX#}$E;OiB(}i9{Iv=zN#QrV5gmft`QWv5Q#B6!G z&?|W0??;@1mKW+m&)_~bH4(6;%XFb?-&b8)U9YSQ-9V-RcAyJYdY2vSn%hu^aJ18v zUaaU#I_NWEv-x(X3*_iZVf&Bt84#8FKMmGgw{q58XS%MH!QB5&7j*o~(Un7=aP>9U z?0-CGzOIb^3Cr_zS)2hfmpqmHL23xw@A!lFtvnB5JEzx-!#!Yi$sK;bRL4WU-}As9O7rv{=I`KlHZL=-@!c}Q zkNSqzg`fjoYl0y~x*+rS5YO`S^5?b56|Q-ZvC94Fdoax3LH^SFLwwQwRcT)n6_?&W z;*0Lz?;qL|A$N#BvC{-S+Bnro7K!h6y_>_+$9kOG=0in=d#if^KP_FB${D^i_O@e}Hs8=zS1- z%}Jg`y8CgFdNRM0&D+n@lV8ToZX!-W%M117&*MJw(q*z+?Hi+uXO`Bg`V9H4A%d?b z^FECK1rNTqHDHO!!+%VxaNNgPy$|BujAOb-yMz23$5htHqhK84H>|vF^}}{U1oO=C zC3O0Uk3D>G^BnNS$1Ogup^FcF^kQF^615fPXF?|-gnm%7dIdL2x_PdydTPg%7T@dEW66eZIVuh45stt zM8o0u!S{?0T3$GQFkPkb1L-kd(ashwIy=kRiO0&$&g@3lerLy-r{Re2EzW8G9n#oOSTmG(*%=??k|t$emQJk5BZDuXYLt=l(oMl@g}WbIKqDa7tIL|kiV?{biTZP z+TBI>U#0#L@^1z0RuWOAFpIw@!H-AY(hpa(rjW9)ems?R_2a2*liol&m1WZJ0Ijl1 zntnNzMbbtlM7BsjfOwTP(&s>{?2tYWT4jawBcN3_NM8i4eNEbj-Pq$Fmjar22x*UB z0(~zGN6K7akNe-|+L2$8A4;&x6-~B9b0XQI`2_XiDnFyJWWS?eKBTZ@QZD<4+j`&Y zTABD>*PE*QBFDHN`XJROxq$JM^oHQJ;I81l;IZHuSk3hG1sPwa;I81l;IZJ7;FD;A zXZLwdgcLO46n^vtfE@;&@zU@DSY{yfNidzCRMXK{!LXLsLn6wfLMnmKCvowI@T?(j zmQQm8=Rp;p#P{fA@Ic!~jBa)C3et^mk;!kxkIzb;PvWH;lH@ZkSH_pnCvh|U1DiSN zoKIr4+IPI_ON*7~{(mp}Br2TW@7Xlh*!Ld}+UBOX_j> zEw_~6pTy_gKZ3!IX&mzS`pgxPskR{wg;In|?lzpf1 zpnVogtJx9-4A-9Z=AYkq2tJD;##Q<#Lf^#(SfA&+7|QjN;7K>T{ar&!uFidz0UY(u~czXbN`!^xXv2Fc?G0ngy7@hj^A>l%El0^|vIxDE|NvMfcA< zO*Epc{GP<;l~4UxVe-vsujcVo(-WIA#ZK_AYnbsZ#Fw>iAo06tAM>PWWD$SnwIKy~ z*8N=z^W5YeZ7}MuDodnkGpg*6-XIU9uSwHp)V?K6n^F6cG@lvm8`3`P#>S(~N$8;{ z+IX}vFQWs|q|nCmzoEKg8_%1CUNq9TJ>h3R~PjYtELTe*vzniwitU#a940& z@KEqra1CPz(=Q0#5Zo3#6g(DO!@V=T+HEJsKJy;L6ucpv!f(Pp^U^RLEHN-;pCMf( z`wZzQOA4t3Li_CVFpxfqxLI?`9W=Izef9^uDG&5Mh`r_{&m!HYaFO=ekK~_>`+vj-F|@}*TJ5uam|OOq`-xz*@4ya>y4X+A>s4Kc?))9`>?si@ zXWwxXvia5Bp``eF+^%8J=8syy}13c%SV% z-_~=VJ~nNL_MNpE^qI4BE?KYZSbrNXG0d@v(8TY{-h-HeCWQ9g4O*~`cJ@hV-!WYk z`z}Sgo+p;6lpET2->hig4Jz7qFIKegUaDx{U8rc^wPxCP)xMD&=ijQI9U9LID_>KY zV;>!N`!46(7}jpXJ5cQTr;{)JJ_no7o(t)#bN2LJwew_v@=>(Uzzq!I(LT$hVr~!f zZ+c*=l&0_O;MMEu(%0vfyD}M|Zl>V9;`Nfz3Ok_Ax+{|b>IftJs7q>H2s+@kCK_2} ze=vU!@hrb6KO@TOZ%KSn{sAJmek~7}rztvgUc70a#OIao^KZBI8I{u_{;+%T zAo06tAM>Q>_^rH~$F=!_>v}m)W;D*=YrsCEY|(x?LGy3^H?Q~EKJ&hUy{ccqwl-q4 z&vtL0J>xxysXTz8edgP6Orr0O&^}|jD)!k3>3ZIvqxFXN*|jtOR_*)P(LRgznSDgn z-U#O-s-MGh0`0SE>m$F)0W7q~Lb}8*vmF4(WLzH^?K5xwo^r7l`z&y(>N~bbkJi^` zk^b%57v3vgr59Rfl63Gp>#j@&Xupi`JL>jX(f#xOqJ0+aGul_TLl)FmK>7~Qd;lo> zq>J{{QMOK)edd4fe4p(z?+fUw`UUi8pHbAfHjv}_JPANB)SEb7zYRa82|I7Wc22VJ_}pE1zG^_~Z5`=E&DR+Gh=Y z`&b<9Gt4iE4(-32l}o%fz`tmpCBe>g%OUb7&YxNPD%xk8=YRb}XO=#+xaxlkexL0# z@00MW?vwDGLQdlRnYA&ZeP+idzT5bFw_tlUNsjLRwQApnUtV6R{GFB!S(IUI^?1Gr zWFYQe(+7e05axe+hr53b`m>z}qtDZ>yK}T#-*~^-j2+IGh4j&wKRZbNW%frrU&Mbb zG@SA0VC^%0N6?%vvZ6Ix9PP8$);^pL#%6I)>2jPpTO_V)}(?`ssRE8Z!OD+hi)NEZVf z&jaZT*7HL2oRD}vi2Vj6-vjzY?PPr-Wl15G0Br%D1=1Aye8v4^&5HZSK2UN0*aH>! zkG+h>RyiMp-^AFIdmWXQaFEgoX*FO^H<(W zE+=^9ij{)w`vI>1WxQ~-$V2u0k%vBiMJKxls?$dMs@VP+Kp!o#FKIJ1#eVYG>Vna} z`lVmGJH6wV-}SzqNmoxVo?c9s&fvp>E6Zmbi(Eiukr$$U^_tpOYX@gvt$F_bwP;^C z=|7(Px1xRJ+gIz+zKZr0&*PtfY5m&ii+k1|bL^Aje*WRq{8g_vHGehtnK*xCWGu5E z;`+dehfau$KZmqFaDB2Bs?$dMD%w|*l3}SLxzMzEbCw!s@HKFLA#LyDbUp@k;u-T- z>j!6F`D+E&qkZK)EOGv-+V{hb?E1j9Gts_^_Eog6k|&dIeU}59J>C5)-}VN%FgU$` ztcralrG)#fLOQMwjOzm_h7^~>v9H#Gd4p(QC9moE7@Yr#`>)7^Y(E3TasKMHoWFvi z_+awbM=mb%-;U3>STi~kwJ0xhLD9a7_EkJTkdNTCbH4lR`Kz_XgR`#|J^N}g z+E?Ci9PO*)ZeJ}$`zqR3(Y`t~`zo}jLVGLPSJA#YWczB#d!cL9z(wo8%=`-Cxdti^ z;`tUy+<%oP7{-cYthxJ_}6xe&B&e^Gr##eHrh=bu7q(>ypWp zn%5nPZIP!nbA902(!tqROP+nT6zwao52Jl`-0iF7XkSJ9D%w|jv#(Cw zebwzxi|1Q>xa#+z;{Ge|RqBF=z5i-$*;Q=bToi^=My3`zqR3d$X@9?Z5iWiySz^ z`Kpk%K1tPay`eS>PVfIZR_B9c_CvI9J>35m@(%-+5kNU;$3vaw%&To$27xu=C?EJv(?VR(i&HT^ywwn)f=i`5kAMLJi z{>1X~)nt2n;{5EH{NLVwD*26{X8EpOX$J(|*)xm>ING(}FTbGumy>sHkB~Vm->wHl zdnX`hKkO%$FZcY$?d>O%uU6zw)_$kIA1nJTr~P+SnLlg}$YRGw>8H@XMH1J)2gjf3 z{-Y*+R3S2Fvo*nZvK4%ew(PQLzyUJie(eBwO%3><%4`M!J>$bToP`uwt@ zot}Tc6Zx;gpI&d8Ki_!1hn7vsPp`K-{`7jT95=qb_#WPQh4XcgYN!0^^^V^60dB>8 z@cY(l4c>PKs##p?_C4pc)R&QQ$6gyCg7JC4^Z!$^?~C$xX4wCu8Tp%-bNgUk<+#Q= zdx$?<5YP5;=_2Fv+Ba+dlX+T5RCNE0A4vHKP66vrAzVfEqv;NQ(1o%9%kLn6S^Xm^ zKg*ScSby_%d#k^P{99R(6CqSx3bXi|oIw8v`-=0!Tnaxx2P(}^ljyU;__u=AXM^+x zXnht)bN#N$K54GsRaqx(WI|+*G}qs%tdc$lT4j^;dC;lI3h75ccR*|VE`lC;@gE1R zvcvQp&?*b0eb~)<;Y(5gdBF2TKMnfzSXRtu;wF}#9YoXEUw_MrIrV1M{9lt3aBz~& zk~tY?$()R{WKPCe@=wNT_ze=z4BI;Q<|J7l#(lH}cLnza4+W0}*YM(D`USxog4=?- zg8PDpg2#dvz#it`5Zo5r7d#X^7QBG8On*|oXMTgX{5-{N5l-R9%e+m(eO?;UV4ZF$SbWm6LYYr5>QT&d{KS+O5BPiOmc{wn%&IR9*{p6Ji> z@L~8X0{M6TBIq1@_E+Sz|9lmH&U1gC0_g1M0)I}8!#tqHf4gh9lkeyc+TPxszhf`{ zTz1?}{T7AuzO|JbYjrM-qV5+0^LOw&8%79C{cD6D zZ8EJ3K?l6nL?eyu=dNY}=I++=-12Dpg9e~k4&&($N<~&k(;w9F=nm+S$O7Yi z*e`$3z0j!mOa%U*m80MfTJiirE72eH@WT&1axppm$fFk@I*sq)-u1-A%?Cf?%fzhk zUe@>czMfPnIt5IHoMRs08PU!ymH9J5e-P6_tR1LM5c-39NY~NAkvf$ep+9I;(I1rF zP|Y9ob4cfdwvX6<3h!Y$T$tq#x(Dt1tXH6x7y5%fHPauoTG1c0yp$T4?GO6X=nsni zpl^G^83vub9Q{FRFK=&8G6}TrPxSp|x%S#l?AaWDit~Gz!RP9$&?Un4CY|Kv@3M{6 z)*tjH{h_XW=o|;(5300(K{maQT-_zQC2^75 zD`ofJl6bZ?gevt9kbf)8C^VW@3bXhd{XMqt=s(#2C-qq%t^OYJo;3YED(j>v6Dr%J z>F-flC4COG$|mXapj8%0)8C`AMVkJeL}Z0D{XH#@?tmVMEHK`O{qpzR0h^jK8Tflv zkAlBv)${kPMt{$1>hHM|a-xt*;1n<~bIc`N@Y0ahcYWyZVLFJl15FqDdpbzh(ZZ2B zl^mhJXHe1KlT`Hg+)~lsb8AI^&#e{xJ&(=w_pDX)_pGl}_4nM&1xo<(G)e9NizeTS z*?M|sFXh;4;d=T@$=kluOkU^Y!RU*pK8dAKcXwEi+NTW9fLwcR(hl6qdV8)v=}p?Z z{(c{^cfI?YWBR9(3l#pq9_{tY_7ge&`Q?kg?e0hFyPUkMKgucJ+P7%$1O)A$>2KJ{ z{BY)Pi2fe6m!rR@`hKNMew_S2R%QLqtN)rJ?w*So{+@kU2Q=|Sc|`8`6Yk&A@l5?= zJM*_q`wPSJ!uqQ7KO4W@ey*wUC+-(xe;4y-+8+}AMfM4SO|swqA}WC%sBTzf_o`Jy zn=KD~dpplIX8sO-XY(@S8r9Dcer5ieCK_4fFJS&2;#t176+s8)8vd2l-$Hy@{R4@2 zg?a(jpWL1O>-vpCC=hf*4&HaJ#W#zXd-lX+2Bb?V~eiG&xAW;$j8K2IV z*WZ!&y!w6lnbeGJE0|}5{AKkwVeFLMe^26fTR)AkE!&)_|7cn%%;InK7umj}|78Q5 z)MtUT`ink?>!j%~qQJ7RNmC|Nwn@`pq_Rr-9B7qI(&s^|ERv?bNM(yO{Y5HEr0FkG z*&*Elt+GJchyC&workRPnF#zvYe&IfwC4GX)}p`YHT4(yzMxbDktQ=;0(>VCULfIt zzUxDO5z}FabfD=%f6)NxI$AhVr;;P|7bWnsTtVEd{bJ3E{-O_5^cOu)(O>jHMSszi znf{{nivFUwKB(&X4AEayb-z;d7e#*&bP%&1sk*-+$6vHo#b5N5KjUCO%U^VL&aQwe zStk_zJ>aA5Hq+F=hHCx)0{8nk1sz({+=H4 zm(@>WrR@G&5}$YfRq7ug|CZiRfYG#4n8n}d@3DPH|H%e8sm}sw_4iQrNngY3gVv9N zzsEl-Xg&ISUQ>V1ot`fzl@aI^FfVh=CHOue()z9s{XI;FAC(njF0}F8T|`mrl@~>`7QD{4UoTx z|MS`r1vu}Sm`EDWgEoCr=I7OwBPcKkhy(ccsOJ<;D2zwhbIRsvUp)&i`@#9obLfXz?#SoxJZe9PE#Wzh~Ot8s3kkv;L~SJ}U0#DqnwCg+J5& zjOg#NsuZmGecsQtz9>qXpy=;OlIZW5lnI}rKPj&7iT)n?TW*IesBe|@9TXG@2z_a! z?*eXtrtg&WetrKd`g_(FkAlBv(ew8#Mt@KA_ux4vT)Y0BrReX8{+{UXiT<8r=tjCg(zWhI{9LoS4n$&WjKYwG!%_J{3$Ki4{qFb|@? zC$mxM+X#Wz24cg8aiqCECzbU(Mfp1tUzC3|BY#}qQ@p;*@LbmK6!Ete*Y`k9uj8>A z2GoDTS9k|M_1F9a!Xy0DU&C)EH)U;I^!M2FdvvWA`QgKUo!^sx-t+p>QSkRHdH$ZI z=XG%AcL=$31j^&$54KoQJnCKY7_vYSqw2%maTvOy1rV=I`J~n=%jRFB#!iwx3FE z&Z7K1+yu+lw)*MJHT)~9zlHd+`Uev4m#bm6Kb_&P=}5fh@v*u88Tq5XC;EFRGy1GD zTuc5E>xVPAZX%X`NF(_!LGe1g5{XH^}UAz9CM)dbYe^2!HM1Rjo_xH$1KWXRczOU>YoRaTy zNeMaUMc;ULGdxcxTwk=a@3F`AJ<9BSywmk7+uKhjUwt>r+KE3S?&r$m{-OJO8k4Pv z{+`60IikKTpF_MB*Y}jKuZjL1Ut%W1(cfcbhyEIV?-jw^wq*Su{XNm&qq2~PIiSb$n&WxR^w-=DS?FQF z;ND2m@x12ji8w8v@g1=|g^Y^Sqe^2!Hi2Po= z{+_ky?}`4N=B*RiKph$pSKu@=l5J88w4DGoWBJ83Hk2mo8EHu zRq(Tue68a7I;*dOM*Txepa&iu&+o}3Xou^2)(^+uvur#)b@RU=UZ2e0v+ntO)}y~C`g=s2uT_7~ z(wQ@r{5>m+t1GF2)(?E*?f0FXn^Uce>#HZftk^VmRg#$P6WB3(L-K>!pn*^}zwGR# z9D6O?cX26s+jpAD>)aB<>uSwGa_W;w^8I&rSiIVI49@^(kGT4$?2%q?+8%ka^7l)w z(tl!V5qmK8)*py{t(M>*x& z{VQni1O)B(`6K1I@}<7&-*?IGXL~!dmnX~H-gfkk?ZM^cs|oD&9r1trn)LTP_goSG zpL=ea|6k?DCMunGdo_9Pxt;OiTXzbHTSJL!1#eNO&g{w|w1`@CVMntp!6^1}L_OukjM z{OR#0XZ#N9gTL*KY?+fQGj1H!^Rk2S!}Sm5NTomagMV)Po8q7HC9Ci0G?Zz?tQBFyR-Agr=Oot9>R84m%mJZaQ?)c=iht3^2X;bC;#@J z_YjzrzvrH_{MzaHQ`6&1C#gC$aSi+*WaKJk8?`F=Wz{#>fNXO`}Q3Bo(dKrM?RzZBdt2DY*+6CwZmdwFFre+R#_ z6S*=1Ta}U#e)IupT?jhhwI&+L_&i|#9^zSkQGQ00)!#yVS^WcvFRDL9Bg*RUNPJQL z5#r10Z-U9C_mB9p`mq(P{Qf1rh<^jbZ{;;!c;1{ZFTW@8Mdf4bT50(m#Pk00fc-y` z_`LGb^ip7+ChXiI{xZIY__F$w@3--J_507qq-AcK#XK$KFROnb<=Y&S|9SuE5A3b} z4)T}PKa%n%Yqk{YZ{o(tpWWVn5Baz93dgnig6n#DR{tjP`-Y}(xZZFBOw+N3w0_@^ zeNUPuRZqqe(ncm^Y#{vr;#(el4z!L9j6V-r#{$xiusn1iWrOrZ;6$Ev(jN!ek!P25 z2lU9JFM-x)lkv}h)@PCQr$OtpNBZ|b>a#@pk3j3QL%I)IpB2*o0<_9L=_{aB)=B?Y zpjEa>e-X6GDrp~fvwrh`kOD^FIrr=S8_=)6AxS`jM)~SWr{nNJy4M%^&$!!-w|#}A zS#xQYT$&Y^i)TzilX7v%gpHSe(PUdR`4&yaMU!*UWL-3QmrULzlXuDFU7Ggro4m^= z<+4e+Y*H@U>!!?QQ)Ye1zX3n&&jlqPcv}g(FZp#B&Q#I^fjGZ zxB)V&kV@bbFx|&sg@OCLG`xVWFmR`Y!D0hUhatd$rsG^7!&+Vo>G<3zq!I|{7GAm; z5y*&FD4sC;Y_VPU+RKTm!_AwLOt3SY9$y3+e2+g+Kif zTVb4A*m!@A?JB-0&vuP-3%+eEK1XN6JKt*6wPtZ{;pykU@@?;-4}*u`TkK8FtvTN% z^q+n7%{t%wnm2bRzM;^U`E>GWGiW=xD)4PzZ-&V0U$Q=2&vP)mi1~{qD0%`S)QT9pS53I6InlhoXO`5(jl~vN`K&xz$F7l1B9LB3}jL#Bj z`o>gtNOwT1ERgnLH@>G!QUJ$?(zD{0&MY2|?`hi8l&v2{BRv1nqVGR?^WpoC7QlY` zfi?uU1@{FH1&;+UAT86M6o1d1bf5^Nf=>bSGH;V`!AnD0-}Rxthv_iHInZ>Wzo&zA zlvRaP0-?WW@Wasd5I4);gN2fn{5`iIoe$bRVsx*ATbT|Q=z93{vP64eo=l#l-1ut zd|CYiiFb|i0<1s9zq0zNLzmS*nvuT=CSUUE^n<+T5#r0rZ;HQ$X+y~CGd~UU^pL2C z|EA3O^7>m6pI5&xKSlna0rHpCpTd|ayZ?^F@3#IC@^AS}@xo|YDa_(;^at6#qkm-s zoYZH5wEBZC;W}yhgH+Z@QzlflNz)&svP$|K=mZ^f7KrqDV3kGE^fRe!k)}T=6{hjEwkESV%D30^Y+L5<;76M)52!wl@GJATG%<=4+561jLp;mZwj$`jT*JSz`df%E ztA8Nzu23()`cwQXtDib@S^c9K`I}%eZPPs9{S6RbR(^_(DQaI{pZWE${0^lNWXO^SC=QZ{B-0AspQW=3x0rN7)T*3t}4QZo{ z1Bd<|ro#~DK+}c(p1A(UvM5{sQ?KUlSz4@omfY{b7e$~Cjl0(3S#n8S|6^o9{yBR& z`g@LuzbD6D3;hf6EHD+}D*k}DUy9s{`=wN7e4NS8!TL+yj7rUZDf=RJO;Fva$nH}c zv&dfb?ae&f(Ae9k?X0VDGCWQj5t ztY4`gm_H-u4KZIukaWnTUVbHE}M$Ik3 z;I8c>Mz=b+73oH}$URHkqs?a}Z_m;zSj+Mmmn-8-xM!&j|G{QXy3A+MsN}O)t}m@s z-Luq{dyPJect(vUdRfrg5oPtaB)%yB01+R|s~p$(PFC<# z3B6?6q&BU)=mnUEHf_=U`{ny#Eh3NS8b{1~8cF&7bqzDViGs`c)06l-{`hSQ)EZNT z$%962X@vov59pAbb$=((W@KN`=Hm9N0T@WxBTfBPWr_4#L96VL-T9BrStT@|-Ih^IV zfVR-SY76cP?h76Y9t*BvY%%tj;I`nd;8}LtiLuYT2QdY22&eFyu+O|Sj0cMhOxb5h zSIIs@I?9qlDuK{G`#cP!k0NfCea1QJD)!kQ@TNS_`ylq3lRS%bpTb4jXFrZ#4Zl45 z>`o;37~&MPywE;NF@SDrB4ACI$@WS$`)sB9oN^PkBO%&n(LS@15d3%chtp4wyM30U zUmwPt?7`S??5*voGc285x%WK`)8%8$MaVB#pRDzND!J`%v1Q?Ptoe8H#CZSvhtWQ? z9GU!oSoR^`U&cOMnXF&mK}CAHz7Mx1vpI_IM1?>-FqfIXgCBL&JfM9v!mr3aV*Vx? zX>?hHLty?M;#t17)lXxt;a^$(Er~D6KR`s4`)6B1V3|!sl-1vp_`Lc}nP4*S-`As&uhQmrXu^XgZxGOo!5pG;92)~E!dCb z9ql{Xk1A`VX+NrLk=`H=rLRfTe$>7vt#gj-OVX4%?OW11=cx4|+QDw@$#ar>1i_&_ z$vMhzqC+V&fjzmh7kkove`D&K8~DP8r+NEfe{S&R{kJLm7_ai?0yn@1Ue~$6lVV%G z>^-EZ^m%Ao-WfdT`d$icOQ!S3K}{FV{WXz}a;1<;AhazXz@XGY+$`HNMS?1}<Se3cISN}Di*3dSxHkBC#%sGL&U%e*Ys1`Fh+Z*p&vF*Zq)xRB^*<#T)-QJG2 zsXafg`nT&3-8Nn2Banf<>jKrlCD8Zjmb)?;;5${pQ$h5Sc^`K`opo0x1GK$H_#JiI z^mCKVc9ehr#*TC`HbDM$5K(&n60f}Wi(r{eRC18EX-~@c>(#Jn6FRo6{Vj>lYroH* zBHMI;{99UKfae1`B=cl$BFzc>HYWRmwxZ5$eokoW=PGNAr)@eC*&@9GT4jkeZBy-g z(zHzz=}Xd-Iqh50v`w|INc*r~w&@+{aLP-?b)8yNvG&eID&x zSC&lQBezL9j$4E#e!ktAf+mEv=>;v=Mw_}A3~f`Ut74mWkZ$COXe#A~w&}AKZPQjo z+w`|8+NQr<(KhA!)hf0r&*tBhdnD5S$hy|iFO+)HaD zLjJjVs*^JBdHt0tw&`F0AH4s{w&@kitrpPr_ut(N=LM&2)9y<)NBkc-5IGPz5IJx_ z9B}Wi=-Z3FJs1<_+Ym?Cw?_wn2WkTZrj<*f=FyhBG8yoFH+g;*=I`Klb~2lzXakP$ zJL3X<`p|f<|$pdI#72nGhjZ*RSlZ*RHL zSgN}21P9|8h`znJr@<4wEa+^bngH! zCyxL7x@Z2N+n=p_hA=j>G90p z!S5`7d2n28$FlaPxQQ~`w}bc(=G{E5nfouv@AKCWYjJrz*EnMGzln@&Umh^NhxoGl zqf*6ql?A^XzfFPqXOb~b3;DPFOkQ~23+DxA-QTsaCxN`Dtw!5WWsNj#LzOMk8=yxb zOQdNVYTuKlZK!=s+Q@|TEos_@+E=7~*o$pAKvB9U;Y+BGG85Q_>wC8i%Xhl3d$!^F zKHG*H7(~rJdBI)5W5G4tzu6ZrxGngk>`C~t_mHL{G@)&HL-3%3H3mZ4km;(}hAGlf zt`t%Ugtj5qRdf(H%QhUrV60*revgKw2YMgGUUQOHkgket_$-XaDz+iluWaVj>ukft zGu3Rv)q3@HAJI09dlIgRJqahqHq5ad!gVJ5c!oO0qwPcAPw#Bzg8lkWCFj4ufzqXu zefHC~b!K}-+thotxM0SggSAa{KmDRQYNZAGZVgli*FJsUZn-Oy0pB+9R1}wp`8)WX zbyp?>#x}#HGTW|+Mi$vt%ugMFlTry$1zush9G^rO&@$hSB@o)Se+rxMGU8_0wjCs>V%z=!3-UnQN9;8xc^2ue;3DTee*!;_?U>>; z?a+GwncRo={SE^HT3)!{{sGvTo0%Nh_d!~5dXQn#^V~> z-vkqj+HdX;@hsoh`LsBn|9)8G^ZG>Nh|N7CQ4xO`-$HyD{{|AD$3MSKP~)b6c{m5N zH5FqoAgUB*-Cvy7wX&zSvC0~0+QvPREwzmkkp;DlweLyOHrBo-eGatt9cdr-%Qn6Y z0iX;`&hsuV9*%A7opHXn7;R&}gM;v1)&%=@Zz|=6w(*yPfk59|p>51`{y3@WLfd$R zbR$n>wcgM+z8N-U729}F(KdduqHX+AMceq9inj5yGi~FgO15!hvHF_e<{NBhM%y^r z#`0KCBB#5%c_DY!n$b+mnQY;_V<&m}yDX-f?%wNJ3-HpPx0uP5kN4G)Kg;d#ZR2=e z0fi(&sGe6 zT|c^YD_?szd#;-A`yl%_+tcCJ-Q>t;c;3L}w5OepPjDj+1`FK z`D#V}SK&{uH_e}KJU`8!UN5eDg3v(hFC{m=&@@5&@48xZ;E{>W6=m0c3PFBjb8$Jl z#*peVMK+-7OIwrK9Oc`dd3GZ6cknywa!dw}if^LKH!{FY6xr@acxae`~3U&OdMB?;Xm@1)z38$EI$uee-k&pm->6izm-=wuA%Bun8n|d zxUP$RMPG-0r$uSq^TfVjyq?#g^aievv&SFZmT7ea>+X<1g{>?686swdGo>VuNvb;=kK%9Geh)yrhRk= zfCPk7b|1k3j!Ym3>%0hjcz@`-uIg@E)ea1-R-H>PvjL z!1ZI=;WazC2krYTt}AGHp+D$T@Xc&$B4ACIJq7iO{-E`hs^?GM%mxFZKPdWxtRw{g zoj>AW?Crx_tL56CV{bdVTKomkA9VfP)vM4s_HnJB^9LR787T)WzkFJvzbF_p0y6rG z0)_Y)6h{$rgZsXwfnH1DZ7U(8?s{)_xY zJ>)N|pT2y3jU(H=P#;9f6>DaKlI4Om-Rz;(g7oo z3O)tQ%laO<;H6;_)fGa25z}FabD-%$e^CeN23j~$r;;P|7ja$C6~xW*7d0#Ti#|}% zU&M2E_*l;J7d=qXUvy=rzo=2oU$j)Od~VMlqiuxfFN*#mD+$5>1GcxLzi7s}D~|up z-{SUen!)GT>V#%w8)3>hGN7|55a}P&YH{a~ihg`d@XUdA$%|wFq`3eW}a=x{2lzxYK8z){Tks%8%OIx&;hSC(MZPU0rU3|&+?1%Goq~i7UIk5A4q&r z{V5tzR)0t0i}H_VTX~sr&F4RP5dwKKK%%nySDTY*LtvR5@t62IwWjmy_rn^W zCleY+%sNL>zJFcAjBn1Dx4$RxdF}VxROFALu~5Wc6kQ6l?k}#Nv3*DX!Uj00vQApp z&ye?|ck2(~v&;PFfmK#Wt3Twd#H&9<>%(OSyYY8?TynSYkZ^s>CD7*~OO(05-_bZQ zf5(zJlX%ITNxWpvBwkwa{2C2E?E5(0bogsx7Vv;_%}cl@W+>NnP0UGI19QO}FjJA0 zQ^0g%=ve)Nmxf97eH{8Un9fhC=|Z2z0EsA%3aJD_pT@t!dAdEs&GKoa7&I%bfe8jz zZ6C2eF5iQ6BV43U<5v9mtZ+#Q+u=1kxfSjE46Z3?dEpwE_rkxhsfmC!UA6{hrJ7G; zd9m_0SpPcuG~#!5zU>KJ7(8H`F#0sEIiE(Qvy}hhpHmPgZPD%RBA-T$uOUE-|D4YU zdec6x;fX$x?d|v-BYW=4(L1Zz`9xOu2xOo-#C믅Z?T9?^ZO%OVkoi0Koz2UP zYt(~A_?7u2nrI~B^MLt#h-dlQRzID&hJR)Cw-8@e|3KpXay88QQ~WEdza#OQ$H&Y+ znvuT=CV$S)9Mm$iQ+@p`L7F}h?Q7CL?3YjE^N=OVT;LN~ zd98dRzJFvT`a}+Oormx5NJZFA0sB6YmxDo7-^Za(gz5aGnlAK-u<(}mBG7t6pU7WT z^oj7iq$)m<-wFm-Z6C4!r2Te9pU49heIma*(P+j_IFDE>QRbo2}QIwi&W>EL{8j^3A;Obo(zS@9K|o%D3~{Xzv6B z?f3bUI}f~*dCsi;2V)aPpUAc56RCEF_E-Nqig;z82$%T*TKHXm|J_X;Uy6Mq-Itg? zLgYZ?K;*#x&)(YrOLARhg7@`%-I8S?%OD%s7IsSASZz=@uc}_Z{;`1qJ+%c0A%kT+ zBQ36$o`j5L%WJhgvhc1;j;B^L2*PH)gCmfcYWa=V#s(a*o(W>?*r?fk5qKiZpaAcz z7>k(NiH6XESj=Kr4|vu4eK+sPx_R?vR=)qLSLZ}z-aL7K^W2-~o_q4#lS+YYqd+FV zZIArGcK7=^`E8{9vmQTHk@9`{Eh=AKxS)1+>3EX)H$RWBNB-RC`eVI*uri(U@wDY~ zmbG7*?o8H$_e+K#^mTSn{}h1vyEsl4V$vI2{tj?d>2%v@B;#Yi{5{08d}*tn&fdeR zs{Rh*tLpE&c)wh^X8j3HRrPmWyyWpi<{ym6-v*J(e0=-#XIUZe`P(pRsCxdMi)Y#p zY?)XxlRmyqL(=*6`_~d58xs=8kabdTQP#hV?<2md{q%=YMt{Fe`ISFwPwVd@|NSXi zI3Fn7$=?|De5zAU`-VE)C6G?WI&sk{iw|+?lx3_ko?}ABCUNSNslMTT;`bnwu|u3X zWf?2PsZ*A*L7X~e>1*OXY?V&=d5k5Fxj?6Ue7AJU$2~i{yYOxyZj_x}4@Pixbjn{s zIv=Ec{xdNC%SboCO-wnJc6LvFXFWT+ui-h)coj>%Lp!?@wRFl0x_7YlKe1J(Tvw;L zJ!?YMDc7Zc_Duq7=Fr|O)S-^!epJj!> z{5>S9qK`qxmOUTK>>!@>^JQwO$FJYNmiXA1kvN8IU*DDQ-DkN;;Im^m}FR;B6kmOx$3* z5uvZsc+yM5Bp{uIP^ZCkeo{#n>NI*t#PKMQxQkGyF+F<+PuA3FoS3icKl@qO<`GC! zwUg_R2$3~~+R1U{74i4t{JUh|LEU%buBrRKD%ELBolc{cKcr8-g0EsWt}6W@K_^fS zJ7A}Q`fV+d_oKv)VtxLQg7PE$DWuc%*lFxJoyW=iP!`#!Z0!bd(?Z#r&tEgf)_2U` z#ldw+3@CmLaFne{nZJ!j+Vu^tLty?M;#t15)lXyZ;Z#+B2k}+)_g%bSu3WSJ1gEn4 zefn&t&f|V*P!Rg{v#lYJK7AyrqEF)1l}sA~%j_ba^z&tIN$1z^UrT&!%t#zV);VzH z`}gIV@$CcE?e8JJtbhGBAz13owlP)#>!Jg?HGCPi1 zIuG>$P5P$L&+mOvore$x;a<~u;NxEoLCMk89=u zjas9dx&TG(pEp6y@yj({T;+t)!%pVez|hZ`c>zV($ANRqZ@f z=K%?G^Ewap5goi@{k%>?{ds)BBT&YFzVL;J9gQ82Af-d!AcHPXJX7=(3yNX z*Q-Os*9lO65Q5bSU}1kcjBq&fbX>em8>C}=AMw;VZI{j@fnuUeXT~;l5nt8*fy*Cj zzfT_|D**GfRcC_l82ijY&_eW+#1E5NAP{L!oOVzh;Or~nTlJsuPrLGHCt}=KWcjQ| z#wKyviO5(aeh+XNJH%-xB4dR(?L=g35T~7p^fhrGw#rT~zPe9qSiV=WN#NLt6YX;dkCSkhN({-^PTZdAUEAYl!$dJE(&S!2DetrwcLZ4K9BN zIH*68x^S5R@3qm$GMyvy_YlwW%knd#s{Rh*tLpE&_^eUh1?x|6Dy!e84|Q@Ou+7u~ zRJCtVQ9kpxQHlDP4k?@BwtucH?_a-v4n&Hu{e%4XN8)%Zmd8&Tdnf#OwbM(-K6SiH zAdHN4;<7h!yM0Xa-4~tncKDd)`z`*M;y$LE&E3*D`!;(`)j98|&Uv?dOmjR6B<>>A zIlr~0kLmu^_4X!y9qD`!xq~5jtiW?fH^9wNdlSE0)5r8TNBNj;wrc5|7h1>b|F=-> z^z^@le=Q?A5^nRFQT;JZi$A9A`DVcp8~7{Qayz%6{4L!ZINbZ2?cLm3AKai%ub1-| zHM0HuFY7OSj+71efEWMEIP$!;Gjnd^I+KqEQdL~Wi zJ{K;zaMgutF1+Z%LueDz?-d`{<7~%w6YSqU15)pX9p5)FKB!aq9vpKxsE%Pf*!2QW z!jA8gf*?c|3opmnPxrNvc6?oUJp?o0JoZt$ljo+kKJDHG4r2(ngy)KU(fceiB+efI+Y6- z!tr0g;2%DJD&ZfhbK$tdiqO$#e=3{`1GiN9>+o4a;mFDDQv9_Yhz8{Cu#o{`K33VhX_WJIH^3Att>M%i|{< z^?a&xN&AjEjU^Cn;NB(TVyD8sC0SLd?e>0B06=W_Ht51qa5=$mi9^T>|cv3%8I$cY<# zHzLILMq~Ll!Yhe*AoF>+carJ6;_!Z?5bm8!kgh9*BT3@Yg?22r)zrE4YVMub09&1Knmn4N3) z&5geTb=0XYYmVKymdw(O5HI=`nDQUmzT+&eyU(;N;fHmLuGDWsl zw{*O4q4=GBNdHV{RG@!x&41qf#DzhmeD$%t@x7B7{R{7Jk^bYQbLr)En*R9Nv`%6; zJ~RFnS#t}&l=tD6jQSww`=3I;pHk83oJaN#`NspFW!};JV>th*oldV;x^E9-r~RJo5#{Vm$S%@2joT&%1Y_};J%>#nme{WX8taY(~=1)B)EW8DM_PnH`g7f0MSrg2 z%jjqO7xC;Lf6XKH`1SkO5+56r633A3W5H$Pi}4-ASGB+I^4qdlo(F!L@E8SP9k2OV2%dA6Rwn%0wg z)ANCKaTlRJ>l3hp`8~vqvLWhU zS#w_&()l3mW9Yw?&mrB_xIr5t%3FM|Vm3rCKu=}GXT%evywHZ|4rD%)Cds86dca$( zr_VakoUiLY{hO-Ks__lolgHJDXiN1GYD1(pM5@msyU+9i>R;ZQ19{oc>#KbJ6V)eP zxbT?yleaKu4I9Z~`Kk{i=^X5pfAVGeutj;YG!$9vK>l`yiM)4zb|-&9nNJ|LHfR1W zj?T7t-fN?gW%>%{?;)P$m*r~v}0pi&|{+dbB`SttP5+56r6338rwo!1| z_+oqy@u!(M0`{4)PAeNfew*+Z1z`Cdjy~)rw6Bgn?4u*~VaIFf!xkHhwf`r$@XGW_NmGMAh^T#+iL8fIAI60h_BpB#Q+=4~!^nF@AEy5fAT<<}0!jg;z@Dc-wtr!JEkiVT_vR=MFyOY20^`$Z0Ci8c3oX%&~ z%-=>M86N}Y?;)P$OI!VP_8v}E^>+|oRe#^b`{l|t>rZehtKX;3B!5rX%)bdb*m71y z|Gta2eId&9;s~n_-#7C z3IkyIJ>Lb~g#5ejqLH=cM56Y3T&GH@qE@PQE zzb7PaY!T=81Q~0@`8`3#7V$1{8B4^^0hh5s+=s3Do^UyA{WwO0?+M4p=X=6&?|Z^= z{hlx;-xIFHxDiO)Mfg2|`?h@$S>q<$xPDL2 zf9-lhZ+MxlcSYZ6VBePRU$t+v{r76PpS5dV_HAEOk+_oR5vgh~d>t9P*F`7#pL;Fm~SVlj_cMxAipT3K?W%-5U+HX_dQ%stW zc@i|TjD81#@=0i9&JJN;6X$wW`j+?| zz@;yVGoADeaUV9aUZh`nLLWtOKPK0==h1;2Bf)y{#Aeou$GF$BVRul^H z`tL-3{fGa89YR|+v%hi~yvFX6bYYnfcG*w4XZA;WFJb~362kS{SG_ch2Z=0%>o=yW zvwj;O9mkSD;x4$>py^rL;a|Z9#YfydHi6@fc51icU>oLf5PG;-XZ`jiX7)gygQ3?P z^JS#_C~l&9^W8XDFSi@AZRG0$w;{m?1wkm~h5IAhV4!Cr>4xjKle&HbiBGlja&@nl z;h8OwNj*BnL-$z89=lADqX#mR01-WzX-^*T0rBVl`vVS7zqvTX#Sy#S zT?;>J1Ao$EGzoBmuHSZe{nnb-^_#BW=#M7{z_;!DLS+3pq3btKzJ4)VFPDCQ+p>QU z>GwB`RR}fsPTTA4yge;nl)d!*ttHAx#{oE>6J$)WiKVT6B6|;~s`^D{F3aCXM4jgsc_*x2*Kg(YJKz&5 zavd8}xnys?`Q}r}Vf=sO4axDNjiZgEIo~)wzZi~l=8>_^>pAl`mlz7n=3=Qo&yR*# z+;P7HwPS(nEvo3cI5@V5Tfa5E?{7_Azj<$yuHPno{npa;o37t<{k8+^w?E@X)`I_%@H>jG-_mtiNSE{G z&py{H&`<3rIi>)cS--W?BIK;=H(kGVAoEv!AMLyN*!mVx8R-5uwV&i*puVHpe@Uyg zee1WDw|;Bs`Yn4q)3povz35DI|6BS^KK!56*!nMNE$I49*KfLh+ky4l4_oFKu1nPa zB&Lsu|DBLdx_(QiT?j(r{JUiF!d#DkAI>URf#3lVtwt`7p*KfLh z)AbwoyUCl7zB9W2&0m?5KKU=9v)04kkiX2D%S?U$lMqC=)PC}qw`N=LuXX)4>>}%X zQP*!nf{+$GCTIP2OxJI^e$(~a=GJdFo+|855_wtvSMW;5<0|5g|j-i_Fp z@}iB}Pfn!$iTVx*Ke(N%+J^JKiN3eY9IkUyO~ei>rtTSw3(xTpZ3e3^b+ z_RQaoGCmS1r;dKSgM7>%1D4;%LH}hjU1(XmklaEnkHpz<7yLi-Svg-_gRp}`aQc7l zZOZPubi;YcHlC+UZ&cO(u$(8%XJ26E@cz!VpYMd7 zR|7viY?Ti}%d+`P-jA|*mG5H*N7=l|cTylW2Qq&j2j`j?u>J&%ESqGD^*>H^KZO*$wJI><=feWpOzX7<=W-I3TAFu>5_CF__=gD(Vpo2IDf_dKg zZE5kJ2=>1Tksl>^Y}cFkohufWIRg><5JL=-B^R!^aMgutF1+Z%y&@01i38t3;=)iK z;QZ)=yz8Mnz;t!wfgaMer4SUHxWYqu;O%&6C`*iz2L|Z3I`Y6jk_mVqO(mE zljzdJAsYsv^gU@Lb1c9ztK^Y2#^dFg zLtCu8;=;WmkGz#Ho`b}NHzK4SKzPQ-y);Y$5?Bc35vJpNA|UBP{X`Gx*tY_Sy9nix zXYr!ekw-e{#5(fGFS4^ekR~wnAMry-S4SSu)Bw$kyL3U269r{l%n_`Lw!x)lc~J*|2^k(@&&=F1sQM z(pP2kqVSec@<^FH;J?ac^LZaFE6dON6Eu?XW%;`<9!Uzo{DX@8WzQ`I#p;we8;*fI zK-zFV55Fsn(oawx5ZY{|JkSQcMII>8Px$*+{R^*WX3`hw3MM`fOf5u{h)hv8(NtN65DYVsk6?jeQ)dpOBtNsa56o zOXh!ma_is_e1h~7zTN*Q{e&3uQy$0+`A5kEtDuYOCqM)bWQ2wCz%<%VY>j^6c&&ZZ zkOxjA7Dn6Qf6Fn+RIR*gcK8@Io_^v*ZxGqb;`(=N>?dr?)t>T(OD|&o#n2u!`(AN8 z?8`hZJfdu!yjlH($^%1s3$1x)&iqYoH%)$b4!=SBUuKEVS{pIumHB^^Jn%ZCO;D+P z&-h;8T@U|$-~$f_n!!f)0XAIjHp=ApiXQ}C^1b4Cx({&pm7>w0X=TI81`Vq=Xoy2i z$^pl{Zx+Y(n}soL&~}`^S=^0zt&R=D01T#%4a0WWRPsF%z>u{N+Aw?^&v8Z)A(V8( z&uJ(2oJ5-Pm!5zk$2`!@^JLl$%cX2gii=7!hU*^_MZHxbse z9qrF#0=}3PAY)u*f;f?!$R3a6-7&CX5E&uV5sa}+aAKV@!3j?$IH59u$^^o<82Zxl zdh8gsMkYA9=VXG&K7xo$;OPm-2WOrz-}S4!P?>=LQ<*8yVT|@&(%8HL@h(*!NQqHL zM^N846By}wsKbhJV4yhru=AG%b zEd(RA@<3hNLX6^}hQN7iOnok?KZJCAC23Ib-@IEof~m1BY}EAEINAFRu>Z{suq-Ib z1b^@kj0|-I#W_!90@7(0Wdi4yk*$b<%u}1y5tQv8RGDB%b)hxyY^6*f`w1q;wh)YT zeKJAIlL>13Ok4$>br0fj{P9Z0;C6pEm>!v+rq9Hw@Zo$35XuDk@keaiWrA(q4-m1v zJh2yiIAe#G1>q5!l?lr91oX{%eOi_JaCUU?gEG2Hn!Whl;yrjc`c$GF1C7NwcDBN2 zqkOmMV^GUKCE`Au8_s9rP)|{5$KdUTY&frtqwE;g_)OSer#_O{$tei03FVP#^x=G) z5Cx&oCEWiw(uZ?nFZygO_(-ayqxfo6N3jb&oK+sdh%V}oM)_=PY_ZSAG987=BgQ0- z_rzq2y=}5}#Dn%aIy?;u8ky{;!b;Mx(Fbpj$!(UtCO&NYOQJ;+%%WWL`Pl;5H z@J&Z|{GSqyz38(MgUbqNnU5y;Y|Qi?MW2dD&VNe$^=yKRES>XvunY1Co3jme2q-p% zZI*Xf$#%3qv!hsa&ruTCu18$iyja&qQ<*%X-%N&t7h3bqPJA;dlLth8*u8&BfRP6B zKtWS6lmR@SjScnLh_Tbgp>~z&wB^eK>+!|#^Nr*4i>=6hSK&M4L*pP1?Bc#l=d*FB z6{!4P;dyLqIFF5^zE`Z0twETT?-mywuK$=S{?mcBmv#R++4cr;0-6%|>6QPxZsQ9^w?BRg}=r+GJ&~tDZ!{znPBXFG3=1PMwJOvCJ?tDTt`;_ z*P*dae~k^#Ut>f4HG=cDai~nNx$g$P9k{4I!tVwn|Lf4K?XPiy{4ro~S%P@q4QkjC z{O)WA8C512cbT9W(O;wEGLUyc?FcfGW%|FS<~_9c=%%gQ?LIH20#f?8@o6HDicJA;@z5LnP8`F3y(UwiJssT@c929!APx4 zFx+NvoWFm}859hK0MBJ()46O^c>v%41rm3mKAerY8Vrqg)i1*_hvRA-v~v&}XOg(g0x%-aO#Qzf zn_K9!@guf(^Cz;U4i5cppx+Hd^b~oZ{D073r0dfWcs?7O>a!8=TN{UdH%O;0Pc$;? z*>A8l-wkT|Y@8_nOc-1nkO}^9?uR4(nRY=(u+94cBKDVi!aq~f`EnHbZM(i3s6PZ_ z61-xBn7*Nm?rDyA9*MKz7=O1Y(@}^&gx&Mc)GYXn%&8}!u4wp*3D09>(|L^K`m^er zg?y_}|4hTtD!fMhGu8Xg)JXqK&AsR^k}np=%=*4rd}B62o=``z3qGV(9zj2Z-;SOz zqx>^9x7c4~nT|r`5tT>8&f*|OY8Sjlp2;Y}HSK5^b6N83=S zJYo#}K>DEaNJ@<-u`sFQk72YtQqy1L{QLy@V~F{S%;b!s4Tby9)gOG2w9V4FZxg#9 zkDwJ8=lad$(u=L7w?RMUI}b79LTyPM2?w)GvOdnB9=&ba0f(BV0!c z#PkEq-^WpwpYLaa`Sv*85lCrB&tA1$=mO8?Pq&|CaR zm)KAg{54kUCp?dhP3N(3lzw8B&xpYza=}H1t4-zh+f+`CKZa&)e~lBf&qC&pYW+kw z@7K2(R2vG;8oT$8tL7r>F9)!03uW`7$^+%JvoT{V4~(xr1~5{qA6TFzrBw*v`vkvI zSR>1ZRTkinD?`12=d-b?J{vLc+BnpP!mb7Fn#8_~IPJU*MLnO5jgyULVxe=zhi|#< z^h~;Rw#}Y_#i#IL-uQ%Dgrq9u!{$nZ%|sr!In`eSUt8zDl+RdZ9?s=n!R~TQYy{T* zd}TWM@ChR_NiF)-FCR6!mHE)F^M_yDKXd64)?H3_;(b$K1K|VvEr|OtYpu$McV>g$m^GIVBXKngFMZ$V?ywH7=_x*b3)k$k zm$Urgob3Bp9Bzqd%-f0FH#hLyD>j{bMO)qslvZp%*X_$LTyf!=3op8GudL(04O$8$ z?&3y->?6FlYbme{7q}zQdUJLvK9$SEA3Koon|&xWhQE!C|^Q zRl-JPlG|5UY}b`7bE8AOV54(({qj*+Vb1Ql7D&5_b9VAff;3^e$eg{+ei7$fOBuxG zH@1p(^lyTLpmR2eu#TGkYILl}yw|BUpYce;t{t=klY70@(JW5oLM|zkKTI zLty(mII(>(VEO%;<#X*70?SWONLl%pG2Ug0(Wk86T$U(JCC-Lp@a=?SM`XG_t~pkS zhu=;P;(pKdHRG)w#nGPl5yW>~UlHdPT6YFq)#n6bt{`4|pS(#c^Wa=HftKRiH9)9Pe_oZ^;Rm1NwOQ^HXcbP+=AJZ+l zaK(jt<$KLpJexq`E??KwXisEO)QepHWsVSq(bFLpYZ3*k-x9dEnS1OcG3|W z1ut)KxnVi>&nxOD1E;ezv5}C064Xs}qq?p7a+=*ovwje_uFO`*?F%|@e&)^&3JB8;b!Sp~L{6^P{(oQzA$``_ z{*11X_Ww*LQvMdUzb5^smOdl;_m$`!yPjy^q5|aAFOyegE~OkCOl!7O#&>W~R*c1S zzU$+l>=*;aa}F$vXZd}^SJj`Okg|BrsRCu~>monbAu(Y60~cSGzl}sy`Fk!tmfvrm zWywJ!NFNFYW#v;2N|*)^E1&s075OcFU3@IR-@aHp%TExo(e{;%J3bE~R%aUH&J(as z;@IZ8<{&~D%fz`(NJ_hBRJuK&gr&__{RcfAw%Bj`Ymp|BG{ zr5XMsglqgcfM?H4u9dq^S7m7%X1;6mx@;9~$eYiFJc1P5N^c5brN|9;mckc;vk8IaQ((~Z)!#>d`Sh*d-hOK2|Bud@PyO!|>!;H7TWIem^0(Ki!KJRRd|Uo? zu1~UcS!8{3X9twl^;P=+s^WK`y6anAUtxS^>)_$|d<90AU0-dXZ|z|Ew48!-YX`@u z_0_N1)Wws{kBOvgeZ=^FMLg#;fmr)EA0{}J$^R_B>*CAu4@Tr~qY#!K%kQ_3b8iT2 zU(e+a6T*4;xu8z180zXY`0MQiHhfR^RHb^M;LoQr$;ff2_TzJuihw$7?zgN~s*Le&e!DA7^HPYQ)8peYZ z7Q!_W)74ocb&-zaM<8(*;TmZHYmoOMZqynnskugaW6d?vn~<)HhvXXRl{n^b#MVe( zM#J8ZI02zcxJFt6+>!-i$d5#IO7%H1f$)X6iDJ7Vb0Yewj^6N%Nauq*2Saa)Hg7_@Z{Qy1L~I!?ofB_D``U;X zkn+Mg@#9E$MiL>Ebi;vI&mXwXi9;f8)b8T_zfdwK_EB~=CyKsmSYLRx?Q>!(%!Jiu zxQrp46El+JFDBr-<1WmJzQ1b!yPn62ygAW%sRsKpGdd^czNP7$7+)uD-JDp@C$-Lr zL$yL}X#trNw5L24_8+rCa* zEY|7Y(RHFvjmWjG6Jxql=eM{*cj|d6ZaGiIx=vKx>CWp;Yx*VD?}-`n+vuG5?ib>7 zq7~%FX-?c`zrngr%!X3-ErWOV_&U+~0j`)6JqN%o=KxseM4c0Neon0E_gCk{jFD}0 zPW-!)b>bs^6g^IJA~)|;fUXlOh{GsdC&t!^zMtK=?(~HBJ<++?)j3h;#GRiLYx>pI zIWc2|8=Vu6UK3v@w)@Qk{2x;5qY`bIG3WlY!$xg!`L<}k{ShCM;hbOpKc@=~Hn|)&JLht3 zAyBq|v4aG(#f$;JcMfpejw6=8PWf#-1oOv$<@XTJ{SdM855zKg_hNax=&@L*lD1;^ zI>0q);qQ+W{2=ZNEw*C6ZPnCr&^n3Rae^9#X&DuaR zKV?$Ny)pT{&YGf!{9H4{faPPGS?QX>FQ2-F5RldW6Nhqp3|M{-r?NGRUw-WQSpLAZ zudMub&GG|RPqsLgPocbuJ{=byYoFhK|61D0^7|voPf&0j`n*93^+J~4b@{#9*(K>e zs9Anl``cJpmeEIj_6*mk2SICj*SIFNYf3kEiOc_^_^uG&X}{?7Yc6Aj_227_4dU+v zE`3ehhmH6Je8?5h#USLG`WJzJ0%M8eEboH|3zOlR+W!^|2Y}xHt5R2hHojq3-VOVQ ztH6Ug{irvsH+37^w5|i2o_!T~{%~pT+y$~tGp{W7XSBk2Jja>~FS_s$c&qh)|mdkceYW zAaNI5qvA7(X*>M+E8+Lt-6L=37~mXnD-O0nKJj%i@zwF0^c%qhDbK+W-J8KvNY}?r zCVw>!)_XM$w#{p{xf|_!688k8yl~zB2-e_dBoRVMHyq^kd;9Au z_Kfe>fAT+%;sb4q8=`(6w z{)D;5E+jHKI(@@XuK;(x>AG#qePNQ1w=qC=Yu(2Arh`+}x@>^>I_nP3jUll7HXgEU zUBKt>x%gOq&UpfdxEK$B<#S>zD__?gySMJ}yJ{or0{+j5&_*Y7UBLf0y&ZkcF%hf_ z%6yaN*9G?9Ne#QI;j#-?T)5`Ki!PkQd(HHRT)6DQ z6&J3#aIeVlchBL$9V9LcW%#GOG)w{#SO{f!rmG{v_mPg{Lm+V%p$vZ!0(%E>6i2IM zcvf0RhJTIUIFu>R!O&}t;lFG+H_|^EOWZQEPh`LZ%1smKymzRzWwq~riE0wB2^VanIi)AS(c76IDu=BkJzjH ziSZpAr*Xt&bk28u993(GHX5O8oH+e_k%;To5Uf0bL}hCn+dnQo)<1sv{XGiL>DZ*!Xko@>|D2gguO9(t`M5J^%g~k7AyHMu)y55>A|2Nz8TZ|{fdaE$!H9M7^>-^Jp4Q=MS>!J(i&|h`dVHYJG zo}KBJT)0=(XCLxj#00b<+=v594?`Y8__CLVI7nh4T%R$WzXXzWbc?}jDQ|#u97_U; zy9n23pTPp@5yXvJpLNmLI_tCF;6r&J?PKUQ$2^5}b^d946WaG^q`Yu_mW=wR?Ls|2 z-1<-3A+e)-1Z(`$cB^#w&Nj`L|JAnA6Gk@LKjr&j(DziB@X+;H$v2|CzrJDb6Sm7X zG+RH7xgUJarEN@Hx_%nHe)8vbJ9u!i_eQL5IxapCe{2zm%HUwhHz?|%J(ifI=LO}Y zgcpEV`P009dIO1q4wCf~|3B9OPF(`mS9~=GUi=$@xA8(q`X2$_^YAwVr;=Ube-fzl zEzA2E;L=ybeb~r)>7Td)dMJwPrTc)#|7i=s&)Tk8<1}k=W)04)*;?uEY*V|n%AeXU zcz;t^aDP*9Yo!|hv|U4cw_>fdSJp_^c`s<<`Zio6-R-4e60Ru-;TnnQ>a3BvNXPLb zkhqI*jWh}WwEciQ1VW)pxJIh}r|rT!=I86}KWm;mF<*E8*%}v?fK*j_*j#DcN3Ha> z)9w?=_6J>E+#i(Ln>d-QYhGfyL8a;+md)5LePGnJ|!~hW9IVO z^g%tYR<}Q@U8KK9A2thibWeW|LMRU24|}=U=VAZD+h)HF_dho~*Y2Aee+6oVQ(eZ0 z&YjnJ*zPsnaKBU5KcJtq2QR<%bCcoO_iGtUXZvHo{B3kn+4CKUW%BODXzE4picbd8f->|q2s=1PJL2*$GQs(oJ#k}$ z@dtr--B=)g7&rn;8{+Z}Mat(Z(06^uc>az+`il4u0++raelu|C3*tWpTxd_+hmFYm zKjjKYP!whUyMTWbeam;yvr9__nc;pFyVt}@|K&SZd`)Vc(R)?3BaYl*9f#1_9%Z z@?VcXX7WN&Kk>)PA2BsdIeXkU$eG??eyYC8^pAC(uY>$m&(}wM)$@tY zF4jc0Pjq-?&qtl!Rk29qwa*8=1LI>!%KBB>63ZiTHrxdpb<&#p%5l}NlGdVMrP4}p zpKe>FU%mROsD9Po_q%!hs;_JH_x`GW)$daDc?#Df;I)1C5Vmn#gMJc7+(oEgeXEy- zNu<0`zshuV^s61DOTc>s5_b{mS08~rOdb7d7s}5%`qkeEz5~j0F!Y*ZoBV0n(k3heas$4)v?`_5dF{u~^%FVvdSofa+IC1=X*T3O=a)#HCA|3sXCep&y!z zMp65mP~Vy16JS5F|BH3>t7n&~U(KkX7fJ!8fKp(>DX^En7L|7m*tqxo&g1`?JXF*l zKdk(}oS+(`6i^CGAO-d||Ic*e>0;mZkBIPPdel1lV-{4UKkgvDN`KsU@dye)9aMrw zviz7Xm-?74;`h3K{4Zh;k7p-+2GG$mK9;1cUy;p1ERV$5Q1#<>>`@1BGYG8|ueTTvJa!-iH3Uj(+?ur1OEaATacrW9~+} zI{NXi!p66be!Pe0IAd!{Pg3ttKVHuV%R+PEcxr$=`u}#9ucmdSQ)arq@RZkvxP552 z?=Hi${YSdLkVF)Hdq$tkK6JbH7ybq|4{~4UxbH7i{rj}&-!EKn`(u6kY5P80xDb9n z=$b#dpYMqv^NJq`+fRE?aMD*c+5OolRiWKE$z?gze?KQHShm<{r-{bBt?`0N`VQd zz~0t>m32;je#!Cw()s1A^8Ye&>V2hvQeYw}FopcTV87+@{|f&xYX3Bm16&)e6i^D3 zQeX=CKWKsP2x|XSIwmwiDWDXX4hl>m|F4q&XYn-~{yRVQsq8yQ_WkzZdsP2F9q)ub zrBYy8C@_WmA6;8p{?F!v$ISbb|4++Hq0gxlm=X$1A^$JP|L~vI&g6Y7|IZBVpq%`_ z&-~F6?Cl@vU|isP!7zRPdvW&t;4!27<)-8n(#KQ^>?I0h{88;A_fog&vnU0W0_&x~ z6w1dSk=jSDcbsT?rGQdk?@?e1`F|$=%l{44K63AkYkeZ6fKp&I1*VYygDAoG(K~J` z>>qae@=V_i4++R*W>oJzdQ52wrGQdkvM8|A^FTFq^8DGHt;3)9--s1dnC{Q>0dPS=j-JC40rbQPngfX!1BWT zb^VKm`7+$qcitR1H;9y<`WHoehfr9*)U^NqGX3p$P)>#Yzs`3UY9?8J_8PYX3hbTfgZ3h4LQO7^Q$xVDD34ho_Vst**TH^4}-+ z*WbUePpwnSsj4wb0j0oXQea0JGb*d5Ql3ArWBG=Mr_6rokN;bi65fyKw~%UE%dgUJW%fr|JKghi&BN-yIvfUy zD+QDS6HS4go=JAHzVeRA&o6V&mhS(~=7UqIe~ww*hfz*djZq3H1@;03^8C@fP=`Ox zJ%cBom8aiHKEKm-$uq`7ogw0M(Ys0krNHD;V5hn4PSzLpN-+OzseY@~LT#vkUc%4) zX@?hn`OY5f5`LuV!OVH{?X?6qGQE^bhy8gkZ~e17U+$&N^jlf^SDzaCA9VS$ax(qa zpWM$fX7pD~kPKAve`jy@Ql;d6WRAqn<9Zhrf} z@mcQ@f5fp&= z6Eu?Lm*wvw{sV=a=?yzf(8$|M^4EF3KJr&RUxG@ip0DfTV@+iH1~^qcUmK0As=tT$ zs`^Pd#>as5cMxAye;@IG5hFhGGJpT2X?!dR$44LhyfXiHm*@BU=Q5NPf-V1hMwEZB zynL4VI#=j{uyEkE{5KeLRqWwh`~bGjRnIqA*j)VssOu`rZyR$C?Ta;${nJI~{uaVm zy#M@V^ffBuEd=O>PI_>Kte`WvtTy^^g%hl~4{6cm6 z+wUrWzx?)>jjtZ^SM_fX-x{m>xBbt```3Se%Ifd__to`xS5o@M#t-|q_e;jy03IBR zA6382|Iw6wvHTn#=40jbwc`iz7~)Z2`F$53D?dgPzo1wiKi<6g=9^C?hu?hroo`5v zA8j0MB+dE8@%hEpd@hwmIM)iynZLTe~0GIT1Iorm75S;b&fJ^?j0_PwS{GS5t0GIR~;CK8$}K zaW}Ux{t@DCt{{$KZ~7pDl!sw%`i|E#{+|OE-cB6D)Ceyp{x66--c0-{;_dWZCH^$< zE*ekXOZ+nk+iy1Ji?01&04}_h@&AUn={dWL( z0wPO)UI|=y4fB5|aS)xnoA|ZBg_jV2E${(4LCSwU;~lSH{7t}xHxO?E@3?oJ_zB?h z?i2qZ;K{EI+p`3`>)}5ReBj}C0B`>f!}sBBz=pS^ns~=DqJa+u*6mQ;Vks zo{sUf$kTD2PVjV+r^dWJ+dK`MsbO<9Y_^8Y*RUBIHfO_TZP>g`o41+PXY)2~-loml zw0WC0Z`0;&9)Cxg)|Sz836)k(el{VUz(XwTogExp3KqD=u7h;hGCCx^NC%&wPhmxa7iR z7p}N)&4m|TcnG}L*5|@y7p}T+&4m|TcxcY0cj2-NS6sN}!iz4PLz`^7T)5=I6&J3$ zaLt8t2V8m=F1c{Ug{v-HbKyl7nxhYY@ZD$6+=KA!`_k|MxjK8_BWKOgcL#`Z1+H(#LAqRxgY6KS;L?1)XUyYL2ynT?be~JN`YB`1;GTe_ z8?w&DqYwQ+lFTPVNUziL;=+QBXw0`-O?%b3;={Mxb{hIyDH3((rL_;eK8;Gp!eMiz zfl%T@ro)sysK(dfIGe&3yJ?nvnGW+M?1&mVOz5~sk3a_)mgnh+W|;m7^SK9DewNO) z0}q9%FD`k?R?B!UYkB?1+2yCc-zJHd-UNm z&zv()Lsq1G^L`Be+2_*%Fk|-Hfw2F%*|~P#-1sXPs;9clAUbGX=V7Bd$n%f094S}E zMZRo{75m56VLN(-<#f%Xe8D$7zQXc6`nmCS9R>1X``09+ zsyM!~@}oNV8S|L=U`_fI-;e!|WZx*Ve&p{|J3r~ zed%98SL}RvKXR%a%I6MOejhAQl;2M`$5(zo-W=a&jPAO?A3gat<8LAVQ~gBB_>|u% zznf;BH{RTC`&%~#@-5hSUO!Q>$2a5Wr)(xOqk0PE=x3e0{`MJzs)G zFg^xsUl*sU=NlmYcVdl4Ugqz?;DzzABB;!T8o zH+G2UZKC&?A4I&24aVOLT*d)4=LyGv_!xi0fl&s@th!CXvDF!@w7 zV1`Q!@$xLYaK(kIE?jfrMHe0dk74>H7cRSS#f7UbTyx=fp9Y6l(YL}>XEvhe?X0896+O_Pof@c%;rSp0040+Uk{Z02h;9vE_eH*3w zDpr*Lt6ighFPLujul#=#{CKCc#yCIj73_X!7n#ZXZvB$sZa&y&{^CcdYw4f>%ooG- zI$s2qka<+?grO;1u+#i@-0ItD9=@6Sax8y{6xR2({92j2Zt?9mviU*h z3#yY#LBC^8_ljZ4r;D-IGY{Efb`{}|-oF15{m9UML-izNhRXMp?@crB8#lRiqwUGK z;_#xtANhSPlLt%rquOr_NtoBaRQTQE?s2=1bZEb!dKjHw)P7@{=N3NuM)~=;TPbMs4yzTuRaCi{)=1F@{nE;?UQK_gjyS^Zta?{&XjRsUulz%dQu%jh#0;kV1ck5QFhujJL~zm*G}gB!Mg z@iRW=kJZokZc_elX8anr68!N;KR6+9{PnM|_N$iMP(A*-E%1F2^^eN zjlcGfmXE(Oz9+PbjcJLqq574x?*@I?+zf&Y@WQ13vQGWV32$ON{mKb1B2K?@!h49* zubl82;%9(&9B&~`zi`4!h`$@Sy!*uICr;jV;vZys_ihvaFmQR7i9Zfp-d*Cq3|!t- z;`lX(k#~>yuLGBNjrb>l%ezJVQ^4h2BK}$6^6n7-UE=OtA^xw4yLW^5mw?N=K>XhU zm$6U$_kqh;C;kV(Wo#4oVIzL`{@4}J#-OL)z5fh+8J$WV9QfTkzKwqO_?zhTm(9gr zI;Z#jUpcSyC(gmon}{g}_e z7k58g~3pKH78g3V7ooAFOyi*HDebWjNX4XXb_ z4h8cPT=~87d*%1z!+*n;)Zvfbp2|#~&1@u{4NKSDd5i9;S6lJv=61TLKIAXchHpkz z-RZm$-tTS&`i(n0oA|uVVm2QPZMxs8^8jRFm3yaqCYWZKm(MP|9@aO&Zhmf0X*Lw1oJi`X{FE_&g&HZ!Xj+;j6UvxgoD`a#&()nnb=cJH7j|(2* zkp=#!`j^mwk^J)xU6l(0M@T z0i6eSp8sxjjd32C=Z_V8>OKBw_tfv(X!~}1u2@g~#=Ht-vwP~f!6yLF&O+JVQf#Bj zz}pIx-IM(|+;bcQ?yu?KsM_<}cku`c!2AgsS+%FRi}=01r~Y?h#0PCipB^?|F+P@r z{nHt-r@nhl^`7Z2_SBy%Dc|-_V$5%$p0fG}i07W?7})Xi`s(@(Hn3IgnNF}T^#+WA zSQTaCTG|rJBXKs=J=29f(;REu!^>@YGWLjb&$Ns+;@mSWV~hA*#NAjTeg=4wq+^Hp z&jXjSLY#Z1jT;-pxo29&0&(t{mcA$M!$$TLbI&y)!Jy`zV(zhCYDV`IpV)~##SOc6 zxH)gI%edL__WYjkuf6@hVDw99^EmAPT|sxS9jh*s{lI%=Kkls<7Xpd92>0Wj_tG#4 zSd@iuKQ7bN*^k>pI*v_ f5@aUZ}u{~5$#TChBkbNJ;r>?a?D^Ee3oWA*mqejVw2 zkmq3Nzje0Vyxsk9#%t#-5Qx2qoQcBmBu)`*BY$ zo^0CfxJl=V58razX)Fk{QfJI;RxWRT`(PTS`*BGJ-H)4&hT&QF<4)UtTB-yg>hZ@+UMTK&{bS{i`W-_5u{6ye zA@Jw>*bz5S&B=dU9Fi4IP=^d&id1iNiN$ALPq$nca}u!@3uo;dB%q_2t79!>g|IPKA-FNvQ4E`3MbhmF{i z(VmUaLs7IRqy5@fFgD0Tf`3$;+(vsc&s@f{8$0RQjlE*`?Z)-8LmlccM53lo}c42B4_Vm*-KE!UaYt$}`8X48c zs6IyZG3(cVjBAek+$UImepkD&8Xxpr66KG|AC*6jE4N#JyM!ZpVa)Df=(o0v0lE^K|yL4ru?+-JTcweRQDmQpJVN84v#O&WsEbRT^8I2SwBb|OT>Q=VHX38V~_aF z2nWC?-!2S>Ecep;SHrph^>u@$FJ=nNmP0un`K>6g4L@ zSvfuO`jNSBtjBIq<=%3-YK&4qDKLo?2pN3!GvxWF`C1+RIrluu46B)Fyo5%D^+j%< zWa+-jPd^RK%X1wRiuq`y{^e9^yaGFVosUZTL2oMslmg>NfdYS2{mb}ulD0@GpcL4C z3QV*BJfiXC)XT3Q)}epdr}Az&RW(K_pcI%)3WTh*`YH1Ka~=AZePKP5jHkYv=NFF5 zV}Dr&pp6CD6O~1{3*8qx9{XbdqGSUp_oxlv5S;O`B;2nxcv<=X5bS;~_>ZqDpU%Wz zUs68nZzu2#j)7EGf9Lw@`n#{MuD=V%>Q(jkF`monFB{irwuM-mCC-NWzlOrTT#gm) z)8+pfWb6^={~Bbh5$FFJj2m0T?;`HT67e%YW$X~={}yDd5Pvst85_j;{{cTY_UUcChythohPsH20=281^jXM9?u-jJcR|WTmP{OL@$EuqJ(m z&m--x_r2xLTeu&1+F`Hyr>y&2>Yq*hvu%&Zw8<#-zyyJtuOb2DQEz_q_9IQ90la)Q`@nPRxGeyL}Vde;%?zt^!JSmz6_mGw%dpPmdlo}C^3;fZOk1O^AtA0fJ-M)Rw@08zd4QHCnQucs+j42_nA6bVzD)wKg z+^h3|&I8ju3+%oBJ%zJTL~izO<@x72>``aJdO~~;%rAxYMLqq?8?JlZrAz65R@b#3 zSmz_1k90oL`6%S1z3g61r}~%a=5*u1)poBHdq6(MJdj^M ztV92T{lF^ka;Dg;{JrjT={%tG!0vJ3?XOvc<#?FqpX<=S>>Jhc$(moVUCh}1z}{Xa z(8fZUc?|dT2*mbI%6_2Jk|+qdeW`2a?H$Z&VeqGs;g&z`yWUF9!wF$P=HxwhKS|ABQs za7sHne>l?a{C?n8t^L3!kF}ci_rS^M{{!EBFnt*PKQQT_{|9zMI}7yx!1{mSr=Je@ zA9sz~yQ-c|zbj9-mTm9bIqfZdST?B#7g!V6ukNWo3-5b-CJ*U;;Q06Vy5A%AYC8SS zGTk%4DE_$D<0tETNWk_j+M*9PDur-z{*10Yb?L<}?^y3=*1wSFFNwEj&Y4@NOuELH z8{q(L_WAv`gqS|Q=x=E5+3bHdrTgj9|JlqKU1y~8&R(5A>OPmwGdj=gg}H>xGk}7< zt9hXgf1G=U9DAcQnf!Unr(%Bng88N3?=M`x4F8v=_F}5XQa#pm&n|mMkL7d4;dP!r zVt%Q?A3496k^Aw==AX%$UtWnvwRU2GKWkFZE^H7UAQFK(_EgMPWlz;Xe3d;_-^C*+ z0PU#~G_uN`s*Cs!6mq6Fn4fNBr`=wR&mRMR?{8y`dsTFCoB9Xuz@F>|87M&^q;C%c zjQL|lFusqqH1o&e%f_8l6U!rUHdK4Ab=z}sEbxB|{J(?rJ@LDMOJ5T|16=x+IREb; zeM#Jhjr^~H|A!#-Q565z!2dy9ye|5`hSs**XAPaww>)dCR%(rvwrK|Ade&{4hD<1?XdG1t_jawZ_GbWFYQ^% z3;)CLEj-7WNV?&WU#Mkwwa{udQp2m!c2_TaI;~Lcu1JTyV|Vo`$O8M`ZeDU@pL%ip zKL7wdjScrdH#^tH{o9lD82)d7sq&z9S5s$q^+@)giqh{QUGr=I3;)BAA1jI}1(X6x zfyt#n+`49b?#3w#HtgF?4f%H_&xGF{9y1?P{v9W#-c<@H1tydNBlw+sH&*?`r1hq@S1F(r*f0g+ zQswyEjXzjkKd}x!diall>M7zh)w@aorNE?8AmrH9&ynY!<`cE-CZ9){VKuvsN1jvV z`v_6=mQp||Fntu*bp}160r4Km&rj=+@8Ks~<@-2I^{!GtDKM!N2-#@$bL9EwI^_F( zVLiKz$DcEJzQptE@bVijz1UiM+l$>aC#_3Sntc}|t@BSg_#N&%(7^ig29`SYmy<2{m} zpVlGYPLr>Ndl3Md68mjWRlt$va`|6GTBKNr@s+j!(TRlbi9MQEFBljQm5I^_HPVLiKzN1jvV`v_6=mQp|| zFntu*ZT>u}{&6}>LUuF@_n45dRHl+6qsBJgnYF6N%H)2 z9rFFu}{&S%f2vPKwQa~v%eH7Sj{yeJwc#q`gr*+8pSEzg+r>Ndl z3Md68mjWRlt$va`|6GTBe??f&ZsU>XRQWza6uqSsPzp>R1$LW1kE%c3Bl-Dh9rFE4 zRlbi?RPQPUlme4Wfsl_@KS`c{u0y_mX;{y0BX36#%U|dD zI>=x3e0{`MJzs)GFg^xsUl*sU=NlmYcVdl4Ugqz;B#n`&u^~&&I8r;C-14Qzw_|s>TjQ|uHQUbU4Q$-o2x(RR@Xmxyt@A6mp50x zd9u3x{>Q58H@{x5{=*Ue6ysTbvKY_xav z=TccjWC0>`=5H?fDQ1ly%Xx>KdkC|*gK5SB=du~ZV_GpC9Gv@zzY1aB!^!UwH@7qX zAn>l6%ZXchpc>BI#KDG52e_0Ewrl#prTpW-6HG{g{~+)#a7lkN@Bwi0QkM5)z-8_v z4mOp|mBjC4em6G~2OBXm7ZN|icsKVE$7^mn$*}x)1DCmr@pui5%vHoc2)upMu)TOq zOwYqHtc}b)Opjq~WUe8OVP|A+A&y~YWUe6oN#H#-vutb zocO-)FqzwZ#7bxbRNme+*oBCGkIDyyK0;|1)smb;SP+ zxbQaOf5~{q%ZUFCaN$kF|6kz3i-`Y!j0aKWd1o=UgqJY>CBTJu5Puot9j_q%3gGhY z6MqeGdDn?w&v^H46Zc`(_>u+Rm;9SLYcBVbBmOdTBg+E}E;HukNZ$hf49aIoFK78@ z&phzXcg!!m1Je7^d(C^_b+*A%lcyF>3p^d;X_2QBJe}mJF>lW{dBdh}*bG<&FxF;i z*gTEn_KwZkuz8y{Z!@jR=55-%O`ErA^EPeXrp?>5d7CybxD3i~*}Sc^oi=aF=55)$ zEt|Jx^R{f>md(3h^DfxD3pVdU`j9s7g3Y^N^DfxD3pVe;i?PQTzJuihsgVocgcmzE?jltnhP(w@X!I5 z-i6C9Ty^1^3op9x5XP=8--XLAG)Eu);JeSBxd-9d_od+ja&`8;N6wm~%V*A>F-Pxt z_+fMOeGjF``|f+t-ag8U2Oqlk%!B6Wy$`+n-S@o*>EH9v+53)SUOV#e*)#XP3*A&3 zUW1hA9)l)ZSa6{Pj3Zo+gV!LJg*MJ#Ba?NIxbQ}Ve48cRHJ@-1E|BuT+HHC0Y70yU z@?;?CAnxbtO^}W}K_GD#Y&VvErtR>n|CKS1pb*|e_t~+|cHN4DWoJ`<&lu7`fN?zD z;zGIqnx0&xA=3~T$}$whnBx#GjO+;$q;7by~T=Ovm4 zm(r+oEF3mhnwMs2?M2}`sJYtvk9o;|#=GVv>8wv;UjBcHlv?_A(xj;qo8zT=^yKU&nvaQAN;xpFSo3 zd4J4YUYkB?1+2xnKHCLhKLGdN z51&4c9$`6;nGe>c4<2`)U;h3tdh~bYUwWyZHb*7RVR-f2)I%FkcMkF`X~QejI26l>$nEI0byhm|nM91^Kvp z({O!K!tYMmMWLC2oO~zb*kL_vVNq4LiTrW8Yy4ve6!UfNXt_SCg<{rm5z^L_KjugAPHyOZtL zx|9M+0j0oRq(GcE+q)aok1SyC&HigTC<6R^q<*Apl%Ma#ai!0s6xd4?DDugo{5to1 z9r@epM`pqI63DT0dx=K+EJ^{TfKq@IFs8^K%_DXAK?%%%& zlJDsb3dDRcQvP+{2X#Ks*G4Iz6c}3y6!~M3zpq37orC=QI>^8K$M%7>VM+m|fKp(C z6xgKvyW@HRW4JBV`eB1F0)p&yJdmP=Gxt;r*e$byxKK6*pAPN|%Kg!PkdcHp5tDY}GBN!h8wy%p*+4H>; z@dL#F1sWf=|MR#(`VX+-z0A)V^V31jzbVPj`up%T^C-fwd}d|&?N?Nn-+8q$=PJrK zi7~&0a$@DPeSO5o^52RKtiSX6>iWCiZ_H~W^)o-8uZMN&?;woTZ_96tD1UK8`EM*Q z{{ZT(f>@h!>D7-?!H*K(1#X)DF%U||K5_a{lCe(wPM|WjiQffW#xn6Uz-8qp6rHR6vWzT?Igak%&~T{o79e++ofjUD1XY{ZX` zxCrTC(9@64r%>P>&{L4d1%7;vjgcQ8&%K7{H|Ln=HwTjz-DJ?e%d!hsT)67OH5XoV z;h~u{{gMlpUAW@HRTr+g@S+Rn&<(8TkPDYwxa`6e7p}T+&4m|TIETD8zYCXKxL5qp zycOd~AaNHrBBZ+mJgS9{duezBq_q(Gp<%kqTpR;Q7y6;;AsxrGK;kY!KQ!%|jrj`V z=>LU$bq)vHMN=r2jaSn`yIs!@&0R?6gS3w!x;ulr+bA11=!fQd9IW?h9BhZzZ1d!g z8uLZm6Oi&kKQxywjq*dYSkDj5$%Vxe31PG!nw#)FpP+tdNCokiqJC&d4TAcip?@B{ zexA1#luWj{m|@YcWT{A0i}Rapg@5kpD)@unL~B>`+oRH zul7^p>e!%s-S`Jc*1Zl2!F*HK&Q#}{LQm@rrGQdkTqpo`7C@2z?yt3vz{=PAAYZE= znsMn|ZHH1oDX^z05HN3`MgDDWt0h0b7n!%jPff8+xjP$_znd^JbABKnsV#r&e6*)W zzdoE&V6rKY_8*Fm;wP8;@93Zm$m@0W6UrYad-!PU zl>&R30!98w$Nk9E zdCXuA$>eMKk8DxCo+-%B`%DWPN%or#3d4L;h!6h@I`lK6^G%&T(lkl|rNGWpAmEKe zGyb?f{lmv@A!qEM0OgN6-;Y|OQa~xN^%NjO%tKNCF!yX7`Pk|o=AeK0Y4t<9_5GwJ zDg~4RJ5PZ;ZzNXakLHCs{BiCXWZrQBVFb@iFgRF#0~mV`kjjMlf;;hAYEDceZ-gfG2{3ed~bO?>o@QN z_Hz~WckmAU5t5bF->&cj#`-&p)%ADb%Zcp|%NP3g+Q!^~F&f6BXjAsyF^&++lg7BS z`UzXNpD?})^yxuAVKVlKm-z|f*k(NagvnSYE`Gw;_r&QZOvWm4`U#Vuu-tX(JuH2O8BBa|sWj34!wVsAqG{w?kcNO_?jv9G{(^^7D!DCts%d&k}}Ki{n7M{MClW079O>i7}+1{(}m zhaa)4PPJd`+DxQ|^{zXI&xVUEj zLR{TN?iKEb8^=gnO&8K3~U@5-9l z=jiBgxt$-sSDkuM@=1AuONPhHFW00Ga|G|l6{lXz#*-Vb8SchI*L><~5-<|0wEYg4c%a4qoTKs3`AHaVA5&mQEr>B5^UW{Bu>i6e|68?AIJT%us z5#f7Lcl?I=GJM_hTYUV6Q21%hvOC^=MqL#DL;!2M3sOR3|{ertjhr6oB~?G?L}-FT|$uXczJCiNx_% zt@fi4mF-7-W&2%xtO>ULIF+^kmB`dZd>bL3Px=FwlrHVTH2~|60n;RS$g1{tU3`pw zY~KL!ET3|G2#jwdW7+dFzE=^CqBCIH5ZHbWzRmPs7x}B`GeCS5ecD)zF}{pGJ;Ybh zhfbTT=+mi)N7E`H)}~yBUC^VER@CD_{c1Wm`0T`Ag|P48Wc-OtF#18{U zU};bM2+$62DUYnH@8R^bonR12{XYb}3%rex`FXz&T=LUJbTT(ge+Tfchcn#(xTL=u zxQum{cMotG+r;gX3mwL>N}ORAxa2vKfv00Uo#5#tPmOtdwkaDn zX~U*%*u)K+y0K`}9JgniwPEu%ZQf>Di_P1#d7CzG^O#eP*#`O7PC3SQ&s^u|i)UIU zj&Q|=t1et~;T*;q;}5xT$%V@v90-N83OD(IX6MVx??7wW>EMCLP+2%)4K z>cU#JbYacKRx`0M+Nb^luFq5#M#9V5bd$QUk-CcdYaLw+UV`$g0;0N%@n5TDPqa<# zzX}!1b1g_+SOo}=fd~@?@-%^%Tq^u?vA<)yOxeHV|Q0L-7Dku1L~e;4sA zKL%{yz~zs{v-~y^m6gx<9^zSk*;>gUQQ7k`f2Sh8jPA&0A@+7kC+BeL_4x&rzbFO;2c2mX8LJH7+nzo{sy zw(5Liwz63WB34^&iT2DxZbN4od$l!;jIEASO-fj^ zKpv7&520*t4P7af10%T_CpbMqR>!4zp5_=R*#rf*3&Pzjhm2b0V{^!z5m>D%x@6#rnNl7EC(@-N}O z=Nta^ZF@2*Vocy&AzLxT@qw!U} z{}RIaem)?7REDbFzk%?o_istKuYEE99C}5ld_w(3dEKoS0qlEbSJX{tBVk*hO@lTP zDtxRP(*62NS@ulNe6%l+{s3rg`=k$o*0xUCv?*!3r0Fl!woLjy(AsuMKfwH?Et2MY zXxk%w7__!E()5>V+alcrt!;_)L}WcLM|8A0rNJB(SYqY_ z7}eZ?lZbaIZg8G_H-3CB%{%1HVmo{OlFaPk!EFPYpKFi06p0r!60pWw=^N8g_NeLc zsqt8!=(orOpb-1^WxKMUC~oL~S)Wh)1GH=eqn=DDi9Ve62Ye*$54d2&e4kv_&${-6 z`27JMdxEF`x%Q}L)}%uzVt)o>ZE*Yb*aKbu)Bc3&_7iW9^4mMKJ+9r}wch!A+JCaA zVSJ6J|qk(4~+kkyd*h>xQ)2>oh*^ zYu{mb$X=)EA3$_%>x|Df-ITUXTJ3cjU+s1Jye8snTV(vlnV+;B(oZr!i~a&=ZCebt zp&xr5?RN%73wz!&h&dP=K)Uw4>GN&RgN+dT9r&-ufN&|9y#r#p+qMS>lqqL)=taEG zM%eb|Q6+rNqTpkKmj#~{?Ar9^k;bGGd`$3GvGv_T1C~H8_&Q)TZ8M+p)=?`CX_aGc zkZTm30mj4d-2si~+WMB59~-hjF4(p8EyG6k62cgr^A(ejuRHK#-sAWYmM)I7^?e=j zY*7A)^&J>~8u7+)gLBMP`0=@5rDW@S9k$5-2KN;-KiAgxAZ{#ZBw&rVV(XiUvh_{O z&CSKy`W}!vOSV21yz0Jd-2YHI%cQfGpufG|W>V{{o$}avtVUxlo7q2};YG|@EQn?r zS|@*7*AafpwwR&bYd`4nFP-Jksn4O^3vZeM|JF&Dy$o3!UDmX-&eKX4I);U0W@~si zW4D`uj<@q}fY6v`vj%?bA|YL+CE-9NVEP1?)e#nZ$C_4VSGC1SK$ly)HWBX9Z<)S2mL*Q;8 ztd|Vl!hjLuZ~v|{u;_abTkK@7AzlMFIred^;p_Wk@LRy&#}KBV`MEOqC|+PeBLQo? zl{P$^Wbkcv9-on+%mm(%k$cPFBap$3oj=LoSD$+mI|Dj0bALKelEJ0iMmpymc4TlP zI9P+0bE#vPGo*H6*;9s3#?y*DpTvX2hA;Z?;V3SN-|d zJa?xX(R|d8(9GWTd(1RO2jCgkg{HBxht|!{vct=n*kAp>nZL&4H6Z#-Y&V_K%K!0f z{7f4e>V0Moh&~fr(`kN67ujSZk7e(SE+0PEJls0d+Re`@9~1R>_Di2%!j&5@`b^*! zv+2MZ>epk3=bF1#k@wom$CE$(I6d-zBKzv~aGV5m7@z=Db5JG9C zjRN77HVO&%m9Mc;;IGm~f$)%xgYt4)(ueY|kB0L{PzOSOz9mEoy&w6faiuD}Q4vo5 zTL@oE{nXJotIB5y;VfSt82(}CVYtsm6jMG8q_2AaR*&!;K7>&EP`}f6@$sx-2B$sR zrfg}WVI6BN;{uqBol^NN){h{d_#kO(ZyYI{` zZ>6Peq%*apAb|YqO`1gnShLQ(3C*~(rds5QbOw-=Pe8sp|7UjRV9@w;4-}k+{?&FF z@+;Z?E}w5n?Va?c_<-iw27V!b7Sp#R9H<0LpMy!}A9{Wh;cM|1(r8=BKf){dm+%tv zxMBFmUnTzt|4ZM?N%|&?*_R;P7lq}w1pBc)B-(s1JdCe@+MEVP$we66$p&x(o)0zPq zJ^jVYpr1zD1PL1X+m5KA_~x;D2G9YU#ctp6COQLX5reAPw=8&B@K*69pX3MD1aiUG z0b^N=nNNA^H7gEjm1Ay@Yi;d}hb0yr(0E+t#%s<`26p404Ot);?D~>NvBuyfgwemu zv6V^4*B$sVzj6Ew?1}RwUx|1&D1XHI4h-Lmcrj-H-TAJ#Gk{*kdn{NF*5`J*aBV#K zk~hQtK;MA! zTfBDp`+0>g`Cp!lwb7+`sRU99q!LIaaQ;d_#&QpW9O(Fxb^O=)N@<-BMn?Z>&g%w# zX}&mrb()@>N+6ZM;7WjFS~nzL@;PiCuYh&-#d>_HYOQwqKC`sB za{Ef(ld&CJD>m7GEQcww3%NypsQlaKk_TD)~ov@+F7sSN(0J#(^87 z*3D4+Q2(42wR6e#qyDKyX1ho^}-2~0P$N0RTe90&Tz)s^KE3OOrLi0Una|fNS+LsJR)G+#zF&SFEvgAuXypY}W zOCNjirp1NB3+Cd%Pu;)pV0P2}pL*z_k3D=iyXoOi9sbx&@Bh$;Z~XM(h5LVTr8V@v z;yKP7FI29ePu2z_qH2dOzTS+JK@h zq;vEJa*kf|B`06b=YY7a!%5O`r_r4EfJLv3t$652PZ%1h@ z&o%8^vC2pD)BH_op}dC2R=3`^Mo;@mw!n|1eI-Rt(EicccO(07hG$<%jS6uE=%}qS zyBig1Uk5_A7Dk{R?E}jA4g4x?X%Y@p0;bQwB=ZkFzlrc+umzTw#|^_j{wn!L_y>K7 zC4C#=kK#J?{tZ-;nIb%SP@l+=u&RDqNFU-4K^+L~D`_JCQ2p}#+dabTXndjcmPmgAw6-16HVkTC$vtSB>;v8VN@^3sX$zdNY=INW z7C5A~z(d@$A&?8c4j99vnNNA^q!ov>$}#S~62?Q9>43(gUx3#fe+ez-XAR~#Zvtqy zVo)7F!WrxndkL8LIJPng`MLu?=BKXL7QO{dd#D1#_`6H6-v2J**}ymiV!Ow_hIldi zN_K(2m~Trz3A@~ac~bGG&t0*VPbOPn+E)^#>!vdbr6UT%h1s54 zdfJ-a$VSY#37eA{@N{LLysv{W&e*oVJ0fg>BM<)pGTGN)PHW=FW6SZ>&l+ukM$zch z|9ac%(itjI^$%k`7i1@>&e9oypC*9A^W zJp_=-fFYZLB_12u*Ud)d)p<8SXv*3R{P@b0on2u17Jhb-*m0OX2b0V{l)j1Zwb+U% zbXW3^@JjwA+~!-a4gdJ7`ZoUl5pd}J8>8X!Gv$l$s`ty0afm-8?Le{x zc8a2N5mP>DukqC%>sReJp>Vb5_`*Z|RvGlA(J+IPEztBm+RE4mw6Bp)w!oE^vJ)1S zrum5;VhZLg9rt;=f`B>_#>oQG`nUj~dko+VpcQ9>SDX|l!Hh9__TbLZ<0 z9lh=^NAa6Iy6)x}sTM^lgN1Z@+t%RI>uKvDP>=NiZ4C|lDs5R34paiB&$odsj(Wcj zxTfIU5)dkX+7Ij|W#_~CsiP9B>Ssy9efcA(10h=+jfA24HTB;kyj2lS{&O_Wwb)v@ z_Nl6TxNxJYd>RtoZ~3&4zN&n3EbOQXZ&rkd`mI))k7o@tIN9Qi&CRyOu`bjWr+tSs z*X3znA#K`}v|ZAn@BeCk4M$1XbrgQ?idflYX>x*yY8;e{6;&`vRp3Rb$2&lU0Vxbz1H2; zBiG&C8@cZ85aQ)%51eCj{KzU;F??v5fXt5KpaX7MQ_%ONnahs%Iub8vBw&rV(nF@B zY;7~OiMiN4xR+j0Jg^Ws(;nQk2iIzVyriyUCe37P%SQ0+Fo5<;UK2o@QhNM*4U&Uj zchyz?qpy~~4eZ)7c%JjEGAkX+LS* zZra1&EJhjirLEqU-x;OW+gC8%d6M@+Wz~?)(NeEz5-tJMTLbf@km3gQ*9LwRQA6ol z5)M=Xrq977^ADwOB77~jWSZ3~`A2vq{}Nte9ybjC_^ad};r#Za4`>JJ8swq-6NcKsZjb*ztw8<)v1OVoO}hQ@6oo-HlTfp^aof#(liP<}XWa&sQ*OXbUTf=Sycl0W zb_o($gLMv);Q9()-yP>G$S#Z9qkkph*`V)XzXQYfB3_P{!tjyh_>onguizH&7vn2< z{_VYd1+!7Ug1Oq%c&xABb@PqBbY3T_4xqZh=3kfl=bwHv%YH7)u0w;|`EQHE8b`97 zqxDuc^Z)$1`Qd#X9ov+F^Ot-D=d}M1hp%AAr8o3kmwU4raCiPiGrMGZ=U;$Gu&qnL z>C-k@>fbvqifLavpug_?iyaBJbqN#=3FD*XD;>S)=7{sEFHYmqwjPm+m*3W%C%rrs z!qWV+b6ao0jnzQK9qkZ&&kWsX6c-3OZZPbIJ(C6HwvU#PXOteC&od>%fHs<7~M z)=Kp}Lu^gw)en9xR`+@SR{5wsz|oV_zPo18axj3WeRtScTmhWly4zRUcW1^6DYJ6< zp#QzuEJC&ab?E4Qch?{Tv+r(Jo)bW7+X?yPEc0{Fm(8r_1NqaJ+Q2X53#16tl5n6B z7+)-yWd1(CAk#Myz7}6A4fB=!BfOG-2`@2^8-{=URq~JU+xa3M;O#bE{MJCY$se|e zTSvp?(}1t`KVd`<#Q5r4SnF>$SvwoDmBYqbRentg_thWR?g0G=E|Bdu(ubbU@H#df zRD~~9gqvc8A7d@;r-}5T=bQRNcvbn-FAukmnDSXd`q1-DwZs2X72c=_4~+|2Prf?U zFoTn?-t=wyw%G=>FO#OPK9{~r`XFfStE5?H+V@BsU%m7t()S@;`xa^AtCzk)nr&M9 z2I<3~wJ(tV9BBFk8IN=mSlcq`$3eHH?UFXWdTFbqzkqOUd!)@7S<;qBbDy5JEz&mh zxSZ+z0pq=oj%kkf4$O%BG^(;qdK0@{5NjW-|WIn*TYQMffXRJ67KF1oJU@UKf%WYpAmdk@F*&W@v@sf{n>{OFWd)w z_?HU&fL--S!SGT#tG|hl5XYR=|0RB`*aCeIVl;~m zoJ72XxWW1R8vOWN3`2%DR=vXOc<8@U0$B5N_Y59~PkzA@Z>4+BMXdu!dj_pSEZG?| zTh9=^qN8WX*}I#69Y8v(U)q4T{$0C{(yDhJ&+dI|8yV<*$!lo#3<^ITq#h$?( zA6^gJV#+g>Kq`S$0_URyIs;zkBKbMep24(d5K4&g$KXtZ!mi%wA7wu~&NS$`jxc@q zw&2V0qf-F$ngN<=ios*6`;Ci$ewAb*RU*=LG|7Fa*(-0J-2}$ZFZsb zEeQuI0n_JTlKF?yHxa%TJ2jQ|O8yaE$-jh`n8yvnKmIEDM|j#Z7_ML4XXPv3QR`-? zedxX{D{AMG?N|3{b#7W0rvBh33e}(e{E(kU_j&pFWB$7DD-^E#zdgK5v;C1}akV4W8& zd;9JgoEVSt6{J0b(ol%JwqjTI@6cPuSCIA$N*nOjzuML%&ZhdVZ~UIY(MOuu#eX>Z z2)vUCwsi?eJNKbd|A^l+IQmH1_OiW8plDDq<(O7f>=}sLGq@{_OWS%xDqenj_n!3j z7(Yt$5BChZ6O}8U-wcuF2N~s?v}f>q_-xZNH%AF<(4N84o+#C?)Yqo8^y`twvfnUg z6&0oE_VzBiG(OPR>E@@jK5tEX64RbRYlDSnEymV6f49_r-T9_Ni?8^xY>!!V+;97J z^Xt%Je_E5T-d+nU`E~Li8eey(kF$Swm;XTczXlJWFMVRX^Ca&@@};9#hQOCT40{Iu zo~MNvUvrN=gSv0Yle}0TLKt7V?91};Z$CfetJi&7zVysL!`_t8S`dcozAj(-3smH%b{!Q_3ntyZrJHWr%xcN6RYZK<$#I2dgH50pL_Wjk&zQ3AD zS~F=exgv*&;wdKWgh@ML(oUGPp*@30+wuHQjHf+=Y0n_WgaSB@@Y;;sz-iB5Q7$X} zr53dgAnh3}%FXA$n0qPueo;0Med8X#?K+SG$qK*;MNQMqj<9E_`>8zK`0$ zZqA;7tNt=^mummf+Ym%xT*01 zd#<|el!HIJ&=^rR?CeFWe008W%i)RafBh88#J!Ji5On5KDKoDfSJMrD{+{-;_52*A z_SKPh1M=^h{1EAEL{r{X{i9Ru0G+zv3OObD<`O4R>|B#(szqRH| zZ|V;TL-o(_W<@ypPkRQ#*;1V!t!^1DxSV;F*nCwlCY2;RC)lbaX>om+i>9Yt}U; zC(mUN1R^R*Mabmt(&&&mW2C?+1SeQSLy3O_^_TYNdDCq5b_n|6}En+ukr=h z-*IAG7g)Ykz5+YF&o0jNz0McR<@`YR*`&?;!{iaFKl6S_&-M{2pLBj;u?K*krkFn!D3A_A)MgrD&D?MZ?$`_E%53~xgY|FM~{VnSYNaqJi8}Qb@Yx_`IZ6m|% z3y42I@PaFGe&EgvFyy79s{QEzTC+31Jk&) zy@w?8_S?Jnq_@ZTQJQ~vexT*MGi!fbU&750X?~DVzDef?ZZ2R1*qer*L`Ih_Kqw#i!5^esM99xM}pw|}_vafg=n@I>~{ zUT0$WeqgO;ssDA-_3i7w22VHp>S!#k0JX7(_UF*1s}S-bRzmP9JogYX)(#{OWTpD0m)0YglQ)lcUeZGA4>HNT=K8o5Y{`>Lm zFG~gubc!D52TrZUw_iR#a1bX4@}$87mWO}JzE0-{rt;f$mt4c1d%qo5^Vj)KX??aufp2P0`XUp$>`w2QPQ|5nD%J;q zILk-(S#=n(E^Pin>2+V0m8^4V>QDA*b#7W0hJWnST1)xpJ})1C%wP9?g~D|om@hok zZ}k;?X*A5>bbequKM)OJjpqkWuf?yh9(x9-Eic0KdD=5LkHLj|02c)x6TB?=tl&|^ zVZ1TH?q0!Vxu5n7X4zWy44RF2GWg|!xeUbKGx$23qb<3|v6J(QZ_gmVtrxRr@Jht9 zLFFxCRDTEdB3_Ogz4i>=0{&w53_c&&Gq``eI1Nz$ZL+v7{%5A9OqANhltgL#t$%#m zows9oc8BK?j2bIcmibsy#QCw1+O+CE`DkeGBd1S~Dav zeIZXRK5+jdpP9+WYd4OM*BGq=lvigvY9~c6S;DY^*dM~rH?MA{x%disYrYHD0NBuv z4_f=e5;CF>`X*rRv1ggSjrp6+szq&mbiDRa)Rs;e-1Z#VC$3(`v#EPr&T>ohcah9xj zxm>gV+G8T;E#1FdH6}LjAZ-WCiqGZmF2O(s9#w{fR+89miAQmxg?k(m`D5KHAKDjj zE4u}WZs&!7=7;4?7@=0+Da2b?Aq{UN_fJgdaA!KS2FJYjm^ezt0W4GhmIa*^Pi*(11t9M+J)gOBA$gMxP4D==VjXeLWPuwit%$?b;*8l$9ubM~l z?;=yIZvlQs_U`Px*`7{_<^Mc&O2*_vZ>x8nZ`N&|I@O_N?8Wo1&JMlnS9bWHzoXzN zd&|3;eA1~?sD^#Q(FATB!~n6U+ot&3E4aUi-%I#e0Q;?5J`YEh&%-C5-g(g_Cp_g- zl*ih*^p~c^xmeLh27yp_WYCPow!da)i$pbrdhkq-7O{e)3X`XxKcsBl5ZBPFAei8uuc7enH zrDgs#e|_F#*|JkUT%%~qavUZII+llIHXYwTgSb3n$OSwxYvT6>H$Z5n&+(9DV4qCK z^lgOyp2T+%(>D<*Boi{c-6On?NTKwc^Atk-Eg`)<|7m<;KA-(PWS`^vH6)x-U10ha z!kNEJWnEF;(nXaCAJ1K}Hqid0GB4W-Cl$&nP5jt4Naw)0v<1@d0o|6mCrvr4DRoJj zZM1FCl&`cd8Gb8htsBzwpff3J(jNfXuxQH5Ezm4$hTG7OOwKwd@Es_Ve*)JRp+fM8 zfJ`n&KdtF2(j{?zqAbqqDNY41BM|Dwz>_&IN${fJV}h3jpAmdk@EG3Bq!YX-_?Y0W zq95$CI#P~zC%F2-omL!%qX-PR`T^s`=m!nNW7|>4<-*ku>QELM2&2wG7Dn;&*-Yve z#_0$5BAyM(0bY{b09LMA8qEejxI9(hsU_fsE~m#4b*o4)je?i^RB zmGxcEJ}dpF^nK4~pSAQSCLMV^d*AP8&7XKt^MT$3c=p+yqxEK%&DFDPZ;l%s{fgIq z@Yp8~McOA0{n@XL{>Q)laZEF={id)_tk_J7NBeCiMOfGxQP%$+jI=*I`03LZ`uX$O zAI6>WJ6D~rV9>JfsQp2)zhL!lng40gwGn)oICHmtulP{^tap{Tl`mwwCg%^}o2+?8sD*tK%$y<+}LNYDDAZ0rK_ zuS1D`#tjgf;Thyy>V!UE{tXHDwGU)n2|k{>5)83^ek~Ynql3{lLw)&r;3f);wiMF) z8E(;(vFj)>4L<;S3AF0lKMk5n1ltPJ-v+F0hx7+Qw-B!J>DS0nfNUEK|5@NA&}vWk zdC*$748I?=)+K4`<63v5ZRkhe|CD6VLRQrGKM(pVXd7TTpzlu>J~*?n)2zan&afSG zhJR*j=U@#1lVwA|WS3tLKI?h#N_~D&@G-&5g3ky(D|i(3U#0&qOZXYVqbM839}_$; zcv0|Hu@^j#dRNHh;yPgJ<#>GquUm0=14U%OwHGknB@#xY@mzl*GiTdV$mPPd7wp4i zcpPE9>;)|hXfgi8?>YmY@<(j3lf8y`FW@GlbIWZ`t{pjZpNd`@1Mg6=9`T^w6HtAm@E5|jh zT^EN!Upqjxeq!AG*UGB6oV#Q%(VZ%^bMiNW0dI^L^)oMcQSdRr%Yx4cJ}Y<(icyu0 zuDbbIiRbF*TSX^-5OuAP%f)rTwoY#A?Tn&2rK^)OUW`uOLOixNgEv|`sxdnGz0TmP??G&_lO005CER3mE=wK7&!>~WfjxRpBTPZ_b9M6FA)S0q zRP0Edd}``|DDk~@@)yK#U&sLavRxUNwZJ1&rZv9R>2-~$G6K*gl!5tzmKWZtR3icr$zt#N3U`C)9<{c z$|kb1#(|4ztM`S3xh<~|h#r5F%|lytZ<_~wCbrFEx=7lQQIpLhY%@^3Rf?<&(dLjt z@Eum02W4^v5p|U`nEX?ZUIy~nC+zfWLoP5q_3o-Q5)J4v&$tPNw)1z?4ikg=Mh+#5 zHWwf8`ArG;rQc3And?y&ODHhf|7i2r&jLdMDNP-xVbNSep>3P-xrRd9GU?kuH&H>l zrh;oI+Mrn%4Cfk(IvUNg&|E{IZHeJrL!oVh^!=cGkkc+~+l?H0K|V*WSby7%+HBnQ6w9ar z+J4Rm-YT}7m(d0ka=CDAIlE{~u|OqA*OtS0F}9o>@z@R(a=CDAIj51?354PQ(jp@`YK(Jf=iVy z-jHy8j*ZEG3*pS)r%Q(FMe|_#9E{V~72>~zfQL1KgZX}SD6FCPgBqP(EoprGA!#M} zcwW>&-5_+=`=w%#FWLgRP>IK52E{TH^?=|4+7&sP3wTho5LMm zbDScy5s&RlA(snRCp`(5_z{Hl(n%YL5Tlbm%8V>f{)jDhvZIK10yjC^6~ABhYf{+5Dm!~*kLb0*4}NnM=l?EdUF)aV zj_kRZZPN!@NBz#tEdC~boV)o<7o4W(27A+VMH&Ko6W?tRb44yMwgk+%f@jG52tW3B zzrALzYpy6w19RnRU`~uJ%yR_&c8nO6G%t9ojOTCQeH3!JaL4mov~f$glJ0oUcroL7 z1M!w5FQQzo-SK=5<-G@Cy~cA6#xdjhmG+>GeDytu?V!CNzJ+@n&$&Z^ZNN94zm9lZ zr=y_xx#RgkyvKq@0@ir@YqMPkAoLv1XXYeIZ~y!YWEwE6pr@4@%6gWdqq#y!quFv$n!ve(d| z4FYsjSqwrJF#85r7${%L0`J2m*Mei1 z^~(aa@v#%ci;)vDb|TFLmpOg}S57#B&cd;wmz=-`5+f&EiFh_B3&i#-?qxjOq@2L_ zA?ee3_kzElLzsf*=gJ9RLA(Wx1g!D!4KZ6Z=(#3+u-{b#8|UF0Vk}F0?5|nnVqa<* z^*ax2=5g3Ahko`SX{a#f*t<#B1WGkjsTTCLY5;rDG9>6;r1^zfJ=TX**z6 z0Z1yVurhKX&EB@V91XR_E&;==ZmWLr&ChW3WBhpke*?mrb8WT;k)%Kdk#I=rzbF18Pzeg z-#Opb$IH3Pep3W|2*2H)2<%2}{1{Fh+y#c$!DLnV62fmsJlYstFt$kiJ?sVu&G07v znBE75KZJ9QnQ!eors7KQy;E0$A@EVKY-zyEf!p{geJ!rF?A1r1Wlh@n7^G}T^E|Sq zlqKn(1l^XhBW*)Jwz$7188lJf)I0A6eGe*#(wg5EC+9btvw*x`Rhr;w%rz5UD<8n@ zy=AR^K&MgNbP+tzZg))Zvfwj<&kEkE>$eZFqX^`JT|3`ND-NTe8V$Je8{=IfVMH2_ z>sffM*|c!MwxE#9g=^>g5jyD|2&Z$wZFv=0O;(W={UX`S{+%d;j8XWrbrRj=01Ts0_Z4feZ zE-$tO%rU&@o|cL3bwKVwj!G@x5+^q0o3y7z3S5x3b$2{Zds>PDa>w)Fo|eh!)%mj1 zo|db3T%8?y*RO2EI$$$YnUmGTh8lgo{ziR2gmS!P51Xi2-BkN%zw;4wz9xQYPsRcjC?C#R$RZMSe^DS%~~W$9a35j!7EN$H=*Uo&)bneytzQuI@Yp;RTIsAOdx)dqeVB(ohiFRMmwzGst^g;UU zG{$d&zpC&?ML6X<1z-N;kA9`wHIjq*{2ZBZA6F=SQ^K93hGhCS!kNF%Uv2ZJ=d;=Q zFnt{lUIz9(pL$Le_|kO69|GH#yJwE?N?X{qz}j|5Uk_T_3TfkyMgg&HkfsczZGkj> zL|V6`*ZQp-WY>Xy{3|?vn2@8<(Kh!rO({NN4fzv}yAR^*Sry95In zcogw$(Dxv=*vXC}-Xpll@$T*Tv3>je;ID(R&m&Ah^W%KRaZlk@WVE0Ju*TazsoxBa zJjZP7t?iyjYrA)5S4i6!ln+JwLKFE$`N1cGYr9cDC1X@t+l_KfdjS1o;w>0RZym|Cv1pLm76+kAT4Ga?IsQ54=Xl66urHjv zRe>)}SNtK?b!3y!{kCNXcJ9P>}?!NSm4_U*o82Meg#lN}u!iz3B z0nzLd{6?Pt)hBM2T}9>Z=B=iDyS`zEePsN0hP}q3*FLqO`Yz;p^S`=%T*c)0+$+uO z%kM9)d;ODt^bfoIlV8LtwDY}>&*PUl6#3oDLx1*bqyBHmto|#PmgJmem!o`a*_r#J zLeNW=rp-(NpJgtA+Q(?~pqM^ldQtd%!;6^P7lN<(Fyq2(KfPPpIusowaSzFLOO;ZA+x-*U`2^nmVYq71H$UXx)>hUni5gBz+r5ty|JOTV3mtH0|0s z3Y~RFntquj(CUW**@1p^F@9H)&_E-lF7^nnr%<6_G2rK!t~!e`*3U!FPx(CO3EwSC zhr6uzd5velH+8(Tf=4kf7@be>qTpkKmj#~@Jc@E){H>xB&RLx^$7>N>pU)914#QCt z23(&H<6RkZC`?!R7Y)=ZgT(~};G3YgHZ@qjzjG%UIX2s|7=lXoEWJVS!f5a9$ z*QeLkO)h;STX3YuTZzKQo(&`7`U?yZ{o;PlQ)$iTv1~b7r^YbeeYQ;WTHEur zmTtxxBeZV}!vA4q+qtBOl;a`Gzz|1E!1=a~@MlUP#SNoVAW}%DVt9tXs_;fdIOlYQ z5PvPCzg;6an9t9VNtI64lyE1hA(_67aOUsR$!z}8TDq0C#7=iD%TC%3Y3f`{(pE@s z{k3#6gV3=`i#cY>>pNy-d#sUxMwvF^-Ec#-Noa}i`EM-KXF0Om$&o#5NwT)K6}f%n&j@(>Q+4T&wsQp@=w3>mLUIN zcs1(>y13=Kd)pW3(}!3h1g*KG*M{}(&8*js7S(M2gT7?=7nTvjr`Ox*-)ZHgm(*S zxM#~c_-vOBj)fUx;B!57aP@J{qg=LXW#B5fwza(tj?<+#qzSk}q?vtVhjt=~2m-i5gh} z9Ye3eEnc%v66*M!wmMi2n&9e9Z&+~{uKBro6XV6`O*uL}+mJ#o7p~rP5Q@tK2=bMsKYJRTX^djD4!4q%)wE8CF&IOs6nvp&8 zz4r~C5nVU=GSj}n?YVCd9nN&fQ>Wzpu`lt>X3-7N+s)cSOK)Pp$nor(f0W}w*ADV# z#{G>YSc_c!_HVp(-Q;T8dThCRy}m!g@v?~@ZRtKRav#cn8G+99VWKmA8{z%R)h0du zC`y%c&n^cdyO4IAQ$Y)cY8-QMuE++iAz_$W4svo zu8w%DdxcysT=_1Cj8aEfFZr&C0VGDg`;s%zC=0|KFBDE9UXGg_D`^ks>-+5Dry-{< zY9e6G&z0{Qc#j27y#3SDt2!5AdQ!gu-dn!g%}u<3B;O_ZPUM^DwQAoPU&Xl)<16L+ z)-xE)^RjI86E9}j#m{GYE`;Kufd>B9d#%@I&p)kI+q`Sl{`!9kuk}KAC|l3FR!^B; zwkO!jx>ipGIu~wx^pj}6-@pIA!uN|F2Jm z`M>$;;phM8zXNHJ0smFw=ecu(EB|+6oV08uljGKKsrKzb_X zG3jkxU$ZjrADR9hHYNv{zKM$A^L_P$qOAm9opmJ`V!!cwz-Su-5c@v;wzR`&Unf1m z7eN8BZCb^|N!uXZ1g&*V+J=7C{yr`lv{44MKmIOgo;QP6 z^!uqN<=e7RpQ*5y`0{$ze9FQkt(i|;;8V1?k1sj$-+bZ%r>pbYST=Fa5wFY3gE9TM z_RYz0b!!{mNA~n@&y3xp>#h$zhU%dG^o-z9TpN3;;A4WfioJB7tT$y7%J~Oy?WGS` zaTu<$f@?2jyh|8CK;yB$@)|{Fpow^Fs|vYXxc1UZFT*&1uwM4k1~yN`*h?REHd!ct z#C9({ig<0@n%U@`nlrOXv`Hi5U z$B_3{+FNlH@1u~*g*zsu?_~JL#5I2>WBS0V&O4}0>6)V6KBTY7oHMLGB##ZV9=Ue8 z{@^!9ZvDY!m|EPkuXkp<#G_HPWUgFZgmilmw#d9Ydv69Ai({c}7cla+w0j$^bxdaQ zH}Rtl!8iVH<}sUNuD;tKWcnQW5ti`d7|!oW{RqGC7~cI&y3#;i{qvOXE4t1-&L4=y=Yt!v|VN{mR&BJTFRhr!$-F#N=wj&g{Z0mm5pKapQUC z+jTIXl)v`_S)nw<>j&)8c%EfxJYTQzd~#Lav70zh6B|cw`MgO(4!=vSv8@bTgz!H4x^w547j!y#*4AFv=NW(LLrw6*Vghf2EBs_>*Y^`x)x_^K|CAu zJ%}xKvb~5`$4%N=;0iQt)@N%m`*5ucH9yzZ!f(1Pc;fA!nOW8Ti(2}|bovI1Y zX3IJDck;9?_G>F*e`wc^87*7jwa%rS zE1UR*^i@K zO2&)PE0++j&5Q(c!LD9;7L~mZVZHQ9+DBr1_+Qc&lIQ7r5ZkYK67hb3d(8C^SGOiB>6K|NwB|xrue85;plvMam0A)-2i)1! z(>ccNG~e%KsLpM==1k|d9AP=KSq2`&+{U?*(84cHuk@TLUz*m+r@~Llsqh@Xl3s~I z09<4b^q{qMxN{lf#mr?n;H)<%9YbJ>pr@4@%6gEmaBoSj(R zdb9(R62G@z`GN@3!>U($&e%wLT^8}xH)}4FZsSFs_1n>BP@J6FdC?^&(9PZT+r@hA z9%neft#Lu-IYYx7=hXGRCs!|}tx!S7nDaFkQ|xVn3C>^Am6SDuDMwU+FHKkcA>ISa zxmMqO5OcRrFXi4w&ar-fY3S_Y(ga>Uj(DZRX})Ju5=UyNS*G8$uyUV10qV?o}LNXu{k z?9{5(B2G>mh@Q*MqIf(j&E+fSq4k($tQzvJRg9ktpRSk-DK?&;ZwJQnzd>_(SAjdk zT4a$gJs2*3tPLId^8ek}!u(@x>Cp54#nWN_u{L$+`9E1Y$F~Q^ zKaV4@eMEYWFuStOaloC zf}J+$M)s*9#TeoHUyE*u<~N3){|}!H^MCu-2FL$9(eN$Xz|^?a5md(8thNElybAWU-lOiV z`XyBG64+@RvD?IDdeujJrKjxe0@JJh+AF>9ENrG%eYfBA4d^k;$fw`*IUK!fN#9;$ z`Xy9M==sRn>^BAK`rZ&}f};`^H?4nPnOMPDwu$__gSM^QhJw(xLt6{aZql|u`YzB~ zx1{-vTdk`>*k*nn`4Mt-0@`M%!_GsOWuNu>ou}k1Vsm70#kbIG+YGPGLBlnZs%Dba z${Ut2YP#O*DLG=8{ER>WA0q~@^MV%z9}~PR_^jYD48DxND0o@$S;1pa_D#6pWx-p< zrbB~?KrXms)3M?(3W~-+$)y_*~8_%9_qOT$h=;%dl1*oO+H^c?0~aIqd|k8S>TL0EE?&j=)%Hb~Z`XI# zHv9L@)|-D%{at!t6rl|J14CDPr@>Z$9VdXMJCI zgz=xqzWCS7S>q`mBO@#P%9G1`4z2t(o#s=ddG3|t+4x_zJ^Al2Lnip`0*C)g%lvEp z`n<=o<>>Okqs&vEeOAh6&i(%Kv(H-PL(WDX&))a@S(D!rECA&Kc=p+yqxEK%&DC-K ze2yEP^5eB1JT{R-k!J@V`m8dGZH3|Vw`<*#*0Yyb*Q9R)*19E4olxtNGW;M038gMb+t81{UUk9-vQnLJ3KhyW?biuA-y?vgH)x%(e9Y67e9?gXP$!%xMuS`w zd`$4N;4^~H3LeF{V01{qi-L~{UKV^t@F>cG@wbXjIA?Xv9Ir)ib;2W79EPJP4BQ~s z+R7LYYElO@9``Bm+KgksONhtzq>#&ns}u4&NHIDgm9-c@|CLngEKvT4Ep{@V(bUAv zUOFND_c1!*Q+SUB&vWbUMmQ zOAzR8x8m8CM%F_nn^k8e|8>ZzNv9n?ot8SO*3BSv-20{BHqof5t9?;Fq+k06YyD#u;6L9ZV)Qs@0{q|VDV>nHG%)Op__ z&-M919|V8Dg>VHe7uOGZ82aaeMgrD&`{(pbj@*E~(7m`W{%6GfIW-ag4U(s%B9hLV zbl#-%HrV?Hs*@(2_uM%nZy0}U@`JL0ZFN7Wc}MvhMxA$1{C($V!#X+k#`LX|4~oD4 z<$nnChjRh?=I;tHXxj`z-&^E+s0@>A2FYgNvx)Sw88EzEVN+mu6M6z|4wS=Pu+$be z$k0BXx*~3ZwbjGwM|W)wv>9k!QYQEWXsx?J*d#tB71t7*#OFcph9VfYNpyd6bO1I9 zWKo;V_+LIXY^wYT(<%Lgso`|}=!?*-iC zILZB1>=!bJMFjrwsOr=yS@RPWB3}OI?xO=&-3i z4O6SfV2?Z=zn6Uo&MEWwc$1HQfIjqOuSoWa?Y3^)9w0sAWBj`Eb@I^RC-FC?5i* z{!dZ1ZP8oC2}QqwD@Z0J34x2SK+$YkbDbQ7I1t^LdAWmq62Y zMEX8pty|I$fY!Ps&2(CKq;2SDpTJ?spoOfshT;j()%FVc#`CI|O4w!zULT-|V#0g| zdZK2o&GzyMkA<#NS*mz{ldgNZl z`a|y>x%CH^p((lF(b$>ok`)a_kraCyyY?$;S$TBo^qrIeeka9KzR6~hY!;pFm-d=> zio$z=@v)dJu~R(lHP7Cg?ddKi&-{^W7E(mkJ|zF#hj?o#zx7&U(N)9cvmyq%uZhnZ z#J(UlOM6|&w7i7MV#%hGY$_p}i0a*;aMi;@;i{MWY%0{$bNFUy2k-%PF#2v8?n|$_ zoG&f!`FQGzJH%^9-UCM4=%8E0CPSNw)-`Q3p98IRI|!Ri6ZsiHqoK{_pMZD?ZHKlH z|Gt;$o9?HDWrlyo?ou;$mzuG=c#rj?g~mkhEG6Ncu+0Xc6Xw*23D1#$zFYEDbz{H5 z#)WzCzL9%k+%+f1&_Vh9Wx-oz4a&=C7YeytxNA^$1@@Y_Yfu;uri%{foJt!huhou} zGe0G8nd3*G?SVmc{0J{1v!{W1kK-5H0@=L-Kjt@%A0fw{l$bRrKZ$rYD1XEpe-&;) zyl>$q$64mf=X%$mfWPN75wPax+H(%VwzA-fxBtNS>dp?FoQ__Da*LR6l07HwnGt>T z!N{`%AN=8Kt2jGw+$rDObH>6V8vje!lFg39t=R=OMCfn5*LZC9{5|%%f$Cey-V z#eI)H9=%5G9Y-#xI@@nx-#g$uWb3*!)+^~;71DQgdj1U3_|8-3eA&d0en}rNeU67L z1N(Fjrf(zs8DC=DWBMgT`Vg=$z2OgkRpE__aC->yp^QvFgO!;K?8BxOwFC!RG#=sNxpn1WIf{zJa7JNqVS;1qdFOyF2qTpkK&j{Ws zde!%>PMM<&2(DhW&*`Kn0t2pI#duIPI-v1fy^8iJwjqUFE?m9p5hykfAgq^O)qt`U zqgOpjrOX25kJw@-JBoOZ;3oAdY$Gvk%BNSo4#qz3$LnRx_oqa^+K@L0a^0b zp?N|6Gsuz4K$Zy0y9OMQRd08&FHI+q7enl4ycX=W(E*+Tre1eF@DeIq^~jCZD~(<# zbukD%(|6|kGV*7e@avhggU~bS81#7fX3N^c%ktH$Of6{D1hXVg5h6XZZPl_4zRWKimZTSB;!y^`B0zQ&NeUVj0!xH%mtbdTF{r5fqnKbJN=DrV$e+AgdQD} z{=sqzih0cQZ`00V0bufvgk)aH>Iu_ZbLt7XC9Lb z+Gs>vJM$E1eqWG%&TrG48=OruW)nndm5t}n%{j~Nxo7>?*r?re9>q`l=P|)&1drmL zS*s)XnBc8qC*6nkp^(dkYbSlcio+;6?74PQ#*49&HW80)R3VoOcWur^m%->NPqOrY%Zkp_*rr)ji z+Mi@6-Mn_v@BDVyPJzZ#WvA0#c3$nI|MNc!^WVcxIu!i>kN+mje-At9Q1JgR4}|&e zVJBTr{-e(@Iq~n_Qnlx2<*e*AaO?2{MDzEX7l!#m`|g`R%BZ&8je9RbpfX~z!};w< zl-FC(A#M*8Ak~X}bYs?@ebmDPpI?VDW*OLLlL2cTpq}A^QI8_+XuI9SpqXB66}_Gh z=T!-qUTqt_(jP3PE}lt);8Dz>a6G!zNsf?ZqIi&h*)(RtRjWieiiEvt=qY=;WDT)4KZ)37O> zKo}p-@o*GB3~wb{Rvi<5j4kV4M=;R$AhvB;hY+uYn;c``g&&{mvt{iCe@h5c(EMCm z)}2Vappk$z-u?pz>?2rvp2s?QU^3d4byVIp*|L%?YqhqlAMWnMmNkKf&2RL0Y+2bN z+Wd*M=I`bKo(G$3S)13Eb;S!|TLgMhl`Ttqna7qTy=(*4{9X1^nExKOto7tS+E($W z7l&;XDE}2(#VWbwo^;DrF+C1C1S$hKB1tE@ibv`ElunU!U9fy|2xc2`ehQm`3w(YZ zLg_Mazq)!h09(Zu0?*${y8cyo#~dAoWldd}`bit~GeX}8yaWMWb$K48jb7ZLsoPWE z&~TpD(gJ-uF!Q?&Slbfm4}xw=+ai4z=r(ALPu*VYp5bO+oYW=h`w`v(&AK6NLqBU& zJ|P(_AuH^#p&wn7~#sdEPWmOj>f>_M(XQZMK8Yx z^{bG}g{zl8ZN*^}ol{)Bobh7x@)qK;jVa`E;p*i}yRz&E!g}fD4JgntdikS{F;m}z z*kUI;ig+h*lhNOSAKSlAFW&|Jo33CnuQ53+6_NDvq?fN+FHh%cN^k9duUuMVV(ZN#BP(_UDcbUP81kFX>Df#e zjnBP_?;%(Hqno`nUssT`!*1a6M_I0FyY0CHwi{7X;25NV>pU;=N8l)YfjdxZ%#D75kY%|_91k<(k zSwm1VI@HQ`h?-@G*uC*~2;CF2RqPQzLOmexdQV~@BO@ododAhy`a4k6wWZgQN&wky*QeD;Vp zBJB~EqEHsB2kUcTkC?O%r0r#on4TS%=)LU`51?-lSf*K)zT0X(&`m#fz{3XFtqVNz zWVF1#+0Uar+Z^mV0h}3>VJ*3y38c8Iyj^0w_4&=7|B8Np>Xg`<(sw>ib+@8Zr;1YQ zluyUrQN(-h71yruShoEB?mR-&TE>S9_J;lJcwV3D1f-V*HRSF$SquLoQ(^x5Unj6; z{-f;?tW?O%oY!#IE5%kRrqh55stp!3e( zum7K6{%|(ZdFSu_3t|3n_R)Fg?_W2<{NZe)^Uhz@_=2;G`sVK%3{JK^(PxL!QC@Y7 zWKT@?M4vs>wg-x;s7=RU>i)XcrC0iX?1?eYrx7A#kF?Y8>*Bm1$p2Dg`h$V=br>FE zp1%}G-;PXQ*UoC?L;jm6*qG-xZR3UH!Sp%o7@_o7##9NuI`2x5&Q4nM*-5M$T~}t? zb3eg?mbT0APl437OqzSXv~7}p6tuQA(vN}GwnO>}(ApMA+tAOtwcnHs8t8eo+#UtCoG#XHU^F1JvMS}o7$9nowIZXotk`& zqM(VliVgZj%PyPawFs^a`bSnAhU<{&+MpRP#svfs@;jSkmAA+Tt6t&cW%wSp62O|DyC!ZFll+1w9&FJ1 z@o01KQZF0y)PbqF;)JH&Ht54-0+4LbX-(X!*TfwetPR@iqPZd2pwnKpVoWms+j&jg z?ywCPWz(k(T6)&f3A|52E~SR3?u^7r4pGt6JC4SGHK`<;Ii<}cO;?c?u1LgTea){v|-Uc&<6dC&^H1vL0|rm(8IP@lr}xv#z&i;ZR4X&&$jW=rl)l~2%Ftwd>&v4 zosKrUr*Qpk7!%k>{WiPF!e)2C*w+TP*A&*eiAm-;F=hUz&Hqf7wp>O_Bc)-bVUQMJ&y5W>~VF(W7|~7<$|^&vQroO2#jD)%RP>H zY`-v-m(GrAL#T+c$Nkt5KJ-0^F`RVZ4aEBvZt}I6FQ4nP$GwcRqn_`i3fto@g>7uX z6A$*dSuwCh+2bZBC!+0f^Z^i(Jucbf#2&Z!w)&e*(5%^tuG{kE&my*WAmksa6U zxH?<>n~PUrkJ}erzFliUH~X5*_2xgV`Ly@A4#ghS``&iW?Jw3IW+STZxO&Gm*?m`h z<0Ah#&t*&7MP}kzu>cj_)4y`vgwf4n>)gfoUL>>sb#8N}yiOFIe%JeKqTlO0vHOD0 zZ;A}>(`Ojo?h#%`B}geho#oZrmYD*>mG(Sk+- z)_D7Cwej-$g<`craliQ2^L-|#=Aw0{R??ktJ_xEIUbeStD9b#)sLj5gF6mAKJoh%~ zPPT3{vK`Lv84BI0Gf0)!g7meY63Yd^E1=qRzL{I`v(sQ-xeET;1+YD-NURxbNzAj2ENZH4u;ON+FjE zSGRi|IuUIMy>z=)q;B`!NZsx=#B1UusoPzF-za`Q-R=+~{3gN_v|L=>j%TkdXe3~b z2ikWAN7&#;MdFXt~naC(Ji2RT?@JmT6M$gK{rvMs{8F{xJ6S& ztE0d)oPIv7d+KuZ^HB&@-S9S$4U49quLb&cV8*APFPE|>O+TO31!)`l(GAtlS4URr z=eq|oJy;0nhBJfPD_v3xJ-c*WZt>cTC%|?54xug;a=CDI z!jo1UM$!CSosjWjbix+mu{|l|a^dQPW6-5ybV4ePG5)?Qsa#s1??G&_lkG*kCT{l9 z2~Q$IjKA-xuuiB-UesF2sp-k+?`(csjC4sSOgdp&E7@SL-!sU)!^z*5{C)Euv2^C7 z6S9wWz_VT=T4#Ox@2o~=9k~Gljjrk_o?oG}DuZj`51%1k#ah@Mr#G6vOaFW|{9W+c zM)UW#{$Mry?b^E<{@#fSw$~ERYK1#kWxr&T*q$~C>Oc+XAt9Ru^;-q|TJISh3QqBu z^o}daWWn@Hk?HA=a)If&&N1|SM`d%9XD}I5!zMT%FJyBW$D6gG(5a1ucF8&lOzB%d zFM+-tm^PC40n?zNHkUgF-v^<-)c1(EeeA&Xumchw)j0BA}0@mlNw>$x{pxm^=~>$nC$`Sa}Uz9VvP{vE$?=Y_HMl%3h` zuJN7gjLa0h8;sa`|6GT$;zH-(r0;J}eV_6kb+Uitv z>GQpYfol-7?gpVB-!JvtM5Ca7{29JK+D2GEo*Uen2A=lrS;jC|R)yzu!Mo9gu`y>1 zd~U>gch!Zriq3l$b*qreg{$+9aR9JD=ZhO~kJqX%GG3I73!KNmC-u*QSV ztDBUgbl$Ya0qaVy&JMlnS9aX`gUe8igI$+x)sS~xY1-4A*1dPyNLu5N);Od!4my*S zcW$gjCr@h}yz@`=8j-Zd;r>THGn0?kZXBQH8gd_K%S|?q?P>F%VT^inXpI2%N(K8` z?-|1y^q83RmRnJi8^fIXx#`by!G0$FZ7%Tn>KFH=x70c}siA#ox+11E4xKd*A40*j zP$9Pi)5dZ)aE=0G-ILz@Ya9-opEV8#%7&c-X^jI~RW;Do!TC%3c;VMxNuzVyRT9sP zRk*I>m)1BGWoMb6vW;8gFi~608Fmv>@oOB;h>fmj3;VKN8H`gFc;xYV`{6vp>IUPXgi}&%XIbIil!3{vvi+n_Zhe_V#bQHP(l_>hqy#qqcmzGrA6}c$1ZX zof9^zzQggljX%m_J}~ky{zCG&&XvBjytkF*;gF9~RVT z3+gc5HMKM2aXv$Lk26|#`IfcE8Ge>AJhLA^;8yYHy{5t*$|1*(a21 zjt#CqkMW}Xd5FilSIFhU_2=b~QR)cm<_pnmj;91ipXy&;i=s06|em}D3DBgqVwu%gT11mxx7wpQQ4_a{;MaLgk24%b$8MKLb zY!3>#T(~mmX>{Z}5Y|furExVz2EEczER_XfTL#^Wc;mQ98IQu;*on2uu;oJrW+svhi}Jq8w1E}-XdU!XR)jz< z*p*>VTX7gg#}`+IWxN;}wvBjf4+^-!GWPD@ zS&fXn@n-{Ge&K5P+xW8q|Ms7+hQEzJ8}O}vup0hWcQ&B&y@DBjbJ+(fo+KU0zh;Cw zRughuNXN28M*CXJn(1@+t7FoOIZl%r%=E3u^t3;^!1N8sd7_3_8);(e19s^%%@t^3o>lQIcF`s3@X9aH+|H>OyC(Kc11Xnk` z1v;1wI&QnVDdWZHrd;#FcBGKYg{zx>4aT?!5Z24TvV;gR{*|vYBMbCBh%I)q(})-I z9r7E%->-Y}bNwrOp(ieQ;=#XiKn|XZ+Ot1#U?N&KJudH>bkn4pCf&5b-j{UKA<|9H z_c>Q4^c?6qWK5Oy`5o)FMb9(6l=UEF`41pJ!V-9-EN{L&h62YU0AE+f4hovwaRCWnyU8LucP;wKKRX5>@!`=x^_l#Zn9;AX;Vw(KW!sx zl@UU7sA9wE6kyMcg|@!-$>qd5OdtM%n#7Qk8>R7*dxfFUCwW>nl9!z zV}hE_V2vuD9yv2zp1!7w>5KV}V5}J^xG!n4J!(24Anmu8Y6Y+cg&x(+~iRPlT=ReD+N*u)Sw#T#UoI}q` z-7}ljsNBo)o}dRK&Q!PtbNz!qeC@)EE;)f_8gqu`xMPpYgPilsae`u(<1Tu=&rsa_ z`J;Yz6jm3p2S)E%e8-Us{AUgnCk(7@=Ur=URScMb>EzdZaOiaayr(4T(iEmh^;H@DQ6Y&n;EtwNx4&{}2PF9aSySvSW+ zmVte;F6Y}e!k?)~&v~6T7GHYiPsOk*yipNe3`NDm*(h9K{w@54__x!`RNIvW(>D<* zCjIWNlm)@`b-Xys*Z2NgL090rsji@Hh4i(!uWf_$^`NyakTy056cFp4G~2n>HEH_V zweCp2546?=Y1%ThY)RYDk1w5k7(iCkO%_0W880hIVShnP8ohi@L9oQ=%c*9D0o@$R?&Z6wK`XhcP6;{&mO0B4I=t zkGd+a*{2D0=4Um#oHqfk{<9AQ%RRW?OaI|nk1_hsy@+Rn@<(j3lhMX@5H~rl;qwWm z9s6u?&x5hgS{Z77uKv?RMhl*J(0^uDvmbG4YBJgucUU%JC;i8f&%>I9RYTsjrqS}* z$)|Vv^@k0VFFpRqr2kkoob(?I$*z8Te%t4XNd5f8H;=F4yI*%Z{lB+2lk{&D9{_XX28kdV4v zNI!2$xG#UE&mreCy)S$e_Z58MhCiggT_ZV|`L_|yBNsyH>lYT`PEtcM{Sv~Ne<(d2 z|5eX#NVqROSgQnInyv&xv=`tiFqWgkEd$eDK>e@{`Wc~b1YSagv91|z_Q#-rmF5|k z4U7J1(AqW`|2EJ~G>AWz^dDq=6p*IBi}5Y`XF+S*VtTIkX`;YcSETO;Zi8mqApHqo zZ40D71zPK#v{_FfbxHbBglpZBwxJ*U$YYX08(Gml@)T&E7sEc_w~x#g_K{*~QjN~r z+JyPH7bO{|F1`uKP_vS$HfOF)s)=!4Pnfh5ChdetJ7N666DIA1NjouHb^`luS$<&* z%46VtE%uaov>)59a!lxD!Dj{QHwDK~cIJ747X=>^yjAQm&!b%^xb_&vyF|i>G@fgZp@D^MQz4fN+74)YsSAAsnLRD{IDWDHl9fB~W8TIt3Eaj$ zf*59f7c2gCR#UJu}DKhgHu!@sx+ zdzg+7??icW{B>+yrfqX&bugdZFfyw^X&CmGwev;dVgd*EQ(pw!MH^ zz;zU$@^dff3X&d^nKmX^FK?7w%`|}H+UqV|28L&UkS^Hy+Q8{Ll z?BMLtv|O9VLh39n_nY(FvTW0P*UvV625p!&XthndHfgm*FQdvB?~LG4TpQc9;A4W% z2tF%#tJtt#M%z-z<>ESE4F4Hk)xa)pEV2MaYrwT(GhU1hJ4ZaWZ-rbgTpRW=Ea+cs13Ub19OZG`%5%LTcGbjZ1>!gh?nCA$Nn5YK9@)p$)h!MF&L?zn50*VSdv+RY4qb^7k6}*Ci zx+@E!f)YGHMICh`m>A;~VEy@-A-Cb~VZ+_s4 zY~`}v>$sU`;OT^{aL9|BDHjGe*FcVSOvqLjUfi4jzFq>qT)3G4Hw*N-M*k4LBph z&H3&^pp{Ux7BAY1gw-K)txi63vpO4>8*opAn^$Ih!ks#IryJttF#8g6uc9d@znTYb z?yc;WZqc-2;ts;SnI)ddt?YogTOM3pQKB9peRzbc&A68ORCmDDLHkM;X;m!)lTy}5h{XeNgOSNZ3OH+F=$;KM%XB(%DQ&q&$sc&uLHnmQDx|SyWl3h>@ z8m&gSCjCo&{(6v%Yg3pEfla8hVG5hm?sKjwb*f=-ZPYTpEBW2wroc0A$d7?5c|l&M zw&+A|o9RUE=tKwMl5^PD514hLn5z?IS)}e$WMY2ZCZ_8)=zNNq1U$D|xpm5|S8k(n zyNfQ;inZpo=K+ z+`7p8NEeCh{{+Oy1+^DgcwOY~ymS#`x3)RzBKrIb`9>pMWDmPyOl(Zdj+ewLO3F(e zeVNa%6K_fHG0hZI`= z^UtWZTLwKO^!aDMd$hoOW<;TtIjZUIVVkilfY;99%oWtWQMr_FbyMpZLE~J6YV2Ft zH=7ha^?A$d_*_$%453YE^9ZYF$hgpGBwX^MBlL{4Dy8&{0}=l#$ZJ+yv(2M4>o|~4 z&G4^etSH^W?H%hhpl>6eNnU%$5LSAPjbOHLZ3Zw zooYa%v6pC_pt5&_Iopo&nP&ZaOdfhh_*1R4FMxVTv<^_(pJ*>Tw`z2yz1g8Bs}5rI zYOxoN->^RErWCye_8wckTAL3`kAlmr18&B)5f8djxZxD>>eYosiKJy!CM;`+O+VSI zjMru|=;@*NYI^C?BD0?E>gBC_HMx&ApY-VZW$5r3DfQ1+tP44|TX*K)@|Z6fzJ1|1 zaJq*#o%QJ+cT zN1LIE7~V$hY=mpVBn+Q|f41;R2ptv>p7E!0_)`xI3a`I^Q2H7Welnh8B0itBflxar ze2wxC3f}~O#vhcwHX^3Y)kK(Xla-jh283t+2Bj|nF!|$vSQwsj@U~K=K1gHqSXb1ksc9rF8um%2iJ5?HAlH_)c;B8g*3oKpVto~$6QEf*ZMZ@FXRK*5a$)d#6XY7SYHO?b_+4=>LPGI(qtQ#^I_LZZG^k z%bqJ4TA%*+cAbLPTh}I`C?dS>+4~52l0kkv6sU)COG|}{>lRt=LbI1Fu z(r=V`!S}bIhi9{Q)F^+C+U!IGQ$bcT<#|ScE<7$h5(!N~NoU<9z9!C*x=Nl+kK6HG@C4JWOXLrRTch#Qz&C+sSyR2zgi?SE8)x{{d`kIChG#QEr=JnbPD5s#R6O+jC zo8qI}S4iUX+6?Xuwi%S?v%azvdj~s{4(;4?3G39mMmB?Jj9-mWhSupn zUzdl?pp$g^$fl6preGMu41L~W7u}0C^jz1Ir{;k<{c~NNCcHiQ_xNXp<}qM*3_aU< zO@e%bcO=(F)!CQoc(GhM8o1Ke1Yt($r_O=wu39*`WPg{$k9w$y7~aN18sVDse}+%N zf0ZdP?lF7=gbssi3h$&3|FZelWbtR8EW}Lp660^ezijDGB9d%#d6{sA_oxldqq;L@ z8i6;IvL)u=njtAm@-gOsDjV_@V5O|c?+ae?p8SE}C9lbU1H9xdd7avVX?UItsR{Lw znC2v0H=^uVN6cfMVzzC$csNH7Ycvi<7HhDvektbf2@JRKLdU_ z@dt2EDEtwCqnH%^D_94)X}HOD2ix^Jb;yK2_CmtWgTIixk{5q4qFNDxD{>gKtjuRk zb!mA;=sCtqfsIHJ{)q5Lgg@MGLI1z`;~O+1oAG(h?a}|YziO+%IkY*>o6SrA*XxV- z+K~RxbAbQ&r=Ef7$8%ce0JkT#{xP`--*IG9!*>Ia**dS7dJeOzpcCPNWvv%R>Ka$#_34dhsdglu);#ie&|YdPb@xo~L%1j69b zUoj$$Vsdw+6$JAS0{&b@VJgY*R?x-+*A^B?PN*O z{h`Ojv&`*Ag}U@yEsTE2@KA9B zaZ`j_^2aUAYr!p&w;h2?hX zW;x##+ys7Ic}%Pk7@(_E}|7%Fld zei7yfT*EVcNd##W%g9_`o)Io{;8sVC-p&q_H zV`AB`CC6og#?&HgnLoB$vm_?E|za4DybNRfZfBqg*s5#&4k& z`!heYjER-yv%gGfMM>!MZ*GX@YDW9cbD=VFL5+z;`^#jU%)-3U_VX;@{JJ(xAtB zndf5q?PmG!(CTKDDStQWTuejxwyAz{&WSeeS6QOoPjr?|jSHjwQOvk8s9dCaQpdD` zO>Tf|!kuUVtR{E_&84KuIUGNd3D+`w0=nyDN5cP);fJZ)7?$#pruO>$c*B(D48bnE zKgtLsG=&dH_D2~FK8Xy|=VGQbp7W*>C@}FK5556B^OlWZ0xm%w)d}*vU!(C;!8d^y z`6IyF$Uv4orOMffpY zQ}AONq<>37Aj~|@8yS&C@*Z@x$u=~oE7=( zZxXKze}>5v^{&x8&S)OzmWf&MRXQJJ8Z!;{oZ zWVpzAegQt%Vx*%jx_A-ZN7u!>i;lgP1*6DTu2;wYK$D?}v~OM=n{r`vY&IIKA40ae z@aovtL7|=oKdOt_bnGVR>|u25*C3~pB!Mp5ETMIfOW-EkrUCfz^-VhV5Tx&H2?ST- z^Xk|wkgGMwVZLHjK6`k?%44DT@K~tItTS}%_MD@X&IZ5T_}~z0B{*O4;J4oIVcx?l zkJax69VzrVQj1^9;~c3vOItN=fyvYv*j}4R>QZ}kh@>fU++!ck3QHZt)Q5XM6-sB2 zDNKey7qFWpks$VIHWQ}awIlkt5sVMigdh7j_OVM4KR-F+{D{i9e}06|Y83Z(Uvanl zV!Q=tLyGC5;Hs5dr`+z+7cE5|3fbzy+ZR2o$xuXCZ(l^YFnv)9a!u-4bZm9)?TbD@ zzSA#PU(|q(BuroQE4{-(yhw&abak(X!K84HeGyDGfql^mq>p{2ki_Thi+ZCn)rt^Y zksBMUkj^F4-1)B37cJPMz&v+7#F>8SY-mScbnkj+?!14*ZzJ_Z^B>RS{d4q1oqcwD zGM(X>7g1m2=0{t`MDp*83}>tR`Xc{<>Xqt1bu=GQU!$vVM(ARO{C7*I$l?sKkvdikZbCP#fu7vs@{`_4P ziR-inH+5uR<(6MY(i}$gnfBtQYy43=ci30icu04|O+)Z*N&NWk#7V>8%DZ+1ZrUC3 zk(%%$ZrTU#4aiG=l4jhb&Nr=ySv=9ynJ8Z2pD12wx}}f7Zvoh8g;adxrHvoSi=EbK zGV~YLi=8MJ20Ia`G%+GYwsO7LsUHfMez~wy6XFYlonC{SPVydfb+2_`Qn;53J3Wk# z`baH8iO-9jO7I@F2037-@_goZ$I8crK0ov-ejK3g*k66^DW|kH_PXQHcD|16ugctF z^!=B*7WG$>6K)n2W_-!CR~A}>RPM3wWq-uBB8i{$S2nI~L?ixS)6`MeDtmvW&fC(@ zVPbM>RW=HuPgUew2#>+hpyaLg|YMPh4-jU*Z$VN9(`41Uh}$Q;pcV9 zd_BFdg6fr~_F#uijjf_RGK{Csrpwm3@Y_+32r;HN9AkP%{Nl8LbF1<}su?F+XC{rD zq5g&6gJfJ`uRd3y+wty^!j&C$__YUNYa@jEe4=vCE3k(whOXM#xsY5k~HrTmwEJtd5doqEcwt)ASP z@%im%o|4UmFMTnZDIaZ#dWvg9*%W$8*7Fp6))T|L-^_Co zP@u&q(MV6pTqhUlDV?UL#Pd1tARdc{-rHrqYKU}uir!cm`iaoC?Z}?eBir5%r*Dya zj?%Cg2e`DoYoBnx4!@^hdZ5Bj6NKwJOyEDip4FzkBZzTyyNI-9f)zHkJ!Dlt1`szj z;NRo`e`=D$lppbwmo_IoB-1_;JT}vam*m*Z2)HQ}AoGqq?IV&`9WmFyIfn{y+IWW8 zOWs3Su-cmKC0X`Q_isd3>E9#0GINh~6lgKu4S2p z9wPf4%QqP5AzH(vUv9*4o6TPj$+DNOK@TzAl10x>*AwX>PECyT5M;x~(L*ZonF|>& zFAY6+f1a9564^tdeS@~leS^4nZN^@u*f&V;XnC#e8`Q=2x>fc{q;b_MRet6D3)Ux@ zY6mr8-ma);kRi*aA46)Bn8RrPa{4;{^5qZbssxtPv#79?*=ZCR*H7mImT7_Ph6 z!no!|$W|9#9dw!|LlJ48ytXjPg|UUvcE$Q2WUC9WE$m@@$W!2#YwnPR4?4`;pu3(`Di9ZG42^6Jw?{To15 zr8j`&GYca96uE#h$FGZf){ z{dAv@`ssv_`ssY6?^JmSxbjL~{nQTBPpe}2?E45CY3O|)=STW!q@Nzc%9-91|HvAE7|BUSsf z#!4IusI%)(Ebd%8Dk%=BbuFX(U*TN)=K)svH*&2~8@b~7_(CH+6nQ{O;MbMyq)j39 z&`oJ4{T4G)k+j`jJ+xP_9x94uxH*H7oitiw+4eP-ksi8v>!DLZj@3_j=^~6?p9+=0 ztB1D3PU_v8SlYTsPtC5UMs`wn|9=}5M)cIp-%hIbaBicW)W5rPmD=4o(ofm0a2f(B zfnQ`Nb!`HGZE4zwcG9wZ_JNL<$3yR{Sr^$!BRgqiCv|2ssJWP1%v{o|U&la?Nk471 zlV+Vu%JHg5|4erWu&nus{e{@_{J!oPjw6*vG)|vsC(SiZPrIq)ZAaKi6RI4zqL%!Jkn@Qb(_~zNA}Sz#6J4R3o!G3e#hEJz2^%^TNl|!Bl~Du*Tl;>{^mE2 z)Nl?1hV0ee$2sSb`cG)6QYSP-_EEMgk$p5%pJbkF68mVpq$FDBl%D4pW)I(J{5~4L z$Jc7u-_ZS})Bj6LyWLv*(Bt{PtFCzW4HAAx5Powes?l^v*^=yuu z`l(@Me&$&nk^R*9xDxmujo)v=@%wm*Y%&>cerbh>=U#{39F5;c?-&vq z8`b=S@AOaaI}S9By`UN!eS1Oi43_Wo`l`2R@CB~qZMUsYI!!)txU-8CHaD3C9kX@E zsKV_M?#@{dG3*nOv4_-F)?h&hvP(Q-ufs3B13K-h`Z|8o87NFqWPiE;xAwwf7UZya_YDKGhV7P&v=RSTjz^O;J>~`-*)c$ z&wX!XL1`q|+q;gRa$(l-H$jebMTBg1;a$f+7&_V%_~qJXss_`s!t673KIC+gB+%9E zuS+2pW}m6GXk@~yj?5~mi69+%{q5=^0Tr^|z($?Be)^oes**hGgHW8sk5}g9~ zJ~G)?>7UBspMX$Mc)d$C#n1kTb2OiVYobWMZQUoJt@8_*x1FWm&O-sSjLrL0WjQOz z*%l!CK2?T212WGJiu7COlS$zJeC?@2wXC^mjkR?zf4^n6CxHEqL3{ek`AclW zyd-^qUz2tvssEAA!EaaRD)S%pwOWJesw(45sYpL{K9&Uj4`v}KvXwguE=-2$d9pJ! z8Hz~T$7n5wi3@hzu*gY04h%{>}=QD zLZ79P>i_id*Nt-aHmj11JC55M^MAE8>6cPH+S>nlOznEq&b6t}%MjXxXa4EwXv^6u zG8U0UMBF!U4BRF7G4K8MfN>|H6voWvZh)SNS&mQUktxotjJ6aRU5t3U)7d9W@jgPf zy70D%4~u|urM`OGM9PI}6H|~&;wNOQ3vZiPkMCN}9AO=1nX;{(f*;esbD~H!V5A<9 zryqaQl?%tA^LbMvVd<(S#PMB<8%?<4T6g~VTuF!MqPS&EK%mLIP$cnrG5d9ps}&)* zA~!Z3i{-N>pgXpS-o3&kn-$D|%!?lTOk1Ee#J{v&K z{!`Aas7s&HnB9H{r0`^W z6>Be8Ha^=*i_mA+?`ZXtd4e!@U{%L{6Vs{nT^Q`KUG7{_G*=n6TYXKme8X+EP0-eq z#BVizCZdfgfrm80HQ8>NwrpeylOewe?Y**|g741pHXE+IYe$T~jZiPz1edlC&Vg(} zUhgy{ zx38mI7&~zSa!p!%wz~G(iKn6v=$C8l0tflR*ok-1jl76g-h;0GibEim!adrEd*g>> z812MgLT(!Tgd{$%otX3IYDEaH$c>F-^B8AUuKUk_?cOOL=UPs>d0)3EWM8-F_wzfY zuN!O)C^~D-nP+W1XG!gXh4beW&OT#-R%)4-n`2+6uaA^E*xtTwO=h;FIeuyhJfsn> zso&}jeI4JuYxH%7wSK<7&M*j|R`jubi~2fb0x0V1I<2pZ=QAc6uc`=r-fj~W1W<(Q zwp?82)_{Qj&I}>?rPqNi388CnpMxa}FW$OWpR3T!cPy?}r@vxeZ3uk5xv#_P{Pd$} z9ffA~YPF9=<@gP0JBeerSiL%9ogd^cvkth~N^bk0)ETVf1Fc?NSd>UwR%ODnhS<2_ zStrRmUNY!{v--C_U)gCgo)5JFcAMeWtd}k=I^yc|JZ#Nw)60P*h1Txsn|2?n?TX>v z(AI5ctZMBGZ+(uMtQqvCoqR4`kotiT{yAd!`ZQBLQW@10$shvb5VK%H`yi+z>isEn(w#*cFu+H6O#D6cC1-=fm#uQD{`=7 zDGOCNJ660(#B-0?G;DslePqXSbr=6ivQ}+|Q|70kIZf~JBkMQqq ztdTtCgG7zo@$x z(}faQtz33^cXqLe*oP$jP7oS)ZO<9 zsk=`Isk<)?sk=`I*4@kVnS)wdF30iZ*4>lJ@DbVNBfGqOXBnYMXL)hoj^+jb;n%{4tviocCOE`%~ zp10hZ@%0oKxi4}(oZi4YztNNaSbtyoz44q~VwG93VL#sbKkTO6r}lK!b;IlFxQugGj zqf1$nXPs$KWk-G%!>h6&uTxvbg-%itBoP&{<=NoZAbx%m#&MxoiMu~V#vh( zl`LRC)+-@fU3jtST5N~25PrGFm68w$Ge7!9HP#}}mGsfol4GraToN}qt~3Zg)_Jyt z3@&+sOKS+y_dQ-HlK8yiN<+{P*NPBak;AxBWjE9rX5#Gh8$N)E}WLf zxKfG7Hed^$a6brbL`>$4iJNuqSa-mVcy}E;4j$j3XVasZ>5&nC=(TD)F4-#EoUINU z_oRNR;|}UfLefUIcmDoriO}P+9Z%pPjc`r6tJ5Fg-~FC&!ZLgl{HfoW!qeZzzij@= zEdK0sg!YyT&1L*4{A2prPkG7HWqZAiY0ePp0^>3)J62*Fu9Ow|5lpBm8}e-(mto#9 zyiRS=mF4WBB(y_c(qt%tEO5xH-%>7&ew%_E z>w=K2F1-3}_dmO+H0EFPr_Z6vT>sb2_1kFP)TY&MFA1sNUUJ7DH;R6nb^cVO-)`6- zO{lg8K$=v`uqL6)>$m!zk@9Zs)o(d>#YEH(6L?4?T$6t4Xg&D%peZo!F?ePo;8)O1}q~E&wx{l&D-r1a`rTMJ+EyXGqSNqL9w4X>WKZIsBKN zn~+{}8rg3*t$rKXZ_}02f_}K!uM1$;uiJ;aoPMiix9`%RpNC#E{Kr4_%w~UX^C}zK zZghLI+qU|W?%WWquD$yCmTG_2O=_mIuZS-iAao7f$bQ|5wfND8T@y@fM|s+xB`?YA z)E0a8Bo#puJ_1=+Fb*J+Woou(t39W~>HF?<5T6O#zdLnooU8Tox$Rk3AU5qfyia$s zZR_iOZB=Go+x8L<_?LFgYulz=7~6IOx zo!&&czii&=nDhN}Tr%gil$Odg@7#9(S?UPb$nNi%Hypf^PS$zCY;JWj=q91xyyaHOzfy+y-8IWdZw7hN z-_O71TH=@IU2HXm&L2l@)5l#-3c1(mNrN8iWgfTi&zN^xjMkA1_x;TKg*kq-OX*`5 z zO-lh9mtv%;J?jOk(eN;QopS4y+pOH~vX|4B+DC08&q$;2!*BxT0=hJzr@BxMvcMtl zm<#2?jJec6j&(@LRu|qem#ffV%!6O9F_$C~8)nSqM!u9r@*Z@x)|fL`EnhAyZk58#ng#(5$-~jQ0JNP$|Y$-hl1rb+XPYqzX*4^dE&J5%oNbZ!(HRz z{xL3hC5wAMbG$2FRvP+jyIu-oM&n)4c$ZtNJ^%gdjH2-_EsHRo={5|lXa8Xzq0F=4 zR<6{>a~QT@x%K!jZCuDW32$0f$aU7C$3u2_Y@1FS5239|9}lT?-oXD)`jqzS<*WTs zJ9iwt6%Wa!m(!+gB8G3uqL;J17ri_vJoR#p7nt;Jm=3d&DNIIy&0rrO<}LL~uinZz z=8|{xF9$DqMP8@2*!L%>2oflN+V>9!KNxy0{sQd#>g==-27R9q-+yFUOdXl#Jg)$o zX%*wSZL#5Z7u)<0X1pR>xnA4+EKPNR^EWJBFuL(S)5oO|Oww+RP+H3r~TPrjD zGSU&<+$cn^J4j^=?dWW@!tSNRyrsNXM+~xUQlIV!9Z~8W%bz;pRK%NIM+|vJmrp_T zpUV}~&*h5rL#r$6hg=7nK;7ud`e7Z?CnRmAS3hhB)(^|0^|I+XvC&>Rn|AI-WJ8n> z8E$9Kt=Jgxd(KJH=A64P+Fj4#+VJS;=g}6c<~aK~Tz!!hn$0v`qUwOOl;Tzyj`wPp+OIxxH zH%LEcSyDfzel2-VK4|U%^R^@Od1vkdpNWr#`uqvF?uAOjI%J&F9arZfh2I-T=5%{C ze0;C|TN(ReqVg2;JyD^mm0PFWdgV4Mw^_L@$_<*o-Cb<-*v8YaqvZB4n!zuWh&(O8*S_<zMKYVw{DI3t z>_bl5@MTj{onjj{t(Og)OAOl~n@xQ^+~&Ss_R0|X&w1Ndj#%6&^R}~{ZxmP#^6h!u zjiFn2?m0!Bzfb3uiVX&Ry!|S))vCG94;#c(MU%F^z1YAx^4ME>!Ly%9;33pYJl(G& z?etgpM}5Ua44;C3kZ$k9kAKj_xx3P4GV%Zg<57 ztQ+iPY`9Vv$d3RI$0>XAwB4svS(7I=NT{+SPaQzYlDuPkS9wdG*g*1{{3P&_x8!wd z%X|tFk7gKb@JvW-z%x~A-B)z} z%d3x#m&vC1q4v@lS5m2l5prXLfvO-jBWw_j3q<1r{60(=P5XM>%SiXnbw<<%YfIJr z`%m8KP_(hCna!^I`zn^Y(H`u-vCfbUO1pEv9cu^vdE(Y#=dR~7FE0@LPo#3{A%5Su zuiIX7j%!WaZ<%%cLySn~_Cv45n%;@~W!tN1zloQd-B|CNy?J^@!+NG$j=5VWkp`6wqX5J zR0K_kisOJw!9Rt%5RCQnI`i4Px07=|bj(>d5_hiS?zMl3aom48bX=Vd&9oJuq88Id zSyU^xPPz5UZB%Zva$A%eG)5?UJhiaFM!dzy6DNM<)+x8Uj3qvUau%}H#VEMCy`VQ4 zjifK~+6yQb#$I4Uj&)7QRu}xPI9``fdN}frf2HR}TiSE^7LtgF?fDqEOYmdf zo9A_;_v-Ua%JA>E7th>p4;fvIc-cmFmo}08pOCFCylo=w{5nZ}^|pzW3)3d1AeY2X z$W|BLHnASxwX{Xq+Qb?pNa_KjV*2=_t|4i~rFFi}Xnwq{w~0$}qY3xeCi2I+BIt5++GT&czHVC&VZJ@FS@W*u;|mE870 zi44yHtzKPNlt@}uWx}$C*tn6#(7ZO2!3L8ExgT+2!5#(XwS|RNZ?)Tm`%u^B+7k-Q zj@EA09_+xWGw6LzXYG5Xf9Iwg;CGV5kKc!?inwYees3xKPH(-HamDa8$o+HRn)cm7 zQ=FAd&&&wW1=hziZ-{Az!cF1Fydcl^SKhrNFwfqI&mrU|`^W^CS8&aC&D=+-eU-*p z#4{z%e|MK!|A8NI1C&v_B{BX2D73|NQJ{6otygZNa=S}kx(<0NWUC8rUpj;pUn2?P z?Mo@Ae`6w7iLktuekj5C#1oe`ek5;S+E_%*I5)mXAmT86=}bw0^R(6^Fe&;g&Vt-W zxW|5!`Yn=S>`SM@V+Q<$yNM!#=fixFH?sf!DWcPEWbTAd#JuUY5nay#-E#LFJBpWwt>W__0 zXxY}ROBi$q=BAPS`BxosE@t&^S8r{8zJH&Dz_C--56^gnUVeUE5%pugiOZ~8KIGeE z=KFpVv(=B_@s#~0rsGl1TW+nGmNLYj?|6#2e(X2V9Zxy-TRR+$HcmBjZ5|Iq3@<+N z>IW4U`p1i2dgRp&>*1q)U(7b_HFf5_w)TD^hxhAWy7*`|%tB86$cSG%+e5;6^Dk*# z_XZ;<=uud-RnM)dxCW4`%V)%|>GBf4H~p7c?|hihVk}TO0A0RGyPd8d`n}9+!}C%9 z1giu+f4SA;9vcyP<-+ElH=OWNUy|1F*O<=S`KQWDACEL(Es0;==VEJ^Cw>;WV2g^q zOG@$`ucN*@kV*Cs^@SSzg0KK}1|gGP&+sYy7{7_AswD6QaXcs}e1q~23Qwhm@teY% z#<=u&`1~4#pBoU~Nk9Ibrw7umX?w^zqE&F`#yZ%s(t(b$FpgkS4m;tsHaHfma3o#% zDqdsN9RE9E(}QNb)uZPI?OlwPI106ESJMavPP~tlSpm7PIq( zT(xrRmD{M?X61Gl4Eq7fR>)QtUJSd})*|7$$O4DF7?yHcWd* zTeiiw0KZ&gWHk^7gJI8SL>fu@=xWKaxIV54H;G|)#;*uJw#f{Rs*$D%NZ)N~uJwJr z7`7UCveqC63|p1Ydb@ZmJcga8$~7y7buu77dufC*RYCeOl8#XnHudVjTOP)wDMi;I zISfE@svcb0h)l$9P6*wfkK}u0e`umG;gbkB*%TP}_?@TlW4{~p`~+Tt{w8Ah2KY06 zQ}{4CBpao<0pZo>ZF;nG&-Ba;;Z2~UiB7||I*A|ihB}Z9H-(?*I3sW^c}xG%;3Y4~ zj|C6M$s6)IwMFM~+eoAdZq*3_MM8MZ1t<_}6BMThz z>L8R0qk}X-j^!<6s|&9V@(eyC>M!j3`Arq!$8=4>kHJguBPHMwMhBV62sDx;(A8g& z``Y%yP3jwqyv}MXD+_&QKoJ{%P^5!Y zALF;fiCsstV?}oE$j+UfcW!pFjZ#4>nD0!Ek3tXw*kyxJ$qA%@}T6P7DX@vtyc8 zGopgb+J5u3XK4rFpXa!5=av|&nZ^Pf$XrYpWl*QwdgV4Mw^_MG>^LDOIIvFf^~!Bj zZg;_lSD+k)Y<1zqhtFs-6hRg^-zagt@CIE-=^c2bQWC}WB3~W>(u-<&-0Nnn;`rZ&68rmkj(ifrogKbASU)7pmy;Yaq_LQsu;B>nxCjxXo=a>l&@71$XdXfJ-e0nr5Ie+>$W@tcU{ z(**y?CQsbc%a?kZml)p0gM-SK{tfWY_IwL^YS8nUKQ+qV^nUQlN~SOw0lLu`qTplJ zwS4d~>yF@KsVn4(kEL#qCq9<4CQp1UWlMfGcqvQr#K%&0c6s+pOFchxiEOz+8XvBts2`ZJ|CXOnBj8x<;2qv z2!*E^kw)?!bhYGIUqUVvo(4|-u^~P$p8f;gqt+k?JYAm88sJjkZwGkWxz{bFR40=a zPiL+xG0Y3s@C4Jp5!T>FbIMdjiRP5~&sWW3-I5uPM0n1vU6K!~t{EJ2{%v`9j%RG> zc&=RKmGm7!c+SBike!U*Kov%J*x%IP7o_j&c)_H5Gkgj^#&04%KY>JM!$S?qKPWsq zMaFM>ewaCnH3&a9AiR@){L6-C5_pNA_tWzy2v0R2d{F-K`8FcS_WUILgPza)O(}m< z{`7=@HZq0DklzG&itkE%L0zf_Kjs~I8*U0e@gIrngsMCArykg#@nP4^Fz*?@n(?W! zCVw#FQ)Nef8h9xy@(d?sL!Rqqq%6qm)E0bnl8T@PQ4t@V4L*2Jc)}C4uaGnS(_PKt zZk!M_OsK7Xi3<$k`WD$H&NpM!vptdXOo2oes-aadpmofU`Pm+96oiS2kRRO%`|PEC zgf{YwhcGxkFy;L%A^6CkZ*$Dr2Qbag%N8ApBUjOk;^$7xO*%2}yij?6VXR)rt^YkpuRTP2t0hCB{k>RLYHgW-;-g ztk}m%NVML?$*5?q=|&w(H0#!)lLwELL~HV$+8T{DsXY_C*rdYEo^%@SMdf}YR(Nh*I+{`723it)-6CPQ!&U=zV2 z)OC{h@!hHG+i+9(F|WvvfGc%}{Aln}SICbA4=24|j5T|To~M8LymPw$W|9#+;J83dX9VM!W~KAgfO_{M#$+T??G2fjjaOMBqlpxFUf>1ihc0KdP(Ccmu}Yfbc>2OMe@YWP85o&KVIahWV31_@Mmh zX$qv>Gv%q~-KF;`8-avM-6GD|6TH+V@-e;$GMITop05#@RQfmRsC0*1_#H&!EpCasx^8RfOB+3ud4wOoSyBSOy|fR|22UD=pN@Mt zj-r#q=fypg3xj)-kYk+^vegCCO^lOJd@nR;U46Xe3YAtmk}qD|vjp!^Ymfu(iRZPq zM``%|#Rg*@9LcQJ4DN?&^v{`tu)duZ2TmbP~O zhN|v9C&ER{k_Z>I7Z(jgF6wj9oOS!mS!ORN2p8#kyQh0~!b$fSq_>9&pF~X5Jx%23 z?eNHkixPN=AY8!k4e)3Dru2uwMfm;$aS`KBX7P9O2SP#Vqkj$jgWg}yzaZSygz!Q6 z&-fFFB-`^F;2-pSz8^C#DF1rWKMR@iJVU%2jt9-f3$oJ)+8cv;N&iW3rR>OaJV?rl z{B-bAHsqc0990(Nb!rQ4;@Tln5>XL1QHPy^_*v)7Yk8{Lww5Q1C zXN;&G?Eu4j*XzjKv|{8#cbcO%Rr~mCV2nXb@e=r8?&7c)^V3}$M89P5*ituDNn zsX8QPvH|eIj1}!eAgGbN2VE^W)&$5Uag%N7ApBU@O=Cq51K=%(pOD1o#Z31GW2Q3y z9vAKk9QVHaKfT{Ygqfmqe=^3lHtVq*c25yz$|%q1+!|?1-I|ecE{`_WBXbyKtfzIX zcVnMhHHFTbQ9K(f(fO=t%S>zGS1`S##*R zEoO?9bRK3xi{u@8ij_o|iFK6qz9)VpcWlAE=70GnhN^3)y~1?@zX&tA`Qx;~$Pdy+ z#7q_W>}gO|BFEn3Uf0tLYurd~U5Lh+kQMqlGsd$pqq9=II%vk87U&Lp4C^u6>X5Ti zG0wB8F;knLzy87Cajt^BLXUH``T1Y%9{l_s4|o3a|Jy70`CF~){OAAcso>}L9@6>G z|Lc_C=MP@d`OkkY%kyI!;rX}B3x5BarJeu&3zr8!|NFB-KOY@`1}4|~2f^eS?H}Z$ zJuDri0{_h8^wNI>=U;c*!?GB8p^Y=goVkU#CpvdzGm#pT>9*Hq!f^~CU3ZszPW<>6 zWOLEO>(_etWXSNIp%^C$=lO^@%=0-O<0Xbqh750e1A}*-4`WoA=O+TfCqsr`5)d9O zaj549g->P)@02;#L1nd>!GE$LZM>zIdEh()gwHz900p1z`3>+7dcIRW7;~e)$!3UG z&q}5+83DF{c?NUw!c?NU?o_^2@{^bm>f0gDc?L<1=R5;ux`gLE1F7qjcjgJ80K|Vb z{Wbm+hF5iu@@IgpQFVz;lA_WH{t?YRf!_@2Lp* z&Yb7a0DcPMXPr0BbBM*-X0vnVhPUykYMEE=Gw8+qHoll<T(1wW=ih6rptG}OEbJ#i`yI8I#p zmpOrQxWT?-SN!-~_Tx;4c;{6#;zq3q!4)~oMXypDnTFf@ry~4Z z^fkTR2WGVqW{zuXA^_RzNhI@G@nC}p63wRAlqXDYzejjpa4S6HFwA5SzIeu zsx_F^{S$&=@o}5aDH+~lm{q;o)y_F3{(V>TIJt!NW508B$61Ex{sF_zCrnW{m47%hY;g8g%7hrwa9E|kp^(OGlOJZtMYOKKM^oIj^<_8AMb zuiw4gk}>Yl=k9bU+CbF|Mi@83xLpV1mZ~pR`sfJb`kF5126ed_C{1(W0-pGY`cw-4 zuJZY~H^N}tBp$*pJTQLcZ+ZmNmw@7SazJ=Mnyh4cW=4QbFpfMK2_Pnm$q6sRt$`k22dAROM-?VnoI8HKw(j$ zNiQfVMg3mpbu^cJtDal;(nlaOdwupXPe6|h!f4dzgiQLpbkEc`O%x`45&@~FnuxkZ z3cqX^CV`irzlj*W0sf5Nl>RW|kWk07Vzeau9sS#o07o~%zqtX=XZ|JOAC!Ljr{Euy zKYISs*6t;SPe3TBeCXc<|7_0}+~JLzJl~HvBq)D-ngVI}Ol6{ZZ`5&6{kg*Gv#w31xSMoO86n@M*@+06TR9z&$C-??c_sGYhs%*(~Z|EjfmgHxGm$D;Y3tq~KyiSEyW=Rw}ntiK8p|!PR2jHCs zR2q(J$~Y%uGLLJHb1|Q@+jFJmIqxRSp`0?4mxGwjsh&8R(>JSkoZ*%LJf^JxuU4(x zdgV4Mw^_L@$}L8DIr7S_Q*OO-8xdiV~Ymfu( zlS6O9&Ce~1g&x~{CBl6e)y!{xWVD8VebTL_GS-kWKO1Jtj$6ZT7<&vof41-2FdXr7 z>w{mx+6$JASFzdg=ck9qz0qFPrZv2k<2OkC30lK@nf1 zj{C~Ae0BSx2=`@VNe1KeS68}U8PJ5^eCp`XT4G;fpxJz_>Z`|ZX z7vpt=`{FI8jR%{iFt~5Fl5W5|5ci#ZwEDU2KfQ+HM>(gxg4@+G-?*C}4Z$0L_YM3S(>kE&0 zI%ljeH0JA=HIrxxsn}VoR;l@f3GZ0rs#RM3VAJVh-o&48!nL~ z>A7=~cVKfU#KBwz-=SfM3uQR*N0E7~O2)W?FjKT|RQCMKg*lg7-EH5fLC6pt`IV~- zlD;S!>ysLj={h=)($m|5`JAQ$k%)er8N0Ksi#5_y7P<_>ClUS_{ib$Jf58FT?et}Y z3Da5O=(NJM1rzccBDol=^Y-ed{eYd0U_jO#@|hUW-FHaJp8lB_&^_O%6$85G8?|CU zci*8_4CvHUzMeyEng2Okg>6Dqf(f6(M-z+*%iDtqor7gPOC5dVfaU&i!14@Chy$&w zk#1){9_2PFw^_L@$}L7?>Fm#=+&bkpDz{m=&iEg`S!etYZZ-0Q;p&vz9mW9@$dhNZ z2GIsj@{R-c7O?4hr@uk(I3VTvC>c7)N{3A2fUI9awz?ojPBtm_7yk0R31IH9}$ zlH``(HIK7K3e=fCq5)`bgy`Wuc3*=}96H(Kw-=E86uIfC-a$ z-R?O~SlQ{A(6A3`WrPV^zn=&bhFdS#1;+`;<+o2vWr?$}(9S(~bO`pQA-VQ}=*(Ya zMb7gSqVJ){H(8HVyM|Yqg4P?>K!{^wCL(4{!9N>jO`sVJdOq{7LHV1;1ZDif^laWU zg~^cJj4#1vaby54*3HaUeyKi+*d}*o;>%Jk+LMu zePyKV$a7zrgenX2wcr~x9&DQ0GPm?(6}kzPM)sL`5Am}On%5gvxtOt(s|DM%&y1`y z-9R7`sYY2+YY0REU(fm@UOGYN;KbCmx8EC*vxUqFCF$+rEWrk&q{=$rF1P=w{ znltaUk!G)4j{>WI>Eff=@Cfzi4kj7W4kmu+w^Dn9VP5FlwGAo(FWCYlZ zaN%eqya68^%Zj)xbKjXBo_%Lp*BmC5e79S37%%DUu|%|UUYHm!i7+85l%i-XF&rlB zf@6tQ`Rzkfp{Aqe9!ne?jU`5Vk4gh!a3f6U!-S#765lL^(P%!xhgowNjU`5F60KIu zJ^VF(jJYwl!uSrdS8F18Zb;uBtM2p3z!Jn?(hBx0LCmmsVqu*6Enhzny737GcKLl5P)X z?8@Va6E=f!#4B5i0pGVv-f_fxgT@g{OJe!$QxjpvXdH3F2DJ12hi%~AtLbr|XrCJ7 z2D(4*-l2gf7b?t*4>moH7#cIC#$kZ%vhuaO#aM2!6l|K!)TmQ&MgccXY9V1G2ZEzG43B{j7ONU^-GN~W4Lj~ z&X{}JPRv-E-##|&JL9mm#>hSzyc3;m@8nB#-o=)F-bHc9HH*cAcYzUTt^qUl1Zw4> zs361KOl{4qj0KV!-F(eqyi{e7*e9d8rBY)u-HyV1$7M#F z=E95<)*unt=5{v0zdhrGc8+nvh8*LBR*rGPnrNKR8Ru*3I3eo}$MHB$D0P86#|fqE z$#a}g%91?C38n1FbDU7hiaf^&rEJLS)KTMvYf$#6KIS!t@zPGme5HQOR~liy){<@y z=39%h6|&WZcfFxLmPirlZ@lXbDHmqFAvalV(yFRF*Sp@Z+n;e*T2hwZJ~h!eVKhz{ zjT3g*J~fVF*x0D%?j6(L&K!4bY}}x=j%fA@dkpU}+&U)yKyO*`SAb>=CyCs4o1hVw z|HUt`26}h2ldUHq7H*eNd-M25GgZ5*I}v7NZbawax9{A0%ks`Gm3_^n505aT{?)Z! zcNAv4qBY8lt1y_cAqQrpQr;fSSd#-YrgC7$1X{jL7BFk?W*sM`@{v@F)0?ui-8^2LnfxC?5m z%=ur%|JbC4|6|U7!$i_DKV~e8Fk|aC7h%TDb#7^_B(FVeVx>wv_Z~L0)MjU{T{$`r z17C|aw@=mwX>$sd|lt3b~?z;*9Y|po|jI;6mlFHwNKcaCi|9Uv)H8Bd$Op&q` z%pzq)eiHnfRN0W1xsj|3F*{9(Np{YH%Z9P-X@q+FQ!jW*<1hlFf(K^>V#9wZch6_|PI9+SYNa*OXN_%RK#cXSelALfA& z{rF@3m$cIFMjD7T5Wv$h2m@E*L-os$`vP*c z2D!1Nv3NfFpo|+=68apzX=6;x^u75uKJLhTzF}`b4Hq)) zJ-%)I>_5D~7?6{4UYp6qHS~+tY&tm<;p&ZFzY8+`P zlHnWR&-hK@+q;jAuBYM=KH~F}$Rs|0C!eo6?*jhq$-f#rBwPM9!9QF6*(juJ`Im%$ zd-5-Z@N@C*ru=99sewn(^XcCN|DgBN>sOFn!tNQIzl^^D{@I>yL5~l5KFha8`J3Jk zQD-Gnn2Z43aQ-dxl1k%vxG7cl$tS?qsJcv^a!so4lAj7*>MHpoz)RgEj{~Nhy_t4pI@u4ieJ`WHU`5`mijoodYc6j(n*zTwCfKMu|=nzNLn_y%m0wNrjk9oOBlq z&fjJtwvu|Z)3k{M*-DC$<@B#pZoP6FmD{4+BFIp#Sh>~8?Jl;KwWuRPwz?Pvmo^Q& zszV=WGQ5GTb;xULp`6}_iCm=$Bk?hE)>9!{U3hIRQxRDM{AlA~+s3+Vvb8i|JC887 zmR~_mCrKY&6nB~)hFl6a*#`{4kIyyPT2?^O`B^$tYrc4GEg#@LY7KI*wT#PW|Dbru zIJNXN_ZTnRB2rdc%SOSvR$pc7(9X6)Zes~^tUxV$ypMEWV2`BN$^OjpDypb}*kFyO)UIjHX z{aXG=d=kGC8sRUtMtbsxpVT*|9XaX1y-P}BN{o*CK=<3#Zl^E#O$nLw7HJ;XZ=3x2 zz1HA&I({b7<5!k|&u>uvLE+h`1f}1UCOsb0Gj)G!BkFPk z)Pwmh)K$1eQVo90d-7}}Q}~JhP+Uvi(SIa($t&{gH{hh@$qKba_lc{(H7F12KKp~8 zg7{enT6LdO7M?k0_KB#auHNG)D$YbR!=c;G@J>2_tEZ&dOdSOuKsBD@=n~3pRBp3! zTa;Ub^ii(6=nhl)5h=2jI|{C@J6xg3Py|`vkXLu0oQ}Cf&Z|2#K#t`sWUC9W?of{p zh+%W-4y+_$bcbCar;{XsuKtQcAlDB!`7Ug38O)?R?1l6l4L>1?&#OB;47pknf-7>+ z9m?|=r-_%wL+cKe(Bnu!x`SrtmcDgdT>4f?V1e`<(wDgTkbVK{=lfJWbl8AZ8-BIw zTaDXKy!ym3tFL|bp{o~EzV*?`iwhq=y7KPbPB`36hxdP5``)?FFeb6rq0}55By8X7 z4d;Eo<<{T+oHE28s_&hU&cC$opyE&Gr)AlQ-747o)9EvQf5knC$DW;Z+rhiceEHo= zPCc+>!;EA4ef^2XSC1=taQZj*|G!ades{o=vG1Mo^_9op`{Mo8s~Autzi#0#zaHNA zQ)8Qw9_z%{&R>u?p!vy>I}hFWg+Hf?{(8^FbL{PUZdYG;&^dk9?a}kLo343Bd#3j? zQ}@XI{wS^l<0zQ?`F)4%5i2}s)r1fF|9!e?o()W&btvxjMw5nF+WGgfECpC#*)G4(SG~+M82gK*;x>UX58QY6@Wjge%n1J-nz&#;}&#P0t2)SAjf-7>+sVeiC zb005>Df3NkdyJ(Tt*)w5IoXkKpNx#N8L*&e=E9PDkN?WPXUemKzv{F1(-&WT`mN8t zcSOZY$DO_Ws{tSGR59kfb?@GB-~BI48u`rub6&mpx)0x`;XtQO>XXxt@W(%>e@>ls zRKN31u?BroI<2;D>YUT0`l-{94u{5qXu>MB@r(RX)#<=8!@ zJ-_;g({Js)&xU;;9=m9Vr@!6%AHSV2==;Og^t@x?-}irVL(A|pZYUbj{A{lczdB<6 zr&mwh^WAq3Kl`EiWmgri|M!y@{%gRVFI@QDbNXy^`FGAs?sw4@56{^1;Qsw9>>Hn$ zx^kZvF9g`&_apj=>_aQBAm2b|=_JngjE7|F^OH!7^!ei@VRSDx+hBAN#$SW@r|LJg zYw9#j@LvU&ZH68{`x5neY9TT&Jxx`nC%H{vkMZgh%sc7;w8!8gtz!%YD|tizk>DjS zIznflPC`oHnbaAWw;WetJMGsQ^u0$Nok3R@G7K+j4^hz+GWQQfWv)j2CS9Rf-EUED zcd@t3b3P)x6v%e|`*njgnhZryBo29X1In>I5E41BZqNidmaCAhF1)(Ie0(5m%W~=l zs1%`e1IXzlNuaC0BJC}FNxln)Spszf>JX0U9Wo?|&#N1(fLyIBk|8&?G%gceZIYVw zs$IKx%E!4@nMgOVESou4FmKA`d;a8@!uhXHp7s7;zIWv8-oHEHyX{zH!|fAgq5*Is^Qb&L&}PX4~TL-2a~5&ro7_K+ZZR=P3<*|Uy2 z=)1j^&wT#5Z+!LcY3V2WFEVw9-1ZPuV4Jb@*zmx!z4m)?@wg9=p&VM|2=Kj( z4s{jXz?;fkeKU)w1}|}{H=yFF8>HYbx`$V6OVACNH=-LzUUZgja1;uJ&9+}R(D#_j zt{bTNB%&K+?h}W~UCsA_qF1NfdgV4Nw?(<#MK_p{Zig(lUBLT!?FKh!GVn%uyX4gk zD983eNaP~jAW%1m<+CSvRZJ-fc5b`DD?{B<2yZvo>fZENf)rd(-zEOm+5`K1`Q}?k zZ}V=yAy3|X?>_5h9Jk#^$J|_Y$BF|=KU}tK<=9yBxIZkvJpQBpJJo*s_-(JLTl|N| zR$M*vS17neOSf2W6kc+(Hw{9e-@cRc)^>z>== z<$3u)4CypFW!6du0y{#e(|T1uKVs?KR$KInEzYx z$*TMRcf%(=9-nc2)AoP4y?Nbf&u#s)qh2Wf+E!;gc;k+bHtqI7uX7H+`J(HFHPk=- zmzM{fx$n1M-EQ#j4>;`D1&b%metGJ91OB_q?pM5)dS>#^9^LEyJ6`+dOTCUb>Xhr3 z9&_lGH=a8D>64${s(Hjiw=~Q-{IGw{`^k4^p7_6W?DHoq|HT`xA3N{Kqc7;O@S>j| zI5zRdh@JoQ-&+SRd*}TPU%hne8S6`W*M73!o#&nQ*dB+R@W<)#(U(jZRJG{%p)U?B zJ7L{PM=d_--(S1nu?v^q^T&%X-Er@ub{~3GdDHOA4=w!s{h1f`|Geez=a2kw)s+9d z{`~7-9bG!;%-3Qgw;#FY*bnUis}J6z^wfa^?prYZ8%@7I=%v1WKRoEz$&b9XXpeK= zx$~r}?>Tku;yFiL{`#O(e|=}m=|^3eIJ@NI-)>v7!|{iVdbg~2r^#<#aKV}P_ny5& zals!yKJL%I{QSMoe)yy5=T6<{*K4jR{^FOb)df|Dzjf(DcmC`8 zJ&)MssJ|_}VUMHU8~)wOAN-|h@Y8E{e{9a1bFUn*;@5>2J@m-ZBmZ^G-M@I}lkFzY zZ~AWWna{uf==vc~pWATZHA^n2Te|q8GvfQqdvpJ9Zg=kBz1~lpJ^JUDfA-%8&zpPR zPlp#@@%rNZKfQd=rX6d@X6)1`_3LcYUlZ1dwkauUU=iS zPmjClFMk_+@M*8Se%GN-A3t*Nyxor+*lVBXzIobzUO4l21rIO0=Cs=$Sh@Iu3AYWu z%U*f?k8WMI?(0AMsHVBcqm}O+_UYqSOnc+UJKs3(>Fe*U*k{joi|)Dn@KG=I+F|~p zLr#C>+ba%S)O6rGBU4|y|K_dUF1_f3BbMDfWB=oSGhq6at9N?y@lW5sVbr3Z?$mf^ zvVMo}-Cy+j!H2&%{q_?I@4Nn}esh0VxvcN4k6%xt@Y@Zw$33}S-@k10gMS?O z(AU0v;eUVq_O7$nZ?oW?y`Nvy=j&BhTz<(d*9;%=m)D-FU+~-wefLXTe$XSIOn>eY zyT_@&{P8WjE?zfxze`5G({DkK-&Sq&^qzgbd%@L{j+or%*vp!C+wa!p$M#)wXv-gd zvj2>mZ{DWj=s(8`r|kOI!udbHf9S8i-TUZASC)Tz`vZ?W`QIPh@~2r>4*JoAOUE95 z)RMdIDgDn!ONL%_)*gGTdi{l;9`jo1O_Lw}d-CNQ?mPULW3HQU_%HVT@$$yUt~utr zO)U@H)4Tc9A$_L~E?l?wPlvpJ#M?avEMK?kt(6bX||js5;HeSiMjuf6)q(Ssj9H-7!CCzVfqY7tDb!Gl)jgipI-CtZ(Nc% z{( {!zoQTR!;Y`frT5?bfgTssBDN-*xzD!!AAN;xRMsTlCGpO*rACMHk)j(YIco z`k$en&Kpznz)jn&I_1Dm&%1oq!uNi0eZk#d{P~{`zu$MrbKC!R;YX(r?OT7>#|J+0 z=iN^{vHpwwF0Ct^yJ2>p#JW>{_wANb3!hqe=|P{YshM`;3sa_l_LDFFHGk-%t4_Y7 z`X^gm`}j>YLu#uoe5>rzQ78Xq)}q&jJl1nb!kBzH!UuDp7y3{{6>%<9nly-f8}CemNp`(7)Fl^4B%rJ^#KTL*KZ4#B~Su z|G$YB-t%<7nO6@zJNAPf{pL+Lr}>9}{Nc&>jGJ}Hh}-ww?N8H(7H)OuWy@B-_0QCh zhi{+y^_%Xz^X2pVUiQQjC%&`)U*Fhk>a(XUI`tQ~T>G1b>-z3=?M;s#cwx=+bB7*s z*DfRP+wJUvukHK5AI`aA>VsQ7xpeuA+5bK2%$2e4ufBHw^CzBuRKxF%ocV)$?i^NptkD&#!S2U`AaXqn!@pbm zAF|7T<}d%(w#{d4yCJ#XhJ9Z?=!KI9-v6Wfce#D$uCWt$z4Rwn?z-!u%Pu*n@rp4| zJ^bR0R}S8G;@e*g>N(=e^M&i&T?YbXEZSEb)L==nJ#OFw^O!nMPCK5t#|`3I+6@Wyjb4ZiAopV`BTzMuSZ z`=!aR23>N&_?E*TnKI<}OC~-4^sdeOJ$Un|ropE`Jy zReaIHt(NV)?NvqB{o{jcoByxxeZ$T?YT$wP$KSlH{+0jq`R?j96UKeKdbbrrwm5QW$#BW;r%1#g7f5;~fzkTT^ zI~})n^rU}Y@UJWCPOj{K)3Ng>{qOqegP-_*^VP@AJ!-+M;mdoS`2Xx(30zIj7k}-N z7D__&(jx79X;Ep@B1w@-o6;g%q!l6A3aLa3QE8Es7Ah@B3vDP-mNtcoBH5zTqYGB?OBoLRL4xZ3c5}F zOY-S+ST%P)pifz_r1{dW`m&pXz8w?u<#$dkTz67btIPbIuBhtdOKEy1qN#WJ&?-() zPf0)bYCrG6OCs(|T~pF?wy}p~snc9ya+o z*K+2mO?S5_+A&DWbu#5n-PWY4sTHzG@IX$O{)7T2!<-#gN}I!(jwR^?dW&D$7Th_p ze@&O4%6Si-%O!1!C#arnYUJzvL_R=hjopSe9?v^C;Qc(R){Q1**SXn+}We9-Lt=gTPk4zGB5 z*MG}_={?1%y*1pOX{naAiMkcrBDs9|*P0lY_4&LJHdMK~XTnbLzG!7d+Jq?nxYu`{ zzy1*S;-pSzQPMruY#oiBD5cYTCd-5|JZ{_T9cQ|emQq*yF|WX$)eglxH+TE2y4Z8b zLs`J{{5zrTCesV&ot)yi`@V$^i&j<3#Rs!_RXB^SoxkKwrWbLcXSEge*x@cN73@gW zy!NDy(af_tEN=}%cONU<@z|F^cYe`Bk+O;I zqSv#a-QipH}85nZi=$694j4a*b<%Y-7= z;y66yW}D(Q{kfmy88+~; z>(S_FB}|COkMU3H34P7*`h6pl%@aYhxppJ;Zz<`oJ-A?zRNksYS}4~>B0MtJGs&C z7B$$P>mn(A{7S;9Q1@HfWz4?i4=-jW6vqlGBm{ioYwS48s(h`H5TNc1!AZ%1Ca~%jBI&RT#9PzB2p5gf_au^EI}b4X!@710^@pKBb$$ zuqkI|^^_H2GAFjlHU>5wGWJa17EqnC_sl)V_XcZS=&lI`i!I#$sh3;rsCV3@tM!Lx zm$4rT^Xy6YWaM158x;VIGOI8g zs`m;P(IrsQX2kM0t1+DDX13VT-y9^y)#%4X<4rZ|L7+!d`*N?skQnQjX$;M`4$|>D zuMv4|%NT>3C$6xs-o}%1)s`0L*i&I2GIS5CRovtZkG$F27eBvYK0by@;|-NrN^zHcre&unV_K)pdf^MW7NDQsmkoR6|{^6K;kFK?t=QGJmge{0ZHY@LV z^~db=Q{TDf02@9Zx5uEUGvl7e&MHhRvbTKlTu z!F9>yqWpouCZgK%+b7MW_+quL^rh%q^zf0dq!yek%1BOFVy#i(YmrR=U*g; zUcLbPfQOPO`_*=Dd$6HtBGYEO`iFZT#UDs(v|=otDP$QRWXhpqThjkzjZZR&V}_HAxAZz-Mitv^YO`0O}405E5YMB`zFSo_`IFz+_d1< z&XNYoY_&x8-IrT(O|wdb7iu)+G(EM9d~$Nlk%P8}Bj15ZaK+ARYq{A={ezO~ZfAvF zPZG21Gg+s_KJE352MN;aB{=uJi#YbOF=%b$imkHxpKOiu1(+o|yjyr01KnRnzPGP^ z@0exW@*tIJ%AQ{N9X?SXV((3S{lV@1$(FLlSgo~89Mkg>DSUUPcE!EyS^RE7sQ4S! z%xXTd#nfjuQsHjLWOwaU2~WJRG0JkXrc?LT1&J2>FD~>KUY%0WW?kdf({W|TLk-c| zR+Xa2qp_Sk?|f6t<~7%f?-c0@(bbuG@!G+crJ@(TI>cl}x8I__b+VxM#6_FEyg{M7 z-H`#uqvVz>9WW}2sR`{VwX770D|~)=nf1iy{7Hv>MI4kxo-3uqS6fQtu$@lpuif~Z z>Sh1DYDJ^-G3BRhriF!cN2a=&D>ck|6@5hWMEdMg%o?XJQ0Z9jD{9N!be?08gQ|S> zq{MXrSI$}Pjl6xr{e@oJB^sI@jed92;{GoWCSIdo>eD&hX;J*n&WYBWraI=>&$D>x z5n#P^dY|0Ny0Wmhx#@m(Yji^HE8hr}Ei8*RG3@k-xcPeSjv!0Z6&KdYFOX_j+EQ?5 z;PSvE`YJ^#>rCICwDi8nG)MbQ{MV}OaN$i+LD z3K!N3C71{sy(wP#NyjV+zbXC=?{3TDE6LGs-`Q?4o;+~tJ+ppK$*ioCRgrZk$yb@Q7X@V2AR@#VHR? z&dXnZ?U2f=i)+Nu z$ojEV)#d};l0=*pjIdafaG`=%Xv+<@mF39Fo%_K+XvYv%!Q@>cpPZ$t(`mCz{ z{Mg)uC)4vYE=DTVt;^i*RN3Kpm*R}p4C^b7i}|aKb?YN#WZSA4qH;r5H`y<$zBhMM zCe?=Ubrsb+v@X+?&ti{wF`r4c?ohmT8*8PB!r`dH&jLHQRdHm!b6PH%HY;3b=HBa@ z%91blh&*DDR^>jk{DRf9qOvq9HngN9_nISTp49Mc_;POJ z7S|UiSqDN@W4nYsjtZ?k?R1L8+5Az}=Iybya|Cl{tJ%;?<~2n+%n14t#Cd|fwbpOe z)mT^MXdW{LszYLid#OSVFZ9xy93M!mSbH{!k*5gHW`V;^0!2k@anSw?RCj0y@mJU0 zyclDV%-|3NWZ+xta^d1wct2b>OHA;7Yj8i)81l!sJS+y@?+X^;jg>!GZeOtB7|JJ= zK3t~|4Hmr40To3mt^eZM9atA|?G4;#jp`nT2iNst&kBaQK{Tp+7>4V5QC-3?T$hXL z4u;|SOjK7eOh`X#uTT*<9E=(W9=*1Q@LM3G*7ksHLW9Tb673bjzV3lm`Cwo6fb#$B z6$0lR!-Lo`!ecJ+nx6@?5yy~=^ocMCLO*H+kdK@-KX}0Bi-dst@!$uEcs;N*Hx8!? zu8+4KI2zata@GUq64@4%1?ZwO059$e;KPH9uq-U#2ippCVLk};$3r}Mdxf@ua@c@- z5yA8zf%U*r-*tA2oH*J0uQT9+L_lM$`T2T|=)dM{74p~1QVd}9;l-H!s<1#)dna{IO)wwDgAo zpB;*CR#liWd|_hp!JgEpIZ+(>?SpE(_TiZo!?JRVXlqE`%Fo<;2U&V~%oUKD>Gf*C26Y&KSV+Q@3+R{ z(KSLBs>ebQKh}C}c)u$6Gb6l-z)uP%5=0N$lW1`NSow$Yqd~^Mg_-dneysfc7cnV1 z>jz>|U+{x<12N0Yv zP+h|?A^iwuRlx)_f;_{$YH&}`d+@9vP8f|@v2R5TeuHl46Lf=z8IsuKK8RlDkKE~w zeG>wq*OA|YVEVd7-4CP<*Q&>2ZV~3TVlLY2t^x8qxTYO*{V?};S;O8B>HrZQ^AO`% zC2GVmN?Xs-Sa|gJ;c&lmN;C zbO~Fz1>jQ!7hzeZfFCSADLf0m4`B=95FvTQ``ZjbIcyLUa1kHCvohaxo)9>UaB%Y* z8Ee?DU}YT(&yuj0GlLh%cyXI2Tsa68n2LF|HFNDto?6sib3u{>KJ9i*C0a2YTdQ;!_8Gs&or<<`O;>6hA1DS z%l}jG8UsiM;Was;BngA43IA2RHWpric*z(1#=;|m`UYfzP=65Sj~u+@3+^8)eJI}- z{Cx{AL8UiV{)kj1Vb%uy`xu2u{Llgnq!2M-nMeF-2f8T{Zg9If|Z3m7^kckqNEbBM0m_YtjoI*1LmTBBn-mPkNO4VW5jr%gZPNYsDlwG67b<6 zGazDJE)D9N16&_Zm%|K@Ge(_>GCG*r*ZdKd0Y-5GzG~n?y96;WYy&Ld2lGMLFFOI> zB5(~6DiX0S*9SM*ASU1G z0@1f@<+sLAup@kH4CM<{i5^JCV>Y6+YAZYOz_>FQR^s1TIG?` z(emivdMK9yG-3_tf`@5`xqg^igt@Jl`@7g~7TCx!!ecJ6?KULffh^#W3=*;JhI~*D zAVPe^w%Z!;!RLwyk9mk~H~dbqIEWk1c1MHfMUL&xCF-Oo3(zGj;uXjTF2b^aR}y2| zZa7|p?@ACMdBnC`36#SIF##9xiAhOGNPLg&9$sEC{y3}`E6{h??jN=-P|qRVKVRhU z87BcajhlnjDbZscy!v0#y~N`jtXPB2kBn>JI0;fA_(9zX`zh4Zpt+LJo%0FCH6v6d zj2Njc;T6L9D^STAKql0ezl%OJ1VurF$2`RP@CahST-2Y5^&#XVXDky9_zJ-f5gzjp z>qB4Ar&&PUc>2&9WQZJn=#4UtrH6vhCDeyL;6fp|2K6EQ!FGi5LD=_{z)k8P4iS<^ ztPhU>J{!aYT*L?Tq11QHOUaV|zReD18qjy>!~f1$hL+s(4x7s_K5DpDT-5cz`sGl4 z4F8WFYy6b=Jy1^%+lJx9Mte{j__vM~fU5f@jW?F~H@7;Lj|J)opj>$HgG6k9A_;h4 zJPH!qAIL`z9xnuZjZhFqc+4fXKaHTiVcdB3CmQH?a_mnop^*V{Q8}PX7;h^XL`(=X6DAFJ3aG-2RfYj!fz)nmIwt?zf*%T5BCXqGe>vM^JEL@5uEAU+v#m z?@d6(;h_u)bY@n#ubFk$lx>If=kds^nLqQ}&cGlX?H(WYK+oTs?`r$aY4JOph!e%a zzsUX!r#4DH#doYHK~hH5uX1ci)vjn$uAD1z586JG)H6#-#&-n}WIJ zrrBjQuKhAC(!kF9#nCxESv7Bh4dc1gPjAhQIjN~J<( zc(T#PM4t_nde@|TW_sg3|BTO>7vuHs@86+Bc~_z7^VKDu9-{ksr+vH?ym7N>&2{l5 z8FngyTMBe4uH?$|vG}>L?d(5qR-Tu)q0NLQX(P1sFu5=m*2s$1CDLdEyE@c7%7XAx%^tKABy9kdzUq=p1?4N1hhqvP#^!N@r5(U3s6&| zXgvG?^`SK=ge@uvkp%dzvJo(iCI5H8FR*Oinu~;W1LOG#>f&eM8&Y$T@O=!lL!;&* zCB#SL8?cj$#5+UKHVJ``g!upaT%;jE$H0TSg+z>fju7y`c+?$;u@B^fcmWaOBc6+d zbBC%Z5-{Vj8;G%wKIlMDmyCyf8bPBV2m5@2jfa3x7NARrefl9ExCqPgt+~j4pg_o( zi}V5IupyByz&^6yb6zv}Diqm!w=^*2_G_`vSZgiE|90kJb&Rx4v$h;HHBB@y>@v8R;~}VK0ZF%?DN<~V>M^I@TD%VPtjSD>^+>yX!&2U-EhMr{w@;^cLWMR@ngQH?R5J5z~;`G41BT(P`t36BHKH-V1_`% zKW%&e>U%(Fe@GD>xHt!kAW~0*S3#HiCXHwN|IKp;+@NIEppC$~`5CqrG@(IK1v24W z0^Ivj4*aBT?Wk`pV&6>~VOK{^VoRVI>>-&HpiydoG`{uD?{}G7s0Q_j2#zI5;sGCgmWc3}huFSe1`k*O#EoZPtw9GP$G&PZyglW{saljnrkQG?upEoomA z9=9gJ8wqH%{rgwgSJ=+JHb#VBl19)v`H|mBg6$O9SMX*PhbA?-}!sX&mR&#()Q=CzdM$e{5{t$#U}W_bvs+ZXk_mI z4;~qdesunnV#||gQ#&eM?P$4R+gLi4z)mJH{Y!T)Nu*{Tl~TQTd4KtPy%YG?OeZF7 z$$j(ezzysD3s%BIe+cPsus?7fYApI=f4!uiDU_92XvPdL(r@<)z#sRohw*E^_ibhz)cKP1j;9ASS(p3Nvhcs3ZcoA zfk`Dh%=N?E-(`OB&)TJ-`98u{{r9b1l17V>$Q%F2pe^9z?@C4_!o6^jGKiEXPO#w%11R`_}xP zHHcpWeuQ)4AUH_>#qkZS3uIrcfghF)hT%T9M)3QUYh&fX1BG2`^x6^ZY_+e)su2xn zMs7Nnz)nwtvi={&H%h1@fb!zO57J!lBb;CJA>e`WC`kPN3i83ZbVP`c`2AHhh-gGi zz{O*J;`djDpku%|*heAifX@WxYZ3TC+2Y^_$rp4sa^7D>5E>D1ACv(Jx`a`YAkYY| z!Lod7Z7h7xr2%*lA$g<=m%vOloX z{Yv{Y=H3j6QD<8b*`JYzSxLwdoNw}Hd;^{+4i`zJZ%~lf{y;u*>`x)!YaEn3^oPg% z#P+9=O#2fJIvY9m=ij$CLt5^;)=&Ie`$N|Hxxx4Qr~%-r&wpGM&RYA~cAH}GY4bX_ zYkILKg!znl-z0Ok9d=cZep0_{@Q?+9hfU}mIsPGkeImsQb|bk4vGB!-`(@otX_?IC z-Q3Y{JIU2+IvwS59hSB?k2Za<4;``PY zpzU1azu$?401D7|yx+0-{`ohnr#y#tU44AcG-k$j{EB;Liqz)Pp2)fMz{r`Krr1@o zxHWL|IhIWwvh$v;xW9{eO95qF#Qd<%rl-4RIfP8fxuWf5+81#``IG@OYs9so{Eqk^ zX`k$d^EdANoTcsct$0H^lMSybStFTaFHEtX9lSYIx|O3skY?*Styxiug13(i;4=1k zoHX%zqR0P9YkO0VNa&;sXO3Mub@QEEi2M5kD|bJxS}a|%?b^y_izDZ`RvJA>E`Hw< zpNi%1*V`{i$q|(?GVrtP*U^z;heObQsbV^N_#%M^&VxsTAA|wFi~WLif$SG58yY{M zx`1Iq`dRDaj)S^}U3S#_BS{kbp$NxMpp}da{(spo!m$w^doaZI>mlkaSUd_6&)-2l za^~+~6KKR_K?jfdiRbU|;DN%p@!lUb0(s=j-+da{^gvr3BIpuE^<(*iW%<_oqlcj5 zYG5*;gX9svKT-wdupz-GCM6^FJ!h*($o|dti)r-!*OBvg$bQZ9o4RzMrMC5YO^LF! zwmYTFg{ciSIVqv`GtPKSH3}@6*T3aM7>jS#3#HVke&=;kzTwF_6^Uh`E}k1My|&T` zG3h^PPf$U~`@QxHYzD`}dnrB{M@Y&Sa>@5BKIivn)?~J`A7(`*-bM|k~&&%jxGfWcJ>Gt33rgxxdd&br5 ziv=_cDVysKhx1^W`y1>R+RKEcIKn|~?XQl%e$;-!^Sh(L?~nb0R_81I==!>`?H7st zMk5T?$gM__*j6K$tN(}f4}a{}klp!*?3eWStbdS{kS6B ziRU8@1t8;w)7-33Z@wa&(vNwDOFI5G&otMA%gPONPxAT1O*%l+EuK4}F!}A$qtqu= z6;{(Xdmn9}T3DRAu_0A>*NS9Li2|wl=~ot%pIJCt@v7Ca;hcT-`~bdCg?Ce&-Mh_` ztz`LJo9K4g&Ls+O8jr*UT<{jTS1>o5uW7?-J>7HaP3y$+I?hq=*sEzY|IUud*@e5+ zd~+6t)5b7%(Y%~bFr?+7#!7-c-DTS&xXYdq2959-&%V{6Dq&e&QN@Tnpp zAU!-x6cF*)x)XFzsB6a?Tl<1WLC)AZVk8V6R^c!!1l53x90aCAW%<_GU6CMvcjiu8mb)vcckt6YMaNJ8y+582M4ay=c`k+6FOPZC>GFL-esl5J+nO{Yu9o2N*kk8 z*X25gtM?`kl(lqRD+_(JI&bzV!B^>@mf|x@H!<$dad(;8BIU#3oF#fhru+4U?Rk&e zRX=tSWB$?S6CacoRMwH=WD&D2`@St*$0Mie z&b|ZE1($`r>8U*OxE2rOo;tVTW*Y9)vR8&09jC);VwLKgd%aHf(@wehU@dc<@e}pi zi#`X@FT}myd$@8(N1<^gYlo7Q@C?^y(TPea71{*JEwDR3&M7VJFo`qU)_K5Nv!&& zybm(T9|s)wEP6f3>+G!JMIC(&(zBf;rU_hppLMEUVTPjPr_=}eeO9ibHJmFa9+-2K z$|aJE$DyVn?>2pj;LP1l7p7kE%_}&f7?$-~Q7UAz(mX%8t$ovNl|$~+Nu@f>bM*GB zAbReE!5?j(l*>ajgn0d@I0$)OER*fk=`-W|VrS98C3%;6%d35h3eC&#JgaV-c|<;> zKGd;mhN!Ya0&Kx_r~ zRz`y#3d7}x(4L~T$J{U;gkjwbV>7HSeib&W0rE*>GZK3*$G~PIcVS9myDD%YT3-{6t#>xDOcZ*o=2qb0YOELw0&RmH!e2QXglHYL~_>z z_G?+?*_-H818*xgUD>9=;t+e?!#OhkRgQkAH$BaDQ@#Zqh+70D6sfEb>*qX#;mp0&Z}U9g!GHB8HChm&O>%EA<}>7 z5&c!$I=K9fL=vz+z&;A~Jt_Jf-+REiAhdlbOl*LqIw;yNUr{u_epOXJ)`#%4? z_ZYG#g!b$2dv7l*{ypo?B*kUPo?8&c!1Gvh3sUfEXDJgLL%1HYP<`#(M5tNSt^6$lQ4+0*57QJ zZUm9&I^v_mo&**~&dB@|)DMzJEN3TzjbJQ3!DRGNhGf9Kei9ZMLN1=@EwR(-$n2>%140BI7QLlldJi!iqpbE!dIA>Z$EK9N4bW5k1EL7EGG zaDD1vUjS|Z0S^d*wlhS;<6y|ggvCJz@r^n^0`S3SjtGx=h{wT4KxcyYj`xlNK16cH z!7~9LA)zclm#~POfR6=SgkyU6x*Xod0)8+bs7`-N-{Mtxgs>r3wiB4VhnZB}eMe>r5bJA3d)iv)X9t(dwl{Q?oNWavH zjkq31^(7Hp2c zs(i8%*7q1R5{Hame$dHOp(qNizD&J&5>(n3LmXdLO9V!RO!7QNFaN5tJ#puk`tSuI zxq1}$mPcK(KXmZ8o4k6n(RzPpVuL-p{6FO#(Ik*PLR=&X^GkwI6~gZ$kRn1=1G@hx zLi)yeRLsx?sAqh^4;GtH=YZfK!TTG*kGNU}Bf%fk->M*!uD~UAKdC&Sd!Y;E7lQl8 z%HLo-`1@x1Abza$|BE;Z)&;~p(AM~ZA1pfzydVgpx`bgd7?0Hr z3_~4Vh}9(w6Vi|1DztCY7d$_RtMq|D4$uf-nX(o%tg407v%YO!dILGoevMn3W*qBSrG8Rcu)m{B#ik{ zi-3IO;45Fi2cJD6Jmw+BSJ9vos)D$2@fA=OWZ^3!rGl~mT~r2`6;8m12Nx#-Kg3nk zm`jYWltBLMKpY|@j~HJy0zMnW1YE=i@Rjs;tpO1y|NCu|Fa`E+#aDyX@xAsLR2&}O zNI`ABQ9NVSXME`mU(++k;#$@y->iC(JXLG^yeS)mPQ+Mx&OZG>T5+4XUrDvHNOc4L z=}sxu!4$v#{UZB3oWN-Lqw&vJ=bsHX#Xw?4cjU#u=U(;W#|#Z3JB1`(cdRzrA9Y2}q38Ti ze<8#sLv3$#w%`@i2YwYk8LUE($hYjjFUZGO_Mb>qz$}j-DBl{$9}9m#eA5Wx$C8hA z&k-^S1LLLtPt4O0;|o|ehzIa6<5*q8Fdqn_x`APcFHl|l4EzA`2_#jJCd3a5f!`QB z5U8g~;|Frrhz>!75$i;;OK3s{rt$x{R@8K`LxI8r!VmtB#tFv>cpwXSJcC4x6CfWs zIH3^m!DoyJk9ml3f(PgnVbO69nhI;PFziM-g;ZK^gMY12Et*zE30x-`x2;kgs{ z9`aA2RMGIhU|sI*(-Sz`Y33$@aIR*$V0Va_&uY2zSh@ zGO8x;6R+@`Yb17@bCCbk;>Ge{_asU>gX*NfZAV>Cd2zOj-#D0Ueq0|&6C4N zqG=0sK7M-r$=ucP?59938|eWDy4q8-3IbE6uf4xx`*TWv*`0mG7Cf=KR2#eKBO5AH zKltes+pO9Xy^X_0?%)>V?8!~bQadG4>P1=1XYRWK zt7arH_D1eKr}%c~yw3u!S``;uyRG=(siXn3s9p6Y{Xz|)lLC&Ku}c~=BNnE(gj75g zI_z&06fG3S((Regf1LVK5n zwb_JqF72BZd`p0P-N#IhwQjWs7CD>O`d*z=z9+t3udq3*J2T_FIzDB?v(RHFmb-ln z2nx#LH=SqO7t^_{!Ta?B&$|;UJw#306O;41_ZYoCq@^wJMkhJ);+us^tSr0w?y=FI zs9E=1LBv@?PcVBCf2C66jGObPRo!o!A8PI{fEy6peP8*0$Hz7~pQ3d+1$(9`JD&Wk z7j%c!taNk!wU`~IvH|l{KCcYVv+8EAy~shCe#@PDW2zS?a>td+{wcA3paw=C3P11g_CxD52#q&IWrT0A7uYcZV{eteCQjlm? zcV}Pf{tG5==$>1%sHz7s;)~@R@*B>z-!QaZ)w#pGno{g^y41!7{;47L+v>JXW_qM` z{8ZG#=sm)9OZF7)cRyB5sUoc*L_xh`MxoV$%P%}=wnX)@&q~%}VawhS7X3)5#+=VF zN63w>!0Kk~EuNfM3!#o{A3t_+-PxvN?qU_v9Dn7llEwWuyRPP3d9!}%8_^pYJMLQc zw%_<*cEeRJt(13CJ98_g!+_?Fa{1cnW-Ysw6DdXf?mn~9oLsY7<3eWVy45Q>4^?%{ za5dPqt$BxQ)IhZ7wAMTad_(-3^Enw*x^*kwpIKilquCZ1Xm_c>Cn)m3m(K3??m25c zRgZ~HpYgiXs210jd_K(h?A=yPI(XA<>73P)N zr&Zgk%ChjhmuYD)-de`K=&-W}<&EiEAAN~`p35FOtLwm<^fa!WTl*ceUg-lh=D<2E#L=0XSEGV?H z=@fYo8s(Lc{^)2Wf1TQHVXGx)-*Z3lNHsk4@pEYqU51v(KG|@4jdP|umxQxUnL&6;~ zjv&zg!|(I4d0eFLfs2P?C>$5<7m8m_<)TEJRKYB=(f`P8&SI@p)(l>@wKm}?AFoci zbCU7JWfv#21=9KRdnq5QMo@L^^K{IPjgMvtlLG3f}3nvl>gqe?D|R=#ItY~GVJU+P|ST4<~gRpRCtI`>1OSNLbu z(v*g`H?!<(NwMUrohT{!D-f}3^PkLr5e<@pFs9LNObv|S7lhVn?vyP;uoSuLDb7bH|ZO&vCZfQzU!7CJv zPueTF&E{{fUPFN|Tg7%)uR+IF;CS3uaNJASDlo+| zDp$F?-H+ z`vY5M8Limo`ss9G!_ubbN2)dzRle3?e|qAW7(e@a{ynFZ=D+q+o43xQn(sW9Ld5J` zvp8P1q?Tp!pRQ9aP>-8beVgZ!j>BZr0o%m=B@Y@GOW7;xB)5CBuj$<}Cu4uhDHrSV znJYF#?$|}`?`%3@`^A9x4MCFA+v`p(Q!sJ`xE84ztQ>mr2bL>gE%}*P0RIbJyOy=)b z-c;JhU39th^4jnafeg)trPC?hj>~iv(r)aG4e-=fq+rpF$1!I-R&`6ycwl~Kxfqji zyQ|ip!-|u0C}w+hp^K&k2t;_AXDPc%~m~pHIc^xx{($`torVUbFi@PV!(45jgm#J~fxeY1G5}$MJnQy1Y(>3T%ecU4(wmDvMJzGSD@d~_H@$}eCgBWI-2XgH`3nG(WYN5k9oo1ygS=G!*rWm z+x`wcs#iyr)0?iyKkg^Na_~Ce>Rr2AiXW`HzP;y8__C#Iv-o8TXB1l}sV&^k~Y zY$Bfa+4BCL$5+|{WJ7xN=P@g&2=Bjjae+DR#XjSPXDmUxt}eRgY7whH^NLNOinL}E z=N)s|I}a+R<}S^vy}OcSQ@CRGM#(j=s2cbRBzSv9YUQ;Z5E?F`t`$iSda# z>9-7Qls_eVzbKS{oRY7~VGoUkB8qvx@H%6qKgq(;f7zCZqYDoR{lJY2tH4a9tp zJwmCjPM4I9cua9mmCkz8tM_Tz(QENWo~E1D`A&B{JJYlC9b-mrb<)Qn^0rC0jxzK1t&FMMgQVH;h3& z(>V`xi1)>^7Y@+AShJ;>`#@DWyAri+8#ga6@3q36cGi@K`~L^;MF%wB(E0-FtetLY@KMFf4U-K*0uOhj_U4%N*=BX0ZVVb z7ui!umEGUx)Q+=Udt6y0FU(%Iu!t+v(jwJxss6Gv2Ekdow&wA)-qv)n*r{AbS5D)Y zG<6-5=7OrX4Vs#(X`aL$Q?-;_!7xuIZCjMVl|-iSjfP5=18n=;&)mAS>ir@7OoNUH zo12t=0>*-_bT8f4XkEW@o`zjPFDCWK33Jo1s(oxlwy#@NJ@vPv?EnB!hUlJ{(JjtASldm~QWaq>;9JF)Gtn7+PRh4>zkB08zix}zOIpee_9-`eo-Edm_n0Ggb5qH!&8A-hx@G<1*a}3?)>YKE zcw2Vrcv}|a`Ob(bit3r|r)EFzxQKnQ=b4f&9v#Lvhoqlcml=Jz%e#FSdv5+!mFw@;`f{9k z&LrgtD>9Rt)N1P|hkUu1IiZSn@}y(S)XHe`3}4i-f0((V=wQ!vdTwrOsmF=;9a?O4xZ|2mm|3ISxx`tgzkIQ;$$ICoOkTK7Rzq^B z(+lh5Hvi)-Z3Ak1ET!k=Zx8cjR@}rO|7PN3Ee>IrM}%MsrB=^XRa>^Kt<3U!6EeVm~p zr{{EcX4Kxlp0>`Te*66-2I$eO-j>O zhBWd^MP1$9G;v{M1Y6;|$GRue7e0^?_FvTV?(u!Td+8=z&sRtn>pHaV_&mY*`g9|2 z6J7UO%k37-cFA9q-d+!_Nlq;=+Q?^f;<8C(<)v0xS9bPC+s!&dsaMo(_T><3+qS%{ zojH7+p)^-7zs%ETA$hOfISIV;_AmC`x#?NL=aY0oIrT_C5xArDBZ0mf#@nOUQNVeq zuai}O=3oBIzxAIgzeOoxZGuT_0As%!@WE5$m{iE%3W^H zQg(5$UAs;-H<($dIIa3%ia@SPruM?(%?cOqALf3{l3{kxSeduvU;*Qeokp{`>21pQ z39fspSu!nTE=L6Qi@1m|&kr^&MV1nVw3O;Td;0Wmu&iTFw+y2=<-V%iQ70wIsC?bd z#3MUd=v5wB*py!{EG@E_n7Z0LwfD50!M)<07u~LHOQJ|=>^87f&0y_`U-PP_rzg?6 zlEWok_Ux3dEc{IdzsFZ@Dao&+Dy?qfE7X}a*;`F;72TF?MrOxN(D~rA1n&K&_4>Cq8m?2ZG^p~K zNd3Xn{jPD+(R`g5Jl3=IX=8JhZ~Iid>9f&&DWu^Z-1^MISDk)N=v?cIntlCZciw(v zc!Z-*UEMpEXX(E6dMoi9VGBxcs~otU8GD1LYQl4Y?*4)Ow+@w5y*;$c;JQs8o-eBQ z-t;n)eRg-kDqJ=%(>SA1WY2y`Du2($^1|c;IR-I1IGvfdg`YRntlPf2@Jn`5(EdF# zMhp=twohkAIm~}ZHP_tzi7#`x_!ON<>0NX8o@Dn8m|OQ*(WA~pl4E*;_f$>k-jF>L z7kS!pnt3saBs^g;V?E3J@cpE=S+D%o3zj^sO1tef$FO4E?o|3v-7xiqI^9*1FYOWA zvO?ilo)X@`QDLPXOwLmis|{3b}Ce< zo>(Z?w6snpjeViwmbaR&@wx5qDv#$+dDyf)LN?=WNnFiamKV$1-DdGsKUU+~7@f>MV=?LqDS6OVlq)i`FtlITIX;Nz2% zQy)C2UdVc4+qAhU1%f&WlTMp#p~q`&x?GZ;p8sZYa)fbR;$kzaJpw1}g7XX84)F1H z=)@RwueX}_VM+7Sw|U|n61X6~(`l<}!(Rq0zrbrc{oo-T_C58VT?-hFZMt}sBR%~_ zznW%(fLlp>{41rPW)=o#1J9WO3F^*_3){9YxnVF{X_`#W;j^bFt+&oT-clIKUr`pY zWs%#SPgI@OVac||Ts1qI#M(bBvY=?B4zk}AF~_3Yvgo;8S;&D2^VddjZPvZ#*+D6H zY6gXFrT82PDKXWXYaetkDekk#Unp>|ze;=W*2cbP;ZJjQ7$uc^jQ6gsb#zK)Ipbbg zXGE|1D8JB3HEy3r{!T+09)B%%1!>pvFCs24@ojA!U<@%gUO{YIZETXt_ zv3=2lD;s9#9&A$+>MhDUd2RydLrr$B7z?&q!}IF8;pN+edX{i)p0go(r+(7Wi}SkZ zjFKE~c#8!p7y64VJEwb5Swg6oTi)L8s6zq6<%DOe?Qj)wU%>lOk~Bg;;yTIEkJQyb z62re4==S!{c;5`!{{tvnZLaH1S;JoiInw(%Sn{x3ZhzJFC|@p6b`F8pI}Le-__$ zz*R-5#<=}?ufH-SN1qDEf%gHIye7=z=d;>F(XvNsl~D!joJVW4UWUGSVSo6cBb)D$ zSY^r89~V|ArgA5Wgx0Gsjq_8yk~-NQ`@ypOE}gTfcKo81u&Yo^OG zJ#;ysr(kxm(ju#Q9Jq%spI=`&b@twli!UYww@eIvI&?-b;kq2c^Fh!M;;*j5c`?Sb z8GK(3)>(dQ9S#mGhJp7JEi)W^)bM_5a6i)+^2fM5+)Uv8zTidsSowo%27JMx8c;r| z^x?bxXt2?E4yY(nY5f=1@xZ!(>u?6wLSS_d!+20uc%U@lI$>1zXdMr#OBjaha8TXB zFkC}`>I#Ml>1VAIE}HeNbw1xbZv-q6mK$T8@QBk#hF1I#eg_`Zi3TXl|MNQGQc&-R z@R)~qo$!R&h-1h_x`;8Os=|!n3lo#iP~Z4V`viv#{#fl}k^$HHl-hxK=iT*#`_r*BiJg)7 zbNqc~pk3mj3`(@m?EGw-77w%e#o3hMnv$i>R_CW?_nQaiM zj`(!l5G);Wst|T*#M*SwaWz2t5UcuOZY<^&VQwqt67Ol#0Oc6OxS0F9oFUK;>H-lS z^AKZKC2GVmV(uw5X+V;*Ac+DQk#@(JR`!>)MH(aBl6 zu1KU1P!^y|*y7>dHC1qNBDg*U{9y4RhK2bcs4koj$RD9@M)HW)t}6jWX#?&>g!sgy z#mYJscKu7(02SabV8_9__)%;?MeZKAI-9l4X_-mBZ{sz5QSD>y zFTw`Hsf?CS{x@zZ(OHF;)~EEerY^syaFQY84nrfCan#gZb56G>Fj_{152r-hGdg|p z#|FcV{2#)8)a355Q|>RxRxrFVccU*4=wrm^BFT}inZc{53IA1W_ATs!1BrYKyZC~f zjD=mGKC%Y)+YaV-^dG7DHbO3Ve*w1NB@Q1{TTkj6rCqrck=u#gM{M1$M;T^$ zV;*9R1J4X3=bWTy@DRztIJtn2kWdz&OHd8CD}axjbCSwIN4Fvnh~yDt96L}B8xni~ z<4AqiIY|P*ba)7Q4x=%^PnrKf;z?jg_Q`1d1!^dx&M}(Hf}_K+yM!9r*y-D^ z$2)Dto7uZ=7?w%w8Ho|U${%Zg4JD2aq(GkhUsONDI0W`@QiQ7L--MjK_n&u`m!+xrNyMMCx}?;{O8%fpv#42&xN&K~UZODh%QQo((h?q%ny6I2eS) zkwT;{k%>WyU_F3F(2BXg8wT-#odF{}<`QF&D+D}{1?dN33;8j8$3mS8=We7WfWO&kDDhKAW+?EO7H-n_ZN*%pw1p) zM~IR|K~#nR*6|6nhudwz|3kUO?NxWFB5lR6BcY*Qf z7Ghfj`N+ZXg@CUS3c?7Fxx}`p6DWQdH=Zqu2D+XcTa-&^aDZG?4(Jj_LEF&?u0cCA z3H)GNAZ3dpLH-Ou93mu-*cMF!0&EZya1o!Fl)Sjqci19HNg3=@FXONE>%^4FueC)~ zRI?M#)SJ_>W85_SF`SH5Udd z4i9Be2*t&0?8#{r2=Eu2=@rfLq$X%WtOHNh>gy8mT;jX>p1up1b6#;kwp3wCX)ST0 zSojy&qT$p=$*1^^_oYY*as4jK6m6KiCtX+kmQM|0dO4-k`Y>+sn%q|XRRIjwm+H!ipKF>$D{eS& zJgBzSTQs@a{^PBeS3R^|^Sm~7#Wk-jJMXYZkB(cfM=Eo_g+@TP{n~5Z&x#L3%ih+) zrJUvUIP*emacA4bV3(V_fl&3 zH$JW7T3y;yC;MuT%?Q6QQ?r*wAmIqbQJ#*|qOR+P^aKI^0AK(3+Q!?pqTh|%xwqK zhGTC(%q_y)R?Piv#^eN@1P{svi5LeRA>e`WsA~}8Ajn4!4vGeR@EIe*V;*80WC}VH z)G6cPphjx)aL^~fM@T3O(1raTQ9tAZ7eR9vEDsEl!a@B&nGmjtMe>Mo&^}NO8zg*4 z^k4|!AW50;z(K!wO#XFEH!8@OXP%;UP5u#bd6${|x@5Rfui9 zs_HHICevped410`D)^lA{x_Zk6@a`W?bO%w$HPHXUSc9!j?r;3^1cdo-tj85^FTp~ zQ}CyRBQdX2G~A1%xEU_dPGMnLlpc8?i=Xj^v8%v*L!$jIf76&8d<%;-p(_5Xb`p*| zNzq_?28oRI&JNl!U+{zX6LoKJ1&8}D+A%Z+|JRMlC9rR%NenNC9)0{aiLa(fNcHaaR_WYhgZbJ_UZ(P}kSgUxHN=nkg%^>5Ue z`RD9!8ctxe{I7Ek$PkgR^+%up6hG$tyRG1|)ZC9^Z1Zcq+lH_j;h0d8K*U(K4q-3n z;S7)T{8d{flbp|%81-E&?2}ld#&V-ys!E_YszdTAz(9f*qyxuw8klQ`xv`l0yNv6qhx;uK zhX-YYL~Ki0P{$jJ9`5SI<2uMk&bST__~3IzgvUI@LQR0lH)pk5Mcu15FvTQo4i}=8}PImrx*;4Yq zDQfsT+ftf1;rI=XU(&6&$B{EQOz)M`Mf^mclWO0yo@4 z^8vokxrMg-ppx#&joj+Q*8|IU0_F3ne*kOSeTDIK>j~Bx0D6$snxq*|<&8NTl+hyOh#*zN34PJ&{dv)!|J9|Uv z$WS<_@u82f2*0l=zIsH$0W50g%^-cgN*h~sE_-ltU=gS1hdO@0O|SsV0QBJ|AAK!y z(K0kCKtE~VfMEcO`pU*uPlGSp5-nZKy}xT4TXP_b!NA9Qo&xFp5ZPk}>ByEIN-l*Vd9vAJPi&Q@ zx7^D4AWn@^3f*&Kk1bXYx2TV>Mw?sR;2I)PPqD^Yg!2^X;iu?K(wx3?7wj-Q7=BaD(N=M`pb%0pw$1b-{>+rHMMYn_!Z_dtI$}`GVm^X1y!6 z<1l3R12m_@2#o{znBW>*M-T%C9An(<7@@At9Na?zmIDKEy$kxKIJ0iG{i1xT8hToM z*^czCZy|$?1*m~sY#Z9vW6*tepSI;$P{M>t|0%3_pY9XvIn_76T-!%C#n?k~fu*p* zOd$#3$>%fOB&{3{iKVjtBtXET_WHZTqQjTJU-!~{r=G2ph0Y_@7&A{sXrZE9mB@uz zL5Ym8d5c=k*NfGTSu;LmW8(Xo?EA%U9QL>Ry_S0S?i!;ItG|!1h}Rx$h=e`GqOCY` z;*)Jd9aPd87Wsld!2f?OSOoimun6@HVG*3{y@^Gg`WC8l+0Tqa?%~|POkJmcVbOrx z!@^cPO!b{_p`H$3wimsNMcvTBd0l#$9V2{xwTsV;@WiF18*@w!M=Q%(i5E%vW#uQ0 z9-C$vtpZ*Uyh2C0i2QmG#lhw3CYt$R>j1$kiWQfAw`iPPCY!KhRAAlJ(7KrM>E!jD0v-&g2-)V4WJXha`j5%huP7Csdg@v==Ii$!0PP5qa<9>ir|D-JB; z+{j8@cL0lsa#0+bIM}2@r$o63<|88)WrKW7+ytdzX`)>8)%&??s;PZJwh83@uqoKy zjz1Ijb{x4X_*CWk+wr@1O_nOgJz!qRj#$Kpjt<-Vkx)NHaFCGD$n?k)$D(9&l3D_G zJ?B+1xZX!tMBJ(qwFu3jp2|fos6awY7K^?n9UY_vUM|Ax=svGpq{r!p%z;Imd#`E?*b5c0$4WAd5$^hr zT&WVuI-yVA9zJM2bmh{rBi?T!mu^cqaW8bjU3Zh;d>30S_c<$Zp~mQl)@ftL_PjF@ z+twJqDF_)>DzdPE@G^y`9kI%l-M%h$c+FO^blvPpy2Xr%)ldA~F8XRrGBQ~3E_F+* z?sk=zgXA4+t4{57Ig;EWZ2Z33Vu@U<)sp6rC4xt7wP$8tb)G9ydDnEqh(z(H%1rsK z!QXAo3rNoL$aP9qyB(V>j0tgC|ALJWaKJ19GF;HFrr~;qFkj69xlAs)p`>Xlt*U0sk!4Y1ml(!V2r=jg0-(J zEPG6Hy~z~x!x^g!MyOs@O*KuvY#X%u7|TXr-z#plVo4l`WH2b)Dy8M+@`?4)( zH5YsnFJqZ27N9(T$+=+xTeJ55n{+d0he*s;+JdJldC~K$M1GlCI!x{KSwV64b*pMt zEF8nocTd&xTq<*P?<}YkgQ1VG4EjoO3up}WR4yC9vi7|&zg#TC{FyqlouG5NGSM+t zCWw*!VK2-9EMsBIXTmaVerzY`>Szo6uI==KMObe@$R9v2FtN5TtFf-N{c^sGIpwnd zES4SJ?XyL)z(!tO|EZ+t;~m4o&iG$+u!^!Cq3C{ZZb4|-=Eo%-y1`?$^nRYb!BJ`C z!;C${wPyV@Jtet8Ch~+v9WAxoE5Ck&;FC+8V;U;U!P;z0?QR5jeTD;DMHJbPk5@ffr?t!b9b+52y?e&eHV@EQj2|CI0$ zJ5$-x8LkUtb=_q?p58*cAv8qxqJU5R0f**)>u6$UUfC;^xlXhjmk?U)X=ik2Ou`MF z>}szH(`&n%7?;dvR1P^-*5&787zGY&WDW7ngjTT zx0C2gxo_(c)9c)!g=~d<R0gCooMj{pO%tXUH4{WU6J!3?RX6o2?rsJt4 zUgFUaLv2iSwJi2EnBoY8k{xld9jDnk08A%<2+EeZZ6X*-GJz6qZ*3XM;Z+%HN9$e5 zyKZ-7;-Dneyme=uU&)#FO<3)2?Ob3TP)#nzv*`^!To!XC`seLi-LjnXq;M%nXc3Obqb5w`G)ysN^Y8UFx5M!ygQuFIO(D8KUfRU)5adl^Okdd`8m>O~aJe z$-0B!=St4Q;<;|z4rtftL2!XhEobsBJ2Y)pB7n+_Sm{)x=i(xL!A5> zFTYCIbTouMH=hRiEc`nawhacdeA-^r5!T<>zioUPD419Im>9>-PfT=G|L6FIGwciG zvmn+bfCHV=K-vJ%0ogFig7XA$4r#;Y(=b}}7N1rE%7-|~)!&BB#kaE)K8@4Mla6_L z_Fq2j0dA7O=M4jqPaDgFzajEzFdr#C4djF43I!UL;Na81WFp0sBhpF;Cz5{v_Gx$Lt5Z*5S`O-wD=S_2XPbzCOFW3I-Rfclkh90bNZFi`q|NrlqxrdQ$>`UQb2nlD*jIqSQv6V`tQj}4*&_ach7KiRMTD6)Kj@+VX z*C%8-a@$IxRr-`8w_loGzLYtHLB*LCih`ThTUJU-|9efPZH*ZW%E*K%L?GCtG# z4ep@Z5X{BNcCEG~Yk>8*U zL{LbkZjU2^^2ch!5TfUAvmo7Q^Lj#7mee)YKq@hRI@k&JPOuA!K^G$Iq6{HED>)M>Eb=C(bpKoJ4R%GmJJXGsk$Oh8EEL@$d-hBtJ*yaLq5<@^Yn@RDqBTZN4tyruW>gI{FGjc0W?))W zMOzS6#W04{H3u~eq@`Esls&{KOnWA62%H@V8OE)l^xDl0Ba&XtnB6<}PsfbV@n*)P zqc!{WNke0^j8Jx(@sbI*qM%6gEYxm>qG-zdX;CAqekhWjmfgb6sBaAH9Z9#*fHTgv zLiJJSKs2vmWP9n<5QCb%qFN+^ctlJO4l|-?qHy4>qG%L>bmPTo>7iINI1fswVUdwh zH!FZ5jW`-Pa2D#u|Iaj@!>|WxA(d&?`mV|um{4YKGf=H}rV$i52cfUETUxb6xDVP8 z5CQxuWrv2Kjv2O*mR%pClo84jzFL}5LMx?R`Wk-sPbaR#w$U=FMwCrq5yyA$N9*NXJ!va~6v~(jd@cx`? zPaD(CEF)lKn>&o95o8P)M&ZC(vqC6jUoT_pzG>&q-f-HOKK=9{JOo*C|AU$xh8sW1e58zzG<%IlorSeVBpNzflwOeL%^`j zNB~<(C>|LcxfBU(Ba}X4;3_i{lOR2io^9@H9VsnOG%qbPv4@R{811t$6U8qhE6}D5 z=VOh4*gvw5E-;Lv>$B31pEl0ebvk><%G0mq8X7C1G)D8kySgK1|R?Pctmo|WE0 z6j9fl{l1YAfE%(xd6>>K(v1k}j|6IMy)P@CvQ1A_Hn z)PU54V5|}g2K4{xAwo>zhCV|hO&7h!;!pn0LZ~SO-AMjKM{*#oA!kG26QeEU9LTwl z4v>xz@#~a8^1r1Mnp!T{8IqT@CISUMy$kfNT3k1TyF+?FLJ%=JeIR0@g(3YR;x_;? zur#FpbAbw$hA#B!7g4_$yo}+Y!6}+P72&%f_d=#YB9Q5j8Ib?i&xY{< z$V?_G24_JYhCBv&95NeH-tP%SJ_&gS@+@Qyqy*ysJ*P#?MfiD57r}Xu`H%&WC}bgI z5o9rBDdZK%a>#2C|L+Yg;w^;V*7S;k|AFCM$STNtkTsBXkoO@jWHV$dX3 z*-;v*_&+;o+NCA=6yeV`T?W5o;45$sNCQYiNFzvN$eEBP5czAyaC0qA+H|&py)~q* zFI_uLKL_FVkPeWJkWP@!kbFotNOwpN$axU`*Asd#2(DErzuubO2jMWJKV$#|7c=90 z$Y99D5cwN|@FkE-A(ughLau-egIoo<8ZrWM4Wy!95p1I%*D;Mnjt0j-#zMwHZiL(f zxdkGA&qIF!G9R)45``>;IFOehOCU=juRxYVUWL34c@y#$#q%tH6QUy{KQVmiAB7QZ& zY=#ptiT~Eo;_4z?PtzM{VVS2P;u=93Lz+OuxxG0g2htYO9?}8Q2@-_JUmn8w)C<5a zkU~gT#>sSo-L$yw2=~x*VebV!1nC0_L;6DoK?XxEf?NU_3b_(;HAMdn*YptxU!&TJwhh5 zvj2So_9r1vL!N;=3z-8cfjkG93wa(g4-$pE2yq}wA;<-$3?4zJnZq9D;lg z`2q41G9Lb4!LA=Mz&AvGX1A$1`2 zAPpdmAdMksL7G6CLIRMMkQ|8kwIW6MY=qlTZwt1AoCE0q=?Liz$%hm`3L)JgJt4gy zAxIxcKga;cK*;%!iy%WFmq0Fs424_{xdL(}MEtG>M=&h(YZx907C}Zqu7}(J83P#$ z83(x$ax>%>$au&E$Ze3@Arm2!A$LOVhTH?W7jhqDI%Edqeuxe6|7IfYLBI z^V?@$2wn`i;@#d~47=&?3q|-6$j`B%A8fAoz<-7yd}eC@}Lx%plVqE>(5S~bx3}#O1|KJ1XFS)GQ$m7Gi|68l+S^GK` zK3c_g?^;)LOFLTl(;M{pf?mzTXzsDX&SjZEU zC&5J{w*2uF*zAs4t+KXHoL91_S*_DockH!#YsMef6xRHp_t0K>$1eG8ru9btn3W$N z$bDpZ=H1g89C>Kgtgq*usJZ;agI{bu@ngS<&b>{VHJslk<3!K5YV7*zpHnZcfBLUZ zEqC6vCKKk{vmouAnc(YmmcKPF97<8a((G%Z45rBT%=jIH-n=-y$*b)?y1Npo4 zCbt!MHe}jcM&^$7w=Wwxr)jgQcb%EJcG9Vr7uEQyOXYz*`?Nf8rMdR+rPbOwd6TDY z^g{oQx*s;UDmJkf@)fl=stJZ5eQPys-CK|n22bDj+n$9Jm)5y+!K~&l-H>yU;9Za& zo9BLaH@L2``^i6_te+~v_fn>T`;Py*Fa3gp4aTPb*{{i4bGx6N^T-AFR_}Y{xmQLk zzw7a-n;(w1yu5j6?)N>ud3)J6gV#@=gFHf>qwKT}gq}xuE@ac~zaBny&fGpPAbh|* z&{VL>{D&`{4~~4W&#!`a=ZtuJM3t!@&Dk({^8Co92XDE$<%o>c&mC=g<=b!d{1p?S z=Id84`SIv459Kbdx~=DdRzEg)_^NG@>*jn2xpw~W)q*R2zcpt&*z^9oKD)d7#|R7V0%!bl$xmw$7Bc;wS=-Wgy|wDRS+9-y{KY4lj$iK7UbfO} zA8I&!!`DR@JT>B-N%uc@%dO{FlP>w=d*uBAa^0WBI|Tz7uZ_L$sTZI831K0>KpHRo zeXiiIkfV?W?asNg?cJYcuHSS1+&y<%Bkn#lA@_oXqv!4~=>5@vTZ_NEzWR&LEh+4g zakBaE3mdJkW}R5n?!GG1ubWd<%CS$Y)kHWOvT*463)lR5{q=vpJhE!BW31lvM(DGC z4=#*8{8slf_C5dG(vyYNZff{Nt8>3;((Zwl0~?(8%lJ?0*gFO-ZPuXM)aXsu-}rUQ zk+naq`_uLjd%T@DHZ?Z9+%EL>E$zG4+WS`3+hcRuKJw4St@7r2Q=1KsH@fx(F!TNT z;d$T!%0f`cB8c%s*Xe?1b-1kW`gzwjTJhMApRVfTTrjm-d|J*=9amgba(YXzq28C* zOg?e`l-l*G_qe*z=)K!=x_{rj{sq%_{d(_#GrATVOD{eDJ(RJQvJRZPX3?e3W&OBE zgx|etZQYWdUw4QhJYweFnVo8%-ce;t$M-fs-$>a6_WI?YONKvEx9*4U)VuWh3x2hu z{Wmt-Vi!LCUGqyXS%~l=iUUq7Sag-(^PjFc^GLkI`!6AU_sTu_OTe$5SsnWZ4!OdXvNSzj2z{}dsvwzHeW6Jvv#;rEJjz0O#&rcU0 zESgzz5@nx;3_Eni--2leP~WS!{VkY5$pp`D()7hWe{8EK!j&QYy0o7&05X5psvZ9} zdhNIf529QE&RG0?q2Ps-f<-Sp97j94UO6;l9~c|^^yA-w{{&`t*|GffX-m@LH+{J0 zfdvN;C*-PA6W;%3*0S_<-VF5$i9hw~>BfU!UeX+4_kq{*(!&KLuZg?u~r@t(8p-h2DZ^gzpPeoFa){z*td68?)mWreGwKiZ(hIn zuvc!J((JeKJ0C=TA+snCgF-?(U)cL7_z2|gS^c`&Ckh5Vj__lUuf3lReRV@C_xpEu zTso~mze96ZT>J8QIX6ygdHxFr!!OJ}Yh*^h(74G3L)KsW)6Xx7^d~C4xjLTn;h!ae zi7!JJvW)U7xE%6PaK}}zgF>!*BK-54;L3wn4V%{C+Bd$M`NPi2?(;u|?hOw(yZ-E! z7yOcc<=V-WR_?AHn7ZKVoKN=KwH}J^`uE7|%RVX!R}CNAds*I=t;k=r^qP0)6XCv_AmZpakmpyvQPJ^F*f+)oDWvN z`S^}X=|AlL@YpNsu1R~enUIl`QD70|ql|+!t^-^C^unt>ANtRP>k+mfSD(Ez*mS~Y zv#vp%)^i(rUki>#d^^-N65;mXD2*MUUk_cf6ZFy01&hXd_la;W!Z(25t*JiYp3GCB zCX=f)=#030NWB~8>{>qIl}$(PKC*ZIIgfvCyL;aJYX3v`zBl-#fiDEz>&{#Fap8bE z8wTEsHcX>T2Zh`ZnE~nh-Tnuzopy47@k>_I2cX}Fx&&uJrXf5S_58W_+1(L@Pds(e z5TT23gW%ZO7a_dnnuqKe&}V=D^7b2g?pgU)y_xMr{QZa<0zRPeQs@stm%JRhkOi9; zU%dMI^|hug+c@r=M`IVy%Y3xie8|QYFU(i~E`+omvHual7a@KB{`aCq;9`ga`ET`$ zu3Uij&WF4N{qI-CG&+CfSL>tDzkd9I&I`dsl!9AEuUm|;kojoK5->_eLW{4s8SPmJ zeLVOgIPaTv4Mlhn!Vcs%gl~l`M))PjM1-9eo}V>raA?}t*~2H?4t)vYmqI2ZEaXl| ztBLGaa`; z-wcUdxvtp;#0l9**#x?f;`-0eKL3p2cbvDm*UZh(2NVXM72JUKY$Z1${63`L184oU z2^6v!vVQ&zXA5@QKB>;KKejH|hOm$kzYhEJWRbP~ugq6Y?Yrmcg1uoOCP%RyxY6=sNTMl^I7Hk6P~}g@s_ko zk2Vw1^y|wjXMjd*V)JzHw!>Rq%>;#1hFml6vgJlP=3$q?-7-KSnUMFZzgkJKGUeJ9 zr)pF|I17?->XBw=fa%}|+h^U`{Ku|+GZ7Y28FJ6IMms8jtEShxqY5abDkS~#%WDWO zSTf+7uZxZrbYD|)V9?`t4QYw8gycZ>{``yg&%;%g%so-}UZIcb+vxMNK_P7^El|ce z2@4N7f-ZS0^b4R1o)4}O?fUNL-(u6U-ub7CdCl#JAB_0*h}XlD5WfL& zl6OGg2wlh~%9EEIYP1F6v17WmId}L!)gKMThj+=_F!=Q5H`c_L?fBw~vo^Or)B51P zR$sjL*l4s@NQ;(Bei;J_83!2)X}n1@}Wg_06^iz5@%N z-E{68#2r9b$RSGQc`yB$+3ed-V&`Ps)O^ifPrtWw;5-{``0|$PMy|Xxa@T_h3zq_ZBg5-M?oRiW<+0j9Gn_mb#0UEO?hvkp0^=0Mn3!TDbypvM*RiN-qDy2{ZPp_ zU!@oP^?U}xnGh2)Xw(y#mB0n(4|D|IJ2dKsx!b2jvJn2#zPrt3iDdi~EA&-r?GwdwAFW%EXjx@G05sU4^FpY~vLBO?qL<)PfUP z6N;7`xv9VZSxvSU5kOc^&;q*l+QSg`_7M3CAkghhya#it8sd>qEu*&aPz^l0ez$=C!;YzV=Gkdq6K*Q4bIA68cpG@lLK|gJk+a zP4VpV%W6q|4AKYI)-&R=d{N$}dPWiTx59Y7y{&#S{ejMSZr-PEQeTVok?kt|Q)lCy zLtlK@#Qq!><$tE^b$a0))YoV)%YUXmo`W9DN~Ukz8tt7|BdH(2$1lTnR!Zs%@i9ol zJL@I&^mFk%_|Mu&{R#MU>1O56eeh?)xyql>rg*M)QuTii{8Lz<{ByJxp8d8|?YRLT zt*pFU_4f$+=Z>kBtZ#C2JS+dZdQ$I+{>ApI{&nq(@pv7b8Qr`dtMs=(k6fhm5>eij zO5Z5b7b*Q`=+QCtlj~~$K62XKLCxnzXkY9$j3=JKi}9Hc|FsD#|NT;k=hYc1y`6*S z`oon!TeiUZsj2i1)#2ZZ)%X;k+%~P0e^0=lTQ5-lycippS4FLdYPtCSXt(PBP^`~e zm#gyAF~6rQRsOsl{+m))t;fsJ-^2Zsy(_k+Vtmdg_lK>b|3THCTf3tFb(Q`#`d2bR z)%O7Ub9}h!&!gy1!=UQV&zUH%l9~^npM&xKUbW}a#;D&?{oRTF9&e!fJE{rhSFze3 z2BNllAi)X=Kuc`k33475UHA~+i3VR*w zUqy3jCiB0F@i@L!jmNL>|KZlk|GBN;&pTEBCUwVqt-i|MuM+&B^Z)}xD)&w8d`uC2iFPaAZJA6G2H;Mjr zLi+f-s(;uzalKRhyHNE1C*_YDh2And>7QBXZ^MY{?}M;Ma6OB0{2l0lZ?lbfwB&KDE~;b!RMuTMf$ArIP%3tF9jNQk?7tx9O#vpy9 zW`ol2Rz!JELJ!n!kZjLdQC>r(HyVKY&un1Cng0j$Z{=~-zs{X-{l8AFkL8#TCBLcp z(7O$ao2mBKdvHA~#`RFP=am5Vr;pV2m`oic>AkZM`&k4|DEmZ&JLXWg+U<5cmn}ps*rJsZKTy2F~ zuSZ3B=cxQ=;(SqbuG0J9e9n6gm$qd(F|a9)%CT>*ctn5O)B8|<;5vY&+i zA~+Ao{=5LYk*Dlw&9R>yRQ}uodkE(pS^gz;VSi4w=L`7vXg}rOg_Y6X$!h*w+791< zzM{snA+ATEBg+35;(F4iiSqwE`2Tnx<^RK&Pq9XrZ)m2NZ_tFPK~ zCg%U~ovMHNLG0%Xlt1nZ;e3Gei|l_Mt|xI^Pa`aUq|iGmeJT38^i5U%L&Dxk*+(H? z@f+#M^4<}4T%Tll=jLGk4N?BV)Hkw9lz%S7dA-eSHJ{_iUzArb+25+zKLcHq{+k%j zLNy*u2Em`*m0p1K@g6vzbN&s4-RPy}-zeB)*pFkhe~R&GRD?FkZt3sqwl7<1=uT8lU0F|8Gxqy|ghtL;tJ%{~wG`-HmE|PQ%|>tChct zaGo1DL+w`=XJNiARsLIv=9O$w{vV3#cX3?x=MnTbG#KN-{rFwzMVCQm|3{!dZ5pZl z^*h)jS1J1n^yl!8sz1wdeqFj=^|w0iFG5AipM^pnqx9>c8xz#|{HA88Z-`o7kHH?m z{YilBTLr!7-g?RX#e*K3q4ZD-%?B9oXsPb}fzt#r#ld}Hz(Z7Lrs{Yl+ ze!TTcHJ)?O{wYmV`)i{9z$`UiyFm|OJ;XUaqoEsf;ZORfR{_@Z3f14)BKA zMSl$DuOasL&y+u|g+Gd0tM-fUW(Iau;~U5ReDi8GKZ6~ye)}kYTrI9&->UqJMgMXC zEBoIl0R2VP|8eO5ZcFulRVDbNlbXLj!ykohl|L3>{gurG4!wScGbUrxE`$RtooCU{jNBy`g=KsGm8B(28#XsrB-O~43++N#2c&A zOTYUO_G9peh4m=wdmQGt_<)b|VL9|D*1y!ZL66`Az9`54AarAw(#5ys0nGm*+5=z& zAA^OkPl@`PoQd|np!|6r>`{C~6=(We@O&U^rt*tQMaX*IhqqMK?41e}e^?|}We@Fg`qQ*b^V<|%(~t%CKwP5JjE{JHWO z<hIO?LkJ&}Nq^i4J+K#x zh~x3J@E6Y4Mf8{Wb~^T=ne^}d@W&!oR6az0-;|D-FOO4Lxn=0AnecAD*bj?=zHM* zt#y?D9)UfA^JED9683g@elWJ9>dzYZD{GAM*ULyBTCUprI>zHD{>n`DZ!_%CjjDd} zo$c6qYJJ=TJ&Na7QMO-v-y5o>^#4GQAicDI3O&|H>8){n%eqeOe@9_AnkxGp!v9B= z|Et31zHx zA?$cwA@k?-$Mp&Km$E&3(SPqnrSA)h>zDG+)i__2v{ib4l(!r0llj~A#(c-~HK~j5 zXao7m|Ki)%B3!Sd^#577)GuAD{J9(U=y}S140abw$G;z*fBaZOmA5Vj`}0j|{AP;s@cdm=DEzqyjE_ZmXqV7? zVSkU}{wRuJ6Z(zNi{8L<8TRj1q&s}B8t<`q9fb z^5U7L-$4t1{1@#TI8L>1sj&Z~%HIS%{L^FOH{z<4`&J_$FJ=HHL;U0GA@kL|I)EXDI~X&;aL(WA)E`o-Ui zHN<&D+8bBF_`aq5`~E#TZJ9(b7It=7kZUC$@ddGaDR0CcjceWu*YzHl;!;jJ%sloQI?;B z>)UReXQY2G!TrTjybqK5S-4(ATdMp6gpTV+i2isqfb)#2uCLd%#D3C6jo;09-dD0; z`SUCIYpki(L)&Wbe>c_MAlfz7Q2T8wTuO&!sQEDq&)4csR{PD}Xn#YTuVi~aLHh^d zA+ppxwD0gYs(rVk{egly$@Q6s=N)aHQ01>e`*-$M?YD7$FBzl8ZyxeTaDN`5|F=Rn zdcdF5e;58aPw7o@{}#jjtMvaMq4!tgHwk)t5Zc51Kfzyt@0Gt6z#hf@UySw-pc_L} z`c61MjBTL&c?|Z@m9TSszK0{mV*iu=h``^wL(1Q$`eT2`^F3+52mUU>KSUw*PvGAY zoF}Dz2F??0o>l(8EQImL`$=hk82&7NS>^v4{u}#<@?Uli*87FZzb){*APdhQWd5bN zJ{(@9_S^9|pN;)Z`Qt&+-?LSJ597Sv=7`b*m>&^5&kk^XLU{&gCJ_Tl-VY|kQ*9?#>7Sl+09m|kCM{)OE^ewqF=;eWjEmHKzW|L-dQKac6M z8~5wdJ|+kCU8($^i|g<1C2D-y;`%WV=M$N}mw5hEUG1lH;J?FrmH!^EDaK3r_abrL z4y*O{Ci-{0zv|z_O7KtnN=5|j64$34=uaHy(seBw2o>AkEqXM4) zs{QzHo~g8$F~QT_)=UzArV`95GS?q3eCQ~UMBNMCde_0!*nkUlCl zeU>*B_88tD2B@2u&rv*2i8K9g=*Qum%D+d>z-7A{l%U5xUK%5{_bb#s&# z8VrB1{6$y~g?OGO{l8PxkLz!U_MS)|xeV7I>L*~2El?hF*H;3Zz`UDX5o7v*`L0!8!s#SWyl}H_b@X3eb9?WV3Xi{ z_!r~VX0{ryBIFOeqVnGhJ%sry^S_Mz0X&b0Ge0g(#!6(8^?wF?9N&i&(f_+J-kn;h z@qPhIYYNu4On+LmXFB@F@}9wbFgL0BFi@Nq_N)0I{?2h_NR599#=r1f<Mdk2>tItkG52L8s>MX zZB}xBXbL@o=QjcNr@OG@dm5SlgcvV;UnT3ut(s9(sO*;oU|*reV-ft@aJ=&GWTZEG zs`8%{<>Px3S>NyQZ!z{SS$>@eTMW=e7_*mUkoIz#hPUF6}jNK91o2AjI^` zME>WL{T$e%?<^$&#IScy(Ee;Vdb4Esrp?HeuZYt(tYJ?tU8zlbrt_(zqB zpH}CG8KS;1@o_AzM6k{)rfzLOzGlpO^fmTLi%@xC=c^n z*8eK>INmRW*xrnRC=c(WW%`@L*snIJ`I&|DMh?z*(q0Sar9#|aOZ{=|AH%SpN&Tv` zasPzxC!{{SKGwrNHJ{?GaQ%N&&5!f3Uya4}MW(+1&rkF4K27S|F(2X=s`VjmJww>v zBlKq_%-1;HHwD-q+&UQ15y~Ed9>abi(_bUfcwZvzyF~p{FiE+;e}(i#J2AdYzZ>Hd z!~I~Cx{dK!iTC-kzCT6!FID+Bi0A7E)&8F$&hz*_Bu4+#!TG@WR+axB>?aMe-^lVh zAbrt3q(?HbzrTU;%f|OB(%uRALmt)x+w*xC^F+`{;KS+i}oE>_6K1v`b*jOz#hW=i^2Xn!hRChKkAt{ z&llnQ18LtN%Fn2rw09ErpK(56`r*(cIR8r>kDiQ%-z$HmBmY47U-q|4YxIAyn$O!Y ze~00HuC$-R^*MTdH6xA);omdyydZXKH6z0DKNt7MVcdVq^o6iT@%&8MFNa=)@6DwC z8s_KHPt^RpUD%(hR{C!>i1HtY9>DXL7{}`r=I_`AYW^;VJ&y0G;`z2X_b*$GmZI%C?zX5B4H_e>hdqGr6{H=XLK<242wB!Q6Z0qb7uGNH zH^hEz)W;^r{=Er%6wm*qJsErmmQr7nx=I2m6?~(2Kr48mg z-cLyVvObs}cdGrM82Mw3RepSGZA5Za`TL;Py-^bc3 z{c_w79DiNS=epwjkB?Yodo0YiVL0DN{d>%(DOqZL*2eXGAkKf%{v7A3V7aaZX!bYqLs7Ycown*Zydhdxw#N8Hbq;36#RTZ8%W+5KvM zv~7#=JErCjJ}odJcpfX~!|4$AD}0YF^B;#j_GMP`d9{J(E3qzW{?x<%9QsD(ZvuM} zp6|)>xbR?RLze*Vm|a!^I;_P5WYu>aQ>Z*{7Z2?lKJm}JyxXbQ~RU+ z`2JJcpA+TXtnB}RUWD&|WO=RnVt;s5jo)p!KE8qPn`Qnkxp52vj2|x5XSd-vit!kFM#`_825vlk-iAuV+1&VWq(ZkQKZLBN`U=2o`d$>uKe>n=0_C!r%WFg_2KU|WcsGKe=_lXptPS9_2K#xzdf;@ zTVTG#FILy9#<)HO@cul63}U@^fgZu%OGKzwt%UPs9p#T+$REIbi?e@lt+Dc2HUGpP zD6Pc%9$EhgQ6Jt&pQQBm1F(May|HZ1eVES!aUPQT*+?J7`x{x_O3c5*mDGN}74x$g-^Yro04!^3#s~POZ*C?Oqdq9uid5ppJ5=MPR z5jCDy!5+o;ane2t_P|VK@7fvTfqy+*wy)XQm>>B22C3hN^l|(>ox%E^7dr0uqMWZQ zp+}xk`cT||9e!8&^K(((TxA#k-s4Jq|0K)*P2|Vp&o89?h$tW5 z-%ERCoM$4nm7XJXykCmZ|GlAy@V&T9e*^pxU7`GOE$q=|RgDPTB>4Bzt_Y~Na;yOopm?SUS_^JZCp7S=(VQ>wpziSj?je#ZRQ;`zvDc%LKt zcP+-__>*cp>SDa&pQ-dqdcmLg`#qU{O91-~*1Ob$NN?;>^FVg-h>~Y*bgqZ&_ z*y9*KY0qnc_SaGK=|+ra1p9$(-)hXChB&WFy`^}cI8V)=ohaW}q}q2Y%8%AkzZi&h|Vi`h&kmk?k2T+S6F2uiqE_!+E%f=^qy5;d^*l-gU4?@Q_LB zOJNT*SL^LHksp5#7)P;Uy>Eg&g!daUmiL{|@jbcBe;RtMz0%LZddE-EsVbt6>E3iGoV z-@D2De+WCCuS1OD8B`s*DXy`=aJj7-OQc@a?`zF(L6Y*9Y0KQjNT(Bt^NCC2%>2gKIq(O*k2H}?tjD`BUk>M}`LYZ1 zVJp6ullEnUZ8m#9j*ngz{H_{t_ zs`T|ye+=_g=I;zWg6}7!J_LFQfA1vqTc8`Ql>U&&kN54;{ypZyFud=Q^(_(Q^-y+K zls8c6pJDupao(5d_lfd{Dtiu|_Z_aM`rjV&V9HE&KUEF$%h;vHrz7+T_M14Og@3>9 zfc>Jo+K;B>z%T-bYVHS@B7F$otH|+r2KES^x5Q|l40{p&{!H56g1rde>qcoW5&1E{ zWqlvR9>w322RL7MqCaiWUz6<#;QF=|=Q*kWD9XeAyG&oDm4WyFN^cE4ey7qe?uqN? z3bnuWg*}SQ$uj*k z+~)<_tMzhY0rq#iUzF+3!Fl}f9yNYm2F4TLQ%n2Z7{3xcUzYln18|(f-@{6ML`Qtj zf$z(tzPc^O>q@mg?u5VE;JhjAJJJ8K+g1My0%HBE{?0`IR*qBs`vUDBn5Wub73+N^ zu5Yruxx&Brdm`E2ccB|I)q4F**zvwGf_{nl^eglj{$3`;@vqU^Fe3BRd^iVs2=8;` z{Me7{NinWBvcB#Jw88h{QpZ+qOu_SQsqcn=ZpPpLO1;O~m@oKybEyvsV|`&imijmF zpLenHUr*fsmEd_*(hh%Y#rs03pIaIA4_5xzi2fXZK=~uk1Mg4q_lYvSF>>UXTPBPj zIdRgc+b4}2X^b2+^um$W=-Wq+88>m#=-Y>0*!SiM<3|r2b=}RQ6Snd#Bd?z_YUB;$ z#*eyr+|<#=q)}tXjqDU0*{M@d509LfYRuJ)xqf43&Dhy*%+ri{eq+97%=a4$G-H9^ z*hMpT@f!;@W1-*JRWo+=8H1gaG1$p()I1an`i+{0f_@JLH4g>-9tvt63i>@1)I1dQ zdnl-RDCqZ4Q1ejG@1daPp`hPGLCr%!zlU-)59Rtjl&g6t*YBZR%|p3<59Mke%Jq9F zSMyM=-$S{YhjRTM%GErS>-SKu=Am4_hjKL!<@!B@H*v{zlk4{o{#k^iv9sSpoiz`2 z_Is$a=Aq7h4|Uc&)Y>g@MWXU#*M{T}M9d8o7BL!C7b zb@qEGPxDZo-$Qwthw}U$%F{fQ=l4*a=Ak^lhw?NJ<@r67r+FyP@1Z=+LwSA=y^H84OLwTBq^86mk*F2Q(_YnSFgyaOv_j@Q`^H9FuL;0GA^8Fsl*F2P;;-Osa z>QEZi_dXFJ>nsiXjj~Q*OsP{u$T~~I{+x1DgfV4QM1&lb(y%|L92H?q85I#BN2N6E z&nZVm7*j?C5y`7VY1o%DC`UyYQ$|HZXdX(vItZiYq13B`Flru3y*db^=AqQ9gD`3y zO1(M=qvoO1tAj9V9!kAB2&3kq)T;xG$*V(Y*yo|-)j=5j9!g#vgfV5_iU`d^saFSK z)I5}Wbr43)L#bB>Vbna7dUX&+%|oeI2VvAalzMd#M$JR1R|goASBKKD&qK+pgE0C% zl)O3!qu)cxtAjB5S6TAvAdLQ%oxC~-qkokpuMWbPviFGy%|oeI2VvAalzMd#M$JR1 zR|goASBKKD&qK+pgE0C%l)O3!qu)cxtAjB5J(RpU2&3Oa$*Y4f`aP7qItZiRL&>Xy zF#7kQL84M4<)Y-!sz!< zzP8Hp{T|BKR$0E^L;2bq%J+LHUzf-lMq2{4NzlRDn4;A`7RH%8V(C?u_%|nHL4;5-2D)f7(Q1eis z-$R9(hYI~3D%3nw==V^e=AlBrhYB?h75Y8YRr63+zlXYN9_s4%P*=@EUHu-yd;a7E z>+1JVSIt9R{T}M7d8n)3LtQlwb@h9wtLCAueh+okJk-_ip{|;Ty81j6?4&$|aOzGS zOg?eR9f`2ts5}(xJ1Gw#?8~X0se`FcT;LV$OpUNVr{*F5nL4PQsS)<))I8)rQwOy(HNyU!nuq*n z>Y#R}M%bTI^N{~c9n{X$2>WtsXX;?;6Bl?$J5wX<IHf2IyALkpD~_)Xvlh`*Ug@@}H@L+L;<*e@@Lq{xfw@J5wX<%c-5IgQ-tk z;34fyjj%tb<{|%?I;fqg5%%ZQJmf!92emUb!v36^hx}*ipmwH4*q>ALkpD~_)Xvlh z`*Lb$>Y)Ej9n{X$2>Wwt9`c{5gW8!IVSi4|L;f>$P&-p2?9Zur$bY5|YG-PM{W&!c z`Onlr?M#iZFQ;~<4*Jj3LG4V9us^5fA^({=sGX@1_UF_*DKrbgJGQ}dAjOdZtD)Ci~M%+=1+2>Xrdt|Qlfrq0!#QzPup zsm|27{xfy1_M94Fe@=C#&h?+EbG7Hx2>WxYGj*>2Or5Jer$*SHQ=O@E{b%Z2?M#iZ zFQ;~<&h?+EbG7Hx2>Wwt9`c{5bG7Hx2>Wwt9`c{5bG7Hx2>Wwt9`c{5bG7Hx2>Wwt z9`c{5bG0)y!oHl^nL5{hrq0!#QzPupsd>nMrq0!#QzPupsd>nMrq0!#QzPupsd>nM zrq0!#QzPupsd>nMrq0#Q)Cl`>YG>+P|Cu^hdrpn8Kd0s)|Cu^hdrpn8Kd0s)|Cu^h zdrpn8p0hLFYe~&a!)7? z`#hA~6NJ(4q2!(*jD8O#@3V!`@1f+LAdLQ1mb}jv#+0*(h|oM#W=}}oXN!dXRhE2r zC5$P%rijoylzN{HWAZ+`H0<+G@;+M_{T@obyAnpfhm!Z%!sz!<^4*m%`aP7q&lbiM z59MK#kSn`1thZJ~$dz3h_8aBA6~>f0MTDHUrD1Ul^+$g4wX*q>ALQ0m?%QfnSc-TQ=5^HA#ECybhhQujV#)I5~B z_vNFXvO%R`y|p4jHmEf0H_8SHW6F?;2-%?0us^44kT9kUnTU`>RvPx_ltU(rDMKbA zhR(YEDQU6=Br+nR?L?My;Qz7abUr z*Ok(+ub;{5iZG_^2_i!4XXq^R{!y0@2t#=fl#qd8TeoBb%g)z|mZ3bz>ACeyR*x?`UsFzZ zdeXA0xBh{{LzxHqx7T|jF$Z1OHW$CXvtSqdeRC;OMVQdC#_(#& z(hAm={D4kRTEW_qum1F;6|61!ah;yDg0&@I3+hQLSX=TXp_Vk|U7;Rdc5S7+Inn((?Q&;(e>2G^&D9eXBquEzhqa-nR-$qslMUe2vO|#axJz$X*&#@IB&jDYI|M1u$@HXU zhalytnVz)l5S05U0p0RHN+^vg->?2h2_k8E8}Zwy>`f#sJ6h!~ZjrR?XqCIT zMbfgPRqo;zNz0B_xr}Zv{xJA;kqgC$WMpFOcE{!UGwET-(B&}ey z{EJ&8E$@^e;>(U!xz7nj(z2sf?sGzswCre=`Z%9JIyBPK~XJjl4zcBkwsGD+%Sr0gd$ zN$Oyv>?1Ns>R_boA2LbmV5ICDGD+%Sr0f?mNve-i_6eCJ)paTR1Cz*AoK(vWfLy&Y zNjZ~Lu3DKyKflVjRKKLGRGB2zFDWZDkz}%UtAFV+s!X#J@hPLus0xy%3~eH5*={7_ zQ@X;a3QA4sQX;8-4A;ArGUSP*W!GRLK4s_`RY3#%%Pf()+@(g7zQAQ_|B@?>PhED5 zD!&=>6rlAtm%J)F(N-s^Ca=q4uAa%tjl9pZdiTJX9O}Sp{rIz(;IlDlj z)Utk+yTQ%luDia�eb=i~)lO_31k@w?nW4{%vFN!#`z(U)ulv?|&Znp9lWuf&Y2n ze;)Xs2ma@Q|4%)TILU0oziW(tI<)jRvDvsP;*|3#;>54b>*)sm8DOJ58F(Y1JETXN zs}u2I(k30!B|Xx7kLgK^v`LrrNOKL-lNM={F6oix+C=&sGE7>eO**89{~cw~&z$#J z4{4D$>5wkzkvSWgkF-c*ECM}|p@ zv`KSUB3+oYNSky>m-I;U6PEv3f)?qJF6ogr{{7+7c9I@xKA4ElA;Y9aI;2Z_q*5?94&Stwvi?m6H^homw)5=AB%tumo(=vJsBn~(ji^aBh3=Fi?m3abV!dhpJP2_n6ycUbV-lQnag@ei?m6X z^hoo0)(k30!B~6Fv z$uMb=4(XB}X)b2FNQ<;dhxADECDucRNt<*?m-NV-C9H?ENSky?k2IIE9?~Lh(ji^a ze3|LVFlmtv>5?94zQTNDn6yZnbV-jimoXn{kv8d&E@>`jdNNE}q(i!-N1CrD@`Xu@ zv`L5bNb@z;LxxG4bV!%<$eh<%4{4D$>5?94zQKA(i?m6HbV>6~rYFOsMLMKQdZhUl z+eKQWO**7Uns2inGECZ}L%O6#=B!{nq($1KOM0aF4(lN;(k30!B|Xyo5A%^>(k30! zB|S3dUAB+3NSky?k2F`Z9?~Lh(ji^aT*dTcn6yZTbV-jiSF>HDMcSl8dZhUt>mkFW zO**7YdSuQT)*y`LxxG4bV!%<$eeAghqOqW zbV-jiKVUtiMcSl8x}^Cb)01J+A|28tJ<{CHc99lolMd;T=0~iD43idVlMd;U<__i~ z!=yzzq)U3F`7!g6Vbb|D5$}=aXG}+iNsF{ehjdAgG(S(|4}X=QO**7YdZf9B^^sxH zB5l$kbM_|ETck}oq)U3F8E5&VMcSkz`CTHNN9OEL=wZ?#UHtEIiu-5?9q^9I{TTBJ?7q(_=>vL4bR zZPFoK(tL~Q$uMb=4(XB}X}-;Nkrru_4(XBR3f4o0Nt<*?m-NV-cUTW;kv8d)9%=rE z^^g{6lMd;U=DSQ!hDnQbNSE|Tb0ynFTBJ=nq(_>oSPvN{ZPFoK(j(2)%tu# z9nvK|(u}cPq($1KLwcmSf%TAK(k30!B|S3debz%-q)ob{N17X14{4D$>5wjIx=c@o zNsDwym-I+;6Wc{vq)j@cN1B^i4;dyc(k30!CCx3&M}|p@bV!%me=DCLPix&FxH2hDnQbNSE|T^CPy4v`CwD zNRKpkupTl@+N49eq(|m_%z8+Rv`LrrNOLFaAuZA-9nvMuT})4gNsDwym-I;U6Xqks zq($1KOM0aFDf5vQX_F4=lICYjPlid0bV!%4(XB} zne!#YSNSky>mo&d(dNNE}q(i!-N1A)sF47`x(jh(4{F?QUVbUfY z(j`4I=fA9nv`CwDNslzYVLhZp+N49eq(_?HG9MWxZPFoK(j#;BvVEjQ+N4W*q#0*D zq($1KL%O87kLk%UX^{@;k{)S($99nxX_F4=k>-BZLxxG4bV!%<$Q+OLkQQl^F6oix z0oFrWq)j@cOPU9no(z)~>5wkzk>(+`i?m3abV!dh53?RJOxmPFx}-7v`Ft5?SHa-(jslr zAzjiV&A*tR43qAOM7;Sg?PQp=NSky>m-I;UB=eKDk(qdpPkN-8mWaq%#{cJsBn~(k30!CC#RZd|}ceZPFoK(j(1gtgm^3 z7U_^K>5<`9iF7vUkS^(wW^0y9hDoPwBHkm-c1%ZxNsF{ehcr7R(uYZlv`L3_Nslx; zvYudq7U_^K>5)14Oh?+JL%O6#nguMMw7MpAhjdAgG`lf9873{#!T&zAc#h_gW>2Ok z!=y#pq(i!)M0&G#f??7kZPE*~+xXqMbJBkS^(w=J~9L43o}< ziFl7RFJd|}Oj@K(I;1-!k>0!{!7yo&wu~Q5wjIzRG-L zn6yZnbV!#pUt>NpOj@K(I;2aQuQMMRCN0TT3A;nOq(_>onV$@kHtCQq>5=Ap%twYv zi?m6HbV-ji*Dyb6kv8d&uH@!KdUFf&kzvvzZPFn<(%i~?WSF!_n{-H*^hk3X^OIrH zB5l$kUDEqM_U;4Dv#Ln+_&qKH~5Dk_QrTxH(9Q@`8O|7M0a?!KM(M*r;xzkSZB zs&nq?)At{`X9ne8S^s%uLq$W!z{Kub3un{{JDMMK9#`3`y5P|?s)e$4t% z(J?Slep2y@j)95tQ`UhE6%7LuV5027eAv*?F)&f~Bo7SIGiL&w0x z?f~XNL&v~GIgt6Vp`wl6wBiC2=r6c*OZ2V ziQU>7_l;$u98&EL8!8$)1}4g_$VYF~N4X>8*ig~XF)&f?L_RiDG;|D1lsl7;4HW|u z#2Fg9Di-v)T?OxP5q70P#l8+4)4FeP9e&k_8NBy%JcTAKAlZOoz9TVjt z#A8FnKz~%lCCa18Lq$W!z(jcrdDze}FtK}V#Wz$m3`~^AQ6C%X*nd=wD;hc`%G0QW z4HXR?1LbJei;9kciE<3_sA%XIm?+1Qhl+-QiSk^o2OBCHIws2TTjrM=opwNf6aQ(&@nJk{s;4*qG4k9>WWh|bWD`LVSa3=Xy_Q&{VnT2MMK9# zc@6WRVZ6Tj#TmzjhK_-W@&@v-p<-a7oJu@4R5WyyH&%RN_oiygo6CmXTdJ+t-db%# zeOt91?d{bL^mkM{N8efP?p>w5hj>hs_Y#K<{e9J+DDNi@8!E~NYP_MMp?sKeR5Wx9 zOq7o>FZ#!;ohYAR92+VcI>zYfl_xSIGg$H2tytCiPKQO>0w6%8E&6T5Gchl++ij%URg zItC`ncPp+#L&v~G`Ci5Q56eXP5p}SkqG6(3Ks+{7l%LgjLq$W!z{K|R%2PCSjB)(e z73Ub3C>OInZ0H!6D3=hA`a9}lV4_?~JT_D`bPSYTuCV!aZbL;w$G}99%ImP9qVHbg ziLwXr*ig~XF)&f~WSv(o4IKj$sSMZ>^ExhD0op`xK3 zDjO;qItC_oPa_W%{TbDtD9>abY^Z4Hm?+O85B1n;I|e4oal~UoMaRIz?u5!yG;|D1 zloOc;6%8HpB;sCFHdHip3{31!CJzz8tvq{08JH-qq&_xOG<59# zw&E2H9Rm~PHPpw3_7AKF6XhR?$A*fAfr)ZT<+V4IhK_-Waw_v+Lqo?vc`Nl%(a7;e312^qM>78qI`%vR5Xl_)wq0| zbzwtAL&re*1bNsng1TogjtvzZ0~6)U%Ck?Gfr;|3)I~)@$3Xd9#Wz$mbWD`9sE>+< zj`>C6zC?XgGz?6XFB6Z7hVnJWQPI#bQO;o<*f7qme)%Tj*ig|iFj3B99a$PW1}1jj zB_0(W0~5O+R=lF2W1#$~;yP?-=osVpPgyTI1}1hFvR+g)lwUB8iiVDf@=Ml<4ddeK zmrEGOhKi1XiSirPacODj7?{{?A|4eT19KeTW%tdmpB)1eMQXgEqM>8Ad&MalItI!f z71v=y#k?ZpS7KgNGz?6XE0c%5Pqh=}s*GbpL&v~Gy+-9Z1}4fiYrLVNp<{QQic>Un z43z7#PHd=XH>mNzMA?r#Y^Z4H`&V3|bmU<}MMEFQZ&LAwj)94CQ|e+vMaRHIyJh7C zCdw-6VM9ej$3&Tuhiy%@4IKj$Wi5HwP&ZV+V_>3eBo7-Z%57`Bp`xK2Ky{LnVhK_-W@~7luyHB+Z9Rm~P z2=cIDK7jrQmJJmR9Rm~PLFA#Lp+C6B6XhYyhYb}C9pj-DFMmNEHdHip3``~O5oJR~ zL&v}z+mB)X$5ICyDjGTlCd%W;e`2X<=opwNPa+T7Q>ty~7?>zeB@Y|sG4wyZY^dlM zm?+O64;uz1$}=lYQI2CCR5T1sl;<)JHdIWM{#G;~aq7m|++6%FMi;;^BQ z?U&TJp<|%DlzeQcXz19ztl}Fg#@POw8g~p#?EaQ~R5Wx9Y_F+!MZ+B1r_^|0qP&iI zP|?saFi~G$d4`VS)$eaE6Xh+{?oiRtF)&fy$~@>8*uAaB54Um?*y^9~&wf zItC`nrQ~BnMaRIzZWDRm-D5KRIktv|j)95ty^8O!p`l}vkx;Ej)8Jr z=0`=tz{Ku))I~$bM7ch3sOT6dH(-8LGz?7a_MF;N~t94Z<*Cdwl#-kw}KCdyw@4;v~P zItC`nQ^?1LhK_;qRMvxzfpR4Eu%V%&KDXi=0~6(V>R>}f$3QXSQPD6kv3p*{H#Bri zloN4Ffg%uK6TO1G2U9^@;2&XLq$W!KzTcPsAw3N*u8`GprK=;ypuRo zbPSYtF+VCA1}1jzrY;&fCdzw=Lq*3xc`x&$qG4cScN%rk&@oZoM;t0T2Fm-H9~BJ) z6T5$+E*d%}$_I!;MaMw-XXZym!@$JugVaSs$3*!Maj57RC?95iR5Wyyk5La54ISm< z6&L?f%IVa{hKh!P{>h3@luwb54HXR?1Lf0|=bxb-%4eyE4HXR?<#WViLmT_QSmTO@ zj)95tCF-G}W1xJw;^dsNp`xKMhYb}C9Rm|( z4f)tm(J?TwTT9-p%7%uHfr)Z!^01+zVWQlIcvSQ|RDYl};;^Bjp<`g8+_CZ%4IOjz z?iDBZC>tsoItC`nJy|CzeBOe!3O+GeM^wF0yFUl*(!-k56j)95tO7gLxqL03o zc~Sn3JZz|F=opwNe@{L(RP<42UX(YGhYb}C9Rm~PRPwQ*qL1V6thk1Tj)95tF6v@K zMMKBHM0q#!p`u}6qP&NAln*gKDjGTlCd!A&!-k56j)95YM_30cItC_oAFcQ}vrOzh zNgY%)bPP^b4ILBZOXQ)V zp<|By=T^L9qI{D&*ig~XF)&fiBOeSTZiaz%Lu*MY~0~6&(%#RHf4IKj$ zaxbhn+ItC_omsEVLxZ>v5n~B}Z zYBy9gbPP7s{a31Z$3(d@b+DnLp<`g8T!nmWsOT7&*zH|; z4HbRt|C1V5bPP@yQBiJ8KPnnJ1}4e@78Vt4<_Z>Z=PnAkm_;{D-epeXCWhKh!cfr;`6^0A?!p<`g8 zJd%8DsOT7&*gdN98Y(&lCU%dm_;_-e*!?ASP|?saFj1aTc^x)XG;~aqr;>+?hK@P5 zpH=aJ@@(?4p`xK!3Re22+4P)$oe#IFECdvz#9~&wfItC`n3(3cZ zhK_-967ks3P+!J+F)&eHPChnNG;|D1lvh-KLq)^DM0q9g*u9oE8af6h%HOeGY-s2x ze@`4XG)%8?c?0vKqM>78qMS+|DjFur8(9Y`$~)*sMMKBHM0qE9sA%XY?;;Kx8tR8@ z+%PavK0-b=R5T1sl#f=PqM>7AcSglEG;|D1lrvcmHdHiplur_m4Q*_HmUW_IV4{4E zI@nOr&@nKvoy9z87^7dQ@x<=zYBy9gbPP#MlaGduf%1cjv!AgJOq8Ef2OBCHItC`nMdYKRVWRwkI8-!r%(4G>tQQmIQtDts zMMKBHMA<|>DjFur&6Wd;ur)U_M zSF3T^mvy0{p<`g8T%C1cLq)^DM7aj*LPN*I))9w}fr)Zs)`1Nb4IKj$y8|k}p<-a7 z97r6>EtwY;4IKj$WfghY(9khZro>}I$H2sHq2lEb@=(#xF)&eXMIJUZbPSYR6ORoY z0~5R3u)aHzhl+-dfr)Y_^01+yW1!rbcx>nxnAqK=;@jb+qGMp9+?)E?P|+|jQSQS$ zsA!ldM^GOX0dP|?saFi{>x9x56JCd$JrUeVAoQ667$9V!|+1}4fA$is$) zj)95tMDnnqV_;(UB(CG=(l9Vlj-f6#R5Wx7=oIoBLItI##71v%|Dmn%x%1fw=4HXRo6Xm7kVM9g7z{K`4)`f4Zp82t%qG4d7IC_q-D4(sk4jU>u26mrg9#r(vFV%RUe3|;#P|?saP`*MQ z8af8b*%c?}5|4_8j)95tP4ZCDFj3AU4t4Z<)o&P>DBmX!8!8$GCbsh{Pth<&e^TR# z-A}9CP|?saFtNLkJai09?0!~p{_`?WE~<8i@ylu_%CD;3P|?uG{!1#(&@r+5O^qx1 z*!~@P=$I&%)_8{vWyO{2bs9D_43w1>*HCsP4;vaf2Ie@vd*wL>${y6ihKh1U#<8KH zV_=TsS7AO3l)b5k4He~TjAKJX$G{xNufcp6DA%MOHdK^rGmZ@n9RqV5zaH~ppj@AN z*igs*8`gM3MaRVMMir;nZcG~u1LXkfqK)mFkcWnWiE`75>o9I!?L;}4`lx8=7YUV>(!+fY{=;Qc$=0n54MA^W67>6()%B`3W6%BnHzb*5jVPK*h%6yo& ztG3*pepGbKar_R%--&o^Xc#DWuDFJBH}bHdp<`f<b z(9lutOFdLH3`}efsCY%kKzShbP##Ph8!8$GCUy_0yoNUV@alIAOcZ54Y-s2hnAkm{ z@)QkY?0;O18#)Fi%Hu1pp`xK=P=K)I4T+j=IF`P z{cG~Dp`v4;{14($(J(NvdvV1#G;~aiS5#c0ypnmap`l}7V)rWMLmU0O>URuGl)onr z6%8E|Fj3x4JT_Ex3`~@FkcSQ9 z!__YzVH_JO8agJ*N6Ev6iiYu7=J_1)*ig~XF;UJU4;v~P%I7Ptp`xK_v?u*QaijIMa-Is_*MZ>^E`7-OmhK7!T@)hE-p`l}7j{O%`UZPw= z9c-v*7?>!(ArBiW8af8%*uL#mHoqQ{L(2{uDjGT_%3@$w%FP@6F$Lj)95N)p&;u4IKj$<;LV;Lq$W!z(hHKe6%}MJ1|ii zaoAANF)&f?NFFv+G;|D1?9Q!xMMKBHMEPdLH&irq3`~^sSSL1AbPP;v-(r1e7?>#E zW?iUg7?>#EAs!VC0}~~QM@7THMENf9sAyyRM*Gxx#lS?_zs5UkXy_Q2C>?p&P|?sa zFi~zyJ~mV|bj(K)|LC%zqM>7;Jcc}MsA%XIm?)1W9~&wfItC`n2@jXZ3qXy};O9bI`16%8E&^O?-^Eb>s%&@nJko=rZsv3)}ID;hcmCUz$> zKPnnJ1}4h$nI9V}ItC`n3&_KU@-o(eiiVDX@^b26Lq$W!z(jck^P!@lW1_s0`LLm) zjpMJWI7LIpz{KvgtOFGt0~76(iVsYb*ReiqXy_OyuO}Yc=-aB_&@nJk-d=GH6%8E& z6XhM`p`xK!}sl0}Uj)95tSImR$<<&NH3`~?)Fb^skItC`nE13@!4ILBZ zRm5XML&rdQHSyR+Ppy7K$G}8+W5qR8G;|Dq?7f1-Sk`q+Lz9vV6Z=Ggur^)P-!8{-1n=oeNy zP<~eJ4jU>OI>y-kId!o6MYS6$`mcz?MEP~~>+ecK$G}9nwBkB!Xy_Q2*lnsjnOv=& zXQQsHwxMI7?os28fr+vw^{}C$V_>4}MII`~KGmNnS0xS`DjGT_%GJojhBmgZQ{#$; zj)94CUFxBtp<|$2ui_gT`u^1)m?$0fv7w@2V4~cZJXG|XFb^imO^L^biZ+g~tGI@W zhK_-WvYtFtG;~btHdMT#V`8_Fadfmps^3v=UF{AV`faK|Fvs@ot3OfhKt47!43t)J z4GrT?)I+&5^)T;RZMhr$*ig~$QR9J$a!>LPCm$Os+Svbqic>Un3`~>7AcT~kI8af6h%F|dM zDjGTlCU!@&E{wmbwj4`6Y^Z4H7%0b)hYb}C0~6)B@L& zbPPmM(3`~?)GY={nItC`Tf2ce~L&v~G`A61=iiVDXatiTp zVtuG+=opwNZzc~F4ILA^w^V$*uS}HpSG&W8iiVDf@=xSpL&HG%K*cpQ43vLn9J|wL zqoSc>V4?(hsA%Yz*qu@FijIlhnKhoDDdn?ehYb}C9RuZaUePhJ`yu1#nArV@@n4pP zj)95ttBUKep`l}7V)tw2LC3`IV#d)iF0KAV*~I+VP|?saQ6~HHJictS4dn`qV?#wl z$H2sHcj}^|VPKB!t5kfV?9KexP|?saQT8DZ8yY(1wJT1pLp(NAG;|D<>yn2J6&(W; zyX#e+qNCiHde~6W&@nKvJD~C#DjEhR%7Lt7RcYuLm?%@$hYbxK0~5Oi)`g0WiQQ_} zv!3;!V_>3eU_IC{Z(aRz8^*DrqM>78j^3U+cc2b7R5Wx9Ol)_rd__aYz(lzR^I=0p z$HeZQ74P>c0~6&4>S04gL&q4sU*#pr{i%cc;A$H>1}4fw$is$)f%50XJ*sS|Xy_Q2 zD32x&6%8E&4Zo;*}Ebd0xFoV<;AY^Z4H7$|Qi z4;v~P1}4fo$isG8wG|B=0~6(a`j)95tQS#6*Fi}3nI?f;-6%8E& z6Xi_uP|+|yQ{(bk=D~)FhK_;qIqIXKV~l>e;u7U6%!dsX4ILBZZ1S+7p<`lqF6%=@ zL&v~G`6lzAj()594IN`_f2YO+6D6x(zDHebsH5jo9~}eR4{BV|&@nJke@H!a3`~?C zQTHdrqhnyA{FJz#myUsna#4+U7{9J|qFl^4HdHip%(4Bu$_q@COR0wq6%AwT-{tC? zUzZp<1}2JBT!#&9Z0}LyiiVDXiLxj4P*JWzKQ>e}bPP=F_OATgx0I_>4;v~PItI!$ zDle{0J(TNE4;v~PI_Btpl_xhO9~&wfItI#($Ul&LY^Z4H7?{`{RQYl9GEokuE;dv& zbj;CPRG!?DdMK-CqfBX|EL2<9l!lIh-TE4DsA!nCuJP_R#G#_0V_>4(w(=C?4%JSS zMty9kXy_Q&-I4X&gZgOb7?>#cWIi->3{33qMg7qus%_{Pm?-yU9&Bi%52|s;z(o0P z47?>z;ukj9b^fdA?Fj3w|9x56JCd&JX z|46Cm7?>y@t+21}4gx71yDnp<|+al6Y)r|Eu}~0`y%70=opwNUm_kA4FeP9%d8vo9NJ$m6%8E&9Rm|(FV>BUhK{)p^{-kg8af8b)riN2hK`A{FY(yWu3i0s zavkEZp`v48Vt3ujYiQ^gnAq)K@rsUtiPBLQ6%7LuyBiaaiiUZ!8t-n-{AlPHCk`rD7R%DsA%YzD2FmXDjGV< zorpt2$H2ty&cvglW1!rH^&6T8D%4;nfKCbkDuykTIXJdkyu zqM>7=Jc#*G(a=#IN*o$G1}1iYK|Crt2Fk-&FE&*4N7Z;@_h{;(qG4d7Jcf8wG<1x= ztT=fJ@u+C%nAkm)cr%lypwowli9Rua{#G#_0W1=|q(cV<;KzTFc*ig|hFj3yZI^JFyItI!+ zsE-Zxoz?FcXz!{1z(jd(^*2=PPOE;!_Wo)cI>y-lLF!|oe2Ds}=pU*6MEPj7J5-F1 zSHFCMacpR)r`Nb+V2=G~)OeztNj;2DR$D$rKQ@$qt^S6JHunFo8aH%|vH!C*9+)Vf ztA6=B^-M@2)&L^;3WJIo)_{t_zU*E_fT%{ zPoIABkq1m(eEP|!9Wc~A-#6z!v(N9Nj#ygb_zUDFpL)URpE&;ppZNEcE6)D>#YgUY z(o26kl>EYxd-h8{{N9_s&=)-EA;0ZwR<%dIc(|US(D_I7fybS`e_yw+bL@wPMNN)6 z=%nL+QER&D@fTci(|h;pC*Sn4p{p-+{;J+Hj~^meRMCE+L%kn7pdUDC-)`85#r?YI z(xLw8=l1oN?@=E%|CsNx%WohGOGprmKpoGOa4psxqxA)2cG9D$}Ymtt!*1vQSkPs>(uD zS*R)tRb`>7EL4?+s6B znyRv<4`vbL(MttxA)%G$olLhbxOKQ_>h4KUWvFtqv^ z2KpHW`WXiL8G44DALwTos4BzG53Q;)?EKKGD#OkXt*SEYeBT;&exRxhJ3q9l%CPf8 ztEvn;KeVdKu=7K!sth~dw}zb`s4BzG53Q;)?EKKGD#OkXt*SEYeBT;&exRxhJ3q9l z%CPf8tEvn;KeVdKu=7K!sth~dw}zb`s4BzG53Q=QwyLbHDr>9C+N!d)s;sLj>#EAS zs-^mvaYJEt19cN%KECZzN)ORD(kDt`l_#NH8s+6{vZ1PMs45$(%7&`4p{i`CDjTZG#;UThs%)$(8>`C3s8j0Dro&xh;oxbV-D#cOX`S8as?AlVb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9 zcBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfA zr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fx zb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9 zcBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfA zr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9cBgfAr*(Fxb#|w9b{FdGF4Wmw zsI$9JXLq5_?n0g2g*v+nb#@o(>@L*VU8u9WP-l0c&hA2;-Gw^43w3rE>g+Dm*`(I=c&Xb{FdGF4WmwsI$9J zXLn&ZyQ}-hj{f_0p#Sb4=)e01`tSaM{`+=-$o{*3X!YOy1O0b@&v5MnRb{yLp;c9e zYad!wWw`dCRaJ&-A6ivqxc0s^T>C&(8LoY3Rh8k|hgMY?u6<}#mEqd^)^P0uRb{yL zp;c9eYad!wg=-(aZ->sRGJN0mt>OE2psEbtw?nI{4BxjytFN-A--3Q@pdTApGdz>q z=SHjB{fAFhOiuX5Lx)fHK4jCS#}1!NCjBp3Zo0G|S#0lfqfM9g@yAZ~*mW3Rv2qvL zb+;?*K779QkJYO;_4zdm_4iv+pL(16iTGGC#Gg2M>!XME;=HV5#fmNKCH}JOUs`_~ z>wo^_;1kZ-^pKL4+-zvVnE?qC1)SzH(Ux7c1h zzt7lwX8)t-cX_>;{n>neulx9!{rNr5?_&LJtpE9w2kdoTKf&_2?LEJXdF;nxoB58L zJbgR&XUqPda>|zb$85b*PFZX(?*CUGIqc8&?f)sK%$(2u`+Ir4+5JD|loKcC95mEl zjN5!&r<`(m_m9Q(FRf4BVjb51{K+p5c<5H@*Z%kGo%vX{{-x)0tNVY-DaTFD-p>8G z?Ede1+LHa*#`=$)9QCM8n{UiB3!OLSJ22mY`3~%~JFwyp_+#5&l-b9Znfw1XA774~ z-~YG0q4SaX4$OC8C)|NQ;M@P!Uc3)qq07AgvE=^0vfjUW-RqXWemQn>q|TrJ?}P_@ zzU281%y(d$JMc$%|L^yre`r|p{_T?c|73h$mizzW|6k_$znp!@VT;fA`F*a%Ha`zuIr&1HOm;oyq5W66 zf4^u;{Or$*=kFKol-~vOMbCF&z60#Q;{9>_{mz;9$LGHvIX@`#9hmRHAIT2<5k5ce zzq0e+kNhJ!-t)_x@4$QqE@ub+2=D)k&;Q3iAGqZC|Kj@_%ikZF|9<4<9HRNqd=KjCM#{{PPUC7iE& zz60|e_`k6OJNh~Ij+}4X`!oOj|84Khd}O`@^BwqO*?}E-Ki<)EZTo9Dd;cHa-&y|i z+{HG39{9w`OK&mMTi(CD@9!+nTWl}Bzq8%{e$3+Qm-(Mx*!EX=J~H2d`40Ty@4$|J zOxcn1ZTqV?`}2uixBt&CtepRL>b7@vJ~H2d`3~%yJFp|~%fnokze}_C=ilScFRa{= z*Rl0$m_I^neP8Ci^BtJ)z|Ok^JMzxDqvu-wRay4<^M8DQYxwuo|Lre_DvR$+@%Myo z<^8Qb>c6!9<-NbP`1?nT>*W2jV<%6Y|NYg=kHNe>-+}oK?9@B3qaR6jY<*wmz4INI@4(Kx13UUIyCdgY{#9A_`1gPH{jJrj``P*lhQB5Jgl{}_ z_+)8)ejjX8{|{*{`B?G%$!}x7zGLxyDdJYHnC!Fq==<%nBzE!rt;PC#FZum5@)qkX zzQ6U=M-DYstlUL*-R%myFR8cu)0%JdEUbTNed;aNXTIYmXaC3RFWsMQ)c<{ce{S=B zEnWXkRe$yBO{?4em;U?PlWQHaY55mv$@y6^#Gg1hYx8rn<$vyTdER8Q^VjdMY30oR z^yhQ=buZbUVGCA1Z}Rp_hEK-#qgSmtc-5-4lg+Fv))yO!jhmUSDyGFkvAS4ORF!F8 zWo=)x4;kn~2KtbJK4gH9exjk(Pc+a^)H6&pQ0dc3pH}*`(x;U-t-OUwSm;;Q=Pgv; zLM1G$o#>+<{^X~v+i%shpJ6)FT9|3Ao@uR_Y0XwyH#4?=rnOp;$Im_I?TeG_-p??Z>^9kb za?QyNCO4T}YjI>kM&Ggc{OG~^9JcuQ!1I;GHqSTu`EN9N@U@R#x%K&1)`}*(UHjN! zrvCT;cbOc-iWd5g!~4Jb;9BEzq9I~3dFyBT|I_}zPYtatA6waHJlbuXd9>R&^Juqm z=Fx8B%p>o{nMdA@Gi%v6vzCop)-t^G*fQVH+A`nJ+A?3gNEz=ILu<=?Lu<=?Lu<=? zLu+QfCC|e9u_e#Dht|yOOP+TRV_U9vXwA&tzaCk#vi@bs($>uEOP;UyRhB$oA6hdz zvE*6!Ft%le_5BrXi5yy6Rz0+~?Ag%Tvg)C=Wz|D#w&s>q4`W+a-M5zP+0fc@UWV4p zTKXN_^3i|)@cz%Kr}F;Eh9$30H$VS4_0(mrPgk5UdF6d3hwb%&u}=Ml@TsTnB8Ppv z?;D;+41YiQ;`>9x=iB(W?Bny^Oa49PZN5MBgJ*1`-m>og{exxy{@u*`TRfjya(yd? z_!B4R95fUfpCk28-!@&^_m8i~mrQcm^)G$@W*h5&{^Y0w&f7};{{6H5qkq0O^RevD zZ*JH7Tjy{0{#@q%xoSI~->uq|du{#s=jA=$ow>5UaoPP_*v{u?3+Mdg3R|E5nv=a} zzjBA(cKNhpdn=D0+kgGXUe5LFHlFW~6Jvey)|Ht=Vx3c~v_m8pu^7WrE z`OZ%d8z$gm#fn-X_m8oA@%k1!F7wG&=I_7%#@9>Rn*aHemG9oKueCgGd-rd7-q_x< zfBT;^EcHM7{`K;DV|%=w<0dznsXsoJ4fpyr!^DdpwLe31et+M*Df9dL_TS(BYwquD zJMZu9D&OAj*ALsg$!nZ`Y{_e!%eH1-xh(ma#1J{NmL;!-hOzaNyB>bT9q-V;PMI!# zwy^lw>c!92EPl3j@w0V{pKYnK;lKAUsm78U7C+nAPqn2ne%8MlBD8<)Gk&%>Xa5*E z_ASoY@8sCGIA_0uW8cQ{v;Gwzef>{s#?Kb(^*b{5jrH!=4qvhd)f#J5Ys{|JSfN_8 zRmPRo*toiCE!hYAOxQ zR~*9o_LX{8^<#h1d(b;qPOj5C{J`eg{eL&_+t;Q2%S$&s>4AOnu6^5|F#IrYGTHaQ z$z;#oZ}#=}>fO8lZ}`=xV?I8aT($Rqvv(!nmJ?OFUia(Au8pE1Dh5!%9ckAVH7d4< ziaR&&QeUvWnTL?b97vMB-rO3yjTNp9Vw>Q7R6 z_w~E?Cg0b6bMOD^)T#ee{dKC6oBIa359XTm%C|3FwT;Tt=iBI&eYl8TU-5aRuAtWo zZb%<^9tV++=m_v z6{G#7Vn3nq*Vvz-^)Y`x_QYejspa2EJJJ4U>A$i6lJA?=`Pr&Y+8kNz=lh>opW*7| zsQ7R4FZ)$hKaW*AdhwrCXxd-(@nw%!j-Ll`bpt=lLUD}g!_)cG<>iMAu3UVh<@bM# zpNp2?{*?1G+Mh-GY3MUENc;aMF9vi{)jik#bykSxuZU0D_0Mc#Y%_n=?q4?TyY<=M zzB#`*?05NnnwtMpVSgWvBpsv;YKPQ6zvApL`edG8(P{1A9oQm0%|cfB3of64@|?c~ zpIW1iq*qsYEqKLr_Lj@1guC)Tu0Q;AKmTJ;KD$l*Gr0apaGU?F_ygrL{yvNA*Mj@j zAAZiwU&en!{V^!trv1_9as5hgSN}-}=l*3oxPJs+!1lG^yq2pTS^EiR`z}2EqPu@{ z`553UyMB2rH_y~(cYfPapXYXc(V8D(oJE@cv#h^_|6zXLm%bHb;b(5=civ0lgS*bv z(th)M@Z|>mBOJ}osonM>d@OOQ^i7eT)ZR z#kdCe%IbHt_MS%%`kl$C(GTgpxxZ!3Zw~#S{h>j>iNRw3uey$G&yRfH*W`aH)=y>k zsegZXS^PKk`&vEqJN-J=$M73&{o?#L7QAe;al-nizKQiaA{^;=BIOOU^1Kc~JQylngtpF{qh zT_+vyS@}Dr=K4MLE&lEr^+cO-`Yh9r@43e>>zfwbW`fJ7gtL8Dej0thLEi}H{U_Uz z`S$~VecKNDb8s8|dG!9>^vA{xe>Q{qWAf+JpGPele?;P-KTv=6>#0A%57(&da<`=u z^Z1SlcjX_fKk7$r{owKu;cVZfKPf2B_QM}z{fPzl$*;D9{;a=K`TY!c{427hnp(BHT{V@I98rB3$hlm*F{+2q~tLG0>KmQ)rkx!ra-Oh+#*ZLabH}(9#eFgZxt-*iS z`eurMPyM-#!QVSN#;bw9rB3!{P=DUpkxw7}*J3iTHmbm|DF}#{~&|^uJz42|LXQ-?hG3=l^{x!2c}`{=3#U>-@(n z!2c}_{=3#UQ~Xn7D*2;%eavxvr^ELPCvCr;|1Z6N1^Um;jsDZMzJ~r|^6$8Q)ZzMM zou5hDpZfg&11r#fZf5kKuJtwapQ-2ngDb%QO%49L);Cl9*Y&y8_1l{m{C%inyc+mh z>SV93Z&Tm@|EnXPmHE3>{0=nY*R{Te_)R_k|GfhIA7Jp`wZ2*B|M(T)e}9AjuJz3n z|I`>C{kXBg--kQKtAW3zPWEO{|4-=1r%(KDWW=v)eGT!Odj0>%3h=+5!GG8K#`v#~ zUz2~w`n|*bnJYiOTIDbM8vLEuF~w#P0@1{JPfH5WlJC|C1}g|Md<2yVf`B{C{c%_`jaPf7kkEihpWMML*2z zQ;zk^>c0N?=@sZddl~(wYkdv<$K>C!ei^Pm<{U1=^P}qhzt#Hpx<>pz)3Lub#DA%) zy~_AC=U>P8o&NoYJq`XpyUhG|vNwbI=jS@|S?PbR#?N((_;szXVf>i=-=UwYd;jP2 zE5QG?4gR~i@M2{=U#LUJd*$b+R{u`t!w(eER6m9!C7S*4Gffsn?(XSpoj9 zY4G2*zFFu0e^-G2YZ&}@t#8)(|GyRBe|LlbuJz42|6f`G{?{A)cdc)x_@~DB%%4{` z`1^9lcs201)XClq=09KQ$fr;Iu4crqYkdvzoBI4GSpoicGx+aX->mch)fM1>SA+kq z_02l}Ut0nGcQN?yTHmbm|MeB%e`kaLuJz42|KC^v{&zC??^@qX@lTDZff72to-;J<5qv(EqbR)GJt z2LD~_n<@UOF+Tde#^CS!9plx&-%=-gGdTbLpd+6?@mnzB*R{Te_)Y!%d-4kKuMGaX z);H_?|8NEP-*#_eQGWlTYkf1tKQ+cjKdv(P`%%YuHSo98$=(d=|BpNJ=@Y+y8u9B| zUqk$+UjKix0{s8O;J<5qv(EodSAhR34gR~;5kiYR#4gOB= z7_SEYmO9y+!T$g2j(k?~r&jU%ixI!B^)hmch+ZEvd0)zjq_02l}=?d_FzQKRj`evQ~->m@u=NbHWt#8)(KXV26|Fgk=*ZO9P ze`<_R{&=pz-&q~w)xh6UCwtSL|9kTPCxidrFEjt0>`goWb^n+C(2-A{@pFz5zpnK) zjGyURe|h%*KN|d<-7#Jb{4I5|SMNX5#ed!Zr9XD$)2IKRZN#r@eGT!Odj8K@0sjAB z@ZYt*nc}~$Kj!r>$Mv1*|Ni6ejrjkmV}EOi|57J=b^S5UyuSm%G~ z+>ZUhNB_?<`d`=j8v5VV>;Ioufd4ZM{=3#UQ~Xn7eERS24F1mR7_SEYmO9z1kKgI) z|DOD(2LIiRkL`t!GreEP)iR3m;}>uZSLbn)-m|9@rhcS*;1HSo98$=(e1 z|4Tda>C^vzX~eHzn8u(l4WUt}n5jV}!|F^ASpgb0~s*@K3dV7`5KO=bCRb*k!g4%t<^B%f;{%Q7qeS9r1KY4vw zE#kjve;N8`)*jQo$&bT+hxi*i*Mo7u1pwa`SZ2c(cwpFHYHvK4pzM zr1+rnx|ZH2gda(-uJXYza=cPBd&}iD;ZFwT)i2kmO}4`H8JCX)x7Ba9kN>uMaQnhv zHMEcHBmXp&NB*UPH~A+a8*?%9?^NucCLH;vPQ(61g8TZHPzpQ`#7T2!{ckyG6FIWFnDfTZC-09!% zuzv}aclpOYX(|u-5!_aPoA!lgV*fPZ$Uk)!_Ae6L*T00y!~XSq?4Kqa@+Y{re}BOK zg@i-?&c^;lf_wW%VgDk*ef>+QJml|u?4Kqa@+Y{jf8hn#KTSB~??UWfB)G4C36+QZ zU4;G9ghT!W_wkQ&((o_t{F(6>;Mtt}SKPjkaKwK?IOp%SgY5?wV_Xvs`4QZQAFedSv@kR37o45RTdxUOlhBYMbA){kQ>F>l^qH+{TaDKCY{JWcmB< z4ecZQsC_AwNBv6+?(1K24eVb?IPytDDx_D>TI`MV+ZFB06_zX1D} zkbUHzrt*+K!M*+42m7Z9NB*gOv44@^zWyat9`?Weuz#9x$e-Z8{)IQf{%OJ?e>cYd zMS}bKmr!}g-~QM?O*rIFa9{tz1F(OZaLC_**uO|{U;h#+5Ba+Z_D>TI`4im7zij{g zrtbVb+kXdmmcQSup?!oS{u9FC{`<`_t_g?y2=2oVw=cN`ZeK_^YM;6#_Ae6L+dnD~ z``4|of0}T}pWwd!g$H5(G~tlHTVwws!F~Nps66EFVC5T zUnIDQ*TPjGMlZioHTgd_jd?XiE6;J*GPR37%fJ7E7b;gCPUefQe=j$lfR0f2=2pAmcLVZ)IN1MZeL0`>R(!LU;o1UVE;7Xh<|lo>|Z3fuYU=Zhy2|S z`=<#<{H20>`*#HPFC-lDcYo|(B)GSKR37s80PLS89P%f)uYchKv45Iy$lrsof05w6 z{v}i%^7mlupC%mgC%CVF;X|;0nsCV9L$QC6;J*GPR37qoB=%1e4*3(@*T3*#*gs7; z`TG~_pC%mgC%CtNkHG$gghT!wiT#TN_w_IQSL|Ox_K|;@%0vDH z_xA5m*gs7;@=rY)`xgoB?ccv){}Qr~{L@q(@+Y{re-ZXi6OQ~-kHP*$g8TZHP$L|ZVf0}T}pWxp9 zy$Jgk5)S!$G4?MK+}l4Y5BYlu_D>TI`4imNzwo8lKTSB~?`7D(NN^wjvi)}|5BJ}- z8|VC19ox`8Dv#P1QhAiW#|^mpj|P4O_u(hof2Z=Wf4v;HPZJLNm*Bqsg|BGfk8o7K zdS#AhvE+Cf2ltPNaE{N;#^=Rp)_(+dl@B)Ow$XFBRKxSD=nI6!vA}=7MV)vIe^Aydek{=Q zz4qO3s5uzQ_vrayr5*9V!|!*I7Zv{x+c@IK@%*jDHP1YY3f?lJ|5PtNhv%cMTiRhq zrqOXs>GR9V)=bF%t4js^ovb^g{hp7O{AjH@qI7utg!L`>ajsuBt>J;K1s^Y&zvJ>L z;V-3ESNZ5CSicj(k$wk1&2g7LYr>I!r-Ix3WBG0uUWVA=qNRV z`n{~rXB_l-(C0&sEXSARDb3H{H1+weJ@r|ig7q&Yob}D7U#!pJFWmad`W6$;`symL ze(5gH_9McPJ|}{^^f~xdZr_D#!EOF!^9#VYgFXk%`8DO7*%xOw%Bx$iXHcIX&?3KH zxa_CYu?~#rKeeoUvO)70^nK8GAAMghorv@AO+EEJINhzUtZ!OyoBpx>rVZu8U$0f0 z>F=E72{)JA^rz*K%^zoAeUAmV>9_fO0Gk$b`_ymp`fdI(9yQ?fNvS`D+&;h{xak`i{Tfx!1otko_A}h( zO+P;C?K9WEj`+Cq&5}3cgvMA_%Vd84pxEy%_jgJ%T~&s@gm%@dE$KRd+-_%oOBdCSD(^N&vP0shQo zeBL_o_*~g3KER)8kB?`5bwwxs-sX;{g}>(Y39!crqj^~D8~Oc==GVu$`8K(cbD#YB z@=oyw{>){3-ahg8{Jm3rfIo8?pLa|=K9_Zh5AbI$c@xlI7^wr$oaonHQ z>-SMj`~BxPOaE$~pWij{_*~K{KENMK`({5sc=yEP^S4g%0shQoeBLwh_*~p6KER)8 zj}PU*6@6~Czx>xu{Jqy5PYZv|`U>n-^LvZ^+1I!Cx%sa0;~D?Ibc#RlXD;ItPdq*s zb&3!0XWHXa@88S&`{9$eZ{fdLAKyRm{&iue{ssK0x6h1^BY*Gk{g{=vzr5>@djB%* zPh|bn+`m3B@&0u|r~U=}smI^s&(Xi8{r-XvPCP#6cZv`2XD;LOp^3-myiV}}{>){3 z{%hj#`E#fE0DtB(KL0)O_?+7*KER*3jL-2CkI$bv#RvE^m+|@V#N%^Lr}zMW<}yAf zOguh+>=Ym1&s@gmBNLC$*`4A8{F%%6oH+6L{Gn5PfIo8?pN~#FKELl2AK=ei#^wnG9_aU?8QMvzTdF@;HZ@#|x>52ER zGdlGz;7`4MCV!6Wi^KKnyz{Mb^xuB>|2Frp&rH03{kl{C0{+zd*Bo5G{_Mo#b9$%v z0DtB(KA)R-d`{~WAK=ei#^>`BkI$){;sgAd_W005R>_}2P>w9k>>O#A&)Uv%?b<;OGrzw8u$;Llvf=YJ+1pI>x}5AbI$GO zJn{Jav{QV5KXVzMuS`5XKj{=7;Lo(j$5VfP+=;)$9Zw5?&GQeiSJhXG{n?*?zUt{^+z{zy9XL``7n7^)KL0y?>eUaqRC7*ROM#*k0GK zzcumx^}SC03;0v-UvqH%`r8wa&v!e;2lz9W@%hfgJ%T~&s@gm`xB4PH#@}#_%oOB`N72F^NmjN0shQod`_Nte7@c(KER)8 zk57Gnpw<0TU+cu*58d&!@YlS*2JGbv!_og1`?J5l_9HjnBWB7opZn*&+A03PpSg_B zk0&0Vq*Hu=KXVzMpG-VHU+EMd;Llvf=cf~o&zC#J2lz9W@%h=rx-TG7x1Uvzs&dy*RSjS*S!Af=)aTx{`IdW-oL)kseb`~>ix^)&(Xi8{rhjHPCP!J z?-U>4&$P#f8ftt z#^=`)kI!d1#RvOS$v@5cXCm|WvW`zn|7zBkGbSFNPj`wB@W;}=W#zA~4-=1nb9{a? z@%VhIQ+$9w(;lCC{9EM*pX|inZ{6{<@YmcwfW7McXR$x~<0p0VUFF9!{-5X+f8ftt z#^-kvkI%-dr}zMW<}yBKO*}p)b&3!0XD;LO`-#Wrqn+Xd{F%%6 z{9)qpIk8iGus`#+K0SNl@%c!n_yB+Aa{T;p;_*45Q+$9wa~Yp=CLW&;cZv`2XWHXa zUq71HM;-fz)BgSIKTW)U9p9;c0e|ZK%Z!iX`r`2Y>wKGJ8NPpAA0Msu*Z#Xx{Lgjw z$9nwNH}9_jdpR+q|1I`se}C=IZoWs%lxLOvwN?E8t5f`eKhqu`V$p}c4|U@2Ja;@T z{56jsV6W^Ia$>PR`{U<)H{Vr$JmdetPVoo+%w>Eon0S0X&?!E^pSg_Bg%gj@`#Z%4 z_%oOBxoG0?i95vy_%oOB`OC!P^S(~;0sc&Td_3px_jcm%ukLtS_-oGJfW2ydVzEE_ z`P;>AzN`Fr#{WH?;t%|p%lQ0l;_-QRr}zMW<}yB)OgujC>J%T~&s@gm(uv3Cot@$X z{F(Onc+L;+=)~V;?s!`GYt9dVz3TjDu|NCy!Qb6{SNZXb|JysoANVtu@wt5B@j0$j ze1Jc58J{aA9-p^$iVyH-+T&B#AM^U?j9$OKa^n5#t)2Q8@TcCt%=iq~uj~DH6?}i^ z9~19iZ|T&(fIs#AW%B3fU#sW)*BdtE9e}TrZayQTH_9?Twyj~HJQlX9lNSSedzH>V zBY4|YWMR#M+I_?G9=dz}Y4(5qK4VGjoBTNRvETRmmo-1G`)~5&@V~?TNmFY7aOn|r zZCyPiT~JF#$j#G58lpk|k-ejDgi~ZAtqxhzR`|=n58QYHuNBjln;qqE=U;oku`{DW6zl3na zUvNQ=+x+90YQbIcO9^-JV~#IZ|A;Qc{w0FD{EIKb1(%Nmx7FXKeMy7; z;IG)fm~a$7b#adS`WH!gS9}w~5r5&|uz#`OzW%98u>FW|2C5 z{YwP*^)LP>wjU6V{8Lxq@{!=a{v{3egKgNqm~a$dr4}>X*S|>0yW*P=j`#}~^7>un zW5Ip=%krZ&i_ZL+@d)5Nza@kt{(`l*eKFxj+8RfnW%K7E#v{T}{fXc{{BZrjI&5DP zj^d}5aQR4ZU;mN@`@s&_znE~upV~3Uef^81ye-7p`i5}CU$_(YFBaU_KeaQq9}$lH zOB>3EyY%BPmhvwC)UMb+O*o2gD!4Cy;cnP|OgQ2%xEe061^4wYZLl9+9s8FMj`$1K z=eVzbTFSfPn-Y%ri+0EUC4&3<7hD6|*MuYg)HQMWNN`{Ok_P+19@xK_a1>v4tsM9D zFOu@E_$GuS{=#cx|6;*?{ZrS$_9McPe`!PcaL<1H#ZunIpSmvgPZN&fn+opBU$_^x z9}|xF3$BODYr%c}OB?Km*T?=Pgd_ff8|1jJe_G1B;+qnV_>1<&{w0F@`WM^~+t-96 z|5Sj>M}ph@%km?_k0f$jc(9KfH}{WtFTQ$keygcGif>9dYG1T3&d-wuJlGG{uLZZY z-)vvDR;VZUpF>t8D6UGa?wNBo61!~VsB`}(JDj_pT;BmdHd z^5HG|@fS;Z7k}!O*gs7;if<~oFMr{!u>F{D#9wd_F0Tdm^)I?Lwx5!H|abc8XxNRIqvIU zD&<}AjR;5lg?GUI#e)0#r|yXDM}#B)(uVTk#(w<8Qr^X%x)b(K6OQ7W3hv8aatO8` z5{~!_?u^T8!F~Np8|;U7!Tu$LBmRQB=D3f4oZo3Gez&XDSL+oEnIOP9s zIDgj-cuF|pC%n5qKis}p%F}7>V1Cp+aQigj$iGx@8~<(cyKPDXVe@|Rq3-0S* z+F(E2g#AkhNBjl%%5h)+w3M#}mp;h)KjDbK=rHVGBDk-A!M(A4O*ryT9gfRKg8TZH zG}sUBgZ+yMNAXqn&2eA3E_wUDF@Br*z zO!kp~x}kh3xG#U<0~`D!9QhYK2$$D_`}&tQ*bg6!{YwZ(<0E)Tj{EwjrMzo=q=X~> zqK9Jt62X1_3y#G0HQ~rV^)OsM65Q9nq``jhaO_`9IEt_OmmK%?FOu@E_$GuS{=!FK z|6;*?{Zo&`_9McPe`!Pc@L&7!7fX2;f9g@#KTSA_Zz{MCf1IC$kH-0X4Df8v`rojB z5#f-3!jH6(L!V{qg9zg>;fNpgn11n#q`b{V<}V=}wJ&@u_AeIPCw>|KkHhvO!jXSz zL;3LW{rC%>fc=ZfKJrgDlurfsI}mg-^lu6S9x|iyO+Tr{?y3{fnf$ zQ~wA@{)JD&?TZEX^-nz=+m8rG{-q7&!)Ns4FP8Ey{?s$Ef0}SKzomlv@)te}+m8uH z`~}a(<+b3x{-q7}!{=cC62cLG!EEU;e_a*nUhn;xBj=F0Tdm^)GF(AHEv3E_yp@Qv8NSa4te z)SIyVh;Zaz+E6}xb3guKDevM>y#@QH2}kiw1^4AIc`LRb5{~!_-iFI-!F~Np8|;V2 zVgC}s5r4tkbKKWIE#+PDO$kT*Meo4=C4&3<7rYbO*MuYg)Vpx`NN^wjvi)N!ePttK4BHzgdkFM1Eo&yxl`crUJB3vO#)oBLDJ2K(XraQhO%5kEnkd)3n6(bz~n98&Lohul>Wn6tA$6e(kfG=@*aO?pvhHRXT6{$Zz zEI4Fa^|@N*dwJf}A@Y2*jhq_O;eMXjh7H?P<@b*)&#y9`@3p{xzeSyR4BIX1mFIgc z(DS|a-EgQG%tM{vqv|{pY7$T{;neXX}w^&*!I| z=hj!&zesSK7O^HK4dsLL7u9C^J7;;qO-Z0XEf2OIT!8gm3+~eIlyIc);e|PF^Dmnp z0KOgc{l@gHM4b~v>}1bPEZy~!dal}XMtUiAX`c7hH>ic7R>U;W^MfJ!U@%aa=Z{c6v`p5bk z3vM%!<;NE|+%g1huRAsp#@aEZHp?7s&1YS;H2vix22{is3T z^Z9U5z3Sx@*u{wcQ=Rm^iBC3Y9)rFQ`hMtY=%l@N~fE1=Amahrab`|mb<)$0$Fdd#3dOhb0JRkq)Fvgd zKWvd-8v4T}0G|w-$DlvW`t!V=`V*{K2iM1%aLzwm>)TXtGj7Fsmfx&h2lXc<9IcN- z+N(qQ6ANzBmsO}g2Q^=x+PF4fhuur$af`fuTVCDQs|wzW*J&R=liHu%MF`^g`=vd{ zPrS5F9aRusdEJ5D-%vhtjh|o#-2XM-X5DL;GtzuNDM@zACJ&)oIfsLlTV zKF3kVI4I(7(m`*!^F8hQBEPp~USIXPev8%zuk5QYJGu3R$A7Rho}abg+!?AzrXPgA zjR2QE>0PisrGz7W3U{5V^+AX6Qq0GNE*0Zv(5Jkgt#RD{u(-xgpStrs=u`9h;Xixo zQ+PG3PYK~@{SaK;tuL%knsB5~!FqT3Y=4( zF0b~;$G3Ke*OZg6m-Y(1fG>BNeRhzUpfp{|Sbk4W%Y%0Ke`%RxT|{ixl)?v zHlGpkiDi9Zd_RZ(VqvQ~c`=}q>b$;&zMqrzSN^N~sDD4l?7xonOSA43<|noOGOurZ zxaatYZ|EK$ZLV+74@AQGF(MqT&l4#>OZ|IG>;64+*DnrhbN%9(XVD0`X~e^%)q2In z=a7Fl=ieXisSkQzw?6RvmlBTV&u~AtK5+S%@R!o7YyJ#w{}GP#B^7*@^yS-w zzEF>GUw=5bqrSNK9Q37GUq07UU()@tzJv#0eTfC94pBQ;U(|tEUo_!peV-DJ^d-DW zj;}_2vGiZdd|S<*NB2WM{rXH`_I*n0_uM9x-*Tq|^H%3svY-TJ`#5)qE_mlTxG*8jJ_`VtF1OZrmG zx6S%O1P|+f*@qZCU&LJhf1~I4h;QW{AFbB^2f4=w_wR^sG=C;iel_-Q%k}L&TioB9 zOyVLw?=7e*bAt{YY+y^&_}F z)(W(=+OZu_H{O%79`G+}>>dznY;s@m)r}oqjbtkMJ z5#cERNCY>VU7WLi1czY#(1gSNKPg|>G+)_%c<0&Ek9)P&4njg2c?%(ryeg1Z5QNZQ;e4G6a7oS7^-JE~_v8O%+cX#Up z&rh0gG=HXo)1TIkY<{~3-rr6LNBR;RiuFYcK1=%Y?Ll9tFS*w5i)$`Dli&{e;^K4A zmu7vrpr^j*O;}%2!jZm&_j2n4>q|^Hx_%ZM<}T0sgPL%(zE1^TjrwBgzn1F@)$6~* z^?3?A9d3QW`Ad5~E%6zy&*$W4|MSxClAijK9**@TybsowSa8Fw@|5*O-52YNCLHB2 zDd9+8!u#d;Ea^)z-wxO3`TK!}UbOuE5A*u`KYEUj@c!=c(Q5rqf7>lKr(~kM?@iiC-*2HK`;SlLp!dC>e^c11zFOwTI~e!> zi(kh0VFL@B)o(8j)ef|&{G8j;ZxEeN_qFiHYVBf}D0RU4{GU>Hy=vXUwr$n+@ZS~( z-G9ixw_~<%&yCv(w0Je@U*NyrqPD)0vBG|lM-+cQdY!a=d;cx{68_5fazBMuFU)>( zz{J6s3|Frkt(l6;><@-{N$?~mb{%(~&Ow0PvvVNfcRpd2AK3cvP zK8N*NzOFCU-6cO|{xj+ITi!vX-eLVlbd=9mS=Rn*&wtB!%Xlc?d&Gab*H;#PmUaE< ztG~ngO{TE=`ik~v%Jo|7`SAwjj5vP6>yw>(u1~@U=XWvTXnmp{T!N-};-(~qZ;i!GVQ@Rcd@@ z>(d5od%p3oei$Q&Gl%N_b$5NNm@MD=&R@g&A*XP-{$u~%b=kq{*I(OR|KW+d*#Gaa zet6%*xg5Oy^L%6dIG!Ju*MAn(w#&&(e*ff(`^zmT4$Js7^H<5|hwDrG(pBft^DE2s z&Uk#w>sQ0|rM!Ppc98uZVYUBkR>S&4M&L57Pm1wed#&3at}jtCTm0r5PXoL6T)*ij z}B7Yk0N zY6shoo{raNif~u^xqT_&AEQ@W``CW`3^%`wt7qc&MS|PbFI;~@ILFt82hVczlf?(% zW_t49_eD(_mqXZ$`Jw?82q#W#3Pj=S2Y2}kWu1-HeA+Y~<6&5x~5njF|{nz(&` zzg*wQ{8YY|`MmkLKSdq({Jd(p$M4S+4b}IYcevb6EeG1X=UvVf|N7Wa&Sx^nFlra94hx<>xPU=eJq@On961jV)Kq@@FcK^55_! zxP7tU#h5T(vz+~^V+m}#zSNs_dj>WhJ zcorYR;rix3aQhR&QGA1!=eVtXP3<4nC%iMtJ-)pEq}BT5q|FhPDc4D|j%oY-k+NLt z>-X%T?eLwyhU-%~oA&i@H9xAae<%I@q+jk5k%Ofl9s5^V&auDW<@+hM@p0hINB3ts z*6$m$i?R#9rSBVkcHy`5#&J*+>({^9+24n({7KDx_}0a+;f(Ww9B`QE6adi;j__p-d4F`&-GET z1?QKVa94hu<+p-YedG6>KZjd$`>yp%Ot>pQ&hqb9^;;ilDv$E#lyKC(@YU}8oc)Ul zXZx=9sn@Jik0#u9Fn>`4o)B(IifJd~=Ren}*U^Wr`V+!k<+=XgwU{3*xX=26{Y$C5 zi(kgW*I_&cIQy?&@9sa0Yr;|cQ^HaI2;Y$7KJ6dYSGD|cSYNH8=Sx`f?`6&3hV@nF z`~TXnPp+(_|K(d2MLFvEdHeO%l}+mqs>9blB`ynB()#cn3s=JRAywhEzJhj}+Eo%+ zIVngTy;|~PGryO-)7U@YqV)UF!}^M!tK<6q-RfEYSn_u>zP;CPmi{xWuju}Qow8(h z{66K;s58#$>+5A-U+v#>eWl-m^UIWQSANX-Yxq`o{+g{n2#4#Bx4H9UF0Tncf?jRw z2lM)Y4QKySDi8DL<8b?8!O2wZVE@$Har+{|QGTBgj@DnnJKT8258-Hi6}%JIuL(!| zq=NgbFWA5EU2c9Ej~j6HZg+W(Z$!9jeV)Z%%G00Lj;#N_2e&^K+^7A+`f6BT4bSi6 zVOL(i9M*3Y6{@TsC_gB#YdG?^mAO8)%jdN^_3*Wa!}X8v`f4AgcKJfnI){j=+i$)8 z+~xC?l?yd`8StO33sjE7!N<>#@np#Vk(c;FY3Q=`y;`*snvu1O9*HCuJvW`-|qDpuP<~1 zo)Yd_ADZnyr0N{K&-gnYum4iQUG~|(_`{gLP;guOxqfv*Zr`@nVLTF?>#80ZzW_Je zpVd_{z&3-Axcgt$KEhG^)rq+Mk>IxWoBr9>hc-^kCfID6xF!Fg`LmjjlWN zsM<63hgazPRVQtZh=$US(ftwhDQl*A(EBV)l<$vw?XQ{k%yZxQbGUyoXVKojs_UD2 z{~GRJWd2CKvhVko<3Psu#%vI*{eV`#`s>;c_^;2@HPmfL8lP{mPYKJ~4@`D_w)O+% zf~<04j=-#`=J;;4KD+YUY$M|TTCdMq@yQmA!=ew%ygsY#pG|uGw9MV!}E9c9mD3cIW5ZzKC$N{z?dk*UvtKaZR{ueZcjngujkn z??(Ts2ggT$)?J?QlyLUncCh{MbME#r9uv;~+13(_tIy{+*Ht|jj{t7QH?vhSz%~;q z@9IB{hhM<$j|oTZS6|F=+xp4$&xYGLF`HoPb0$8lub2&rVwPtP-wz`)_FT^2$FldY za{VK`m+#B<`?UXl)hv8JZ0+T=zIxYMdXivu9aOxh-cr9lWm#`j<4fx|USC~a*ePBs z%ODoly8YJIzt&z}wO70+yT(!3KWVqVdO913_&-Z~E$d0Dq!piR(Kv?nRnz^s!}^Nu z(-a+DSQw3$yc1da&v5-~J6!+T+Zfa4DanGmQ_uBP_$8cQ#)QN5$CustYnDF~&iSh? zmt=`f2zTYjTt56tzx7p2@}@?Ni^v?TZArt&fKF z6Gx0#&ek{e`C&9)l=r96{$!cINV)R8*{3y#9pBB`E%W8+RUG? z9_Fq2p0cvm&!?&mtu7c?y{b2OR%O6G4_NlU&HJxpf1`ST(eV5S{QUgk{jG2!U?g8G4bf1Jx} z!u#BxmQs0i{UkgYw=Wiaoca76`=@@0+ZPf3Qd?pAjLWBj+pbUW^?~R|WS>tg2Y;OW z1mnTa*QqnPqgW2EKlsHubuLxzsz3O(JHA}MCLHmb3hr}#g8d86aL0%7xB*wcahK2d zCERuWj`38=(`oHsJp3(ge=N99`)${xOegj*-&oFVF*W~elpn;ge1GPk>i%vV*Y*AG z{~D?tc2nv(x1~OO{@TSbQR;vW&y6d5Sh?#5W&3L1pNiw^^&PFA_;~iP`T0J4{UDC> zs}!T(udLcL_@nPn#qk#PxDxXwoXx2)fy|Hk~n zhUoc?yL~;Tlj{6J`k%*}|0+L9{VeS->-=bWeumflLUL_AIIX>R&-G9E`*rFltMxoT zPYCa`{s{hn^FvKIT3@At+g!}@*(*C<^SX^&-OLpo9NYcuz#uGKKXqX zKU#db;?H>8fU7^d%V+!&?&{x+r&8Y5KE}iIaQkDyecHcdtJL^xSl^h>p*4spPA9D2 z!}_N4{ZZ}KA2e|-ep9Q%ezy2cw7!|i^}%TUNISuBpC`S}@8FOaIOMeHqp_weOcK^YZ~}_ZL$BS>(qw z`(*d+mhYv%wEul)Oa5u{ytA7lzf!dC->t17x91X)(bR|x8aiwn#V{VCY9f>c>cZ2>xbI< zWXSK0$#B$vy3H>`elMeNneuycOpl${?VHzkWPMt_j^-uCocmBxvX?Rt?^-oOYQGTtqx$|SrPb0yl$zw0yUJ^T59^!Z`pfj)Usld< zlCPKVWxm@;OB&MCmuvOQ-PgUm`}(G8&$$0$^*b!&Zg_nY5zhX(uJ0s*)1TCijK8bl^-V%J%I|}#WB#<@w*1{(f7o#L zFQxJ>{uvL~V>|{p$4~9tEKdCT4OJ75e?MoL=eJ`2yv#q${ktq*?zMiZ-#^sudc!_+f6__K_a}|| zubF>WuXoh*@4M_65VO_4L-&`L_Lueko=M*yH~sc0OuUIoqd>l&*6RB5u>a4T(NWJ| zmsvlibALW3$I6eXf8N&@t|t|6*L_0I{8(SdoxgB?r1tEWA4gOk;1l~X_fw%2&Nfk%~~^( z*=N~*_W85imlAz2@{85Ke|k^j`|(zNTTqMY%EPJoixG3si%)xgR`MtNu?Bx!X%%SVL2h+b{_$NHRt z@{ET!!ulKw?$T#uG@=Fi}m3A{8>HqB|RX|zik!p_zDli`VtH7Dz9$h&YxL7BEnJr zmq>Y+{otm#eVe|RS&Lm3`OootVaxaxbBbxF$$y(>n&mC|r#XHd*PH44 zUl+5Lh5hb%^s7!h`NA=aV{ayO9DQeA_g|tcvT8$o^60hsL?-zpee# zt{?|Wl}2d>i>QF_o#mv z*SEs)xGs$1EP71&%SGhaT3>xH?K}1T#ABF&^6zAxS*ZO!qPPE?b1gRe?`{7AvcJyD zzIpw@kv~rU_q$%uGQJ!o8e`d2Ub#MJ=D&{p#bebA+Vbyfza{@8eM%DX-@?D4e_4aK zs<)gG&{?&A()D9Hl7#=4qrCoI+Bf-e#JBzWfNP=py7OOIf6${(tp_*gZ9qRw&2s6Z zzAe_rlyH|mvi^m)bC+j4Zot*;bNjXia?TJDzKLFK`pkIJfCqPQmuH)raBiRNU_6!b zHk|7Z@94H~^6#@gx5aGCkFx(x`}|<$PvhgZet(Nrr*lHxVt(NDc|CtB?OW$Jzvt(6 zTqL z9mRU5e?JrXRBx`l$zxC&5ZB-9_cR&U0{l9DeTOVIE|2~M!x7a`A zzv`O*X5*`3A3eY7Jw5Z^_)hNpHQTc~1n0jI;hdk^jx0ZIC?DL}T|UcC8}PIN5ATBQ z#|^l;t2;mD_CdQyUVkG5#cWX7*C`; zoz@PnKe&h6e$)D4UCrY72N{24ANiL`{o^I`cNu?&`un$JGirR+o=3OZ_mGr_EYbm>q9nufAi0onCAT0 zcYT%bPgnh@?;m={|M+k`{`A%-{`1OT*XwJp`v^F7`B2aKSs&)!UuS(%_r}-PBEeY; ztA}}g%7*i236)3ldvJKJuclTP^_ZWT=LO!Re_X#N`$rW8DzB#h85b2iYtwzO{}JIl zKiK>;KQqsZYTEdpkbPhOmx_uUuTAw^^n<=1RLzU4`^THrQ@^F8zWO@tzyEYvYkr8iY<<)%KluGmLnFSDAMgfkwn~FH4pw))wu#I-}D>W~x#j^gh?qBlr6CQUi+pqe8=GXH2hh=}IIzG0l zQ{EMm{jyz>NBCV|vE?5ty}o3&Y==cZTIHWz=g(`|DyPr5YoFM2{!ET=>wla1Be=i2 zJkL3raGpQ1xrScNgFj0JH$N}Vv-QOTa{I3GG2yQH!<>`K+rbLs^vX7a2R8UmIP_m| z!)$rV_QMBZ`?27*_L=_Mt`9ZMZ<);pyZLE~?=Ziv)b*iqezNFmsiUIjlmC6iX_;Sr z^>>)xbBP-9H_Y#)Xd5RZe#-GVk@@{PMxEv<&+nh=Ill)-y62xJ{pa~ZgYrB-r-Y;V zF??8#o9!yjxqM9cCVI8af7xdbch6tu{OFqBbIREIW51x|2YTo`a4^n&H4TPr9PS0r=9z^!|zM; zD74>y(DV1DYy4a9zpdQAXKI3Z&igw)>-)C%-%h`MVv8rqj?b6*;>MAFTyv|xe)#V1 zwH<$X%f|M1%>L!P|D?z7qnq}f`%~Nd`)|w(AG6bchx|K_X#M|W{QhWjeeCG}?VsQ2 zo8KSz<}h>A$Uh9ni+xq&BXBy2_U$9}u{3_M=lUUhv^ziK{5K(-Z+GMK>cO7{|JLvO zYnsY$sv4H}Y(FI&<=K&N?c4I}?6b$<`Xj+U0 z%iH3U*?e3>`vkYuZ`$9*;scjS8tey;&)dIbDbGIZ20R70>7UI$`xidJ-9H$Q3FrP{ zJ2Fm>%5j^0#v{VHf7sS%89#&{Wiw8naryA*ygaw1df4hT|E6hw*jN9C^_Q?*Uf&zm zU(0#_bie$yn15+>t@`h`+tzob|IX{T?Y}=iY5Oz|hV_@u)gbS0{r3;b_z(Tpy8lt~ zvkc>-=)c4IEAPYg|C3?;rE^w_@!h<>G}m8A&-GXGq=x+P$$0%03(mP_^)T~e8=igk z6rBG?guB*1Ts{%JS~tJv{5E)MZr@eE7Ti@nCEQhimOnoY<1xTn@$+fbrm2*ncg! z&3?uo;b{F8KHD8XE}sz2<+&}@!&ayHH^cgCvd_<&^#1$2-e22q{Z-ztwCb-PjQUS` zf3CT|?C^gDzQ5h_`k=-CWxamGT1Lw|^ZsJfzIFedpKtntw*J@coBTWMcX)pCl-nQe z&kgGn?u*r9#80{Z*6RL|uJ>Q>U9DK&^VY|=d*=7y3mWnd!r}Fm7xuiqLghC(+Lz@| zguC)<&dt-`nCp<;PWf<$I}5 ztG3Tqp1A*YeoX!y{A^J_dj@+}wo7Jrd!TIm22bWI? zNA-tWbG%xX-*fqxa994{lz%tnZyA5DYT!?B8~^NILO8e2w!fS4_iA_h8P@=B6aQ4o zld0OlK8LTt?TZDswa?_&mZP`g_dng^!)zaOQ9XwIeA~8#@_PnVcC!1IC;Iymqx_`Q zXLJ8f^44;{w#-l3-k(0~kLSNnRFABDQm&86{pA|}3!^-$>1Bzkl#1V zpZ`$C-JQSH{Wte#rChbXt?H;9BO;(`-#0(6+BsGo-17Mtqy9e`{yECc>x&-#*X>*K z^Q!$V>akB{&#IsM=I2#AtH=H*{~Ypjj(GJL@l)#mME1u~ett^N{5*PtJOALEBPAT| zkB4vUw?7_JdCp&LN0#%v$(L1~8?)I7d z`sU{`*+0tW9DQcCFYBw7zgw!jufA=Hudlug`{%-RnO~LqT+0t_&%YY-bLMYS-`_6t zS;=q9{AZc+^Qt{peqQy%lE0Pxr_687{Ltb5R<-x5BjT@WziobA^}lMTZ+>32SFNx8 z^YOTs)bsPIy=r|O{IA5V80e<{^1w; zSNO%}XZ6$veY`t<%uhi7_^`#N@FV|=`u|Pq6AM3kZroP2Q_TmqsEADudW7Ebtc zdw!PATqyNAqt*D&oZoC(na!^!ttx)jSD(Lc>pxw_*KR%e2|u=~_&Kl*KX*GE^&g75 z>>D)AuROo)(UZUE<4fw%MxQiKCq2Iv?Hr%qO5O3+Z?g@=QO2hG`TN!SwyHB97?Fwc zbJ0KAe<}BKq=xc+IX~C-2kYab+wTuo{5S23U!|YI*Y^K@Pm!y0|GZw${uzJ5J-)M? z{gXLv%TM{Ui11AkuIdYyPXxD>XFT{+ZlA|O^)U6@JTLyPY5dwWzbMPE_WZ9JZ%h97 z0xn(tU2Xnmv^XmL%Uqv0`qwZ%a_;Q=+x+_-mHAJ`CFM_|7v}ibx99jsK8?pm@EJTl zG~sA`q=LJ~NBG(8H$DnJjroJtk7d7i&L1aU!VxV0PWpK!P2`RJ>k%f)Z* zP5uAv&_7IlcJz;${&dlQv;R5tf71EIFu&wI&3}H`O}Z+N|ATstfAvN8_~r2*5svon z6T!u$v6n2r`k&msYktv$Bm1e8A2Td(GJX1AY(FNP?Qf6#Zrb%}JLIQ>K23TK;S5)9rieQ~V{YPwLB9KO(^^v}SKvKN7+@e{tzk@D*%d6Yk1?*nTRw%YK*) z`jiEO|C9UUd*s(su|C*I8qD+eU3!j>@N2mL#e}2zRec@j{}JJ?@@7tNo=fwF{Jy?_ z*do6lo^O=*A6I_dVSVDoe{Fv2vc59o>sVjS&-!O{f0g_Gvjy||HV1xTt9r{B0iBfl zHJX*1wo=*ZLyU#FO3n%JWl1IP1GjKl!sna5}9WTt4`ryS%CY z>uRO*IyIGd>3_EV7u@Av_@f4X1h8}EG&{=unezTgQ-6o~l}MVbzT3WEQm(t|`Yzuuxy7j*z4Gsd^;y=Li+*0;-^*af zf0JIHJ)-CQl%9(9FFXzFcPzNA`Pus9bhm!8{zihk$|s<_IX}79XTh)C`p^Dp!P%GU z!Jnmsqxm5`!`(i%9}~{=5{C7exqfoYf8DN6OmhD4+h48iFOAI~yHGt>GN{TFA3R4^Gon2+O!}^5=<1oLN`m^fSFT?evSDkqBg|3+;|GcukFyp%{^Gn5ki}hW% z^~=+G&M)bCSRcdlvA)KF+gQ%l9~a>HB@*0KJ^|&IV}1!P#Pf?5+%`Y(XDQ)mehDvf zx1afm2_M!k68&L*G4*F==a=F73itPAxc`v#qx1cN-R76)_MBhBi?Ke&groI~`Wx2g zh;X!iNdy;#8GB*<4K8t)Uyk`jlYO*)Nd4J@r4n9P5|50_%SyxY;L)bJn+naF_mP`hKNb|5!7%;Dt@| zmCL7s+w_$`3;%)J7YlAHpXu{I-R(E;uQJaIAD4;~$E)q0fU!TVk6*KY_Rc>i{rs3g zpE;V;vl{O|8?G;m^?Tz@C4V;i|FX=#75gpbuiE@ri?6BAujr}I;kE|-A{^%DbY~CB zZzIByJ||M%w!hAr87yG?T5y}b@@FaGT)*vL{SDV(|6;Z#9q=LY>E9Ocj9E;(NGIrEkEEhe1x(WQTC*Sx$fKjku!;HKT;ob4xq+wAja!EU&H zT5wx=wx1I2nmC z_YdOuSarU%T#4#PL>j z_fJL^`)kVQzn3-C{U?6p_bAtpV$igY{2{}PUVKT_?U4 z>OW@u*_Z0ERQ;gxzNvoS@i*i*LUgIWrGB;2-{JSqnLqpbu4jH@ULSGHe_PbQpUCx> z^Q+_y`TYZw4~!j^{J^yD$j^rSCMS^8jq6oy>NaI6OQs5bv^g|&;Cb*qx>dmC?8xO*RKgj`AsUgt^IBCoA3ti z_OZ>Fa8$qA+ueS%e&75iBKt>G126B*_z(FFks{BJ+4@Q*sJgBd(u^0`UpCigmfwdq z)|VaakDgyp>erCp#6|$j&lf-poJh^Q*-7so8?pp5G+Nxc~It z>_4V`hyOnLP3b@JQ{7Lg_VaH0Hx>U!_RIXTTA$DUP1*k^GJm7zn;+kE{!aIC>u)yy z?ThE{L~z^uWa_sK=g)%u@cg3*NAq_o_;|0)-?9JUjokBBHvbXsTK{Kr&W&;X5#gI` zmD6WjJ`vp3eslh`?N6+8*eyQJ_}kwdKa>BgEk!|jU8=mVzHO?1r2pmpH>SR2`qSt4 zdr9B;@^ORyjLl#4_w9c_atj8~e{d7re>LH7{0W{lxbj~%{%-0nZ}xxlyf8ELPhukLP)7f}s@m`B{j=@; zZ7b0~Kiji^CO5+8S2Uf0jnG{1kZXa9^h z;Qpy@5`387iH!c=pFgmTem>}J0afOj-?I*%b^DcAAN{Il z|4i?I`)7DZ+&^Q&A5Co74(^|7qr1GRndW(6YXbUd(VsGovLC%w?Y4zIC_i`Z&rIw7 zRdGuv_tf9^>_7TWZhc}+N(tY@bXpGXAK@X>*FVnR9FXVp(Lc`a*+1etAkCQitbJIW0@7X_+yW;*4gt&ib!l$i&oU}QboBr{)p8X@e8}1+B z-Esej313D1qxSuX`t_}?YW*9id(`F^{;YD8_lK7I`%`iK%*;Qo?Abrmq3-*`v-LgU zDE~+ZpSJ#S(dz^12-W<-d}0q z-`J<;sLkN-4;Rm4$UEief8Ia4PEUQ&_r>~=67I@BIKK(+m*XR^MrXXg78B0;#D7~o zvd@md^+$r+%A5BG7CF6H2bW2xJo|4u7!U4`>(_$Y>NoR0+xG{SY?T_H*>Xk$p4$Am zY(rgtEaSJTKU-Dn{VS?y(9e?X+R31w`STHwe(v2QUbs~D&$H&ckj*s9GczkHW(fCLOFZ!(c%KbllBpx3z;lub4);iu_ zWZ8djb^WL9{@hC3U$miT{|z67`)^D*>c8sI?)^9JzY*cC@}_2+=fxNp^xIFrSMmN@ ztMRp3uCH=GoaFpAtUvSh=lWv6S6(@P-Plv#(tpGH7DjG;;x$<;c*V8sE$f?ljC+3O z@)6;#=c6&6NO?9@J=lKmShsz1eOi2H)U?6&HI--mwH=J7V&8^m`N!kj^_!YqtT{|O zgMQDaey^7MAGj|L`fZNL`gxM{zrKd_`))n;JAMMzZ*>&b??~`^%jNkEgl{5{wXk~d zXTi}}zct}p-gdBlrh?n-x6$wL7_8qh;i!J~M0fiJ{pP4qWR`he%{e7}q|5#r&;Yhzz!cqPmJ_Y+13+}7m>Zxx3*=9sI z((goYTm6H6^SB^p2K{Cp%J0Xu-Ji7Ve-8IQCETavDDTfG@2^^RekQHo_wT9S!85Qv zX~L0yr-B!hny=aZ!ZWdc$AlyOR?ouzMS|P(vrYb;P|z#iKLU?}TvPf3W4J{8{i)te={2E^j;7ek!=lejEJ`Uxw?C z2}kuS?QY+o-yF3;zw^F3((l&auNd^(=s#;{sv$i|_GxC4W?stgJr)&vCdZWPH@Bj)KV$Oa z{r$h)gdR@FpV?FY(%0hg9lj3hUo5z|H1@*!r(TcsFCrZ2Pa@^V49gp~AH2bBKg*v9 zXZx&$)x*>$^St=GrQ*c#Iy}GND(c_mI4|KV-0Cf7$iv1wHjizX|J8N;r>iTmHeH zg>QE23+qEnI9gw;x46r*{fKb5z7^c&U#4Gg9rTH4%#Z%x?=<_bWBhGZ)2>gqI6EZ1 zy6Dq%u79~xROSaWz7G9setv?PKk1(O6dZ@gza|{%Qz|&OwR*5Vgm1_C6cdi}C-n~O zUnICopAy1{{7E7+=#x4Aocg-k*%1-eMW3cKe;U5u+x-3BEj{%$c^B5N;N4hXwcs*> z$6i=pQ^HaH7rqDUYfL!G|I~Zk_S@{wMN}T?dm{G78YXYD{PKP7`pq@(@crKU?+;q; zpKqmqt0li2=~J2iS^Td*KlIt}w4<9em~a7lyH{Vabbob9s~Ru5C3 z%=6;!mWmU{>pI8h<;N55zms}CC-C3wzmE0Y>bd?j%AdOF(`Wt}5CvWIskCqAe-3`S zt$!=muTA?7{b-+Ga-1vn&G9`TAnXk-@km`@yu9NpGp=-Clj83xS~pav#k0w z;%8X@j)FQmsv%P($|D=^n8@y3)nv`xJ_SMt$(RJ z%0I&|;`(F3ZS|Wu<#7FJF0Mbd((i{IAJE7c^gG|zuFr4tbp7d*J@s4tAJ(UcaHQXf z;M5^&2kUq6C9L0?aHQXCC%WnH^^gE{VNWaxr8u$@>&~FOJoaNt^>q8d( zE_GVg!&}w7{JsN^*-C!DEc*jjW5aZC{`!TU`j>nakMH1XSpT%(nM0NTSf5hDUHPl2 zPq(a;<+rRU;n%S~#)PB&1N9Ae{aJoZIO`w#Qa#N4(>yQ!ZmBqNybk-D)AIcvw0}_7 zuX*`>1Mb$7)~~Ph)Gz%lJpNO{QT`Tw+nxWgKE#Cg(J%EKtX~n~NWT)nZTS`Z7kqcn zFYc$=G2~yZ@~`3f{@hz=L}mAd&Hnm%_k48J{^$JhTRrtR{65yNm~f=O>IYbVBf|UW zZ$jnK`Z_on`>zGJ>93i;x_*BvrSfQf9sUs49}8})-^@ve{n6RmAN5^d56}N+sT=g2 z_5I|Y`X2lQ>ysuN>3b?TN2Gdi{u=(YpT5Ub9_hRK8TLOC+@`N>^gW^SNZ*5>LXI`Saa4XDN>3b*9@suUR9)k^Uxv+t#;j z*4M#VxPDDIsy`LnR{yZRHplU>zTS7+RT~aHvcvbUraV6#z8{c3p9)eJ@}(r|5)EO;eGTy1@>7p!*j6zvEVj+ZKLn%Pww`y&4_TM?}^~H`UicV7kw|k zKiVpPAD%Ct^$YLsr<(VlUer?`!}IX?jtNKlsLprmN4CBvypKL6z&>kEZ~^vT3vSaV z_Ae!T*ni;uNXOjnKXlWt;ra92S&HB5tL`H=f4|<;ugiMsm--7H{}JIxzY@W@Mb(4# zA^2-Q{nAvP>$e@ONvYVk;aq=svAcf8W5Ngh67~lDYL$Nt&!^}9vOM~ARZsm&F2VX0 zT#EHe3oavI>?O-@2=9}Bg_mLdiU~*SL-lue{p?>v_@G}Bwn4vI>DTc5dhRcjJq-8H zt98F$P)jm=sxRjLlkK~JoPX&nuzsb4qx>P+h_kH!jb+ag7e>2 zk2d>*!9Q{Rns8KqD!8qFGd{!p^RsvTXLNm|{C=lJ-|N?}=jHkKJRT=~f6}f!^)XUA z!ttFDj`T5D$nmQ7@O#!rO?V%DOo4sYoNx{HKNj4kPwbysoBPjNSv^esGS7>@TPjW* zueLd9>`y0reRFvJW`6x~jC13SuYS$T^WB-MN$b}&d+JxP4v&9LIMT0FaHCt4r>qa* zQa}BQsXW(jJ2Fk$0s9{b?$WP>aJE0_7m+Y$>+6wzq3av<{A+l=IgiHW*&p1ir+%e7 z;qf2tjP)xPoLf{qvixS3e)<(rd8A*7*ss>j@45b9S9kr4Yr+TpVz%fQ^sCkSad`eY zcb4VRuYG#zS9~?BU+U^uzaqi8Mb(4#AtAia`Y~9K^-B{D_qPOh+{hq_Dy|Xmiyxl?5SVTHSzdQ2s;kB^;vEVlU**|sdLBE)W>=^W`m4403^TD}KRP=G# z_3KtW^()vDkAF=#(yvtTd;pC9&-xHvx1WB+R37P<+6((13GULbgz#bgC~@nkU!(n_ zGJi4qxAXpk*8AV&R%QH5MSf9^f_naC(Z@26>;C-hIzJ}=-ucn4MR%ar+x66!^!j*w zhBv_a5({2(YMf;G$KGyzVLT$-HNIIB62e{j!sUY-y8Sb+>6zz+i}QYcZ_o$s3DnEl z|GsrAeQ5oBYpT7XpUbWfckZbVY9Fi*5#cERNCYp&ocWrK-+i$@Xu^>`q=X}V2={aQ zXKI3ZUidiZL*7BTmu@~IVp`1pIphzX`NQ!1Xzogd?$-CuX6^Tv(D&mH?Wxbfjj=v! z!jV3wf^$Tw2kUdVKi21%aHP-b0JlDKeispr_U9A9`ERR7tNULM%>ApD<@an;6OQUn z1-I32&Kbk~ul4(1hx}4{*)r#s!}F<4UgvxMxKGddBf1&Zzl3l!e*`yo>nqP6nsC-v zn|?B$N_pG;ZCob21)e`*!jXQfTe|CSGk-)>p4)Fb*uO;V+wg3Cb1QfK!~DUl5sMCe z9Oe(qkLC9bEbFuS{^f34*lzi`@Nap3EdAA__a`3IQ@`R{H;n&-v3^B@Gb7c5$8SP7 z(yw4cZr`O}TJWlEexK=|;5L0U^}#$ZY%LWhj@McLe!`#+9C){W`s%~^n**}DI`rXR zdg?=RTdWVk?XW&*!I|mmk&R!%kv@dC$NCTpUbW5d*}l4i+doqi%yTZr$Dj{H0!?7U z{w4p8XnlR|s}IBTo4HRFx;x+N�$9r+38q9By>$ALmT5;2e?ak?H51us%nGqy5W7 z@TzTo&-Dj~VE?t?{I}Jk&H6K?@@V}T-Wk^)3vR35oHK^~%ep=e`6c&Q>N$?}x$pdO z(&mWlw#YB**VoMZi^Q+ej@(b9)eA3XzZdqq=h684!P#G_ycKeN)3oonKj&EWf|mA2 z{U=GfTtA(s>t9FroIipP>z^hZ?O¶=<)Jb#3D!}CW>IGR7y-LZa0g!B5rc5wZP z;5PkkGk*m4!1ZgwQT?glw)%(pgQMow$IF-%`SnzJ>Q`&>zB)zN!1>~Hsfp%!;m4ql#KfSF%dU^DpC6smpRK|z>sQD6xcT|<=J!`#+*4oT`{VJc9)R^F z61*65=4-b8A{^;U@Id$YX8q8Dn|6zHwx0?<{GX?Q*} zGe{#c+xMLB>pL&+sn5xSu|5Y6!TPKPFZ;A{lIbVmNT0)pVttMUH_Vo&nI<2J{f`8< z>35s`xrEAderP+`X7DgvzZTq9znN1G*LQ~NJGq`U=VwJ<^xeN~{rqRDXwv(0ukNW| z>JfPSMTDdEYa)2TsrkzK6+9B_mnPh`e&jKq3U1mh&e?wWuWtWLeK609^27R*m>AZd z&h@9SKJ<9L#Ioea=KAxEJ@p}YG}Z@AIMRny@M6rFui5zhH>?ja;Yc4;l;ft|;+*YA zf;Z(4gFX!TgMa>j)}QtDRqN*$Q~#ZG{_ysm`Vc-A>qAU9(g*dphVe@{TK^(Z-feq7f3m$;Ra7+-9ck5T^6O&^Bm12cQebA9i9 zJ@qX*3hP@!IMTP^=mz~E9O+vsu_uoDBML!9T&y;YaFX5BjlU_c%cgaH3l94Ix($aOIrjYv>c7V3Y&HVvscWFoX(dzUEv4Q6P$$v%lnfaq>-#Wj=@v-W(miB%1>9{wC z?3#McL8U%r@ALnP{yh3<&(Z1F8HeUGJ?E$7Sv#tu#;lIs@ca@!JD(r;yn66wvEa7( z!Mwk~hG(BW2hWcY;V6Gj1h4wW@7cfLx$gOq>(_+4=0C<$DNm=hqp5x7n%X=s46Q3p z9Isq|_`JORwm)G!CVZ0(q|dULJ>T7a(FLLWU zYkKrzoF62D^ITOu%=y8F^Jl?J@cgC;NBKc2c(rbR&;Exmbfd!`9%}X^CzEI5B@9_oad_Q(KLT@ znedhF`Iqg-grodGZFbL}Ts|V4*Vi`xviX&8lph3J-2OGS&zyhFb8;s;+T;hC>PPuO z3jE{thg;q4H+}NW4`Q-E&<5@`E8i$cG!czVO|i`9biX zZhg<@XTni_pkABfw)wYd{^T+dmFM}}c5wX(;V3@{Ugw@axx6MELxlOM!X|Npc1C2*D-#rZwE_SnYQn9JNj*d*pMkQj(@ND!9;A($&1fdmvn z24l>9UqMUo?wb1w=B8&chp_<%k`Ty&I06JP7zl^W5pfs@HaNf^hb!KHRjZ^|uU}WS zo-}WEX14YF?LJB0RCVi9b=TLeetMcdFfWzshu2>a9=bogPDAxU1^$yhNcy0SY5tk? z!QA>FuzsS`0p0q8&zxBR&E0u=z7SYHF*`qz)*tWyh5c%auRl0{q&~=BDfjO#KLf7m zgY0j|>4OsNHGNP6uIYpPRdW8s`dh#?ePGUz?VWxBT&mxC=z}U!zwFg={hU4`d{O$K z2LCHwn`;j_KUf!kTlP}%D*nByiwN&1>ue;??1G!07w6! z{D|kWH|hGI1YD{g&wnBRe04vfD6wbS3fnCPeOzOCu^7kcS~!{3rY z&5}My`T)WJHccOVW28PP&y@Rj*QdWl*9QgRq5Q-1LkP!n71&Gp7t7Dys_TQ2aOBC~ z(7py-(+Bz6bbVj}m+BY0KCTJ)ep}Bz`oO$huU`SUR6o4_itrHsyiP;)L3WlLKb#*I zOYMcz=dyR~AIA7e^9RUSnm@oS9(aE_<^A^iV66_@(BE(Dr4N2|W)Al~>4T&Xu>I@$ z;G&WGz@8)b?=C;TQ`ZM2;i3G)^Fs*7b2Zp&`7M8!t`98XjwtUxmy_PD>w^Mt?fHI1 z_MU5Z7`r~6fBAmvE0+I|pX^+{ekI@LGD{&}5->Vy36dbdBet)XOFNR6+4^97kFgK)q#H$FN{iAMQ0*?KQn+AA2_* zf6!0DX6^iOI2nJRd#*hG^7`kc-R7dREtJ^huc`UjbI--v(AKSw>iqNfkC0vGXVCji zpgdO!)t~#{XYV(ew|ySg^5uQvja|BE$w+aGZ6g0?z5Q9hALIFL4^h93X@8+M+xo^& z*Z%({qHh7m{1e*n`f9>s`u5O(1GLHiRqlTzURzhO>suH7L9LtO8~TT~e}}7c&qe(9 zxzjxGQ)}2itU><8I16ofX$ME*yZE3U-xc6ee7p8hHTI!<8Otx5GCsC-{izrqYnne6 z93NMT#7FrdJw9r{wfHDLyr0F#Wc($@2lSdu-;UH53yzN?Bk^HBqQ{5%s2(3B;FzEG zoBksnA4~SGn2dK>DfSpY*?IdeekSuz-Shum^RL(YQf|z##vF45yjNw!`>iMO+m+v~A9S-9!uz2w zxeSQwncwX6`b5ZY-S|D2-!|*}p(lLpFc-4hy2IZC!tLp z@t=QQu74l@mh3~9i2Rr@jPqZRz2v_d=|B6=2>*nK_~-HGuGOog<3Hj*|Dwzf`m}&! ze1`n<^7(#S4Oizc>DN~PF2z6h$@jVc3hcG`&c7_^Bb&`Mh{9&&2zxOd|ALZRR0x^ucc?cAjKDSU9SJS-^lpNzCA9! zEZA%Pm-)_yim$`{=d+>yE9FOwt|q?zY-D_u7mbTA^Ibi@3cxo||CRTNuXFB^56F-3 ztp4b`JmU1T-K}Z<3(hb3y1F|iJ>LKK2i8O1|K-T|s=s%zc?zS1@AlF6#rO62ssP_W z@zrboYpuQ?v02BDT@1{&55B&I#+`oq*lkWavj!L4dHTD)??376sJ(T^r1*GEA? zuE1{ordRvh0shzG`$>zw|41WT-a7Eteg7nI|Jm~iSE1eJ%pYd3=f`<-|L6UF%WQm= zrtkVVtj@gOZy6R}GC#BWG=2XE?@Rl9cb1=>X5R1rT&r<7^FKEIQxtuI^Mm;hu;|9m+0kNz$N|TeEzV(ecyPDwtKW|z^&?!mK69yDKeQ0nqy7o$8$4GN-u2mR2krC!)yubpGqY|N?aj~i@(aLMI*aKYS3k0!Mw%m6 zzhCJ7E#SysXmgzWQs=)QJj5Trzmh(!z+Njq`;}gPN%+w6Yp|F2-B{W6pJn{NJyzaK-Gf86);^Ia@<`lze_%>2#l`k{?8e>${({?21^_I$?Oe`6jF ztXvJ5Y1h}{eq@{FFRf4aD6`Yw&*}I{-_HP|Qv9gnLky)9KVF04hbewi{M>*4{eD}@ z|Cht>qwK%;KjqKJ_xDo%)bm5ipE^G&esq3P{OJ6o_|f@E@uTyT;z#Ev#gEQUiXWYy z6hAsYDSmW*QvB%rr1;VKN%5oelj29`C&iD>Pl_L%pAPl_L%pAPl_L%pAPl_L%pAPl_L%pAPl_L%pAXPl_L%pA95|KzXpPuH`@;V*B6lP_ z`Ig3P|Niy^^2#03f34n_oI7LtWS{RLp-;PL$t?4eY#(n-x%XhR!p`yC1K7cVY`@)Y zZtNlE#P)>uiPb91A?E(@IUNMeAL6-+@aD|)|7f2rHU1_05^$;h&SqPreuRho^XqrP zIbA(>O;yBywq34&AO9uUdqulLc5Kk&ki5SKiRjO^H0bBNdNhjbbc)1 zL-{dB=>7}Bhx)G~{!iV~=BL1_hjpU!~ zTh95Xr;eR}uf&HAeDJ_MG>2-|;`ve|}A!A4~X9e$2IW z{{`Vg{Z|qH*|kUVPxdY6{L}G2(tmy(ogYj1P=3sHb^it7L;Y6~|Jn6M@=x}h_jcd$ zKhl5x8#+Ih@S*&e>+Ajt!iV~=BL1^%B>!aJa?U>;|0Dh9H_-X9gb(G%9Hsj&2p{Ud ziulit9?3u1bKcv1$NxzG`3-e`Ea5}>F~6z%F9;v%zl!+JerqKEWZ!bmKOO%g{pZK% z{8++=@?&nK`!5I|>c5Kk&u%=Df3oMixBHI&k^b|W==@m1hw@`?s{1bpAL_q~_|I-O zl7F&qIp?2_|B?RlV|9Kk;Y0Z`H`o0agb(#!Mf_*C7|B1`bKcv1$NxzG`7L#REa5}> zF~6<*F9;v%zl!+JerF{AWZ!bmKOO%g{pZK&{8++=@?&nL`!5I|>c5Kk&u%@Ef3oMi zxBHI&k^b}B==@m1hw@{7SNC5KKGc5|@t++(l7F&qIp?2_|B?Rl+v@yS!iVx>PSE`q zgb(#!Mf_*KHBe>(n0 z`p<8#^J57g%8$u){{`Vg{Z|qH*&RmmPxhSmcHi+o(tmzOogYj1P=3svbpHk6L;Y6~ z|Jj{K@=x|H=ls+0Khl4G7o8tV_)vb#iMs!S@S*;zi2v*lNAgehocDI$@judkepj6z zOZZTJ%-wYV1>r;eR}uf&AC2Un>|4(Hr{jO5|NQPcKbG*J{Fp!1{TGA}^i!GDhx)G~{)@S*&e z`{@1)!iV~=BL1`cj^v;0Iq&VhG56E`7laS>Uq$?9_aDhW*|(hY zPsjgA|M>%Sek|cb`7saF{TGA}^HJv2hw@_{tottr zAL_q~_|N`qB>!aJa?U>;|0Dh9f3EXm2_MRjd5G@6AbhC*D&jwT=t%y_p7Y-BJN`%d z&kLO&OZZTJ%wOpK3&Mx`uOj}lhmGW)>|4(Hr{jO5|NJj?ek|cb`7saI{TGA}^MI{ruc&mXJvV+kM1k9nN#zaV_5|0?1?d;CcL$)5Ax?mPZR`p=)B^J57g%8z-X z?!O>>sQ)VBKYP+h{>i@OoPRq0NBYm7tn*_DAIgt;itfK4e5n5_;y-)pNdC#5^WN?| z{zv-HpQiI;2_MRjdAjbuAbhC*D&jwT#z_9jzU7>MI{ruc&!4IDV+kM1k9n5vzaV_5 z|0?1?d-h2F$)5Ax?mPZR`p^Gb=f@I0lppgP-G4#&Q2$lLe^!pcI*BN!iV~=BL1_}NAgehocDI$@judk{(PMuOZZTJ z%nNk?1>r;eR}uf&3rF%#_ATf9)A2vjfBqt!A4~X9e$0z?{{`Vg{Z|qH*-J+9PxhSm zcHi+o(trL^ogYj1P=3tIbpHk6L;Y6~|Jln&@=x|H=ls+0Khl5x3Y{NI_)vb#D|P<` z;Y0mb5&zlWj^v;0Iq&Vhr;eR}uf&t4H!r_ATf9)A2vj zfBqVsA4~X9e#~oi{{`Vg{Z|qH+3QB~PxhSmcHi+o(trMXogYj1P=3rCbpHk6L;Y6~ z|JfTy@=x|H=ls+0Khl5xCY>Kk_)va~)%_QQ5A|O~{Aa5p`6qkMd%N%WAL&2eqw`}4 zAIgt;v+lnje5n5_;y*icB>!aJa?U>;|0Dh9Z_)X&gb(G%yjAyK5I)p@74e_FZ6yC> z&v|e69seW!=Wo~fv4juh$DF16F9;v%zl!+J-Z7GYvTr%(pN{{L{`0eSek|cb`7!6{ z{tLo~`mZAXvv-c;4PEhx)G~{G5?_ZF9;v% zzl!+J{&6J#WZ!bmKOO%g{pat~`LTo#<;VP!?!O>>sQ)VBKYRa3{>h&6-tIg8NBYk{ zpz~u1AIgvUXWf56_)z~<#DDfLBl#!$mUI5;_#f#%|5u$KOZZTJ%)jaW3&Mx`uOj}l z502!Y>^bl4zTh&6-tIg8NBYk{rt@P7AIgvUxbD9oe5n5_;y?SuNdC#b z<(z*y{zv-H|3l};5Be>(n0`p-YB^J57g%8xl;_g@e`)PEK6pM7p5|76d3Z}%Pl zBmL)}*ZHx859P;vLHAz}KGc5|@t^(YNdC#b<(z*y{zv-Hzo_$L2_MRj`I7FxAbhC* zD&jx;@<{&4p7Y-BJN`%d&%dJcV+kM1kGVkiUl2aje--hcT{x0|vTr%(pN{{L{`0Tu z{Fwh5SAQGx|Fv=c3$o|DwEM_UHPV0fb)BD*@S*WjNBrmC7{`w#`<4^_iTsSczXiny z_uK9}{zt}7R!8_Jd@%nJ|M@pZ@=x|HC;Zd#|E+QU3$o{a+kMCXNdMWlW&Zi^2Zs2^ zb0yg0?=OZn#B0Sr)<6G_%nvXB&_Ds`--5mL`)$hs8-6PG`)EUdU-J$>&CNjvwQe_ylxOaF6H{_3jq`<|<-{_mgeH2F`~ru^oYOR-kn?~C%^FQwlr z?S8*>?%zi}?zp|+dFuC3`R}`uKX!df`1iZasmEZQx^k%=OG}gbA`V;k`>tL6xqqSl zyUj^w)?n=WZ+<@(>N~Z0_2>MI{(aX;{k!|m{k!_Fu6Fh8_`mSpSjG77(<1+?tMl={ zy1L7p@|)dhX2|6?>2W|tpolW{-M58n^%9%PmurB)g9)7p8QPs@8Spi zH|@9m{o$pqJ#XvyzvMEkVw`{ctJ(Nz`-j$_U)~OLaZmq~{-djZuipp$&U169nK|T` ziv2$D!{N-;@N`>0+>dOt?QhNbo4x;S{nnDdE`DeD3-!O>-jO3Q8=k*Oe00Bm9cZ7d z|HZ3<-`D>3Sr&Hu_CM_RwP)LZY5MkGSe6e3{`paXvhfuDX7_U6Yfq2*_Pq2C{?;L9P>*tr=0L;J5ZzC@Da`Z|p-Pe1#- zOIbkryPZDo@;4tprST>3H9NlObZ;789*4~kgK9qg^_^$u#vHiu$47W&v-f`kj4z+H zIry98w=}-QSn{_%{G{sLM|2x(EL{}p@0 zi$_HCH{ja%E<0J)_o&}Xz)|0a^t-Dc;qWIj8`|fO)XTSo<lAv^S^d(apjj_FWo=aW*#Tw%b`lKbD=(g!Df=5=F@jKxHxxijyVE9 zwhw;(IeGrFWa#fd6KG-N|h%o;I)koS)$MWXbF>Pw&akqWQ;5 zNcC^;WcV}j6XwO8?dC7K_Qm60XkVr2+dp6#o0|X4&d+A&Kh?kI{9|gr*w@T#sr~NT z_}T3Ir~0e$Gjx12@A`pT&ou1j1ZWHMB4vJuk55BmH8=iyvONAnyaZeuAJ>3u^EdfZ z^`R2|&RWH9FJY?U_FI*j*B3J%~HdVxb_B6SEef-yC@0X3oc>U!_ z|MuxRKRMw;`6-^E`!|FS^$K9ry0*}8v2_)!1ZU+ey> zk^akw|C;cj^|#N_>z@-o)W0cp{{`Vg{Z|qH*^Z|Cq5ey<55+(FtO1wi2lv(d-#H)1 zU3FjYKGOUjX0O2fqA)*^=Koyqn0EbkH$O^zrTI(ZM~I*OXnqTb*wpiLss8HtEIogS ztlvxVlj3Lc9CGgGpO{Bd|A{OJTbe)9+ZWK5;zx)bJe}ev#n1iI_=Sys)AM<+yGZ?~ zM+iSm{b%YwQ~wDqqMJWV{U`4q95YkvH#t9P{bTAsQ~#Oz&(wcMVul1GBpDDRH0r$qda_sub)8+Lwxc;UDTwPxYxVpab z`H}UNfUD~(U!a#?5I%JMQ5Er@y-==SpY@d`*@tc+uCJ^|`p;ja^J57g%8z-m?!O>> zsQ)VBKYPhY{>fhCf29BXr8+;B@S*&em+Afs!iV~=BL1_NkK~{1MgB+n&tIYQV+kM1 zk9no;zaV_5|0?1?``eNHlfB6QNdNh(bbc)1L-{dh=>7}Bhx)G~{+6|70)nKhl4`N9V^9K9nExX5D{5_)z~< z#D8|?NdC!Q_z@Z`p@64^J57g%8xlq z_g@e`)PEK6pS@!w|70)nulUDn%FmYPCl>JipKG45cX~b3?EC3p-|vHe1?9R@0`CtBJ|DJrhq-XL zfBt?S!9V>{ zaB9D1@8!^rX7fv+|Ka&d$iExs_pv7ZPgPNV@74dj^Sm4)!x*kls>+?3{%;-h36#4~ zed77&_jl9ilf$R)N_T|%F0|37zR|6lxv-oI9WYyE%r$p#PA&*@vh zC4Gy1b`7}J|L335>t_iM_5bbq3#?m6Kld5`norBuhh-LkqWj;qogZCr{nwA5%{e|@bpNpV z{X+zy2!K{b&sP^Rzk5wABCui6|2|fKd_9t10ax|MHzN82@KO4M>;sqYeqSK}FWJA- zAAqa+qn7mt+82OJ*YEU)f^$s~(kHR}k2cviWqzIh09?~YHQ9&C$NJ~r(yz}dIKRHo zwYW0Bo%GRGou6K`KE*cg=@&l#AdKHP^!n7boxh*uXHE58fd4i1KbfCS`Y5#iEa@X$ zA0J=esp+FnkJLxycO&@~a7iCv{>#57=WnM^03V}|%=h*B6@*LqzXDv-N7;Yt{!756 z>&NS>6`bpbQ2j!h0{f(PbNv25<`;1bxTcTH#d`gV2wo{TzrN75VEwX7l0Mq1`e>5h z(({3~&HA6!7I;43e#YIuFgV8X`4>j!AA4z}|N0-f|HA&IAUse#H-4@FACrHwAIsxs zEWZR?>wjy)@o)XjjZc5lTwiE?7VlsAe(NXH=e8JrVwo2Fuke#>f0^xvc4Ph*Jw95r zJ`B{K>;Db^{Cd*=cJp&^jF7?0p z|1GxvwctPL-?jbz?`O^|AhN>WZ?YC3w!!hjzTY}jf8F7yxjE?IwvulC^_UkKbI1uL zo}2xCefyU)pFw@x*tfcIsq@$Vo^5F^xePrGeSb+?zt*2$-VSqdPyZACHs|vRWN{;Y zzwL-~a;zF{@%er2`)%JJnO`zr_=XKjsH;pj^`}kQvb^}HTv>5 zr=Pb)>Q8v6{66};27A2z(1t$q?Rxo^@KE{u`lRo-nFC~gmP3_d=VI3v(AWI=vM|3< zn!fK>+Nkq08#q55-{<>n_HH~sweQawkf&09g4O~p)6L(c?_ayFV`-;Z%lvfd$oy0- z>-}qXke;7P!dbW2?P5-;0mt!4sDF0-`@x5r$8;9cJG}pv@>2!&=s&cfO?HS}eysn- z`jud><)@nbOXcTRkjv-SC*>y#_EP>%`RSL1=m+GFj}PJbg&)a#Crx(=|9+R*eH#9aKMwNk;JC|w-SvU~@yAQPpZUgT)%5e- z&i|50<1@S?iyWT?{PXrFte;%`{Nh^X*UOariVdSUOwT_R;M({uJ6z5$n7>NEF~3b3 zA+p|Vc&-Lq%AaUoTh*m1$6ufA->nTW(DkpK|E~XQb@$R_o{-vOX>Rpo^fh$; ztDAQue|~?y!yMPs|Ae13{}s5qX2MT*e|tUOp11!yJXAPF2>km$rT^poN2sl1`>L+i z^gp2@xV_Z>WLMYwpOWxU{}!qfuLs)HV6XK*`H_10mhe#d{Q4w)Z?3Vf{ZFs>S?v6L z*MDr;`LC1CtRb@e>ulyf{C*scx&G$!gMxnQ|NWDp{YU0KpD8Lc^L%EKUwDi1_Iu^0 z;rbuvKcSD}{DJ=T{Y{Nu;O}>t>z#`A^z)YXe%|i)H#`56>-WpsZ7w*p2>5UAKlZ77 z^XlK_?|H^A+VhJ8zPl9EK3E6rv+`@n{SWWILVYRPS75K|!)rJFYp8$3b0y)hJF{U< zr~ya+A^T9BxD&L=uhZ}Pr2JEXy?TAum9MW){YtXu^=|jw^#d+lKfgbr9KPH-5cQzssb5lE=48hUpW$txLPj zLmr#Kj(S`&6(zr;zRI$G z`YNO~(B6W*rmxHmWPOG91>vwev!Q;f0GITWtN&4Y`6c1_xBiCbYQP`j19Xgdezfl2 z0pyA!qXv6*{^hsy@-5** z%Qwf!@jF&OPx}8(pQQO0SYLkXF&HUbULu{TjlVnol0Nks**fdfll$n?U%wJ7>FWaj z_yAe~T;Lyfx^$j-kECz+!qa-_`Cxq&@aCqL+<(X@ZE(!z$Asfy0Uq5%P(9MB!*jBC;(YMu2WPQN(O-O5@CdqFa(Jz3j`tN44 zK63gGa7q7R`4!=?JF}sEcC2n+0{+Gs%jN|7&u*??UkSK&eKp~sBCvk>E%f?Xz%~77 zZmHL=ARMp7-}wEN^lJt7TKU;;>*be(4=uk2`xU?9be!~SY<_01|Nb|wFKPVF=4Y1h z?~{H#aEa@VM%PVr+lHQB4UE71`k!vjxDXqVuUGx!u-=+#iVL29#j^IbzMIX@Nxw8P z06n_<-UI7D+zp#wzg)d>IP*X1mn@=R%3I6%f#)|#znI(T`Kth2%kLH8GnI!EPJjHa zp5IHtCHp#JpC2z@Kjz#DaMVws&DHO=a{V}eA$<_yl$V3$m*8L14>gs~?b>~(k4_j~ zKP=yZebNueXggoO`M-a+QPv+VdVU7)+B(mFJ+9CE*DqdxHS_g?f86SaHJAs(;zC=} zAHYhRhx!s-|y$*Er~xr?fjEoSp53Fd7lqz`s0|0{-}Om&M!QFhH@q5 zr~D7}{A>Z&^oO~8J_@9(_y7|Ow@&5Vc`p0{hnr{HLI)v^y z|Cqi1-SeY1ua14cPMW{qgwO78b^UPjhACE(ii)r5!qbN+_vhy0Ip{a^vt>SyjQ^B1ch zUQ+?~EAScGmP04mxlqh7IO&JIm&5n{nLbL-Kh`||+4Wst9?-wD`r(WVpcO3ndci+d zbVJ*Sl70XtpqEPTKWZZa;%aT5f808vAIg*D{J`@|C>OY#c~3om6@Y8=4;A4P0w#NI z{@`A6{=@Q1!Y5XfJ+!YQ_W8Z#>qq|;;97pp?jzTa^EXsKl;B@|{z2tWu6nYE*Pq{a zc>VDDE!ZdhfSji1A3y@+cYi*kJDz)fb_+iL=%*hp#CY=cf`6R!LwJ2aT0eo&Gto_K z{DG&}SU=n@q93aJ%lU!lKS@92576_g1zgh)=7Dm4#QawPj``bZ737C)F257bPItRb zfBdO#Uji=WM_1;9^y@1K57m$JH&j1V;9t`Z*@N}^m4pweAKKJlFY&Y7F&*9s#SH(; z^!y^tKX~uA+ye6tjShh46{M%SV|spcy1Cb%VJqgsI%e-%D|Nco>Ve@yw`3tM+M zw0~U7{QpO>{Qn3!Kk)n#$_1ETO0d`RR}HwD|4)|lqs#w*qyJF;bLSqZmtPPr*;jzC zgl-;{nV+Kjw}ean&7V z{D1a&m-2|3-Cy_of4ToWWj6nBrte=alD|p&Px*f~a)9F?l7I6=`TEeN z09@m*B0S`u-ybpmKS{p6W#PKp)1iCbV)!{}|7ra1cuDIIx4`^=H2*KT^@nNv&)R>= z|GZyp_lNe6YnlHa7|Z`pmGcA7FQHt3IjIDDEq~R3tNH(Fa(;CAA8_;^%75mP>hIscoX z@twy1#9|u%Z@lsU-e~@(o9938_m9)_|FnJ(LIoef@5AT+4~^yj=g9ei=a*0}z?@Wq zy_Uafz}5U;%K6ddf56dyDF3;0JM{7k!X^6(@D;p8femf)=j#3~;gWyzH}dtNO#!&Z zUqyJxKfga>{(qi)eanGs=BGmUoZ~6~r}ckZZ~b39|Nqw)u@(6F-d_iv@_)+z5GMOL z|F6XI|1LQ{@ca_W1(=gcu-Ece4Y->Bcgy+F<$u7@e<=UCbEoU&7lcdp72qr2KeVAu z{(RlPC0z1vULao|+7y6m{8fa9{PX)G=KmMU*S8$HXm&1i&l$|-|I+-w<0Z}i?+^3; zrpf<)zW4P&%Ks_GS^NwEnN@1t#r3J^$zZV!J=#XTI^#T0Z}OQY`gkh*XZRJgiH1n;4AG7^FGlgf35D{5-#~S zuamD2Z3@6O{wl&l{`vh8^Z)DR>s$7&*FOy1bN)9&<2yb7Cl=H5|4sS)|BSEV{qx8B z{&CY{-SCe$8oob!|2NhA$)x?K{LgP|yFcM)-{t>j#`6E0VKf3%6IQkFeKX-0bFTWsMvabMNX>XYKi8lEj-M=MV@^9WOUmw~OfNT6!gopg| z`y=N6Gv(`B_O91I4Bd17H$&q)<$q#vw*TLx-~V4--TCzbFADP4^z-x8)$X|aeVPmJ zjepv_-Cz6u-*Lz7HLI&rzYop%A%AQh9-hCfuI@6Y{3iPE%60GYSzXnBzrCwJ_fK}6 zpYHb~?!HNEe6S4gqXo3Fp% zPiEWKn)5Szf17$te(%DsSO4GFnDno*zFJ*n@sG4D?Ka;&%fgP&PZOW;dkvGVV8gM`b7T7RZL&V$`X;1BP!pA4 zuj!{6a8-Z4UDjt#e*%vFL;A~|J4-LW09-4-B0NB!!Sb_r=;fD$OZIidK0o_V^N^4+ zoWtw0fNT7kbL9Gk?inu%{TE=5{Dd~dEAk)09Y61s%jfYU>EjaYweoB7FO{FaYh3vj z>{mk0;oP!tzC9h|chW!3*Zz|}Cx*NH*zq@`53TL;Y^M)5-tU`s`gTq8d(!8p>+_eh z@w4Xo)2{FDvz**VpYM4*wx6zDkdE|q@EZKC>^kt9^nIIc!k)r0V@x=$mm0yB=()Y+{`u!dtf$Q(!{O>&d|73nM>HF2y zH2;q4?Uzjd`Q=IcbmQBZ_a9s9&u5=*-f(qn&oO-;z8`4WZArfa6_6$2zP0h2=I7Jz zOEvAIiHq6i7xVu#vX&bei#ly1pv_*YtZuc-LpJ9jDJKS)XC~ zCE?7h+eP~taIO6OL$ZEEdkeUx-_3_3*H5_Ps;gPEgXb#1CH;ta{t?~3B|PLmbkBGd zoXtn&>qoo*T+{Cr;i2+*{7Cve`**$k5^$~jn((3J=O2^#U*=>5_GA2}`T6wyndbX5 zNx!%H2j*L+w%PgDPIm^!PxGuF2 zzb1TW`T6JN_+RE^1@>e7CjFoEf71WZGMWBK`hV2?{qcSD|9S5Hh12?~{hh;Bk1m#vYjLCsWwy{50SFYEfb zBs|c2IQ?4#j{dPMf5UV6SM>5N;HrMVK-P~=zXPt7UlH!t4Ue6EzfiX?0e?)$7|ywC z{;Ga`1>qrnLidapg*Fw~BR`=H@$74Q`6c0@@_GD7`n?8wt^EA!dij>{q2-%z$nl@_ zyS{!I*LU0L^~HSsJI%kc@1O0r@4rm*_i6qfdZ_hUe{(hHxR+x3UD54rGD!Lzm}u@> z8^1}vC;i?uk0ve_t>51g(eLJ4vVP(EE2ITcGnHVk>Gv9NO+V+~mh~IzUkkXVpUrpl z@(aMV@+-oddoumM)87~A<(Gs{TQ)~%Uq|fo@5=lmzZKvbzuEWX`i1Tpucy0zV6W-t zn*4LSb|0@V|Gr#4j~_|DTd>#4H~+0)e?d52i@)_LzXJOe-;j=%h4by{7{6)$Jr`hTat|3@#sBz)SkIdb|NaIO6O$C2wNJftt(xu3}VBVGcI<%c#`Kf*)) zL-&mPL7V)iGXIEMz_s$t|C9OQ@gwQ?0_-*YUXg!Z?{?qa-=B>uzXbc0)}i;g>>c}u zF@7igqxStZzkl3m()(?Q>Dl?eKz`|TN_xKyJT7DFD}v8I()%a<_q=p^nD{EqC6{6R z^;>_tNc}lk|KB~onfd-}yDny;cTYF3$NBf9-`Vf~$@(L6zn8y|^$XWuA+6#x<1cl6R{*Z*_lod_lj;ARKKqrd&#?TG@M+8D$mv_a zwes^{%lZ-RE#RnM-L-m!xO4v(xqiYW`wDPLKcY>3x$fT*9`YZ$XZ#YJ&0hKX5ibD8 z>kn%iNe$UJmRsCK9u9aUCKD7LN>53x%%b|;A=VJUO{hsFE)BHQM%ryVL zcJuF-cjHxY{(UpOzh;r+pGp5K>(iv)F`>!)%<9vm-x~?g^lP*HtgU|kKt#Xi2g>?| z>#vYjLCsWwy{50S|uz|p^CpC6=`ZvofzyE$0ak63;IxK@5e z_;k&iBec&B(d|pXS3<^c&Rz2r^y@1K5AhSaXS^u1slXoj32lgHhw9~*gon!K@gwQ? z8tk?5^DFA*Tf&EyZw{0BUk;JN&c*nh30`gsLo(sVwRt^)$bpQ=y!8vS-)`o71AoGnM$xneH+@G{svsr&-qnk{f71ya7{m( ztLo(!fNSMfgiH0$uBMk?5-!=-5&Qh=GXKbL1-QmP@pT7RxZPM>UVT8872f*Sh{eJ8Ipx>!`>e>a36a95V8{_+{cKZA8-Tj%2 zr~G>Ne}B)U|CRM=((f29GC#BWH0k%Ifq~*!2mStuh<>lGE9)1oe?nRXHB){)U0+$i zHT`UUL)LGo4-3FG{az8?a60`z+Gp3-%P$F^wrq~jz6M+?KhGl9Pk2aQx^p*>`A572 z9Lo=Fu6~4v{D)r0V`+LK2<(FW; z(mM1$m%U^EFvjmBe{}jYFn`AM6&A3R*1vZ=r}gjZ@0X_e_cZ?=n144H9f2*#*YAEm zlk|JDuFL0TxB2#2Ho#xQS9Gkyuq=H~MCBVGWG*B{!DpNjBM`8<9k{hr-IFTVs_E59au zX!-dqW&W2#7tPMa_)Ypft$$DJ-=Sru_3vx9{(bMXE)VJV+usU1DPNcR^VmthC;bj# zvV^gc=HHP8e;b;=k2oi1uC^bLSM0D`uQxfT{eJ70BKkeQm8@U5{t9Uo)JzrFYx*j? zwXUB_!Y5ZV*>n0EaP%M2XLv5Zjb6S5T+{F7cV+#E#+ye+u?{TTLsA$orAzdz@6lfJ*&^dFP{ zSJtO#{S0y?^D{fYoaWz~=mN#D4(n&W9?|b6m-P$RUm>l6nyCbP)VHC{>2JU_{hZ%H z)^BKU0oU}ixuafw0k~FvMYvS|>`r?5CE=2N9kI{vEc1{2R)A~#W_OY67rJM>p6>pE zy{4aQ^3UzseY`*UiE{ZoekA>F!Couh{GopR1>txt{?@1b3hY;WLpoj-&bOyy{7&*m zT0i4BOW$8j-(OvATTk-|zsKrEX*<7O;0ewTeV;e!cgTX4_zA4P3+VSFkxHMpnfZ78 zBjf)bt~=TOH#>gr)~C1Y2R8Eee<%H~tWT4E$D1wllk_|CqqRT(IoH~*pZQKizgKsc z^$XWOA+3U%DgR?#Us=F4{cP?b>o?Sg1>l-~uLwt${SEE2ll1aS!hKsjM*A9Yt^E9+ zk?SWsq%YmMd&&GGUILEghc;I~!bAQ;_l)~NoBZA~|A0Kcw%kvLHi5y)AzT1Pyb}xvoY2$ z&5ob_@t{BM>;L`X$^D=2_X}Qom0AAw?D6Xnj_0Z1p3NU?KK`6-KWoR|L_f&mt37*I z|AH3}zpwSpw^`Vkj=w#78ouWJ{>GU85vw!r?~l#Xzx3fJjnA9AK>2Sbf28p_@-v@4 zpLc!SF<3-k!=;NCN5<#n1LW}uA76#WDmZ>K57ftR1>oBFydpeMeK$VN{!|`+VfiKD zl6?)hR(}2o@;mL#-D$tmtPVt+1C;K{Lkh4 zkJncLj@KXBT>TyrsUP4gA!9h__JRqX_&+Q3@=L-)<@5F-%|Fy& zua%$wga2F`7JR5x_05_NoL322fA;L9QZY5 z96sCr)||gZj=v}UuRMNC<0Fg}nV&R1LVmjbBQXEv&p)i~^UI&a#z!a1`i1MikXCV; z>5;m=Dgal<2ZSR_{^s=eDUJV-KErb*;l3>%qkRpyR(}2{SwEt^1swIGRK7Via{Yu$ z_7&id0so;5ZSqI!{w?7l|Dk)v%W*c3k*^=|0&rD76CNs`$B#6A$R4YgUjnX`UlTsG z{QPlp{3rdcKOe&9H=cgs`a1ah#@b!xR5zhBtuL(Ap5Ju+C-?7kiM5@dq~Bq=2Ge&z z{?qSQ`_DoA=M5YB_cQLr?k~l^U;oq1-FILw-?a-tzi-FyB_H!5V-7i?#J_L-;684O zu5bRp1jZLh-=Eu(1E1aar_;y4kAGjfV`{IZ>HGURSkk=DhvxbIU7zt!()V~5y8N{6 z`u-OYeV;!`);C-vX}bd-GIT zUt;+M;9B_=;eOrm811vC>GmbyJ442B4zDkJx_*5n;URuP_ly^XHZ|C*^YhQp%eRDw z%IEPT>3j1`z5D`jExszkhnAl`OOF3#PF7$)#_yzmoUi?-`FSF{%a0v@T)!rL592Fu zev|W)^!;r7thxU5# zzSM5oKZ)@>$sb+*?KOT+`kfe_)ekfIH_gvCDlf2pIO+G<_zASXc3!$&kF>eokCpUq z+Z%^J)BJUqm-g(u{8+ogTzDU}?(_XS{4@O9`SRbq>-VpXMFci1`k;vZtzRJLf39Cb zxgIq~@j_jnRDf&xGkcM&e^7sxfNT1c=Ous(`;Y0Of1@>C`*~|6vOTveiUxU5Gf6}jMeaW4@_oL3! ze+T9dyZNreA8p1J!Tz$E)T1?(#R`lD&D2 zZeIZYkdQH)Z4yu^55Ff8w|1f{+&$s#hcbOa96fOPpv+K8$eu<55@HQcrUHc2fumAjd z{^yU^z#;-07Jc=IeyQIm=O3QGLb(+4WAP?EKURQi`X#gS_}$IF0FL<=%knpup9%Ld zJa+kcRkyc*OZk^yKl<`FEI-?$Uw=t>sQ&1)1|0c0$afCMynMdj{%Po*v>1M3nfaS# zei65TYx>5VDf7qcB?MAev69LbyS_>PGhh2k&-aM*S$(icpYL_|f3xeG$Mu;X zx%^{z|NQ*i2%0?$>1!|u$6_Srjh`x5ZC&R8}l`1MQr zC_g)L{e*|=?|h!KSbbEG|Ij5m{s2dQL!0C8oicx%A4wmTV80S_4(FDI^X=(S%(WPP zCViBCpS<~f@~xte4m`JyKKl7LF#3DzBl<>X0X7HT>xA5&AMth74)eUPq5rfc1`-2_ zfyBVV80h9F()cosFF}pF?=x+#@#WEx@nwCktpEA=A*A(jd{X?KK0c`c*T$FGd-U;T z2{?{_LgO<$R}&uU18{tlzgM@nfPXi1abU}@Um9Q9_v_bhJ|LHmJ`2DXIsaaf{}4aO zU-r*>{Y%0_{BwS!@nsG6X?%(7r}YIu0?hw*<04uQ*B#H@zfRWQZT9iyV)VtL*AE8x zU(@xKi?07l>h-}aK<@+rcApP`JLa6=%f1Ma(?6aF_fz@{}!Ln z^KS*XrZ2MpXmE@;e?xsy02&gS|1AcH|a0v+1+!iW<4&v?_;uc{X;kZ#m7Hn*XhLW`^$a5 zABP2Ph4+hS>o<>&=&$T^a(?9bHIxf6CtI*beG%GFUzpEF^b6sVeFeCrU$Fe_3wrq_ z;UWEi=jw=k{-1jNE#PkrRUXda^%q~1>yLN^_#&ULWnXIihpLFzUjnY(znbt6e>^@U z{gr=Nj<4lVrP#Sp%rQ8v-`tzlZ*GnCn_ESHrS+%0e@gp_fy6*!U@J3_#;>4^)A)4~ z;!A7$eumpe#;^85d3?dgC!w(fj%l*5>f@ghaP9d)P56X>$)1~E|C&7h!}2ZR6RXLd z8$W+tw=W2vSWWia_!4lf{@FL=^`&T^eMc@I@e=Swj$do?Ke?*O9`cu8q~AYFIR34_ z@%WI&ujadQe5LVg?ENn3{ZswkKegG%e_j1&p5Lsl`t!59&D~dPXo}r=dcNPjk72r% zE>vH1^UK}yCzxOMzt8Bezu3^fkGiJoTPN#Ny8Amb|2}(v=llK6Mc&`Z^V#nCK_EW; z_e-VUM`~IiWX$yYNbB-`vfr5Q^135jUwmRj{}%r(>l3bTB>h{1y*B@!|3KG|mhi69 zY{%)>i)H zIscA}&U3Tl>hvR>|AO#P{c+9C^~q;w{Z8nf^D3av3j8C#p$+luQoVj9;i3BR>zDL( z4fb03`TywUTf&EyZ+60OuKof2)aiIyf06Y4flGV$uI>Bd zy79^St`G0VN8SBT`hU*#Nn^)H^R7=?UG4w=<38h~^!o~^jI{RWk00ls|JL;XJtF!) z|Cy{`xc&-hL8t$~Ueo{CWxD<@2@mN<)Vwv|n*PrJS1;cJuIYdCb6G!P`32xw`4!<( z{j*=__9fseA!9hl`4{#7FZJs$2oLGoHPQdzU(?^&uk`wrgooz#fE`xAxoQS)Wn z4pa4ONqESG)6amT|B$}HbNP0?d<(d$pATqosr&+Pt^A5`$v!(!w=V%-2^qsVt{+AH zysTe;L3oHi^jQIp{DkJudHH<5t!^kLS`0t2%+UUX?->C90#ng*7Wg%BlkRO4ZKgzzw_nc?)tABxqiY! z{Grbp@I~t5{3^OWwt%bgb5)r?&X1&z3$S1Dcxw-r+a2LE6!ZK~lRi%0Pj0@SyqNj3 zq>uMEecbQ+)fapad!gR?IQ_m4@3hl?VjwY)7}y95bn}CY(GPfuRhnN&^9wxI*LZ&6 zVUhWT{2KE3i;v$zV=WxBR$#A<53_6Pix#=n50|Iqjt&*j(B%eR1Q^9$zM z^7t3aF96rduLy7J%sltQw*%`RnSXRUK)+rW?E)LFAA4j(zuIHu{Lb}3D3_zA$Zn+Tj}mZAKh}f?s&AaW zy0NbREa8&9xrttWLAYdJ0WRrR&d;#{2acbcM))B-q|fkN4fvSvXXiK5%eRDw%18dq zv5VEW1^Exq=f*4*;K+YybK`@X%lDVxpO99?Yc9clCFC5=g>3krhS~(jlfF&*HtAbv zWl7)ebu%#I^=&{u`0saG!{66hhxuDipRW1$Cp`ZFeK)P+_NU+P+8^}q<0AUE{2e*} zbNvv?^-eP#r|Xjfa83VKgmc}{?mK;RtHyswpE>jxb94{cb#?6&g#<@|)SEc!3OUg9@o!|M@h6C6+aH|gJ`f1#Bn{kyLEH+_G2(hFD9 z>m!o>olpbsx7hmgzfXKi3bTT<EEP(p_L{5yH@%)eZQD@u&`fE>)SP-Klc15{ml5^AN2EI$Mo}EW&ObQM@TC;&2=|j z-xPpr`n4jQ-Ii|G>7zet{JXL`q}g%$hj0&ahiG2|u9ctPy}>1W3;2luhRWysi2C`D zBm58^@{i{#z~36G9Gv6jJFV;eo#W>odigcsq4LpZep18FqV%&R|6bMIp{vt9_4*fp zOZS)avm7YE@eB4V0Sr%tZ1|ss+62dweop#1>1SwVNk6ZVeoo&%=KX8hPYfgm5(8V7 zfpu8FR;Bp|r%$YHzP|*&_c7Tz{=45V z`^w`lK7I?0wQ&5F|A{_6w17+FLpQ#>pFaLC06!7Raes@qm2G&gBAlJ>cHR8N{q^!o z!aF0j1MT>5@B+M82k{`mEW;v;kpUA7yRUy%Ry9REbT0$h!+NA;`UGIvb-j$g1}31E0C zWW)b7c6~`dC;goCGqkd#pOb$6dVyUh*N1{W@BjO40sXwb-w%fivPoa#eGP8=!~FCs zBKo>~tgJ6$`U&-kd7Q3)3cxjeTM-_*K~8@@KB7Mfm+Wi6wes^PG`M7M0Y`o3uGRY^ z&X1(8%@ZU15FYZ6=c3$ zKc8f=YI=RlnvQ=a`7h1C@5}d(UVn1Cr}psuqpyvO59(*g`iSeRkQPFHRXkJIZx!H@ zeslWoSq(l_aXN7N7Vs0{82{Ga@LWx}kKr-e=g-#5w}eaf=C9@QIX}|)pdfq6f2H_$ z{5(hJw%YOGCefb-fS%E#?pU{Rj*$$aM#7n@X`f+~wep^;3CR+?Y zU3`##e!ksDJb$iUe+#%2zr0SNv4p!Pev4 z`H`LC74&bm!^sn&-!$ho&|-cBSlW<{zW$1FYR)F6_Dfa-xqGv%Uf6 z&*JM3*zHYmU4jcCV{>8)( zMu8VU(fD6ooo{`N*S>iC1n2kh{qcR*mrUZb>mSnh|M8}>t(qQRtoi-*{73I^dVj3n zUrzVW8}auOwDHSoWc*U>lJynWX9u#FZFikM1p5=)6W%B4(|otA|IpqN?wPtnv^S^A z`WNjB!kvNlAKF)dOZpS-v*$OsXX*~oz62bv5C7KRI6u<(r6zmd7LOf2FOdB^eh8QB z%?o9F^j`ojjStX&1^8P-&fy%tKJ?{pXkWglDc{HN7;S38L;Shxf3aLYUOwM%%L>J0 zi{Yo^kNorV?Y^tiOZ55|fJ^bi>$KcDWuNH30{azqj_-zSI3BycG=53XPtx-fXl3d7 zNqTQJsl*gxhd>a~zy74vGpE#+?)SjC&_*;4WjP?cLQ-*Ya_7&jh zAOF_h@LcvPz5EhzY5b1%HQ~N*Ja+RFXUOGqex&&yOZJj~^J>|@bVuYUo!6hFL9 z%dJ!PiT*3FUt#C?Zpen?vFl6oKWYA_ng8jYufg-9CO^37ch581e6fw5=auG?%P`8~ z?wtCtc7TQ~ggj_d5e?);*`8`5(U?;pf?C*=-BfcZ+`h zKWYD)bNwLR2he*9Ti-F^r)wX9@0YRXdsv|Xzh8bN+66XTKltvL{(7sNA9#KV?^?0zsr^0AK|&|?Rxno;gWp~xRf9H^}A~clwX{smtO(i zCx7#@+G0YSw-|o9>wib%pPz5{5ibGP?oUm4h#y|3LtCfp6K(RdW&W1g--dQ$*Eh8N zr1f#cc9&ne{)ex>p#0Y5v2K0V##X zUk2jW&z~FT{XlpZx4ORg$B4ct-zDb-nnyT*|L#UlES?!r$Ed#JP?C zQ2xVnCE>m;9;1C7vCsdm-}OuSq5^v@e`oKJub=bF_uFd;ao%G1>8_vr^YiUK;x*t} z{qpz9{PH?U`oeuUr3bC<`GzA&cKFH5GK5Ao*> zM$TVc-tjHYU%cV!7$nnw*XoeTyiJH4{UzTaL;i1QZ1Pj~&~pPz5{5zqfwub(A6#4oRtq%X|B$owUJk@Ur# z??0Up#2vKgqNH_wo&v8`AuR>%u1Umudc@?bG?^grBZ`th>JW zXhdJ+AC&V0&o7}|hdHSNd(8i#4Rdl<$@vxSOTs1l8gNZt#qS{q`t^MBI`4}J`1>3Kl4$UUw;23eNlk@O6canxn<#edpZ%+fRBv zLM*1|BkKGSvSinN{Y6w?(9N6vyEK1MATNRWw={pTFXt~l710;=<8prB`6ZMKFn?vA z(DPRbxRhVfz9t-l$KTxi!+*&6&*e|TeOo+sn&6YVeF31D z`F`sw#CeP1r@Mag&(F8}h?`IA_opD-{cUSVpS(_zzNo-n;xFloG=GuiFR(FbRRzrB_a=Pibx?)u3;Ki}>n zUIDJvFZ;U8FRzoNFG{dqX$$l|m%U^EFm`=OUnG68#q`B7C+v;ui?qJ8=_w}dKdry; z`%XNb@T1L-`8suN=P&ArzNl(BKk)n#$_1Fe@^9+-%K|Qq-_hQDOCEn?PA>q*{OJA` z|DJ6we-h44ce`kxeOtFL0hjV4zkW$ynD6MjxMW`gF6Bpl{gS>YF44=c0AHlO$bKm6GrZ;! zaP9uogopUy*DvXd{6{i>%b}af&V^!%!JyCg9tY!B{(hQko&axJp5B-~U&6oNWzKgu z%kMX*t?-EaA9;=cc+|D&`(1179|~ETsy|kQ=8SMD=hxu^I7YE_r z!G=?#KT_H^(op{RFmn=oJ{SJ^8^6Dydx0@glf7??$LK%*NfUn|`%QBH;VPEQJoo?B zZ^Wzb?vMMPshg(8(`=*of-{|ee*eji-G7ST^PY}QI{y?W@cUEF6aGKh;3RJ!+&|fM zeyF_N=3DnJz(IGO{%#Uqo%c?kX!ZB~>@sIvf*$sS9P&;=l2KZ~`GpUUmS#XsTX za_XZ``^o>G+&^Rcv4n@(kL#0vrrQ^UhwQg%`~;Bv@?Nu^z`4V}gDnu> zJb$MA3>*PpYpySNe%}85CGmS;m>;uW>FvJ+Tx!34+E1<6JAM1>#=q45E#VkX{)YDE z|7813*#4mZ@7k3(etF>&GPrR6?~sh?ZQ<=NFRcW8^%f8+NLZhi(Xt<$GREMR_y`%n4V3#3Ko z=PO6rf3>ZN@8^2;!b7Kzx6AS0CqI{9FSUQnuQlOPe$Efj?JeOU`%T#Xu6e@c{*9RJ z|2NF|8LGO7`0W^2aQ??~7Eyn$kFObNfBCZB{w(1gCv2xr`!fgW?WZ6-)P7w4jo4=g zH~vHR8@>It^YJYI1?ES59lXn&^Ax-Z{&{v|Xm{cI7|K~h{B~Ee1=`>BBkiv`L~noD z6-MSiuvhaR;i2|}?Jqx6x3`3c>^FM*3(SuO+8@h*7??}D%vE2EJE{HQ_e+*$c-UCa zZ+(65&?XNmQZ-3d9N9I4USMwj?Qv1uVqT5@-L-rd#|IN(5 z^l5))uUkWt^5162f47RXzx--?`?G{k_ZrPnul#p)z5Nt~huV+Je-Zoa$o($=nV-HC z`DeP+<;B@M6v(e>{?nsr(fRN9BJHobM$`VD=G6-iG5)h_j?8~xujW6(rS_L!OSiX# zhwL|D{)6`6-w3~*?K0>6692}}f3x~3wLj!(-|EjhM%rI~ok;!zTxvhP^51o3dwl*- z5FTnjF8@XBv+FhfL-w1n{q@qH=WpK&o8SI0)~2_Gx4#9?PX^|vj%Vv9X4eNoWEnO$GbkNAB21{4y~`hXJbrS=_rzK-p)9%-LvK~wm%<89k)(_n)(m&Kk>HR}~wBEjB{ez9zXVkxh@-Oxe=7xItG5Z4S z$E+W!!G7!Z55O-B;P5~C{tc`j>U4pSA9tHew6qsG6~{!7BUd%||y`Xj}Dq@GwLfz+-M%0^ zWWOofUp)UUUAip;=KOwtALwJKMaqBe{Mh9Cv;6t#Uq#xVxw+o{3c$y-ze=%p`R^8u z|4{ou{aX?ayEB{1e~SGUZGZ6mGy^VD``Zlp@6<^9D}P&We>LD^+F$-Vvc1cHgiGzu z9H-kCgoo_6YWsWl_9C@Ee7d*^^yd>J?a$m=Z+`{gW7=P(*t`69o5p{r{kZ%`I0W3x z=JKCnzg64cRbG|>7yi6p(w|4|#rF+wtofH`MA~0@yx#t5z{j+|{I;^a%YTGR?a!Q` z+ZTj~?6+$ByYv8Te>3_M&e3#^+e_$hdq4{S%zdHE+NqqdbBhvoN z?ez9n06wPuRf@gKf4|@O549hc{|Kj$n)-10PqE*s?eDV(+&-{=VISnb^n4QH(bpln z%skI0cSqW1d3(Km)__axv(Ng4JlE|rYH?Egv?J}!9mYMMEWv(1dOpeX1C75}{NcTV z_c#8}cD!qTexA)g3x7VD`UkiV?EcXE73b+6UJ~ga?49)f!Q5GI-#367;wG(cDkAoo zvo=QRAF7e|**~`Z~xg{ z<@Voa{X(hOJN-?#)c*6k$>qE8H{l`sjjrDpy*?(jKTIxd`Lj`S^l2a2J!O69@(bXo|3dNI z$G^E(V-GH7HrM_D$Mzlazg64MPruaX{m$hKU;YV-@44I0NzX%1CAn+!10AxDq3x%? ze<*CG{ghOLwqCRCCp$lbzw!Sr+$VyaqXu7`^Qj?{SS=qn*4|2yHESc@2j^T z3;6!lex7_}pZ0Tk<=+qgcxe0i>_^a3>%Wat-+S=+O|SgZ-#?T&(|-JV&9$h#iby{4@8r?e{zO#rGfQ&Tm^?AGUXEXnyX`kGubzf0!Thb?a>Z64SSf zs{awKWBSCPvHzbe4T=;!P~jXhn`)CbnD1YGLB zxW4#}Da+;n>t9Fw=MV1Zza8`QV$i<@d%XV87W;nhrqKTzvH!hH(MR~(G45uy?KpI2 znsbBu|L-d0V<27${Zsiazcl6f{}0t?{rfjJ|IhokUixhJ^LYK|(to|4FP!!(=6~+_ zyY{}e_3EBu((}&U=DznUpaB2xCi)Lc$1RXw`qlrJXx-l5wjO=wAAP$({qI`@{I6mC zd-A{E@)NngN8;^=4V!iq$-m|ya(=}8RsgQ$-wJSP{NVEQLuDNOSAa|T8S$);ah_i# zeNciu=I79c{%gV|`}{9-drNr8p4ZQHxn3oZAM-HTe=I+veWBPpehH7&FNCB2>@SDc zFX;y$aC-dq!1(v`cbYeUQOVz;eh_}2F6DRE%-~MIy+FOO%cT6ickj|ts|!+oKMJB^ zvVM63=$}Y_zq$+Nrfd0lB){h?a{k2pU;)?iyLrUn=EYQ=|KaQb*YdYHS;l#Ol=4pj z_FDd~2$$@$N9y(^;URloKYwlmxxkL4R{ZzL-}xze{Vd_J`W^1y9IBsrl!Ft5+7bEdo zJx-6`?D2a1mVl3mU-N_%zf(c64)J^Jw<7WDCga=rx2f7q9jr(Eek~HeX<_emfGs`BU`xwSa5!Yo0nT zeoL^IZc&Qg#l-KUFA2x5*?{r;gGl_Er|a=s0ItPv1^5{KkUt~E?^LI{4*KC|LjU`; z4H&;aj>K>EOg(ldT%$A#Z-5cGqK-wmdJ_eSD3-=W8^1zd|?^W1UqTY~+T zj^82kvqtJ4@pn}q*5{j_oqzq(Y1p3H{f*3{2c*!#~t{{kG_ zSIEC~-L0FDO^e|t-T%4c>wHISJ3p(%7ZkD)*H3;$YM)SFoV%NE{%&sm=3KuB73zL} zq2Kzv$nzO+*lo~;c>M$Gzq|W9V0|GJGob%G_5;fOxgGeN@BX+-OrF2{*Teds4Yqy* zZ_@1j>FO`M|7_;{hIHR%zYh}V|2J8D4ST=GreB}4VcPd%_`fa&K5W=^92Uv%`7SxX zyZi~bs(*Lu`Mm`EB&bIym-fl;HP}n~80(jxF6Vddztuco(rx(s+Je2RPoCe;f9U$q ze@6CQp=<~1U-tBWFtclS-ShVs==@m1L-phQ@O|#zyioUF5FYb??vHafqkogWLSEW!R)6~A_l_^RU%Sl1Ttf2CPxR+i$T{Zst3~pA z@iINXSAc8zJ$t#HA1&Zx^1FFOB)UV% z^9Q}w=c>OCjdK_HugCqtznblTyM8r||BqYD_!D_=w^{yU`EMP*f4h&z|NQ$Q*NNnB z^J+bR7l3Q|y8>LzkFOb*zb)8n<8$*`IX}Am2e?+hTCwM2J}H0auhZ*i2@lzG|E=a~ z;~GD){^s?%|AO$Ce_j^4#m(uPi2v*jGQa8h29P))|E$&cDCvX6=!2UZMZe)hpPTG! z^9;5md7I5oNguRqrRN(wekbqe;Q9NgNdC^Op1(`LwftQJuI0yKbzJ_gz+TJW*&aE+ zV16nA*Xn29EZg&(7s`+5zaaZICiy3hzpI}9(U-sBx$I2+`b)w?_2czFS{UEgivLBA z?&9RF{dY9qfra9qpxI>%Q|8stX@!<}0aBqH~5Gs|%zj>ecOYFHG z*gegdC&N7X_V2g-&VkO;fnRg)kvQf>#vF1&i5DT~xkc-b!2JRK+WJ82a`VsKG4WZN zXSkRe8ehJ@+4#EdshpR#9+UY~MBV0AZs1qtP5VCN3Wr|tu*0tu`U1UUrYVKu zcjCXB_wmcyVcsVAzcTpa8wT`^mHf&3*HHh9{dfJgCVz6j?Y?_H{B}A2puHu$wc(#` ze)lXrKNo;Mg&VPbw66g_2|h#h?{j_mJM`O90ts0f#?FME%EeI?+BhbAY$A@XD2*WjT)N%IHo`Zqp5>5u2TW18Pf^WSZ( zrulF8{F27y`@{VAfq&m;{@_Uu$N7UcO44UyATf{_*z62!<=IgA-b~Mru>N0}A9-Tx z|7AiGk{Cz~Y(fUMcK`3s{ooBk3IDqz=YQ&d)8|L>59;$Hmhe!(;QWTE^!bqjaCQ9% z;A7^0@(=0PX93sdf6Rv)T)MsjaBY680{jP|$sKU$=EpwK;GsVmJO6V+sM72l#?N=3 zz0FAF^je<-@rTzR+T8pW;3~gAXmH8C09@r4a4mlFi&t$q zUtdYMWM2cWm7o7e=hp(R@oO$!QsdYBtieO^>(*cWDq_F1&G`@6^Z3KH!v5y`AJo|U z7#_R+=P=nn`fPvSBh&_*|Eq2j=Wh|uuBn%w{l>WRvl~YI-(;KF3FL+NbN$OLwwZT8 zJwrIZeu>}wHhTH_?d0pj^7A`xbMYy@e}-`Q)0wSL{mh*r_vfy9{j-zw`e%Ql*S{ou zrt)xt*I$aS8tk?FP(Mh&zhxocU*3MC@~cPa5jYg zb7_4hMOj*(iSJjKGrqd@m<#xR!GTZf^L*tBw@K?W)B2;d{%HSRfwa}uAI*C`%j>*N zDYNdtdpe?L7Q=)NDk!=(NmpPi-e3+&&DeLwH+H++BJN!rQIO#hhXC;G1fNc~;v z@Al_DZ(cpP)&72+rzeDmP1Exe2Ylsb?fYxQ`3YFnfeSa5l5TDK`qYo7emwQ#o4o1 zLTe>(eMSYix<2p1aqBxR*sJS5zN%keK{!-(X2bO(72w+SWnVkoyeo9^VC&Yme6ztr zf8y4!d{6#Iiw&PIrh3NaAkaVFEIL1OLNl>%(mY9eev5tn{@v@Pd6K~bbAuW7=^xD{efmfD z{MHP;y!F=3W6BF~=AD|Jf5G)ZzTWPRNsm*0f%QRY9tJZ^($)KShDo}5XivJa?7WVV z4yXIasr(|$H=JNL*ZQCZ=9iiAOIp7H@ieu0@s-wZ+<%wZeHv2Ktt+5*Hbq-=@c-HS z5_ms~BLDuqyq7~l$W6G%1TnCnktkwxVRRuPuE@F&T|pf&Mg&9zL_o!fN)m5CMPyMY zF~lRnda$1S-BCR7z*SU40Uec9WKr<|*DLQ|)zdw{o|*2N{=Iqkujcbfelt_Ax~pq? zs=ifyjJ1Cid^~>xv{dh3g?^M?i)*E?w(~ctxUs)cBj+V17y282 zY1-hf@#eMoUUjSNUx@wTi+#2>iU-*KbKZdS(tVyd7=Md9xoRA58{VcqhyAa`UtasC zh*OR==WkTwgW|e~N7!F*o|(rn``lejoB116`&L}5{785H2IooG?y=otyEnOT>qw=s zV8|MN#PPMl9y;>(YJ837Z%Bof^Do5yE=B&OJAZ?5HTxI#FYI4NYSAYbpT)nxt+IVA z`4`9dXMfG#IK-|t?OVhj+wKqZS9<@H1nA`cFn?><9|q{u{wXQY$^Bve-g18!;K%xH z2kws|cG2yN6y3$20-b7KFid~{FBsax`TaB8|0URM5AyqC;e47NE!jhUpUEYEvNY$n z?e!w}zu70}x6${s6>8iwzyIX={+HNq5Ayj$K&Sd&s^~_w#VN`k?4Or!lOOdP1D)!B z;($F`eLpY)eyabaK&RRl1UbEElyQRXi-At{zYOT)_r(sP`(Jh_-M_@)G(C7M-T$H^ z>HZi0qr3mjG<0D*wLSCF-__$AbAFeKZ;JWV#r&8#vf$3ZjKQIqvu2k{EM2T#JzVu~ zfw6yzDsLFOVSaS*?>CE`r{iT&uacwF>3(la{e4}2vwVmATf||TGE4dV{Vq_-vNgj> zx5ZEC`M^F!JpWDYFXV{-w}@x%mVx%Fc>>@5Rq#3RU#t0V-S58?`~O$#iv@qbi{oyN zyE*QjT=DaGOVegP!bo@vhg&)+=Ld}M8#wpJ=6$izdh`5cp1<7R7JR(zEZS8n{-ekj@<1J4ctUBJj7Td3GRq`7r8uRPQ`R~FXbmxbi#D0MD9K24i&w=lF z+ug}lUt3%5w#`T>+h=jUk9{6G4jJ3Z)eFC)4I|9I{L|-(^?xTG+W7r+_DALH4Ci6` zJ2L5WcQk3&0a|Qi%|3GerEJTnE4FiN=la>!O*R}n-tzQ<7l%`i_2mb{ko?kHq>s!#>LWl?O&D;Y9n2Ug{TOFT2|0UC^EQ zYs>X{;uw1UPy}>p{ZOjtHZkS;sAK8%Lov|F^-*hEu8#tKa(xugsrCg=Zde}$baH(Z z(5dgYCr``iwzWjKa3}g#di_)UEPDM_{MUH#7kHs6e=NTDKAzviaaDguRXo3Gr18UK<lA9ihhmL!*2(zHRKkih}X{gW~bn_ZO~?ryKfH`wQ=T z78X(bozk=K{FW+Tan17&JhBc`=T8{-Gwx^H-#gBptQ>{gD4mr3JI_Dxx6f=J**>y; zoUGQacezStF~6wAho$)hj`_C(;?A$a%!A>-XU( z#_#$2v%LSoF7Z-3GA*W>;N_+IhB8ek2u2Bw1s%$R<bqh_%>^RH8A-!P_vJmf0=v_i6vqUum;9n15+9RHwf?6UO9f~A^!s3zh%7Z)+e#`Y&@n`AvNg2?o^-1C9==Dhn(5dxF z;zoM?RSfi2`@aG|wf-vne{}m2MYr`*xjyXkbo(Np-|N^YRj!ZvQck!139he-zV2RM zh4lEp>GI?6?;#F?!foYa{ppYP5D$TlWTRvG*&THK;-_@|;+J&&;eGDexH`te~mD|cJi_O{afDmf%kpr=iPCp-}fDR-DP6t6gmKiI*xLDXpFBA>%UH7 z`wzh|?~m5s9-zOiKimH)Wd2==fExbyn}2l5VUX|WVf`2T3(TFezhHmS&pxA9d_CTO zZvn_P`)J@}V*MBAN7&x+_uBi})?wSn+kQ>9`lbOs2A5FIkMuDA2)@tExR?C^`vLX? zlg%=Zt~?gpY}_i_&mQIT`i2V`!qbAEb zF?7Re=+l~gn{!Kzr=j!_q*i!uc7&5`SEV^ z>Gfap=hN%I7SQ#JJ?Z+zesulea(Df%X8=QA=J&ar>vMLVj(=LztK{f(@|8YF zQ%7BXvwVmATf||TGAN*0{s5W_#G|DHu1)z({V4gXg&hKq+WW!zHNV^%$5lLz(9bayw!JAn znC|qc760T0zy5z2zZmwP*MBv*0?w;(Uag;fz;w6oP3@cd_J8$i@CPb7RPpyRpZN0F zeSmMV5D%Y^@ui9@>#oHTUku(}>{snvKe0y2)Df}Zbrc+DaGcT4K4v<_85RRs%fE>G zeC*@kw`D%B$w4{jQ{Qiynk>gJ;9rK1uH^UBb>VMv{~~yOhKg@Ej^Q|_pM8wOOisDm zrd8~om+d3?7Z3Z0{zWvdzi=sNYWbI?T~*c2Ff`h~?fig)=9A;+8PLi30T5&%-FD#q zqY2Q-`2j2EiwkVba1Z%optqVI0Q}_qfP?AwC5mnn5#zn#WM( zgX?u{6y>Y>VsXXiasO7-5g)7p)&Of@I%uF_xOT$Hb{&Hm zHs%i+_L~@gznty2U738BHNYB}q8gZR1Kl8iMXj~?$8Z0R8#WdDr(U?G@%zmi1>1Xz z?)esLfHg3=HBhsU2EOI|#N>Wa!PPR9-oS*1n{|%U5!?@M1Q@+a@ zU=2)F4O9&^-Hx*T6jyo8zqtp>tX4DO*OqoNzPBiaZ?Ohg1O2Cg2{+IU0@$BO*+2Dw z?_qyE#`kue@?F*dYhbEsplU|xc9iXB5BPqdTF*pZ+uK=bpSgdQnon5W-)gh?(0y1| z_5K9x&&BbH{h{(*)&Ogu&onU6{-vpY`{OA4pC00q862P3HOhBc1FV6mtAVN=rCUulAqV022{q`qP_D?{pSJ2SOfj1 zfr+-yP4(NKNZCL2fbZupzPD?X@3ID115;N6RXa+zq-;NX!1r^i^-T1&rJaoLElS~A ztO3?Q|7l>N?Q>K8_9s&IPd(uKhcLdkYn1P@23P}AR|8c$O1GqJKYPIU52@BO(btxC zGQPJcg>SJ2SOfj1fr+-yP4(NKNZCL2fbVx>d~eq%-(?N32BxkCs&VLBYv+r#`bOn<23#jVUkAS~e(~g- zUSXA&$R7b6%XjgoK)=Ao4EK;fJZ`=?!NKp-z6AKG_KBy^?TZxMCL+q00-b7KaQu96 zy{+-Ui~QNsbGq$M@cASs&lmG-M4%x(eKuWw9L*O80l%#XDgO)Si*G?WHoB?b{o!w_ zhm>yvU4L{IU4Qa2zxroZD~D?z`NH#P`NT!EeBmX2^11XAyoRnndp%u$@Wyuai#O5r zrQA@P^~WEi>rbz1SATLnU4L`~U4QbKcJ;@frRxt< zy8igf?dp%dLf0RBldeDdPP_WUTj~16?R5R&U4HeiwAd$`%`*SYW^+xtsO9g({58YX z?`js;>U*5Am?I1B49plDnmKEBsl?L7>ea)df{!fU_Z&tupC29k`^{qK>3CVxE5z_F zxIY2k_XH^_@|*f`e4liqnC-2fyaKFc(_Ilri z3*Ht(@^|RY8G~Ue9{v^~=B$a4a`djD&hW4#;-zuG^I3h&y1W;t`j@R4HvT}K8ufSZ z?>CDrmm)!zJD~JX<%4T$|0?*@b1klm{&lhJQzPwP)$&U6gPt~vea|Y%-(&wO%6G`W zMLcu23@WJp-GF*dSaHh zY#sCpv5F7Y0Be9Xz#5qJ8tD3y(pk;_4&J^dtooDUTKSs+@gBezLm!TyDDW3uKc?vH zFD89=U;$YJtbvLKN|sSxtX^Hi$MK;x{9UzoYh+L;I)IZ;2AtffRKu670oDL(fHg2i z8tB^by8RZ%_}K3u$ep#b+e(HJ;_Jho1jzcr2nrdB4{gNP>~F@XBXO~;0oK5%X+YUT zH6@(@96%7S;f3fHi;`5Tb4$#f3ih zaWDg0JMQs)-M-i7zx&O<``Qx#`L2ziK=22R_*ab&vOnP0hBd$%n6w(G+sC?n?*ab~ z0{%S!@bA#1Z7>VQ8ek2u21clXmiTwv^8!NPvQ+cHX&i^P+&@J8g5F;v0y?#SNUG?j zT>2dMrwD#Y@2?R9o!UP{+|zFVkO=tKYJn=ha{mmVQ|$|WMemOi10BnkOOh+)FNNz2 z==TD#O8*Glz=he_Z{7QYAisEEzWAhrU&{ZN`Ql>uvugRsisgrYrOS`R0u|AvE|0@Mr`&Y5v(6N3#7QFr+_iNDo ztEw+v|35-N#cZqr)&Of@8fw4*Eaqv=|N4zTTmyRm4c#0;Nxc4l8g>?L5^JCjHDDUX z{JcK?FqHU=FU$Ei9bW(6hn2V{`917!CUvi4;aCIxtpPA+m7{KdhrH%*^7{Y&?n&Hw)&Of@yfsiU-f&sB z-{POW@bfvqJSzJG)MYB&86o~Y{3(FE^ZmCj^v2)3AI*4oNUo1Hz#8z@K*=)Z7lnP? zwk`j@M1A~k+qPnUNwNR;W$?kSp%Wu01Ms?UeuC|z_mkp3WDT$e##;k*`&h@fLo0po ztzLhh{VVSyHQrB=>thYD2Bv}rtoeg$eC+E`0JeJE*YEr2wBkbwe67FVSI5_#8h#!S ztLFo<77-K%{-#EEd~X8Q_p`t8c}Dy{lyxj*M%lyM2;K66`{(qzYoVY~R0Bd0UHBh#VcvZKL;yxey zIQVT~9{2rE#$RK&N22-h_NoSPFN4)>_g^_^0l7a(1oU-Kk8Q6B-2Wm~^r~!ljr(T= z56{bY@y9^Fz{afj#mWWZ1UR?x4;p+ny4;@w_;G&}+kx_>K&RRl9Guf#{4vn6d|Umv zzeomja{rY_())*q$1D)HLE+W%asL*SKU=dvJlj#f+<)cqboo&T`;QRi2WuCI*AnHY zK%Z9?4*nhwtUr6In~wSs|FS?lm#9Blw?Nzqe`c#fw(ptl@{t~$>ZW7;@$++fwS2AL zWWxfn9A3049azOo{Es+nJf%M`;%A*-6!X@E)%`|_Yc+l!i@o;2QikPGDz9>}di5|u zNm)xiKR^U)hO6Zbqnh%ggMYtS>^vPWi@#I*cyv15cwhZ}U4FBC#aEQ0^p)daGqay#jy8K1?s=ke4nYVtR7FDa#&yhy?systKC{$;YIB@+gX_)Vg;2pdN z^n$m=jKMG!NBrhe`48^sc^61^9CiJ{^RMuA^tIkEBo=R$8*%wPe-Nzl{Hx^|?Stnp zI-A7-XP~_L@09Ev-{)WD)7M)5E#j0pnWcQs=fA63p1#&{ZWM3w)DLo0`qx9&>?-<` z>aWGM>JPDa|CJDziANm{_(c|g|8?K5syv2%WrbVB-9rhSRsRm!k5B4k{3CUYasN>D znf+tln$gs6-X61jun)T3x$TQGu-ouFB0G<OHr$DFV56*GdkMhMp$MPRysX@jkif+?C(!-az^<(NE|F(Ld{0Z>4d49pUw0>fs zQ~Jpi-PykLX#FIL?&25cyY<8I2jC^yxlR04*iU8ei)&?1TgD%a_^?&{Vfq(G{INx_ z|3yon@ni9PmA*Vw)DTjg|vN(fsU`3%|4<1%@kdURQi$j{UW#jkoFts zlz$Qz)AB`%Zj%q|Pk~PPr{I1*xJ{PTO3_>}WErZXAi{F9~sc-arm-zeKqe?HKE z3q0q@fB55T%ll#CYe)IhA3y5vcp!c}t|fj$`5o>{*8J0Hhyeh40KAqOwn!n!TQ73=HB9);gW)C<99qhyv`p#;`{(e8aIs38Thx)#)mEV&hq{l`oX^0iA8)ko-~io%RevA z&lv0eYl+XQ^7HugP{;Ot7JOQ8@c48r^?;*G!@IzIRQt~+!SPM5Axr$h@l9iV-W2~e z$7g|3KgKstZyDdDZ=msK@J1RR$BM2*D*Yfn&wx(F2jQFA;p-ImsrVsybA$YfUJ_hg zNcn+I%KsL3{TSaQ4RrC=Ts~X<$R7cnYG118Hmp5p6zYnPg15Q#gYAzS=ovvr`NPXv zK40KBUn!$WXrV=LIjx^q(QW#X&ll*__(^yLt)GOTbNqx)3!aknqmKDO^5GWopP9c> zd{ukda(ufsKe#Ag)z@SGtt`IKgE%U9G=0LmA>n{HpC=(h5G{HwUytsiWE)Id)OI{O!VsO(=*3&qg^|MD2TV*j#y zco)o{EBwL8{5$&>rME7AGyThRTKbphJ+%Ezflm3C;Jt49F5?%VWBg>Z-)R3cMaMU$ zdieO4@O|$3vHS$+SikK+`9$KD&&R(+!0*xzmY+7zgRO3U_AmH=rmugo#1~%kJI>tZ zvp#TFirOQO`ur-4pVAUfM_+g65AA(5{)LZ!vyJ~$%QNC9HU4wmFR*<5cX$qm_xivp zpT5@eZxO4$ltF>|J{Ar~$9H|8=F{cr>%17z*(mn%)(_SzD>v5nRm(H-Ke_G@Jg?sG z`cL(j`N&uuU!*yG@|QnS`|*?`eb)C?^j9dYdt#}7>gPvzepvSb*XPff&v(T69dmu( z`j+@LeLs!wg6(d6h4?U5^lqcOXNcc2pi}rYytZY29r!7H8tiD0U(vf#ch98!Kquw@ zKwf^At9vH#Gtepd#0TBw4|a=kuHTD*pTy4%^x#8oe))WX-e&%o_%N-X2hQqH%n`Gq_v^U=ftY{$eseb(W1az#8z?K;1Z6;v>jkRq=g2zkc^n0)`fGDCku^VA)wjM@{iBEV6_)H{GQn|zb-yX=QksuyYjb~e@zu#iB$T*{AKVlcm7!BZ-L$_fBW$U`GHQ# zujnPg)rFM*6AkhM9rx$99WsCW8T5x?-w(k7mHv1M7AAPCd);Gk3hl5R*#6+>3&bno*VX<6=w_EO%R&7_chl_?if$|4 zCw@qQ-=!ZZ|NqeRn4qKl8PMB2-{=>#eo~<0^RXRL{$IMEpO1cG;HUJHHPFL*-25D0 zaeT$`6~4Iz{x$HadZVY*`ed=}361#uZ=xd&58(KHu#I|@Nwv4~Q;DyR^N6oHXMX?+ zSs7tTt>hV(_)0pz;`xtt{4@ITTRA>7`Y*>o4UnTd^_*DGbjSnUMSM;LI#tGuv6zGV5ZTKJggWt5n-wE(j_*(q7L4HLy z#4b*y{6Ht=zkh)^q2MT=Ab$+>OW@ble(}3pzA|TiCG`t*s(q=V+sYp_3U!TN1;2Oe zN6Ozo&j>ooAO4};^G$)Dia&!t()x)NeWd!yfS-!5!Ut%2LeM$B;`oZ=D>PCCzBcfw zGG0?FzFG|X_r|&8VEyEGUy5tJo>aVjE)H3lhiYr($AV8S`l;ss`TKtSeZRaTS^5vh zHyq!@dGFBie_@}Ly_#I{&E}Tzjra?V47z4`QIV8D9{8 zYmgu4r2L9rmOQ_b^8dX-exM(3V}^V9eTV}T&4#a0e;M#o_&wZ3w=Yq2TlqfmjTm<8 z2iqSt&{Kkr?F+=hR?jy9eo8;0vyhDcB1Ipmep29f^&ip0oK4&*8tk_@?nXuIX`2n$U6R|=kx0LQ(r4a zUOySfs(42A`H`zv+rD3_<)RqunUh({_x=7T<=iOVv>%@5@shf0|EcMJVE&J z=!0(kWCt!3&&5Bq96sYC;YxS=P^<*#l>WrQ?)HP&#o=0?7XiPSvMdMOL zQ+#{`=dWTj%tMdAXuOioUmZAkEMhJ$lQqB^U=2)!227impIiK+#lBbbtGvFL*B3kc z59fb4{}boEL*uCe&rh2CPml{J^FPN{hqT^d}cpjhH;#-;DP;@0y=|{%*K*#vm z#UHG07r!UKPsQir(GBt|dP#6~A>{`;DgR^I&0h`IxZ{7Bp8-1AzQ?=e8#Ef_%+CP7 zD?cXN-#`zZ;O3Y48KAey&-^2;p9tubeo{rZ^*p1<1fQ^gD?T|KS69|PX=R|n7GDOmljfxI(~Wd7=0 zwoCnPl%W0n{q}I{!G6^I56)k$I;kQ*qQ*Pd$oZ>?Z+QOdMC8f2&Z(h+ahktcp8q-e z-)E4Mdy4V(QC&YN?N3>LV|+*FXZ85EvP-=GMx1K`vTt(#-sYu2e@R>9{A?Q3l(x2laJbzWa%(eJ?s*jHh-u{G8wXOKk_+8`q zHDa?g%(1xT6#S#95zVobtO3>lYrw66!r&Dr<1&A>7C%?*t-e-bb=vITBsl+Lf^lnn zuJx_`oxaxk-zHL?7u2r=&oPp zXMm3N+YXsuQ}mJMAA${T{mAFnK+g!e%+I{2-SbU>-*gG49%TPJoz_pR=p)rn2K=u6 zBl9yars)Ym=ll%kXLx-vzR|__r!hXM-t;N;{ZCw9Y>XGeezctehibff)qC3)I z3TuEhz#5oZ8ZePrem*Yw83_&x|1sA2lhL35Q;TnP-a`8eeXaeWe|}@C&;POXpXs;0 zxcvM_KYvntKgKlw!}%G|xBezB=4U?EGCw2ErsLZP=&txw<_{FTZk_Y}!-AL6`HdLp zZSphXoCf)UPRg(7PWfNfAV1LCdZtib~e_K6J{tWnC&)4L)$&dWeMYMi`i)sC&!0*bh$@T$1rJqdEZSo<1_)53_ zIRDb0`4?V4tSrH_n;+x9et2jfSU)^t2zCG%DcxonsE+a$@>_xIbwtq1#2^FO$LxH`U65bOI<^~c4vnr}Pt>yuX~ z@o{|O(=Ep*;@8mm-3;icGFyHY^T%QA&L3m`HUYXTKP>a_8{PTqLEzVitNs}Hsri)| z&`J4U+aN#CN%>z#uOE&srPmK9o9Xq#*_+y}9}eHl!IpWyB8_F?&P13e?? zJU-H&<0HI&SiP;a_nhP}jFogTk`Q_i1^{`^sCqsMLjtDzt5FSP&A`r`Sixh5dGm=62L)%sU8pHW<^ z@rPFXyN&+**Yf+v^Hbq@2KrTn-~Vcv|4FW*<6H4=cYKQRcckb_q|%R!kAaTyvn@VG z{^06%@p}UNRD3S}y+M9OFA1(Lr2If9<-exg{M2wOoqrJ9==LSR?~-rOXp}4e5JCB9 zB5cn`w!eWMyx+|)^D{tim7m#8>n8#__54#sx3$klKf$%`_R0KA13e??ZSym$R}Zf~ zW}P`dMJ!uW8xb<_PY3^gv-ma&-u=F>vitQufcfRGfPL8=|J-tz`m^a5s|i26P@Dk2 zHhTN^!@$Nssr})C;i^9~+K&Sv0|UzkR*3K=2X~ITe<57YgMXcmyn6E*HCjJI%uRoM z$8|+>XG0A_%oMZ5p0F_BV6m*A7~}g}x2o^!p1Pp2KgZUsRe7NP<>J)6Uol{>e;}7g z%-lQ1nzn9*&xEg35*-dVP6SmhD`U2ux4`}N@b6~$XB>c!tNJe_GUP`H+f7AO1f4^DW zC0{7ZGpuM}s+X_cC}>sj{N}F-b-UrU0(`x7tG><~zw?$@T>IpTA{>{fA9z1Z{TuO( zF3))XVLkWOt((P_40 z9r=Un7K*F$Kd=3d{3*~~{sHO1^)x*u=*Fw+lrIDRwKd7|8&W_2;r9R7zC_V&MIgWU zXkNYzf3g3w_?LF}x%3#=|BbqS+5h$6zb*cQ{ofe)ztT%@Ty*opJ9a31R$G6*V~2qc zkhil*Jn6k6-tE)6AixE1?AS45FpPybG8AIp0B#ic0nhD+#r~Y?iN8<1?RA6CxO{`< z{mt=rHzvrdw#NiH&5gF}`1&kQe0|n=H_o!lXS3g{D)CF8F-(Yb(^ahvjF$kI%=|zWCD% z#WsV-JjMFM&(Q5p6y4T87=K#qtId9K{zd1vy#2$2clMBf86*EN)$=D~EkEPa;bBaW z=6R^G%g>lL+dQ}6L+||To)-?;@z=!WXT9wMkO> z9$$OgcgBBOvqpXi#-AqB_#fjx#($`R{4la`?u?=C)bh6teqD5#8^6xD2V9$+modUw z5F?l0J3o8t_h(Z0yPKbFp0nYWwuSv=e64$RGrr!d)T_G}_-5>C!q;DEz}H`Gz}G-0 z@%7Da{3r4C*WCD6;{OJE@O3x8iC-CRl z{GQ5>&V7x0{<_3Rw>IFn?>68!pp*FRd-V8u_rf_g!V5f z&|UMpu>3IVU;koxKfTxAo%Q7&*59ocr5vfo0@y!SHuTT%XYT$f@t>mWGNH)gVE@nl zpXvkH|Bh(rf7#F7{SWO&ba#V&{2#Y{q-4WRZ0pl_UmtDW-!WT1+o|G*;##d!9$4`@ zAx?ewyT)VvtZjW^RUQN1sP%tB4?$3B>@t57dl4pQlRQ_RN*7x-`e@gGS7K>k9Txp2o za-#5=Ublqy{Z&ox_pjaW_dG|t^lce`0Y9!Ev*qxS9{k1~-y=P4pl3i|3x8+J@5=c7 zw{(1;0v-8nhm;RCk+}efw*3>PgMWKt!}AY*KmFRTpLLt}Z?y6oS2gMX4{rTq|4bBp zI^j?Kd@S~t_g@mCrx}NojY9jsqoMz$e{}ahX?GwA<*O!z;I!;r~CtJ_rZh{!#kZp+)5U#sug%K4Qb~GJcpz(<6dzw%=Ah%9jHFT2zqb!1{w( zi^%vOR&)!yoPU`C9m{v=H=Mo5Isa0RQ`ySKdnjKD{P=uq?W3?0^4oauzCJAd-+TTe z=NI*O=&*bZluq^c87AxZ2ROf|J3su6b^dRx%V+#D;rM05-zOQb{qLIci}w-uLi(TG z==eIEOXG(O=&tx04QI0ZBIo{KSbsE+#s_HwJ=nv|?}Hy=;HU6I26QUF7|ze>hS@1j zv3&{9UHHM2&y`;k3*7o;e8Bm&qO;jf>iG-C2Zo-;+JBFA`HT-3AMpNY`CFjApW&U~ z8LR!#mKgR0^E-cOz+c%S8h=HLY5XOYxbcC^j{tp}A(MHE_#|HH#!pDk8tCDkZhjNr z*m4yT9|Avxzr->ce?^LJwo9L*{3+1e;ICjWw|>p`x$<+FC%-dkyuXul~qN5-_<@sfWI%+4D{Q0EVA4}(a5MRuW>HVX!{TlGa{tfuz z0Jr~>_yXux*EE;kK>r&BZhRp9a|1nisGHyPzbe{e~Z3uI~jZX$@BYcde`?j zKGK@7|F*$T4}8P@eGRCszKd|_ixu)MTUOtpQN3lQ-Pr815s&CZhZ)&|Uc_Q@+D21t5R0%B^3MU&owgF;ah?{I30Tl1KT~ztXH& zon!sc;ePxlI{1Ute*B4pKl9`d@nxwTD1Y*3zxtnr!E)u0?SD+pZ+kvdHGio49jff` z2Kyq`xb4eSZNGlZ7JTZRza6dpeZnUFKi;i>?4Pls+ww>Jd@S=9XNbA!kMFon_W^-l zPa*b~KB3|HBu}89PwObQp{`C*s zIQsR!=xP4-58XNX^*?`i|N7_dJNosX^cMg6mt8aZ^*_Fc`X4n0_0PS|zx~mx%I!DD z$4_mrkKs|YeM}YIW*^bNg-5&XC(=`bu5k|93)?=@vi#6pzR5oy3#lBkeoy|O!i$%( z{wMm?A3FF`PyX1!A3n)l|5V2hmigPfe?yP^H&A^5XK@%@Q`PVGMsJZ1X6Kiq%Y_g~6}V*lOL(0|k8-TfE)XZTdQe`Y}64u5B})s$?& zV&%d6`ek9Iwy)Qwy9->ZoJ+c>|&zyFp5u3WT| zf1KXGipZtQHuC@bS#JG9zOY>{8Hf2b@4nM5Kja%Hz5G|+=$0Sym6Kln%U&I^!AC>V%OaAzI?dlJscKqV`?f6rIA9Je@QxAK+e(1(8#~&Pj z7~P?M%KP_-owwwpRBC^>Wovl0}Ad}ZPfTb>jB zfAYc{f7#Zb;P`s5fyQ4c(6__i*~Zu9{E-*Y`%46;yVqw)eAPhD2)fyRmwe%i>GfR+ z(5d}}#2NJdLJ`o{f__~3O@V$k&~1m$_b0+L^XFr0ALA3oC$@f7++%#g_@w9z^%KS? zb)A@Z7@tUOIA;@B@`v90JKuJ|;4?1YV6or%{HgA4BKZTc&z8z*CHc&C%$T40W=s4O zo=xMY6zEj`Dtal6pMrB}{FDNn`hHjNGMXL}bRYbb0YBm!+kyBkJeS5#iK4ss#d$P- zih$k*KV`s=&&P(JB>p_#O=o;%c|Y6DEGcyZi~aDQe>n-}uUY2j^8U@7|0()75p3C z)8rL2J`FCU@o5TlGQW2bjZcG%8}MfXJtOEo_%wVajZYJxlli?@HRShzPUiQ3-UgqB zuXf{4#HU#UJ-&qI4_=egZTU&Yw~TKMb5uX&{2}KL>%F45!}zvPh4qB-tyD`XKW8e6 z@ok|E@BC)L0Vi$rH(vPmo|gDFel3k}#p`H%n*g1{x6$iqd@C-c@om&VPYJpYz700f z_%;SQg>N%OH~Wn~m-*YxG`>xM-Uizs4vEwQ-v$)!@ri^}&u=dT&AmZz_EeH+F0O8LtiHDLbv!ItH+(0%Z^xSYo45zr}oo+`TS5g|SguAuRG4D>emT)dse z*GU6Cdh{_D`*IK7IkNA|$(@lb-j*a?Pi%7h+OYA z-j%w0hWKZ2BfWk(e0Pp-Z0l>$f2BaD@J)0zjcFr6uqnU?wQ0l?{(uFQ@+P`*@`pdkAZ(X{MzPsGCp8@P;?gC3FCudw1Id4&Zr$@ z?Z3yme8va(4S1aw7?6(|@(HD5H1Z3j0*#BQfDa6DYo~4GUv!xp-!y-J)_;FhbG>l2 z0rybe)A&Ygr}0bFKu-y}i63nE0Obp=rSVM+bPC^O zieA+{Ud!>-9qsT<0{kv~W46z={yX}Bo1gI!<0D(YE$+3zN7o-Rg8T`5M0D1-0m@tQ zCkKQ=tXL^@-bDWvqS{Wz8edHH@);jZU3~PdFT3#tybDzRM89R0{Xf-PX5>$7@0GsS z1|NO>F1P#*_-Indf79-6`FH#De`QLGvTmCgyO@8@LzRoTGMaw3? z{I`F^E&qd4Kz_=84iAr>{twW`((;S(SqL0w=S#TX4 zpT!OIjG&wGiz_}0ucza)1n5+JCjKL*ThuS(vk2&GfoL0FHsy2WpHtv>>DT0U#b@zH z{rGMBu*&%IV}AUHSrmZ$;^Th&Cp-94PyTBi{P8FJ>OWRyugZnU_TS*g{~YY>l|#1w zKi&KsA9H+M=`!WZ7V+^74~`%{UJupZ%<-{)2xA?8b9_8?&lK=6R?=7?3@o2d?Ld5-0-cJlg3r_ORSa~W`09BU0kHlI_+9!n+h>d4 zkU#k^KYnxHKrIULN2wn_BqeJH@&{k=<3F*+osS=8!0+0>&ZqtH7v20E-*9|m>2}>) zE#jL87mpymIUK6SFC$yV|Ikl$F5~gP(fqyw$2U_qzFGQFH$H{8h>CCYTV{!G)LS+V z<9`cpcFW%o-;AaF-uU&_-QD;V^xws=JxaTzYkehteL@3%jlV+USMgOEza~I;;VU^l za5IfxgRi;qC*q&Dfu0d`6W_S-Yxs2R+jb9_6``}l6%+&+ip8~&2zh?Vf z_%;5fAHNH~hPN>O%byGHj{$mE5C7WikHPEb^3EjxAM5<{SeMWEZ|dT|@mfD;bobh+ zCI9EW{%^eI$Jc~5Zdl~^$A8}+9sEaG<2Ler>(_4iO8M0Wd|H)nPeXs0Up>AFpMJXm zpMIwSp90;5pCmrLwE>@gw*j9v&@+N=;x{Kg{ayn;1v-gOzu$mQf!+$A0>4YYX8WA@ z^fo_!CqDgw8=v~rpAr0=-{kzJVXo?@E%KXp$D^Cygmn)B#zpnI2K`%?*|;;-_;9M1 z&-ixg;@hEp-T6Uy1xA?PRBzch>P13f(w>Mty zmd_X8j-`Aze8DXr*!c<9-?a~Q%LnsYCS1Ntf9jSG)^|*}d{2J9TRvF7G2!xkJ#xzj z>oX=?KFYqp`il|Ex5B_j7@t0?AwG@npySgF=vNqJnx}Gn<4$+{gYjv27agC9AJg$^ z)Id)Ox*0#Y;?v+KbbJ~Eor+I0MK|@L&rv^N)-FCxfWJ+A8vWFd-xZ$*KWi7Crk?z+ z`lFxw)$f{rB<}X(cg;UaJoyv-(2ZaD{Qt+V{?M_$BlF~s9qT*dU%2b%`~c?%jP6=L zZIK^%@WRo}56GDrhjM;^=RX4t{*G5%jVeiZlR_*0i@{vtk3 zfbNQKV>G(1D4IMwm4fKql`^1moZ|V3k0Xh{wiu)VJH-YXmzWE4KvFaT4n*zT} zzh?WKPC%>!y_z!;dyW+>-kAD2F_%S8;IsW4K%ktWGZ`JYb z`UT;xIR68UZ;R^%%ZGQZK4#s(ih<=~{hxO4A^y^9A)DvIl*VPJ`uONr%g^JllWzR= zv<1V}_hs13oWXX%1Iq_ih|`wdG~2#@xE@)-7oXsb>>~dB^(4M%s`unae06>Uz7l_? z@l_0TDnB3m#qGaQ>RuKaug{D^;S2g)b@PUEXc z(Ovv0&|UaycN>#&59<$hEfQD3uT6gT@9f`=?ovNx|30O^@5BC`{X1$PKP+F6sK4JM z`aY9uk9(~7wGH?o6N|+K@OQ57_e7n=Bz_PBi=Fuc#1ARZDf|%4SWJGuCvBhygKmBw z{15{_gYQ~8;2D5vMoxcoo*{{-l5@PnAS*ohxdzX{M?^3MYLawU>&e?`V0j6YQO zu>aKU6XzHB``<-h!Td<&`#8q~cG0-V| z94w;oaRziMzZWm2@o&~Z50|+4eeiJt{I2{M;!m-Z#>bJO>vzihMgA1%SiWt3l-Ky+ zo^Jdr%Wt4Z%iR2?e#~>-2HF0-{P<^UCgT_R6Hos62A@7f{%~)1{fz$^|LeYD{bl^m z6zePbddSt?)JDf6>iXZ{4c$r^k8DzdY_m|2)eVU(XPW)wd`Phlh5eT;nEP zw{1?d`NR<)exwN>?%#k9fllJX0~+ul&`Eq4xbYn}GHalR4|VgKn8!B%N{*ibKZy^Q zH{e4>H}$U1QT`O@t?=OrH$IZ(6Lf4}bl_rfi595xi{ry9)IA;_=KXJ>E3AiqZT7$A z{43{Ql|?~(!Q;b)GAt*IzXZ-7!1?h#jSp*8w$UHwU)$k-&cEj0Py1{GzK$PG<7=^! z#@7kZw?l__;n(P38efY;-1r#rW7I%T3Azuy4*r40*D=tk`3ae#>v!J#Mft-++u`d3 z_^J5`;bAmABj~1n%yZoals|riyL^+!m46K$>BsNNzorB~=U+Mhs{5+-x9{_>pcPEA z0E$uhpJi*h>j%~RL}UIV{%L26`0{50IMMST@ut8$ZtZA=Z*H37n_udAeWD)g!lvKc z~C@;ZGVHu(e^h5I%R+3HMIQ=9#7lfSkcQZ%dgP>W}&ho3V%PZC;Z)0{&Tndg_fbm z-3|6XI*PXc8PKWm-S}wQ{)ZuL|1+Sw*2kdz4xgCQRg+3TX#W$SyX-&G!za1vjL#XL zmpWASg7G=q_YtmtTr!6CU3b$q{%7&KdhtKwzrJA6tX||B|MdlX{IVDM#(#amoDcLO zUvKLR7OD=2@#XIu@I`nGjW1H5Q}`k}mc|#sS{h%ZK&S9U@MIca#6YL;MQ|KVPYJp? zeq)~N_Z#s`^b~jbCXZ|UM;!0R?;8I}2!6&-jGuI0wf-`GV*E6T@zX@l&u&`(C5H}Q zI{*{9?FagY_-V9%6(`XCH39l|D91T|_H^36iW6!78Y#N11t@dse{$fc`xkopulo7|sd`KN5qj>A8=m#$j=laF zVy;@vkUy$?_Fw6XBKo=E`!TQK{RmH@-;WgNuKDjWe{^!rZ+kzq9A=*~&uu&=y^a1} za&Qm&6QZQQLWa73KGkD=3ih8<_kKkW{l|ZQ@Io{^vFPV)&;E7xHCN4;J?}D0|ITMK z)OTU-?!SCERDB{C#ATKY_s7Q24)qQi=k+Vs!K;NLCzjmtdo=Vf2s z(!=`mlX}LVHH^Ap11P`8K8*br_+cdpw-q7r`G&lFSN)NqyZBRr zpYb{4b6dYD?$zxt=idtD*d~E_=bAL?_=HnQIIBlx$~AfzTEy~IiMZ`9y3wrS6x){p9m}`H zf2Mqg6sOrP)~{KW!i-wtxv4)t^H$Ig30_d*wVMq^OP16&C zZsIE!ei4_r@e9@;0o{ckC4N(YxldGXa)&o5*A#^XPuY#)5qPvQEE<6iW`9`IXvMN=1>jS~JU znS;tjW&EQyKd3&wvQbpWZzz0sQUksducz@{40H=w2V^)BYIvsrF}zZo|i% zpX2Z zp=1AkgKhte%Ki`fok#zFNyGacTuHy*3DBwcJA9Y>{lxcMT;+~0Wd0fG7r>v{3@pFj z{C;B>avt^f+h>0h%w%eDH53@I@gg z{GDt5ptw5s|F-#ih#z90Q}`qJcN%|WK&SZQYv}xN)<6&6 zd?emW=Z_;rck!n{$MRkJ4c_ODzg*v)(RHDG3GkzSUF{1KdVj$T=#2kRqx^jqP{Mln z*Jk|R+dltk_c6hL-LXGt$XJh$PxbOG{&ht2(?HeMgXd>j)l%F9{J{9Hk~=AsgC}+T z=RH6Cyc>JKe|r7s;ZUb*{b+6(wSCdQC2?yPb@@m2{lfZ2WB$R?n&9~j#Ftll;>$fO zWk~$Ay#ZeWox+E~wGH?Z=vQ0n##=JKwZn}Mk)Acs!wc=r(*j)7EI?o(=OFWZU?VcYMbC|7tv3%0Iw< ztOLsjRtVnzw_}|dr~QKdHM?W&e5&Kev6mn6?^AgHUkiTm9{+mLKlgxN>ifq_*K5g7 zdG8Vf5lAE)IPpJ*8W13I>!{jc_S;NN)v z{n=tqaez2jEUWgp(sez)@s7`U{jS!efv+ar{{Bvb>XJ~pv(0%Yt z3jByqZ1~LNx8WCwzdq~7?;0NsKS$?3GN4o6H;Qg#e3f@E##f++CX1S@O8;NCuZ*v> zZs2$9^ABS?|Edi>nWX!3tnyqRv}*8^-uVsViI-2Og8rKF8((Vh|IvTZ{yzgc<^SW< z?f)>p5q^R8|Kf`c{=I>o5_HplyY{CGZldMSfWD#JEs87j|IwG+{5-zE^P7v#Vmo2~ zJB%?39~^ZVeJ1o*duoFmO&MBnh^cjYgF zZ_@dT6zCLw3U6`qGk&tzf8O5}db>L6_LJua4{PP<-^n}vW0}7&s`D2SKUU^1TE0(F z*3Z_ho5ht6pzb`rPf_oGM)}}9JOQv`~eAtLEh3)k$*({Ka~nJ zE-d)&G|%s|pSJX-+4l8Wb^Fx&iY+Z;UBBZx{xe$rQ?IAe&CAw|_@`BW|VVw&4u+MMqetGL~s0UYr zIp;B3?1%UIl2_c(!}|aAEH_7nR3iL%8aE)-fm!Ty^8y^q$1d-tCk zb`2bL|3XoZrpBrNob}}n*548H;9ut>uim^yMMJjzBZ&U&KL6lnbpJ_! z9^2U^eh+@$SN+Fl|06lS{DzL~KkE5`0&iAIY}KR652B5I8m<1dtf7BJchmhV13Ky7 z|A+fm{?yC!>mG75q7#dKm}dR!poadH{(|mb;VvRM{GZ+@u>96`uh74*-$dKz z5ZaIOxz<0WK&RfH==B56@hR*l$rNm@h*mw-G@X^oq zH_-ZtL4TBf#AaGQ3D8~bllh-5G`|4(T>NeI)5gB@`etn}OZkKTUf+BoynTnms~lKz zC+mTBbMf7Dul3ENm7kwu8U^DV?c>KA-v8)-Y5Si6owASdeGU18U%TfYNDurQzxdo1 z-?M!fcl_eLK6<>qFJN@{`e{A?F>&hyFn(D-`Rqg5U?1Y&()K~zPuqtC=q~>*@xkwC z`w;w|?E~&&r1JaT@$=rVFym(<|1q}l%~ZD!eKvkH*6Vl1x_t0|5=3m! z{Y?Hq+t1*SwEawhPT9}+0eXBUc+fpQgYjwHK+g#JAn@x$J_dcEe(_%Tr^Vu|%6)x_ z<1YuP3&wXk-s1f=%A+~Dw^)Ab_>S%O6q-M&@-y&Y3;SK0ALp>&$KC#VuwE~;*l!!Y zv08ND9M{o34ek4#4fZ|yGi~29pp)_QUugRt{*|`x8PHwh?`Yq{ztQxBp!?W&@ppQB zp6z>qM;0s}-nIIeb!^|+zN3Y)CgZVGhDeg^|IJtpX;{kDxIAwJK5pYb{8S0L{7 z|H{iu74*4X3o#SQj7nNQpIU;%C4Q=o5$?%>LA z#0zQr9xQU(XE{FFK+g!ek9`jpGd}0}EwD=l=U>pMvwb&Qn{|BDGyn44OJH@tnPYF? zmp9n=cqwh)#h$c%Pk>I@_h=by-^E_EeUBRGDM9zK@4?<|-`T#ieedp1VHh}h+UNKk zL8jQgUFqkI3yQTR`TWK0+YSBTdc}c(6$8t~8)yH0t{y?|ERKl8^jOM+P%tjn$sEbx>%(|GB|_Co5_D9UM&C?-b~i{f-Zz?RW4GwEd17=ovxx zvESjLOT_tA!>z8TtNqq`!T#~=hW-&f!reb$h5>ol#(Yc$^?t}zLMp!Y-hZym{vT%h zPj71fBd2%!FKBB2s_EVS*EhBQQPZ#e#XDGEpLb3@ekr07Grm9P?e~t!`t?1uFD zS+k>$Dx|HQSnS87Ti;IENVLCKH1)s3-ThCl4*>d(nr8AFn7T|>yZtjI8<5nTTzJmLS+nO|rsK0w+rLHcOXlSV zr~dlGF`s{@_TS&JL&XhGTo`5g~z*!6_{)^QTH%jDDTMEjgQHn;D# z{Xr0)L`Ty2BzT40W%Qu(u))8ue-q{1 zD&`qFLjQIn;os2yrbp57Nq96JpNNq5Un$T(YRF`sV*T+GY5$Zp(8DLW`O$wRKp#v0 z75r0Q`7e&oI6lKynBz0lf;^1)X$0%LAiryl{}|sl%}d{TOS$}`kJ>Cwxe;mAJTb&+ z1>VVdyVpk_rQ$!Me6WtN|K!m}>2h>^Tg0>W%Pi&R-%qXPqbu@1YQb=|JbkU}d-*Ey z81bm(SI_!0_$L`#f(u)J`U}pv;0R0Va9{l=s!8S#`+up8QhaOb2hT_Pe3m@8_&vVQ z$M)@VtQ#Nh*BkIhd@PMW#9BIjPJzB1>aoR-=>Ov<)A4h7oEtyL__~2Ep5o?jijU`m zeAI#UM^OGc__gU6+m|Z3tsLYJj$a~P1i!ZY1@b3Aci|(S_&s>48~^yUF9m*-&-VPL zVf@edX=3qH>>2;Z=bYF>{J$#w@g3JeC(d`2=;iwxB#z?vzcK#D{k2W}O5 zez`u&Y=rAyDI1FZ@%9G)n4UoU$MEU2e-tOu{xJpmCqWL|A>;FZar-xfY!$UHIo zhw1Mhe$n6`vXf~45S>itZ-aHTf5?Dd33^S>=ifL!(z`&& z?^keq#PN|}|HuCCn03bZDGo^ufPGjYP8~1*H}EEU|6p-igZ~3MwLTzxL4*HWPseX5 z&`JOILYf{Ebkl#i@_QNZxAK1*`pW-t{5P@jAFq!v5cpL0uig1E#s1y%*M#NyDqFYe z>%8GRZ;8dVPd1c5oT7eUXFYR#%9wwn%QO5F%pcmib+fqg0i@}A^LaB{w^H+a3i*xl zHJ>g=*SAHi`a@7qj0XRGCOv;81v=@!&!Xuu zK{x%kEk4HiBN_0oRr;#_$oTvv`TP|Zf1>DBUc5$raduw5jemEf69@7~z<(9|a(vA3 zab=dqvZ`f-Zn7T!wfVk`&-g8lAD;V>1A7=h^#Af1IbH~DD;-nae~-2Nj1Mq>pm7A_ z1O4)t_+bAAd=R{h#s>+|srWuRm&OOdc{G0pbP6AY=hO6rp!?th@p2j;L_o*+tv3IT z_##zwt$Xtq{d;ghJA4oWe;?rk&L4380AC?;-l=}a#@fGj*KZW@D|}z0i2vmJl&xD! z@gGEhTf~o^ri(@zn1Y)@Az`bO>@R9zSOY@#+QdS_>b@++JB@#r{c@_V%mR% zucYHk@hZ1}K>HjidPVi}676#ebhNKF`##ggWZbjy7-SgVspSvGW&gZFhGM-{(SLpL zKhNJ3;zZ~WV-bJx`u?JG3Vc8EMOctkRO|ox&c3c`u&>D_w0#X;(}1smj^kH0TZQ&9 ziRtz4(MH<7riyMn*5Xv+-`Dn)eP#U0_!ayAB*Cv^y?@u(mtR>QY>Xe}W@fssKOg?W zA>RS~jSw6Tdi}X=?JRO3^KlLSMZBK&FEP+5{2pFP`xmi^#_uW6sr*l{nWo1Cy($0W zv;H@O@~QRB;g+0^`mP@6{}Q0P);CYX_+pdC`Xr1mHXWCZ$^Nc3yXzctu*7HH>oc#p zYKDD($%*xUZ}reWj_fdMWSO2*5 zcZ;@-hJRew#e6o+5t+bjm-5Z>8x8K_3nO zDBec<$4Jr5cIk6$Ukda-@{b%JPON|A`H}kNgWu`kU;EYnEm*tP(|rA(@yJW3ZSe1S z?N3q?xO!0^-|&9FfAhRqzT;=znVEY39QVk86aOA{bXEBL{e$}^K5Wcy9Ch?&@tn_M zS$cdipZ{{y(bW7~_x^fE9j(jB<=c777V+$TGE4cRv%lU^N9X(N{r;TCJ=C}VF3m-& z{g3&L^$qwfxPr!S3DBwhM)YeDxbdY>TkszC}*?&)bo;0Nj-myf70da_G}c( zE9IMy9BbAGcFwmp`2Qry{kIKYOZ>mp?Y}jS#rj5zyP%rxf^I_KDwr)0)-KIew|@#JmIesk*-c$1lbH6&lYO_!Z*Y=@P%3 z@~}l)Ievk+K}8=5e{=k@E*9e*zqoKT;)4$p_yF;FdR}h2RiBh|D(bG1HG01 z2Y#3T$M%OGZ5N-Uz)!U=_!!;380Z|I$bAshcm?NIhdQP{iugyxLsL4xdia8l&d0#p z2j9ory0y4g&wt?IuY)iBJnjgYU+p2A3NLfzu;bTiePw)t`-7eFFf6F}J0&NTUp3>` zDqnG}+P6hKb!%oR-z)!qS~owZ@l{d2mUD2^qfq_`{~J?%+w+IIzv_IOpEcGZ{s`#Q^Gy}qmJ6O~3S&99@tA)m-~UNCe}nVW>M3!4y4Co)-M=wD$a|O8 zgJ}`U=XU+|A3j)AR!eb(_~0u9K0yB@(%ing#%Cj-yZndge{8lK{Y$3G$EvD_#0OuX z{cED=RbIT7@_(@5&*4pO|7hyR<)0Jacj;I9|1Z(?$3Un2bEfFF=QAq) z89SNa@m)tB>|DF69A!hf3f-DY3WekWgb z+jk%S;AYys$3Um@>zShGPrUrU^uJ$g=RXtRr~GH|^#=b1beI1!_2crN8Sqp7Gx`Qy ze+qP0{ivVdn{NG#ivQ&Jc2_x{&*K|qeQ19M)%Z84W4CAj-PV8Ge6Q3j{C7X$zfJ#Qv+rn_;@jN*#fM+~fc7sD(5d)3Rdj4m z^^o!7?d|+`4E!6QU|ajKeDOm!UFrwulz-2F?((mu{#^b&{E=J#Sbqw1s{Y^(cm3GD zSkZ0mXa9~JzuKNxZSe_!dYf8fTkum3Nz-SrRMIrjDc;bwRJbN3zl`hR(xyZ&X@jD7vz zBIiCcGJ>&abFfv!2FI(UL=Rlitg?l(O zGWX2`Vs{7K#FsXFhxjr4g&SY`@Tb7u>Z*F6eBrO$<(vHGxh@C!Q%`=|HeIs*d;RLSt-+S{d-4ZbXyaGb|G$3qhX$WM zmGyh_U#OXkUs?Zse)YTfQ-WW;Rln5F zZ{6?DOhcEpQ`x&O80=%s%Lx@&%xi63mfSYpx# zX#XDp9r1&UKUH+Ja@9l1|DYQ`_~7pt_%}eouKLBF+U;)>13%TiOwp@t!)u9;{%?%; zw_$w5_^5yI(X&1GCx7<$HnrNH-0NGHI6l*_` z_$dK;8~haPqVZD2u_dfj(CI11`}OIesxXoOwmd{5SN!HvK0B{66S z?@U{xjC(d7gDiad?=RlfuKxzm|6Teq^=p$A^_KuYr62Kjy8lLsZnj&WOZx)!HvKnv z2i^Y?pkJ&jto+LN@0|_&K&SezxYDg3Q@^hM8v(!T`JnzYpi}jS&_Af>lPJ3F`L^x9 z`T7%7D(^2MyB5#S9@qKV6Q6&F{Ihg2+qS9ovtc#9-L|c?e<=L@!193=BK*;{fKJu} zzx@7}7<_w%J!soDC@;S=bMF}M!1vc?h`FNk#w*|=|NbrBmPh{nRrd$c<0(9Ugy)a= z%^z8+J5=Qt@$(;B;tw%*snfri{?X>2@YRZepYm@R(9u7-_`}`l_#^>(8~h>WEhX`D z40IR%kfvjgrQ(8$-u2}yI5|jNsDUm`lD|?vz)#_W4CpTXnfiC(lW@NK`CS8yLm= zJ-<}ZZTe??VtcCHdyG%Iy0D!wKB?i8Q$6v?sXu=Vypd;E@QH1FMj{1o$a@5Zg z`N`@zLY&3?nNPvtkl$Gi1s>fe=LNr0ciFToS&`eUF|&o5JS zoBkQUl)7u}g7Ygim6UF9ex;UQ@y0LNqrq{X$@qowOKJVq{58XRezsn}rLXmVd9he= z2fl`#ff<8CGb#Ov1*>0i@`8MoT$}GZE-k(F-3y$5dt6KW0ux-F{?GKEHvfhBml*g- z{|9s`{}MjY?OzeUBtUP2U&NDW{1OA5!Y|^V+ToW3_$mA%j&bYH)V~YAM8Hqsmkj7s z{o%3h`lbFA-S+$$zjWV4+Zp2*n^wB_7{Ao;%YmNrTMk^d&u#(|%k}lkGhqeup1F=K z`3Ly^lAevL{hP5q4cR(d#CbOaa8mudfsXQL_*eNMcOI(x&nln3?)uMn{21Ar{ij8K z&Yw)O{K>kO_#-{e?Y~U_XY)UZKf%}*bqj*RU(5B$+qVy!uTe+L7+3-Or>r~tQ*$*! z=ztx8mCV;(TSUt8`V*fJbHqxBQMcp~K09ftc(ZZOJoUjZ8Ss<&i<8~@GxhJn zFA4Bd_$63J*B=9&dVZOr+w{-)#q16BbIzaCbz^!$AGOmy~wtB;uyRC)$+LgFXvzKUT)W)eoAir^%H(M zwLp=oEet&si$oVH#cI z+y}oTz)#^9@m#n5O#Qp?O9cEBe#wAN)gM03UBA@7qT8N7;}@edSWX$gSd?PinrQrD z_b=?9^GBrhU_7wOsa=2l=bsl<^rA0uen#BVKc}a;?Yrq8Z1!2k-!Eve??9*gvsmx; zALt(aF9AB%Z#zu=xcsNs;MT9iH$bQSX9jdv{ivVtMQ;7f zv#{4-QZ&&6Q3|uO%`!n`ph^wXKW{)nP z=l%un@%Wt743E!^fB){3=C|2l^bS&Rizt8xSILnO>=ato2yTbZo;K%y+s!?I@ zVz`$9-IYJ_(O>iuT7N0fDg6a!)B1~n-bQ~J@Na;2+Vqd@k6!AoAL%L3v3}cO>c@qz zgLB;a#qtxNQ}|lE%w4~XKNQ{8zL_?mje9m8gPh~*altoY4>kY7nBNH6fmsz|j|zV3 zY!d(ZiclP~N=rI~W<(6#Ib$$P#lzns#GExT-pTDVp8bFJz5=Yur3;rvq&uWLq$DMz zI|Kx!QyP>I=`K-1q@FzE`DFNwHLQ+5^?%w=v4l1bs@tkx2``k0n1K;dDd)CaX zS?irOGi$!NF#KVEfyzhW;{PTeGUzkNo^u1EvI9~S(KEU)tn)zULh1ni9RuqBm3?|T zegd=)^*{J|rhNeW1`OF3j6@bl6IAXO`pD`_8M=Sw@|g=WP0!`2|S6S+9ZQ z`#-%6n1+D*57eJu?&SofgB5UJuaHGcJg!W%Oh&&Eti_NT(p3>`&N;nqXbah_#F(5-8at$u zbsQa)_xspfk20~jsv=^6J?8et^-Za?!#9P0-+lnT{eJ%khElU&D$+P4&KK{(IYgrGa1Xwh)b&n*V@TEJ(IMIzE(e3d z+l8#+l711&J81eN?xAZl-wuR-lYF1F3;6GQ`dFwx#eXUk2V*d-O%^$wyVCmih>fj@ zRrRgzpVIs`@-;q~UHfvr<`4Vkdwl#4KH0fG!F!`ZBiEN2A)kc6eau_MXocC~jj-Cz zgB3)Y4wGfEEYNy9M|S@?6h%|lrQ=Ekv+dv;bPEeNZ7R&zo{}H!wz_Pg(e=ALd58q( z_t?RW&(*(5nNAWFm4i6CMfwHzfQu3s*m-t2s0l#*&-+dNuXFyfe$~1BSikrI=^*{$ z0#yw7bU)uFIQx?m{BgwslRo?9nK%$X+yLo`fF}??&eDehH2(i@{WTKzqf5IDX*MpZ zzBC_jOAq0d<~u?z^M!mNd^toy8W{M(gd?6?yd^TK?30Q}A%20v%)pL18@|`Czhrzm zE#iCn-;e(n*>6DMI0+ZoZ>nNXEy|iNFa`bgoafj2{p??U$39gMW^;Fkh#Eck^F$t!Lo&r z4ko9S;1*EuTjPqj-zuvjuHTMh%Zd?XS@ZRM!N}ai+WW}wS|lp2j<*K!zKgjXtJsvhj!BpV*$+l(kJYq3KO}bKc~m$tu42@x zrTI*R3>21~Aw( z-|8yb>h4~4ZghE+|JvOXn_iKcdxG0-~OHa3VO8jE?umvt6h!VQ>PCN*TdMbD^Si5RJA^{wOdJ9Z?v3V}x%_x^|C-1! zin;!zyBM~xLc()7)Eu1tppC5{pGEsRUt-FHks^;^FJud;Y%no|10 z)|n@TESLC2cx00ATY{JC+D#DkobP0}oBib`qVS@PI>L)Mxak(4^8Id74PC-Cvy!@3 z;~gVpRVOq{Id!=t4tj>gbw$B9PFX;s7EL}d6?d|Ed+9lqRVHq7j++-|Knc{iF3l1%5A=Vl>q)T89aXSbi!&6VaOG@0Nd zOXEPkrO(7)Qka22d-OJO`b8O1rz0+Pw(|l)ev4Em*o40E(7=!l+RI$Vpxej=?UzT& zX>pqEuZ1V+vP;)=rQf*TI%$mT$$n3JSHgo|qjWDgGJ!OHWiwoYA|>haAS(B8?oCrt z&xh^|%EeZ9-t%bcTDiurTaHVABH1=#&@PQdOf(kScJNcTcvlz>p0_vpp=t>kzZ<>X zV*MTovRCegP|YZ{mX_BZpXXgjgJV4;{0F(%@Jc;@n+s??0w3imxXvqhI_$ueqspKV2Sl^gx2 z3rnh4zlf8iUYyozZk(1UxWE^gr18V8Vu*OtVN~HGw}&L_AxWkbD$n&Y4U4>uxNO0 zZMfl*-+`hQOk%?v27zM4^ROx6b%bF)tGX0L1~1W|JP9PUjE`^X^oJ?@stjp@*qoeU zM`WLt7Oh!<#fhuZU8Ythh4CS^38BciA+gOuF4}ztBvQFoD2s_~z%TQb_CEBNE`x4$ zdZetkuW0>(IVd$m!12aC#e`S4)WY&}NQwE<6RLxcKZ5IAZ(xv%>+|&USi1UPx5dc? z{#J;8?H*b6G^ZER?Wa;}%U}XhS3a3N+JbL-0DtVpcg#C1)^CVW5?OL3LyeGGi_kMI zkdV;I$3raHpP{X4AUY5S{>IE677WFK14%ZCVOy=NLx(J(JyNb|&5KaSrinrG+!nSD zMi$Ez4jnEM<_ab>n_2BBPotDMZ&R7WO~2)NY+Tjl;8a+BxKdZ;7^vCi-UTeRtlb!8 zqO@fQ#&OIR?MZ8O36M=d&h>-aDd{*6U(c$I5d^EF%f z1dG-gjR~PPh|MsJ5nne^MJFmY1KbJi95M5Wdzp2wrVMHmHWf)phEj#bZw996l=Vdm zkKM>Cm-%$>6LT?b!mR|TVOrx@#8t=Uqv}cVThQh24KC5D597>!^xSajwrJFkt5(n_ zbIoGCk0Gdv8hDgI9$Stw1!G`Yk}W!4$s!@vr%%bUGrRGuPbB8gcv{JCVK)!Y015I4ZYnw07wV=N5}yBIBDk?y9t_f_r2# zIArJ{uFLptWn`szKGtfXV!N#Nut4k)G8Btit)6{>k+xr>2?c>P4iy-=s|B<#9{f|N z(AAZYrUv9xfYK3;D=Aw5Y==V9GQC5pjEH|eOzdfsV|#jU687mJ!}?aqrS zAV)ip<9oEf{)#2JH^TvG#)If6s(A=aTxfb>2`X{%!|jaX7?ccoE-L-$Ie+pkaE+Hv zEYCuk?o)_=ma%SP#DcSXNw~At7FqKye>@`|Y|6{Av!}H&y<~Mqki!mXi$z(H=UQy` z8{D!Ism-bx&rMv_Y+8{I&RhO>4LMO`Rm?;_hs)!%1T_V#8Yr5plRdhmb@lc`_$}ob z8#Y_Bph_e@GBJV}HOO$K)!KC>pVk_<3Um?A5xATiH)l#cM%z1R-Ig!caJpmGna44R zuBz=yGVr68=1WB;KzTU9a9=w>CM{@}~PAaNmVz%rcIb`MXfx)U5-%C5PvepIeP6>32Lo(&oP$yjW7j&s_XkF4Q<5ieG z*5QP_*zUrEROnw&c>SOOo1SJMe^}Mu!pycw5E30BoEn37m$Cv`psDyajhF1lqOyxkm9`nL z2MpzhgJ>vp%td8B;s`~F4vN$zEN2XEEEws@Kb~aL$UYbO&s+cbo9CxcZ+^ai1_2fT z*rbC7(*{)fzZs7}ZS1GG6O?Nq~fAFa-%d=Qf%LG+PW&oSMPnvooOe5mm4NM zmNI4Y_500FDNAt@D@~b0=;ac^8?ihuyiwUA;3pP*9aEIuVIU;MCdjG1^$c6cIy{{; z3N`}mc&Y7Q?$Ws^;nvZ_q1k)BQI|jw?U^kYAtdL+Z_ze6sz!yQH-kghWw3L#Wnu|2 zf}AmZ?iefCnK#Jxs+uQ}QTzq0QDw>c zGBlPmb-=?iz3^UCeOpP9j*LxC6qP_tWxe+)h(L!Q{#Mn34fxTmw*#<4T*in5pHwm# zl+(1g1&Q2X{Pjo5_ugGjV5*c@sJ)KeZgedNrQIy;Lwxptl|TDb)90s&%<8&H#=ZZ|+SYUF+v)t+CdhH9$Gg+!L0RT0MNP6_A8_U(WfX2nN-Y9kyXs zWz{>YfZ}b+Ro!(ubHXf zX(XLetZg#ajf=9UrHaX~K-LA{AMGyBy|e&Z_i{j2WX#H`FW{Or%slKRc*}|_y=ZqB z*&?0Urvjz}746eWsQJ-+6NilUWKGRr8|Xq91^qs6lL$O>Oew7&4I*sE3XHJdD6~h! z7k7exeQJeV~}j*s|MBpD>o)qx)s)3Lpic75zRaT28P7NlxU`rrua!JduznrgSaD>vNz zY#1CV0y>p}f!!JW{dJ7+915Ja7y;7s?C{V0%heRQVYN^DGxQ!B+vLjovG!d*_UcTr z*PqZg3vSMNoDtS_zj{yfdQcM0c*Cq(4H74F#Epb-g6ikJ`)R&Y54`Q>1S;-`Yq!bB8g_h4?B+T$U}nG@QhTBf1>oVgKvTz7O%dn+a1UL zF+3rd%Tikvu_}JN)u|qwt3fgxnIRP^7WPz-rfXv(jn{57PzHo3F^F-xAY1`I(lT%R z!0?f`iBe=9R-5mrw5*m{!2cmq3Jm);oRoso1}1Z;lod&;shDGT-OI^HDp!fO!>a_k z^rGrE{6!jLSd^DmNEU-{<=%uB=gi{*m+uvWib0I8m6%fI5gpiPhk}l3PU5;utftHv z`zbAgzFPR<-dv%Dw!YsCSuJzSn~DzTIsf`uRMi`p-PDIgk1`}jZ#yX}SQL;NV|&H4 zzeQO=HrIRE2g0W_&+pdn&fpzredVI{m(%sTf7f6BU4Qv^{pH{Fmw(q^{eRx1U1pTYcZqhGDRK)tyN+JC)p{pA{9O&&l5@J9@!1#uwY={$0O`ZALB-O;zc z<7tocr?e1TuFz?w1uNr7=(Zlb#Vy&+$b+#&Og1t;f|>8=#SizsKBtFKk$Vp(^qI)J zp=L+-iMTKkjM!u?+UF9FE+?CjzN?QWMFxg%~mRxv|beyp01dl*NmBr zGkE$$Hz;Noun5k*(qKx0)#ekNIowwg)|kn7cSp%w6bpN^c_f|n9y9)<-RSTSQ^BTF zcOJ4!f7Vs3p+;t2cAO=f3b6eUv!_3}XH=p%JCX;9=Dp47>Ju+SJ z`xOZKT-D3zTF@S_*;uY}eJji`ILFr%^DG&kY}YMEm1bs;$(?>RR8rzfLBo>|Z43nt z%Z%&{F0bHT#no;{7U=kr2Zxcb$M`>w<+v$-tk9G+5Vp~#*-f8P_rC0w_T~4KnL%#! zhP?Fed2-TvHJK|gUgRGPTD*t+a6r?`t?)9bGhPQfB6K|_&qj@Bj9@L{sYqlYVLY<% zi(E(v?MF=u#g;E|#0~j5dl53s{j0JxePj9}ZI`4LN}-`Qgb!?$TMmv!E;qo*JFVav zi>JA-T-LV4G^)_2QU74)uPu+e!=Wxl6{qNqO)A%5 zP31ee=A1WJ#^h&fUmuqpBf#}=LuwbhZR8j3#N-?4TT(V+Yw%zT5woQ0$-6}d9#K>J zzvita(8trNANkfk?T z2}sy}h#cQf4#?E)Qq_W3@H*6^GVI z|0XTE$l#lVrm*3MA~PH$%9|mq?_ju(528#7?nUeL=iFa-;d8*%E}v>a(B?l5NA2&* zyDyV75=T>WyCINot-ydWB@6?-?=WSw!#sE+P|$tgSffdr0mG@1mtWO9;x#WV(RjR9 z3)oZ!`hFXIN7%j241+6L&r`1ys0LYw2QO-rKF&XI4vBV@Q4h_{l`PJCPsMisRiZT8 zkoAm^dI{1cESa?C%7xwT%x?WljM9d9-HW0(>7d>2vry@<-x^8aH)%}jZqL97Sv4J{ z3d^0+6UqlDOjAXxW}!wn0A* z&&p4dcsp0?T~m8Lq>U04HrEl&Gd4n{$DIUpofE#oN3fM&!AGcG03C3V^^etT zHI)g2zJZ<2MM|2o?(vl!%^ZV5!F*-!ty&E6+6F>}6c+`Iy6G!yYcUp0Mu-N~ir;hx zG&RIlN_XGjo=S@n%?mVpMWP;9Q9Kugqg!aE-ta(vhCBSQKjP(a>G2e+UK0<_M?Ys86=yO(0W+hYVzt^MwqP z%iV@idVZYIWty6aNY+G*p$-NH@>M&Bb0@<@({JvN6MJKUEnTpYed1pd{Nw#`;wS&f zf1ZCDFuxlhKhg#CFZlYjslfaR;TP8r=r^1Y^B?->l@IhKsC$70MhX~9&nxS9_t*b8 zpZ7oGzy9m~A>hYf!cresFj=we(h`AA&1NQ9u-%>qMcvC?Gb8+@)<00KSDxs`qE9`tv`VMx_m(XOg`*O zl2BA0Tzlu@M5ywWSbY8AYkdDN{D(mP!#V!D1_`S{919Cd!UA+0@OyWfg83ACa^BiY zbwS!7Q)vi^K^fA?6Tqo1zy7-DbNnCwlJ#%U5ecA~-u;{S>z4d$=M&EQMS)s*A_6HF z`xgN*(G8IPBmd*6FXvQk{gZ&@*8$R1&t^IkKM!-yB%ho=BTl=x{y_S~ z=|3KS5&-!x^3VERd_PBieqDcn!f_HV^1u7}`H7S4e^!4WLH@}?Jsj2C0aBzXhDFK* zjywlF6!SryTs>r1d-tMk40$WU$$3DNWC`g8Ty@d=zv#LzFRYpwKN&c_@dYFQ$&ifm>#4r7Sj-(x{<(}uU7{8?K#gs z%YP`4f3ri!rP#YKwH_;U<{HedODMvVqDj^p#p+Ou(Zix^ugZVw(3npg!<{40U< zr?P*HAKHNQi|Y3`;0M;}{wN3^zB|9;28JF9RsVL; zM`aHdkgp>7T70Adaqi3WZ^EC`Qog7Ehy4DJ>Bo8Y7qE(Jzl)!FKgKWZ{2$}j6d?aa z`1LFJSqGqh(fJXeP7xPete<~_e*NkGKd&yp{`vHq_*GYUF@J#Xza$0x0mHxe^B+C{ z7o~`SQJ7yn|1r~9Fh17M(zH6F{oxA@(Bpf2_)F{`V7~zaP(ENH|NQy$6Z@j*$ND=} z{A2yq2Bcr4zvs#HNyWeX`rcBVsze#>T_;m*7}^A3rf(L=4oPG=6;`29GGmS z1+G;c+=Pdg=wJYQ(x!*rL17zE<4i&}AIpDZ(7or9C!A6Ygi@Yl-P9~3#YElnkF)Qh zQxSV@YM~6pj8w;nE+HOJIP*GoUB*l%RGkjHBPCS^&Stgg?qP{MJ1p)B;?WPDe^$Ou z_f?snxUq%i_ZLmZM#Dw~g3C<9I||J3h1`u`jFbkY3&?_OVVV5EN# z4oigSA<(*+=Hw{Awbr?Px4Kr#>aFPhMCy#wgqg4&e%jU2Rfo?|{a2?tzz{j#eZ%B` z9G`w|{r4%bnx`^x5r0>V4@Y!fCl(QB(^FooA9%m1A9a;K){nZXAL|D{ApN58^;h(R zxccJq|F!>s?;rjCd_OTzexTqqAs=3~*yRsFw2gImom)brr2C98dM{lw|DKc^(MAS6 z1)K4+D`b(3&txl)ALJi#P0VEiGoA_mqxyjYtRfIRPXb6kGQSGuoL`@>zG(hP{+s$S zRdca?p4g|gKh_UzK>F|K2Y=ng<^QW6KhO{8l&fj??+B#Rinr)5!h7AbQ`q)2l(fV= z3h<`7ItLlWkrvm3K@8)A(M7I3@LGcb$H`>&8A#^7JpU&BI6FUL_)Yl)Yq(fGPE@Gz z$MWe0$bXT1{%_kK$>}~HZBn}s74!|yzIfxCF8t>GaKFAk3jSa+LHRDEq*ww+h;A}0 zU%(0yqjc%(Qs%tkXDs|fWqzG|Qjx@)NRbE+D!1M}Zr1j@p#s{t1l8dmkRQ(9lpp@4 zAIlGa^N;1H4v_yJlppF}-XHs^ef6c2zMkJOoznm5{JDwe7DKKU4%GfK6CC2ROg|x$ z9OGEDo3in$5m3Wa#_C#G;r~lQsb=kUENJlX2VE=ird84HzYr`={{$$Jcda1 zR_&!1B=fJL1f1^&*yE?+Yx()3{GZAXX8x=>wNDm8a;=cXdpY;(lH5D_oX?_PhR*Pf zmRAxY5M$4hWOY|)&6i^`XcdlfT=rS&4iV|07L$9%_NDZHKz^iuQ+^WKetiE?Li>;9 zhZvCV0BG(%BtL(wpMm7#r}ESLa$h3~eeh7%nLFf#+OSQ7RC4513Ptj*Z2W~FE1`tR zQ4jo6Y56|#wfy`SHpyP^y}-B;DCMT6aS2F z_My2daG$^!YB1l>8g!ETroYbn__h4}7vmRTpZc8g!66`_pt!{3OvYGg`QzEaxyFH3URE(%2)10zv4M)5Fnzp4J4}UuCYpl>pCVA)N|t!? zVh>ErS=^$sCAu=&!_4gOmu_lFgeo1x>4P|P=K0^sAJUioQSi@-(bqWZh&VT7vb@F# zP%%QCJz_zxYizoirM_+~CdX&5dguKm7yV+*C~i_emzwIL z4Gg)=s}k!z);3a)n_P zU-=^itipbIfBw($?^OQM2kmajg3UjC*3722^nrf8Uuj!dkTS(r!ArSVJ>p8I`9P+D zn-(PB23InZ=Ge=MZc3xK0{p#qr`dN!9N3maK2-4)k*DeTgg!{{!4vG7au2ACVo_zn z2~?*Btuy>h@^`9z-_!pkd|(0+IK>AMYpzkXJ5dl`$arRj#C>GgR!?qq%2mcuIHe#w zhF)i?yi}L{QT`cJ96y&H+>GP1F-XCdJd3fss~&f<@tJE`t`}C_=u8wOBNmQ`1lXWk{m0vG^X zj|Q^9PHd6e2sM8;4I_zc%j0 zyC01!xTA$Ks}r0c^0-K~57UW!>F4&*AN9M)K03vRkN_2Fiec`%ba7o%jQ-o5t6HKY zR~Cy(Jf7Qj>nP+|-IfUI_02wRpIvTf4;$C3CXAI8u{OdZ$`IY( zPwyaZGFiy7`V(9B{;`p__$GowDnX0*^3E75p)oTyb-`Xq{3sV5x6$Xkk(wPXD~17l zmCKJwpFx_%5Rn-Uj8*r+wbEYkG|t7Wa;vU=${kU%$;}dq%0uJD@o)!MmpAkcEK8mt zjgg~Q7l@bVJio@rUzbma+o8gAadn8_`)=o^O z(Whz`^A;*_*#nP(m#cfiKEM}>y1YzzhJZ$S+kxhJ&FG3h>b!Lche7p`JnYVWz_@jG zpAIM@kA4#$-QHY`Pe2i?8~HIl5(CnK_W61C^{?O~@hBG9W00(W!+sz>){R|E|8Ky@ zKkO4woi5TpaM1aY-Fkl@D*47iGb)@~x?Ppn>tKbi(f0Bw z9O@W6;azW8OTVsEzf0GkFleIku;ngG(($%9-K;gbaqKOq%t~o5I5PU3ku!|=TK@j1 z-%s&Tcp=hm@|wpbtcH@#a!XkLfIi;oDraF7!{kOglbE!%3h5O`IOs-YiW_Wu8N<7! zvM!vX9CXvo*)QPX*if)_sws=-#m4Z4%4}e;P`RmPUP5)pPfeAWYMW@B7$|@`eurOR ze+fRG-QRomoARA7{-5#n3`b9+K>41U__2KR1JeJl@%f*-pYwm_{O_6jnZ9(xzxP+2 zXwjGX(HZ`L?mGglAAtDvU*2B@&>zH8iT^tCv-2@POedbY`2HuL{V78>A>@$=Zz&N2f9_d;PJtR+B_X(c6V7s$0_e_*7ndggjrBdivqt^XQ(Dx`{`%rW$0)sA{d#>Urb3PrK~<$k*dL&#C=?(fAG! zdVV04)BCFmLXAH3G6%$lBG`w+ajtbQX1E`XM%@UllmZ{R9b2j&_~f|_r_hYTJs%UG zBApH2xBo90zd`5mfF@MtZ{QD5zo%v|-oFCsxAxqB@ZmiB^8_Ehq@QgzC=T==CZ4}| zf9pKV0p$fgf%Fpq`AyD#c_x06zHqU9aZ)}Y{U6+4`(D0(xYxryrVKYC4FZ3$Up@RP97iOok9*@0WHx_XhCWIdKA=!G6n2r+3qlUYEojJ;L z2Q^CHa5$!XzC!YHJURRJecbw^tgV?)lBBhE$Z5yOHDY`NX4fo3&d;+BC?lQ-5U{en znE}qvtl}N;7nz!$lSW21kQS?OF=O3%pS&bmbTqsZoN;tGo;*-2N1fiw4ZGTA;$*r7 zv$D+7?tsjxuU7{lmXpD<)Sh%m(od~{myWm{$ow@~WQM!F zmeO^?baB*1BFQ(WilYT{%tE{7>4JO|f)nT>P}c1Wt-7TQ^rqMHaz@N^?KzK4KgVY* z7$Hf~>cAx%K0ls19;JFs=PMtvpcAnozk?m}ikifHzZl2VX7I7NiQ1rBJ!z+R+Nf0B zOv!q2(MuuXocr&>!Xt0n?E41?mryFx=a=`pO7rhCy6m7XUWjD_hUdMIpo;M5E!_;i4!H#J?-|)U! z-e2HwYBH~=^~UBkiaV4FevPi$W?j>ePs4Yp5>>6Wjx|`1(y7Qicf)IR^oAMP zj=HGPY9(25|DCO|C{>+`_%vf?GBIEDsGFi}4cdbnwo1dEd5w$)nHYtv!%1ca_vM1i znfP>*9Y68|UVeOZk9$TJdF&~Ss4Vl{_BXN+DHsD8sY|!PQ{9}>j$87z!X=8K!zC1{ zlV6v9cpnXMK>5}#1=Tb@(5aC2Logc_W56eSX{?phbn7xWZa>YGrsmN}O^TWAMIUR) zJx7lFaA60fJe`_WaRITo0}SeUsZZ)K`E0hJN72zpYf8=dLzyy4kS$-|_hTE*{_q|r z1W}tXQDQn;07u1%(-qna-XKe{;(%W>=}KKWk39dY{`qijI+*sG*uyu6#iqO?CVY|^ z?xKRR3Y(yWZRzUkfMXB*xN!N)302M%=yuTJYm*^(XfgV-G`f^1O~jPm;t3FCAF zY7|BlbT$~ZS{=!+$SRW6>6RPz_g9HtJ4>jUX@$YbWO*uIj8OZw3UtSN}UL5!3-a;oRaCbGGp<&##|ie>bJd2#V`*D2D~cc`hwtnq-fLkKSqKQYTRP?x9P{{SWqom-)YP6o zoDmmqvrSt^a6$)sJLT;Tp;TQF>qDE%Y$D1G59W%rv==-32ofpJ@zN>vDr zHAzyOc&`N`W>)o=a$?@^sS5W`M!k&GJjKdn8MeJSoTv=Hzx$rr7dTR%{*JPmJ|kyp_~H#W>j^6)NBKh}qyXU`yX zc}pJ%!ST}~IqObI?Wobs->5^J^LTZutDP%7=e3~@xBj8&heV>>#3Qy|{JqHKE-T}M zyN~*&$P}VEFjK0~ySv%xp|;mC-48G!Pl6pgvs*bh%J{fsT7-6Z zN}Di63#S9R3*`o~gFnm02iqsdQ4fX^iAOm@Rzb2#)_U66Dd6O0x2#VJKzB=%%hj(~ zIPpWe&RACyL5770C>r($U9X4Fqv@)5q#MtE5E$mgdL@st4I>~-AlVqI2620`4ONlg zX(38k0xpZ;XQPm?LNL%)flo~?c9W=Hcj+|%CvMlk=$Gn}s^%mzRy2z2_KD$p zIg6Y;cysP$U@aJ#?H!z<^oP`Fnz13GM&X=h?(hY1#bc9|SR{MRtuhpCB{Rswl(A6_ z76J0NVB4evqendIMh3sT!uDeV3<#L)D|qS zm{~)Lzm^9N*Wo1a9$O5R>*+)&p;>n4DB9A~ActU+T#_eucgp!*lbapfQTk~A2v^H? zicwTfpwp?nBGpDes~cI>=FRZ~0);z|tUkY}86mpEr*;|~S8zFB9r6Bb7k(EjqqADNjX85&^Ov$k5b4z3| zI${}YyOI|9&BmK)cV4-3KgQJq%Ev_cl1qVq+Wp{bxC^6At#I!&O}rje7K<^K_@iA4 zNMq&8)^1%278c1gL0-3)Z)!!N_W`pix-M5}$@`jfsVCpq<9(PNzbUP2 zPmdm(6C z{8$BFeae$;$^%}@wjGkDvbHkQs8H%6kuiB(2%G0@t939IE6M)$V%*>;l4)SbMHBos zg+(K3uWvIVDUM17EQu#QBbU#|$LVW#>KS@Wgk?jWO|#6S5nRlz-BmLUezlUqP=3)7 zQ*`cbydi3Q7Kw?_D!bttW2xaT_iYvxz4(T5CF?tf=@Y`fw==-sNhj;qKw{b7G(klT z+wsMXK_+i&Rus&LsscrEgafFO;FFaH)lgGm`Fg)k#f9m>H#wi4eQ!$371~d zqNbsS@wz2=$kgF*`aX+;%sMKb2-*P^($s^j`#HSKhn4!seR*lHW73!t8|)F*Me>sw za`ku#(>87Vwa`c9g~Qd9P52axLltic%zU&;h{xwX!mhN@!MYSGci|-KvNoikE0M=Z z#oekG54t1hE=$YP$`N#HW!0(VX|a&mOzG#cVdzG;=KNh)n8Nzbq$PM0&vLaQWoM2B zzhx=NwWqh?l<(9$_hLqQ(nz7_;W^tfqS5HG@jB|3ylDv~dmUbjcBX*fL$6+5IvTEI z_%hWHM-#%ifMopRvBr0>q_g(s9D2tgA(kLi4s%( zq2?R!iK+#E_RtM!8e}fMtA4KvZm5ARJyINdhZ5{jFFs_Yo-BQ(N~eyGRb(3fwHo{D zkuJt+K3cDf*s^Lj7}Y18EF|3g|B3Fct2;` z)m--E%svjTS=v7OIGjDi~ZhqY6Sj@Y`X*lgAO~u_?gRc!|N8R^gKVYPH6K68NFF@pQ*g_26z{P*O%(Rn?Rd)=tWbj~y?bYmj+2K5ZSM*Q|7{vBe)5 zJ&*q3WyP8oUC{&$X<<0M>rZ&>thoH;JND?kyCKUDc8nLnG);)2EkzJ0~>45N}R;0Cp{a|Y#+F11x8jDLRDeq~dnsP+X zBa9~9%{hL1X%}?yoVbFCtdL8MH(~{H9XAn7JwCRvzRWCX?sbpPpTHR!%XB1U!WnUK z+>VZaZS0mY9O*p4C@n1z$}~Hu;=JH3N2v6^zxfTNN7&IUO65GGb|Vq>LSw zt*@+=kNnr!y;3l08B&M4MrR#0S0o%YYpdPxlA2;S2)zXKX`a*Thu9~!u98V0ZUwT= zYqu*L^^?1JU{xNxq7@(xUChaV2j}qFrMDtnB_~2(bJ@Y19pPv~-SQ54L}+evZR52- zSOVOXe{6ARf$>=N3})*~TRQrwRozFzk=(iY2v2U-M5NI1u+$#1icVT3POTwks_7pvOj!cTcd+APb_O!s@C~D|YLGh&?7*vGtTLSIS)pAS2Sf8%kX?n8J zs2FG2lj6E&RH~vSb!+C1)CkeW>+~-F~btO5ZlVfF#P>#{DojsrJom zp|3xXi8*N0v}19YHl&1cO5xH6MhI_oIM0rPG3^A(Xay}dNJOYk*<@u9yf`}2A1K*1 zyv2ESm|ggqyz!ED_JYsz*@a^PZ%tO38kYz+WNu4%&aKNDq%+2?O@kX=((~RrOH};B z#ZX+`YKV6JuPml)2)Wpi+~5>-w0R8QNbyCFI^<;lE(+Zx`=nFd(vyy5Z*Z(H*0cTs z=l<q+1BDYMAgoh6{wG=+w5+BPwh}EO=F1b^n}&j9H$dL=P^+ zmAZo;M*o6zeWhsdO*3zAeR+hrdiiIU$@Ubc&KCw%&94vS3U!M&0g&WL%-(2-{U3@r~VyHxxsKN<{DPu(n7V&bc05Qf$Ok za8#1C9n^GDN4}eV#PhK+Y#=+YR>6WoC$dZ_rn_{G-3kk9+(mUI4C>CXwHprOg7fY6 zMdT=RIaZ==O1AlTq19`<#?-rxJ}qwUmhaLJ<6!A3Mo&@kkH~lUc*gz)t*>0PK6<)- z_wV}4zw0mmuD|@d{_^ko%m3E;i@@+cvJ@dDc_9U6#2=9VUF@s%mp^m=4d^{`^cF>^ zc%3^TzWtx-1)ZP?njWCpLL_v%J71fNK?JWJRL2L`H)Z84v=msCkxXkVjIw>x;Duon zSQ|PzTW4|Gm`h(dC$!3fyKFyfURohy6qiIn5vpIia@ysHZpc8&GdlgNG-6!^n?UKO72d(XoAJ88d z1TgDjs(@AA>X&-?I09_<>A1t@1cZmpyBrT3jD|)?st{zlmi*o)In}%xVlbfV_jR5`sF-5wY=>YcV&lK+zV_P zoHN05rq*S3`HRpu(hSxHHa0S}yK&44*;CP0ONcw*y(X$&@o<_$w)IX^)JYJaIttKg zz&>zRP`$O2He8o!CEclOs<}hZR~`axiok$=TW`Cq+wLr1tL2KjITfL!;gc(<>_rxk;y;0C#6D+6LF)hkMD6`adIj%ev zuL4_pJ_dToHtOsUQ^XDq;kGM1y8Ak!%gp+gaH4RNK2{)0jkiT-UH0P&*(6td6J+P8 zmvSP*E_!uG<(a{L-fRl+(K)*Fgt3O#-$GKU*-pA4cQT<#AQY}r`NmEN-uhuj+tApFWAAik?dTb`N2JV9o0uZR>nbexC!WT$j0L9$c7Y zgpi=bdJk%;H{*jlTxAC^^BNv%<=!5Xt$o@JB=?_LB+uMdtiE)Qizg#`D0}EBK_ah? zVGA4uk2_Znf21JCwEQqzK9(T&gO4IsX_bq+-Op>#-cGwjvlsQZrVM;US-NFwix(hx z3ryF>sognM?R#g9TH($k!N*`rv;%ms}b5NuUIl_voQjEqu6TK|M}k zVe^52NIJDm>tfm(Pw)&1yos#+75{W06GXuUmz&M9ggn@68$qcr5bkN0KcB4&qwH$; ze;{t-{TXsaJ0e@Rg=oNansM=yxH|Y0RIt8fG^zT!X4Ct-?V*n^T{n#;vX&gOUxwg_ z#{-w_W+G)~VdU>H9a+EGvZG!jNIi7WBj)>XYUf?le5C~9HQo(HU(-P&<2;l^+wNfn zIR5dPIxYT`M|L&ta?oTxqF7w4R-H%mW=qxd<6AWov5pxC#yO3orPD7yMT>)16)cL6 zRNW`6e6k=wx7}17mvssMtq2xTk~+qq+)E+Js7`0PjhjT)r1ultr8A!u(5%8LWEwU* zG6wM0`Ox3Wk}Tk5rfVVL)W7@8uok{7{hi)ju&$J&i#AKY!pHyS{+s8`q(l@7LJIw@ z9hVXaq^fDMdh$!8QkvS1rR%&la=Tia74|}nT4Rg|<%dijkFEH41{4?HZ~O2<;Oy|> zJl^v!b+|-8NulKpKI_e*q0og+I&L8PA#7<$Kj^IyhTGF*-fMdMf?eEsBpLK!qeAj2 zUfiWtFvD+Zri)W5u|D(%O{bGjXwe2o2`;L>W{8-9Em00E^WUf?Y~c~tqQL=s`{8|~ z3MQfNa>3H2klD*2^FP1;rsX&H$B9=izF!771tH%1@%}jR=1=aw0p$O!`)>{}uHVW1 zH;~vT^w0Cp0s6AnUBdqN{u{tuHvn%URMKPM`kUimNg46(<1`b`QM>>A^4$Mlxz;wLl_j<)RM`?+5TQQz%CS}-4ZWuhf{-m%%bIw@ z_nR7gxBl|ioF4!j5jzRME*khv{B?uJ{w4qBv*&WY6#t)B@F8Gd=wAfHL^nV>&@J;k zd<5eA)R%M+&9hJ7wgNvQ_J#gW!2ET9^o!ibPR0+Ui|coij{Kkcoh=s>2bP}z$bXUl z)nD%)^=t13{j2cvq@90OKThwr`I-OXu#V|WesQMT$24KLlM?^<_c!UsX#wBU|MmB; zK!DCa{olSn=l>G^o!+1GGyh56gVu5`xn?R0H!^_20ME360uY~OeiNVgQGcwz{AfSc z-#S44i}V+${|SKnx}XYw^So%v0Q%VpexP4mzZ3ibq+eA2|JV3&dOr$V%aY#JXjYhM z6`T!pOmGxuniVZOcQz6X2@3qMXD#X>*$cLcequ{jSLd#SIREAOy?+1A`^#WhsG$3! zLH5yi=O?I8z+l0!%)-8TZ__tbKmGVM{{BJ#)L#C^{(}I61(fh>^#3OQfOH(lg7x3j zZ#T?~^#`b5ZdgCoZ!kdmMf&wC`a1>4f6@IbC-{JUarr=-h98g)%zvJJ^Ec@CAM){E z%HMf)0g^ZZ^xug+0f>Ja&Yo{OkC#CHXyabYKj1l6(l12+A^!aO`2-OEE}UQdeExaT zw6FE|*XI|f_p?Y&CeHi6=bc|I5u=sCrP%g@=BOQy?5)S6x>lnQ-@2v{GpY|p!{JZe zJE#1GnV`qtq~E}P0|p?AkfZ+m`N|Xh#ruhVU%6Pnfa50^ApIi!K2N5BSwP`DnFXbt zJiq7PpO7C&NW%2QQ8hRXeW`aYzT`e;Z{tF18~nP+ z(@)>G|8E{Y|IGa?-}3iXF~boIfuJUPPt zh#RuirfDp?#wE3z^{d&OdBI2@(Au8IheAh31FDyj-Lk)&N(t< z_v-Jz`cQ8tx=FUFYy~!B+WykeTMCv$YJ;WNPhHr5UEj39@m&yZ#JW5k*gCi48VX=2|sLKGkVYUL5(e@^yMY%g3bMk~O)2iGBIP9d`P- zoxyOts5fi_zR=X^Pr;v&Ex%x}GXMJA6sR&l{2=&E{HVkKF@Dq${1`v@0qMZ=Pv?z4 zKf?zgei0J_<_ExroD)v$d!mc!{|)%`$M^!O(?#oZr|<9ZiRP#-L-JZ>BLTB)i>_LI z#I7agYT5JFU96|~L5&hF-qXz?<=BucR=+L#a~k=z{QOb=&+rKnbUzFET8N43TG-0t z+E(L`&*@K-Hgkk+n^;KTOJUGZ{ttV18MarAwGTg4pjffu5GWKVP~0t8afjj%tZ0E! zT!VYD0)x)R-J!r>L5jN$9^4tUIK1bXc6F_rXT!rY9B{lJ{{1lb{K!hOB70v~@9bVz z&lPVt`wY_5IO|zrR1r==yE@ z^Do#x`ug&}?jIS^Z~gw^FMfYC=KD(yoqqhECT%8IbBURzIP$<(NBHHB_{FVo-lwzf zy4@1jPrCBY-ELX;ij$vQI;=iq$JyO+&-ORt;|Nr~@ z!5{g4lJfJ2DR$X+#t$~`I>%G{o`2e`gLZj;siRJM>(jG$d}z;;_Brf|_x8Q_%H>{| z>*D1<`sMgv?U4VuKmX$QcmIdqUvqQTKXQNR@bx{HpY>J8e;?j<{=oge!td<=Kl1n2 zrq6Hh&wBmL^1oakDF0K}$E?5I|Npx_e&_n=F5kc6AA5Jw;|Cu!bj1Ce?=tAjb=KbU zmQ&aIaPE^Q9Ovd`wz%Moho^mU^Ap$Jp!2scyfgNWzy3wfUvz!g_ZRE^$^DsU`|bU~ z{h9mz{{9Ro|E>M`|L^w~>+ZE~*x;+rIvw`ihRct-Q?&l?fBXKllYBqReTTmJ$k!Xp z`Dx#UcN>4Br}n?^h#78Pao*2A-tvSwznSQ;9m5BwJow>*7meI>>E5Rfo#j^<{0;kO zt3SDa+#J8Zf83nEzkd?y|Bd_Szxe(hdHwkH=Sz)VtB(8Q|M2|>^8G76taQs!r`+=R zmp}FDKVs%Q-mB}+zUYsS-}Cc?Jx`x~=+O@!z5cKEgyr9`KL-EF{So?2{=47bB@sA zU45Nyvo6tf;%+nCdds$xuDjVe<6S9r@U!Fo(foyx9<3>@9&xLv0jJV ze*XoNO>xaSXY?C0{o_&o zH@-go@#jZ6jXnoH?N{f(6YX%^b#LzW#JNWvIzz9gezjh0?6`ma53gUN&xwE4fBpWR ziLO2Ms>@EF`JM}YJp9mi+BzNm-~NXEbJm~SKV|;ketv`ZpR&O3@1KbBzwz~JlmGkc z*Uy_Czrtnj^&9V%*=PD@*r3H<-n!?+b1XFU)h{mm$9g@s-}uFg_WS(QjrVV^dT!`6 z&kS1S^0dLaTODxI#Q%DKrHdB0Vddox9C72Y{dZdW^9PO}_l53jJkYY%9rxGPWAgi7 zU*F{WQ=VFGx_4haWZT=)eABNKRv&rgK0hsdV80K#%(D5XZ(VormKR;}W4D#Rdw1=P z`uw!+Mn4?CQRj=-UvPR= zOa9{TudshVyX;TyKfloAzx(|?apB+Ie|(N2qyAs@`O7Vz-}*oI-*0~Yx9kecJ#rC*%&%BL@VwcGt4^xk6oA>%Ky^c|}nKjkU+zc6{fr*0oUU#H7o?zZPN zzbwA}n|t4K%_eL0dwYwmR#{}XQx+fcbLa4-v}u0+U-us#e)X*0Nxnbjr-@I#^U62( z-0#6XR{Le|MQ6EthZFKTOaAb{)aTB$&VAz@KF5k1-8}B$``&)c_ZK{R&q3YK+}E%E zdcP58toT;?YhJJ+pRJAa*GeTa*-h$&vfxIOY#MUfBuI1-_3t= z|22#J{{AbA{{H?8DF1)^@4xx}9{GNlc@}?t(y?DTXxx)-JnXj3);)c_3HlCtuKxo= zU)=kZX9q8Q+!PBea@sPxZ$A4(FI|81_zNug$)cBD^7TxoUNzsB{>s<(y8o-)`|f}I zqd&j1*S7Cm`DWMapWb?!?&<6W20S}z`~6k>Z*=Qz`}+^wALeEQWBz{iNzd2Lx&7wO z#SiH`$#Yk1({t%>XP@)HM<3W>=w4I5^w#Oe?Df#i_y4rc702~l@0X+RdAsKcU#)fF zghw@Z%r)P(2ljnz#6oYs8afT`vcWaqE;-Xp&wnu{GyOmR#r+|$b|?A%l+|Zmc+gD0 z+^~;-xa&AG-{ubZ>g3IS`2I^j-i;q_I{S-TPq*Qe&CsWYY`D_XlQ$19l;7R!ja45! z^4sO^SaY#A$GPnN&Ay)SwP%liXY)H(9yZ4TCmgZTdutB)^6cg2xL&`%XT+bpe*NOV zfBnWKe*gN-sQ+8n?;kmz$!Py%o$U_)kFQU0$=`1OFZli8AKHH%|9&o&h_|-(%@5zFKkRr)PQm%HB)IwYE9D@1_f^)cuW-tBrlqkdycL z^vJ~~_;LO#rx>~FR6U>FYr->z^%$_q!V9c@!q>n4{V->vlwn!abQ*K?{fzu#=X4$ISa{r<)0JO9o1 z_x!i(v*9=2^j_k_5pVQ6?3=Il?a}kv8KysK_wg>+4Xve*XcPyr!CGOZ>bX>*{k%q_2s)~o9X^J7Wwxc%Uw16hGoY7tn(S2 zCfjtDwI=Sl#+$>oA29J*s~_;?Dd&Fr^04j3efgRj^MqIJHSRZG&++~eM+`gfyu%N9 zZl6i|jXmjgV=vtE$+1rP_gE|Td9C;S$Ir3l^K-4)>%-ONedyflzuj*Br7!*LlHN0Z zd*WO7thxRsU5=V{wIfdNJ$U&IZ@=xXQ-@xA=&(;2nj zyyo8z47vKaUWaWMhOP6+YcqCR@80{DUGl_JRzCQx`Swd+l-b@||L5~Mr9L-p_38AN z^qS#?DOVnUw)YO1^o4&M{OjkQ?Kb#t_h)DM{*-4vK5+A?hR?my$zPv%%a^Mhb=XN4 z_UX0QeD}q)e6#5!BL-dh(Yf8%o8{a-_s=|ExnMiDckfls{o?DN)|tG=(lb7A>99=? zzvcDE)}Czez8ft%)4Q*p)A2bVzC=9pC-09T{Pz8cf4@sh|Ni~4jIQ7I`=vi}e=KPK z_rAX;Ejuc|w)X#m`=kE-OkRI~^ZmR0`<2fJ4?cUrNyh)zovU8E$i%noGwI|%-M;qq zH!O72HqYGN@3Tv$d1KrC-q>%kV+IU4;OvvSUHt8BXFdAO{Tsf0({Y=g-S4g)cP`hx z-ShrVPn~k+r3>`w{KL-sJ$7a9<*$7IEVBVS?mx}%f4x6$*zKl4#~(1+0mq(x^D;fJ z|JNxWZn@I=hYUS*%}b^`c=LyrUt!kgZXf%=zP*>}wp7;%4*vPGO|N}vq9>jhG2o*) zPd{y{Tc_OVwN(ZWedC9RSL`wU)eFqG+q|=ny>Qoy=e~T2#}AtE=mlPUVsw6g!~6F) z{^b6S%a3|}H8VQq|8jpf{eORdJCy&{>;IqKe=97z?4o|w6;@wwHb2kY{pRUc-}jBl zPXEvRqxWK$(QgVj7-NpWxk*Q#n{^p|N^l{b7v!HVZqy0=VK<9MU6C7P@u(5(J;tN| z=KkcU4!XGdgs_`?j7L2sGxt+cKKiMFBIY|9{F?==8UJ)~pKzWu9f-|)%t#nC$26lOkRI>aUDOvzl)nx-$o;%tNZ*HW)wz`r!$`V zVFt-~2KY(ig^$;}LLyrTvHDaD$qcZev{kDs-ckzlic^ z{2H8%--i878vh}jj6Z{m@klrf*Z3dd#<(*l_GT>~8;-^kz!~Phapia?h5aoWKNXye zJzQXk?*oTh)pNj&@w~A7k@@#`YWtl31WS9I|6-isaF@n&{u@~0IsYzeIp;qbbN(|d z@tl8ux0>^xj6+MlR4>mSy5=9`Q&TwsZ>`97lYHD6fvd(HPz^(HO-`^P)G?a;3D z-@q~+_V1ohXE4GNU#~Ay&i=!b+F!lCjCW}1zj<2YIezzy_Q(DsEaS;=HsyP_w3nXi z?D*A0GM)_E@%ZP}Y%jq(jgIGd+zZ+t#}kb?o(xMo*FXGQ`{Vj2Sn}oi7h~Qp!iyUJ zA>(0bkM|4rlGYyyMq}PDGA!e(_luXcKJOO^mi~FaD8{^BgjckFyt7B><7?pzOZ;#+yrJ#g z4kuXpzXvYH4>JBujenf+u(bCq?B3G)FTv5cz!{eDzsvZywf@I&f~Eg2;9~qO9Ny9R zpWzHkdtLd`{;t;V0Y~GWaE2wm7vta4_NIXoEd9?27vovs@V?gX$9P!AKR@g~(E5wQ z(Kx^vmj3%Q{zI+5Dx6^He{HxJZvcmnwEkv{ho%3mVfV4t-vN%syTTck{`X}3Ct81h zIKk5YA#gE13J#xY{h^G9rT<~D`;XQ?6OP6WoMGwzV#a@_^{<2zEdArHhbzXnz~OVf z|J(^T#`nSQ3vK^l#>0}|lW>OReui6@^IxiQDZ2zq|Jd5D7-Okj_)6Qy&|QM1ef(eN zzSjER!_nB`FP<5e@ptE6L`Q1<@!$kY{}aQ-cnUatqw&+h8J6~Dg59@Tzb_n(=Vm-C z@e4BkJ8f@qIKk5YGH@|o5e^uX)L)(Pu#A5_*!`gOH-V$^R&a);{tk@)QR@$e6DA&t@Vd99+v*^fZa4& z|2{YxKLTf1`hS}7(`x+};RH+n1un+#!2vHiQvXxN!_xoPu$x}%{|HCpF5S^TEb%?y z;I+Mp-~>zmQ^3V|ddAP7@qHK%OM7#|Zbq#?KOBu0gEK7oFT?oWT7M-t!Ts@{`S+hS z;bOc#9PlD5^*3WYEd6f-yP38APH;3H0%ut2@5}f;TK`};!Tm?~e-vDdPk_TLTK_c0 z!_xmbu$xuuUkFFzE8q-E|JO5qHm!dvoZ$YW`_FJOegF=A_5SlX+!#LxyVrhR)}IuP##1vMmiQSN zKbN*Q8=PS2e{Q%KF9e6Vwf>Tfhh_ekhuu6{e^odduLEaT`rnB0^J@Jq-~>zm+rhLVQ@4)7S6E5pA3fuw7oOn1WW%7T#PSa{DK;PHREAv?HptwF@7Bmi)j6K84pYUpTKTWt^XAqjemeMEb*Q3 zE9tP9wl@x(VClanT#P4Y{Nfrv9phnXZ)Vsnq4np0qw#!jhGqPVGJZ*|zcid+>3>DI z7_R|`rL_J4#>3M8rZC)+3KSo(hqcKx;fvv4$i8P2fW zf8K=s3hEEw1WSIOF&>uozk$Pw8virg7fo$ z>Hi+aucP%Jf)gzLKM5D(7vQk2)_;xhu=M{9?AFuzAH&i3OE|;Q|M!d^p!GZTKzp$C zKQ>&9CxpZLTE7?LVd;Nb*lnQoXM&^g>~Myq|9Kg|q1ImnPO$VJ;9|T295&MU)!__F zd+Wh&W39gl9F4bPJS_R{0EbPq{$M!4(*NFYF+Pa#n`- z%lH?7-L_hPaX1<;3ujpJS()+MY5ld}1WW%Lz{PlTIBc)+1K|uydxK!NgVx_2j>h{j z9+rF$fy0hk|7bYD(*KEYF+QE~J8As6jEAMYi(ofM>t6{+;~U@%OZ>m!u(P&zH=JPU z|3SDIKf(B2H2!(U!_wZXu-jGZzYRy@kKhc;e0{rVhD zSo)s~c0;uOG;lQT4QE*5`@&&&ZEqep!P5W2a4}wr@q1`|f5yW*p5t=g@2WZeXw30vcu)LfeU3l8r|}$rWBfMk-q-RE!3azJ`h1WnABpntfyVy`H^%k6 z|3j@`&--D?zn=FS*Yp05w4CSt4J`e8*nh0$Jnv7&Jnt{YJns*mXnmgdXIT2@dB6Wu z&GY_b%=7*NOaDCYkN?qlp7&>Cp7;CDG@j@E4J`ffyx)DU=6QcK=6QcM=6S#WLfhkc ze*;T#SdETFmdEW24X?Z>Ghb8}d-rrrzaTM;NvBP<6Htr7lv9$hp za05&K6T@z7^%QV4o(|5i^gk0E#?kn`aAQ0-?0RVVf^dYT{^D>k<;%bUhs2W4ig07R zI_$>N`s=|7miSHJVvN6<;yXdKd)3HFm} zeY{k=2A1~mQs&%bYTU|QG{&vWWmx*hrR+j4jmOq?jWN&r-Q-%%^Zp1+eV+FhQ|{p~ zg~s!|zcJ={ze6Rd&-4BSOa46XFUCCY4^wG5&-)u#>hrwcPp#!V?@z`&?=QwY?+?>x zeV+GcSo-IAzn@mk^ZsPa^Zo)$|2*%H(`h`<`?E36`~CDiOdIb%^}K%u_1$Pc!BU^+{RNixdEOsq)OeovXJelC``%jrZ8#b8yuTRN^ZuE% z{qNWwEd4v2*ZP^&Jnv7&Jnt{C=*hk}e-k*(m-tV!AqDaJ{c~wK&-)u#>hrwc&#mP=?@z`& z?=P^#^SnRKqwzfN&&CDz^J+QI`;#%x`wJ}X@w`9Ir|~@R&&E9O_w#Ex&-)WB^?Ba! za1)X7^SnPA^SnPB^Ss|LsP%c?-@yIR46iSq_q&DEJnxUN^tTLLOgYc{!@?TR^Zv$| z=lyOGE$4ZEgrz;6_ZL&n^Zu}?#`C&-)WRV01ap`-?Hp`$N!pp7%Gf z?}w#+J@3bhs`Ova`;F^)zcJ7I{VH0Y=lu;V^&8l&s^)orH0F7KhNXX= z_lMOqp6C6IG0*$m>RQh8{s>Ebp7$41&h!4ThQ{-}zkwy5=ly<7E$4ZEGUj=IG3I%H zz?%#iAJ6+6SlZ)xzh7I+dETFldEQ@)dEOt^(fT~^&#<)5^M1dsn&Cp7;9!T3*llVX0rw``6dGT+{cbBQ=XrmGr9RL5iz(-Mf7n{%dEVc^63_E~zm1mH z^M2!c-fvvb`v+<~&-)u#+T(e@-&V_c-k*$l-d~J)-XFHp`aJK?u*@IN`~CK6p7$qX zp7$46`saCn+(F}c-k*(m-tTwRa-R1mSnBh<-|eL3JnxUjJnzr2#PhsA4AOX>_cz8o z?{_v{hWE$4ZE155ur@AtcFInVo(G0*#paXs(fL+kUrKf}^L&-?wJ zYM%EeW1jaHSo-IAf80ysdETFmdEW2$)^eWrCs^w9yx;AkyJnxUNw8!)QV#;~mACAy? zp7%G#Jnwf$YJHyfCs^|5d4DnHd4D)c%X!}4z|ud@`~A^c&h!3c%=7+Y%=7+mjMnFQ ze}<)hp7;A>)jaP{#ysyYu=LOK{&<|m^SnPB^Ss|5ukk$ZZ(!-Kp7#$`*Ykek-fYj9 z=l%W!ZI9>u4J_^Pyx*Ou=6QcK=6QdHC4Zjxhm$m(=lzW_&->lUTF&$S2uppQ_ZL&n z^Zsy(#`CaPn-k)H}pXdF>nCJcBRE_6(e}*NV=l%XPHP8E#G0*#pG0*$M z>DnI8`!g)<@x0&vL(TL4WX$va0?YV$-XG7Gqt>)_rp@Zp7)=n<@LPZ zxSsdJ12Ap8|J3vTv(@#yAC~-i-d|v8pXdGY9F6CBe>UcMzdu*&^SnP9^Sr+p^SnR& zQ`_fxe}<)hp7;Ak&GY^QOa46XFQ%O5{oy=~=XrkvOFYl}-T7*s_ebLgSU&oXocFtr zHGVkCqA|~RvvG#~CtW+7M`u|2f0*T;YJNPAO~yQrEwIGb^Vt8W>v^p4b1nIn&%3&f z(GJ&_`GzmFKJ#siGwiW;+^#*e_y2A2MruluTFzR|dzAHx#QeErvI=9`S)YRNZ$ z(=lKFt=4D0$vDFWw)v*-G@khuSoRO+H+-*Vz71^ibw8+?Z#4eACEwhlrC z_5TMUfoZ|8SRBBw7q)2 zfF+*&yD7Dt{YT?+BW8OId?0?x{nyW=<#j*7(m%&jj1Oq( zzx3(Yf0#wvWB-kDhTW_k`%kds$Nmd!`wz3Jk8SBc%-*s82A1~Nznepy!3f*&7gJu> zb58BAuBY)CE&Vrhb?o2Gt^L*Ygk?PJKb!JPTG~tVc5JV}c06G|HQQ@oX`lPk&9CJg zPlTnMuJpP!a5qy{n@}f^{VghVTtGZxUIB3u1_@P`eaz*xjugDj_cFF zQqJ{p+h}`Sp9o7i*C!iuef&U;=lUdLu1_)M`h;zDd|aOl%lvSC{C3(O*C!dz*D~K} zCynQP7g*Zke1}2m3^%Zhhx6@r)_geM30@sPdA-!@0haiBJ?x_G)$75yUJtu!e7zpv z4%Y*G_2~9F-_2lckMr$z)B2q6Xw3P}u#AuM?T4s2-^rNsU0~TyobR~1#&fr6ydJ`yTE2AK`s}Oi4ae{bEbZ0x*-xEO-oTPiU7!6m|GGYKhxLIa zzOK&!+Fo5BtkHk2bS^G^*LBw*T=Z758PpW z4$=6!KCt9l*XL068ZGnfkJNI`cY-CK`g&o^`3^^Ee0{xuB_GbWKf2?5Cs^{~d>2^S z=X{4_)ST}ImUzy$JGNW>PB~s*e0_+QRPC{U8)MG5J3+@^??15A=k-uv84s_AaH4wCmi0)(w0t<4FR-*%_y4Kt zjPeGS_UryXP4lVyA6^}CWA0C|#Mk|Qy0%yMzj59F|Iqll|6$38>yhEjMz=o_Km8eM zu1A9HdiXQ7KG!3`k`LFT7;`NBiS?G{!r& ztVcOdk}^NxIP7za;{IfRNLqJG{#&HcbUf5`8Vc#XJgK{zg*{o zuLlh*{qf(ExGS_j{(F*WyieQuT%+;BIi72^y}CZe8RhOejj!ticUT`-)`#m6uGe_3 zM*~Z~Tn~4Hn(Gl^yB-;q>x1jzZ&Z(j6D;jycr}hu2HEtK)h!u*BEvBWrv0`Y^872Q2aR`nX%?zg{24Bhg=hCEt2|+|zMA3M}RI z`nXryuh)lhy*}>K_%;iemi0&vYy5DI50>`o z>&YYPjPeGS`Kqrck7_<#j|AK6qrehhUr!#>_P8F6aeX~`T;sVO5k3$<<@LQ7k7W51 zh{wNMVL8_$Kc(jDyMMNudlNrd&h_xmcXJ*;mvuU=2a7qqNbc>7nse}`qhGrIThXnS0r1j~AIeTwlD zaClea>+1_F_oI6Kyr-_$4=nA~>&LiWKksXKy?)@K=!f&q_3|HRIoB(}GT&UUVqC8u zESB_FuODNsm-|S|xn2<-IJ!TsS25*Wukf+<$MtHAuWOla|GBm|9PKu+op1Mrw#WI7 zu;k16&c>W?|E0!rz7uTcyTDSP^BulYbG{o`=9BXszSjDj?*^9oBVjjE&H0Y7o$qX1 zua9pup7WiI>-%40&Ug4$=ZEv1VdfT|#3oP-R@6fsXnD$4)jWOrjbEUUbv`IN#Bj^PORd=Y0F_YTl2M@nbFX-{2oP$n`TE z>HBfJci8Uoc{)vc+S5YzvKKzSn6~BvoYu2PtbAxGc56(e?OtN zKN3#Hoc{t#Jm)|3RCE3tW6retr;SjOYo-o$Foe*;TA=ig1D=KM$F zms{pPO|Jb9M|FpPRATQp5tjZr{~4D4IRAc1E$93vSjsv71-AE_FqM{b{u@}@=lr{= zwVd~xXw3P~#v@@rjpon!Z(!-4^Y5nB_BsF2nDd`uiRb+L>C~M6Wc)$P{Dm32yH(H) zUvGx9e^}b9?=O3+Gs+{p-{|3TE1z_MTK`^UM|8RZQu`-}OzxwU=HXM_jhC)aPTmj0S~wLBxv&)2cN1WUek zzr)hr5-she1+;$6AC~$x{{^+2{WZol|AjQ3^B-XuALl z{w$*LtF+|b;2()ef6U)4uI(}Z2upc}vngl(ehDpS{>hm67h~ohmehFW-xxE0x0LqJ z{39&=e+Xye&tM<4d?cJ;nU8w^Hs$sHy|l*H`?qnue=nouynjSk+T;Brn{v5uvOwX~f1 zC0N?yekjJ=4`FSMXa0>b*Uzn^?eEbt9zQ_qb3DnI<0-K8pW(2+n&W9;nSYMQZJ_(jXI?+rD+?r&Jyulw7Wdf|G84t%- zV9Af;3sKGMyMZO1`^{~k=J+El^*R1*%<=mzwVdNmu#AV}cUx(D9Dg+C^_`7*efzDo zJzn3*nAdkP=KcuVXgue$fn_`%b_3OXe->dG58t0T^B9E^4kvW6bq%yK25%j|9v7 zjD(9Z*CPzpa;`@MOMhGsx0{;l5skSX*_i9$hiH3Tk7UgCD6q88^$5FbzFdzCOZh)r z)+6kr@xzf`hV6RzebpJ|36}BK>jRed>-Djpx?Uf!#MkR%e|5b+V5wiP594}$9H8-> z&t%N`EXJJAaG&aCu^O+CRa?WQs zT<4GX)5bW%?g(wa?r&J;qwa6xy1$Rq_`1K1>;8tNe%;^rN9E$WzhN0)-QP#6xxb_F zNI1h%pZnV%qps^=T-U?6uE(+3eq9e^&aXR8=j*nX`HUxO`EZ06*zV78k~*Wjfn|K0 zPj|BB%lVAPoX-qPJm=G&qUL-iSjNx!EXJJAFihh)pN%o+)19j2oX-eLd-eWpT<_nf zX?eYW8`t|cEcw>^_vvcRX9EvJKir=WwalkGTgy403AXcDj5Er^IodwwvwXJgFybmwV%oX=>?`OLf1|p---d1b#hC4fn>2o_miEhVT_3g|Zr1pEzlNp#!7cUOty<3d5gve_y#81} z8)w-6OXHbef+e2UQ!(Ydp2BS!&+DmyCH|n6e40Bnp82>tHNLKgaYk{5Wqfr#?$UVX zlVB-lKE;^%gskz$x8xJ<(fZ7%fhB+D}bN6dJ z#}|z`zHH3#`3JN;jxQP4*H>8PqrSdAsIITCu;kDCmwQOddH;&Wm$i&9JgV_^zF=vu z&evn=%=Tc(hvUn}9G`z&%Q?OTOM4t&G3NNf6B^I)HO3sDds6G)+>(EKTI)0a0!x3) zKRlz(a0A=?-Lq=uAB~xRhNV5`@1IlG*K1hXtFPC__4WFBjpzC_u*7qH+zaXvE#oUM zYB|RjUefmJ{xi;O?`4gz`_Gu;%f@y8y`t^a{byYFA1wLS{r9T6?mt-O=b4uLebIR4 zpJ0h+{>3=M;SG&v{*5v7cW-Jr^N+B!$NaM~^Y?FQJo8V+%)h`=|BaUX)4N)q`4?E? z>;8IAol)MvGGEN!y|1qO%ed|@SlX-m>jQP&U$C@S_m^?qUmt4xe_HY{A8UQ)A3o9e zx_^u_^Ziug>;5sW`^UKMpZ{okb^jRG{R7+l!)NNce_$E^Pc8X}FEyU|H?YJrfA^I- zgAtbgn142A{{Cw%XZ{J6_LzS$X8vKM#&iA~W9IL^(fZ?#`bu~HS10eMn(wqe^LO8C zJoAsn8P2fH-~XWT%s&}3|6U_Jg#yF$7 z2-|$KDX;V0N#pB$8`t@UrGB07&gwefu=GDmOTMM6#xvj0P2=nSHfFvKAL=Fj)%^`i z`*nXC*Zn<~me>6aOZ~dPjhSy4TjLjK$v5@T`pmb$(m(SJNDSD%zO(h{V&^+ukSgQ8;Cf*zhu4*Z2$h|CQ@gVM_Br+*B>nH*ZnZD zy6y*9;_H5ZrTw}eCeir1A7F{E*B?HFP5dGIhowKhzGhQC684j6eEs_vJP`k#<6Em` z{BBAu=lByW`Ek99afZWG+CInMz>*Kg@9-gUVvaw;l0V0vO*zN!r_p$hKfw~u@fTx` zKTNCf9Df5#Jjd^*Q*-@Rm*X$S9DkTe z<2n8YmUxce&8+75BP`?L__J~SeNi9HcTmfCJU)a^>T^5^mj3E`8fTP;zFNLtOM7|t zj_vt5G@k7xW42d}k8Wu%_UqVQhHZX+E;ZXr#;3Qm=jQ3yUW9FX*_iG5dA0namiC(Y zI=1KL*LaRM8neA@d_zlnVZn~=HL%Uk;X@I{Y%dz$-O^rJxMO=^5v|Ys8hA7O z+@f0kL`!>VF)bgC@B+*JVS8b5Eq}G8ezSy@v%bTJI@-H<*e^R$NCAD z`rozGFH37V>xX4J)^A{`Kh`8naMT}p|KgU@>z(x@Z1c~s)Ss-SzVF|$eu8cN0!#hg zE%n2S9qTu+t?yRS`t!8Zk1KbqpJ7|yucGyrYN?-A)p(A-z>;rW|JBqP_Y1LuqZk4J`4@*KMypuO;8Oqn0z@3`={=*YBjxaDt_M=38JpzhRJ;GvCIT z`MRC8J2^16Tb z)%ZtR@@@9la^~v}(Dv&7HO?r`u#B(n-vc$C`6gJ(>;5&a`}ZJ?XTA+A@pbdbs#X}|7YQ_g(DVOn1IuW{YKhiiLv|H9H<-M_}~wdCuM(s<^Z zV4H6-X1?KQjj#I`mU!mtj?wbEe~s(@g(bf3-(xkt?qB1tTkIs^YLeEJm)7FXSl#Je&!R-(Rk+5z*5e9+_`Gz6Jg1R`zxDr?l1pOji0k6-*ldq zGv5MBdv!g}S7($ru;f$M^8zie>j_JFT~A}?>o3%J=9^%NXTHUFv6g(pB^u9s8`$RS zE>&lgM_AftzS)#BUw@gFGv8#)dc%_zn-BlXTd?PIFaelLLhW*tV z&wLXs@yxfFa^@SZ(Rk+Dz!JZHOFqqY8qa*(^%~E7qH%^ZZ0FD4pz+Kn!BWnAiZSyE zH){MgE%}7uTA%qeu;kBt+|B9?Mp*i*>j~TU6aE%0uj^^dd*Y&(rH^S0hT~A}?>+jI`x}LDjx0v#}o_A_I^KD>hpZU7Gw4C`y+ISG45opVD~dn_y{=^H+>B9G=#A=G(wFU-yibGv8>;d^0TVGhhF##xvh!d}~X- z?gfo!z7dx8>h)rr+5W#ZzFse|#Mk?uDQCXnMU7{^4J`2wwB(at)_CUQU(xt_Js4+{ z7uc?Mcva(>PXkLi^Kq}KnNNfzpXXZgNk!wCPk|-AUJq}mGs+uS`m5K&n_A9%A}r<1 zCmS;#|CYvcJrgYPT+d?sR!hF|U5#hH8MgWQ_tcr~!_q$UEvB6LhWE9c`8LMP*L|Sv zG2aMFd(1Z*f8LUB_*mnaZv)$W-6!hI_F-wC`DRnjeEp|d&U}+G^DVHn|4U0g?sKir zd?GCI^?ESQDED7ze7zoEiDy2=lrx|3rN%R#2A25oC&Paj{YT!<=dU%M`S_6Jo9N_DQ7Za^~9@ zGhf$5+gqq5AKy*uGoJ+8e2Q^KdFZb39Df5#Jjd_G(sG_(MdJ_Q3`_j-E%_9DiI9wk z`Gg)C&-HAKGwjCIc+O9RrG3s%HszcjKc2>OeiAJ4>$K$4OrY`1$4#j5%qJRWIKz@Z z^YQo+Bx#@dBv{IsPcddbVIqy+q9va=iPmR68J6~$kDpYX;RH*6b^pNj^*l_b<#qoU z*ZtE=+uNljA3ufGXFdtG`4nU36Q}S+?&PReJp8Xft z_8)p{`57(!dwhwOjEDUvSlVO%#W=&EkH**afF+*&yIDH+A7N>~u7@%22Yyzq&-+1w zCBB~L8(-3rf1F+8nSX{QpSr*CrC{RB_F-wi?r&4h{KK3b^KW2@ulu{7y1rk4rTzMT z!IU$9KbOYe)RKQQkCrokH?OwG{G)M(Gc5Tqe~&LYlm3~1GOqUv<9l2B&kJaK?B6e_ z?Xmx4oZ$l7{=-5V&;A=@_U{(f@~2w*FN_6a3+GITJzcJ3RTTJ6Q{s>Dv`_IPp z`deJ%xqiu*>sMf@&-DvSXgt@iF@C)ze;+iS`6pP~WB$cB!(nNSuh$PO@yy>Xqh|gQ zmieyNk8!&KKc|9~&illsiR zG5(>Y|Fp8U$Nmc}_1S+|MV;9mZ2NbsYB~Fl#_T`C63_YbtEoAE36}oG>4pC=`j5PS zZPw6u=I7Sbc;*+4Gn`@RuU?;PX*}~w#>}r6Pu|jhUPs$w|9)L35f47mwGye!nd(1x@XV`D7@tnT| zOFZ*0#>_u#qUH0o^zS#*_Sk=dr9Jjvj5FKYT;uEY2}?Zt#}~qnG5e3kOSkkNw$%36 ze*;T!oc)LG zG@ku8u*7r!xb4;4KM|JxHf_l-?Wpn0ufP(|{K8J^3^%a!$Mtc8w4C`x*uMYCrhLbi z{+nI2J@)T*)%MtbG|q5_ZU26-#0SjJY?)K&l|G;u)Ef0|BZ2m-5wqL zkMIEeXI`J|KO1v>{GJ-m^+~Yg$Mq?uoXSByEnaG=I>d<|^J=MK_xjxWN}-bgr`^7_1F z(s+(9!7{#6d!fSUKl1wE4%71CC`+*P&+!%G42Q$D{d#|aB_FPzJ3`IzMOfya8aW!010RK7X8+4@X%8OaC07J6@f^2ur>k zUxp`24Br3@2Ff<@gFL`EY#UG&RT9z!J~#xzn}0-XCEp=lHTI=lJ|Tw4CEh z#vEUPWqfzFj4z(8WuORmV7uqcdq8k@kL{fFT)bg@%evhJja({Dd+f# zDd+e?qvaf5W6bfn^ECg*TE>?y)N+o`U8LjT`bFamXIS##`25A1FUOaRIlcl*JjWL< z(Rhxpfu)?|bC+s4#}{EK=lHTQ$LBB8{9kSvUvs6FbA0})j^j(l8RZ3*{y4sHwdTX| zHO3sDyGG+Vz6cM%Pu|ZtzHG`lK7Xy2b9@Pw{y4s3%<+ZmH2)8NHNJ0tWqy8Fyh+D5 z9L~n|dK|9h8RZF<{_FK^?HCMU%sC%#+=V^hxR{1OMme$t zwtl=v%a>@W-`uO^tncpYSUv%c`hQ)-SNFA70n`SGCm7rDOf@M#uUMEdAfsQs2MTv3>*F z{@vSJ|Dl%p>79=C-Mby@M_BrQp{0I#Z|pJO56k(B?{}=9VX6O4Oa1Vnu1`k&3`_p? ze(;gj=l)N|_4OE*c<%r3vAVtkA=C6FER zi^iP43`;!c&;OwDoWEqu`75yG(`gE{Kl+cn-%r12d9G#SjF}J4Uv%S)>5uc5jX8h5 zlg4xY5-k03{#<7*=ln%u&R;g>{P`{#&;6H-Ie*2N^B1~mJm;@5=KQ&CT3-J>qcQKl z*|>hbS$B=+d?#bhcQLM?$1|43^Zwiz^Zx9{)^dLSWHjdbWMkgH{Wu!W`*(t6J}-w| z4=ukIj>f~`YxsXN8M#KR8UR@$VDB}4VmKL3 z0T<)x;4p*6&jdHdePK7Fmd_1G;|1Ytyg2N8Yy2{BGF}lb#;e0&CXHVYZj3j9-OO6P z6&#IsfV1&n*!R)+z2Rhh5L}FpfWs^re>~h64};yTT7DKBjn9X(@nx`|P2;bHlkv@P zF}@QHeKmdr+!#L!yVp~Bpl|{_@Cg$xNBGR-%rcO zg`@Gra5kP2_H${xhm-Lva53%&hq*O=0k|<<9Cq_)`Lb{{UK!5DYr%eAjo$!H#+$>% zcpx0+)A&JfW4t@;=GXH5;AngZoQ;o${Q??)BAkp*hl}yKa9B{|FM=E6D`B^gmfrwJ z}J)meBIva5U}*GD%kkAsE*d`#XX6)PzktD zJidAc&nu{ZgxyN&F5S_;aSu2fPXzmwHGT>>8BY%v<34a$MdRm$8{_$5x2l#e21ny% z;B34S>{rwHHQ{8uK3t49gTv|?zYW|N?*zLww0sC0jrWDK@xicPQ{#_JR9sc z)cCpKWV{eujF*JNMjF37+!(J4yN$Jc9XJ}}qXb+w-U9ZUX#93?GTsF)#(TnHQ;k0W zZj29u-DX;jf69u_6HuQFXX7(qzqyt-a5BCGF2+~GA!__haASNs?6%Ny{L>_S-hldH zI2+@i#^Cb?v>gAG1fMscejP5x_@@o{ya6r8KLv1&@mH|hTFdb$x{Jo0$439gcof?C zZ8W|ooQx-ji}7@D7^v|x!;SGAu-jJ4=Yym1qHs1|8ur_1{EBcgUIQ-11K_Z|#%~HY z##_T~2Q9~=Auby424~}aV85frCpZ}&2^Zs`aM(%XPlX%fvtc(#%P)YV@#Szfz7F;~ zYdnsY@cr3p9M$0S@6|Z!z~|qqadd#szgOc|<#--N{W2Vl--NUA2e2Qk@%Ysuo<~vR zS9z`&{|txSw7lCm=-+re*bUM0N#JNa6`YM{fc@?oKP#M!=Yoqd-fFtAhsNWrlxvLf zR>8SFwHz;vE*j(3@3Jv&ZO-qd@wk*-GR9VQ#TZNB!rmH>u3cliKkW9=@k8 zPlElv8vhSC8UGV5#uvk3KaIZ%Zj5h)9g^seAN>9FZE!Tc2hPS1!Ttb^e-ci{FTln4 zH8>oo@$bNm@yD<`NXx&3qw)7}Hty5|{U?nd8&1X(!o|2391hm_Y2n6rCfFUK<+H=l zcwRUgF9LfklFV0tlkp00F<-uRt>9?91DuTq!~O`3-y2TG2f@Yo z2sj+6@yElB@i5pOrR8VA(fE8g8(#+dqc#3oI2qpz7vnqOfK4p(H3DvoABEkqTK)_i zjbDPZ@f)x|PUGK)lktDxVmuNK$7}pgaAVwcT=YLw%g2SI@x*X8o)Y#aXuOA$@hosL z?gxhxHGToOF{eghnh{{?5`yJ3%;p3K*Sa58=Z zF2>Kp;S7y`6>f~*hTWN3{t+CFzksvxcd$Q8Jh7lxDZQgAWu4+p#`$b78^H^%G2uF>+1;b^=ioQ=1K{dpR{E1Zn? zf{XEia5!J%4~HA$<6w7zmY)Jg<1^uGd>-sC)c8x`WPA-=jEBSFB8|TTZjA4P9bP15 zejb6N@zZcNei8PUXncW_@q2JF{uBgNt*?1+`<4uIj*P3uLULP*To5A5~jo$`tjCX?F zHCjFdj>h}K*?2;nxB6=}z89Q~r-h60OmMhP<7bB(<9T6sy_PQmN8`lkxFzF&+kon>GF{xG_E- zcDHExWpFgU7S6^u!~Rx{zY|WzBj95EC>;K!@z21G@k=n@bjtj^0Y~Ha;cWaL*x#=4 zBjIHH6I_hDPKo~S(D-rT#&}}b-KphM!qM2n*?1P%-=*>W;AFf2T#OfoL)Q3Z;l_An z*xjw=Yr)ZY12`LR4*PpFejuET2f@X7cR1Xu@%zDz@gcCgPs@*nqw$GwHa;EpBQ*Y8 zI2m6A7vn48aKFai05`_}g53jJem5MAAB3~<6R>|!YP8sBAV^l#h)b}wrAL~t~o0?x+M!~P|W?*k{}IpJbFKOA1x_{HGHcp2Ee zqU9^W(RfWb8?O)hS2cb!I2msP7vr7a@S4UCfg9s}VfVV09}Gw1qu^|O0_=;%p9Ux6 zbKqipAspV&_$%PX_6td$J_=z#*}9iCgTwd-mu4**UN{&2uuHbek>dF`7ytd#=i(BV?IAtV5$E$ z95z;e2sg02KJ)o8hhJKV`TSTk=JR72mhtiVv9PJe^ZBvHn9q;7%`~3Rk0n^z=ks6% zmi+iUSlC?4`8-%-%;&rC0N0p!KHn8#X^+o$Wn(_C<+srO`Mg$R{B6tn#DN;0(Oog- z`owLuKdw)PCI9+--*)Qyd><_Naeaz0*C%YR@m!zAnCs*4OCqVy^@+w@pKQ$a@jGh% z_4z(n>euJ{c2d{p`{047$NgHLuQugepD;-CtIzAf(jM2x?X2edL|Ep7>yu46*T?Uo z@m!w-OaELSx2wAQH1Oy@W3Hb)w0t z##}FtU&={+u1_-N`V?cXPuNG}xjv0C*T?Ov;5@eij^SkaGE$8#Q z(U{NgW@A3T>(AAAKEIoc`TTA%=JUJZpBm5ScN=3qzl#s(8ngaH=Xd>i z8qeoH=Xd>u8qeo?`C5@zw0m2cs{?IjQRX-G3N8T;Zluve7@3{&+od+ zw4BfHMq@s|n~nMWuD@L4`TTA&=JUJ7n9t9KEA)OnW83}wjvizFJu>g-5tjAh{X83I z*x#x5bKb8LJP<$mdNFrP`!Q>KY(K;D`oQ-6-P(VK6DWuOP+x!Y_^9zq?IrD3bnV)-9+vDqLgrz;co@V2buzyVR->4=3@`ToB{^3b& zpZPb&8Fo);e0~3K%=yj6%-=t)@%8;b{Qt3a?(x1&RU4mTR2HVQcjZUeV(y@g%X z_B~_FF~{@F%UXNyV;}d&-v2|~-v9AKQP;!%JMa>G=6>97r2qB?<+J|^_WI`kuf!Gc z0`~ege_)&cM#b&x53twc`$@V<>t$bmfW033t$`l`=bJU2?;i#1dJY@Y^IO$3Jz$^T z^!!d-QNMtFemh@*xgO2$6}SBa_IkFTdg-zK1opV?r@(d|Zc&_m6tK^4?`t8xob%tR zeEQJ^w)eH$o(~laMe&oC4$7v&ebbnF(rL2Fi>eG)la0OSe z_d`GOU$x%!qkuh5Kl;G*qq$G@?L2^&;Lmv;yOI9#{i?_Q3fTQ)e|_KzZk8*b{dM4Y zAEtjO&i>lK?5~2ozU|Kk)Zc|8{dEtjp85ALjW_=SSJnr+Kjz;)U>wr?~Csz_y>kUf=ffipsbB9N5k) z{t}7Tzh6pT)}O{m}(x|7ktV z|M!vk8~mjr@2?`gg53|+&yUo6tX~4#`2u^sov%l!9{sFfkF%frXw{>iB{2Q$!Ja>F z1N_0{gWq3UYlc6MSjJz1T7u8K|0+IrU?0!^(_=Ls`)>oY{|feeJD(eg?R*Ai|2=qL zeCB+1J|Cxi_TPbhee8L&v3NP+E!gLK2wX$lo;QzIoZl}gfit)Vdwu)<$0o|R?|%g5 z_ahSiQrHrFV!s=X_*b`3ydtl8g6h$~4(#*MzqF;;?tifBvGWwz&eIbWr+)?f8GLsC zGX9d9kEeeH?DN_COJMrfY^{9y*MU9X&fAj|x9>LvrhgUe`SdSuqkQ^T0`vPpJ=p!* za>T!azf|Y(ihk1esz?7?u+K;TYGC@8pQ?QNR|3<&J}~`jcF=s>e-#}4%TE*2j{^4j z=|>;peE)5BR6hOaz^-S<5xw;pidXjYOpUkw0`~cAzdTE9`vvU%+I|Ua`=wFb_6zu2 z%;Wo|*;#S!moBia|1O%()*tNi+4ma*+xkCSdUhYt+w7(|^;WRgqu%^n%}2c@F!lCe z&!^sIcQN&LfvGn=PtPm6AHhDJdi%iC+u$#0y5H2>fjysk(;i~#ZNW?M$Mkcr5xr$k z#VhjCi!|Q$GuY>&-Wu5U^NW>l`#G@f=fJj~U!wVJKZCu0>dh||+kOW7{I;J%-1hU! zlyCbP?0VlgqPOm)c*T6p-WqTF8SL{>Z^B=Cb+-Ks_I_g~Z^|Bw;A34ck~;}!E2u=h{BJ=o`?-li2(ZwK~#>P@c` zQ*RrXdMnuHqu%EA%BS8gustu|p!t@w9@yuz=Vf5~dBGc1zl`a9v*H!?3fSwJUhqKg zeqz%L_I%U(7P09KYC^%=?!dp_t$);7wq$y-oU2!0M-A{nBKQ5ZhFC9&-8)^ zdJhttUa;qz-h;)aH?Zji5A+_QeA64)^u9y$nO?BZXL9-uYcB<-ghZ(dcj`L z^nwR^4;PzWu;-iJcZ*GLVABiser!JV-z>N zV6SI-!2`WTYd-q;o+mcFV9z(bUlN;Mu#Y#rfq6gY^OaA%B{22&fvLB-KwsZeZwL1I z?dyv#i|y+Ru+MK_Uxc{%^A+XW*Oy?=KY{OSA$~HrxlsB1`vx6&3Hsps`hQ0J?JiNg zA}@bUPJdgyO+ zh4Sfd7nuI0D>WbeZNWYt{jGuNZ~i~!)87L2eEQo5roYV()XyVF{B5pLyt03=*Q3Ar zN1BiRmcaD42YWvKZGJ4Kza2RGn|>muzb)9u)887H{^p-5PJavdTzvNZ+x$#%^Ea^h zd#&a(f5ASV`5V~${kihZU$Ez!zk$u)>*U{NWB%Ttctzh8?DfpwUuiz`H?a8&_I&gA zMzQ$|9{78c*!%_ic=I=~`FpeC<}cX4U(fxUeyuqDZ3ENa3ikQwZ~l$)>2C>4e|xa! z)87XFQ>OPvf4ji+H~mijZ9n2~x>fOt^aA#J^tT85eDt@uO-z3~u;)nc19t@$|O^`+W4b2ByFHU&^PyB{2Q%!9Je;HV=vEZwGe0 z^f&!mOn=+J^tXatk3HZ1qkOx61Ka)kU(ILtFWBd^`!_KC&G?_Hyjw)+?C`F8)}fAV&=`xor}(%&>+Z1*qN^XYF5 zZ1?ZO6{o)iyab>9`Ic5y-0t7NcK?EXe!G7cDBtei!1T8Vd%oSjt0|xUc7g5wU0wYg zIO19Ok9?q9Hv zr@wt*yMH&*{C59>J>TwM{89vG`rCqCuid{PPJi>p%D4L$yaa9WJbiG)-?EwFmHlt7 z@pk`$eLnhI1Ka(JU((?H+5H>X?q9Hvr@ze;#CHFJeLVe5TZ--e4NQM4*!9@``$Xl_ z-!8D-zguZOyMMtxpWVNK>2Kaz`F8(;J)i#ef$jc%lKMG)#NTFH#Vh*#_S6?DNszW@oY8 zzhKX|`*#X-Ysf_;Aao1Y`L`xor<+x;8j zcK_m+ocMVDeSr?_`TYM!(sLE3pKW0N{~#5-1ZiCFuaEd!_fWhduX%y$+5HRl`RH%L zFIjQ6`xor}+5H>X?%zF?Pk&2byMMtxp8hs365IV7csb{PvHG?97wqHh{tayR?@Khl z-M?VZxBK^{V(#A-?E38f4RP+@{4(X+{R>`#w&?HWBmS1X6|e07l^SpNFWBd!zcsMk zzyG6ryMF`Q{R{T-^tahZZ1*qN_0r#jUxMRo_b=GTFX#M$>2H3u^6760On>{p^tXA9 z^xFLk_WAh#TjhPlnf1W#-zMPnTE%TW0^53kyksz+ZT$}r+xiDyj`k`zet)ESoASB-U0|+%I#Ba*{adilXX_uB z>zUuKe6D8!dp_5*4{XohgXG`uM*M9KRlKr)u-Bu%`JI}N{+7V>w+DMZ{cR2t)87sp z{Y~!@)87{Cv?iqqc$J^`Qo`J3OZxSg-ScD}$qzn!lmluv)V!1OmAseJm| zg1tZbTLaVIe3bmVYsBAN6t5`XfxRC6P4Crw^tTO6e=FGY>2E$(On(d5^>P39f$4Aa zKIPNjE-?K~$0<&KTX5XJeTdWF=6L1P-wy2a)8BN0;`Fx-On)ob^XYGXzw+sC2~2-` z@Dh~edOtYgZ-0{FmHnTrdi1w~eLnh|PZ87K0*?Onf$4AaA?4HGE-?K~AJ%yK+k(Ac z`rC&%{cTQFKA#UA*!!cu=_88M-!^atSFq=A0?wx?pZ=D>_V**f-p~BUp#J2;e}2+^ zLh*`N{-o;BzXJC8=wBb0{xzp7pZl{5O#jjuiqpRqye~d;J?UQ!ar&3f)O_}S5}5w< zU|%o#(|k&t!5!H3E*{a_e@5|&`P$EFyzLio)SEl8?H91mPrZF$+b?G;ZuwyqzQFerUly-^L^Q>lYQTn7=tsA-qs)N{ZW6u zT5RhN_W5o71KavvqqwbqV0&KtNcE_{1$)1C{=r^CF1?43 z_|g7J@rv{w?Ecb^=1$E|Kf1v5BmG(V^rH<-KPuS!ryuz)G5siDpO1d@f$2wcx8n4p z1MiE^+&{cO(mjgX^CU3+s$id=e&xR?pMI6V^s5JZ{t4jbUge(*?gI1uHT_looiO5W zbHCyh=@smH>2F@H`RH#6On-Z@=hNTjA7c93fxTb)n;sC;-xloS>2D2e`|Y2K)87JK zg3nWbA5`4@4Q&2`eSY)zU&=Rs1Dn5K&o_S`Qoi{c*!=ys`uW(HzbmXh?YB}N*!7yf z^H!hEXZ{8@f5Dz_{^FPLI-9>>@7Mf&nArRUd%pP_*!*2daq}0vB>KCu;^uE)^B3&% z+xLf75oheb0`~ds{U9*E-_y+3e4iWfFR!LJ{p-M9kN&0AH6Q(J1Jl0>_I&!6*AUac z0`~stUmuwMHESxL{&j)rUs_9X`qzTb#b@828NU?S=cj)qu-%tnpP&9Ui^TM=1N(UT zm(~{3zZSe?GT+4`{x$0>Z~HH>?LV;R+x~lm*!CaT$J_pUq}cW! z*vH%c3vB!EQHs;Q0`~V+d;fZ@;`FZ%O#hmVG#~xz0@J_rIE|-&ZD9IW!S3JpM*QnG zRh<6i%~X&66|n24e|=#3*KDqQ`qu@fe`yPir+;l=`d7ixzx)I-{VRd#Uk~0FpMC!| zTPmOab%E(u!Y|$S{(1kkfqDN`u+Pu?FK?xM`~6p7_wUCe{*@;yUNK#Iit5q77VPuW zzZ#hSW&9FwpP&Af!1S*N`*`}-Y$v9F9oWZn|E2B4^sfy}|0>w^aQ`(=RlfNb*!Y0CF*Khs>HvgWbeDg1``3Ls#=3gT= z|G?fq^{1W1Jb!IqK3^-?_3-)H?4o=-pMmL5dbZ}{_lw%V^rwP-e*1psuFB{4{|ngX zyJO71-4(BxF5#ENdp+|H?E1~Wz~yd3RS z@VWTx=eN92`F8&Wrk~B8nveUh3vB+rNaMNxTCn$P{({}V(RgT3Nig_!LFbF)xh*G@1=bDR|3<&9_-`kU$eKE{&j)rUwY;6`H}ET{(U_CYXj52 z3ikf#Uw*Ba{uQu~r+@sAGp{PeE`rhh%y z^XXr+L`?rWu#cyI>CIyL*MfaK{i}iLU*1n~`d0$;{_6wNzveBf&-31a_eCD}tKElh zRh)jdf$cs7dq4Cu@2`Bj55Y?&^%iCP$K=EPEN@r5GIo&a*?9)LAM~>Zw)1?j^6fka zw(|`3@phgM5!-nNd;jz^y+ds0IWYaKf$3*HRQdF?fPFst*@Im_{cPW1RGn z_2_2-dp-KugS}qPXkhZ;e)jlBEIeKjYmZbt`dPtVkACK(#PqX(-4FWN2d1CRdz4Q< zyTJ4_9j)>7vkgo?Yhe1Bk5Rt89|pGfX|VT8KbsO(yifCOmC^9z!~JgGuXshQ2YWyCyE#$y=yw;Gey0y8pMJN2>30Qt zKlD3)P)xrI*yp3)ePH_CoTT`2a2J?m zr1A8-3rxS$hc%vlw_u--epm34$$UFy{Kw?O{mvg#ydu_tT|fO!A6Gs4-3F%L73}%+ zJAXn32Ru^U?1D_OF-B@6W29`5oB& z?lj)~4s3p(t?}kJ*!7v;VE6m^84XT8rhcERctxxOyMN~Q7gf*v4s3pdJ>UF3Pi%e% zHow8%5B+YxqpUnlT|H_PllMmNhE>yfSc9H5)ZwvPM zska8E-h8q0ska2C-aat(Hec0z)LX&cKlSEIG@sp%fvL9#dp`9xUlUVr2X;S~WE7ly zxZZxL;uW#>8yZi&6&&^EOU2Y%z&=0q_JOIl`KIF3+kw3w>doI$oO%n`=cC>}u)VK* zTlv)61*YEg9o0WHgC`%Zx4BI5idY4E|J0kS=I8pBz|`A=J)e4;?~AFo3rxM~a?MA* z1?=Ogw+BbP%@tzm?ZBQ-z3ECZ^|s(8_+#GB$7cM;MdZOpL+Yi z)Z1LGeCq82Q*XLPaq4Zs-VgQmAx^!`k2D|Gw+l?Y>Bp)^y=`FXtzfTzYDWI#!}X?X z6|aaDu=_{7Jvi!ZelDio4($2Vo30a6ZyT6;E7<#?-sTs|r``_i^HFcQUQE3$*yp3( z8klYJeY?Qan{HM<^|pbjw+5!({AQtQ*R6Q`KY%Brr!Jqwhbwz~saA=07Q3 z5$nL-KlP?NH9z&XfvLBGJ)e5>pT*Q$0#k1f_I{|hy-WGjTftFpzFSPa1?=-tZy%U? zn|oCMs*Hk@57%4%y886@HQIR%OnuFLn(v0}qf_E|`~8W3)A)*TADH@^ziT}8cY&!t z-LJUmkDQq>_u=!Ue+=hq1GE1McE8wven8CiDPaHmaqKVsQ}yo4{DZj<_b2~L@udhA zaID`4X8qL(AR)F7|5zq6Lzs1OW_2I+$@~UFaSHP~1^Ywx4>$wGrbG|O{4kPn5tE;~03vBwR09mw)3>E z>T$j{Fz2g*IbU9^{MXOS$Nf^*(|oqS*B9IRfnA@iUtn9mM<{OV7x)ZN0T5RhV*w!yF=gS)?|LBqV>W0Jl@?*rdeqf*9)-SNFU)FhNe--TK{p6YXc;5Ss z6kiH%9;f=;PhH>&P8%z3_Yc_bPp(f7_W8~nnJ;asIOl7@uE*9lu&wWAiktqxra$m` zGxOQ=Xba6(*&o>FW4-1HV%F;d+w*8k#p!1oc_2U#`PhF8_W5i*0&~CQtrh2f zDS?-R`@mO@%vZJ<&ewzEe9e=^oUaSa`O;Gq=X`D8>qh2F+YRSy!EwGC*z|3$xakXQ z`U3Ye^DRX`We3g2_3XhuAN_5fCgyr}fw`V(N5#3GZQy%m=Ck$NN%PtIfqgz(zrd#N z8H$^}z@{(oLnHH*XAS4;!9Jhu&qi$fGqCN?opt`$Ujh61TXiEEF!$l_FWs{hU&_#~ zs!xC0z!h8r^StNhXg>PYfqlO9N9L=~Rh;wX-8G+`=fHNJ1KWM}Jmphg7kHDI`6}Yg z9-5E+c3}6D`4bzs*=y=gx&{cpjpk9uoh>dkLa-0sJ~ z_VsCC`}xval~280V1BaQZb1xI}qJXp`StKKI@>eYjW_42{PdIcQo zr9)KjoRNCv9m9G(IQG{ZI;>a0?(Zcd^_s(m^*V5@m)$1C6NYp~Z}`Ei(V^5M_#=KadAh;`sWzb6jo zE8snm$Mekjda&2$e9Z^MJf9ud`&|ysA5@&*Un_z6{iZ&!{r#kql+XLA3!Hg=Pga~i zPiq77=VvuAe}0xvQ9gfuRsydx;!pb#>8+Tqf}=nAH0k5>vjaze(nmEP{b>X9zN=vO z$DTJIQ$GFb0^9eSKdw0aY6EXH(tkQ#{Z!5mj{R4#&(HpwGnCKu?Z9z;)0twsufaZ^ z{r4fx{+mxJpZ#}%xxVQv#qIA?1m^nIz+B(_Y2`m@Mlau=a;N^Or+{5A&sz`neyOiL zTluygVAo4M`Ez1Ee+t;gbAPALD{ku%n9rjcn9rkpj`FF$1m^Ro5B$s-eV@m4{THQY zDY!XL^{BrKT*2u}%D4Lid>H=NpT|9T&k5W8alZ2H{s6ll^e0^)ravv%{iQz@?DgnR z{<8Q5BYL_EHJ*CXMXGOKKLoA_SFq1VJ^A9Ho(}BuQ&0M;^6mVAqn;Yr*839W+j@i7 zSZU5LyU)HM-e*Kl|2>VTp5`*mXX_KVvcIZ)TOaUY_~YsNfTNz~`^vZV0Y^RQaysa15=d<$}*w*WA<=c7%=6dyDAHN*j+#|O82<-jx{HDLGF!5(W z;`vSYi+O(2zr=QbtuSwz&-*K_BF^O1#k{}L+Vdv+X+h$7&+99G0(nF6$>fd2e4gbk z=A{#C{T3uX&+69m()lR6LRydx!}^sc%}ZaO#QA({w%2(6{oH0JF@JwYv&+1xKm7Y6 zU10n7kDsl6`TK72?iznNc~9|G`7Pr)Vd_23>nxBnKTo5}k~PtW{TdX9#k=5^9@ zJL2ihs*kOJzdtFy4_v`s{{iyb)c=3L{UP(xM)*v>PC)&9sOmp#9^&s-J^S~Oj}Y6x zj|}$xV*ft!kz)Jzk-@&-HbT7`*#3QF{3F61w|^fQJa@hqq-{BW;2puudlYZL9oXmp z(AassQRjUr?CQXC^DUY?uQ!P+;w^Zt-lDnl3O)>f?)Oh~^YH%Zz@E?ZnSQN$_C64p z=d*%6pXW3GW{q@VxPSUv#LE%y{;2zv=d<3WIL~LfPjQ~l?jLKU+mXk9&l>aNUz*?i z01y0lNL*2;1$)1Ce}M;n{Cma^u;-f}|4}{jBe3}a_I&f>zq)_zdAZV>ll{9W(T}`f z&FS-pel%-|=|{Wnnv?y!$nL9dvEsb1>Z26reUdglolNRiL*nJY1_eb7P`Mf_0 z*!|%Bksh<=WdANoyf0d?>$BgF1@`)OUt}@wivsq1-WNUCpHFsQY$CS%VoT}kIscQz zydUyYrPuC<9TeyNP@bXq`6K%!?W%s3qI?VX{`tJCfh#yaNBP_@1?>J@15UfiAA8>f zyI$^>3ikTkFZsD*?w11geD0SX9M4bpLh*9M+m}f%_e*)D{Im13@0ye6$J~C&Z(MWo z{J_s|=|9-tckKE0R*kpk+d+zF`u$G%dFhCs<=yIkDfi=NG zk94Nu^rHnwKWgBLc>a{~ZGV9e!=L;8oX#5h(SoBN73}qGe|=hP`wQ&(w!gs9kMw!* za`tnc*zTjRi0wYQL`*-*H&p-n5kJbe6km$^J=puT{qb#aMZ5!hzqUWVGxVc?2m1r; z`L;j4t9rIS0^9!hp7L#ffc-w={%Efh(~tHV>9zCrGsW$^{c_E;$x3tUML+7zYo=B4 znd@ig?bjM_=j|4axAXQ#jn5d@+@o| z@#g178h`JYpPQ^T)oXr&2YzlUHb24ckNLUTT7&aizym+Qo^O6`u6pKYVDobe<(r@2 zfuBzjo1fcjKD)obe!lJgdiq*}_lNup#koJ5T@?S%h(FD4>WBVx;OI|!u9*I`VAo53 zD)=yb_WP{aUH$TT*?~Qu{-o!r9{p(p)1M0VeEO50zt-S+*}q6kf4Wylulci&;KyclpQ4=ht`b&y~-w@0#nBZ(rZtsC<5X*Zfxbt8ENFCm;U(^mM!SAJ0Pz zj_08Uu88M9Dxc?}fa7^ccMQ)%3-vJe>vjm z{Fs`8*Hh(aPs}=pL*5M~CJU$fm!fV9cE9X> zK5#`mZ>oG-5Ab1=ey+jiwAsSJ{oR7yUt15b*SGc9Tx{zB_Iz6p@L)Z*mfq!@Z@Y!* zhOi#}jtkR1_~Yq%JYD&=9u54MaT#sgN<#RpSSBtqG<#l4-Pu-G*)91@(BkR-czcB4OslODT(*g2}>(d6V;0pG9 zu1|j3!s++p?Rf$AxIHfpR6ToM1YX8^V9&Sb#oHIA27gX}?R^jI>&f+~V9)3I$Onn- zc>(r(u16o(o~H*Z&h_ZP2TtbWdgMbC&)@>~`FKA1z_uRmP(IhA3(WOMhbq4P#^A|^ z-&gr?)u;aj?ETaKK5zv$?^Ztj@4%jK=i>;)`TgBCFxRJoJ)i57j}&u#O5j~b`t9DM z`s_Cyt?{;B0#}49*!{Epa*X`8{Q~y5?U$l@wqF7-V?D6v+kSbk^6l$Ku*a7pzYom) z(j2RN?w2kw_e*-8;@mGS*!KtbOCRFgFU@h9kNc$y%>9y%S3T~RHZb=~4gAuLkw5wH z{ZT)l`t&=0Q1$3{30%QF*!9!z<|OrR>ksz0t^diYXX_t$8S8;PpME!|i0OA1n0}`Z zsUH1q!9JdT*TD2Ue^~kSy974B1DoHcN)P?6;Jq*p?+f~!Kce~QcL_|td$8y8d^V?v z?Y<1$ZcIUQAHE*xld8}4Xu)2O>rn$&a6Vo6T#pi%=d}m>c%Ikh4CUMT2yEx$Oy%48 z2+Z}Wfe#$%zx}l8v;PYA`PqN|jJSde*w>H!_kr1e^I7HF&y&EO&;C;NDBsRQU^@?i zKe#a)p8J^Y_ls4Zez#!n-}Zapig^C2@@>C^y?@&emnd%g0qpf`KLlRJdS6pM{Vw46 zzE-}e_nqa4ci&Sz`kgM*c>3K2rr#Cp^V9EK#k_w?VEWyIT@U?kzps4yUBSK{^gCZJ zrr!nZ^YQ-a1M~iAu2B5+k@e_)sCrAO?<(bUJ=(w(T*2NC*CSu8{_TDNd))4qYgEtf zm%z(d5A69|kNl(IdgPxE*Q2>X^|&4#*vE4{(yzo^j~49ya6M{Zu1CI6ajr)J$Mr}z zDbDq1!9E|?qXy=BBtE$$L9|0_3V5s(|9`{ zf$e;NJ>Sm9AH;S(0^9ijyPgdH+S`?H=L78h+WGjS*v<#o=d<$>*v`itihq4$2%3EO zdUSWG-crWyR=%B&z!l*N_I~Vq+@t>Oe1JV}=i@J`XXhjEGS&lozMYSI_4TT~pMsA@ z9@l3%KBvE`o;@GHKHi=Wf$jNlpYrYb5ZK=6Y1H=W{*sJTcd!1ip5}|9)lFUrK$eXgvMz0#|UFuYCI7g1vwG z--kH;Zyv6C^uG&C|I@0fNB>)}fB(bI!3`Z>O#fT3_ecM0VEUi8P@Mi3u&)>WPft*s{5D)u*dEB zv90QHz1qObSP$&^T(7*{@VqoTYP_u%*z>tw>FHvwR||Ikxn4Ce*DLR&IM=Iy-G8oE zdWPZ|+=6{Ru2&7r^~%pwKG&-R=6dykAKaJ?&waT6&9haX{&!&SpZ=#^#TD3sy&w8t z!QMapZ=Rz#{qMkDkN&6K#LIv!*z3{%3XbO`KW}(m+C7HnrF+rvyrh?@zCAC%Uf-S< zf$e$ma^=(i5}5w?f$4wq3hAZ)73})xf8I;;(f<(%b7IM=I!y&l&qzgEokDqye2_3FX#`I6qG z{N;$ZV9)1yseyT3@)G59y-HxNS09+`)x25#+x-UielzRsr}?;EB{0{k2YWu(t9gr< z>(vEbJmP;kQ1zEmAK2^B{~EZ0^V^kA{|h+!pAJ%-{IXv-|0AvE5IB>30wI{^@u7ZspVO3ikD;-}wkJ{VrgikAC-o z?dy#r72kNo|8k7#Ers45?Dgn>Q^b{ifW063pWdtf?fDM&IQ{RzUXT7a$BOBH2ljmW zpWZjTuiE2>_f_});eFMgr2C5gHy>7g`rm=QKK)Opis^p~_WtO94NU*@M--?31?=lZ z|I=xT)BhIi^U?nrnDy^Kte6CjsY|oRx&4~Za`HQAMzkS6_+@9ALESmnj z*Y1DtX=s!0tLEpI7o~G1ybPc7R~Dr+Crm#pc+Uy*>x+D$csaNProTPde;!PKn~S86 z{&s=sZ@O6dZ=LDi&if_mzaqVYy?^eX_G{|@8gTx)`ser0E7<#|ANha9^rHl(A3fOn zrytEy^-n*#!1N=1L;3Wh1^a$5KfvBE{V10%N}od>{kQw!n;LKTL*Qd({4hP=ksr3c z-&K9P-@v|})YE-W^HEQGne^NG2DbIBire~v-4D|P_VZ!u`+c#kFWB>KeJ@u(JU*s#xuF`z;uf1CO=wA&?|ME48)4u|C zJ@l^!yMFrD{76jyITP=U_luGK znp=nc)xdX*s12V{RiF+f6o5xeEvo2 z#r;>o9_Rkc_iDZ+BmLz26hCq-{x`)d>UDun9m%hMALcjr57(y$`}zFB$oTdj!|^@X zpD+K1`O5K>OP@=>A|6YZD9IW19QLUf5|WI_X76)Lx20g^tX9P`SiB~yPj{2 z=qdk|o}Z1y)7sPbmx_96g|!EIJFwSZHZnf1I2_-BqhHO#G@gE?mDV2I4;|R|ANN~Y zSxmp$z;-`?cf+4^|Ix3!%Gv|JN?`icgFT;qHS^b=-Y@pN0DHgx9MM-74D~guDWChH z2fIJi*R8(x^!aP&eGTcc`!BHFe`_jEeFg0OQeO{_`=MD&Onn{L^QkW_R6lEM%0HO< z@cX4-d#I;fXQ(HwtMSxR!Tvr$J!P@_rJg=8^)%}#PCXsi`=g$;zWV3>ZUfu>0rq_A z$&XM!_I?zY&#&&0>i=$j2E)(`CYwtkOWd-}ZIVMI@T{7_G`$xu%Z9_+_WhkBaL)GzgPfvG2LuK8a$Grz6( z7Mh>=?GrRV^`|X0KlN9z?;oyrd7|dG^BI`>o2?Y*dUs&=$KF@AmVbPoYXkFru7W+^ zzMg!N`myi71kT()+bC{dPd-`9uP5_U#Qb`)56rJ8yKNQc*OTpb;@8jk$LD+6QU1Ma zEdF%GE7D8glSlHqord}O8RD}?@|$NW&iXYl&qMPp#qB%<=J{_L#qB%!p`! zysckgyT4ziIM=Uvx!BJCE5x>bfw_KVFU21-(qI0cVSgPs>TUMXc=nfGC1!s$F#9X7 zR^0a2Ys7Zn>?^kWCh(mc|60X)-!!e*?%UUi?R_Bdwj=twHx2dWB}07`?E8WG%A1Gx zZ{AP$o9PQoeSKi+Yu=*!jQTooe4eDYim9&!`~63K73^P6QD3va`hDJrzUIK8z6y@( z*S>wIFCR42SHbapE*~tWz7m-Fda(CPea#`#!}aR|Q(tDu%1VWZ9T#6kF6&->TTYm zeyO()%;#e{T5&!f^D*Lg%=lsbA1goDe|n$t*?$LiKiGeJoc!Q=rQ_v?^&i;!56u0T zPmn%aFR=T;{`^^rJadOh3B7^do&l`shasj(*g@ww|XcpMDf@^do&#{nC#v zF#Tvgra1lR1M_{Sd|dVUzS9T(^o(Ej{fjf?SB0DkcE5O@+B4-B{mq}!`yucD9_)T` zKQ?EHxgWd0^gn%C{n>s5yIDR?~ine*uFjp zZ0F@`iu3+xzAol@N&hSU&4_>9H;4Y^Zw>vcVDFdym2VIIYrZq|uM2GV?{^iae=XSk zpnnw{{mb7I)4u}teD04P?ETQc?lQ66H&smk^7qB`uLt}7H~%gd|8>S6d*A$l{IT=; zL*=vo4($E#ytY@#A3LvCOF#QBf!Ti_*w+6V>1F>N*!^Mu=|^Jr--6vAu73r4KV1Lv zW3kUr4V#j|1Cz3T)@;di8I9 zf?Y5DOurP{c>=p$`dPu=kDaF*#OCL()W1EC13zj+fBWm9{vPc6#lGJ8jp|c>^V^~R z^t++{Hn827fvG?LUV5m%fTR9CF!eXR@~OWANB!+BV(QPgs(Szf2qIxS^nC2x=Z=C{$ST*=jm?wYv<`6`AhvJu$`yC zw*G&SUv{3r?ysGvd&PF1z`noiJb}F*>Mws4+j+WA{oDITV0-`go8o-`$bT2x-?s?- zoEg7(p3*;ueig9qNBWf?R6q2q2mAN`=vVpI(62r){c0XkoPKp+*H6FFzvYkZm%#L^ zf<2#p<^SmWZ~M&X;eF7jb*A61=YD8cSZAuo_QSk&rhZdj1-l;G4=b)SeZS)R*TB@1 zAEr3<6tMSa=N}x`zgbC4JssHdsVA+x&h-14nQ^ek-#(*{?~m=nrLTf}u&0`e=*w>H!mUX0u{q}*`Z?mrA?6(8E-|ROnmOid`8<^`|!Jg0c&g)4J z_iqhs=Y4&}ZM`2Mw)GBd=lzk2pE2W)eSdUA`BTwf0lPn3|NI#FLqB`4`(u7)>9_L| zn0_{oRh)iyVAo4O(?;@#ezt+>X9asc{mhS(9{O1W)6aI}b*BIS%!M<0*?-wodhNd2 zOnTXW2R;X%`SUJ2@0&}n?cXh=$M$bv_Fn_r{(Zu*{{r^?&i?zr?7!Jk`F8(>*c3ue%7mCpP%*0j+&qAlb^2nxjrQ@*QW>j{9K>1ll;DW zq@VVg!+v_OpAYs^o;B>JX@>puV80*PPqVX_{dC~iPqT}7-WEuheDHmj{xrJ|`>EjA zPy3uJe(XU|id`!_vbZ2LFxdNX?L{&=DEa6QwW z(qs1p*w>r>wJ(w$_M2X;{<)rQVCxs`dhC99iJ1MRm+HRQa;CqEaPxBY$NgWyN8>Z^ zhie#rh2lHUjAy*;rMR7sy`|6Y8?fuM`{tGFOn-i7`}u#QkNQjCJHdTm>TmW@J?c-d z65D+V_WiQgOush&zUr6r^hXT-!9Tz} z^w-|k-k^H+zV=3OMt%v*`>hB2^MdcU&6{-J^8L08%=g>0MEUmf#K8Rf#5M5#Gk)26 zzEytNeE@d9=x5$v`naAw*nd7tf4c*uhyJFwiETdzw*3rtee^dUD1G#|1g5_|*z@iA z@pkn?f73zghyGTu=hNSOu$cZ9@Lm|k^|7xX0@L5-5XI?l2loAK{=P$Oe_#7hvHky7 zVE2!|&#b&t^OqU_>34I4{HMPa?BnTgd!*{q-+Ywx(%&BJ_aXgl-Xo^JU0}Q4j#fYP zw*|W&_P!RF{^nzpZ_j72`;ifEiu$qr_+I6Id`9mz=qDW~y>@?sT`&E}$E!Z~Uk~>E zMt`~!q>uij_lxOI8<_r7u53uLck3R7E zGy2(Ie~R?m`S_6Zv%mCV&By*K_&|K-er12nsfu4VQ{T?>X{vAM8SMVrdH$%z+j$0i zecNvzQ~dgw`q!Y3{0Y_Pd>z>9+kXC}#&f=Oy8PmN1$-DjQ_r7f>f8JLnTl8DgT21J z&wonw*-sDlxb3I2v>(_{ADI0#pH|%V6WG_!_S0vyKkh_+8`$;}*z;{aeOCV2c>{Yt zwqBi{_jaFwUH^Y(^xOKKqd5C5V6Vr1^B1I_{q|u0dWQX$bES{{^?})6^F_tkUk7$Q z>@S@s{oLQ;ZUy}aJdSLID_ib~&&M)uVbb-e6zHI}q{RG4(AADc5^}JAi za6QvSs!xA9@HzO*{X~D-i!~qp$zPRT^Cz&~pMmLDbBXHFukMh?AQ*ZNa&2M_aN8``w z7xlK^QT{VV^t6`^_4MGVr&Nunp62^QJ?V1wPd#m5>ZyTke_x?`)YF5P;4}NBp7u(` zUpmrn|AS$_?GK0jrmHlb{Z?@Fzg#`+w-3yIn`;zjza2RG-~LF30SD`L_PA*L}eL zOJKWSz@BgS%P;ly3C~Lp_Wfq>8#gHbs2RPsKW>s<_S=J9FZ(SwOE3Fvel5N1w+Fjk z_S^hM%zitte?4XW{&v`31-qV)%=E|e-Tz+wRdCy{lL|g_e{y|#@L>}^cV;}-E8nWP zop*4V2pG&~y4~kzqGoJm|+ZC_i=8qb0{e!*#Ka7lT z-ZyU&UywMyg6HO+`}cU-#{qmP# z{dDiJeg~fGf9~t=_OHYG`99Tu+Dv^r&wo>W_LKjv`aB;M?DdyX&;7&mk(cW{*m(}j z^Uw#j_m_XHlMcY2bARtS(+~Gk`%m>#IUYRl^Fj4ve*R1SaJ_o4pI7Q@9uiYu7nu6e zzja>UFw+m?&41Mo^;fX>b0@e>>rVZl{=CAv)AuLd4;AeFP=B5$=KWOy^Zlp?yFZ7| z^keS>E3G>{PZjkG*!$sr%PXrN`qP8`eUAQ=RWv{S=>yZBX1?Oo-+_K$E^~3)1+M193mB8$;4{ZBm9r^Q(k$%eJVLxfTVLu%>_S3FE>?b{9*iReS z{0eM-JyQMrc%+~9(ZhavaNIv-gJD0-hQoe(u1V+cY1rI{e}B8(O8w-SIQMJ2wc^{&#O*vjN%7~;#O=P_ zM)B8<#hu2y&rj2M zyYIjkPU_R2ZpYzzq^FCy9&KQ*M+F}^8NUplo1L`&pBd?|K6BV#^Q@sh{6KWDUn=SU zHNU;@2DYzfpQkvVZ!LH)jN|^`^Q{Kv^DRGr-Sp;3JcB#1>*3e;c@OE~_x~!`^RJrG z$NgLPl)egXUL<|opXtTY$Nf>kOYxcgng1_Q|K@*S^Z%uaoBv?<>$fBQ^e-Rw)4pQ3 zAM#!rZ~GN|Y3QfhTl2A>^h&Yq*TA-ZVDIO?k$%#vhW!+9JipDWHJ<&X*9`rs;63rj z^o#xEeZ}mj1ZF=y*!$uB>0Yb#TxBc#!Q{i=pVRAS`UA)Np?QPqS$}UF`c=V${@x_E z{sLQn;6Z;&)Ze4W`g_Yvf8c?CZ&f|(Z-1R1?ym|S^ml;R`U`CRfp^0=`n?RFo44sa znV*6AzL^eGKF?#i^$UM?KA-XfDeot99 zT{(%{{sYH;n-7U?{{^=7{jmD8^$l$63-*4`9O*ZoHte?pM}OOo4*Sg?8~WRW2mO9r zZ2bndem^nOZ(!>e?ETvJn?9-e`TR|%Ykqrvf_=UC^TvFJm_KhUV6S)4i2iz(^j|p> zub8fWT5R)kd4w(Dk^V#P6%FKKhYP`({9?W-<*yaNd<^%hD-2ctR@}K*sg1sKsJAYNo^)6ud z-=2S$D83x=7VPucdVzia*?N6V`Ld}uHn11AM>G?oED%ky_ANkvwk9rH({V=`XQ9gg3 z)`DFRf1XwYKXJy7iu(8k4byyEZ?M;A|9yzF|K|IekNtOnZ9OknJzGz(`@{3wgIyob zZ*zt6*?$N2`PqNIQu(|O3)uDXeD;BNnbF7n-~CYaDmY)I@m%i$_I|kDePH_0T&;Yr zcL#Po-2eF+ji+A)?EUdR>cOtZ?xPvR2T-~(p# zalOh7s#n43R~patYQf$Q_1C~$uY9BOxn2dl1fO{x=})>zZ0iN~di19Ud%s-2=4SQ7 z^{Zgd=lbPeE1&CE0>5`eU;8`NtDFz)^V$9Ld)24DE->|_Uio(afTO-XF!i;!sGi+F zV4sir@~!HJ`Z{pbmu^!&^|gUNF`}=zUG*yFuV9~#`tl!DpZZE*>g&OtPkqfDLwz+c z^)-J|-1G(J{%-D6-0s)F%NhT(;@sagu-#90DNes?VEWbEEj`>19oYM)U+EtCk--J* z{__0vV9)3IY5pRxr-Hqnov#(d^rwLR z{fGXfd5YWl0=r(jFTvhF{b^QIKK<#yo=<<$!^FRw@yG6$ljlw9EwJwgRq)*S1$IB? zQ|3+jUtsSqB{2Q!!JcpD>qGMe=%I zJg0Yo{e8^z5#`(S1nl#hKY{O@(aYyaK27y1xC8rm`jI}W`qu#4z}!C-?D@Qp^2ely z&yx;3_w~n|U-{#T)2|Nfdg)jCgz9lWv|!iE{m_FwpZlTtr1CSk3;f>^y=gV=mx}2M zc&`7+-$wxZ{-oY!busmJV9%%Cw8rA;ey837_OG|>zFBke^yis&p1@w8dV8?fv-@-{ z^=J1f*z@T}UZ{NfQ6fKy4b6S{*Eiids#g)p>uNmLw}8Dq_4a|Ow^^)w>g~Ww@Y&xN z@_IwP9r&n8zd=>2D?fJT) z>QiqCOuaqW^X>Win4#VZj_cdx#i?K%{h;0oc0Z{%KUVeZ`2dc3(?-g-{SNl|ska7x z=8Rr`f3APL>apK;6OFg`U9k6K_xq+|+mB$MkNx)GCHPD|_p;t*(z~2-u>U-j_f^?k z^{B50dp$d!Td2QGJz(#L_gQ{|^7(u(fnPSG*S=oaO7$w{&s%G}?Psvp=lb@6Z9hLr z`L>_Iu9tr0ZKRieb>M=}zP|a%s!zWP*!7xza9rQ^DayC~4EB86&)bUk8`0Z5RrM<7 zt6(2*`*{b|r`{6S_A}V?Z9hM4sJDU#`*}yLFZV|ec0Z}NdAjORZwHQg^G?dA-U9ad zskaaOo)NvcaHjPt^?-dm_4Z)zhkBcx#njt@J)e5hEaE}<_;bIXn>~hl zD|nwtoa>ukpnB9>z+TVxGdSvPU#NWB&tT8D{k*66iz9lQm#ALFd=>2DZ9l(M^{KZ6 zw*3tDeA~}28|tm#xW3KH7pId^$IovMc0Z}Nd4=lPeg;Rqc`xPLeg^yewx0ukXGCw> zNA)W8fPK8}XR!A}z0Iq{wx7YCZ~OVxL%jtY^`_S>P9H-Z>Rpb{9oXyJ*DL#~9{X>> zu9x?95BB`b{rpUo34+kOUnedu*yCKE9_;JE{@b@H&i*Ud=VSl*Krz>=fW02qs|PPZUHZr8Yx{QPp8&34&%YR) z57PWg!5!G={eK)^*ae6EMjCz;ia|iZ%d|ygOh%2xKAA--!xAg@3c&=xAq~h$i2YbB@ zM&_^Y(Rj|^9If#cT){q`^W|d}rx)Ne=jVI{?0>(0tC9NUy~FzH*kSzwj`e%+K+pS> z|E!Vv`S``te@~bF=aa;h{E=b(0``C3hy8b-P`>T|vlOR)_3XuIBkUXMeeulvuLGBJ zv_JU1m%gC>*-rtxK70QSToG^1l|I{VV1M4Rzx+kjv;M%o{`UTNp6V}|>5u)i=W9Is z>A^mp{j?V>POryj>Z^={-GBDeep&gPzX!XXcg@Vl{O-cx{zw;zPnyZM{w~&h)*smW ztDOI;3-7`23CG_%1N}&zEXE z`zhepPxcenH+@UvuN$dfzpXg^X}&Y;uY$cl*3aKn{%s@m`tK>udhKPydObMSYpU}9 zK2k4Tt~l!za9qE1h3c*JWF$;J{QhgM9FDKxIKKHmjbA)6zWiWu+7~sse>r~-_UA_h zw?EYQO-IIeSLuC(D>&BAH!n^f4Ckx{tJ-#p0!1ndct;)Z0WksiIQEwwulx&V>e>2lqPVU9rmAP_0rq;_e`z!2 zUolgU{@2YFXMfEWs#h5Yd%YV+#-}ZZ;|tjLAIGOBYW&?JT(H z<98kzpP#zk^!wQyU%~$TwElO{_`OEPcTXFRZ+0Ax@4-I*{v+e_PQ&pPJedC(8qfV# z!KdLf?>Fwh_L<5rBlVj``PA13uHdrsuznAY&-?OhjsN&a{q{MUpY_vjV%G1#t{=yK z`oaBkKI+|jCjKW}e5{aGo5uJbj9-fQldfF>|BW95r-!GXl7Bu|WnNk}T@T)T$`4O> zg7d{*Z&CUO^DlB7Z&dv8;EI1Qtssqhb^!PI{k+{Ie-ARgpU_O^+Xvhng`by9 z_$}bW(J$AJsOif|6Pv9zt86NehIF)U;0V? zJ2?KJRq;DD=jQu6zeCK*W*p#tI)6acNloB$4c+}!5zNe*iPm@lj9$u^*Wb~e_yUl z^n8=~UteYF&;NnT6IY(<{W*BEWt#6+aJ%iw)BSo6rHslRfn({8-enXtsiC=qyullFruLYNvq5sKx?+@;d zkYDct=XZ+V2fnn?_>VFF?TUBc`6p<-zY0Da&u8!VYL0)4`o9^R@cRquWIx>v&gWr& zPx?taLNE58k6#F$|7Pv?&B6YW@gL6tpLo}*)BL@_H=d&Pdo%a}ypMXlV;H~xVN*U8 zT;8z8^u9R@+#a^(^n9KNzT=E_r}-6p-UaICM(}>v4_^OI;O>DnrvBa!E?3-f6+~W65kM#zj_Q8_{Pkx`|98RdM_0q&Nt^TgYL351e%%bN`1+;C+2a1W8{B<% z-Rb(IXX3o|x}VkupLc=I-{#=%sMS)L)ZY&L5Z(v9zZWw9SK7b(f(yPLX(s+04Bi3v zzvmwdzOfO16ujB)8h;LW{&%JCJK){%yz%ir0q3V{{cZvufbYk8{BCf)eEwALKfxzH zP2*R67S{K*%HIfFzdL_=|8E685&wR$*V_#|{}t+YZ{|Os=hYj)4_vK!@8Wno-+cUu z;N9{2_nbTM{Qr~QuY#MusNQ$Mr~g9x=cnNP&er+)J@ao{l)A}!-Un_Uws?9Ut<=Du z-(#^R`*9(--(UCf#^BxY?*)55JAs=k@jfuge-Ze`ZRG!(!S$H6r}ya*Fcflks_N&WlCtI5y*fZN65Rd+!@Pu2U!V(^K0pYeV+1)q1Y z{CF0)nXmVyJ-{XD{bz6R;Xl!O?FWA4d$eBf2B&_d>3SUxzH~>$KLOtC3-a@e;C0r~ z{c#z%-x<&AiQXT9+iyzmugJLn-H+SA=N+W;^LKE5j^gRr(2x0>Nxjv;C%!@RZvbvC zzU;dv;0GQieQyKbv5C&h@!-BuKOg!3%Dy#B zuBuA=5JG5fVz_94fhi?u@Pkn2)?KZl1qKKT$R!Rz!S0X*I*LMqJSVDjx91wDTvWQ1&mHU5Uf#T8ZQHgU^^o+?>cL*v(`FQ{P_BLs=MC3*WP>W zwcdT-=QMEiWi9VI!k^Od@m9ho?;UmVhxECd($7;q{g~q4to3;qc;;rU|L=fXPw!sx zZx(n7<~ySAE=y3~(>49Rz@33TO8&lr@W~o~IPmqyDu0gwUUZfAUuOYN;e2Oq(Dz-y z(QEf8$A|X-59G?Xj{-LrYI&aq9)rGfL;4$mw_l|8yc2lxr#fE$5P0@9jeit)rlov* z68Nz%s6IO$gZf}R>ds+%?g>1A_1D}`UJZEL>(yTk;IUt7`jdg1-`%$y?^gnMFhA^s z{4NBJmhV-r-!2E)4<*1)t@(${KwSa9g4^M<(eVCp8zl0MeY4t;IWr0AO8Y8 z`wr#b9>;?J-_h~;AmG}+Xnrwp^AoDyk-(FeX!?_Y+m~Ygxg*=>?ZDfx-WL081YUBQ z+UG;S(HnIvfU;I`Hh1I{&^Gc=S^P<$Ufz;7RO%i2SdBYtQUjj!#blPv4{Z zMaLojgPMMK;ITcFF9!mT;`zcT*sl(}2>g=#j{tNs0a;MySCPvGZ5;O<*>|DaCse^vgx9(ZzhwfBj@ z+w1DT)xZld9};_B2t0AE*6#z99`k#Np90?UeXY-zfm>JZSk5=T4!i*S3nG6n@F>*96d0noL@c*Jcafr@$=q{{Bd5}g&6U5U*JV2sQ!lo&wNwmj{$yc z7v;xUz)Lazll(RVFL;&ee6+ce$%Xcp8{|DgFHJbjfB!8#wuk893@co@;enR+e-A{TY@MK5zO@YVuQvWOg z-iH2D^gk1L^dcR9#(=j&ABn#hxP|psJMiiKz>B`1{lz~3*RX%q3I6*6aA#EW`zrA4 z>y)qe0yhuU`aejxuJ}>lsR1qjN#Nym)putcw4H$aHKN}^z)P_oAb1eCakIw1nef9p zA9)Ax80M2AzZQ5J|Lz0s+_*>h~AIuU7x;aU%Tp4fWqaz>7{+dmjNjh5bg+w+Spiuf&%#fxAa2 zA2$Fue}n!!`0rBSPF>fd9{`@hewXAo1w1oP?R_hy-%sW51fKk`>ia|BrC7g9`bU9l zL;Suqvd7cF-TO8FIVZs%kE#9l2A;(JkfdJ-+}*rSIX@Tzz5x4062BC9<~r>^&H!#; z{w?w60k`(qiw-A>{@_C3Cf3JN|I2}+=jNC39|a!8`CAvkr0?f}XTPcA?QOu5vpQe6 z8@Pl01L6D6NFMJemGb`!c;YSUpBI4J*pG{X{dapSipKt)$R7;c*+KO?g7B!GU%U=@ z0OOa)p8!0K{a(Rm0XK1;F^T}ve+}@0^~#@1fV(H^`sPaDfe$KwKTGlG-)dnz`wH;P zU0UC70e5hpNbK_i;Mw(>{+A?wq?Y##@Z=S$@7$BoexFx=?+bkOSG2tz4%|Lf&lj4& z%>(rO;xyoyx$56lz|$uy-V7W)ylXk%ybO5aK;_Fdz@tN$--Z6^29l5Vj#~Il_L>In zGC`RQoT_btFp?2oqsJ{`D?`)*R7bAT6NzAb!sFUjAh`hA4( z@mk)efLoZaOa3UnjM=`%14f;O{d=uWED&;)~+{OG|^4sN9 zoTohc(lUO3;3nF8Go*hNa0C6lq#puafb$2zOM%BC#b*F_;BU!)HSp-at3Tcay!0>1 zzsrH2+M;~>IHkvaTysAA`*XmJM^ye+;2QSpqoCiNz|(tc`X2&szf{MMM}fOzIv)N8 zxP|?*X0YF%fv>=LAoZDl8uGhV>-$RJ=DFH`X zZ^Hh#$X^J&70>Gn{wQ#CrH-ec23~~yVTr$u;-6N3+(q$!RsQ}Mc1$G3w$F9BYJ z@ki2M1zf{^yu^PJxOs#6?~A~r=x@3q{Vl*VE%j#yc*{jP{%!*v!+E6S|7+mJ8`Xc$ z5k`BG_+8(I{C=eNIsmx)jXlf#yjKH9JE{Fs;12vR{C^|xEY8~{zte%I4pu&n0gpbe z^M`TZN$dxT{D*;~-8KIy;4$pSN&KzAo&EPM?Q=J9^9DVC`7!W<|D)yqCvf-N`Q`q{ zGr%>p-!4o_{o@Oi{)xTH{iD79E{g7fyp(q^@XRC1hYYxTkLuq9KH*^P4^9DYVE;(c zpAEd=39bJo;Mt{$uK;diKcf@c=heV7&+7Q{d0=edmGQR&kD|O<7;ihkW6vvp9sr)g z{=Jm{1n|Hz&F{Z~r{AFd-R<-U|KADoslca$fXDXL_HhL8=(yVNb--<$_m2jBj{}Zg zt^RmB;qX(#-!;Gkw`lp705@(@`(6b+i~BXA?-zmFn14zBw*W_bYX0A$^jKet{6oOC zf7JU3j{}clJ}vh7GsRz|>*?K><37eA+P@qKT)T39IsZQtxYN-2((5T6`nQ6;mjcgz zOZ|HW@K*3a^f?cB3--?hUkcp0eBZKv`zUaP`yXBWDduCq%}mF?n+d}{olxF42_LHS zm+t~E_@lPpM}Wuf)A`(g0oQQ8CgsmN1NL}K_ZRj8ZvCy6cMxzB>xt3e|HFZ|zFyNG z1Khb+>wgOHmR~8q)&RF2)%eZ8?O$klmjN%DuY9@&IQlWxcY!~j1zw8tKGF9U;12eC zIzgXr0XMOK&rsPZio1XfV*|Zh_AtzvJ71alfP+%6}Pf z^pKYKO2S{%`y(;QV?EOe@=JhgXJfoY0p!1vftSqD{(cO&iTe<>AU_T~`6_L1@27a& zhmicHfTNu;zX-*+J5c=i7)fZOO#C4Lxq>^{Y(05|_x=Ubz|U7Wv)KAV6$I4@`i{jLO# z4pM!t0d7A9eL{V103Ll7^WPvpO&I63qW`}EFUNU>=<{>n<{_Hj4Di@o<;$OeYv^BV zA^)AuMEP$34)&Z+_zoRE4goi{h3aX{~_=y^v@#y zYv2Lw7Ycq3I9jasnR6ESpKE@515b{ty%qv5#r~_L&w;O>ulzU>c;fq-{++;cvECK= z3xNl=>3re?z>OzWehPT>9hjd4dt473o%xc|KDUzmnc5$G8+hz}+Fw2hJc0c#DerOM zN!)J`{3qa6qWeQTz7yqrQs*ao0=LoLTA};{fUkdpo_8DuJaM@C`$*vC;hNv^6o0eE zza4lh&ex^<^MUu-toC{z@N%rLCH^0QN6**!$UgyZ!FjX9Pg6Y3$7;d9_YlVVNbvo@ zov-Wu=C6ReIRB9NCrN%r?<33^LI3(A)o*X$oSq(2WhdI0mWFkiZm(%%Vvf_*Osp1DKw|2WCtf&HQo|0Uql?v825#UyLU0$jgY&yqXrI3W?#|c#@&%HAo#yxQQMBJV%D+Xx(WkNg2<5*HxQ6|J zZm{=Bz@xv}r=0Jtpm@xW+ChFD@FLug5q;hd+wV>}yS3sYSDSuu89DP;KuMP(u zzSaIL22IUfO@#`%ND-vHdg z{dCc9n&dyD`riY*7WX?u{^!7>;9o8HbB5xPUgGINhDEqvAb0_A8~eMW|3bp(zea<9 z>c9=0=ZpMNzzYTxp9daoAb-wE8teoQ;q<6VT$)${cC07rk+@&ALsHMH;69Jb$Q zfIDa(osj+(lD`c7bEwa^fSb6_)7^pPzegDBZ?Vr$fTvKN==&J(*yGw>p9Nlu`#BOn zZzak{eL5k(y@1>E^gh=igmM2w?AZWr;rw07TSD>kHT}uJwg1ui?@HiB*zc9{#(|^n zYx)-OCqAV9o&s(Icjj>YZUi29RL8fwftO=`Dfw*!?qGf>_WMuZ#;F=V3%nHj|02K3 zD(H8xw(q|IZlFJw_`@k4<#mERn!xQY{2B0Rz+3)H>$3{DbvD}Lj;!xRB>&4D%klSp zz*D%-I5+t76Tr18j8{RvO&IqNMnnGp7r1+m^6_7RXBKOD_mli@ly5%=?qGcth4eF& z{-3~?P~IPbM{zz^3-QrvMEriI@_cT0-~rrUnj7Q~1n%6Z@rMFW;Q2v`Ka$e#q~rhb zz|+{zl=!nK{wck`vIe+=^Gb=ogz*1p{FQ|7-KpgFHNa!&k3{|}zzcBSR`9ogXMUmm z$$h|0+^=hf`fUfE`i=7c3E=2WYM*C;8^@`?=baNpE$lCg{q_Q`;r?L<$*4a&2)K#+ zaFYLP2qV474+78JtMxk$cxpz+!{xw}U)K0Fz%8^dsn2D=W1mxfuAz9WuRDPsp9OAU zJ}mOL0e7&UCh>QXJlc0Rw3iBb-D)>{t z%do#I_-nvhu|FvIJCq*h?Sda7jQcr)e+xW?{Z_#{j-fs5t@l0l1a4yfBKA4}c==7L z&tbqVtVc$J{oY9Ow`+fJD)1QApOXJd;MwDqpX0!Dab7I(9|oSpcrN%l;PwgV-vYmG z1>S=DS`zz9}8UjuGaSq;OMe}a{aOzxQY2tH|ReBydCEulKz9hQ-9F@>eIl>F@Kc! z+km&?JXi4Dz|ncw4?_U8w;uyHu)ikpUEoDO)cl?XUWoaR#P4z*^2hvF@czIp+)s=` z`*{^`1N$8kKLk7%^%MM7;3nofBL5EH0i5Sc{953J@W0?IfG1w2?B59w%)9C*s{$b$jG5;3)3~(3oSF!KB^C6G@A&EZ-cBRB(Y4S-;V2{|5sIhPvFV#ss1(K zE&s0RW8ke5ijM}K#{CS*|1{tx{3rE28@RS@PC1`i4?K$dQ=;Exz*8t+(qBXP54s-s z3h)5tuM+`wLHe*?F$U)m1o=WRg#xW6R% zA4C}QLBU4=cNeNZjstG5)cj8az7^|XkzWN|+ePzxH}C-V3nl&|z>~P&CHMy5rI%~` zKLd}QrsaPRc>5f+$9CXp+%K2(PY}lbvfv#qi17Tj&KLFoj?UEkH~Rs%J9^*d5a6X) z|4I5m;H^0C5qun_pPpCFuTBFVziBsR zaQkY#-!%=~!Si{|;GcVdXWy^({V8x0`}ds?{~r|ptj_QLKh-Jc0S3#6L{&xL+Xn8Q=`}3k2`B z5&7YHPQiZzJcaQ@a0Xn%c|sd*q5k+d;7RyH;+F%@p055}1KhxUVTr#4c4iGBVAJPrR!`2(9Gyx&px zFZKbR8CL%s0$juMWZlp|Gzg=A?*zOAcrNb8N`7Yo-*dd$XB;>>MDuR}kK%q-6!>=y z@a%tRfA~e{Iv&g^Wpg=-VeBq^^U|J0zA7_^&14D*gxH1vqb${J#p^!u{Mm*Tuw^7|uj3+rFecgM}(Bc6AW_yd5KJ*)mpfv0f(An|VjZsUHsq<=f` z#GcC6jUd&RXH+2-B3EX*`?pJOA zUWEH{l3xqBjr+Ee-^WQF>6<~{F95eNzm0 zdf#Ujcni)GrTkqkLVaZT?srprS1Q-z>mFE{rS(p(SPcB;P-*MxIfYk`u-GnVjtz# z<0Stm_7{VH{s27M()q$)foB$Kf4S!b;_p}a1Ar$mzZ3hUz%$=eJ}v=npQz=Z3>@94 z`JV~g!2MH6zYcixPkJBbV#463*zf(oO`OM20?WyDI2Y@@+Pwa&J zK2GtNKMMXFVLUJ14F10nc=CGX^PRxaqbk1@cmn6`qR;=M^w;V6(652JxKAW}ngyQ5 z^Yp<<$VTt!DfxW8F(S?%ZU7Ufv3>_3;r2!3*(2_>zBY2IIolVXMk`2d)0rp zOVJZng8oqO8j{C;tKdt3r*Yp@@KwM~ z>|cm}p9Eft`{5G5g)q(&1%H#|@qD1j-v_)M_m3t1G2l@=57P>K_!ICJ+;^4ufpxB9|0^G!Tndtj0a0kzC2%h&IkiINt7P7z>~P|EBHa+8s_Js|F41DcwYqxP=Eb2;Vaai(aMeE zo5nYvbI#(G(W=!OSD(9P)A;I*Bjf8vR<7N!e)XnkWMtKbk#pB>ID5s~kyYaxHf|bO zv3Vj|xnbP}Ygdo2UbVR1Ut;8(HS5=mtk}45#l<75*N<Hkv1>V=0)1PNShaF^CE3tq|J-8d670R(&k0l!6NNok#?|1J6NP0 zEYc1ZX$On6gGE}r5C)nI7HNlyv_nPOp(5>2k#?v^J5;0{D$))WX@`omLq*y~k+xB! zZ4_x6McPJ@wo#wNf$HgVy0cpyo;H5amu+c^lbjG2uw(=lc~#!SeV z85uJrW9DScq>P!BG1D?;UdBw!n3)+fHDl&x%;b!joiWohW`4#@(3lw-Geu+OXv`#y znWZt)G-jU0Ow^c}8Z%X6=4#AjjhU@6(=}$k#!T3l85=WYW9Dqkq>Y)iG1E3?-o{Ma zn3)?hbz|mk!rV=my9skQVeTf(-GsTDFn1H?Zo=G6n7avcH;D`GCd}Q0xtlO|6XtHh z+)bFf33E3IeQ)S|rS~mbK*HQjLT4Fz%g|kh{xWo!%-w{!n=p41=5E5=O_;k0b2nk` zCd}Q0xtlO|6XtHh+)bFf33E4L?k3FLgt?nAcN6Ar!rV=my9skQVeTf(-GsTDFn1H? zZo=G6n7avcH(~B3%-w{!n=p41=5E5=O_;k0b2nk`Cd}Q0xtlO|6XtHh+)bFf33E4L z?k3FLgt?nAcN6Ar!rV=my9skQVeTf(-GsTDFn1H?Zo=G6n7avcH(~B3%-w{!n=p41 z=5E5=O_;k0b2nw~rp(=xxtlU~Q|4~U+)bIgDRVbv?xxJ$l)0NScT?tW%G^zvyD4)w zW$vcT-ITeTGIvwvZpz$Ex!+BhyD4)wW$vcT-ITeTGI!H3+K1sjjQ29&7yWJ;hWs$* zhe1D#`eE2-?xxJ$l)0NScT?tW%G^zvyD4)wW$vcT-ITeTGIvwvZpz$EnY$@-H)Zao z%-xi^n=*G(=5ET|O_{qXb2nw~rp(=xxtlU~Q|4~U+)bIgDRVbv?xxJ$l)0NScT?tW z%G^zvyD4)wW$vcT-ITeTGIvwvZpz$EnY$@-H)Zao%-xi^n=*G(=5ET|O_{qXb2nw~ zrp(=xxtlU~Q|4~Q+|8J~8FM#d?qIFw zaor(W2bGdBErArdWk~FnA+cMA#BLc9yJbjB%Mi`e>5@2I5~oYzbV-~piPI%U2q+E~(Qcb-JWZm(=N!I$ctyOX_q5@BLa;HnKx+Gz}%`70K=?G~$LOz|=f#S3dgtQKXv<`%{4nT(U zgtQKXoG!7`#c-Y^oi2v+6z6m?oToUai{U)t4Ce_sT@2?b&e_Fqp5mNc4Cg7%*~M@k zafb7RoLvm(DbCr&aGv6vT@2?b&e_Fqp5mNc4CfJNI8Vsg#c-bDoLvm(DbCr&aGv6v zT@2?DXE;yD*~M_4;+$PP=W}P5-06}#yW~!n+}UMN+aJmsbh->Wy9_#A2Ay37oi2k; zmqDk?pwng0=`!SW8FIP|IbDXFE<;Y2A*aib(`Cr%GURj_a=J8}E)Azk!|Bp+x-^_F z4W~=P>C$kzG@LFCr^~R@W!UL5>~tA+x(qvAhMg|MPM2Y)%dpdB*y@5^qH?@VMzC4r zkktiSM=s9lf{i2>XLZ50l8dvtV3Wzlxqdfx{ch~~-PrZJvFmqZ*YC!z-;G_r8@qlt zcKt4PtgL3P-^Kowi*t5y{Vq1OoTRgh>vyr!wLGG0k#ypqazC6)0?D&v(@#w)3eS5g_Tq%vMfWxSHgcqNtbN-E=(RK_c*j8{?_ zucR_wNoBl}%6KJ}@k%P^l~m3vshn3*Ij^L0UPE2*4UQaP`r za$ZU0ypqa!C6)6^D(96{&MT>$S5i5zq;g(K<-C&0c_o$eN-F1-RL(1@oL5pgucUHb zN#(qf%6TP~^GYh`l~m3vshn3*Ij^L0UPE2*4UQaP`ra^3~V zc_o$eN-F1-RL(1@oL5pgucUHbN#(qf%6TP~^GYh`l~m3vshn3*Ij^L0UPE2*4UQaP`ra$ZU0ypqa!C6)6^D(96{&bt6Pb2n%1=FHukxtlY0bLMW& z+|8N0IdeB>?&i$hoVlAbcXQ@$&fLwJyE&6KXVT_O+MG$7Gih@sZO)|4nY1~RHfPcf zGHC~yw1Z6AK_=}WlXj3vJIJIRWYP{YX$P6KgG|~%rs*KlbdYH}2rA079vkYeOK{zc zn^Iwy-AcMC753a+oa<)XlnNX1PSSOGZc2sSc`NCrRM@L`ajwgAQz~rWJ4x5&xhWNP z^_`@%iDsH5;vv7>59$MO{o$$rApjVHgQv`#7(IZx0J4_6H>ne8NU;9x|pdn#W`J!-zm=NV*E~VP8Tzk zrZ}gI@jK#--w8Rp7{61Tvy1UN#W}kezf+vEi}5?+jNb`4yBNPyoU@DZJHn5i_y zIlGvtG{rf)n5i`4%v73?vx}KZQ=GGl*}}-c0!>Fq>p)1;5u!R^nw<=d6z8MqF#pXm z{N*v4q}0xYv~Gmd&V;mXK!$&W)Xs#Qj)s2}=X5muqd3(iM|qkHA+0GP&4rM9i;&Mn zYeaEcBSKmuAX6hku5?oeigTr#I#8S|&$JrEnRY@*ZAQqIXIciumGxUSw(^1t2T=-? zFO%EAG8Y?In$8B6b+Cbb3o7ktCCh5sz|y)lur#s>R9oA?el=1*Sjm1hQmxS8oi?x^L$oKglKmK>{i>Dh$9dhbu#)|Jq-z{2+0RG1;xUrC@UemY ze5A`DE7{LSx+t=e{d}am&Q`LYk95IgBz4_n1N-?%H>Ry*KOgCu%1ZY0k*=_;WIrG2 z7Pgh_=ObNx8A)A)*}#52(p_#V+0RG1K(mtle5A`YE7{LSx*u*Nbq!|&`}s&$bXKyT zk95o2O7`=SuJ){CKOgDZ&r0_5k*)-dq%H_;U_T$}^3Y25^O5eqTgiSt(xs!7?B^q0 zNQxxpJv!5|fjyQd$sRo^u*dQg*rO)}_E??*d-SBh9?K)Jchsi99wSp=KjnJ|Xp-!w zyiNp-L3Czi1N$kjs}m#HJLseI-a(%N`_-s-)F#Oudk(>LJ;^Ds#~>8g<4p?eF$e|r zc#{JAmfm9!lI-y&0(-qlfjvC~1@@~^uZu~tUyXWQOp^U-)azoB>{p{+7elhw#T3}D zM!ha3$$mc4nYeI?B>VZOmmwrs`e@Asn^v!cD@t`Fpfs)olxj#oX;cX)iNI*4TrH4pVYoW9diINf$P_2McK_se*sbhnL zI#mLydZ;r+qN2yjhJr%;ekBh*n$2hP; zMh@&(sj53!vR_TBZe_`SHPzP6hG)rsHPzN`B&)72l2_f$f&KKXx}7CS&ykU1Pd)0y zV@8fSY01b4&;({N=dKKC^PaU-iXZ5SC_v3}Ls)zQe3 zGfq0{#N*$D&}ApSN%B1Igts1j)CnVRJ@(ksj#)Oc?5LwpI0hxr<4NZ9M4kYmWBWl9 zF1t6_8Hk5QHm$*%*NW|&Kwl$U$H5Zs^c1^FMz)T-BRGSSqndi2*hu7zgCB{+?!Jx0 z-UALAi%97b5rjjzYEV`;$wZX;#89pTQR=vlD8g|rTFn(FgGG?kHk2z+>Qq$0WLk#> z;$ahDO2?s^D}{8_W2`#P<6Jc9WzA(ciPPCa6y~MpNc4NI-*J|v;X&RggR{;@}XjE z6-@DQZq%Z*I5#dcc1%{QVgJ`Af@5*?TrJS~n)b_Z0L~fHcX18U)@>6iG>}LL3ag6@ z)VFn%^)@b&{eX?F>=S#907k)}8A}TkE<)Lvacsvr6fh&Ii@VE}|xV z7bTD=bq$&#B}Zu6hi%+5JH0^g*anDCk-Ky{CaAO*RmT=?WCnvHMvh;0;)p&Wie8hR z4_&t6Z1ko=4IJQF8>0r<1nEYbKmvi87O> zMc-|Eag3u#>7`**v4Z0>iZdDDjsx@JaZumEUuwJ5G}Qm5|@IEjuo#UXWXJ$=#HO*) zhLbwDh~*ps@4B?4$)K$`1>i1_)1*puH>?<{4_YrGBit|Wb*#(us5o`1MB?FIBWuY8Ira#ERb!r(}Z(O zg{js10CJx+Q~ECLh3YKzr|?Q!qe@kRh#CEiOS;LpPPwXX^&ZS_PW$jkhaI3sC| zy{c`a)LLYyc z!L1#-6&=FNFS^J-(IC&Ej&#dbbaG;Q1e zP~X@yarR3QIIZ7E>-r|j#xxq-hBh{ns#VQp32C_{@@SOR?t{E2Mx}K}@0c=Zdke{l zY*gupD5u`;8rND2!e7dTtA4bi$S}Z~w7DgP zgj4ge^)(ii{6!S?b<+xJ>D8$#q`jC?Vi`;-mW%{m>>?b^3ecy;QAS2nd=NBB~{dx zB;jOX=}XBwVi*i!cw~dUL*GraFTFYWq$a8u2)a)?4g>`t{xPB?t5&5M~5W zTBmoWJQpqmb2@`mjx9)0aXYkh)s*b1sar1>h6~jZ8E8Cg`E0_ahb@w6&2jtLTMflH zGC>~i^D)(>0N*i?2P?kEt}7=Q8Cf~8f{qhMXvZ(qoN(QBus@Q7iumto)k^T$RNjhYAs6>TQ?j@E^tBF z&`8EIrJ%F(A*B75FY!a$EWLh+YeC_`Jf?!Q(xp$xXw=11A+r`pr11n%Et=_(7WjDhx#x+<-zwm;D*OyF;PS z2&LVN`pCoW15+N=WdPnhRngn6%_J)_eLqVhTzX0)T6Uy}c3Y6d4M*<6>S7n_x-4-_ zjxy+)AUn%5d*t-yFL4mYP5v$h(&qBwo6;eQS+&`q-s%inj~mf)SR~$5*(|feVtlb3 z3%S%UE)d}9O?43;Qx{`eP-blaGE`EMO-+??O zqN!EAC<{YK;|U#aOuYWh1eh}2I>v-IY_D&^otI2_b(&l5WI!8?WTtScOu0a&@0LB% zLJ;mIiovU>x8n%TdTjvp!?xnW1sg`iH=Lo#<1$v0H_ccrs|C|ad(IA!q0@=pHdnM` zu@1cNm$g(#sHl~(vn&Y*EAUt;cMC+C-d@8uW~z(G)A!IPn(WG|7NS+vD~_VK>T%&D zU8!hg+=rj>go`r;-a_C5=)HVpA2)2BDH_t`EmX4Dd6T9^n>RLhk%wMxu1R$3;i6lF zn3OUfDY`jVJL+MyXnI+rb1Au{ftw}guG_GFWYhSHjpMkmQdZ2Ad)|fr7U`jk=00{nD_*(r)qDIq~c|lyS2CLqr=4? zwOhH=D@d#&%MPjE-y1u4S)eGKBLajT5Dp`VbsvuKRuZU$NyA{bF*sBzmNw~z_d zr0;ktpLv1I`~Xz+Lt4q|c`x>_%1BJl_`8&f%*^rvgJBSbXWfo16T2s^8FuS<+PzRv zY|z_zm2)wwPNmMCL=0xv{xZJ3mmmRFd|M(4_%TJ>z4_OWLtf-svPs z0|x}!PLi^5+sRbPs!^yJqi#C((GH-G*n%;R)ZiO&^F2it2u>9s9x!f@P4h}anjB;O%rbC9)(U- zpGp&?$Z9`^3k*gvF$QYzVt0ew_)t{abjm$DUgZH8*{63xQ`V27D;))Nz`H$!@OW*p z(Gw#^?~cQelPLVj$xW@QlbVXpDUp;(-%UT}1|yqekYS(lV$kszM)zic?$v&m-sxQJ zcw{bUGOiK^3nya~Q3{I7@Na{9`&b!1zzcdKwo`yIsZ0&%9okNYJQQj#1rc#7ex#g2 zkf{nBQBKm}{A$hUWz{`pX#>E^rcA|)rlWl$PLfQdDN`(3)K@xPXxuXg62IHDz2DsD_QU-Bh7U$lA)->KWU*6)L4I=lJA8=`1MRwrU7sC1Pw+1XLUjI|vCW zx?E~d+FrlQkYjaI_vi*cay2>8%jOGna0y-`yo$UMP_1pboRU&8Jog!Y#pWo4-gRFV zD7%?9wQ*H-n4q`jS1H(cN<^IRHD-0!7n4_0J*z`-KdI~2nlQaP47Q2X*JyBkGKNwz zMUZ6VVKoQdsNO%BOcH1qlUZ2N&sTU`n%?l%&}UZGMtcgfpyzLDu8f5%cex? z-BT;KLX(sz&b3q0%h5mtQH1Z)Am}y@MG)bBGE7DkBGPx`aHq6n zKqZB?EuUeBPi8nevoq!g8 zbv*{u=rNpMVjw@{sZ=O>EZb37B}~E6bWA5^*UWy_2^v8+EyU#M_l=0Pt^zdY3sXGO z%sHKG;bw>?Ti3T2b#j%Y4oi8B7moH7TOa_72`9 z$exBD-NBcwskN8!hD-!aP<8T$e;;EMp?2#Y2tWW{f9fUh-c}!g<%bCny)bumDJ7hm zMP=qoEzV8$w4W#EYqw7S%%`x1WJW1hH+za~C7f=Z515ART!i%Fxj17I33|Jpo~e1+Sr^@w z$K?QM4|TyY&Xu+RcB805KKOOv)!g z>o2i2WTbZrEJYSN!iTV`-|*kTj8IXi)CGj`Yi+8FSO?!-FKV^0)G*{DTZo~+> z9>j#p42K$%TZ7Vqz#EU$t5ghc_%t;&6zCa=+@6+{PwgzUdK)ARp%!4xU06~aUy#5Q zj!62yXfmqcin@uE+{vFtrq9I-cZbs?a}$7~tl(1N1zo%=OUFyTP3a_V?x$m}ZX%@& zvW1y>+J`!P%Y|Ruu57V#lfIMMii{id-KgXiC&pE7#5CcucY^pz`y)$BE263yatoJD zt^B1DN-KOP1x=O9M_V{={}!Mib8ru-JRIs5|q>B&znzkSe=*N+B+Xb=^|jW)Y|$K^UT3mnW5f5w*>P z4fh}W@E2;xXj5jT?E#PS6b~WGKdJ3~1ld_TBqXX=r{?7oQK)Of_C7@`)5cBzL$c@$ zq{2|p^;RS=&+LfCA-PFXj(3oj;mSn!nfxu$^Pq;!DfJ)@2Q5vIpBr5S61xUDk0h4WY_KE*bVpA4_PH7qJ@R~@IOJAbFO8$B* zWhTz03fTS&O5^dL{<*sjl4@7wFaC{+Nm;m4je|!AY$TL$8-`K~>WC|DCQ)k*5v6)) z{BnoLv3y(Ty5in6lU)ZTR%heM`%g zZx<*AFAle!ux>EfRj*h3E3DL39eJq7b`3_dDk>ecAq`}%1^Ma)hRVq%Bzzx<05|KE zA`tF2c|j)n=h$okQnWg7^$fe!=@c%18|D~ml^bJJ6>IQ%6fNF#@w)L9XXEeqM*ce{ z-_~y!U%mL;^_v%;y?M>rRfn%x6%}Y~#ip@n@v4j0BPIVG-^ei+uHLw5&4%?3j392~ z>a`>vEiT?8wRn8>#CWtA4~(oq)P_|n##cm(SC5UHvvI|`)hsizV&ldY7qg6fM+Pg_ ztyzi8Hy|~BExuqazHsuhH*Ja*uiUV1-Rkw@(f`NK0g&AppE>wsJMd?rNk2DyUyQ%c zz3{>Yl3NZr`rLU)6zv$|Nsc}Ze0IZ!FM(}eEur>b)X+UHH48)QZBwmtMJ(cA4)UP;m_4C zXnrJ*>?5dDq??Do(f!B)pM~^2{E!^|Y{G}~C%HOg=<__j%MaC+elEtRlzRYj_$(-5 z_?P7O_d$;Ii@HdG&y#ns4E?T!uOGl)%8%rp`t+RQBYBXBeE%4}zXTt$^`cwmM2kK* zr;I~T@ttI^!)H%?NbWGm9rhw}Uq(FDmE`J>t3$4X?@}K9CHvim59vp8PeJY}$cZfw zRF(^OmU7Xps7-rLv^xoeAIgtD9egCe8sut_>wIz_gz`@<{Jj@{seCH8d)&*T?$FCi z-AIJ;pr3!khrXi&D1Jz8ukfAzP@H@UUxc_nLhhw+o)f(cc(}&8QN4&$RHppQy?npu X`S%Laa_1w+%I&bj{?RrSEA{(d_X9^i literal 0 HcmV?d00001 diff --git a/test/regression/tahi_test/tahi64.a b/test/regression/tahi_test/tahi64.a new file mode 100644 index 0000000000000000000000000000000000000000..5cf04352d66323414977829096e9ba6d43b851c1 GIT binary patch literal 2656014 zcmeF43!EH9@%TFrj!VKL;Ss_sY!V0uLb#dTdqsY6jSvGWtMBWfH` zV?=)#QA0$;6A=OkMpTT5xFTXi2@wS&06R~TTvDr zYYfOIUPQTao-rWT-G#E|P-8&8zY^u1+l;X?{I$oS%)ZGC2RZR+l+!OW!$HoyK9mv9 z4>zG~U1~;H89C-}G?YJGVn%|zV2^|R z+a9yB!=B4f4x49o06F@4ly^R2b^y8PIF$dp+w1^x!$g!HUSW0s`OV`f|MATZR+{#> z7v-?grU~Q?ccGlT$TWd09FOwBV@(st@{3U}Kh!jVe10iP_ob!@5N03jgMER_5b_Dst zdX#RP7vzQ}lv}PfJA!^%`>l5a+V95M^Vn`cIW zbe)g#`b*6ykYiS&{O?U>6v!zjp`0_^i~?DFIm*&~%qWm$PosS9SThRbE4QM2V>dGj zrj;YtbUM(Y*~;eZCQ}#Y4G|P+y`OFn4*DNz*L2kYTW$pQ9EXch! zKgdJ&7|0)IqHMn1j0M?xTPWj3o@qjv@Pru$a`?q4Gv=FdAje;hQn;`i9eJDpYncYC< zO-5O`)a(Yb>?)M2Z#TPv-1Z>Ky64PpAip1t^3SPeH!Hi3nTay#6tg=>$0aClS!s3$ zIsG=24=**lgIswP$}JC@-9di*0?NkA&F&z7z7*x($C=%&?6LDalmo9fdw{ebiZc6h zvj@n@KFWpT%^o11n2+-1^=1!{Z(o7(vz2BKkS8BO*mSBP$n-mdxCV_gmS`o zvnR-VEtpi184q%= ztqWwseJGDSXU2p4aW|B|*}6bpek7E=Ms78s>^j-(1+w=nlqqMMy+97X9Hrwnvlqzg zA4Yle9cC|(w_k&D+TCU^kaM0!x#$YB7s!WZpe%pJ>;>}q$5F0-(Ch{B-6oVDzF_tO zS!a)f{PI4OM{YNJfjoIF%CojTApg7sW$T${FDnz8cSG6tb~6Fw(3vQ&-Nj4*d6V4- znKuz-(IsXA$fs6@viJ0}O(~qi)D92xH_5u0yr6>8WadpM^UgQ>gIxRq$`@}p`-7~Vj`HYMvp>j7mxeNN&&N$D)2}rX zLEb(U-NB69#p%e^Q^%rpmpbUchQ`x$cp$UA1Bob$3d z0OSL^pe*0V902l_Q&4Vr#2f(fjdqmVuP_II+;bPo{U?|MKpwXBf&6|R%Ac)1kS+Ix zlG*t=6UqU@O$Njpk8<>(CIe#I6UzAynheN?rlPF4!(>2id=aHM-(*03WsigWX>=%) zhOIZD?0u-21aim>lV<%B=ZjGRT}4QBFSAOa?iB2FizDFq1(( zGZp39yUk>fZ$5|eiB`SlDl1?15eQ2uh9nF3<_6Uc#MW}!^D${YxC&~qrc`Q|{7nGd79 z^-yyl$mvT_F1XJe2=amPD3{qZ$QQ0bvGbV&LB4f6%AF6I13}hbkMi5I&4D1#SbZS> znHS1IJ6~)<+3#g@5Xj-ru{}XAS~cG7aUj$>t!CFP@3=^=r*RAa^yP zJaD!-2&81ogS=qNTA4cHE|fiInyDaD??vexZKi@8b2-Y%yP2sVXRkyFhMTD%mtBmq z(xySW+fi;h)=UN2VDp1K_6*9V$IVob&1a*$Ji|=2ae@g|hxA2$bs%-s#8u*@6`vcQ%Hx$tt74^1`)gM8fT2DxG% zlrP(o~7 z)Yewdi1eu!o^{C?0{Akm4`#)|tUj0%2Xp#hn>g5}54MYg?fPJcIM|^Nc8Y_Y`e2th z*rg77tvv_5R(()d$n*3;VIj}g2Ze<^Z6Qxs$kP_`goQk9Ax~Jy(-!iCg*WwnK}!a`YXp{%e_R$C}5ER@w2$_fi*wS}_6 zLRoF0tguj4TPQ0ml+_l>2@B=4g>u3|Ic=ewuux80C?_nG(-z7J3+1$ha>7D6ZK0g7 zP)=JYCoGiH7Rm_=<+O!z!a_N1p*CTmHf^CcVWBo{p*CTmHf^CcVWBo{p*CTmHpfD~ zxH^PsIlKYjI>WR+$aTU&r%nJ|XPDL{*(-3+@d^O;N|@Fq*(-3+@d^O;N|@Fq*(-3+ z@rniIt3#MpB|Y{E9CW+_Kv>AVI>13;A@}M42Ze>)s{JX-th00e4IH)aDzB<4`CvE`<3%OSZI4CUSULD||u#kIo zfP=z9?$rSf3JbYc2RJA!13~q4L!M4r&XPuMTifTc~_>fP;D*DqkJopmTKqAS~ow z9qhsK)geqP3ze@9a8O&Qe06|>+Ct^4102*ADqkJoptew(=w)r%LT#d#wP_2ri5P0r z7HShQ)TS-eCM?vZN9uOIe%jWyJJ(MDVx(@@7HStGb-T7uyBLSswT0TnIMl8!)GjR4 zt}WCqEYz+o)GjR4t}WCqEYz+o)GjR4t}WCdEYzVb)FCX?p)J%QEYzVb)FCX?p)J%Q zEYzVb)FCX?p)J%QEYzVb)FCX?p)J%QEYzVb)FCX?p)J%YEYztj)F~{~sV&qgEYztj z)F~{~sV&qgEYztj)F~{~sV&qgEYztj)F~{~sV&qgEYztj)F~{~sV&qcEYzhf)Fmv` zr7hGYEYzhf)Fmv`r7hGYEYzhf)Fmv`r7hGYEYzhf)Fmv`r7hGYEYzhf)Fmv`r7YyN z_E^ZK-I3ZWKXLI-wP}5@$3kAKvXIx>Vb84H`C546b zoZ1s}YMa(2g@yE-+7okXo7N?Th4h@-6LV^t)+L37^qkrgb84GbCB>ZDbDy|a3yC?k zP3w}vLV8Z^i8-}R>ypAkdQR<$IkipelEOlIPVI>~wN2}i!a{mZ?TIu#lcpdty#))4HUvke*X}Voq(-x}>m>o>O~bPHoe=q_B{l zQ+r}gZPTixm{WUtPVI>~wN2}i!a{mZ?TIypAkdQR<$Ikipe zlEOlIPVI>~wN1MveKDuDX??KguEW=JYF|93wrO3mXHMykWb!a=9C z0JybbT9@Qe6AngN%l?Fe&Zr51N6j#;)v`a~pfhS(P#zP)v?^I16X2k8T>&60)F#!$=3%O$g926FE#{_$@JSK!`Wufwz z00*^&%3}f?)G<`P&xV7}l^1}pkUJ*8L17_xOn`&JLhhIV2Ze>)F#!$=3%O$g926FE z#{_$@JSK!`Wufwz00*^&%3}f?)D|k=XTw2lq4Jmj2X!wi-)F-?XKn&OSST_kl<%`4 zqwZzpcUN%G88rb23%U2%_F(xwJ4`DJmG86Rptex?-4z_v7AoIo!$EDK^1CZIs4Y~! z&xV7Jg>rU~;GP|(WorR&&koc2Ajd5nbm|1aaT}&}N%jgHbjCga9JgUwm*lvGgN|1K zuvfygDp?-;>_K-v1c0v&VOp0I7IMcv$So}7j(u=YSjZjw;GnROJNCgrVIgk1qcr{Z2Z;Gj4a=hE@+1*b2(xZSqc+Mfd7L85t*Q$rk-kd@3Yv&s=maykPC zC1|Ddky+(vCOJi`gA%loPi0nlEs&f%?4Sg#6xTAVoQ(<2QSP94tvpQ0tTJ9Ck9y1L zB{FN&TTY*mS)<-^dXUT-wSY6*5?Q%(I4Ir%+*M@O1PgG-ky+(6Rr06>oLQR88nuAa z@nqI$ye4%+p2*44a*&lg8n4dmPG*h9t25V=S)<-^W_}_oPXHYh?=7AV%B%_A;>n@R zn&2&-D$1-0qYFn_q^Btj;?z$)ocu=M9<68ohEm z@5^M?=yl6^dnU6+uUpQ$G?_Iz5;||zWY*|N=)7l>S)(JN^VUsfjgExQJ2;s&+P9oH zaw03gm~&8k-{RMFGHXKL;vd4vtOE&c(W%$m@* z_|>1xn$WlS$8|DmLf_)of--AD-{O~qBCGSRQ1WQsa^4)utkJ&ZyhoH-qkYSHt0=QZ z`BsRX<9AtZ@SoaCO-TQG(W}v79$E z;mD1Tc&+-`8)S_O7vNEE#Xft3tWj^pc5cWT^;T@>hOAL<#ddDU z8ueCe=Z36NZ^d?Q$Qt!lZ0CloQE$a|Zktti?hwU$OLuO_n&2(nxgl%ZECYDdTd~gx zA#2oIvCj!1Yt&n@&j}%G)LXHm3uKLY%XvkMbS z;4H3};`CI`;@ZXOp_t{OcQ4dk zk5Hu9$Q`c}O33QC7PCfA1G#f5gc7tmr-WJMG+dsR<8sUz?Ssf2*Aq%;fbM3PJGQIQ zA=$w>x9)Nwce@>-_-61dK%B2L3y?hOvzXqBwK+YOP(lNu?v3fas3Pj#m|l!oqwbCA z&6qXn-k4sES)=Za>D`#s>EVRpE#UU_FspOD7A|mmJZ6pddgM{NI@fEdHEP$GQ2@0@ z?aHIU5&Dm4i@%{Am&|!t{1e)l!szgCH1Tai_!fWK1xG}wA4{{bG#5+TVrhFU?TDqF zv9v3Wdabe4i>0yW=Ea_y7kh4AY#aR8Hu$k^@MGKH$F{+bZG#_cUq9Bqeyn}{So`|1 z=a!8vFFwvdv5Kq=hhy3Ztbz>)*gFq?Xl<99(!&bvFFwidu|=E=hhK>ZXL1b z))9Md9kJ)u5qoYOvFFwidv2Yv=hhi}Zk@5`)){+low4WE8GCM>vFFwqdv2Yv=hhi} zZe6kG))jkhU9soZ6?<-7vFFwmdv0B^=hhW_Ze6kG))hTB``EHI+Fqd1_5zKz7ihG- zK%?yi8f`DoXnTRiwl`)@VDoyhXAyJthrF?8;l-YX7kd_7>{)oRXAv{2ux*H$RRE1f z6wugni$jNsB;<|tn}{8}x3P}` z%QI~zJuPC=V`(NmEn(7QVJ1B-VA5k*Ch$xy(tw^Y;%sooAIa8Zd&(waib|trK>%M4;JiSUhwhBLt*rXj(+p3;lqX*-iDbOre}|- zG2J72()lo%H)Bk*vA@wZX1EzQIeXMe%N{Ghk+IXaZ4Dq{4~(0{9CdbdTbi7sJv$?NlI7G6Ov{P$FFJqmMVYo~xoNG3w_g#;$*Fw}1Su zD^90mV9$}}`E8PMdPJ<}jTvDb9Jh_In)J4-1;a#surF^TVl55&cjPS2_Xrd90@!<; z)nA~To9R1azk$!8fGM|3{F(D;a^vzk^0Zp$P{6pI ztmBK6v7G^Zb9w%rX*s85)?dcKn7rdG)8`I)W)nOCcEqOD!oEIt$i9&>Hq-ZL%fJWP z{=nkuFOgEPuiSL~J>3tk*}Y$z+FM)c@>Tt{X^j|!^I>D~+SGGx8D^F}79Nq;CS$g3 zwZ75Us=$mIxow-hGz}jya)+iJ*&y;HIbFVXf&K!}e$}7N+Gf~cOZ*# z{jc9@960;T>Hqde<45{8A%0TyuK~5s!v43ZEfL7PP!kdk1u3uq&VJ$J&ujKK$@A{>E z67+xE-1sb=EAzo7aaN>CiOwMo38@8ug@ebnrAb|59NxVP-#C#_4qT;iOXXt{)`Hv$WDE>C$ zCB^3v&r<-go&xc1#m^+p5Arzwxx@=iHeolm=OUX1zZ8jc{w2gSbU|Uhlz2d#^?a0g zN%6~w=jqu3=eO9JIKEe;c}BXz>VapW-K4*TR9;Pd-Of-GK9>s<@*xd9Bef4oeRx`$ zg^wJ3w82L^e00D^Cwz3lhy7J8e0t$$SjaAR0TLFoOH?2o7PJdXARQL9%Ry|~uJnM< zu&n*PC#2~ovf(pX`eiMq%g<+5(|JKy?-!l`eryq(LN7cp8y;fW4e|poSb=S!;>C~} zvr6#{^`D~R0r5?Wmx$Z{hZ=5NFZZ{C;@sbsD;_r1YS^fFflqFXtG`IRMRD$LOBCmR z)vY-9!*z;tf19wATQB#kyyDys7bwpCZH408-_|P5{jH=p_qS$>XSOr zL-JYuFUTI~J!3MQpzlfc8;06E?eo`!-7v-R3*ioz2)eXZ!XW@c->N&?CvpDwm<1v{al(5ouE{6y^LWW?5ejpR6oBn zf#Cq|-L(C|FFZ6z9Si80!YvZow64GBG5~L;dw*7+&9--D!mave^$Tb$gQn!+!+yeh zWcOL?d^pgr&pL+ev-I%V-}|$m#mYiE;Le%csvH$u9k!FUjxa z6QD$YKO-1x^@h&~?C+84>31{w83D&_wa*B+-%PRgfqUA3Ix6dFAzmWR`410VbT zz=fyb-6^d$H0!7xU{3fg6mJu#0l;OS%PU@>0t*x`5?`TshWxfxarQIc<8i(0=VmfJ zbN2IG#kSgs5 z9=vOk?yX=(mmEEss8qIO_<>F{0;q;(=zLis%(GKJ=R#d2=?_JYaP|k{R7m& zZEv;rSo}=tRC!W1tx&wOVrN=(X)kA;RZh7HzN9mSIUHT~8HL|kpPcK- zj9MSmyFL1Jz15xv*p6Q4aut~nVsddyBc@3QOIal7rl z$DZT&ny~ji`|h{@!~-&uCQmu=ps5G99CGMu!aAcLb@-l3+Ar}Q%-r#__}NTS|)aZ!+`LF<1}Z3lxd79)91Fp+Mz(2Y%lYC=S*2$9ocZZv*d1N~FJ; zzGo2ML^r+Vd*7Zpd>gNuhF|BwPxRt{6DSIZ8vy##zGf5E2j-xkaoLnHoz$^`%RbKU z5ts*%*>1~K{!&PdS)(}nW255i4}M6(`q>{XWB}&ukD>aTv1iKxfrieIz4>dBO+c1B z1NxpzFA|EhKgxbX2=KJ2x8IB%7B?8%^57S_CB4t!@_l`uk)`_EWo0(a_4D^k!DQC6 zs%(GK`-}->sJ_0>SV;A+qK3kAE_ffQ?GJvD{f^I}nGAP41N!FkX57>3;cut>*XP=P zHFND#rly-~^SSEpI-F}u`z6k`-_>vSvla~lsxjBru?73OuO-d()DRu2iW`3D5?roo zK{@3n^mqVsmumF!9LLob9bcf{?a`;tgXd7a)eHHy=XrmU{dK+l{oK7g*R~gi~G}UZf7gao9pULjl8a@+zKdx2K(J)88ErpO4eu>2J)n2kGBZYRt9W zk(950{N0#qFF4Eo{ZaZ;tX0gl{f^Xs=Px5Ja{165iO;pizP9J@{3Slu9u;2b>;Jbg zwZ0eNKEORhxQS8t-PgGwUmG1|c8Bku)Bddpz6NW3eVx03zQH(mgC&&Vb5i>Q>3W#E zah&kntw0WDfAe$FB5}^o&q*_Cjt1HKF9x_YuVTIb*qh^gOueNSJep z9O8i{{fDFFq#wTE847RwclChF`=}NQeC7ozFh}ts@g<70-G=IO$RnjOt&K8dC;pmb z6LHTW=g^HNtlft#?Q_TvsCrRL^xiz_IV6|oaWtuX((kH2LiM+ELHdR`f{njtigb8@ zKE79F`;(qSt|R;P^*Lmb>gT`93S&4t|8J)D@pIs$=a6Hm{ygR9FFtSH@9C`YcbR*i z8+EmH=I{?qR=;+&`@)`Du|0`%qoz;yIyd5$+aCzj-`{y`7tdi6o+FMNHse@pgQfx) zB9*#HmK+mq?b^|M3RZ)Hk< z^eC5_4VSvK|lU{aRBV^3;U<7uiou{^#Iu46ZTJAU%lJ^ zO9Np4R$>3N_0_xmuNeUQA0h0Yw!V6||Ca~A{?mm0)7Dq-_U|45`yVdspSHfbvcEkU zHGh(Ar1(EIwbmb<|2KVQ0OIE`5kG0`>m`1q{S)rrQ~V#gsC{a!f6&kWuN{E+ zd5wslwDt88KZD->UmXDZA1dshw!XTue{_7V>iz8@!hYAK^j9zTYf7arI=&71`2Si; zd#dYqRsL%c{!3e5Fa8_!_P>4r?0>MZf7<%$-TpTWfc>Wm`=_n1uIz75rZ3~iLBf8k zQ~IkH`!%J~SBK;OjVbNf7ylh7{Fk=AUi>%c$N!rK!2VN&{nOUx*gx8TrTr7`-?!`c zfl`0M{i*#w*WquMdtdtm=hBz>ohG==RrCCe{%rrzn`#w+WP9<{mrIh|d)F*U|W| z>iPZN!vEh+8E?J#zbUOg)qmyncl+%#@bjyx>_0)+|2zF`|5W-0-afVVZ`185?Wy9g zD*x>z{Fk=AUiy!;Pr~@QUC+m){#x{}rtc1b{l^RYr>(E9?BB=ne@|h*wJH78i~X8X z>8r!>=X)vb*_ZKW58=PG_4VREIX(=^@#l^Ku>bDD{%Py0cl&>T0PMe;uz%Y6>fQc# z4uJi~3Hzt5uiowdg8{JrSYiLP_0^UA?aB1z`njvH-(4yF)rrTL|Iq;0eC5;%T-fjD zDgD)p{hCtgtHbN>FH+jGFa8@Q{Fk=AUi>%cufO*Xfc=fIf7<%$-Tvzb!2a8gu~wx2 zf04Gny0X7LnZAr4TZR1|Na?R$?AMe^UmcGB8&cY{FaG+8jTgMR#fXaMZLMc6-Wef4hthX=s^{}T33TVGw--=2&bKjizbSO5FR==k6Cn*oTQ z7e)M}t*@8(k@j!Ae~iYbyuKvFXNvWYG4Zo;0OIGLB7V}==fuyz+eg|zAwE;AFN?AN zZwJ8s{}A?1Tc2b9X#4xuJ_GOHrbhX|)eod+L z)nWWUn$n(X{#2F!o)`X0TVF5!8}#GPV*_CS&BFd^>#KMBKRy8V|C_LX+WP9<{=Xjp z`#&e_pSHeww|{8>?EhC`|FrehyZ!$#0QP@Y*gtK3^=|(s2EhJ*5%y18UtQVXo=jin zkIxAEJ(<#9z1XiQmA=6~|L>#y|19kPR6pB4mA=7l|7iQ0{+QC9ed#}&g#Xgk*GvBy zT=!pnjQ>9g`#qh~U%l9`DV4rx{0uJpN88`@r%c?Z0UN?Egn$ z|FrehmHngRk9_}?@P23TuYY_>`2Wu-J`S9eT`eFTJ)c#G+ zq>P8YjQ>xH_)A+~FY!0%$N#?!fc>8k_D@@1UD@BBOkd*n55j)Wru0`Y_G?O|FWP?x zSN!+U{v~1mzxK2JQ|TM*_K&u|>A95l>`VXoz3^Y!`g-X>q7^)8>@+>`VMVCj6JSzFzz{=Q!0JY_!;!^|58eO_GSF}weVls`g-x-ptt|a17QDO3Hzt5udeJL9e?EeueyEz z_@MCrzf;CrFaB>zr7t>uO8Yn7KStwIj&BL^xqa&&Ur8AceHs6MDdI0}eZ9n=v`<3( zq*$L=WBX^bSOGkRSoT-}PAw+>w+)8_vxm2BwHk&GGvl)FJ#ie; z@H5)K`qw^KUswyZU+V9N_zcfS>X-IO(4XS>A<^~^D*d+aIa`yn*RwOSCs|JIP)_wE z+(0wt$eu$^YJ{_A%t>~?8hwy2ZqxeCwVA5XH!Dt=Wm+HPi_;fp7hM*r=&N1+o9Ch1 z+&B+o8vcMN*uMTT7~@K}x!Q3pDPH2n4P6J=S+ngOue84HJrAvKd)wDnyEM)NqNV@i zrQr{>tNzs2_@sW`=pWV3o3yRs;RVkqY-;?crm0cGh-jj8|xv#(0Hx(4V?rHpVNokhV+Gc%}1g?|o=ooa%S3 z&_dnM`+NMW_CB=Qe2sAk<0{U-+Lr_2-!%Tfmb;&W@jM#yjoObJY2vEkkA^=Q^9>wV z^*kbJzR?(W-RltVY5O(esu5Ql8?W~HRpUC?xDLMB#w$IZZts1q?t_i{RUDmaZI{M; z9PQkgH}Tcb{nq{b)iw?_`bYeG5^a}8KX3GNut0xbR~vEFh^t0iVGO`$W896u9yR7y zJuxCvjro?pyELu~J!76s>3-R` z??&rryEMitw2K~J8sl!fT^i#q+NCk>q8;?79$y;cE?P+2r7`ZJT^i$V{QbVROJm%{ zc&T>W)%~q;zuFjw&;rqCjKFn&Ys~-9TG}p+aR}{F?Kq_E*NCe|T!94|^S}5wX!MVG zyEMjKv`b^$MLXzEJ>PBIccX>0T^i#q+NCisd3D`)>o{%PuQvKGkMX*%0@n=UC2rIC z(##`tS}iAzPNl%F?GbDJ>p;ti(3;Clg%7!8`J6?-rCw}%p2eEhUuA> z6X#!a{^E-=ZPRkoS`Tl(DBSawdhOF%bJM)mL-0VxZ}r+++grQhbV>$m&qtc)w@Jq7 z5%8bvVzv`lB|@rlH_Nie^FZHg7p6Hrq* zzFLTv6hEAJo|?pZeBwpo+|CZ-9C)lBjzhf#3N+?3Sr2j6Gn@60iMZb5hzG=3&)bNX z6rV>tPXWaG3#^AY>pzpYX|f5sv3@unwqNl@#EZmP{}SS6N1L!4>tAZqq5X-o{*Mwb zDSjF8e6vm1jrFgv=}-@G*1wXt83nm}+JCi8hwWGVTH;0Gtba9eLxTnDzm<4EoZJ6x z;w8oJAf6v%6Lw=gMVp596p3@a_YyZd*@WF#|1WGhY`@|U5-$>GJsXLeoo&Ky=i--n z+%`&%?yS zZruJn@qjqjJBzqE5c9MCHxn-?egg3#an?VV^&EtHSpTWS1LCazOyVWQ&m*3nih5Z8 zV%9^P^}nCEIoNIgrNj%0e}Z_CIO|zKJm2EhdnNIJIJf^A;w8nu#(EBM^?aT65a)Wo zMcf?fw*L;|1;u|vyhxnwvySz=2KBK12Z#s6x&03lFDd>Q@%&+~o~MWxiF3VwA#Pye zYB$#Z0`Y?4FR>ottOw?=&>zh-)WhxHk$6Cy_3uKwr1+l1^GBc_*1sR?Au;;jF6;w8m@Ks?`xdiXkc5Aklre@@(VVSaAUgRF-*x97LS zi^N%fiFjtZTkoHU2gJGk&k-*v{!ilh*P+@{21az;%tXGtS66p zSpVCJ2gF(bDa1>PpFuqTdRNc6#EZna-V2GFnV6sTUqZZ~_=i~!an`e(^}NBY_tV4! z;;erq@si?SBA!1A^|1cySPyZw&&|Zm(Qf;1BVJJad&G;xS$~oBPy<>2Pl*S_x&7;j zmlS`9c>axU`yXXJ#99B7#LaBC{m&3DDE>V0B5`j27S?kN>S6uchzG>E{Y^X2{8RCr ziRX`X_3S~sNSy24m$-S8+y2SK3yL4YdWf^0R@U=ox84ro0da2s4B{olk0zdf3+iG0 zZ)QEj**!~G-2QIXbAsFc8;A$Qx&5~iFDd>V;`z6_?Z1=t5a;&)n7DbH z+y48A7Zm>`@gi})er+V4IT7_R|2^@5IM@3$@$erh+9GU+zY@=r0@m{n;@yh>oAtci zZU68l>|X`NM-eX)=k|;xo}Y_)xIKFj4~Wmg!)7A!lHv!ko_Dx<4r4vUx!x>sGtX`R zbm9fYUr)S9oZC5@^_+})SpV_F1LCu&{U;GGDgG|v`FFbQe>dwP&icw4z;-4p;Kh@Q9HSr>GuJ^0NO#$=IBK@?1=p?e}=1PC*nooT<`A0&6${=_3uNxp!g)# zL!9-ru%7q0^&UYyAkO;RiI)`rAL981sE73*MLZzR_IVR=bC%ow6NncSe+Tg*an@g8 zJ!iY^e-H71IJf_N;w8l|BA!3T)$;-3MdDoVM~L$c6YIZ>c!5ro`Da)Uan`en^_=I{ z`(@$*an^G^@si@V5YL~FdRYIrSr2ix|M!WT3ot+HzngeL@t+Yd5@-DzSkFSY{l6g| z5NG|56E7+LN8^(^sj#s5y+EOO8HW!6KS&v#fe_OBvw*56D#bD>-BuEYc4 z-2U;zON#GLJipj&&w;FmIJf6D#LY#RpY{913yOCUFA`__!~3@I`On3uhxNaactD)> zA4j~T_=&{x?{(Y%PS!)5^`B1MEOFa^Ht~Yu|BrZ)IO|zLJpVqo-VYHEh;#dw5icqJ zf2`*cSI_5I4{@&di^R?Q-S%HgyrB4v#EZn){%csz2T%{||1R->IJf^U;w8m@LOlOL zxBb6hJ;Yi6uZWwaZu=i0UQqlG#EZna{hL_Nhurr6jd(zu+y5f*lH&g%o)6sij~s>Z z84&08k0EY8jQLsrZo~_U?@hc&oZFvaJ(r>$)_*YZfH>=)M!ckW8}a-{-1Z;IdWf_B zHxM@;b=!X|@q*(2OT0*&^~@!n|Cn3vsl)@~-2O9(mlQvb^(=Gku$Xv}INR<0#LdUu z_Fqc8p!g?P4{_GBg7qwS>%EeAK%Cou4e^rVUn8FXgsbQ4#EZna-fs~%m$~h~gLpyl zAF&?dtY;nT`J`L#1H=R3-2R7&mlS`Dc>YtUhxI?jdWf^%|3cjSpWFTyh!+%piFlDX zU%%jY4>0~`E=N7gcO)JV=X!S`Za(d{b5G)V;;d&s;@yf*VLdC{_8&^Tptwi8NSy7{ z$$CD6dbpjhBOVZE`_Cd?Qv5B%^H;d%^)}W+ob{hf+6m zt@pje1LEBNrNm2$e~k5f-nGN0h!=^o-9Ag)taRId74d@NUtvAOS5;`vpso_mNFiF3U_CvLvrw*Num1;u~MdWf?g_#IC;|GCPo_fNzF;@tk{ zh?f-qC-M9jQ4i~Xh4m0;zmFJ0^Cxe;^T-HiL?F*tmjK^`wt)<5a;$!C0-{wGfH>=4NxY=^mx$-DLp`kjI@Uv+ zIZzEn%{CmWU#90sgE)C*8f4y7pPl*S_x&7;jmlS`9_1xgeTkc! z-Fhbz4~TO+4bNgoyFDZUB@%$~QhwFVa@qqZbc-Xv^xVaSp z>z_xwp!jLTi^RG83y5dF;p(}7c%b;j#7o3k&j*R;*PtHeA0^(cIOG};`=11X?}$p& z=Lr6>tKgrs`p3cVAHIoj#mV@6CGizI4GY0YF0=Tw1!tYw>YZwTc|GlPv+$h79(?%l zk%f;Oe6+zwJA8D&M<;xA!H3rxeuibdu#gv)^1@X2Y^sY;0II8aLJR=M} z4`a{6;PWv0JPbb%4`b28VDvB= zJq$+=S2g_7^5BrsfSVOVVHUtryd5Xhmq=GsCpQy9tNw2(duEidKj-B2CRn>>tV=x z7_%M*t%p(TVc2>Yw;l$rhmq@H=z18tKE|$HT>|FuF?M~7T_0oD$Jq5Tc72RpA7j_I z3sRsQ#;)(77K~jVW7o&n^)YsRj9njN*T>lPX`G~il1Iugc6}NvX|SZxl7>qfFKNKU z*!3}XeT-cnW7o&n^)YsRj9njN*T>lPF?M~7T_0oD$Jq5Tc72RpA7j_Y*!3}XeT-cn zW7o&n^)YsRj9njN*T>lPF?M~7T_0oD$Jq5Tc72RpA7j_Y*!3}XeT-cnW7o&n^)YsR zj9njN*T>lPF?M~7T_0oD$Jq5Tc72RpA7j_Y*!3}XeT-cnW7o&n^)YsRj9njN*T>lP zF?M~7T_0oD$Jq5Tc72RpA7j_Y*!3}XeT-cnW7o&n^)YsRjNL58ZWd!Vi?N%<*v(?> zW-)fN7`s`F-7Lm#7GpPyv75!%&0_3kF?O>UyIG9gEXHmYV>gSjo5k48V(exycC$F{ zW-)fN7`s`F-7Lm#7GpPyv74om4H;b{G#n{ba>}D}`vlzQsjNL58ZWd!Vi?N%<*v(?>W-)fN7`s`F-7Lm#7GpPy zv75!%&0_3kF?O>UyIG9gEXHmYV>gSjo5k48V(exycC#3}S&ZE*#%>m4H;b{G#n{ba z>}D}`vlzQsjNL58ZWd!Vi?N%<*v(?>W-)fN7`s`F-7Lm#7GpPyv75!%&0_3kF?O>U zyIG9gEXHmYV>gGfo5R@6VeIBGc5@iJIgH&L#%>N{H;1vC!`RJX?B+0ba~QihjNKf@ zZVqENhq0T(*v(<=<}h}17`r))-5kbl4r4cmv75u#&0*~3Fm`hoyE%;A9L8=AV>gGf zo5OK8hq0T(*v(<=<}h}17`r)|v(luMX00@B<#}s3XUNgam8PyVccsZI#%>N{H;1vC z!`RJX?B+0ba~QihjNKf@ZVqENhq0T(*v(<=<}h}17`r))-5kbl4r4cmv75u#&0*~3 zFm`hoyEz-X;!Z@SPrdN0OU^LObUy=kFOT6ZOn3(~SMU*hPh-CW#q)G*wc_2xHz;l& zB81x(#RKA*+weH-LcJy83l%TgTQS&HDV`@@R6JB>^KVkTKquGvtx#RqJU~U_1;q{B z;4N1?AihTN65kMh+tttOFIyB3cEEgd6z5ygC5jiCF#kHmi^Ml8&bPc1zT>thpj+X* z;w9oM6zBDqYZVWgQEy3cUVqtqyIXI;zHfl7RdHT_IahIb4*}b1#RK9S6o==wux(MC z*I8!1i^n0y}*I#Dtblb!0 zFBdA#>n~R+ZpLHzqT;;%a+Bh`{<8B2ZoRzzvY>dd7v@{8IIq84qd2d>GW)IZ^eZhLtBWnOV!f4M?&UVph(abAB}Qk>Uc zHW%G`i~HeztKz)=a<1aM{xVRU*I%wyoY!A&QJmLbW`1PCjmH^t0PfFLoY!A2RGime z78TEDP|qgC1L9-v#^b~6S9mF%g!`R}^ZLu>it{?lHH!1P%#Dik`b+a;w_aX_oN$j@FR#DMD{cXR zsyMH|oU1smzg(?&z6JGcP@LCgZc#j-{F!^*_LPV(R6KtO=3AwBK)k3pufN=+IIq9# z{Ha?nufHrPZeD}=mMhNdEY~O=P=2#c=|2qjTNLMYnR689^_NQ&=k=HC6fYi*`Zp`i z>n|t#%xw>^zsxJn>n~R*&g(DNDjpnxdP|D)`pf3~+(W#;E@y}ZtHw&J`lbD`qA{&JP#y#8{N;>9f1H})59y(WkIor?4N%Yx#({&J1t zy#8{d;z1kgH}|W0+i|}|abAD9L~&k!*{!(gKt1ae=k=GH73cMr6V|)!;q{k!#d-bZ z3dMQ-oT_}&g(2Q8{GEr z!kC4M^E%5_iu1b6qT;;%a+Bh`{<8CzZoT;#xL;5_Aii92UVphpabACE9(48d`pXu@ zO&;^jQ9K~NMDY^wb&B&k%gu`Oy37f`!g|W{hncvaSDe>hu28&4`PV9L-hg^aiu3x* z=3l$@^7_lUiu3x*K=I%xEWcWDUVphkabAC!dC0Ao*I&+7+|0s!3l$HDuTs23e3Rn5 z{&MWYZoR=9alcb>UVm9ooY!BjQJmLbZdBYHgZj;HRK3Jo6fY59qByU!>{guDWv)}4 z*I#Z{oY!CGH@fX9z6tjiC~n@2e1+n?{&KD2y#BKJx2}F(f7z;d@D|KBS8-l{87R){ zFE=R8>o2z`ZjML&nMd6A@cPTyiu3x*Rf_Za%cA1J9Mro>abABp_IGZ*y#BJFIIq84 zuDCe?%db(K*I#Z_oY!BrJnGiV>o4ah9=sLvEm54;Uv?|b>n}Ge&g(BHJm%KR>o4<) z^E%4~iu1b66^irv%e9L0`pc5y=Iz*y=EvRk@cPTSit{?lKyhA|xms~vf4M<%UVoYS zy<2bo9k@SR@qqY3#d-bZD#dyI{pHw_Tdz48_d6Bm^_K<3dHv-Y#d-bZM#Y17 z8r=SXU*+r9yKuinabAD9L~&k!*{!%a1@){`oY!A&R-D&g=AUre!|N;;D9-CLS14`@ zSbnYI1>((5D*eP;6*s40zPXC?`pZCZUVphkabAD9Me$%h>d!powujeW&Q_e)U#?P| z*IyPDH}6Khn-u5umt+6v*30WJ3ySkP%jJsmy393-^ZLt;iu3x*mZ#l%i)Z5g9L3Fh zkS|f3*I#xk&g(BXE6(dLC;Z8+m)BqB73cMr3l!(|munU0^_L~Z&DmIA^Cnd<@m9ro z{bisyud`gOc>WyJyFqbYf4N0*UVl0J&u)8)=i>fC#m#xhS1HcxFN=!v`pdD;xcYhh zWvAl7`IxVuIIq84t~js1+^9IOzchbw>op5;zeRCge>q2SUVquGIIq84r#P>_+^jgS zznt)_+n)R)+|Mh{>n|55&g(B%D9-CI*DB8IFPs0W>RpWct%?W4=PJ(YECa=PUFHVG zdHv-U#m&W7Z{|6-J-q&Mw&J}0a+Tt|{<5fe@LtrrNpW6(IreXEy}bUipg6CyT&_5; z%Uq*4ufN==IIq8K+3ePvzXbQ^C>{`BqByU=>{guDUv5^M*I!O}-mTYs0Qd8X^ZLsL ziu3x*wTkol%aY>32T_0X3##6wxZkQcufGfw=k=GX6*nJ3JsT9~^_N=|=k=Gf|L(RY zAK?B%#RKB26zBDqMa6mj<=B6?`g#3jr{d;P%vVsH*IzDIoY!A&RGiment!_W1|Pxw z7R7n}9#ldwBij0>ycq0QE^^>X>{guDS*}x@*JW;2oY!AY zpdWw@v&|S`h1Xv$P`vmBZ08Ea%~iSo#iIQd0pn%5vtxVW4)b< z^ZLu>iWe#W8pTaF>e;AxK-`RU>n#zVqd2d#T%tIy%j{O1*I%wvoY!AY*uky0crCUw zuekXt@&$_X`pXrH^ZLt@;=KN{xyh|JxDNHVD$eUK=PJ(YFIOwh>nt}Y&g(L_D9-CI zGdsHN;q{jb70=&*?OdgJK)k3pufN=+IIq9#gg?-4H~55p&Fe1UcwvKV@<@J|y73cMrf#SUWa<$^T{&Iujy#8{F;=KOSOuO)X z=Pf>MzWrXj2)`F_YVjFM7Mp2{&N%n9Y41L5@o8q-{0lF%`xoHO=@*=L-WliH4Ci04 z_>5_9JnqE9FI;@u>F1z%xBGKns{t(4q%`H#KJTJcdC!=sHVF)3TyA;V`5dhS{^_W5h`EUannVMs>Vui;jjDZ>Q%hQq*g{l8ZAQueT|oQ7}D3e*I;<;LZA zl+dQJRXwnaSZfaoQ@^A7+ZE^X{5_M(t88Z6&YZ(NqUkt$Sf4wTn0+DUJi#pz|JGuigpE^Cwc?GvWvMUDGZ&B9m#&^lX^M&-Pp{ zJdm|3S};dp^oNdq^Q_^+dNd9*Ga}~)H5H)owB^I^ycq*$GH!DAsFMH;Gs_+;Kw^T~ zwl#o6Xq9bS?UC~SxXIhL+WgbQqaQbc8MOl>hYcSwa)+iJ*)ZWz{K#gvL3_elNPlK} zkABj(t;hVsApghB%?qG>xn5)2WVt=ja(k(g@_xDfQa_a|>!JFVn_HF@V)Wz0smGdF zhid=qX#30hslJiJ7d>gqPJ=qO&z^Si3U#Zv~If2p7Rq1*Xk)7(p3RnRZ}pP>Ka=Ei41gRVC&zCwG+_75uk zI+pb{j_nB7AH9VxP_UA*srdR3vr%saNNNZBdnJKletg4NSyU_5YJGcFh7!b zpt!|$juP+PG=KACrqu&~^Q1)j;eQCh2KEEqNdZ|NPkL4wcJ=LVo(KhUri4os%_eFG zm>FV{w@zvRaLN)MDkxr{0`R{WVB`G7aL<@Eif7258x?0ivx!*``?-Zo&%8i(o1=J< z_!7l4bQ0Z)2Yhlv^xo=7H2`MFZ~QgMCcssB2K)_^cDvD|g>We%n4YJwz1>@VK-C*6 zvmX>5yqkD$#pU~YZ}kzXzr9=&Cb)k7o*C07$oai0+n;oA)l3(+zTR8$TGSFX6x8iz zMcY5=-m052o(d-;Ha>4g<gU#V zcyHCO_Xdr7r}%qv?i(@pW`pY9rq=D(V@bl08D3w?Hl+kzrX5U|_A;AQPPqxbq%(!N zT{Zf64#?&BTkC^*w?|)J&jaceLnSxQnV$iK^Qbmo+|ai) zi+d-IWzGlH%-Vd=}W#9`-Z*|1;RQo$Tkiit|YXiWm6ghUmT1 zeiUzLMPo9Ypzlfc8(fm7ef}!Z+`F&$PVZFpvR(=g-c7uB;_`jHcRHQwZ!gz`39g^N zXIji@ne_`*wm<3KX%pRh_VwPWo9gHOk@nsxNPX|*Rd?@X|Ke8KdnfoC@Vw>2MB=?u zruX+!)?eWmGM&DY@1^SS-f50_Zjq^`5rApfeLX48{eY^it{~Mi8$-wd$c?S6mz~u>sB1<=+ApJ9$2`&{C+E- zfGqc$o?9$$d+*UaagXNFJz6tW1ZI}^XmbUZeJ)VE0EV&KYQ>8oHD-h28S>{A#o5mp zbq~dUo~=0BZI$Be=c3~5=S_;UpNHyi2S2I?zzq3~zb4rPxGK+pzGrXe`>lIay{w+X zgLf0}(YSnH@6mov^|zO6!UWgP-!m=dw9Gn8S4;pfaC)nB3t)83=O z|3-wZ`uAIYRrhGV{j2L~@6j?M7V=@M67SI_9NF{RzJ%Y7y|&kTv#<*LG1%`RYJHEX zV_CR~O&EUDQ0_1qW*tVC;4ItnAG*o(iv!9UgrRTzG~;R zaru($Mb(wR`g?9U#%d1dmUi+p6n{I#{?)&olJU_WbGa$j&hVS0fI7-r`aXhqCk0fw zfAq}d{Dirj$RQ?cK2Fw_lYaQ3%dbrtvr%vv!z~o}a2R;O3T$%}FNV~ZC5mTA?@*l^ z9Vv}zZImH9@z*4qh?^VnZ?2Y5M(`DwmM*#W2iv$Mt*iKes+Y1Gb_egPQR2K&CwjfzzN96Dhbn_-EBwm7P|K_s^D8{;ANO zA?cql)Z9P+O68vl?HQ8(xvJ*=c`=oLDz`_CuQk6u^y~F4Ccb*VK7X<1{`qGr|5RvC z%=z`J{a%&xgR5)qpMRwCPlfgjN&kGQ=KlG6D*sey&tUgYw0~AL|9v5q{jN#&XN>)N zA73lz)ARcn{q;Y-eL30Q+CF{s|MRK*U!gri(m&lb_s`~3{;ANO!S0`Ed}l=ePgtK* z{rU*#PHKMJzxreB-~0IZm72%b-%`a_h4w_xPuefx`BaMc+XJs(-rpp&f3QDaySC=> z^<1j>s?eUO|A&BozFKqt{56$-Dzs-v`sccu`{&tI{;ANOA?cs5)!aXSN#&mk?HQ8( zxxVK9c_x*ADzs-v`saq4`{&Q8{8OPlL()I1Ywn*-sr*x+JwwtzH`d%ge@f+_3hfz^ z{<*2<{&_l;e=4+RNc!jIn)~OEsr*x+JwwtzU$41;o=WAP3hfz^{<)>*{&_N$e=4+R zNc!j2n)~O8RQ{>Zo+0U+uSZkGSB3UO<4fAFPJdtUotpdScd7hSp*=&=KeyN1 zKaZsHPlfgjN&kGe=KlF@D*sey&tUhDz0RrYTfX<-7mggZF_rz+Ci^qSe!b7HD(Dl} z?JyamUz}f^UVpxqY;SF!KKlPRsr+A|JwwtzchuZJ52x}^h4u_d|9rpZ{&^^se=4+R zu=}Tv`9pC2UKTid6P{{K}f|5s?wko3=8HTTbh zsr*x+JwwtzKdiZbewoTY71}e{{nN+sXG1Fc6_foLW53?7KNa-p@ij(&{a=56lx%Np zpFaBkfmHsl(4HabpSx@BpY^HyQ=vVB-9LSd@B35P@5jmhjIm$u<68xNy8p)LumADw zo@9G#`}EQOzewf(3hf!}{)yU8z8_6^|2NpzU;m`$@%8gm@l~Nc(fE@7NqD~7SbvSf z#PEdpt@ZosdutwF_oa%j3hjx;*ARGr{nMKJ=Vz(>Q=vUW(m(5J?w@t3{8OPlL()G# ztGR!En#w;F+A}2mb6?Hh4tbTc7OD82k19e64~$yfN(gjL~2J&(|JEws((Z z%BjBme(p!9{9mCxL()GRYVMz6D*sey&ye)bFKh0fAExq8h4u_d|2$Z8|J;?zKNZ?D zB>nTNn)~Mmsr*x+JwwtzzplA|?o8#M3hfz^{&}e8{`r0?|5Rwtko3>PHTTaQsr*x+ zJ%imp_AW);pUC&43Ge>~`}^zP)I7evmnyz0v?m&0(m##&*U|Wu?_U$*x7P2kH`YA9 z)~1TD3hjx;m$Y9(d=2)$@BZ7G`{%o<{8OPlgWW&T{#n)Y&)ZYk?~!DG#@Mg-=bshy zm7nTSB1V7xKmYt)vc0u^`sn}fr1F1-_6$k?JX&-Ad^?qYDz`_?KjrnOCfDzN?VmC6 z)%*DJSk3+OtyKQ0(4Ls{>sR|l$A_BxzjyyUUUUE4mdZaB+B4Yw6ZL;p^Mh}uvfuBM z{TXAw-s7W!K7IX*(O>`lr<81OZJ$2+e@!a?S7^_W^v@q^?w@a@@=t~K3`zeyQFH&? zn#w;F+A}2m^JLBab4x1!RA|qT^v_c@_s`c;`KLmAhNOS~Sabi}oXS6y+cWg;PoJ*2 ze{M?Up9<|6lKtmTHTTbrsr*x+Jwwtzn`-W#)v5ebp*@4$KhgU~`F=Fv`Qc!HfBom0 z$JY(1;;TY?qVXmDlkk4AvHlt#lk~&->uCR|>iOFBsr>&;ay&-;U&Y@qub>YN)AJdl zzy6=E{UzDnJ(ek_)cmz7|9>r&|0}d-u=~eau`l+!E|vYBP4;Ju{d#{sT|r+tDku@7 zzyABrUz6>v?bAp9e>Ii=E3{`w`scZt`{&wJ{;ANOA?csL)!aW{N#&mk?HQ8(*<5q~ zbf@x9h4u_d|2$uF|9m->e=4+Ru=}Tv*Y9gm+3$s9f5zCa_xW1|eR_Tpqrd*=Z+}m= zx3*6o{r{y@{;$xUA?crg)Z9N;r}9sQ_6$k?{Ill%`C=;nRA|qT^v{bm_s>Juz{9mCxL()Gl)!aW< zrt(jP_6$k?yj*kttW4#f3hf!}{)vu1^8IL?zQ6u=&ExCysp6|bd!q3r{nL1V9gW{t z!TOz7Y93#oOBG)g+7pd0X}^T{diAWo&So(H;4SI0#|n1G#PpAC!{I=A8@AlsKQd!? zw+6`U;cZ*3hT+4^xa@mR9EUXg#Qo4pq+i-6VSL=a_5J-iKaRFv+9#p?DSn?c$o1QI z>(18X?Dg!7>`9hWJCsvB2{+J;nbmX1NsVy!j5*2fSECQ|#cf*O#Wqtl`l@XoIfeYLhr<2)d$hFFw z-QP~KEbe}*+I+f>YUfSW#woNfZqxNvo3GmTHO3*dy0&w*_N&&v)#_{bqu~#*KqIa& z4)plk=pT*#(dZu-1Mu1CAJJ!8V3)@AJbu30SGzREU5KhiTs7t;7zfpkyE-4-zirQb zXxwv0{mykD;uOv!ZqwsSwfP$NM`+DB|7x2;PR**dUoHA?TpSF>^N8!0jq`}}Zgk#R zi@0j|fXSEP1jp(zH0Bc8rKE1y0&w*_G|QCw4d%rjks#W6Vzl+uevR=8?bo=TN5`hdc-6R`WABK*U)bJpSNAu#&uiST_P?DQ*M<1F>Z@J0 zH}3mdZ{s@MxK8s}tYZkcW)P=wn;v%?afMdWc4_o;v`Ztd8rKhqghu~}j0j5u|7i4&M*lzyMCTEW=g(-F{+?fHeU1Co+Ss{XuWt}9aa&){7w#8yS}iAzPNl%F?GbDJ>p;ti~H?DOg3|@ZA`0oc&lgsuKOF`@P_G`mJ{b+bpGOtGHugx z(^?O2zbM@EmU`{eT65F9)#&7l7TiaW^;&e&|YtKiT=eJ45=@Iaswqv#tv7Q0n zL|5DHYRlWdBVX3S&-1`ezzcMQ<7aQ;Ma3r)&rp-#Isn@gE1;*FIO}gA&Q&u%oOpqn z#M~!dB+mLfi03JwIRBBvyA_{FoK3;`XA>`wiCF(}#7o3E|J#V?DNvZtBi^lefw*b1 z3A?fWGi@5|6A))T=Mpa|zKD2!N1L!4=U-yep`D4d{-wk-&5*k%|3_^)tXJ{Nh?f*! zK|DXoChW%gSK2h_DH7-QTunSfouB!&!~?}w6E6{G{kIY?jIjy3v7T?+bXc$AcM#9) z1i5?KS+wcUKEzqiy~NGVHeomBzp!b@Ur_u(;zh+b63^^n6L#bFKW@`uy~J7nQ^XB) zK)W%2#-_u172iy}NSyV*NIXB*ChW#~Ua{%0Ud8Qyj0m}*{~5vgn~4{Qv;JL(msI{e zi05|;t1Z{N5AklrGsMmAn4k4eB_0sx_8dmMq_|H!PXjsU?#TO7S5$E=wPrNX})w7s*QSnQNXJDYV z8|w*(cN6D!E+cOC!TiiWMZBQ+6~v2*uOgn=7xi$x*AVX}&ibz-ZuWEQy@_~1@ioMY z#99CC#Pj>RdhR6Nt@z!<4P3D7b`pM>b;JvbuP0t4&h7s-@yr3JfZOv3@owU*zeL<* zFhBFBi5G~o{%4676@P(vW)kY*{9A|z#JN3NiJQr8{*m@N8jdrHk0xGJd@S({T+r>t z`o|ORCeH2IkGMGy^E01Jyr6gs@gi~7KaF_)AXiV0c(>xyiJPfz{ygylan?VJcuD1d zGx7YvuAUQ!cPl=ZxM{)stp8Nv0dcm&nZ!$qpGQ1@h+FSs;@!kq|NDt&4t4WiN<2{f z6U0l3uOOa(jobb!i5H1;`>!FMIn1s1Ys3S^zfQbFoZJ5`;su!a*^TwzLAe+>Ox8i#eH}-x6Hg3;;#0$h({}kdSmH$xU`JAiABi^leCvnq;`C0$# zhzG>EJ+p|H6n_ixe7jrk+lY4)XZG z{Y!~w=njtg$A|}te~NgCIP3o`@xpYhm-Splyr}qBh-Y5w=3h-bAkO-~LEIea=D(eI zLGd3DFA_fqi+@{21az#pe*u9F2Nd|J#Xo6KDIJLYzAs^D~GS2(X@WiI<3T z{tJoc-{`jg65`#8f0($L?dD%jyg;1m{WS5C%D<9${uo!!mxy;OejRahtZSc}i3h~_ zylx|2Qv7?w^KWwNEfVi0&h7sx@ywgu{OgGaia$iWM4a_JO1$tESI?8gi;6!(Jae3z z|9Rqp;#-K9h;zN$h!>7`^)&53{Z8?niD%}x`S&0m5NG}S5;yboD$< zyqh@N^RL7+@5217{~yEy#s5vbM4a0{yb0}@KgF$g6!C7w#}YTEVt#JVUc>|9v+%H) zNW7%@LB#U~x8B2ucN1s*S>l<~-2Bst2a3O*cuDcu#Pjn}59>dkc#-%lJZw%Po;lsE z_g%yT#otZ5M4a`XL%i^ASI;8iMaADoJadMdAD;h0{0GEY|Hp}&Gu`}`6E7(KdE!OI zuO^;(59(q4UnSm6d=?%yHxV}r+GF;hNnQH;S%7VZAH5n-$b3yKE4by!BN5 z|8?s;w@&)p+qaYcIQ2{Jsq^our|LZQRGp`us;3U{7I4!41K>TC{*QoXug}x@pTIl7 zN#_#q^nrZ({{y_O@UH;xDg1^T(eED2(|IEB4se$H6yWJY`Sf24yshvl;5~&;1J53I zbV&bOfOmoKcYjXifTu_E<$f#hw!&Wkya$~0zYTcn`|@;N2E42A?*^Vel26|P-Ud$k zuLYhQ%cp+`cuV1r0`DsPhk&QY9UantGw=>@^5^ZqlSlLAz6*Fu;irLjfs_7E0?z=D z{yziWQTWGzC*Pkh_v64@z)AmCfcI4Te*-)_k*D(?fOiyr9(eLto)dEgy|e*t*%gZX;?HSiX2KJUa1*S~teNq-0M?1%E@J_&dSIP3p3 z;K@J8m-}_VTMGXM;9cOX&o=|l-jJtL2i{TmUf{_a^XW6-E#Rd8BH%rh{x0BIJ5T3s z;2q$k^D5x!oAT-J1Kw8n_X6)J{QH1sKb)s?0(b{F%Y7s8^v(J7j{|Qj{6~TJ6#nDD zv$r@pr2k&vUEplr4**Z!nlJamz}pHx1H1>E^nVd}>+w9DUj^P(_^$y^Pv+DA2Jkj; z(*GpzWHF!q_kp(*{@;Lifs@Wf;Mv>qbp8T(N8w)tp1eJu{{I4RDSX>auHSWmv)r43 zXYa_h!k-R2`H_736nG0b=|2Z}Po>`tJp0i+omt==g+CW~@=lkY^zQ`T22S~T z3Gkl6zY}=&5A)?71l|Eo`mY9_p30{`47{!I2Z8q#ejIrAu6+G}5O^0j>;J>R(|?pN z_ie!23O@zB2b}eP5AfEH<>~xW;9Z6P6!7%N^XWedybYZ6e;#=9|K!vEGVqqd|26Qg z!p{Lu-|gs-{(lDE0Z#t>7vRZz^5uR8cuV1b47>}R^gjnYJDsQVSHL?8{}S-zAG`GT zxJ!~e!S%0}!fyoL1AV4WN8xV;p1ePw{zrhffV12m1Kv~V{|WHy19>{{2i{Tm67b}ME2Mz<>@>Dcvs=K0#84jujeH24sh151Cx8AP@a$uGI^P4l zqwxEICqI)<{{Zk7aMC{pyryrb|%;K>=6p7j4A@HTMr=iR`23jYb< z*+0+I`4I3faMJk*@bu^M_53;DZH505@SeiEz_Xvvm;39$yTDoQZvsz0o-g-zfwvX@ zY2ZEJeJ`-)A{?rJHScj9{^8&)uku?7T_&~ zORBBWlimcs(GgLyS$-5=ir{D5pMG+~>AljQiJBd>e)OwIgj z?7lBK`ugKF`KilKLw=g_Gb=xH^0P;N=H+Lv{M2Ubugz1lnal=m!ELsh%~!J-Yc^-i zX06%0b(^>D%CmXvHgDbLt=qhHo40QB)@|Op&D*ef8#ZslRo3Qh*t`v!w_)=(Y~F^= z+pu|?HgD7BZQ8s|_oOy&)8=j3yiJ?8Y4bL1-dUS>*5;kHd1r0jS(|s(=AE^9XKmhD zn|IdcowIr8Y~DGWch2UWvw7!i-Z`6h&gPx7dFO22JvQ$in|F`RyT|6;WApB@dH2}7 zdu-l4Ht!yrci!fmw|VDn-g%pM-sYXRdFO53d7F3M=AE~B_u9OBZQi{$?_QgCug$yH z=G|-a?zMUM+Pr&h-r9`KT${1EYcn=`ZN}!W%~%4p8B3uyV@cFzEREWXB~mk+`bCl` zVvY)g3{nO$gPcLoAZZXaCu=n)Y&9oswYsZ|led}^xSEr=niIL2lewA`x|)-^niIR4 zle?M|yjsIOkrTa|lf9Y~zM7N1niId8lfRl1z?zf5niIjAlfhck@x@7D&52>n$zjb2 zV$Dfn&52^o$zsh3W6eop&52{p$z#n4WX(xr&52~q$)s_fuuOJRS#x4pb8=a8f?0Et zS#zRUbFx`;!dY|DS##o9bMjep0$OttT5}>=b23_ULRxcDT61Drb8=d9f?9KuT63aW zbFx}ei$!^`rZr#al-N|m<$!^`rZr#al-N|m< z$!^`rZr#al-N|m<$!^`rZr#al-N|m<$!^`rZr#al-N|m<$!^`rZr#al-N|m<$!^`r zZr#al-N|m<$!^`rZr#al-N|m<$!^`rZr#al-N|m<$!^`rZr#al-N|m<$!^`rZr#al z-N|m<$!^`rZr#al-N|m<$!^`rZr#al-N|m<$!^`rZr#al-N|m<$!^`rZr#al-N|m< z$!^`rZr#al-N|m<$!^`rZr#al-N|m<$!^`rZr#al!^v*L$!^2RZo|oL!^v*L$!^2R zZo|oL!^v*L$!^2RZo|oL!^v*L$!^2RZo|oL!^v*L$!^2RZo|oL!^v*L$!^1qyA3D1 z4JW$|C%X+NyA3D14JW$|yzTM2$NQcyd^_$o@XE(KA1{5p_3_$wvfFU7+iO>g?4A-XDZCAQ^540?vp!;nm2gDi z^uIi%aIsrSIIHlEnYT;mDV%3?}i;q3_MXaQa`KQ8@iCFDRV;m&qqoxnJk*4=9}emnRfX|I3cT z>3?}n;qet#JBZb`?(l%bmZKr%(UOd4<#e zvZZkPUoI+~{+AaNPXEi~w^g~*?tWU~^uIiyaQa_%6i)xka|);bJ zyFZ|C`d^+3a9_&Ifc{za`J*Ix9RRPh137?h{EZAc}n5*zw9ZT{+ByGrOKUi z_cIEo|K&l2)Bkcw;q<>euWM-@*0%hL*{|7BO<^uN5QaQa`) z|A8v^@3{Mx!s&mxsBrpUo>4gcFE1#Z{+G$8Rk`2l?hh!O{+A~dPXEh}!s&l`PT};w zyrgjYUrv4|UmyBk9#J^`FHb2v%Uu4m3hx5%DV+Y7GyheU`+RqQP~r5yY%84pmrDw# z|K(+c)BiI4Lsjmb?tVex$qO8QRN?f$>?)l8mlqXI|I3}de7W?$oL6|V-=$krcn|m) zg|~oTP&oZBlmF)EQE#FD3`W#IQ=irDV+Y7lYgYjeX+aG6i)xkBMPVg z3?}p;q<>;QaJrA&nujMnU@t#|I74`^Yx+s3`W(IQ=g#D!lt0uDtm_QRN~6c~0TXTf0-$q{+Fi|PXEiZ3a9^NPvP{x+;LHrdyl(6 zsBrpUwiQnQ%O!==|MI-T>3^C2&wRPvgYJGo;q=Qqs&M*Wo>n;hFE1*b{+B!dG+!?L zFXt6b|I3!b>3?}f;qy#GgU6|8HLmT@}R=$f4QV^`d^+`IQ=g# zE1dq9>7VE8L;uU83a9_&X@%4Ova4|VUtUx={V(VLLX~^JyKgC+{+Ejir~l;{h135s zxs<0*|I2BG)Bo~-!s&l`LgDnkJg0E_UtUr;{Vyl~GG8D1UuFuY|K%x#)Bp0U!s&n6 zQ#k!Ecl?zq_x0}npu*{A*;Y9HGM5xi|I70Vr~hU81y$~Y?tVex^uIi+aQa`KRyh4H zFDjh=mplKLD)(V`Kd*55U$zuZ|I0H9r~l;zh135s`QQ0+>3=z`aQa`KP&oZBI|`@& z3^AhF<&40Umj67{Vz``oc@<*6;A)l9seg!pZ=FK3a9_&L50)*vaN9X zU!GSu{Vy*ooc@>T<$QhUf4QJ=`d^+_IQ=iX3a9_&MTOJ3=!-<$QhUf0-$q z{+Fi|PXEiZ3a9^NPvP{x-0?T6+_t+vsBrpOwiVt%`Xz3^C2Usdi8yZZ%& z)Bp0Q!s&l`TH*A+yr^*cU+(;hD)%k!eqQ19vur7xewk+!PXEgb3a9^NawT6b{V%5# zPXEgj3a9^NN8$9pJg0E_UtUr;{Vy})ogzVgx0?U-vpk}3`emL{IQ=irDxCh8J0|k< z>3=z+aQa^!R5<-F+X|=u<#~nE|MIfJ>3^AS$=8SemkSD~|K(|g)Bm!oaQa_fR5<-F zcWzbXzEilKBrS#0|8h~`^uIi#aQa_fP&oZBr?;tcPq}grD4hP6ClpTq%Z|e7e|bsa z^uL_EL6!TDT)COT>1TOF;q=Qqt8n^X_7qP4%N^VE<1R2kaQbB)RCv~rMl<_m6yE7rI61HI zDOc_Rh137?gu>~6*-<$CFE1&a{+E+aQsw@%D>qYkYsuk96i)xkvkIr5Wl!Ps%iOUu zUoQPGXB1BV%eKPlf4QV^`d^+`IQ=g#E1dq93%BO$L;uU83a9_&X@%4Ova4|VU+#Qz zo<99A=M_%>%a+3Ff4Qh|`d?m9IQ=h^r>JtzxOSXYIQ=gVD4hP69fi}+@|?oymw8Fy z^uL^xgXv9>Um54=e|bdV^uIi%aQa`KRXF`GdkUxj<;+*Baz8G$NRopJr~hSJ;q<>; zQaJrDFDsn>m+8|~xxe7bT~IjvFOMp`^@}cjSK;)(yr^*cU+(-GRqk0wXI|m-zicU- z{+Ejir~l;{h137?g2L&4IX#)L5B)C>D4hP6ClpTq%Z|e7e|bsa^uL^ZdcIuxS!N2S zU*-{o)Bp06!s&l`R^jx&Om-i8?7`!Q?lsrrkGSg*#*W{A;&`(Ak^3JwwEH!Ojvq>P z-+SzsxqsN*-1qQ<58nTfN$}9a$M4_$qPyT}nd>(5Kf^sQXI}0~I(VByZZelG=Kl^Pn8a27 zESN6;$5pvVj@caV61&|*N)p;(VE!9J(8OJ>`ruw*GkwU$-iz|*6wds-?n8c+EcvaH z^}p3*)Xy%ocD%`z@G?c1A{p|9$3n+i)c9-%A=F&5XHUFhuqUA5Rl9rz6^7B`h z-`|Yi-2L#kr0GoB4=(P0=bBCXhlcU^a4A|(c;gFSx_`?=pW;OFyn*(Sa=CX};+g!I z-<#!0Zhcnc1^3APMDqA&S`ta0d*v%_iCC^&`HK0AzrXcaSH5D>KR1~Wflcm6PTFfb zx#+YQ@qB!djnXk3x{*iuOUjy`?RyV7U>grq;2eB_AG^W`Rqt%rF~UtjsV z3I4uc|A0R7c{(U>G5OfzEtA>fNarT_eQrttR^G$<9|-7!o~E;H%a{JW$yjem_ObF) z2!_Epx1d8_?fC=#O6G~h=%CZd^Oj8)<4cTQEL~B1>iRuZ z0|oc7GGa-eWI+3k!RE&J#vtWb_#|gOweZlypANjM@UI7+qN9miO4w!o+q1)glg>2o z6aq-O6BWdswXE)3;evo+0OE9 z0SQvB(C?z1Q?Qsg+j&9ZZSd`=!h66^E1d1zRXE#uv(CLiJ#{$H_|EXqTf}vSG&itd!z2uB^33Kk^e_1}S`^;Y$_lZp8Qzh$P zH20du%Wc%T7kyZJsGN{{viZ-c1?Rp+bFVHEzB+s;6W7n$A3bK*!rbd`n|V&#RoO_y zRp(x}VeWN@d#L-{$+a=s_ibBldbxRgH}@JVKP^*(pK9)vpX&## zanWk-W%$5;JUDmMV^P77OI0ezUcBaWn0|-6GWXa1O{nh(D!O4AdekBNlw3^Hd&dgt z>F3z53&g!HSJIW8Q-`s0%-OasjwDuj$y$)A%FE>}+ zmb~rF(y3b_)I-g^mgA=o3_~^ds^(rVxJTPc%CFm1bFZ*B_2bpttIvxt7Mll#e`nmU zd(BmIFPUSd=xEj4%Si~9g~GYl+-Tnd=uh6}g1OgRHTSCKUPjcabuW&{?#lN)ulo$l zc$jkY&As-NntPd})ZOO8wEUjKqg<>r49+Z*3-=tBm@C|dJ%?rogEZW0`+E7i3Q_a1uKKIh&O3^xi*98LJ#`H|BlhYm^WV6w->k^vYdR^Cv z@h`TnQ^bGGzj3d_e3dD{?twF#v0ilNop+?uci;QyL&qOYXLmPu&)h!usJ*Mbp*FXB zrn$Q|^NsEgsreGh+{~OgUVoV&a<(n`OL%|h6K{>a-DEG4Zhe<;Yh;yC<}#wgGf?i< z+B%HXZybBqWG|iUQS0H6ci{Rw;1?lqUheuT_?~h)e2^i~+4n$azlidrT|<|Fd30>S z!#>_pc+31Duesm%h@q?a=FgsB7|C>Dv6n_TF;3 zw)skDYD0Oub{4$kGTRb`cI}zved+Jm>h`|82vkqv`s=us_oZI%y5eg4tFVu-^90RE z$X;W*PHd{Gb*#fVD*YSIum4sbTG4)cUGDyXZWz_No#=`&oh|mfv2;cJ3d@xExb3Jn z8=BURYAm7~!H!Bfp&hj?Of!MHJbj6K7ESoMjD)_#83dW>CD}N1vR#Ib*grdjSs*w|a3lLaXPC2X%#!j?c^E^xOru_U=1;GqmJK=9?yg160o2}c#)vuKi> zRyg^#S?!ds3Ylqml!8yZOqqzZZAJiB+R0Afepox@`&79kk7nj=p`DWXIgT=e&Myll zg6VUJK8W(?m=Raz=XD?Qt7OTiO4h%~PI(b8k5TQEJ(Pa{6_v4B)(6VkDQ8fArXGyX zP1twV`b;_9X@2kAu)5PJR@xNm>N5`AN$X71rH0X+HrzQytunr{Q|~biG1D?X$q>5g z@cdryx+%^@3eWi&>p4ZbFBa)q{@p7rhOiRdR1a;UQ>K?3zTs6ISuaF*I;l7Bn zx~`;)>98^W#nKh=-&X{YaqGI=Gf+1#vCXLKQm(YFD{>@Zm-#RD%^o@o(@z7>ATX2@ zo}1HAxX>Dh&dfan6nwpBz@1a(^eQQ{uLYZzY$>11;H?~H=00C^IAKS)XMno8;9;L^ z2k9l+Hvc6oDZFRVBss6}41B+=aJEN^4#slX9t#R*du&!+{E2FiO~G$orc6XwmJz`9 z1eD+|?uXUIU#iL_c{D3;3w3ekA5|CsE|fp#OL7sG&+9$|Gae>=Tgmzt>EiRyKS$NY zPoex#_Y6#fai#YR)NAWZ7pL8lIyiO3N*8x>yrtmG$!%Lk)5VA9ccqJ8-#rC~!vQUb z z(#1vRrtT+lBw?5Nzd>~I+OWEKEzrell`g)n_Y_pRxb4pVhk7@!l`f7w1@(GKU3>;d z_?O>PFjL+xKDqoEk>*?y8t-SPrEhk zr=%mrjni&TJFK=_^SpCEN9&uR>%;2G^*~pyLswqHWKteGv|C>e@UV}kxRLY{ZJGZP z78KsKsM!;uaJI*3g|j`n3TJyIK3vIt9OZnKF@>-Fk9`c5A)wm*t_` z@V3xy&HSUB{cgUiwV6^50sjbmdA{<~Sx-yvjX9oyP-+=yaj36Q;$h*h7*oW-nH+ zD4RZ(4nvx!R}@(_yR!LqTcs=a&xm8Y?=lS`c4g{jl$&*^D>sJKl^cPs+^BTrb!}I! zbmjbrN?n)NN>`>`x!iYO>+{#&uIzl(DqXqKl?T3iI##u{*NaWHwT?;q z9_jO{bxhGc%Fv^ZLOQ%^dZOd3gr0s5>P#$;*I2nR9XQ6nSh^zqvpil`O;>JKy0YlR zDLMw*eFN#r&0%%rW}qwcd!LnEdG|vPAHRS1i|)Gn_G8Bn-S>KS%oSdrVe*UU>2V+{ zpsUC4XCuEJmzclOmGg`w|9Gu*W$Mc1zSCK+@2L;#o0tZ|?c}o1H?hfDALo1^+`K83sExefIV@*P6TN!dLC`@s~w zCm@_FjAJcdbU-<`p^c8B&uy5;OV{_0{#yQQfzB1A2$ZZ@XOLV(IdTclZMYEN;d_1> zBbWSH@Rs>6;ef)s7EO{93Qs|Iv#z;6H)N*aQ3^isGG!vtwiy9j4`A>c_1uOZQst67 zn}hded%StG46gSuKgUs~*ZGUiZFn=vpJPT`nV;8v24_4>`b#D2U$o|a4*VN+&7FHn zMm@J-C(6&lhl)IFzq6M6j$VDfF|=-UV9fhdPnOn=Hr%-k3uVq_c;vIDp}(mmEniC4 zEaGRiCcin?LMa+40r|e)}KM;0Yvl=D>_fie&}_NfIuu=k!~Mkv(Z(v zGn$u8wI<)UGm0EZ*k%5U{jq}=E#-!5^5#!AQ0L|T)t15~(KvKov(4D*yj{@O`&Z9F z;Jn<0FUcX#T?oFfR_FKC&Y@gkN4S4=5*e9dA1;Q~p1;2TjG7(9V5x{jGN^BSR!=AgKeauK6&C1)t{j1DB zsxJK$ybMOwrC%I-nV4GZ`WNZamr?Oib!pCJM%}-95igeV`&Y|;7w!7%(!XwHdU<=@ zYTN0qgRfU9UAq2RBd9~@(nb8Nbm>Z$_5-zvKn3s+bs`TSqSH}F(&_LD_pqdk>B#C8 zX4A*gVaW6JiXy9~OK*_xo(*gFr5tFx?*`PRhyCtZeNSLc=6BC3U3z`4*;l%Benh1% z%CzEhEn-L2YwG>)oE?3pwAjR!t=r-{&t}!7uWpwv&(BEv ztgAf_>-{`n>NMfFByp{SiY^nI`fHt*I?riRVcXIE~RoEckHKW{>-9tgS z+621vu-`SS2j4ZT^Sfr1E?w!;GB$I$eiDPqZNT*SPP;Oa`HR+Di}rXhe`S|;tP?xT zlgxk3e_1ckyq6rq+oel>*KCaYUn9C&DP5X&)a7+)!w4&Iet+t^(gjz0E};8jkzFrl z7mVo{T6g0+S>!Pc?9OB}^l6 z{Tz}mw$>igy<_Q$_^-=dtu^_^2KlZS=PWC=BeLB^huj!vPMMeBaQj=0NchdMjhX7q zsp`xr(-(%_-}?F30BHMEeq<}MBQig24$P(BUq!xR)%mQBW2N`EHp+fi?E34<)%mQ_ zwky{KBX-<%WoNC{+&L<`Ymsgn(^)HBIX+*=bJX2&&Ank>R-4goOS#f^+YP8I5BuFO zBNBaGncw|d!eml(mCzTg`j$bgca_Ih+phdkrL(50YE$N3l4J_6zGa{of?KVt7x{v% zyKfmZ*2Z_g%Gi}}v@%`Um8v5%eA6ve`=p65{vOPpTga7 zf2yntY)0LUI-0g~2BLkP_op_(??=rgM_+$@kNgCVKc?;a21$G{s@k8Lm-f}RBUbxU z^Ze%ffY*KI&y0sDH{br$vfp`Xtm^r!WptyHrFEmtc|PmhXN@G|OsSRdvs#mnpRd4i zLXR8QO1IQ@LD30fdX?5yL*0STAXiQA4J)Ll%cU+8mKiHo(#7_r#&q*ox+4DTa#wBt zYIAeys+23OtBM>+*k%52jPqF=!+r;<5qt-#!S6s-e(;qayo{0B54-Y%AAA?d__6NJ zXKj@H4%8}t>!6J8M?d(RtO8M;DJAk|J#emk#k{k&ZTaFKncE?B=^}nsx^$&WThYRg z){&`0g=r+N(`_1EdXs*ai*m3Dbm^k+dl@70tXPs^Q|_CPX9IIGKKGSWx^$&WSGx3| z4ZCQ6>-y8Bul;w!BDz{+&A$A3qWYb_+GjHL*TAo~C%}K373Ul*CLepeWvc3Ne0$Y= zv(*G`>ooUvr5)ddE%mK~tJ|f^^E1*um9LmI5`u24BD-kJu3E;9T(svw+mS_=DMODs z59`mXrdQde9cN-ZCC|dE-~T#S*`>w)oT6iFK)dwZu;(fS-wkV2-wj*e`(LYX9fYG^ zUsvIKaG&`z<6+88_pO6Q$?t}ZasO*XS1YAU(~er5&-xX!pEb~pCuC2{$>bwPM3S|x zUhRL?I-}^8vAqH@-8Yu5NOum$5s8m`Pl4b6x=FuNMLV~)gNAd3>w7+{8BF76S@jK; z!3U)p_@Gp^|25xps{OA{H__`nKZJpdegx#2)?fWXX-jxbmo3qulyu zP5>s7t=qD0l00Xp`=2C#_bWF{T)EPh4#}JkrhUX$DYT@A%yNmiSFTz-AM(60X8%kK}^jZejUP52~n`PKAt{IR<6GatzD2lX)R+ z@b|v|89TD4Ur_(Wv_~GwS-kXxgO7f@wJih)5-^}`NH)3P< zuyi_}KFYge`;>ir;7IrW_v3z>%jfU6@V=e={vpYjZ#N^~q5KvMbU}dSl1L{Bwh^rhRU;=T7uX8Ek(uzUX}ZerWlPo(VVB_8&M$Bjitk ze4R`_`F+9y|6JfttbeR;`VsjlHNMYIWmZOFk_dFSSnf?b|wrlztDD zm0z9D-+TF8Zm*wz4%c5)|JL;Uy&u1J*aeFGIN@oAkwN+)e^6gd|77yv&kGTamz7_i zZ_U#;V{0xH*&<@LjMy5H8Od{jbL<>wZeli+GW5c^c}P>!lXA<@dnhCl#5FxxkBreP zn{K1>kLz3k>ugl>rEGf?weP5MCFRC!Zn}O_ZrOBY%z%vZA9G9eC_IZIb z{mX%;=zJ{q6~NoTnZ5S?;@mx8z_V6Ntah#4X~G!vHtcWH{@T63HM<$OW>1)?&0E~& zt=qhHo40QB)@|Op&0Dv5>)~F9@OTP-mv$P@DcvYMujNF5L!|9$co+C3 zg{SDRld{NTg4_!IHtyptMD%Hp2AZ+#EvIQsX@8GXB5tUd{E)+$8Cjo zArMOnXFoo#aQ5TN3THn~Wdl=CPxj*lg|iNcNNZld{N=-$2)Jy*N6Rh zUg7M=ErqimFDkr?ew^$+_Sl2R58Z37#~*RmBa9ut|HScR_apZ|aA@~y4jn&~?7sKd zF?0X0yIJ4+SH1z`iQ{gPq>SJ?Wv(Jx8SZ&G_Y@afguDwIC5quSS?>G7uTkZaF1jIa zlbVSMhGIO<{G+bXydLGxd5SK=@_F57V8+9w?=M;ZqP^e;p5~~%EF>B!EB5S?WeMfC zFn-7|_bl^Y^IzHpNldICcA)+KRUfi3{jB}hOS$h0&+eHYdX44+>LL}$Y%Quann4>& zNgH>64W+=wQvMrp5gS@58{T?Zqlwt?$7+MF)=;kQcN*b;sWlWkM9_v_t)Uop_%*1p z%5SxXB5TM-^RWKtWo_JCo8a28zXzT2Ye1upzttLw8zJKIyWAQ?`S+vNm0;39;r)xB ztM{P<)A|4z)NyIM$R#p2TAvf!L>YRtVJt^a$}L0hAx#MPx_);R(A%hdp^Z(mNAsmD zpNrbfj7+&uR$e3>%p$q`vG$0i)6Y>Pf8$Q4pSMWc7>ri|7w+bOh456L=3e$BP#OZ=oYH{dWMTjgRHt z4LpUQF#Rimw-tT}cn>(~ycRfZe8e9FP8%QbW58+SV?TThcw5=z-w2#GKGyTCz-i+n zZea6{LnY-V2wPcbfJt;~vRxrb@(zQDEuFT)Mey}Kz^7qr^y6M=?1=9#HzxD``54v~ zzB*>~peDh=8++YHn3rJW5&c8$LW_NR`* z*`LlSoc-yN!r7lDmF=CPohh9C>4?JFpH3;9{b{q>v~NSdcCDQxDI>T}nXB~q4EMYo z6l1Lk(~w6IcZq77>TSRvZsyK~2UNMlMc%?tWYcE;QEl4CQ2tz4n2ED|UiSr9nDoOX z>tAHkZo`f{s!jV0%Likn8-Km|ulXla>oJ&#O?|}AwDKoPLS2pdDZQ9xR=Io=|R4SXc6=Lygkntqkmm1mk z9PA5+&urxvU~GwgAHKHDuO8*)%jtBsC0D*= z$b3^vh?TOzkF&l~C_|)whVlg)Y9L>daia1&aQ;p!w>d{_rXm0H@*~=jwT+jzX|Fc@ zi2RgVv#f09=z)WN0miRreDB|Q`!7eo@;l)8$g8(m5HQ!6#YE;WVF+z3A+GglvGtUp zN1IScOX8ZIlv{=#ZAr_~8)i*m&@y!W)>?FX(Dt|7^A_<>^Z92=^0}zpbp6W8i=>0u zCHE-0eo}7PbTN5}(Tk;v^$(p_DypBiNd9!Xjn2PVpUE{WZeqNTrIWqAvPRLIsn#fD zO(2C)g8gfk;g4M_08Tla22MehaZkeS=D(zGK`=?@TCY*acq4&p6e$FP{ex>1ZQ!gY z*C=`lKV)dhbJ2E6I$Wcm?UeX~NKe}-ajsFcU`!)Fxkf?TDbsU}g0@rE^R1xYff0)M zJ6JAk;-vE~;M{LaT-F@qxo9gVZea7S1QX;Y2*a#({DjFD`VCyb0Qh0xmv3=|{kRw! z!LILGhgnl8av3nAMNm(-`r)1<^cxTxA;Vhp8#twG|Lm_T^&8+?hxQw2<0Ys42Dk>I z{RY@ywch~ytM(gUf7N~i?62Byfc;hb4Y0pf{sENS(XOj~hST3*++gieMsS@nR~b_> z-1D-CwSc2|KglpDQEkgFT1$Cu$^G?3Ybne>>RQU3D1VL*gezXpW-NDMpSds&$X*^R zS^uK7l*?c3sExXo(nk3U7!O3}mbTLTmv)Ki#pj;v%Kv3|@xS_6`@?gs)LP2y{5+Oh z%CDu&2hOdTtx2_(Qmv&_XDq?ydzJmk&yq8)Oz``|Lt8HL>9vUUf5wsi&C5$h%mNL%zN}&u9TX>}XtF;vACHR&`$e%U8))BX*>;CNThhD3R z$WOJFa!>g)AS3NF*0mI^i*0AeS64sh5Ac}90jj!BMO%jl5YhUgykg4G3vC`DO-)bA zEklnsosgEqHNCqE=xtQKlwDK!nF79OIVfs3ovy6BNV?b>K&(At>2&)R$=|rs>E|ty zKb>x^@o&4~f0+>LgRy+{KWLiCc;$ak+4k4FZC_-395#7bBM_T>B1RSywEw{(_PhFV zFEplHUz>bTlfVLBa~Aj=cplL|LjQw<0UnOMZH2dl873?#ylc@UIj`^(iq2()w}Gd4 zNyx1&7X$E7h12$aTH#%!?6nM27X52Jr2lv zzdr`_X@%4Fen8>0y`NAx*UCBy=UUl0g>$X!lES%GwpslTeuVqjAoWVRNY+h)Fk z@2ie=&OWM5rSddw}x&I%y=C7uN*A1zxh*F z<;!x<)KG}XU-jJuqid`k|AdH5IBee)uQ^2IXIb zHNCqE=y_X7P)M0_rGBxX%e`KF`JPzi45s;4HeHd;SwHVPO&MkQS429n31Z zCy%vnES-LiqIMg1I{myw@~qRXHU4eSalQB^CL6KTet*B&fL^TutiLq?jw>%VjcfPc zqazak4&WW&lxObm=O7~Ei3F|zbRa-Xf5`kz=qC_Bju+hD-%|L4NZ$ocI^5r%!dOL| z`}^Ap=l*`$GTCq63i>T)cZU57Xw?qtRFI52=Lt4t!(fuWC;BLBz+h7 z0hK<55l;IDw1Ib2dcJrsDZGV&U4K8I3p`Uc`xFnMzaP*BuKfdgz_oushJM#m^w}SG zC>uOQQTqq5KWhH~_DAg>!2YQH0N5Y39{~HK_5)yl)P4Z$kNW!o?2p<%po{*fzaPN< zxLMa6UWIW1;-939;5uclB0?GNdEq|qgOFe8ei8+nmp#Y-eX3m2MYrN@;W_@yKkAyp z2T}f%y^jeQzh$PwC0emaG!n;<214SzSi)XLwTG1mz7D}-#Xc`zbjdD`0{eLc~iou^vxhU@ny4S@{cFJY+?n$J%>p; z{F=j6>FVM<3Gmgk#wdPRy34F!qP=oKsi2PJ*4waw4fW9iWm6(MDQx88d z(FWrIM6~`ZwwE&W9@2yg=-pL74^!_Pl``dqwxKYyeva$Kmm)sv_Mi4EnTj za=g)N4#cZ92g5Lg>%8XB*u56l92&uzL!(-AknS(51`%BFn(*MW zO^mYRK@-VvQ>{6KTyeY-gnZl=#KV-EZ_S}uZq1?DsHZlRKO3m^v_5Au8?F2t2G=yo z?nBpW82%nM=j{WRvCJpwi8{^+|b)n{7x5qmR+D+H5s9c?{tUMRVpRS*j zyS>D7NIG2?$rhs*OBdsx&MWkE-lG1Y(_Jh6#hxR!#uVeJJf9A+KCRQpy-^q4cNdz~ z8p&#`k;u3yL9dapzZI>K$QWSPW+2Rz!+pSez)5ETxLzZX@`X+Z0><&`<-j@klm07! zw;(_=&PZsP|3ZhIn&}S%=RR=O=K*0@P3JCf{Y~do2%2y~(P;xuls^Pt1p1rKEe!l8RQfLPj>1zs zg#M;;8~7!az6X3#`C+iX>Tf!;zaCNPDUxRu&i>j{IQ#1koV`Q-vtQ0Aoc;Kq!r5Qj z3TJ;^QaJnTWref9rnk6u^YuYLUQjsu>rsWXziw84jwfQ=a9m81lo4E~%vHve4EMa8 z#u-SXes|%es$9~Qb__$!+z5v5Yj%tDK`=5jXxk3f0+J^uO>^wX3Elq; z{VAhcen6Au+61pr`lZ)Cwtj$g^tC^HNX(4KL$7^&`PU_9OMZgqHE&RBOO8CRDWnuX zg<=p^f9+$yUum`1CdRzBGO%`2t$lDJZR98-Kb1enJ=GafnBw}8MnooNLD6%9K(u^b ziD-Ian<+z&wxArb2)(-s=y_XAK%h*yq3tNhI`ACVi!ZeOg>{p-ZjZ9*%C_4(O&QPE zg+|IPqNnRumd{1lU$+J$k8vKJ^WlT zVm$Rkf=H}y1%LKY@6Rz?tyQeXS_S)6-Eds!cOhVutD?1vZ$2PE%Ace1=cvB*yjtISUc+ZdmA8?9$*eiNck7qT=v)xYKyuYJ z2Qv|}Hh90^y}zb0W!{%x(qtoR1B3L-uQ_~4)8oAz0R4}7_YA-0a8$ClR?H9I7>kfw_v&y1oUlKxHw{Teo_|3VYvf*T!@BxM9wV^)d! zFLbc~ebnz!99QMCSdsHE6!|YO|ET^8KZx>;+K~$^pVxinuZ)KY|9Q#!7x^z-eyXGP zvXE$`EGb*-dXnWV${+Q66c?ppCY1jk#hy}Y345D+=Y~BS>fp0nUF0{j(P}NBT1%+b z5;oyl!ou?YJ?&(&cjZcSP_|>oa6e{z4Q=%cWxg@}HRCFOU@c+G2dijV+=Io09ljGJQ;yAlf#wiJ}HUH&# zJ6OBrb3F*$oXBJY`EU$)OW}_J?*b>CHv&&_HX-r10&gq)9l(3Q*X=-ZjkLs1F)CvInXS`UgPrXMvypS}7?wgTB8vYR|RU8&%tD zk9T#4zt(Kr9Rb_0@z_DIK@Ed_QhVG!sYN`ebR#*df#E`c=iUuZb15Xf;4OEXOe?$# z{D8t!^w$##Zv*croc;Kc!dvLClV9TsVtu;6Gli#kh$9Mb13#tk9`LgYXFu*Koc(ym zWWGM^$1@6NKR&2&^y9Y1(T|rD&VGDe;q1q$46G)2{-7T(D4hNHsKVKgPb-}LxT|pX z|6zUDk2mX{s^0-WTq`9>$_TDg<|?m<4EMa8KxbWqyvu7rqBJo;9Fp6B zL7bUAdFnHKG#8O}2}8}?2!>+(pO}BtJyp*@`E#D4i?DoN_ZgV+FzI)etiN;{{p^;` zvmCXTg+xtUmnHZ5*(J+Cl-~kz*(Wa~HUFhuV&$I|#m0oL{q6tg^817Le5pNEvwQap zy{GCl`li$(vsH0>s`@sUPUrE@wB#={de23tGx)uneXq)r8_gNgkItHB|Ff;zvTl+* z$E@SY|0JP5ro^uvuHBiW{`t(AhyKh)Ym4f1{5|~n+R5u)BlTYXdrzkRNvD(BGZLOj z3wiF=!L(`@j17hx7~TznI+hp5g7IdBNEoJ<|>a!92#mo(A!kEkS=u=xefi z874~K_y?Dup9y_UkN1Wyg2<0~)Ns#H=zklPpNZsT^2`T>fUd{Y$G59Jf6zZA>qO<>jJ<}CKP_jQ@q2Q9{4Mo?u(E|2|{Olt|vA+EJ@+0H_p!|N-zwH>3dfYbSzgvUq7w5-MPk*fMN0b+iZ)1JG z*cV#=X`<&v%AZBQ)&bN09IW-g!@0lqZ?wKAHmDfAQOn)mFDe()<=#_Ju6_-kosZ^7t7T*!@MEkM>RWG$cz`uq;udw^dw zHVz5?Jsuis?h|{wGtf)S8s_Z>+U)n)#_|cctE>eCH3@9~^Umgf4$mXv9GcN4v9=^Q zL`xno$rRqUsQE6E!h68aDm+8K=_$Med7-p^Y1l(5p2e%aFGVepHn#V^SaOco$)Z~>q^$Y$R?jbu^H7S&+iR#@RH#` z-szhE(k|in#%DMx6*FPUUHq?p*8bqSx13FWet19Ug+R&6Y)vYgyzNcKCS2L%b2j0z z+Dt~anVU|s?bq7L!Y8-=ni(Amg7wpuu_Ltkgf{2(Y18i8{0nTNTPI#`2bGre;&V zefDGi4%s#Tj#|i{0{N?K@=n5xHfG-+T7Di+Dw{m|;GiGMSl=&ZSjz>N26C9(_&Ig( z7fh=HWYDHZTS6|8xzYOGT?UKM8@1ff_7Ik>%N3hOtXxbPd{){%Jb;L%C*{WIjrtt4 zNiA2d)bIH^k+~oBIo@gV#-2mdE2^JPSHwTgjlwm9GUXQ0)8&?x14##SMUIQHc8jIc zav=4KJ;%7y>E}J1t9}1Qr(0|M+upD0Rbw%p#xjUJ+5P%va=j7u>$6?gx(%IjRn~?s zy+s*_92Q z`(TY?V*LP&4gEzjQnuu0to#&$VOV_|^niSr{;8kW-@~TcPJX~HWG?S_65m&=>G^x` z_f5%TqtmZ!(3~h5LF&to-#1}8l*`c$+nc>ocpoF2Z*#A5VDEqA}CoR8>o zr7OqE)z1-h`5Zw_Ps)wa8}&J8tI8E>Zgja)zvt^j=6=-Y5ZhVoIm*)0>B_c85&vS( zdo66`v3ApS5w`2+JuF}(=yXMLrPHlf{%w!&AO^)`EtXE^r(%1bH5=M0+xxZKzfL(_ zsqLL~wC$bpt!?kb_5O9z(fiklA2MFdqDHQx02pl^q6PL10tLV@Nm55SuB!X@HWz4Qt5lZCzXvn zlZ+;03hw|vqHx1v8_p`c1-z&5F7O>{KY5CWm{E8e_(6rIXwbI8xz@F$aN6e2D?G!% zd|BZg;Aw$v{;0y)-%cx>{jIBT_P2`)r)_>G=2W$&EpSkz@YQ4>#LJNdm^Z+Nr0DF{XT-aUQL%gK)!YfdH~IU+pp z>0qmk*_;M!%ArjQ`8*wzx0rnF@m7TX7Tfi8|2OyHzWsyC+04v$TPD8r-=+RihS=N!~SKoe-=MVTRnax=)pV*d~h_07;{=%~`JpFJL0h(N zTW-y0z-G9td`~2AN_LD+KjaVOLG$5c^5M@*{WTtwzk&L%EBbx;@#Al0v#)ISZIOPX z%|`o&oYl5g)&%re4U>hde(>w(^Z{mvklYPqzbt z>B{n@Y`T~{m*wB~Tq_pe#L9@J_BMMnsjqDImCe4g+4pP>(am*_&I*WWJ^tCquiw+m zU)k*Qj3obf-3R{VQzgmfv)R{6+3aWQ_2#hq?3ZL=10l25>Z}?&gI?=r)tI*GToaqR zx2c6TLF}LOwncA~E`2_|Uo-JG*>d~Br_4I$$F!-QXOZw4?&J0JP5t%0=|P)v`Ljp{ zZ1%>ctm*rE@TdGf@YOy)e*M!o9l*XQynI$R-^%9Owy&_t=9?ULj2QUUx@cwdg~TXM z71?~bPet}@VPpmir?9#nQ#>qGi)< z4`kwM(O4O=^fD*4`=#rZ?N#>KW|%Bej&>RT2;KoM@*rW_{I~muA%IMOJMb28_Itx# zo4%{k>;2NCztZ!*Ss(6~?w}(dHuaFe{n9A}h3RQ~Z3Ab04w*diygh}#7I?N@sP^|Q zKWO5XZwlvr=>!8G%ay$2*v~Bcu4UhH3-ssl+;0Vb8v9iJxYpmuR==jU(V*PG23n^L z^a$!NV#l+BO*Ay)`lQ)am5<>-@KtOvOhu@I4h`1w9^8!(88%Vd5( zt;*#eK#sSGS%ORigSdK}`O(chuJae31%mSDd`=f(eqQ$(nDH>_(_xbjF^TK6Vt&)l zF6j=yF84CI34+cq_xjl-IoAr#;*Zh|M0e2qmv)Jje*ycF-);UL23>xCSZtKCQ8pU& znPF{|93!M2nXQboQAYNCes$@6inp|r-g!$*obqi%|HN%1+U6D5kjytA*Z98A7cRf= zb6fJ|ml#fLYY976#Lxb|ywC>c`Gso9%sG|&3>}$6 z_8@pO=pbU-6nrNH&5skI(xQA~8>K$@6c7j|gAGguFQOj8W~jj?mL#0p3Lf^67Ai)( zC5cT~RCw2-eV<>ZXFKzJPU0PjNC1n8vz_@(EaENj?SM+(1%5)|DITJu@HQWA_p!$w zJbvh2Gj}@vh`SzP?D+jBjwibxx&MJfyI*tY_@QL?y~mE3`-k1leGfnQ;QbGo1P?uY z{Qli9y6f)Sj~zdB-|OAetoT>-V0mVUg{PPKSUy5F5`DIbkY~i?n&IZDif{^?mnjpG zrp*Z8dI8G$4iq@-oayDNT$0!IFPbwk|EP1OSEBqm7K|&)=XIaK84r`bt7QF)=1lxX z*{E}-($M$>x9AInxOwe0BIxCa#~gKYBDv&6(=+GeggrXh)K&Wb$KvZ7r?aT0mT&m_oSNEmUeWhSXu;V9r z$}3(&ytUUYxw|A0ogfzY%HrQdM=3)u)Mc1guA1Kd71GnsA@pJ)R&Gp}_qtF(B$lp- z|3Nkz4UTKof6Cp*c$!Oq8#&Iv>hjHvq03Y5R;tUh-FF%Oh%VnohoKx!1Lr%8>8ZR&J839+hen?FMQMsgky9He)BSAB9bH{ zfa@fb)GqFa)s;W5$|ZR;D{l+e7npxkUHJ9o`2s3Fs;)eP@=v2c zd3VTMx2&#w4lfp2?+$~mzw7n&SI^9pJGZ3P99~!E8i~{+vz2kWvaSoNY*U0kF;Nm* zlnzDtb-IG4)yZtXn5o}xShGIgk@7&}c=w3h$-9T4gNV%Y?K=tgzMVp$x(_cCD`H`s zEBk$!7J10E%_g;PdggbHlC) z9~1#Y$n3Syz7fvf3(l@F`|`gaL?(8<@U?II$S3~75{&+=wtYkMvgn-=Jif1IZfpXI zCi7|b`&d2#b=8A1pU`>bkFj!NSW&%w0f@xvtkcN7^jZ6^GZT%C;B(G)D4Gw-Gmqol zC~HLW4(tj+6DA>Gf7`?bzkqw+hGFLo=VbvNye0kqw{w=dvvr2!E6bB&LK(|YF7X!f zZ`OIxr@;@hA!P*DDRY%J%5cxiSuk}0z_9PsXU00Yp{1%*I1gg}u+60^I)BkVt6eC6 z)OYH4m#lx$JCy_4sPEJk%1`mY@=oP@RrnC}X`+&-)Np1Gmd z40ccvFokBeVE0b#+pLH4wR-*+vgAfjbL+OOn>^=7ljNp5+CrSZakikV{+M^JIgc@S ze%)BlZ(MEqku?{ilkoYC0NHQk_7k_js#uqN_DmvuOh_`JX;a}V$ZAVEcA=oQCA^O$S~fw;+Xw3C|Aalo6UcQ3jv;!Puxg)iMEkpTH!t5ClpS; zcNE^ifHsK-C4JwqHmP0dbIN@ zd=@W&m&n5eLD#=O9F*KQQ=c8$uEf29QjN^kWo_udeVxqfU|xr`+D3s6`S~Gq$WAAx zV~6KuKqt-XkaC9VH+)!_l;6|e>8xKJ60ZW=^70eD13hRWu^}VY4K+Q!gF{*p$1B3a zE7j$6xkb-`uII}wio~8RmR81It9xybeH-MP*1gz{TKAH6lc04k(viQ7LzmiR=vccR z2FWA1ehYBwC|*v(!Lx7IYsz-#S@{VyD1N0!*2J*E;vDG9McSC*QhPUoewX1SDYKPX;ToGPJZ>G;p5=9ns4lWXzsquKgt9KUZTb55bv5tzSdRXm8~Qhl zM1SCHw!!aNtmu0oVf_pI63sWLOSZ3wl9A`|dnD!Pm*xMc^h@%;Zx8QwAOB2C9w);8 zKv$L&#;^6qKa-k>mt)vl-S=9$UGpafZ-4dlL;kFI4O@ya(@_Tu>n3qsKY0#a#%iR~WfavJ(a$NhuZ=EGkup2y-Drh9|Awnj7iD} zu2beJO`GAKmqkp>+0Mhx{r*^$OS;l7VJMpWG5@G@zt5rkxv(%3XZgIk@j@jsw^O=c zBw;@0D4P2%;pH^y+;1A?Uq*pK?kVPf*|{IT>3lycimR@Fe|VZJHTRpF*;5~Of8}K{ zcp+r=y3yu-p&dQ1lXp7)-tWcu16gb>G53@Gp`A`nw+`n9(YdSG(I0q@Fxi)Db^Mqe zedM`i*}0RSdko2+Z#UH+ZSGobZc}n@*5}WV^?#|U|Mp?#-b2!t!#r*rhQ7BQgz{4` z_p9dihPx&dotb286Qj$|0RIQahsESKKh!ei>;CKJ_GUcD1vNf|@*lOWbUJTJe!t}S zBL$5_zij^}{{7)m6{yTsKj$O!dIKZD6;mmX?Dw&Jgi|7- zGN;yg6hR`kl2yH?WCCP9Aks`)JZ({+}#<4&i`SZnnw`@ChJL#Hb%r$y}nQwN*T zUSqb#SRc$~!i}z9QG4ig*XlX8$0{Ac%092`NwzlAxyoiLwo%$p*zUUwe?prn+j$yz z4=)Ddve#A8XAltLWo@QRuWhER&pyznt&Hi#)@kdH4nbVhM_Ye|iw#up9&pls1#sE~ zNv8$81HmGG7&td`6Bic)q2JnWA|?=j#KZ;f0%y6hZ$a=BwiKp+1Ms%O-vYb`oOIp} zJcIFtbWQ>9DBQqiOpo`LVa_6ax1l4pW^R(_XO7JxiIc6*T$v=Tce2m z*V!j>KL-Omd}p*3-a?)wg?E9US9ps4by?wU;3)=sxs`Hzz!wyrp+6o~cnA1th4V$< zRd@>zcTwS8;5)Iwob^f3zvdO*2HsLQ`{Sa**&oj+oc-~F!r32rC=Tnx{x~h0Q%oSv z{&+y)?2jiD&i;5w;p~r-kayB&f6Nrl{T}nX8COhI?KXp6p@= zA-~c+B#Pn9`ybv0EbNn#^O?8E?_iMj3PX|2pZPKT`Ybws(cbr6D1Xl9bP?v~b)SJ5 z50id($@&-B{5!C7+v#6GSeGUDU~!NtNm?j>28@;AAT|Fr|D|0t?+uikl8Tw|^X}q* zb@_dp|DIAd|3-6uX#Y=sD?=)g*_y0u@B5!T$544ql03&OZf?B@|3Bfk<#~Dkzt#57 zTy6Ssn>3%_NL9hNMt|&gq!E_4d5pT|;P&q8dW>)H{-6A`YJYQU+kVLQ->m$r{AZ24 z1cC3E)%2f*Iu?`~=;{F)OBbI#1ep-k?~%iUNh}h3-q<@t)8kx6lht`;t`vKYve@-{ z-tGFq3hv9+Plh9F`!E}qHp1C5lqY#EnM=39pSy77ezBgyxnC@U@&6y5`VR^e>V zp2FFl2f<>}XL~Lwob7pD;cU+Z@R4-bo||<}$Nf-fmLz2a*C}(ACdqKm%PH76E&&*J zPWKIbagZRc(k@{rn$t1ACZqEg&FQ`w8AqMd9nuA((z^VjIb9nznNjC-{FWnq-h`Z# zRd!A{gZ6u6$ZQkW_3sZe^X2ArdmBUhGk0K@k*Z|!V}9j30R46FU?0mBzwU}TiC*V@ zJbCCp8Y)jsZhB5v=5#`@Aoz9OfPSXw`}?8Sc}Jb|48PCH*FUljuIs;;-1VWJVTi}U z$1&~$u|i#DPH3uO1*umoP$E0%cV3Do(o0vbY9VkbzUK) zG3w5_Ld=b(C*|tAl1F2Q1&jo!jJdz?Js5(T-nDw(QOhmjOYC{=&=)?eiN|LpDv`O> z^(*3YS-ILiSVR;lTfeV1x$WH7Ou{z8+?R64xo->HA-Xbe-&_^9qIc|sN7zC4s92m!#T8Fk3rK((#2RYsro;Ak& zd|xnw&R;Y)|1Ok2$Bei#Kd<`?&Ul#gZ6)hpG&f(se00>g`6-mY6XU47n`NwLwI)$n zX%~n-5O?X|W&U6e9emdQ@U^$p+`L&I{<|Yf!J2<&>r>6m2j@h$C}VnILeO8KYxQnuV8KF9dC zk!=lMV;afY8jNyU*&0UoF<^hxwg%#~HS{2`lvCOoGIR`%6SOsS6#fF!USfl=6Co2P z9oiaN5MbhBBarl6;H-~<&DaySNDZ@&FZC50LHoZ9~9AoKQIBsH1So(K&@vjxxMFST5ygv)U*=tzM=n+Mkyx6A@X@ z2=IzIHqW3O)<*G6tY4EHuMivF7TPG7AI-vff)~zes{_G z7uhHdU|v3|jiQC}r_pcZoi28EHs^9S3i^B;3m?kF^|Shss5Vo|Mln}!&JTMI%#u_b zA+y&)8%3%0zjMFuz6tc`j2YA1p72fnO(4HMUuymLb+3^|nAoy)+YQ_M-&V2>ll$4M z`y-B&n2@++LW-| zp8QreKxwg9=yr4R9~qyt{GUv|_aj0{uANJn;a9>yeT_w7j z&!=@gOw|Tzt>#`EQ6!AG$E?nAu-Bwbr@OgWV zlDpB*w$gO5=ZKZ7 z*cisYh1V%_BQ|Ao=<r+@VdG<-Qzv3PBA=_QXifx!}RjEaoE=1ZRm(? z-P^9frw;&MyhTd#O98soOJe>cMBL%y1A`#{%2@5!mKL zzY5Q-IUC^NSk_Z`TbN+N4h)t;N7DDqe+dT_o^C(#dlxsZ>|x<>IM;D?jiBuN>;b;?|2NY8N3 z%VjK#je2g)Z>VxfSK1{EHFF~vx{3c2^J7@{xXxd+M)66MKj(A02=nv0&%lg_NpE^m zc-N2Xw1sOFu*;9SMzIs+k9uxRhW0CcZcVLLtx=fm=yzP{x3!DqY+Q{O+;cKne5?G0 zwg}q7biTy+a9%O#b2gT-(qC;GX|+ai^);M6|HCy3FBe#&@b|DOx0BC(QDkLQA4*Lx zC!c04JDEK50io~Hp&l_CU2KiQ=PO*JSUdEEjqBYjPs-JKCEvKyajrG&TF~LxLl`VZPuE$p>Srs^WlP>gOnuQ=M)YKF7+9Jul2(Iqv9k59j{czlqT!5BjO%ybu4*I83Cx zExb;dzt}YjV~p4c``*dlYK_7*`CaBxtx>G$HHz9=T%!oS5L>HNYZP{>En{@GM&Wd? zYK_8;uliTdJDzRF-$8vfL&j>2BF{nckJo+RUp|#tYTk5f6!lVT6tm5}L!ZNV7V9O# zSi>-y(8uTpFDmaV@bXx>91{gD3!^iL)q{=8I0mpixyC8^dk{pzfdvfr!qVrwD0 zBm5inIg0qA`6qm4n}@~6(&@TL`m*U*#;|f#BnP@KW!txiFSkk1U-eUa~ei(SV-9$`adf5^rd}{+| zxsL$vDV+P|GjxQ*LJVOX``KmRy*;lM^v{4FZwG!9`;C47?{62cuhdpt=6kE*zV+Zc zG3M0Updx`yI6O1u>133-PQp(>#5Ej0GKII1=ZM04z|Sf?gZ%dt-T@wd|J9ZYIp?=8 zSReKa{asl0i?-TdpW-3(cVXMW^><-=z*Ds^K10Lm@4vEN=U+C|@wjlpqMZXK2 z=fU!M*)ImZ^9uPN_|7YE{oPjfi_N;P{5bk2#4|}5!F9@9rHM1#^KxXTi(QrmF+s#j zL=$4X?DtSVuF4e}56bJ2U9~Mf=Ks1?A5%Bd*NP>pp`s9wzNLf-gx_mC>Wt4v&f0S*Y__w* ze>d`TL>yZ)>rd z^_Qp2(+~Myz@L-JC%;c>=AR3ED{Hg$`PMxB%4S>HY(>&_(E3hgvvnNOdgOl1INWRg ziS0q>m82S@jRIu+MbndVbzVvAZ3I4NlEiGbm=Xr5;!#~j+2<{)pMDN`UOoSin#9uS zx(t(!Wvmz5t~?v2@e=i6)OI`UDdZzDzG&V{j_vtug?DA^C+%QuyN$}WTiJG#WV6_I zFJORvyODpf`JRRi!jIdbvEUk?RT6v;yq1eswq0w#l5uf4+pf0ZW@uP#!|edqHeA|v zwGEfH-HQdbU2VgqZCBfH+Zf1sZnMlK<+*ws;31F1H@j{3eac3e8eWBA%G^j(W+7e!kzCN9QlH?S2;J&oLve%+KpSgEJl`eLBvh2{DQ5v_-bv z#TD9iQXKhUk5g+LqQ%R`%U>O)s}LV8*ADiTm!l zu1Cc7XRWSoRKtGL0o(dS--ZZV;9_!kN6Tc=^hdSrYC3O9>W|tw?Rw#BuWs9l*rvn% zvIVy3^89z4S?N(<6-5m$kslp9EiN=ywX&$ zcH0!T-DYLmt!%rMZP)kzzHPU;(tW#jPp+}j%9+&mYmc>A8!y_=8`^Wjv!|PtZP(hQ zMCYh%yT^_{a{SP}W*_en#*W{A;&`(Ak^3JwwEH!Ojvq>P-+SzsxqsN*-1qQ<58nTf zN$}9a$M4_$qPy=GQ zT*yCO_Zgh=Fy-d6?ar37?N(5AF^0viJ=VbE0b0k6D_SES_Y){^{=xq}N zw#81z)A6>&yFS#5(08`QPRINy20S$ z^h5cFylDC-ldrubHPd*ceb+htzU{I)FIie#hdzJ&_*tE`5HLyW#FcH=F-P;|TG^hx zjUZ^F%Ca z4lxvl`x{;14fTCL(Q-5x{j4%$vdeu;&2%xGIAeVb^yesk*Spfe=JqPFl%HM&j?9GxkD0>c24}+obHw^l*`h9KBT6i}_ zzQ5|JwzM z(O6w{8oBrHCUZ#QM)*!r$lvSyZrU^WZVFEw+*7@qjQr{T_H1Ce_pre-^It;sZgPC! zFZsvoKJy30nMSUg@7*+i&EHMjH=1ud}yUFxOJ&soICdU)b?_|`HP|cehAIi_0_FnUMQ`DyS75~mD zwCSmDzFy_@z9zMJ+2@20)gyU7eU)w{`!x%{ncdV~HU!keLO zdi9yL@ou`Z{JY7uy-!!Yo6s5fZmJtat$H^JH}YZh^(NCfaF(67fg2_V@#@`VSY5rF z^72-_o5uBSs;!rI)5M2ACo)jIoAN!Ozur_gljZ8&G}d=hZSdVx3*Jq&>fL07v3fV< zdt~))8rQq2+;{9(d7s|SJ4(!(Dw|%u5Ae>HlZ%UEnOcsyg9Q>7;1#qIqc} z2&ZT!G)S6ycU54*v63_mh8Ph-R3x|aXgZP?q$5pGxpAPo7{Ii^2);5m8l^Eo8%2%J zxz0E<{f*%CjOZ7^eBaf^7lNdnaj~k?tGkMN1T<(p{nKg z(?_{nIg#I8$-4$mKY~7o5=DRHOLI{iJ#y-F@hYzw6anx%sBGZRmGBePypY3%=J0E5 zm!F8|*XeOM9hZaaaGbBmDg0cn(EEn4I(kVu;>NBq;B_dx{%v}L?4v97&-yU$vCsfP z1b+_jHgKt5-kXBMr}&r(z72R2xTM3;hanqnr*wFIT?gqOhD+6vBZMUKD20iC%S>f#*O_HMu7rH*AaG~p{uIJnD6Pak2 zf_~ymkcaC&69DcJbnwHt?{_`lXH>qDJlDH_v8=!ts?9x;_?nmL_;q%I-$MTLF2%wl z@x@&tSp0s_uSJ&s=@cmxbODTX(Di&zAklp&9QPqU4k~s%pPaRJng3Gc*Y8^PHBCuxSUHnomTujT{%E!X^u!?|xQ z-{1;iU?CEu*6mvs+aUX6iL5jNvRKc3n>-%w$ztUWOD2oecAd(D)!wV!WU&gloh%|U ziOFL7ZoFo4n*QSU{h6MeTw$=MsWO;Se+Qn#Z1t(+G*p&_?_x}SY;=(}|%M-5r z47%6#{rSc%F8x}&PiY5Q9lMycQF*DlZ*%B7?vY%gcgYX_-UTiYc|tNpNcPYe%P65M zRK5^a_kKFf(7Wj{e9wAIZU-WTY$MG5lltmc_F!5J!>+^jB)03MXqXw?mjZ8~LAbgt zg#@>65}mt~AHm~~c+GnfgujE*cBIda=%D0H4tTiVR$B^haA3NQDZHJd^fRLSEnTlV zZYuPEJ3%hjVTOBg8mQO?fPU>W_o;j(T~v?UCUy21iLdn=9ly>#b3gJQ)IRg)k>#(m z&$L0mLG3e-BL4-vFxzL&p?~QcTR}mt7r$QsPEzFm3IX71`jy=_Zoj4J#ks!s0z4*# zrZQxCIcjABe=Mj*CWs$vIt?;`Kh{)J{x17QKlUY`KBsA{%*GOnt|aHzXxXu=ersh) z-52X*B6Q^foEuhg45LN zJbVkd(Xglkj&#}{iqOPQH``Jt8hnU(pGl{@+LN^dKj zX>ZH7X>ZH7&FE-M7H(T|UG3q1Uu-J8fe1$w-UfbL;VI}ZV@iC>L7Kot77<+PYc~iX zxYXBe3YYpCRT=(V#Yj@rgE$l9VUlG6!2LLw+(WqUSBAe_TU|9O{F;gR^_E)gt#Kj`}-%U>tM-v+sLP#OL(@;{2gu?)Y3{zV)FP+KoB|%Ta7_rIlCHZq7wP$|}eGSmZWO$aDAih*;3!i?6nG9c$!pZO( zWIsufnN5Z->h}_I*dE?PhIjj3_9esn^1Qb-rpfRd>l}5H;oT=A_lOKDuF3E+HXpZt z=k(NK-*))po<5Z2wXk9B@at-Bf%F0CA>-mvuCp6?xL2hP)pDDB%Uu9?29@PxYgb^J4beb{;d{1!N4~65iIQlyJ*;j{fy5uw9yx>j2en7u7+L;0d*lJo zZ%})rti_Tu&)6P$F8#;aBirb(SxNfbC*46{*I8%c_IsUK?0^03aV|KnEO$4oEE6%O zU^)5J!3I%5k44k^Ub=Ms(EaM!+uVBD)tM)W_c@j2kDz~-y|AA-9e(;Xb2>(6&czJv zK~gl>cDp?1Mz?Ek%~swZmXnV@oRUw6E82g%&4F;a_UY31?aeiFcH-w8aW0hKs z=RsZh#=b`^UDn!r44clO_Q&#uzQ#3Bb02EEp`fe_v5q&hLG~w?b`q=ONjud#o}{yl z=)-ennqVY?ZwKB{xSmTR>DSGr;W;pzz9?Lh{wsku(D4Od0^SBL>F)+Eb4MgR>#%wG z(ZB>Jn6eDFl1;%?k{o`VqgAdq&|SWt0n$%Vt_E-smRX^N=1(7`hYXl z$1g?wi!(tUCQ&8;-0eIWoi5QO`_<(yRrwaFLG+Uwa_e+?i7(%CiNf{mUv+bfz76@$ z`+>f1TdjIs(&>!Qy$>a4U(WBW zaoP)vu2zeG%Zu)P`mZ}(UX|b1g==gP{q4o3(vP4|mo3HCPoTL$L~@O9m-AIUzTC%8 zIGm2lxO_W(UHB}1pe`L(WONlwL^TI!e(_!_YBzQ#$$DYBath=n$fNimv0@rZ0r8K*#iw z@$|~_?3V4wkUw-hPhGA99`5(Gmcko|a7^KC;EyRhg)k#~M({1C-vpkag9+XNF7xUI z&p^KiRrnV0j>3geZAM3zbQ*ZMNrkuNrAJgp{H$V#De6<43G#5&W&*%HiotlP=YDm> zb3;s=(nd3Ixe;5aVayphTBiD>a z*?4b3!MZir@jA+BSpVbKZ;g&+GSC414r9a#!VPd85Ba zvAUed`ejOmPp8NE>auW1jm4I)EtYw={k>bC%n;4Sd&Be-Ixc~J)lj22-WzwWpN;o=EyZ;C z`#<+pj~)Rp^)r9Gbg1KvgX;1Z{wWvK#(Q6Q;>npyuX1#N?j3JSVJf!z9uK$iUY6Ch zKE|}vn8@_}%)erF>yR!S(zA5FYfTr{@5|+rck}5I(n&+uxF4y9KSZlga5vsdYZ*)@ zUB5ah*X?N@?{(+L4x(e0<1+r7;_}Q{8}BW8uZ{N>bjS)PvGHCI0*>g0;@0Viqc`3g zcfRh-{AAyAg0IBea^gv{Z}*|245XuX=_nYtE#?FZU&xy& z{U{yR#(RY@aQmlE7yZ%xiT3CYh5T-2a6pSjMc3;UtJb{V~xd@ zuP!~&qx|vG9R+DCzad&x0^mlMFZO+7>9^ANUF*6eukFj{4$qn{$>W$QI=IyPdKus3 z?ywrV7(j3g-^b%7;u6 zgbViJ(7L(95??2yx&pLmjqm?(h>UoI88~`42jG z__n_14#%AjZn~t`N}TL#bB8^uRJ_z*R&Bho)IDr{X@%(CO{+Q{IMnf8&PJslp=+Bi z$+9!V8?UCiF%B2HM5K{tb?M0`%ydbiRN*?=+=D}y5}mxzRd1{=?sUmH(;i6GhGsdfFrt~xTZ_u427Bb9k;$bO)==0 zZ%0)4i{JU#*&H)n(rZtqORmegtDk!p*P)xUY2%W4lP2w^-*I7zr)&kLOXjq!{>18j zTE8@1vY=xu{d71U4;6jduaS`67{XRfmm~wX&2hDH$rb35^TW|4=RI9=-gHS~63jyy zU?iqX7F;tcoWyiV5CV?qkm8yyDZ1oN(^I49Yr15WE}}zGf6zDFlM)rQu6i2QOHwJ6 zt~XR&U@%>~YYwE18|Hn6Gz}X!%qbDl8HhSvm&RDP2wgh8I$ckPtJ75m&6m^Dak;!2 zTj_XZ=sk2EoNs8XE`$wx{O)O#cfPK0!E~;exuDXnw-ensdKMwwOaQo@&4p((>aE|iMc%CPmE@6}+}55yDe?833?092ec*M-f8OO( zcqG2KO9YGG5BlSg<*!>G_$b!r4SKeSoYN}(gVhgSUw~>!PImre69KRBUyA(tT}$q< zXu4CM<8Y=sapNL}oXhm2M7uezXmsx0*6)ELT~5o^?>U;_)9&tfIbYQypL9W4hSPER znZ|rsPvWwx)8l+~+)y}9Pk)~{oQ@ltZ|r--(q*OZ0a1-#$z36A+&%5>foRq{5IuFe z6Mfumyz1oRRnopjSa(`nsqVDs=}wELJLNplbf+q-N~^cY1l^nNq=-VdBd0sfPMYpy zy3%5*2worWq~52`!aId#m5hNC;Fajl`&ujZR|GIU7Z z4$0A`JB4+aLFvM}r;f`lOY4fPQ-;RRLiHBH>gt{I@~=>x`_IMibSK)h+Qyx1+$lnL znp&yuH09||Q>Hta?nKPUbSL4+g)85CaZPu^dZ*dxDBWpxZnD^rv5)mm51n7uL6&=q z^-krSH#eti@}d*fbwI6_UN3YoIrfDtc?!)*yo2nLn;zYCX4Xz#{GlXy>P1aX{8dk$ zHFn~J)Nh_$%@1UI-!8xPq7yo>m;cxaI&=9@viv>{Bl(DotK%ifYNub$k#qF(_eRL) z(zRNSo>({3Om4iM%Q|+(rZdkPXFAqhRQ`y)5i0bd@Q0F{Ud$=Fd{K_U=Ja)!e>u70 zzD^+hV!asY3YClQ{rdIk1A6Fk-j(c&q)&kU)P8h&?jHFaO3r;F7g6JtV!Inv{*&rH zt=4j~^yx+*eWH(>Ly6?wz2AP&uFoK;o91Hv?9b|U-b`Ne9UOmb+huPZWbY20p3d*C zWOroxCI4u*4?f)BLizMTyYt#7hZtK<{`edwZm*rHAo9gm0T|(EO<%@k^4yVh)ken9 zH--&E==&^sFCNcrf=1F0o&&t2@aF^1z|f=}Z3Er{F6~g}&PpQ}T-F^nQ1OxukvA_- z8@QB5)*Ys(Y)R*p2;T%Q=_~>7D10~Y3>{3;;e415E#Q(4pHIlROcW6OyMZ^*fcDb8 zT*FxJ*r3FCU1JC7xA7h~0dIjBI6hGh6;BUlJE5Z!r=}AAoz8z}^55C~cfqr!O#6OV zR+8jVl#{EU+mu`jsY`Y&x!`YP1tNY zz3Fo>F`G`c4~h)3(QG=R+g0DTTb|%>AsIzuyL3Xh*YXL6({VYd)721co6c;MO=o6daX!tj_JVDogC@G`&3*;Zf!h@YoZuHkU=IDDH+w@m@{ zdrQ7Cp34`unZl;iZs(1{{m}g>u<5w+Q~S~LW@KK5(5t_BI;#9-`i}lOzd`2dxb|=J zP+ZIDmI-)VR_l=*+-w$Mx@cPM@@VUOwd}>=bX*P}YqN;expf|U{X%*EQ2pvMbMSF5 zPA_k4`FQL)pXV`aHi3;~6Y$&FFy?14U&{BRMh8jJIKLZs2MyTupK>5_cBQ)foTshN z`hKUmC&@8n%z6Tk;mWlY9f5JbKV=GUBEmj}cYr^r@C*ux%vX{0TfjG?qY5s}W>Vn| zFo>>mUx7DOc%l0dg*WkX#}(cIz8m!;<;kR?Msyyep9&OOpu33lnDU$Q5c99 zP|s}7=Bkom#awKp`?`4)FOq;rPaGsCx3%*qB)%$smwsF~kK$X9|Gdko@JRmRE)gt# zKj@yw^4HCyNTFvAI*&r;4{bsJ;OgLSm=sIsUpJ590P62;{!5WxziY|9=Av}&>8Zu( zes%8S;3-^`jDP6&9DWlw4(-m;>Czd;y2hKE$(@gL8YiE7&TBj9eNUpZRCHbnAAhcF zIrrR^zf0#DOT6^+VlOApx~D-tr*q}H8GV!Us`2Y*waf44#YF>4WpCvY7V3jul{y$r z)!pxMzN*LnKJgPCH_&kz*O-hi@H794O)vBwA*_xLexB?P(Ljgcd+wvT>^ZkFWKXGA z=0_|`Hpt~m>PO}nw{x__WsY%*h9}`U*f3KZ*wB>fC33;XR$a z5S~CbR|sUwNS_^ly!Rmwue43%&yN{z&_7?>72eKKn$xOqq1&j=3H=J_0rDiNc;HTu z%XORK-Z|)~2LSXd%e<^oi7r)Y`_-#%PN>8mRF;`R{`1xBT>esyC3-G?Kj@8-<*$=v z4uF1x$}+bh|0_{A7EM?@ij`&B=&+gpQsmd~T6WfXlVygnN79p8M(LJiV$U@+S*F@} z{coTDM0ZsVr`TQ|+f9sWa&b+Tkv&Uxnk+L6Sw`(y5wgo9NlI-|%RFY6srJ-vdBp$r`C-?M zEJG7kO_o`cvdqqt$}&4WS!SonGJgLPzsWL%tw8HhW|t{i$f>i-ESM~FYGj$QXZ>`8 zD%WHg;emB_6wMRXy)3g}vJ8(&twFm?-Ffw;UB=&z1qagG7?bqi!ZlgOWEst~xn-RC zF{Zfl-)+83*?$A`Wwz+OL_>BN8)GVI$i9)0WoUAr*=5$GEK_%WbScYt2Sm@}fM}Ct zs{Pnx8Ixt!ge)@`cOJ9JGG+e_$TCrLf3NzcloIjg(d70Z8)GUdTljRpSnqb3IXhpL z=IgCRS%#S3N#_1i-8s2tZqmk>bYJCrlVwbn(L9^m#VNPT%*CCLYO)O1PH_cfne8!l znb-eVN(t1BF%>hp_}AwC7Ic>1w}?l%>t(*o94&MhMZ1jD+uB{nM9lAGvW$0t;v5c8 zG`mc-BbqE@vdr3$W#Y~&oSvLq=yy%F>=(f;Kg*kc?V9X>UBi9zv0v13a^4|M#NoAT zn%Dc9Z<(K-lZ<}q*4KpA;)K=<>vmRW=g{F~4X%_!+_f%4@R~nf3q3~%0&N5tLh4Je zg_ioMTMNzgHH>vaEQ|1(XPNJkp@F^>cmoZ`wa3zu5jaoCd+3=wrVEn?7dhFE^x2X1 zn~WduaK8<<6yD&#bRAQ8J4fkfME7aAUUl$P=mB?vT&}|m_u@2Au?+zIu5G?g?t7ow_+Nl|~V@L!7j`d!PO8F${zT966;=3q*1VlshLt>eK0kZUqQ(N}VrV1w+}zm8>s zz<%@|=ka8MayNOC3A7H7dHvh>YMy=pJ!H(6mpFXJKXjQ)P|!hsg?{3iOn^1Qb8-8n zuLYUla|bi3PLm0wO`A+0l&HGSPOw4t>s`k(L116oQYP^BshyiOJHe{YgD{z($|pn? z5Z7b^kqILAb6o>t2cJ6Fph`8FKw7rR1VV|b>tuorvXAOImI>y%=NXhTfwzzS9JWf$ zE7Haes_i+e-nu*amI+{Xg2GNhQ>ZJKjU5!^h#xzM+!u9qWdb^@UVrP|y_-+4So>E`yP$mfM z-&x88-qxLS*t#=sj3yJ5eUg1y_14{)OyEe7d+N@DGdn>+r+7O-*|sewS-NCOCR`gWk|&0aDvonZS`E_n1sDB$;47Zr{k6sfF2o_a`{&9jKh;wN|@7!MZv#KCu5m z)cy+5b0mpY)ZhIx?|u4Ueub8e?n>VEI1_nn+huQk|NWo)YEJO*&nnNi$V;(`zMbth2g2p(ul&W}L^Hw-t9hc*1EVg`g>B&0y7kC9?Ia6Oc-@5nE z;Z|C{P`&Y*b$yL%pyoa_-WUq{Gy-{z@4W4UO8mLpuS4o{8_|dHCOV+t+ktl!ej)G- z4Mf@xZL5-}(*iE(&`@ZOOUDqLV1mN6xG9m=%%RF_Q()JdSJGqNhopf?30EWk-M}A2 z7Owp{@t%Z;@SbJ2y>0(oLO=8Tvy*=o_{Y-*s4;oTc&m?+WFN}GWIMksdh(!$!<#?t zD7=9n5Iq|ru-Q0``tI?UsS%5JgQZ0Yxhl&__~Mb_;tF#g?xwJ^A*Su2QWLr>l(UKF88d^*+ba-nJ3B zMpRd++h3XVl9TBw-p0%G*mxPu&UBUA_uan#9sBoOo9x(s!-4(Dj(6N})1DpI@7cd6 z*>Uadx6}Qt#m#lM-hA^7w@`pvZry*wj#ppt#tU!XzvsHQRlD!NcdNbcv*{|;s*&%v zxTdRM?}quveV=FgA6Gd%Ue-aDdq;a*C3=raqSb23`dk$%eSch{X58jb^2x7oOs9ik zd|_;?)P4AQo_68Euh$GJILuBJEM)4?@~OxMm56ksW!qCFD~IwGdDkyv=zT+29liXt z*dL;m4#W3s@5t@p8)P4BseipjMP$k6(EGB?*d~`R!DD4i3D0qdVXxj!>9D=JgOAT) zxU}6^j?1}4t}T>?q`v5^ZQ9%UVt(4QO_w`pKZ<lL7AtGl`7|qF z89?(Z4y?oRw_Nit4(GnLe1j{5frUtrTDNamY=i7S&h^082*_fA{mMhK*o-HOl{=T4 zELOCWll`u?UCd;$Y7K}iBCg3|Vi$|t=X`2$y5IT6$Gwk5mRHAywTngVzZScO%FcGJ z_FY+nQ$@ovP)Jq^$vYuz*fJ37vAI2p3?LifT(*8?AgMQPj~ce!X&cd*?M_WFchO^C z4qVQYa&=xRqJe$bb6Lj=;fXoejC~pTu!AXEGqfzo>#vAm{*LH=sb2Le= zRCtPXN7b(M71gOz&`F#L@^IZ|0*H(6&jH-`Ygc+%r4l94Zo5XET}k3=y-cc8QmnHp z%^?3l?MgRBmcP!fbO7`l)UG7<-YfCKY*#v${$uS*ZFJa72nAQuuk5UG`?Jr?%=dk^ z>psu0T$E?S$}+xPrec5{6wJZl&dOvZ0rW$MPLI?tHyHp6c5( z;1+tC>j)d<`~|6p)v}XHd*!ia9{cV<7?6DR8ZN-TM0x<6P^-SRnMA)bBHt@p=Pf>3VD!d82qwo&!%^#(`v9{nNGpLSr4Eam{;N+e`|FJsO5d^$O2nScwuVg=Q=UteNqi zvHSI|W383F#knS^J)4f@HA(Glw^xronwQkD%>4VJ%N3He@M(8JcR63xBcF6ZS?1Gm z`I*Khw5Y9hbvuOk`F`M_e5)_C4zIm2aTwSVG~#bvhP(>SUDk5kVBja@|cb#)F|E2 z)3M^t4>BFAY$N5`tp4`ZSnoR4S~;tMYr=FauRR95ZPT$FRYWFr06eB+X^Is0v2=mi zypqT%9mm=r=YxrEWaC(6Qwr@-xI~W!9LEZrW7eOJ<(+jlFK3;Zj)nR%9V;h93UY{J zI#w>H2|1iQdOB9zd2FU*xh8@U6uuuV9V>R-MnDI(y%F1?_GA0FGgSs1|6$!p#|@=t zIu=udcBJW8s2J0+ zazdmahd8EVnT~bM4Y z&kJg5ZUy_!Nt|kII#%B7M)sUz+w%hT4+m_B*Ky?668(xFQ0|P}T)~}@=Ny}kRW_4u z9U@9cS?@Yl^f}Gl^f4W)T{a)nu{>Ik*L19I8Zd=S$EvmyxpO)eZBA_CSf*p0d|yEl za#pBgd8aY&l+&0^$3l;^ajcvWsW2$G6Xe>S7m6r!J9;`+-1*ElSI}!K-8#fb=vdJ@ zVmEzE$7+Y#kBwt7RZPd~rUBE%bS$Pq_vLgf+FaapEYqnou zr<{OpIu`n-=~y`-QpKuF$Fgy(VyR z@g&db$cIz)m@3`pn##e48ywu%QJ((76Hm@udX-M+uH;>hbI`GEm%X+3`9|e9N~?wR zqjbcZAK~o$eAq*ITm41ca-Bq{1a zoC)$U$ua@pejH5hA>8+S{?g?tUr8R-C%3idFG+mOYjym(^OwF8`OmwY3XjAWcZp!} z`$69yS^m27mu`dHI_UXJhmrqL6pr^=WxJ4w!&^~Ut`~G2Acd2GaBrxf-S1j5gxMXp zzC2AQ)AB0(#qa#=Z2n-{WcZSz-7=~#{rWW-p6J7u=0A0^w0w$-SV>|sd_f5(!_S%wKcX`H>_9U7tS7_I znhc-pc*hMl?b&htp8b209oOD|JKf(}++26-%{Sk0%l>4?Ew}E!VaKblc;kh)@85IX z+k_FV(0wk&XE9Cd_E}B3THd?>@iiZn_$I?w2`Tgw*JSv8Hx_pIIg{bXPEcPwl-$3M z+l-b`yX~l@U3IC;Pwck~&$3{U-d^~NdaEmitHeN2WY z`tYT{Jto5!bg3}|6%V~%C&SN~3_qeW{Mh??D@e_gJEC^@^B!r?%l9M0I~`%@GW=@V;b&-WLorC_))V+LJan8BRrB)L za`MrK(^~qp+w@2-*M403L#Gerw`w|$=7r<(UdqMLcm)l~w^c%x`v+Ab(v8*`*q*QB zavY7-+5L5TYfT4{vFI1@OX1@2SAE64uMWrW8@giY5~|-*c}C|>8f>@q3TN29Thxeo zE>i|ZkyRRs_76VeVh&yMIY0# zd`?=-rL7|2x%`95{-$FU)YbH>(?)?%RyX2%Djd^t)#N zy)_?P(QPC<+WI{oM?yCdIFb1BeUS$`e%+e=4YC?C>_hz z?0c=Gdz>bqqc~jz>qC~4=)Hl9ws{K1Y1~}CK>53Mh|hnWY2e-qbLMQlPoZNUn5&$=Dy$^lNY&_=FkH>H|3`6!` z!M=~nLu=D8QEm`f-e2a@C%bB!=Da&f6<1+wY4dz?Qxs$ z*5n44;pyWWe>S0$;i?=&;oW+VtrwlpvU#^1 z{+*xTKB2=^`$>M+Jx(!n8J_y%DHx})^(2AX?Ha%AmTHPvAzOAxV$ybc)&)YB)*0BY zuH$k%jn&!xb$YQn2+yquT{_>`_o&NP#tdxDewErX*J*(U^KJa%n zn348*A@B?hSa3SRF%RDYF8yfz&2?H>={fGy)JnC<&T%j7H#XO)%9qmWZ8AakHrGiJ zg>FY~uG4~@<8C@u5~X9k=@TjS5Yw@2JxP^sj#qEpo#|MP6ctabZf81Hg>3G|=~#A- zd#(eeN@vw;Qt%uoi znBzDc>q!_>*E%1^;c?%kU9HBtlSwq>ODKI_i#~}#UT2#qhfW4M@15F9m9)jOg0&Sv5HzCEEJe1l=&nG9M&=8%CT#&wJmm z@|EOKeR5lS-n+yXTarZ3@$1%(zZ?0_OGLO5U)&|a#qS6GbY%JK)}4GD^6jAKy+4Tj z2R-k79|#wH-upuAdG99cyLQqo%lfil?OBU!W$pN&vi@Utr$hpi^)=@(3^Y=U$ntAKt6Xr?XV7u!a*ZVy z2lb}I-T`A-9@y;q-LmrfvFjhdn`=?axOv4^f4X%cTc6VQNaX0_*1rs$KJE7EjSH1M zzj&u{@6~*-vrl?p$dsb>1J)Trm;TnV{awf9cp8&=^*T+R9_Op$a-6lUtAxsDXHT-N z9OEH#wvOd=jEAh1bu35Fsjr~+z~d+Tz_1*DDn~!&RyxOO&KpXZJI#CccGUPs6O4N^ zm@wZm59|P!aV5bs(5nR~N;LPc3Azc5yG*Wd&)x@A zzLF=ZTW)K|T_nDIUnGK#UpMaZE69J)ahJb}EPvg&%L4R|LC0MlL;lh~IJsxgzf4!! z3W9JoNfQT@JI4|58XqLTreDc^=A-ueGF{9gsFS7L9Ho&McR6}@gNR_dn5|>+`T}`t zSZ4lxsfG-XHE8{3myU#c&F@SXD+nXsN`G9-bTLmCBVoYy6gc&B)7GIbHosC`Y~Itw z=1mvNWmMC}svoqpdRx1vfazk2P`K5)%*N5hc1G!9(~C9-&b5qs{i`qc>UKYbD*XtS<|$$Mr5z<^P+5DG|YBeOvER^acIxsgtEeZuZ9oOx6#NL3v!p zd7Z3p=db6oyU32*-uT)^|Neei8&KBo=REaN*7pukUywu8iB=}-?@4xCd;9HlKFh7w z@7Yf`*WG&a%{Sb#KiP51t^04-@#-tyc;W5)_gwcjZd^mSo=a)4tf_4PSxwqnE;U)d zpdTGaRk>_!dqIx)we4}|qT3uRubGXgtpB-#84+RQ%lb34Ur^4R6Sp2EpbK@MSM$+_ z(^~qp+w@2-*M403{|{iW5B)9D-!OU2kj*<}%O2ED&oZ5k%Xw=| zWIrjFxEn=R3F%Tc$I6>yW#`W4x=@Oay9*s)wRNO*ILE4=bLxY83VTP^FUXPg$G~Wq z{7)0+L+(~ENXC6$lqtM{IQtad27XxKQqLWQH&Oq#-UWn%v)a0tt#_%?8_ke-QgPLd zyNuj=m&LgA?M)Z++LM!|H_UpMfUe3kJ zZrE#a($>4=I%Y!{ne9E0GpSUustLMhwK-F`t#?rb!L61*Hq3gL#VK3wGIoM=^h3%0 z`?#{54ubIs+VIZl7HACae!c5rtrpgcMCoETKN6x(vEHTC0&Uporq8<4#rPGJuIJOo z*1Ir)=#o!tao3-&U~}O5p98lzWjaO7er7Tbx^dRK&__C6M<|tnDNiw&vh!VN&f5() z?b%UGd$T!kcD_q!k_LUuVrBhxcfQNww8{D=>-(~7%^a-d|Fx7wx?J)1o7-!}S!ieT<)k*0xhqE2mJ++Iot7?6)Dt6kAV` ze^XNTWhp!pz(E~R{fm!UMd6LA@7TF z$UD7@&9SmMR@|m-+=Z#oeN|)`dR(`5di|}Zh^&JXe0M7J#K%Yrqs>~gYJ#$5)L z_1|z$N<=VO-_8#y`hu9#q-U6{Ur=Jz)>F*e+Ua4er(ivk)5)+Y7`I!#Xm}>aTfk)v zHa{DNtbY-u^K{BLH%60x(#xOmNldzP^Y%)qy~latiwO+?Oikv$Q~9sIjKVudd{NF3 zH(B3geQwhx>oXO)uk|MDze&A|F3sTTfBS`fd(XKv(Iu>wo_1+^E8`KFxV5 zuWnt)?E0SIp!;H-Z0NrEC1n$c10K@7kEzHml|Xc(Wpi6kQBWvE7n!%@(=b#YA*`-G z{j}I0s!JV)@7>yInzUkjua4x}>4DA#U-ZreU$k?<=_o+kC&}k8ChPmuDE<2Tym9RM zb}qQd`bm_m|Cz6+)FJwj^_?y;bXlKti(I3?p00lSHFIqGTRW}N_vurUzRlrb9RsGy zl5vtx)>rBK^=q;| z>RHRk!`W7L&TzXy+Zh<@T{9kStvuyH?94}Z<4rYnZC>)ZL(QL?_Y zn+(HFFgTqjG5+}y8SUt~6~=jGlJmGy~L+Z>*l`TEjs zHjJ##AL;(jKj8KvazFWPPgI-3Q{|*4>sRR^cNH>a-+gR3iC){v!K>x>=~H7@?r)BYO5ZPkP5SY3R08!I&?TJCfc%z|Er*#<4hJ0> z>%LaA{FHX(sF2@PcFND?6U*{X5 zy$-|o=h8pzl{qzO=LARD$+ z@2h;}0jf`K6JkFJV^U4>K;nyyL~tFShWYaNWCEyMe}MewD`*jxAxUS+^ZP-^Y8a`+ zldyI3*pH&%ua|&ub$q_p@6JItBma*h!r6p9jd6ZRm(ZWQAH$Ih_V1a`#S0h?0RHyE~->Oa=xO6P6`HJVIl>%pq~v z)%;;sO?o;Ur>FTZr>FB38Hk_xS13Ilm&1oX6(MZZWMDf#m-_GEYe1#`*RTv6c}}kP zHS}a)IU?6&;2pQzy8nh9ufF1q7v8>q&vkF}JNpX!&!xC5m+1bT)ugFqmotf+34!r%GlDb*$H9K&(jCV%fB&A&n#pphlBv)&# zqDp^F*nyAV&8;Lt2JV)zeLH#0oSU^Xf4tP8+HKUYPygC+gpWR)2Iy0?pLUxb$>r$d z(jPi~D8E%}pSmyTZ=}3tNL~)HZ!LfCk_42izoqL{2O0EznJzjmlSuR-f6k7by~Va^ zj3?On#H*r9Nk8Rr0M^x7Xq8+f@%g}3FUM|7Ozv!Dm6F-gS(cY<85+6?#N90l{2dhU0eo7!;_ ziLaB<@$1G(o{5O_E~mmH@x?9pg$hKsuhAJJh{Tf^b>k$*d0>OCLB~n1ME*}8Lr(6Q z^dCD;vK#ex0~f-(boop66nTEK>4=V+rHt>!0itAln=8a5B*veQuQ*-M%@sO&cY~fg z9N{>Qx||N==s$EFi2BQ_=|E-saXMU7`!OA{+72L^R6vLg6%3+=!*)4e)gvN4?%Y3fJj~c0M!7cf%iVlYTk^I^uxmHftTRJiU2pQciECIewlFXF6grHpjf) zbi^t@ORKlZ1l^mCsE9(hqo*TAp6hIL>0DzeWqhZjM9KIgtRn{K<8(o%Bc6ANN$haw zh*9ILe)=n352NiV%G~DK!KmvfVz+k$fhShi3ehiw)zM$)8`2MT7`}JwN$i~D70LEe z|7&s-m%HRT)p{a zGBA@t#yg_cllU@f?KsKb984))lYyDKe64jmy~sdCY0KYrBLmOdency=Z%h5JVHvo` zIl*&$Ht;$m+jT95+|U&Szeg z@q`hYE7Z?9&!n|2vg$T9ng9ChNqlXtJowq>3KbpK){_);$iT;JJqZW_N5=ofT_Rlk ze#p_AD-?HrwCRXtD={6BX+hFt{JvXJ<0PLt*r0SxM=a>ty?3##C*gKiUZHtKrXzOi zc_M30E;{9g#^9qa(Ij_4}?lUC^y3 zx%m-J*Ws1*B&`-dD=+HD{+(xcYWb%k`i z5H{WwGYrJa_HI3io#VYKvc2CfhOyrluQ})azFKHR9el(i&L@dHue)4NQXbV!Uq+it zck9hJ-*C(R#OBg*)3dpBRlZxd@7B6oPcjvE9{0@D>};A}@n`fcdmDIWIr(gF<~kWq zbTesXO2+f|m8y~P*5Vm`{mH+JYC+)8D5Ew6LFp-bnx((;Am{}488o#1?WIX<(HCg&utzT}dN((P}& z_KsWj-;vJknB6gX;rt!>-P8|F&F`3;-7z)!lHx%+JvlW$IX}r;VD`M2x1E`M?L;Wh zrr>M^o~N#Bp@_XH-wCFg5})72>tf`R`g#`d1|EoP{v6`NY^l*6dM;(PX5MeV4%;|8DHt

4?Q!5!tLBYIGaCIG; z-plkVG}qSjezr@ZVAJ%f=I(>`m(Mx9)YQp`9y1YKr;p{Gb?C9bkkRxw-q8NdrcmGj z7D`LNn|Tv~{+fn{r8T{#;rhgFaEwK$ACT9#q~ZdHyuK|s=nxs2T!c$~gV9Gf#n}(#cY@Ka`B03T8kg>aKDY6Qg~*48?&Hr)RT(}M?JZ!aMY7=VJ)YJ zdRd( zcpXw|Qxey_8%GuwQ5JE{%asCW;YQ<{ca^NEyKBf?CKT7aFWL?)|GANC-tO7qS6&gB zTajS3<9{@MN5LBSI#c(j8b7927d z^lN`ZaL7(je;*ed;w{i;S(QzXtbu_OOnq3mw)G+-J5F?1M%EVkCxlO*6TBg7-@M;1 ziL)l%IR`5SvnMz0N35(2%&M0etnh5IETo(Cg=ZHfA3UDDo&I6QWwFh;-{w<=XA)pm z;fV~8XBFNN{DQ(!Z#xR_NWI-GYkH&y_4c5`QExMaqu#!%aMasN3P-(#ECKPN-tL!9 z9ysdl35BEHo>MsLZCl|jDUV^5*-d$81h{G?Qor!nMiy>cDFAt1+~O?fxIoBoadOp> z>XdKyvrL~czfP0W%&B-8VdSd?7ZtDDw(gJll! z9E)an(Y>7h;T@+ohGkYOdycJk{}5$vt}cA#8;~E;M8TdLTfgU^UMg1q+@@ z%5>2F@-=Cml5o5-h0A^UYv>##i%uV}{X_ZC^dKYfX|Y|?<9KCxRPY+g$L@j;=g{)60qb^^n^06t9<`5K0bI9M@2=rxSgI00PbMc#bN97sGWUuGB-cR9t85zp+ zy9Hm6g5-9`#;xfHlnMi!>y(uxDg1i{Zwrok@Dafisi3Im9~C@P_+JyeBRJ?hB6unV z&-IqgC+MHkW2E9BUxx&53l2IzDtIC?1>gizR>QTb7g^X*qQkPVOz0=Vk4*3dX}prX zze`^U(poFr^s($Dpq+Yroo50|XjSC)JInC0^>EPs`rYO+;#~QPwr2=hJGhWuvSMZN@u) zM0b)_)19z*evM^;G%8vd!_B|5wbo@_%Sr!R&sNLoHe8`XvFGCYyct`4A`XqxJ_G5m zeSYuv{$SJfWR2bPdlMAZ_3!akr?xDMuHFAeS)wcIC`&BQFIjdGTG{J)=yLt#YkF4{ z_BRwSuS0F%nM?Ju~!9*$)+Uxy7KU4S*2;LDK zbZ~AEvZt5HADbVhe_tjF9Onihd*b%M=5hLG|2Sub`u{1x6IsL~-s6I23MZKQm~buZ zMTYumqQf%Oj?lj%{F@j2q8tbob_8UoqB`=%oF{a0)sie#v_tx`R8bOnMe@Pz;x_t+ z*{WrQ@?u8encyvjCn6k~S9nM8^9o0OzO3+kV35v?gEPxp!uJCTZwr1(;i%7$af1%( z^F`$!^?6)mSMZPeJgacXQgN;d{!yPh%0KFJL+T6sqdp&0IO_AT%3gm*_#xHJB(TVH z8$G$rrQ*ipl$?`;UM8+y+;vK|&t-pi3ntYE!Oa^gE{bq@`KIceA;NF*J(FFBuadpK zQ{tbl2oE~@0yH_uftu;BI%l|D|)zU&oZY9o%a*CCa?MtxW%&6iQOdIxD*mAkK=zAD#4 z4YNM1fNbw@&AYjWZ~M*7VcA|;D%tyOT?`&&+1^aeySX!C|FHJm-0FL_<@g7Bw^omp z6;p!J`1=g;C+Z_}^GZ||JVPrYluAW{f5@B`1V{UT%*ig`C@$3V`z79%2vdMV=F}D(bRcs|q~LL0 z12U(!;HamNIi*seK!>8GHXxqa;hA1!MUPWBmK7}s{Y3KpjNomNbyUlWrU!lZv?Ljt zF5fqu#(mRQCEYxJus$c4OCBy+vahZwJd*%8H^y|>e^D5!cp&93P-)0S2*h3Wrd^O870F)z1yyE)VpDo>HL=PL#l~MV3FrG zdWK{=<1&!VNsHu~56=W>xIN4Bn+7g^pA$Br zSx|EB3wWH}{o*?tlT*9JfBo}xm%O@=+EhfDPL%0T#kS{=UdwEiSeN?VC}+08<@(Y{ zhkBl0$-gJlVMfrmqJR5W60+b<7=wm&v6swp*8Fe(&0FG{f0;VkbzfSw_S5|{&rR3j znqP*ZydFN3+lm&Q-}Sz><#PAWQ_xwNxV9yp3~FtQH73@!9jRc)q}pL^i?zf9UUeMA z8k5(^R=<%fA~#DzI4JlJDBp&{QNF{vmiryyhZL7d zV3FrGdUBDc;>H8#L#_(Y>ssy&vi1i(Jf#}IS$Q`K;r+VFfpqw)wcI-;{(jeT2WqCj zYAuIzF8!|M5dTHVFfWHVuDWYE+*v%qO!JK9-#yJ;vfu75M=iCMYtBscyg#3}K}ttz z)3Q3&a)G&UZ9PO!{dN!E%X-2D&#&vUSngcV@2{E7JZF^d({dd@s!IS|dWOQ5JQ2YD z{JG4`I-ScfKVb$jM@Wbm&k@k6T@>P^lhfj8`!Xa4&MeLp<_M+Xf2KVA&p?Pwao}5c zTo3*3t|1kZAAX%WsPK&5TQj8Jg8Uuf2iTCnBF}B~42`XAVd{SI*Ynsab0ZZUs!KI!C_a@`FAdQ)zBI@_1n_tyRZGE|O2i+uJD8$xv_~QYi zFVnwQ1#^#so?|dQe~v-({-KnYFoOp%_jo_ivG*mU)51EB=57|hBo(51?y;vZ_n-?7 zfy)eg$`g=1ZUS;e;^hbWU9y_35-;O^U7JyO#-7Qv6plW9Sl9c%FZ^)aF(!dUp4;dd znv-;-pj+av*Ez}C{K66%{NQr*P1T$P;rpGF+#&JzJ103>iBDLvR#dDGoy|eYS8Q-T4eZN0LWevj?_r%Yj^zdJ7@7!Q@z_Qd_L2gS=K<*;&WgL&IpcjQUXYjKgR^pv2;uvk zGd?Ww_d92tubKX;Ib%oo*YBJW@y`mwxDD}`RCmsZ?=JsH&S_`S{J&>n!k;ECd55z( z-4Orvd?+74$U1hI}e{cN$%s$@%ZthM~@sM566zr9ohNdLyzn@Id|ysCncWc zKAg_zVjh@gT0vO1m%GRxV}-nuJEea%?^6L1i*|puk(J9P?LyXeZPWoYhqR{GvF8aD zuaL26g`J;O@(P6SckFpu;_r9td9`NxtHz$~QXu_~J&1p^q=UyEE`z#b&v_}o2bjs8 z(b>9ZVydUJ=5g$C`~IP`qJBT*vAkprtu0HQ2+(8CL>zkxY+C-E}odmJa09($&HI~y0*J@(AmN{l`00KI?a?Z@3K3k#`1eSB||L6yMIQP$Dv(5BLoA;Uz=E@H!MOwzOT$!?#K?O5S zpzekpfR{;hr@c8~#%eeP5$Jn#>ZANIc>ILZ%ti|Ca#D1Xv5ZvAJ1 z!~gdP-VvP37iJK1=@_FY z+O+SR1MzR_=u${FdCO zv*_?ucQs#-`1{=pxmYv(ReK?A*|g|)F9h*Jmo<-VTj{^*EdyhsJj!({chQ6UV?8HM-RrmyFMPlQ zV;7$L=mqTX!%ysk`xx7`->R`^&FsTZPWE;NEb0lkWAsjwMm+)Dmci3BZ(Te=`;zN& zT|DS@XhMABbtpQOi^9^{dIBbj=eG3#N(E7dy35R{CqVd(hwj^#8e5~D0C3Jd!9P5! z#?}K=ncjuOG@HCI*RzJghWs-Iras!mm^_YD>;k%}H=iAK~ysIJm3kB-k_RcTR%%Z@8X-$=yAjeVl6I zj#&NkCkMU3D7B1R9p_JEl%^ErI=G|mq5My?ey6~JTG@EL)|IHtL zjf!!C{#ol%63~zS1iiaR*Cu&mjjvC-r*%~Q(D@zG0N3w2?kcy&G=C?-F5>GVBXkq=Fe{e_IC$MLdUMVnAQNKbyrXnHS`k5GOGz1HM8 zp1; ziBuHSxBDgDOyT%GT}N=x`9blIxjEM#m_e+e`8#)3elHd9RpG~v3I3`qY$aJ`J--wA zJ;3f7nry)nWet0xtZ9F*f4XdXCY(ch~>{lWPvj> zXW{z72G4z--M)~Y24^^65Du@ZWC~X43wi2Srhxb%Q{%Ci&xM1nOX(g=rTjjJgvwK= z|DMS`J>6-E=hs&3{MtmkPg$(Y%Raw0QF)(|cwO3lkM}8y>|auz9ref*8HT;{~q3Q9u zHRMm0Uy5qk846qW<#d7ha*y?TzilbG2lHkS@`3jgo#pMZ`}fSM_SnnU%O&I5xgGe zC2rmIaBW@uQ&T;ish^r`_NW*F=KJL+qDk3R09FD~+)lB=h+ zzBNHQQ1safxIyPR^YVkX6I}9VrFEbL_V6F8dG7eJKm5tD>+RupPZ>KdY&7HGlLP2% z3rtXd3BSY`4v$r9o_tRW9_jfe&kn1eL-E>($6alxBnt*}^a4l@O|NQgr0M;vCM0f6 zkM}G?>!m^a3-K=$ug=EC<`7a2L`iwn)yOBtAQ7`W& zJIC9S1_K;>{%yfQ2YddBRDRS)-m7Oi3xfOo%OKYJe}m}rT0fPF2|eZ~1fP+;z`Wg; zwgz@VC-8F40#Mjy;2eGkax#Mbl3woj-$MT|=RDkRlWm1(65xu$6B$UhiVh5RGM$d# z_?8&(OzKZd`xks(;iy-a6^?p^MIGp)UTv4f9&psF0}4mII;C*btBVRpy&Bdt0v}d; z-HFr-JhqXA>wXGAo+o5rIKTx$rq?q9Kd$0+RLb+1CcWS&q&mTyLHI2>;w+M!9IeuE z^YD*^AJm~Br7upgrsp4a617I|o7h+l4Va#=o8ZrF!S;?Kqi! zKR`}vuE-gIc>wa%dA(<9x+i`A@!mn)r>VP76IfHndk0>7jQ0*aW(2J9-a&vV9u$yS z#Cr!GfBdzC2badnm+57lHTg?E5zns2UtUv%=ndLmzGm^#5{g&Ptse0F`&OMkUenc~ zhqa$ii|v{o#~YGWgz~YP?;X&bGRh#REYThygIJJ?2AKk65U2>iA%kd11py8jL|bsw zQ^+6^sVJy#_fs0I>_g#@L39KM9mpV3snjo1c$h)R8kT?WV0sX;hLQwhx_sVo+EX_a z?;S`ziT4g%Yq*OZyiU~pcj{i7c<(?MArGvn@!Ur^?7mN&`}Z-nYrj=8g*9{UU}~l} zT?V@+<(@))T?TD$Q!BL$jprHsri61X)bCrv^^^^t zM`4*&TX0`SJqQ`p<3yj&yWqUWeyQNx|1$on2w?N}QIZzz9)t|aop<5ifbeN|Sst|; z@~Bzw+z6ljf;sEqew)3Z@Js@96rRYywOO4H=?LCX_=3nX4=Nl&kxbz&Nz^5Uw*|kZ zaL6(fIcLDhV6T}J%zlMKmU&L$kY!#`IO^SulsD+3-VN({n6C;yq?(un7I|)?Cl^5~ z?)`hrWiWqO5zyh;ElscB6Y;0=lCyIg{cHYnxoF-q zp%XGu{b_c1M#q28u0~HfGo~85dX`;{dz0qWrX|X*hE#U-L`^-MPyFQ@d(gwVUFqSh zUX>Q~Z?1LO(Tz@j;5<{*v-zUenUYoM2_5tuA)Y$>dSDONyrXmYw%^pvTuXXz*$=UGyzAn=d#EDM5jePM(1EOwzm z?nfDG_cw4dt1dj78ZNWk32gQFPm4@pN%phb5IM31+`dW|XtW3ToSphwoGlP&N zlq3{0W%@wkW3KBkS0x{e`)zq#8W`|Q0;CF0q=TPTct`NF3eTjTTu?ab zPeazWaMYhn;ix~aDjfCan!-_khE*o;6c&+E?uk6{*hZF+OkiHt#L!#O zt4u(jqd|O9o#3pL2_XEI+^4hX@KrK_UzL1MSA++hee@o7-|JPyH@wq+t7HOgxntC? zOaSrst4Gr+8KFdf4hfg1PX9f-CVJ9kHrbev^Dp(!vuqXl9Va2R>4-9cC=;LoWZmlx zp~`L>T>kBs@x6<$Wwr^>T*&2rku07WnK!@vD+vLWdK7Zcf&KK_YsR<#<}Go}m~+xu zFh^E!VLrw0s@9Cff^_~gEq43!Gj`vswGqpe{k0K|opEhMJVCiHcWpH2H44vdtS&#P zFlS}({LWX@l`M#;Z(fBpOYrB%qD@+xFccNKC)(!v`SN^dEIj?Z6K`tvCYY+$=KtDyIcAosq(YZs1X-zQqw0q9NHh1LIoZ0#G zk*5yreB#jDA+z)F$&=(h?i`OFKYH}YG4gQi_}r154?gtBj+1kT9)HqhXW7537n;*5 zOQ)P(n%jyN_UoIw$br22cq)!LsV{h!z#`9W^ki11;>H7Os4~~PCxD+uDFgty?#f!4CoZmf{{L?$tJD9kgR4LN zzcyK&{=Mf`fBJv?f2dCXXU125`WOHE>h%A`8c6^3`p?D1o5O!Sm#^BV#}XL5?=xhH zcURoH7d*i;wCvMs(+A*LJvE;nrT2B{vA>Yf^f+E#2WlgtkOI7;;BpR4?`48R=?l>d z#k(AOZyRv>whx%zfdSK77%;t5H-4hOobouRD|rRIP(9GHt3XyQ6sl_>zwaf`lUYwT zhE!(lWP78zF4LEUS$rm+C(a8}W;mZi6LX8BA^@Keyd@Rn|7Y+0qwF}Y^S}ncA7hDR zK#C&AGGq0CA`Q_bF!Sa&VpDx!l0qbf0lAipwUO0;1Sv=YNrZ%GNRg8#*%lGS&O)?~ zjA&_RfQ1;WN%>$C9WU&oKPHyt%z8~PSCM?+Sn_$v`kWv>+Os%oTgG}FV(+c~zJB#? zSI>06_hv9NuM3#h)wio|Raf1ruKU%kD$?%exmUMe{*+G8lk~?xUw}Z7eh75hg^>O<=m|hE(vOlq=AcRc1o<0!6Z9s8 zo8g5lMH!abEfI`PG?3@E@TEN3XTU`ta5?@HLEMvH9`Q)b40TPvxC; zNAngR)9Wu)Qvb9I@1l;mxD6M#;g0x~GkhhCoFJ&b?&P1wr1R&OIY~3j=c_$IAbH<| z_tUP4_@utl5s&WoQ6~+(se#2U7QPFLD=VoX65W8+rm4i~>bZl`MGZx_M{keb=_@vrL5L>R0p4cUj($w2&&yv3e+`8TX`g<7 znI#hNgyIH*IStpxTLeeg5Z}nuwo1+t!b@wp)Ai%q84EMj>)9DCg84Y;ix7~k`Q*Nk z4SqXC{m!4SJKo5DKpXskN*Y7puNNPU81?ABOzkuDro?k@K)erM)xiZ>yXob7xe4TRpkbZ?OMum2X4+ZS~4Wy&=pz7J6^r z*72pkt>gJ`>v;WbjS?yMkh6W`-4aM?{`f-UCHf<-{|{S2d5e%pMS z`fb?t|7{(wwgz=_s2LmO|I`1_-z%T~wcqZ4`Uh?-pZ*PZ^gsO{|Hbm@55Ls^^#4wU z^v6~p{Tseq{{81Z8Ge7;mt*?Z^-%tg{kHas8-@6VFru>IGF-#UG<7hKlp7=HdxX*r z@e55M_L9HY&lvo@@Jss4uh|2?e&d2V#_)9)*%xR->n^dpud_=+10`N~7wAnxzlY&B zi$@&8?-alCX&SneU&$MEU=yM#A%yRQ<%Yg+xlFCP>>s$(_L@VFn+KG3%VRLt6C z4!@k}(6I!>bjCwdYC+`8jsgZtc^-L1Y$8>}{58Qo)@9cOYk8=nU6odo7G+cZoI__r zx>SO5+YO!dd(65@IfgSUnI6*0aqn;OZ+FS4)s1k#_%Qc69H&+G00PYrpl zWd4hE#S03Wit84KW%``wP0O)0@L{oXe~(Tjt~!S33L&=#r(^@V#_$%g{|H zq`BBR*mTFz-f|h#yqW9v)yi70V{v>EvIJhte4QSA>NDaQ@p&Sc(fd87Q-1!KZgPW; z=~(WuyswVMVpO!2GhIK%P-8lOH2Z zremawNLMfHcQu`@NLT5;tj!pDQv-{eGjx{MppHqtiSkHGCyHWva2=6rXiU;VMb9Bz z)iKGfer17&UbG&4HzqeqGuez7zuPg%Hl*L}m}Fnc{1=T$XcOPjdg5a#&5Xa4%Kh@ohjhwH6P2O<35y^jsUn(b;}<+Ngp{-co^$L$2>Zw znunlh`P21dOr^M*j-5Cr8Aduk3i>e!0J`e@KHcL*=g#K_R)J-1?W5!md1E4|s_r#U zcywPDxz0qhtMsM|E$h^5c)ZULA~QV8b5O@zpY#h;$}UFv@iHPFt@DHgT+gBbAH#js zG1pg3x@3=P;%y-g#Q5Egxqc7ncRS{Cg_7m6?XmeU8gs?yD7zhVG5x(rP{&-lWU}m- zYcJ~W{q3wfpUwZy>CsBI?llf1_INc86tKWBf+n|C)_NWDpv%t^;Gwkthw*9Zw_%IMB8DBhZ+rzW$E$#ae!e{>blI zuw$%on3ct00ytawxwVNU=GG2I_1v1YBHQP$*4WG9NHSNnA#o&*d1EQ-&>WnOnUvnb zM?uSElS88&tY4i9Kmm?J;zg=b++9#ADLZk#eI4*AcmDohP{GVOgHH0jy&SUdmG-jLY5l3SB-Qq|mP=CwgNE6l8p3GKXd$NE% z!?XYsSBmwRZ4k~pSnp%DUh@Ax94;Pn%37dR8FTiM|9|oA;{3~6qBWoYFMPE)|FRZo z&FBBbCyVnhYnj%3{(tUwit~T_H&-YB_FKKyaBMq7IwRjke74X8P=CHaY}#v`Rmw!=SDosb&L#r78|hpNGzUQ-ooj(& z2omXB3)C`nt_7M$V_|qryC1spgTlwzTtIO4;XU?&&hyNWt$@u%$#Vx~Y0wxqFV3ma z`7;Q|aR#Bkmd4kQ>>1@+9_omhYJaFj-;_UfExaG;F*?j4tfe5m1$yr6a+Zq;&-%4z zl(T+$o?gZu1-S>E5b3Pnfz{njryRRlYyXUhSBoxblbr7u_Kc?ebyXXXzcJ~OJ;Z>w zg*G6J@5`n}vhj=70=)^qP}jP<4=iQ5&8J_ayB~tS+N}*pg7mvx3p9lKJL2U%RDL_B zrz@=mnjD{moo;!%+wHfsGm$uNt-IH{`{tXsU3p{tfe&QBU+eByxBS=@)#x{jOZ>;0uOqAdi#wfe!npGu*8Yc8cTFVt#YpJYGH|r0V;;c zd3@$a_eoZI41pp25zt$P{u7|jqw`^SA@>EV{0G9vVU@rfE}}zI>_F*z@Zq>d6I5q$ z#tEFK=8ipcr=Iz%?**X@>|3O`r8_Kb%*7gW(Z(hNyaS|kt^Oh8SHE)}#1NhE=ziaP z-q4%+F5+5-9^=C~qziAv>8c;EC`#tq$*>R)m?3@fnvbXb<=#|&fTz=*|b4nfFbp;Qzi-+NE((o@t z-*J7zyWYsvVHPL#tatu_`rEoI;d@KRbmfic)G6Ml@BGSZ&FD+-HU&{|tL1a*R7d&8 zyRKM%o#lV()C`JdT!<&9>Vfizz)zwDKdKG^h`X!oy1 z%{QM;f3w{*q^A?f=7{z2?!+Jt?^l@7J~^+TL+; z*0n)IH_cYz?riSGysQ^|vi&BXg~sPGyH}6>jy^9m3~xKaNy&G(7d!6SH^*bDf?j3n4^Bxa%#Ax5x{Am*{!_PJ4Hk-_6`Dwak>h0-_L#M|x z$L@S!?rgd$2ch@qHzuM-&H9*#jG=4$Dk&4Tn|s8s7(^2dOWTP$+E=v{uw54@w#i6G4L^otVf1=;ZSV!p9IA%43F!fbRD%{jlF6CXzrfxrT_C z$P6%ptlj4@k?b5-K|1=4iR4d$oxn-3dyrr4_ivFux|1H=Z<7m#-b93ph92WXvK1JD z-YTCK=re{+xtcR{%GGg0r(9hybjlT#I;Kmx+74xp^f^?>UPGr`9W!*w)uN%#vy&Ro zJ*0mG@(po_VtQ~Lk*gMUf_q+$;KR@@Ch|#>F8ONx`cC?D=|}SWH8TE9eqe<4Nkw*J zpGEppeqb*?^Re5b`9T*-=3k)?za5gt0tRT0l7K7IB{}r&`i$v!i-}wW#(10w;cC<0 zIWtyi@1Th;&Knx`2B3+{M~#W(^y!0AFpH=pTmm{t`E~AVU=QiGj+*JDH72r-Fqc66 z)tJbs&Nft`Cvw8axn9V`?q}P~DCg@NhvwP~E837(U4pQBc z!*4%qzr$s^o0mu^UHcvndEtGp&7bPFW%yAC_Iat_^3!zJ5@uubw_4cFtx^s?w$rGw z9Tk@ikL@TXqu3EK8I?D>eqcV23p2OpAh3@Z0{%ScY53>%!b&H#cUFkv&ClS zL7z9+46z@J*%14=WWp2s8HR4o{1f}}?T9qVd34&=j)-zMsCF{fn2%2^W#zjOxd~xH z`+#X2(t;PK)u7*0R8zE^oy-F!UFD$;?9v#b4{yS%QPFU=mzpya%r@vDZDReYBI)fnP z*AfnEA;Bf?T4O>rCM1IG>@41BrlP^Mg_~r|jKt z84Rq()WY>qgsItjs}e4xjsWuTYAx&y)nzE8>K8snH(q0Ou9%2{-y?TA9%w=*({`tB zz1v?EVRVnnyXpJ3AZWzyJ`8#jc0Z(RS@Z+bdq(&urWZrmJ%WbwY0yu=-XZI^a+uzD zzcD>U_NF8KoymiF;{g)!JuMR-JJYo;bQU`!-C}1=Jh0eVj1Q#6&RU>b?2K}o7)-4N zdA68Zf^xTO@a92p89v1L>>4~`e0B{UF}{81+%((Dni$_%Lnp>(*X9x9yKKT!Zta>q z%I%t%zMVKJt16s=> z+4x0vV*d&0cZ&%Q7Z_06^b0XTtUY`*%X#Xt@%0`}vLhtZKZ1uU?ux_O^4EGn6YYq9 z90kYk86Vp8cg{>!+8eya1nV>AqQccIlrmiNYnN&}vD!{76OwxETvil8k6<>KM61`% zMQ@MZnN38Zw0gm`{%{rS#CpkJjS1%Gk84aY6?{A1t1-c}T1*!=IDq1|6eJHd%5 ztTiofCwTIfb|w<%t?dMBJ3$%y)OLc>8oaf4Yiz%++D@>x6O^I9L-w(sS8XSVPnqn) zM^`vQQe%QFB2g5FJNIuZQ+_Mm|7h-3a_zSrYt@)$Di2myQLH3{B$N%8*$buY-EWAW zj5s>nLmhYR8=J0TEM@o+t7&seeU_i58^ZW({)pvRej5eTwC`KCK8nikI$KZ$_o2EB z1yvgi-)?fU#z`(p8!|tuNmd z*=aKVO@3hU+xSIxn*R^dpDKt?KDz@vHOlsa0W{;0Z4oA$0Ec{(0dckQ^`1@J56blC z@lc!J+vLxdzt)Q_d*!nTJKI8YiOWlk$qpzcd${Bo z2Zz7+?FwfcjAFm^h6vYQQJ>;~{(n%OEk-=!fLAAtML+BPjDnTU|4L&fwH;@XWTx~0 z=2v>Z&)bh(yVMy3y`3adh*EaGkNp-Ed~$Q&x95dT=zK!^9i`6HnQH!fc}4<+^mNPb zv}J^Q`~B?|V=Bup)2Y0Cm3a^9hF&!1wdt-F78QDrX`4B@xA`low|-+YI>z&{85vU! zr2X1mQVxnSP)B8ZxCeBORaO4gaZM{Lj&!mAbA0Adp``Onfd$Yhr#w?2hM=fis(VoW zoV}Q#zZdit=;ZSV=m{E$$`4&Xun;|)K(P=S*qlWN@)6L_V(^Y^1c^VX9KsUV zPHxJBIHDmm810W$*6Bt)y5IKp8F~{DnuZ>ugFkENl%LlPo$_YfugNiAap>QFonNH`qKY*IL7C7w>+ia4>$@;&!?&1hAqMrM0;_r zTTFrJZ$-bPn8K~{$71Dvd_|Z-g8KV(nvLw&=6~mGquLn(6BCs&g_B+-CN3v6rch%F zBG|=tUNxqWwb`V&?~QXmd}8ltEfY2-wtbCVG6xqB5yfSjEQWyD5c`g zYmBaYTT|skta;iylo5FhSsopfz>A_249NsyV7008YCHQatuc|bY<&GgDXKGuu#QZ( zN~5{oP&f>MvQQ6YzD|!#cfDdFp>n|#QO670_dO#|L*)k*ts`#eCKNXmPWLVMF&4pp zYK%q73(1@YKRiBD4EVL z;+swpm_-lkxP=8G*GnGVZ*W1^Nj?pGSvy-q0Q3A!)P>eGZu# zh4QFum9zl*K0_z=(lm5pFT}>khuF(y6Q0=19_Z2xPq`XYOy;WwTZpADd^aLDD*K5~ z6#pgINpyQ|BRDi19sj-aWJNi!hltDTpDiTTCWF{FF=k*QQ^D z$t1{lx0npm@AllrL#V&w?W{YW&Hv8XiK%qeUAeV)Qxl_=F`4AHb|w<%tudJzlaUs` z1Sa$A_jF1UW{o-7rhjw z!B!T)G|{EOf>G29CLH4T{T^?6eLPEPRq}TqnRwS;_`TobLvJtqzCFo)to@UfaLA$K}u2a{_B7{llOqLmDdW zFZBA1{JA*=V2}*|G0+zb{U3qe1m?%^LY6iao~f#`zu>2YkJ^9IPU^xn$~lTYFMmoO z#+o{i1NNUY{hNa*vq&~K2NF1#WTtH?x(D`O+9lCeOyBQ_NB8@tlZM{Zz~UARJw_jQ z(a>9xr$+6#|+Q*aLCY`Xb<>fFg4XqPIR>SFiX z{uvRkw%Mdja=sxoo)kwp)nZrCL^qYSk$XY&+lG*${U%+dsndG&UD4bL<3lX6C^ml4 z+{s6fez$Wc^Ck0NGpBf#Ado{gezqb5# z&Q4W3%VdiC9G2g=@CfpvnMhnt>baA8?nDH8iMf-ne6NeSlY=5$i}l=zYhvoslP@_YIXx$P}#?eo#-dys4)belnq+bG`7}o8y+x--{BapXFD? zuix0V>Y+ZiEjoCOZA+P)MxEE#c3Kc0mWvKhiRGz$sw1}D0+>O%KI;cotr)pt(oJB6 zGw6_xgMJ<#x~!kdVa2m6k5%W>%-hk=ruekKzoKV`8rl67wfxlO_E${F*=D)=-PgV? z#sI+Xuh;^8FFI|8pT~#H?z_m2cix1bLkF7MUlH`&{)(s&&M`1uV$*itMPk!-f5ily zs@+GC*z`Vwi4&VXYv{zLFB>}Ld5^)qDbIt7HGkC%AY;lMt|M~QDo$|E%OM3(#hruP zRmGbB#-y8aD~~lZez#cjn-H;EteJN9%r~zn4&J)`OYE3L9}WXweKZT1dTe~Xw_{Na z$@Guop*CZ+Z77R1F9Iu{mpHz&>F=DKh24EQJN=32iOOf>aBoP>N8&P5W6d?zEP}lR z*8II&yTFAMan{TX1a`L=V#SfLcoQdl!vSpaK}4$2q)gpBD* z?L82{;!5xRaLZzG{+Gd;S2F*lvBYoOSd1k~`M0se9&&5H^#wyRstQ@dcwT(QN_wSJB~dg0YdK!m9Qf^)XWZAFZ{}2i7yu9uix03nvHna+T`d4 z$JR#VeH9}j7NK&W?uX=0>BJ&VJ8Bf&2l_l3f@1UP#^q1Lvx6Z$wGY}H5sM(5`))2k zaM+F>1fLj!rx?7t_sXC0Cl*2aBcKzDARq1tK`esrMf*@<5u`s3KExta-st*)i76JR znAjZb?e^fkKMDF-G%CDy-hOj(G{wZG^(>P<9%Ev0Fp>B?scom}@A=@F6-9Q>2bP`P z^P!0cEtG?Px3nl?e87gF^pf5J-R=cJ`LlaLQ2v^R59RN5L#O=Ny&x!mF)&Q#hw^9l zh@kwPG~p?K7Y&{AH)Ak6%HN=3Sg)FoOALA8WkfvMMiLTm9Rdb)2=b!EtzDGGQ0@f{ z%@47o=({FeJ^(x37VrOw_{c^U-o`Jom;7tQ?-s)vg?)3DFg!N>B74aru-kpqFtG9U z9$kM&NT#3Qp}x*-@@LCm>&2G6GCG0*>*w{xb2j~*W20mKp&~w@mHN})DL_|~qvHr( z-d^&eXM38sywn(0jbVvkFNI;%XNsWJcJ6Qa%4;t~-*Ii5_IhbB@7z?xtL-JzHbyzC z?IlGpWXQjH+vYo?r`N)nBE4W(YhnM-K>o{PSl{XohPBjgrM=|u5B{&>{B_vtDHx*j z1_g-bQu(uEks4!5yKXz4Qysr7mJ|wS$CuRU)709(HeJO8%J3t0(B_o-EI&;*q!wg4 zy2n7p$~wzWv4&9oLi|GM_QJ0hjIG=JDTWey-|K8a72Jp7hJxNML?5#o+u)d8EbpsW z7%>x-D|L6tpVC|Cs7^cT;H>plc~kee{AoE5Ya?Bs^%KjZa(faDlUN?tCTHy?2dIs$ zjD1@^ojjH|*2eODtj+HqEY_ywrp{t*O-GF)i?vZMbNjABE-eN(j}G5ra0Ci01~-TD zK4LJn1<)-97o#G$Mp?6=L7SjkY_0{m#pV)pNXOARlMk`H3x-ZCZ@XE0PPrUZjPE6b zRmG4aUPi>DRgjQ?>sDY?O~_GIjPKhfU9tx|-WFnfjNdKB_h(4ITZ}J;9b}eKcx?WQ zFuoJOwH`GLY<#`9V=#@v^!MSRio1S$%VK=TP;ezMzH$GMpXD&Vsp;9u7~i6194>L! z8sn=mJ`wCCFup%+_Sa5L_L+@jts&0~=9OX@ysq?`;`PqIy~g;|DV)Kxbyq^{k@d^_ zw1{7Mtr>mk-NE9{5$khiL*$?-s=WnV0MfSVxOa81bQ)Be$=NZsQ z_N}fl`f$0N5poE31|*b~pL#YjMjv`#A0uQzSh*^~{6qYfxtjFXzvkez$vs&f+as59+<)$No&rBe_{ zp8$Oh6-qkosTV-!+$im-V>C3*aXtt>#JWj;FX+U&$%ppT#JbN&ICZqACe}?l?Wu`% zbFSrai4&TG`7r1N4H=$$63hckB%S;1Ccyeh=YG2_L;n=`bKg;he*yFu7%b^RmZA^! z_)3S7vIg?p78Zg>`$h4qeK+@?JqDKZpwB2MD=zB?b8|I~m6;P#Yw;OpGd`=ojZybI z=6)OQcRW8y)CiE$d80*?pLS($b8nRXT=M7;P4{5ftle)SPGaaW`bM5Prnkzc1^NjS zp6%$op}R;L&(Piux;=3`qQ5urT9x*<|E2G=^ zMRw|+Mf%;&VJ(!*zXr4Ku9-c8d7DSGoTna}|IoW@NTz=g1*2p5zb${Z{Iy;}>7T_Q z_`E##olRft)F=Hz5tp08nw)JQNO?Q;Id4FoxXjdZSoIv12=)?lSl>I=-#IL|3jE%B z4y)d4!RrkNc&~-qZ!Mk!k`n524hyYp73Q$sa&K||yPw1AIsc{Sh`#X;i!pF1|56z9 za=Gng4(kv8X>tC_&S9-&{(kp2i}P1@4r?Xz_rH99asJBAVXb8Te)*4z^H+8bYq|W{ zu_jbbuLDlKcKrIhkn6oZJPgJwu@C}ebthtEUNq;m<*XQ68Ggj#mgA@ChUOYFEXiZA z!}HT?^QYKdD1RY-p>%uU=cz2rUQW+aY_6aAtHQ6}`CChK9M@$fzO*M)_MsT6H~W~s z>;bZ&_aPpU_fko5S{dkJiJ4C&Yd$A}!KkhL33HLkcey8$a zd;qc^Z?Eg{*E4u#&e2wM<|?LsA8ywz8c8$gxeo2wUfwgO6r!ntE(}y|-gy4axM`?zKD6Il{8o`U%VpysFGRXVVvK zecC@XZ#iszB7@?~W9!47QkA&8)Y$rfV(SNQPTpvy;wVyIjIAI1s~am|>)RLpq6H1`izy%f4%<0KXY$QoQe0?%~!JabMv+Olykqa6&(us*vdqWt+@JNd$>>T6mw}p&{Y1_ zaUa^2q0??ML4`6r?I!0zr<^`0yp+FFG{jG=_PwCbp&^j|2C{cAG&^E z8ESv&><+>IEZ+MF=!Y=)&f0Ab%b4ijzOs4VdFWySc7({U_Qx3ZyJETI(fzhJj0UFR zmELrrqbM3tbdH7D8b(4|FQN1!)ZcN0izOWOG89)f-F@ead#KdK!#sq3iKw5l_2}o=3bh=GfqI%y~yT?Rl`J6iS zLiB~d)J}xqC`SXa@9Ubv1Xda|vfrvA-P3;mYRtiXWI2RRZ}1B>p@U|}UJrFVZQs~( zRvoSkKk9mIPN~oG({wQv+7Yy<-a7)xjpbK_Ih1{0s1ngOFCi=o@+c9fJ3DBhn^0MW z!s+=SK87*5!7+?j-Zx|)ayRJIL5X4L8lMn`p;H1%rw&T2Vg~dC0z&%zpwEL&xqkq3 zHXzFHdqAH9C_uWdpVo92Kqnu4?%oR(PYh!}!-LN7LKYbgOG%YAm5&J@#Wv#Wlw%ZK zhQO=ch|-5KPmb&c&dixiu?@HWvB+4%nOclFQ;V@FHMkf{kJt$3 zj(ltXe~Z2V++L6FxAkL&-bDC$Lyz%6Sv2$(=$8z=iEyh5p7P{U%-V zwfQf?J{aFqn;i=qzX<#I2-2To!niU%ue*g#zaMnIWd4h=58CT=i+wQt?PzB@CU~p- zmBl`2zx0d#ONrmUt6(3EDre$MjE`16*LkZ~iHXZkjeXSEhX{6!eMoEQ)a`5RgP4Zv zCM`9 zQMgPu@&bqWVTh82dMNXCdTjnwH!Q=CI%X%gJl3JVZBcB4gVPy=Eqs_jT9-2CZjM7ETQ~pAjh}gwAdV&gNc-ni+ zgHCy-y$5wx%H@OLL!Fg$+IvuEC7(wSo;oWr5!!n!Kp;q$;L>KpQc?vIp}of(1oL$? zT-tk#Lg&faeGami>fb(7dER+AWGaP2e0vNZ3$gYXT2AV$Jx0?}qo{@VRtlZ8kDQo4S&j&wbP(n#RkKmTP3Liio(32Rt|wIMy_ZxyhRUh? z`Kzm)zpekdO8&0>_G;(vP5-J&{%*LVoBY{vWsyCL#a5n|4&Z9+J48%@{SU7;e?{0? zzr$rZIWr>H5F!9oGz&${AtS(J^QV|a8GghzmgA@Ct|ctazHbp`7b@ovtrvb!%R7p& z7k=1wxhsBvL^|SzZbGsV3itg&^fAim8l!Z@#QvlRqa2k`A&gRWcBLl}5Mq=+0{T4Y zZ0D&CFTDVSmhE*9!V^m(UHK`0VoBulENFBEp=Z$M|p`H}n?h z=M0?~=>}_o|FxbFa!96AS2ix%@9!2_7Oc+qc2m|%?w_KFEwxhmq9VI$sW zC`9XpAN3Y5iJab2C4Xz#E>G5q)oX{PqL;%qYrDL(H9RX9XNQPJqV0gL9~kK|Vb+^n z-t5(}%bU#ur?Ui3<(+D~yi`hRyF9j*?yf7nPh4%6*I6&bAbBmqU}+cE89P6&F2Z2f zk6m74ERVYuuZfmWeCS+AgoQ%ah544R4nx!tOenQ>TDo4DV{6dxrP- zFj#FHn~q0c|IJuD);>)icDi0LlDB^C`^wrK)#s{p7JK3TTbM4(LO-1OIz44|*?!x> z=scch2Qwu)P^~LUnJlL(mbHWFx9+6-zBt_p0&@a`miK{v1a=1*USiiYO^uebFUiNt zDL+%AZRLk+t28_QvX8CEh|+x-pE2~NJXc5i3x<#Jemr}f^cLvnEFUzu3x?ieLqz$I zPr^(M=$_F>Q66dOM^Q`$O1JhHO#dVbO#5-Qn=`}Y zn8cEv^5#l@4j(o74F39^- z^j~?c8GY&99nGNd#`a|!eZG@J92Q8gx`yTV5E+{*OmtWM+#nri`nrqQZq~Ysl*w|s zOWAoY>Mq=WqJ^=tF9-dY585qxR-Gonn4M$$_k$io>BZyx`8`u(73YI;%FS3_xf#op zn>|Qa`xCzpIpWc&Mo5t8q@g#JC~m>fV{}j#4V~}56=O^dru>^|kTZr(-Db|vsoNYk zbk^gb+MvI~fGDw)t?x$UMyn+8iQ?y)fD52k)p-t@bjcoKz}rHdhw;1Bd7ef3-ReAN zOXj~w=ixaw-Re9{pZh|n&ZBl0Wpy5&BlT2P(y7Omzvw)Zn9wL?gFfDv!E{M^ooB0N z9xid$dj6xH|Bw#8p8tqWo!Yqb9|4`cv<>T9KUisgrani79jshc7s4>eqo!-fd_u1} zlRpkrzB+~urCabR^|Rvqp}4s~LeQ2$LJ)~g|-_yb)mh6PF?7j zp;H%{H+1Ski-tbvy3mi9jwojR;98^$wJ_-JRu}rDNtemmvAAG5kVs zUscIpeU5_HhS!`fURGz%bT02@LbP7^5zF?H5WTX~6=4dYyeK|yU0HqwLtM*_s$7n4 z3AYHr$0){YjKUSsYGD++B{f~wM{I%E#U9XO=*FZg7N+4B44vl%%t1gHUSFmk7|2fw zAGcQ;3=4R6sp=|9e;vA0ChxiF-0_MSh;Eb?+P6Q?I6qH3o?#>Y*`liV(b=;_N#AGo zHf!QR)6iom#b*t@1-dOAx}A;+lpD5eM35xJ_2C%EV35)7 z1c&qo$REm{FCYETHQyurovw*SF@*f;KH*BIPKV?J^X(InBi^Pa^19_jTen31bc~4MtN3JW?a}=o?ka~ z)-%_iX>?7ug>sA007+*(?=kciGJC|(sap=JPIv=5I@DK;D=#DBQCUn#z?GQDCEQol z3EyYZC3}bmZwqac8Q+&pjb!5&>4ZOt^t;swxt=l0C_Fa(BAsvnACqo%LZ-in1eKkp zRaPh52Q1)Y<^^p2caDuWs_f0u7@eqWo6PkEnw7-mXU*z_WyXZMKlYv*f1|?w*!eSc zT<;c`4@^q#f1Mou`lj&y+*_g>aDtC3X%U#s(ZMLVqqUU<-~K9%oc{XX0i`@Ie`WUX z^uMhsr}Q_(51$1;m}I(~3&jn^RDS;0YjT5*y;$zCyswV2*lB9L(e-1jbC)pFF-;SK z#BYU;$&`M?NqPExap~sZ@5ywmKe~EMW>N7QhBM?fIcfDCpOVIml4}-%c%J)tglO6uvx33SM z2@=}FVYK6%!)v41?h7DUI4FOMvP3s+7rbib3f=hlmFSh%I`)*8{n%`94+q_(;a`Zp z;|5=WJea8KpT8TDxLU@3b*1+hx&7F+;r--R@ywUNn7wrV-*Tcj|64A~fXSV;6J7VV zrdIl?Q!;qjZlrWLAR(!gmTX^v{O>QRbL{`dx2{{N{QHty`>pA>PV%B@PrUWViAp;o ze<8iXe&SD)fw@|KierZO^*dbJRdr@Yu~X}8x<&6B;sgJm!LbgtVv%TMbqRDS)| z5w}V@zK$qk!Ft`BlnLeh9`UPAIgf^*a;&LGT>$oB9{Kt)UzC4DM!R{t zzVMe?$P6bVBWDx4X;VADsDwNQ>hWhh@=4>o^4jre^v_!X{+r#gT-;Skf3@R;ssAySLsLmY1 zWHKE&3mHXvzJYa?-x&!I;wKW=;eNN{u6<+qY5vM!OGWPy;up$a=zT-s?0Y=a&U%N> zrmNE-W%y~hkhAKwmKQp8%bWzq zks+`%pc$h%uo@1}IAdWKtKp1@8!m3c84)*}5pl!W-ZWg?hKt(>m=cFbZ8(zq*s3^c z8>PF1_f@*z2MsIeB#!i^yNja4&|?iC?vSCkKtEyVlzZ-lME*>?Wx~%PQ=^#BVE6^l zxh{`%%6-#>pM!{;HFV1T>xNFbkAcNy{2|}O=tysYe#C^Q+@Cab%Kd_&Q|>PsI^}*) zvDE#Zt%=H8tUsO`5x=(0#G|QqR40qX(MDIrOS@i+<=qRK-v)#fy=2l=nmVm_-xXo0 zjDM3KSo}7A5tjOENPnszKKbkp@YE=+lKC&fQZMTRaou96OrPyuo7vms&z8T|i!FO0 zMNLecys9^z<9m}NSn5obJ?KQl&R3UN>9YJF$UAomk6S zvZrceJDEM(vRFu!GihopDieaBCt&YX+Fold*qa69r}SLQ(T`TZvS|NSX~-TjmD29*AxrlU3tuhH|1$QRYa;*WzgwLDH=h?( zrq~{JCG%g}9<{mox~1f&ZI9YZZo8PvsPg@`x<) zL+RT0Evk=xhYOVpV7!i!wCNVr$7=8^GuKrmf7?6WG`+F!`=XFT^=9R-NL~QlcbxSY zD(CA0c?pq1c?pHPQ;7atlB`*+?YyN-*iZbh_;s#?*c#_(QY=zx7lJ^#%*DCzbB6w- zpf7+Ar*pMMv0V(p~=eb8G7Pd@JlJwe5*e5?B@`EzqU5FEbO0nisfC!Y_2 z9z!5We+u-bnPYkm^p>H29P|VrB=i4IK%WPl`TTj%xtAsB{|xjPje+#ff!+dL+n>5$ zmOp*pCa`_xU!V134(nHhkF$>lf1Z8amtIFeV?EF56*Z=$sZkVd!j!=MA0ha0nPZ z`Li948amtIK0{|aJZtD|hnEeV?Qjp~c9<^P;YmYhJ6teyw!?v)Q$v3M@sDD9a2=7W z_7w^4d0BXC>PzGkqptFtnn^e1qJ3kh89g|VY(#iy?u9m#`K55Tt72!m%p-eYL_txT~ubC zv+3^~n;5OK7wyDU^)peAqit(85|@{HPOY9(6REG~)YkPL1uH$LP|vBk&a&{Q7tDXX zUvBVEj?r6n1jQ%j$5ZxLP#%icYxG3k!-Io)yBzOmz@hviWSAL@6wOb2dfC77-q zfB8DQ7d1D|Q%oWB9+n@m2cMVv?fYuFA%3Cv(8)FHEWa}nAjHq+uc+Qa>6YPFRDOVH zRvlwhRmR5{MQ7O17~_b%uVPR!2Ky=p>V8Q6l->fJ^?o1d^AHSepXz$GSEn32D7;*L zAW&=%?**OM2I-H0PHcmGXs@0?2>D*LS0}c?_j(+Bh;5LMkfrT~Bw6W{QVrF1A$#%< z%VWjjVno@42KY(P4*?s@+EEVgnoY5|)INOa?WM~jaDj~)XY;t)Y};;pJMyn$@s{>0 zM|N)rK04-w*H>=h!MveU{uT|L@@Mywp!^L($<_S0B1O3pLn3_+^b;oh0_f)rJw`>e z44v{fq#%bl@~8Z94`0$Le@zpf^2a@!8J_Yts2J2?w1c#CqbQ~a*AcmD)g-v*g;?hy zEl6=yF{oEfx+#~me(BfinEYuH=>C-C9OHM3LH!oepCUtC@j5O|CGD0!(h$U5E|tuG z5e7wUwp$E}=_e={&CYG|hvu{Fc}Szcs&##h@9et@1~pz~@9T-_smgm_U#KytKl$S? zOD*WYQSAyt7F!49*`i-lx`%>@=H^t>uewj*ODDI4_kp~+dk~bi+pPDoq%72S-MSkp zw8ua%{lgl?pvs&*p!?kJ`OqI#z@R!$18Cz*D~us&3pRGmecfZie#`O6 zXUCCUF(l9KpBG=5vkP9#Vsv^ezccbUq|w1PpKYJEa`#M)(*4^#NrfZjbyapQfQJ zKc%-oC!Ze&ofyFxxmTxWU%Pxla464npf^D$pC>_Y8M=_=Rl`zM1-m*dd=$G%fXxuQ zQu{ciABXOV*UQ_HO^^1l&#G>UklP?3+Zw^bWYQS&B*0gDJZ#CgyFKF3{Wg8l(3|qU z>J|(=hWuSL^cLt_4TdxixtuX{%H^D)Q!dXL`T{b0!O$s}4g`_>YBn?|<#M~hq9~Wg z44ra0Z|D)^?2@5VE{7oxOqX&wsF>C-pgg1soQrYgWkfvMb`lbJy(#rHAxB!=Dmtj{ z3{$xmG+%Z#=I@(ym8K5t(i{0L!n7D4*~r4%_(gVA{{iW1|LQx&=QZt5{Sc{tE9_S7 z6UHOG2-D(T0o`I+On)ERtG&2G6=Isy$xN7I?JDY#Ov?i;Z&C-~ffEiZ# zeP7v^X+9E{ncA*uK<%n#O75#U^TJn3pUt8=sugP|WxeS9YXK9qFSXWn)~8*m=YMSf zq+`v{$Pl0QJOe`s#Wg|Pt@f4PeEPI}Yc_|q<|F$9NW`t6{%KxaMe z0DTVM7=~B2{TRDX2p>1^3;{@x{<}e+(}9OLTmobFv2^S{mOsUq)6BU6_gH=mK87*) zcH~2|;SW#tdURh_j~RMXGb?W1&{^J#hR*W7WaupKK^>DG%ql!B&p5qgza!$)AW23^ zJv>X|1n5=Aq-RXJWDl|AZQ+=d@w*+9{%fS)?U?jp$@~|MNvT73J0@lNoafdyq~D~n zW756o;6Ip^bn3C?FJsc_DrXVYW75s_d4VPO?+Dm}mmia!t28DJ4pZteX=mfd&?6&q zERzx7!6!5$pAlcEfGt0cb+U*R`K|Prw6Q_Pq(30#8XA+vpmU6*^``DF`E$55I)B#F z4};Dz62ohpevC;KZwie`9{_#%F==Dzb;-E_X(K-%ZFn|~-q^4nlWHx8T`FG@;omG! zlKDD4c1&@%JXV_RM-oJ<$D}9-Tv&d*?iM=zen^f9eVY1h*tI?;-EUsN=3mC7vsLzV zZA{K!2wNT}-G@0G%}V0(Q{$uqij$VM?fJ8hmL8LCiEiyUe@JoDYgEhvW74GL8NbQ@ z_HQ?Z&p+A{by^aowv@q9x@~J~9p~hnxND-`kNvhhFV8|_)Ri7n%6ga$fphjcreri`J$S5TZnTqez!R1vv}`ran7@*+?ZjT|DrKvgmF~2I49HZ7U$fG`qMqd zd}s5&b8K>~(w-*M)z4hzenpy(#AT))Qx52ua(~IW_x*phqr#YSd&iiv!g`%6>v~TS z-Sgv>*E-f4EqkVBm2(CHICWq5L9h2Lah+k|kLW}IFuF|oU3sIKMvwuP>(e7WBEfvqFp@iVN{Fh(ea!t~VqM0O$?uhjn_jy-;*adX5()(Qh;m=+Z z*2z*Gti8{5nsm6$rq6=i2v~S$+>o4nn#wRD>*ly@m^wUnpH$E)Qin z==9k9eW2hyEI$nwa+aT_Tc+MPA7Xi8J5Ni_-P?4v-pZ8A7jv9ag5{_37vhJZZvmG! zITW}3wC%I&O~j_C#x|sQ*ba$pG$D}Mp49D>KR3T-=xURt^aK^k@TncO?B5JJ+sC^Q zK1B+nh;sfQ=yPa*q;s#71<=Xo5rmIX@sw}wl`;=H--~;tBoHXd<>TN(yMC2Jx_)3e z9~Nec<;+2cA>E!1XC)yy; zA>>~NApZB{yhr!jbj#42DAXYs_b49?A47>9HS`wf`wX3O*);SPY^O~r% zhstdAdDQb;+Zjllx5m5%6!R*rlm69>D}s5o_fHTxTxrZ`z4NazuPaw{Y@Y5nz1el0 zvL{A|Tgg2#YRt_jr%%xgK` zwrUyG*MF3#x@2e=X~#>{Q8PyHSbk@O9>O^+KkBy2@l#zr#LuSNYq(JPh0?X}L0x~j z_fV{$3_lGQa`t^S-7@v|bcmVIRvJ?~U65|K~aptzUHy$e$Yzph2=d zya#k*9Hj3BofrrC=yT;0qvF{P)aF&`^Psa|dkl199H-@8-68pN`2ki${>o43#LP(7 zIQ_unjtU>e$h@P*`#N)Uv!L^!|KMku2gq^ad6#Oy6LftmF@hZ zhl9B_sSOA7H74>{Tz+@s=}EwI{yxKsZ_^DM%!~BI(3^O0$k1cRr`>0`1^Rgtz6tqk z8F~wJyU#G?*6uS*xosNk%mF=;*RzIBxy|iAj0(JL!c%Vdpp)0vQ4yfr9x-&v?MXwA zAU_L+PPrXa%x=P9PqCD(??&WCt0wV@;$OTeC7gtORmJR%nsmt??08#fr^fimMi$=2 zFT(6Tjr6Con5l>HdEG5!`u(8iOXk1GPHhf2)uTSsKw6qMnq)^vrhfzvRjlF<^~Q7dT?Mn7sryO_M8Hv4G&aFIV=!S;QTBz#2-0Obd-S<_%eDZ5^T$dfNV|u#e z+MK7q{+C>JR3mHUAx?&SHaFerF^=Nbj}Z)zg*{?k&HE z3;6XrT&B}_`BMGTI-73U_vIRyGW;-X?g)Ba$6fJFsO&?bbx7i44l*{Y?R}(7D3?Dh zey6iTa8(Y~rSsZCgdmVUEzg{8Zs

`U2=GFY10w{xp0Of=BuIyP&fXF}%j(B0bjktkQOJJ|nHq&IO!@-oT!TzH<)CT8 zQw|1IXZ{P6M_P+f6w`z2h+I`x6WsH10iEcO7O=RgI`agTyEJhd-(DP?LR-6mjSqWZq7^Ijz;E+4hdT4P$Z+p>M z-*V#G!nI3VF3Q04rf8G=yY6jGO-rm{+N+sVEn51-uwu&&WtO=>{!6dD`o_1eE6l$n z(4XAq*It$0FXTftCL!X}>1s?OEe|{1Q5`a*w`V$-SB$-25+Qyetik5*OojaUYap0y z%kRYkeo(O(Euv1G5#X`>G=HJ@fU0Jr=k7ygp9>@e9l!dRiRk<_W+G*B8ijR_Ttk@2 zPSB-Sc8-|I1n6^y&NWgCplkiA;~FXI%A`Li&otcx6{+&2?!EG-^cLupr$<1agMg5a z#_0#fqHC=bV~L@=z7E0u2#RK9BOs*=ZngYo|f^vGy30A8U6(`59GEKpfMh{8+mS z%8#|Xp!^IhHiPm@OEHRKdT_NsK&E7Qi*!=4~no>u|V@Q819_p=rx65KP$6?6%=?<>> z^4~c&HCkma$MKm)<-Ht7J)_dZ<)_AGYHUUXyT)c}Y{p?2ul~#nyRhPE73bpvYpg~~ z?%OhY&2N;pXD~f*`!;~Bl(uJB3-%!PTUKKSY2EtcZ>3bh4(@AQi8jhhW`$9>Xya2 z_Dr|Bc22*Z$?MlM)URth1_TCqfZ<=8tr)YiNgnW96WIJ zK(ynr=bn@MXVRO;pLy!3C!Ur7Pd{_?i5>5L`2F`icl5yH9|hZ9FDrfSLAQ1cuR~X> z?HD?1*p3g1bma?c#EwDjEPZG5FS>H0(jK)FV^FQj+x|B_z$0;)sdeRASFUyCmA5lk z**$F6yRO$u{%bo1>BtYt-(pm3b&-u?7zr{j|>>m1!g;+ZUna8TJ5UG!=g@veGsv{PX zKuC-16ev%RNF2p%IM2-R%B!Dt3K8b(t(^k*4anM04)K`n7CX^xAKaD>V}UIlX7f18 zEO8Wl_aV=|K=nR4yVipA+*%7fXnK6Kt;YBeoHg_o=&u_(?G!E>IvakB2~~}*{O8ai z95M6-&=(Ayb_!by>=b4Uy#=|NGjz(&pxP;X6Xk(wk79ao9g(Zbc!GOgE@5uDTRVkY zLmw?+4sl{Kg?0*z@2TxBj*VYrr?3s_cWbA>H5ge&;j!r#VK3bG;8DZC#@Bn%LUWGk zcWb9`sJxxRWPaUpz<*^rk@mk{Ew8mZr6nm-nO1)y6`r6%BAux|$ zpAU4Zv;J0iuT&iZ`}*NCjNeA;jITE|AX zXCSMGR}8UvTWB}Y?{Jy!l%*WTDD3#>Auqh|wfXyiJPctTmY;?TIm=Je4e=|gcgxfA zJ6XWb=8v}dmLF8B=uYoJXjpCe6_p?PZS(l~`wEbJ9X-ojLuD0;V$Ro@8LcrHS4?cL z_sE@g^i5QxVvXv!cBEzKTsx9L;23_F#Bp{mpi>SK(4C?uezpgF?l2ZKRMOuE`U2?W zqq>ZSk5Ta|-|F_spVAjVr#!12iqaDZ6!~bJeqcBUg^$|5%!5DA(fMi6dCp4K4_ORn zW;DfcR`3WN5%zql0CdhG-};?-i~P~O?$P}|<+7nS5g|4hOpFiL9z$<|e#Fq5kgt=5 z-U5BW&?$FY4Q4Zs%+44(iUq*!#-5dHy2_536L7W?tU!_6JQlk7aez(}qt{$-; z?)92w2p*gNBJAfZGTtrr!}JprjK0oo@@LCm>&2G6X7wDfpZ{KOJZJMSb~n?N_S~Fo z04l10{lErEvyr&G)Ywmr{fJ-}uTeR;G0w>mVRsGg)G6#qDQ7po(R58fdp!649`>UT zHXV6|uateQA-7X#3~qh4l{x*rTh@ zp7`^f8Bsiz-x;BW^f1ehx`xk7{g$8V5@q;N=U9$kzjWYtcnO7u7xsN0^1}OG3}vHj z9&t5vU>y>8YcytL>@$#d33p35Xvft;1EO5&SW@XtR3zoA!SIGY19}1hRyk95zx+A= zpi>up0CegczI^mU7k!WLcWW`A(~Kg&dd95MFF|+1AZS579eFN z1dGUk7Qf0Q-6fCi_X)%33^csbn~0DYdW`x!WazBt6Nb)uK5ytPlv~TtSGhPCrs_r+z4wejYg?MDtBHfSiec9AV zHh$5(|8Ar|m8Fz=7@ybO0iGI?`+B6Y+P{oPN}=wDk5jk0AJbn%g33|L9}`;BjjZdmw}KmM{yMt{;- zt*~8ie%|UmCDtcz+q^A$&wu>0%|+>NNBa87T5^xLfX#POa$Ya_=|8UU{s*Jr`&(J) z_t>?m-HWXjp7TO9j zez#+W-$we~ju|eO%zx3Cp@s76cFe%^X{)JY28CVOHil7xS}%UP067{(`g=*hmCb?V zonzBnc)6~|3{Smt)BTrj5plA6qO8)G;VW-!*7Wn1Hx+hj?Pbhx`0EwkzaBFo*RuUHB{BFc1F3A^r~NC!m)>y$RqD6X}>@ddv+f z+@j3s{G!a65Gk8ck+Y|fzFw$vi8p%Pqx&*<+0dIBSX_+!>SGPhavM}U;`1mEEgN;Q z`)&V>h*#@2X_K7qEGm2s^s0EoH%+=^k80y>As)f_-Qp4d3F&u>M-2PImgTnm*kTCZ z({Awyrr#|du^09C-*|afuPuMUBc`gXU2Kff+^zf^#=Z?Wws_N`6Rknit0y>3$k1dE-%!5D27M$Z)erz#WVvb`nk5^2l z1B-f0feObZ>AcPE>^EUKyrSDN#e6-c$jaRJ*zzyJD>%`6wZ{}C<~U}m*u*!cs^b;s zJsX+C6=sT8*s|>Rygd6(zy8#3hl^)~<_&wY;C5JiJbTjVDa+4dlAT=IccHwrpSFFz z?$xHYeZAlvR~rv{+fVy=khib@%8uDe@0Go@df0seECi+QN9OzLU3$^v`vLPib+7>|1UV`X;YO z<5)2rTV7i*w!AhQTWWu(PRE4Gr-hE1{og&HH_<^dyvC_AN2cq270;qekj`$5=>5{J{kI4h2wIw$VIgfx1Ga!i5 z$JuX@E$=rV=+X~$IHu35wh#LKfW)zUn)+?nqA}|n#%bM-S(*MJB&c>dI;La0TFx%# z2nI+$shRei&Hv7^nbAtNyaPOD?R5-Xk6EMAbC~s*HF|sW&TP57*MdE7-WI(~`RbT; z|F!?lbx`>+_gc{juELmgy`4*}lCYX%R`!2uXUw|fdB3?aYhb|G(|KbyC0zB77yjpBfZOX7fszxV9|956Jd8pVn~om6PZ=O(uMNeKO*{4Hk4;4%my z`i%UTu&?{BvJXOPPA8?`zZ$i@?{nj4B(V^-Z*hdvex^LX4fl}u%=fYz*ya&c7q_n8 zx}D-JKAtLb$Lk7DO>xt9DR<(g%g@Pc{i;iG)ApVZtj}}|D)xIw!mq#3m{@srg{MN0 ziNov`K8mv*0=|Sxz&>z^^D*-WHOvGSBxGk`YTk#C4{d+G{Ed2azs>D4^rkWq*EIAP z4f?F1w?Kd0&{^Jtil-jVDm*REIK5=QBjVE_Nk&OM=g~oQi>JP7(j|LT6K@Oc3K_p! zyTac>`rYEG+#@8*C_Fa*MR+RrqwE$>W%_K#+J>s&soW!^1fDukY0W}CHr2fm_Sbk{ zS9ssbj!hfVNOU)f(AacQo*k^mrrM3+6RBS3&dBc|jZN!w($acgKV#D+&L0bmO+%y( z+|(N*)??FD7DB%(jhohE)6P=o*pgS(-RSp2a%||+)NjLXfU)Uxl{GKpjVYK0lwb4W zE2oJo(DlEbwjP^yH8!o!>sm+WbzxpZTI}i5*mHX7=1p%jT@x0(OZS{UeL8^KZ;PhB z@PA5Ac~H8`banYPztqxLr%%hk_=afHXLZ^*)g+ccux($v*6r81_pH9D@2oEHusjUu z0{spbf`_Ema?a8Y=R%|e;@)?A&;79-$^FK?wcb74dv6QFO0;AC=Ztu-RNWKdf}WjUMyDE4?Xy>gEkSMt%8vC2M%rBgdNL-$c3Cy^>p?C+IvF zK0&7Jp2)1nLB-|oH62l`mE*Y)@oQBj9!;=-NjY9)e1G(OIYInlZ5* zg24K6&=1|`U6P-W?xSNQr7y4h;5?V`T1-)PI+UWEj*~ycWp>P;uc>vP1JRDho_j9Z z@$54P4;+=7$DeuXsVAO38tr)cnWInac=yBazwf!D2Oj^Z)K@>;O3(Y$x=&{<@q5ba zZh1_Maq~eb7`2=6 zTwpyx`F$PM=Dr#AywCd9eM-;!e11+4wGT^oX?36WyiY3W^}J8k;`^;5DW+*%86D2Y z`~CQ9MfZ^j!ws?Cq3r&~s(Y*3E`K52X9wt3_o0r{GP=($gy(z#b)p1x>OQ_4^h5V~ zNce|zpZ^y0<#ivN?=&{*W_8@|%3}@Zck0lX+nYvadvwmno#il=Upq0IKLBbL2S7t&#bkf7s5t^V$514m4h6&2T;cQ_uf|Prx*S zrnmVux3vzmzIC8IC2imK{NX>5(e_6II#50T6X}>Uq>HQ-9mvQ1{Z_qJbfArTZrqC~ z>{za<>%{n2QwOT&e{f!1m-9dQlk8@3l3iNxweC~vJ}L>d?OWO&?61`wigcf~V*6HN z{%5kvn)F)tsdb-P_t9QqE!d{5v~8Umg2}sPwr{29e?IpeF&+--KJED*f$?PrfqMQ& zg~_?KqWk!`Kl7&7wW9lMl=Cf9+n?_DyP~aSzii()FSJtgKZ(dtX#Pjf<11(ThI2J@ zM-W)EH=X|pSi0rU+nk;7jNfYAr`CN$6l>jQgRJ|pHkwv81?XPQ_H!X#{v-2kF-sY__+NiYW z!FU5Ea^?5BPU<}m{^XCpEV7hZ`CJv!1(r@UL#Ha7N&EoDsNu z`F2=Xt^9szD{Ygu()>ktaRc%*XMhcS_U7!28(By#dtIM7R8?CP77%=x!<*7Gq>K(FTYJnQrG{`>3)Xl*1GPr;BuM%^kdHi?iZ)qsi@;# z*^i1}ZRQREug>H)r~NE>4*IgXQ~q4^*^YD34-YTCK=%a?-gsAK@^cLt%Lr;*Y*A0E1nceZ+$DcZS;4#@V`{=Xj^$>kWpExGl z!9DxL;R8F;E#fxNyb<@D);duayWjTDhvce>c)UI|RU+r6^q zvDZb3d83I+dnJrd!K|*l?lf2HPPOjzojGk@^R=;3$gqZb%>xf*n3KQJ(GTNhV z_4_7W^0nWyBHfDdyVb4!1JdtSx7x~%o*Bp0=D$d{;{MZ$nfT7e*L(X-*6>WfTit4* zylypB@5NBtVIW)a;^SL;4$d0=SPQ8*YLbBG8X-soJEdEk;uriko-8QM5y@ZoeZ` za5e_)u+fvTo98{>D2yFH79y2ahj+KeLG zmR$7h*^UC~7I$O%Lr74~0<;cn`76zqy=L_s>hB@F@tn>7&c@hSm9?<-w{ayFF0t^0( zk4yTS({!;${^^^q*!UVvF+uIJoZF13w&MXTiO$f8;YU){P{bX57>}4J1qBD-d6=QK}Bmh)AeKQahEXD zc|9kw;=csuvJS-2FF_y_yLK)&!U*hVl@F7j`NOVNwAInq<6MZQGm3PT?#tRfLvLze zaZN*Kc@643;a{LU($a~dm>yh5#39TONPrsjRN7ryjF( zmWb)G~p`Mm2W6`}SKmQrYnFT)`a&63@L$%0YD|;;@uU?mx2t!BF{9 z$NgtwR2=DI*X8&$4V~vAv_Pj^>7JaL?i>V4>z%G2`0|6o%;C!rPU5%wK;MVOznMJe z^sq|%(#Qrj_ONU;{;c0UhR*suV(6^ji-ykn9aKDAH(B#t?B9rgME+C;6Z!MqFg{A07paPe zzhu%SZ-@tPqar+<@qO9UNH%`aUZB5*^t;8wTP5>fq+1R_pXwG5XZnkHVXY2Li*rTG z;o)2}dPED&bGG~h568*aDJZ@i9zH%fU0JuBSwFgEjfbz|9DYEz{6tCJ@)NIaSyA1x z)VxHkTN-@C>u1y}x*a;~TDOee9=$VLY>INSeQ}X)iJ>cE72B^`9g6c3Swwg&zcWI| zu&g7f<#(>*Y5T_V(=mC7U%$iI{BdmG&ROcq#@OD2Q2y4s&ZuJ{UuWE?`}R<7V|m}u zeA->0Q>UO@ZZw^dwm{SwM=>VN}KxZ_&`l!x`U44pl#!)mT?a%x+Zgt6~ zJXdFRN$QMNmt_4~U6MMZ)g`GjT3wPlqtzv;GcMFRqpO$1{YKG*(S2gjc^MH;NN2pH zN}{-Kb;hG6-IQBi=PS|~8NXYd@zY4ZTb=QI$@~}Tj4kNg-Rg`?zgwNLiTW#{Gfq`m zb2KqAQ~B(@MXwSQCkXX?WIZ1#f{;I#yq=F_M=95hpp(kF1y{?MkBoO+;kt(OMPGT% zn~&UdMb4GFKOKN{k!hZ^JhHrVS2}-eSf4Ht5j--jen$PU2rdpg8SX#K_{x-A!dk5K(Wbt=exn;eSUe%khF z*?Snr*yw=Hi{CBf5Ska)ed?4>9a!6)x`zBIojNe-Vprhk)PYIYrGXlrIxyw=0nigP zG}7M#`aI|=59;>HpGy}NOgYwgN}mUv^XvOTParttBjl(b^X`ucADwrnPS5iA80anN zI9WepF_f{Ao&OhOPC*ALq`<-^bE>dGm{S6ngkza={?DA=H zTa;)K<)Yt-TjY<9X9FtT?_-9qPeYL2M1;i96MT3M8M+jeb0-Xa0d(q=NH69oS{0A`FM|Z^}ZZ9vi=C-oJtL zrwZbe&u)26zaR8a$@~{#I7g82ZZRCDza8yQv-4K@v*oY#V#{9N;{*l_zo<8!v+pYN z{sd**#Q(DM{^OG{K`(DpzRxSm#O0;NaB2)k1R>MOvvY!)CFlK{NA^~j_a8NTC&bjd z(}v;M^xx<@Lp}aF9T+TWTfPx67I}9cV;SDn*E34p(9h>zdT)u_k6pWzO?SPwgorLa z4XF^z?{8$jPLKUQ=-5A`hxI#LHn#S%bD!s@*QR?$9(bP&28;TwW9lc;*D*zRs%@{O zOejb9h+lQL1qhnTjk;cKueE;Z`l0Ko4Y%rg)EQbB~}v(H?~ey+frX$Tk21j)TuuG$~RU;r&`jcy4Iygi9zD^H^ zETop1)qP0$y_7nW2PQmMLc|bqI z=#@H+PgB1Qy8(2n@oIY?O+W=JKTmaR{j5)|_n5xAI#oSS<#jmgUuSbewRNjgiLI~I z2}|#t^o?&_x70jad+#Kf91$b0@ZL!W<=LW4&kV_)Xjfr<>&u=j`d+J}mDTw;|Kame zzvZ`Hb-ruti^=^D259zuUz9MbF)ye1v_CJmQO;_!Iwa*bmiN^LoM6yaq(f3JS6YYU zo=BWe(|V`t$9&y`!c6Do5&$rEed`g-6J&Cln_k0NbLDi))Lb*qBR^|5k!qO!e40O3 zV&~IXCU!opi3fH*jrDsG@2%DC+88hbJI}TN`V8h>7(PbBoHO($=;sW*#fEHbJ6XSj zI*-S7qO8Z59$ZJ{sxp}1o|jQ{f|o$3I*<32lJj6iwvmkQ%cf=p-3PN771>7qHq!5Q z9`AC={1@q*agTcdh zI;V8^_S~>ll+QueIXVC1iKO##s71PtSsc4Xgsh zX|%P@`P`xBjy`+zz+=&lqfczydCpqr?CgE1bMd;{^-G;$^o}~8eZqL8ZvdT>8|#)@ zk2f*as65ZP&oe?#T*1}r@#^(>A_#5cprm2fSjXe6>% z(y3FtPv7~K*P79n-t85_5?(EzQ>Qv?QC~wgqA&cVGG)5V$5MMXW%B9qXFT#r zGy2MF$D`3dZw2_Ldp1daJDkb?*8HARr+B3K5`-Nw2JKo)XOTEuTM>wmKJ}*y0^M_JG9q#3hyY`LcS5{~K^)`zRpXGNo zb>@)%Y0KrIj@-9z?0bAb9+lyz;X=;x({w}pit63+wERv=fYq2E)-j$xKP>YY^}0PA@3#EG=0I+CdTb)VH9+!hn}@DTOF{c%m36vNkM6g< zeTLpd1g?8kJ{mqj2Y=Rt*CJB)x}h(Ce%a7D{~Ti;ko-CS%=vrLIsbgpgs1#07&_(W zqM=iMW`@%Il0W5VQ0K8FN>Im)6!Pq?eVkZ`ct+cUe~+MztZ^+)NhR`oTBuk*BVo3mq(FqX}@pJ zOO!I0!r3t8uf`P8;%SR`CxDyibI%2Aze~?!zx8Y1SI=X6WvO1y+x`FST?c#=MHk-`LJ5Q_ z1f^W)HKZ5n5eOY22pB>;S_n-dy>k>HC{?ORIeO?tN~8u2RjMFG+EGMAkRnL%qkQvr z-`niX?aC!2DzfwYB|H1SnK!dDZ)V?n^JbQV?cU8=IwzWsVNRGe&@Aie=RUVGg%MAC5_SSYpImK$QP$b_IGQw9r!>fq-M#K&%` zz?D2ch{Mfd>J(i7=s=kP=vaGux>M2Gsx$l=saZ|nNxW^SS|U_a2s zi$$P`jRfG8)_D{0KDFzUkGOJ)Ja#wTYMz%%`90*6QiRX1wLa;L6KPu4Cu!d|S3Dd0 zwn1xsGC7NsF0Jd6RQ?<+5ax0Ch8dETzX7AQK6wJy@4MPo*RKAR`~m_}b+*%gTbFQT zeXJO)j~(ynT>X9?)|~u4KzpCS6mLL3)){|&j!P=n$5{DkJdbqV9G5H}Q&sB!&#q4n zaqzs{A!}SRWPOspJ>pP5Wc2zTll4K^U_sXsK3~k}5$d7s1aUORBvd-!xr< zy?g(YzMr)2VqpE`h%Q0>uBA&j`pu5?)+InTQqv_GA^vJzBGj?<5<5jA)LxMYO<57q zbqVi}diU$%UHAPK75nz<(5VOOkMs!Aeq-6?RwikbW3~}qmVMQ_gsw}dw;#1*82g#x z%9JF_D=~=kY5(oIL}%^+`1&(lA}Cd7_5}N2a>v&t6437ws$vxDqpwTo>k^C+^mU0> ztV_HUGWL6e8Bf1Pb*Y!fT{6MQSL{E8TY){FVqL}QrBI{#c%k)9_=VP0n1s#NUusnU ztNo2Ns@v12d_)ImLV0mQWMM0d5l-o({f(@?Hi4_ZZ|;|rPfE7>DBTmC{ysvW;QMlK zxsz(aMh<}QOe^os4-#idj4UV>1FlGv0g-SBgDdh1eTf9H$lb)Tgy zfg`#P+2>zHPfM5L%YEH+Xoj|_j@onNvPq$R!`H7ROA7lB_`o>9CO|s1z|#Y}AJ_}| zfM!u1w!2q*HoHU&fHD;8OMYzKLes6KvGrxgZ(kN<2viPH%Dh3=fL_4tbdKG zXU&lHFST#JYp%tp_(D1Sjq`u$`qyL!+8_4kO)fbwL)X7j)eqbdlW#MAeJta3&WzTX zIi2vW(P{HP$h(+L?Kr#tJ9S#obRctcN<=9y0=ks_p}3clh{aIkld&W@W*gz@y{@k6 zC_NMzZ7QSo9B;c$>-!(oX^FoLi~}6eX^DSHr?n!3la5O3oJM3o!r3=uMEVvEC!JOl zz*!nzr!^si5+06p5)tpp?kS|FPHV(L!0WVhhKf9H>@-o|bkk{l?R8pT(rK0F)hcz` zSgbcps>(SaqrQ8Al^4n z1g~D~3Os7Wd%6q)C5nZ#>a-WRawTf=OPp>sby~`wR-N`XmY-Ig)EMrTQFOi$W+cijAkQ!|Lm>j1ly8SbZJ#Ke`T^ zyH3Hz>|KGci?r#iuVb?+FesDy{=I+JXWQX(s()*rS-t+R=QB?}+jcgq>aaM*1+Ymm zTzL-gD{U^-Ym67#ZU;iP>+{uXq|J|@dJUo@RSx_JqTaKr&`%#fg6cISKZ1v`pWesMNOr(X!#lx}%g${QoA}T-2VUjN+Ln%D2l>_JdMqrF6WlY#sf;T@_*{ z_lxZ#1xH$@#-9{+YWFu%0gz`(~t{H~L)xOdr4jQdG( z`y-b8>_743=SLPYK~SDwtQ@Dg&;|hSF?=+!`Dni@;bsvP1QVCuh%dl64rfg!h7BB^ zi1;}UH&EfYPA!*<_#h4^zO-<-5j)}_hg%T$M4J!MC%!atIPv9F4kx}$;BewgD~A(b zzOA;o=8Cm`Uo3`33sh`)lfZnJ=yH z9x9*K<>1`|ecoISs#9W!I<1}Uq^#tfEvYW{5#$~;#mr| zXJxSOi^=D*Gzi+fM_8Hx>`(11 zbOoDhP?BJ^x~OG#PoU}I2!lt$cy3Oc{NZFXIjSSdMbn#*lHQ9*v2@S%8sg{kna;ZG%7iG|tjW9nyAM*LN z^zuHKKh3g{gZ0;vjc9*Vnq?y_zbQU2$VPDfprf);G7jWOWn;5A-+oLs3Qo=01p$Gn zKfB-#kzk2WxwriPy*adr^kiYm&jWfz( zX5p71c9c{BSkvXc^P*VOC3*_ki|q}EZ{J=h1LUawY$6rU=2emP?CYC)^;dlRmg+Cl$MQxAw;XOC#_qQK<>R1i==1W1ySi-n7qXzugTak` z`_*=EpG)nc(=w}-6jmlu^ z0`iIVM4affL7bS0>e&%-6EX_5PYmK##EB044)l#~EW!fO>Br(?xf~8@(!;g^?F6Fy1=}wFh!8FR2+A`p@bM7Y@%aC z{!Ql6TM##(tU>9CuVXo!_<9b9TamACaX9gHF6<|wPkbH1;l$T(t4(JOwg+~jV4w(I zz1S6a-H7*eF`v)Z4&odEl`x7mQP_0E3Z-s6NVmC&ji_cb&}}ZMu(|MK zK})BSWdUq7P?SNfNLd(*Q~7ia zQ((%Zw;Zg$mJAzxQjM=3T_*BAkx&bwhifPFm;E*A3}i zWp|aXEJ?0~k>gDb(~ao*wBIJUtY3Wf*i5N9d6bBWJ`2PY=pfqnF;g zEC0N-9>dq~ZCek7=T++9O!w1uaMmWozp2&1L3ain-;4}Ld?wk!8HfXb=+oY86NiT* zokYaDvU>;(*&on1;y@=l5r|t5r}0dCvuTjgyg_@j%{cgoPA8;eMV#n#qjKF?gayJO zo*p)b-i!{|9B8jDwclvO4Y*z)&u?}Hgn(Dt9N6lexU|Qe#m``yWkLJpKW>{gSU3Xg z%@qOiVjrt>Jhl@EAMda~3MUjecCGl60d+Y@54c%GnR_CKTM;MSkJ1}a%AxZe3AZ4A zi=)GuS`7SNa%y)IDuF~ttQ5<^?-@7YL)h&Zr-yr6_pu?rVs{A!is03YU4fU4cuyBv z7ovSsskMo8=E^0y$Od$)xvod~73#E@htIFIuGa_450XogB9x!5VGO3YGAXU^D=~=k zX|-%3iMU9RR+|WwAB*DyY$BfQ&rzF*C$8(wg-R;|Uw>v32}sQz>VV)NG@&@Yu4h#U zQAV*Yx=lp4i3ozqKD&R~CgPXd>4jMuE^Oe5KJ4;6+OV8Uj}ZjF&>+#5Iu)MN5>@4Y zbzghFJcUk-HnZ*}fr^|imA>|TKKWkuwQsn{szTo(U;B7a?xJ~z9UJ6v& zlE_a2bV#Kw$&l1^}VBKBW0hZEnDZ4jylNr`V`(H22C@$DQAC%#SOaN^rr98P@uw)*?D;a+wI z+O{ZvT5Vgau>2soBq>7W z(>0926jvstb0(D-#QC&Zwyii6+|p{>qVm&f+iHsaHlF6!;4+g7Nl__$di;eLpVf;@{89Y^=Y6aCs$E;0boX+Y&7PW9*a#Sj&lA`ly`y(ELN{&4K>}(EruCTaWM%s-o?m+hyH_`Zt zCIlNd73F6J$g}|a)9I4~_669xtjNa`3(D_t=21MCqu=8+VV+y~{J#KhS!jL1h#IoyKyAPzTRhgmqB_>1<=Qay>k z-d5W{RZ`}$-wk-Bix-PPlNt%Y>mc0NMQ7xt);2JVE0@SazbFGNfdWSCLBCOc4+8MY z=hyOk`4r0!(#TJA!r1Q=S0+t#u>M-MfrIFGl2+RQm0t!M24n)THBz;}2L=N43l0_W zp8nlJAz~5%c;%m!*#<&Vb4Hi@NSf zI;-}&zJ3Os$gR3x#4FAS-R(d3x^Yr-l3&`}2 z)Q@z4SJ8uV)#&NEJKu8BJ4un$kpz5|FAg6;$PpF#)@5WtmlW*mo`F~bH9w<3Oy!-;>$%t7>tf10{U z83`x;8N}gcGU{+4(6KC}RtGOc%A%BA{*UD3do3ND@~2e?FZY@{xXHo#Yw6%Vuc?Dm`Skq^ z=nhy@p=!NK2am=68!flA6ye*yl3%b-YR;6?*XLO~)`PYrT}^6N)&KVA#OvP)SY+E$ z|K;xl=sG_1wSLZgG4>@k{haxf^+4Mhz*b&`-#|A&G1Mk0ii$EuI)n^hL@ECQREPbk z(bIK&Y%uP^w==Y#T5zVsE}-x6^R!X=S*S|NB;FhFN*6B{ zQL_!`>+{q?wpVCtWzez>{9D%NCn_t;;(Yy?ZNM*8XLb5ga>sr5>DvWR6(js(|J|9D zL(-k#USFSwRuJ^{`M-O89z-AIS$~d~Z~lvK40dLgbd~Q-i+!y4r`rxhrq{nw_Yd0+ zPy|2mEtHYn1Eg zbMWc3+E1-NaOuFNX?S{C{mZA*YG*#3R{i*P(drL3o7!sMsP&~SK1h;-?VHDaE_9mt=ZNqqIT`u>kiqirGK zHGTh+xN?#0ME;~WTqRqmYzmcsqWm5*B1Mo*WmL=e|9dPyNKR>+pXh`!nBvN$S-{ak zCGcsrYztY?(KD^S|5ScjegA#1|Khl3;Ooz93xTOR^HR4h2)_*B8dc*~{Y*phSD-Ti z73Uu4wgty^`x}3u+r#Nbj_LNgZD9n@k7i-UWnk!6f4^PDHWHF@=B3u&iE+a9dq%~G z(ftzsX}<(n_Eq!>ikS+;{vAy+zfB@`lU90lctUuulyddC|TK(Z>Qw!}IwZ2qK&Dj>%CkS-g0<;tLr*2zF;TpB`1zy{> z;Omodwgtw`yeY%iN4G7&+^^dfQutaK<8{MQ>_@=(_oWdt>9z%I2)t1H(N(uC1P7<) z%)uZ(zf_+&I8|}@s>GMN-vU!=^>2*&v#Besegppv+d`V3|3!kfZN;fV#@kk&m(ecY zd1uC#|7RBM@-tn``0{^0s9k>cLK$EF&-Jv+_nepURCqMB`%x6{Fs@Xry=Fg3fH8a*}ab?B)rCBF_m_`WV5UWcB6C&unyhn_K= z=?(f9(c^iIY>j*s`E)Rj)PfqX>3(y9P=YmPa-<%mIWy0yZKTJv#1L2*pTr-Dvqxzsf6}3-q z#7&6T5vd6RoSh5xC%-IO100ID5hrV+GYWAF;zVaW;^KiOEKWF!vbj_3O#?Vq1`;WP znr(g(`(5<=Lq8r1lC&T$;0suuKkSUTO6vN>(j;3-rjia~K&(W0=s13k$ir~fKFxHI<45DRV z6FUoZz7Gr=U`>)a>3p9Gh$+VsgM`{#xqv}{{#6DoKS#=s-6?0`^K1DzHpB9R z`1&(H$I#TAaU2lnlj^mIbBazhigi(}McCS+_3t0GH0yqpPA^|FSqj%`WIsIoHuNar zmcxFgY`EI;*Wc<#iC;`&9KUE0+8S%;Hj=H34Q%yqhZlD)Ce$uEP5gGa{r8tr@ilSq zv#n9xW{;@C)=BMa>t|b|`gmdCJs706?Ovn0lT*s`h=Z63lHj2yrmb#oOO>9lMs=Bv z{O$00O|2^QrEiC``q~7p{=T_oTP@XJrZ2W zJLrVqqsIpn6=e7$Ic6J?bvp&Drdjgzl)9)QtDXD-Q-UM(NEcSpg1FlAs?pOBF?n)! z^rBe`HG2H>YQ1LE?4)*usys(}w@X)z=Rnm=tx7hSS{v9Tz#EWpl{PcKH{51Md`x>y zP57KNUJUFW1P3ePl)e<=MtrLf|AGz#=`9@2+DXJk#fim<4m%G_#7)R>(d-@qy!ym) z5hwnujkpO129?_Y@k9=9insv>I`9bu$S2klaiT-to1#HM_3Vi0O~@$JJ~4<}5hptE zJJ2_}u?P!92hOb$%jIxLlO8rLXeY2~k&Pi9+iw!$@o4jr=RG?+lAq$dtWj z-?joXmPpgj{?sh?sVw`t$Oma0 z;>x6C%T;0!=hJH0bj(=sW*h-NKing$+oYuOvibN>+5DQLKk<(}8!Kq|=j*NII%+(~)#VY7e=6{tGspCoy;e6Uf$)Q8pjqzuK%ckSEQ^$W$)be5@Q!HXkDzIl3a>LO!6Ah&a(9n~wnp z1=(skQn`qOO$R~@`xE6`wBZmP_#JQ);zWmRK8YL-w9?b&V?bL4Z}T~bx*|TdU~gyf z|EFv|{wj5mZ9ZibwwL_SSQz+kfD_K2F>b;i4l3vXt5^}g&*4UVA$f8(84Kb@4hIzn z!c-17A)dhDR>bMtCLjy-A-?v(ej=RsI+DYQuisXi&k<}7XnP0-@qfxcFBSz}H>N;h z%!~qt0UDSEAOl^3-SkSEPj)a;s01V@|Dxr`L-`fv0x=JtU(4q6E|wo8mn20fKV8EZ zOmSt>rViF$%jRRjil^1)L*=K{=0pB?4%mGBQ*{=)e-IvT=D5wLo}v?tVk1j7AHLnS zWLkMHR&s9&^3 z{csAGsc1bfpH8ct)%s0snDX?r_<&FMy7hCk-`wOD`Rj;UpR46iY}vQ@S@NR*NdMM= z*f9Eefd8}~o1cR=PrnPlY1ljq2)S&nz`W;I$`D}u4=RTKtpgjsNc}uQnL|X*u-VhC zu-TEH8QJV;4dU;%2`W8k0@B%3v-iaU%+pgqKI$f;iEUbPo1*#Yc!ndeZme zShLlQYyCz;-r((^R_@d5d|Eg(;9K!*3toSGYSYq zpTVq(sHnq@BB<@@>dJl>{a-L$JrrQbFNW@Axy#PyBtWu-h%PH30{2~baSs;rRAI2M zzxY2u{4b{V6+bU0@6ZBg7x7oWKzl1kfC?lVK3LsJCxvc?CfSee5{b`6INl2J9B#(@ z6C7^E`(zF$J~JR+5q;vbSPmyXo5SJ6XNeq6e0Gb&iO*50$IaX9hW+iF8;#0mBWcWSE6EXuh6og zSTO%-91oP=KoPuZ*--kS?I?&#kB=kJHH`gEab?m~m|uxOoKLG|L%ELzfwbCCHemTi z~YrTpXT&-`Y{C}MzMfBw6K1O-T2paT2@@fbJ9 zZ78o%!+tD@Ubpc&|0DK?4XAK#zwj^u`cm^!0vDDW;-3w-@RrckRNvaU=*>v{Qf zN|`{;%p&r;TmkAf6hY8!DDt=5U%A(7(W3Ffg)+cEwwm~&MSr!|OWw<-q_5%k7AN#C zWmTas?e$u;2+B?g>|UwkGaXK@*IT_8Fy}Q<7kJIRfb4ax+fZKE`XTBz6nXT$aW<4d z-G;&>4J&pa$rB~nJ=kK5DBKcW4si?OBv({IoXrhl0Qm(1vrvh2%!rfxBk34S!a>1@ z(o5(1Fq;eFRBkxZu_8|8Hbk6sTe6`^AZ31+8aw$Oe%q7KOtQRx)+*4x1C7sK>VfK zP8d@t0!{-mQi{a@!(l4pMvSG^c4EdoE4uAOZc;JAx4)L{ww=(KPf)H=EL^eYNNiAjeOzo7eSQ3&ULXIP&v{|PQIyjbFUCC|Mt*&M z@nXd}FEG_RI~Q{>kov5huPXiMSD& zk#NbDl5*Y)@t0&vVcdrd7>)EKTM8=|aa&so194&)fa&=&lBwKqtdAAbQ@N5Yg`K;C z3{B4~*;4HH{?Hl82AnL24xN!~=5VN%n%|Fv)98h}l%VFP(uw^HHWn+=k5xQ3;7xIz zS00ykekwt)V`C9LRk-6?>`SmWy9AMqFATGGPOU zTM<9U;ly`j#v=L__~o35b>RrqeFc6w)&?u=lm=T$QN|+Vi9OkBLR4ge@z?946a-vk8DP_n&-Mueh)dN z6yfu0`KK(#@`E(;6P+;jJH?er&pB9sEgMTNtaw`eQ>c6+jz5qg^0Pm($-c@z#S{B) zvhtx=oPX9zexY>uu7mz5x{c)*df9Sq%iqGe8Ql7_a(!F>Zs6Gog$-xj#-jZ0ntm=x%fEXM0zd1e-1F}meGjM9HcELOkUH!S)c`30{?~0R zHq9a5$hw@22!d{7vA40XJu7u<)v9bL)1qVlkNWjD1bPQ}`&10-FW&i%@D1|z3Gnvy zDJ%V8@bmEv@(J<*iCR6tc-Cz!f*|P}OfbiRtlL;5ev!weodqN~!)+|V_BNJa-NquZ zsBUAC^jmgcLs#&66MSoCh{D$$l&i9Q0#pusDoKG~HBeEG|MB^jeW- zyi9^8^^gRtK8jPJp!=~vOE@`6Cn>nN8WX8y;A-1y%3mn1-hR3t3$+iuW9eSEu}Ce! z%WD628;hAbkh{`KILM$B_&x_5mx(Be=H6F69kh#Dkaao5kGhS;-o_H5+gL;nA%BvL z@?$Y0AL@QA*bsI$mXHj$v8a4&C`7lh=r$JMNXZXQ5ZsVG>0+b^cjez<@O}e~e{UNx zpKfEphQJH8A6<1DOK3o<&Z-UYPxW3Q`VKsFfl=%SeXkJnan=1;bUzk!jh1aJZ5*_* zw7DM0R=&Hd*jUu|3X#=C+AE}Pb?M9o=0S0A%Ky}D2xNQE-V4)rvw_jz)3I|#r0==N z^d&zc{;WtoAKlY<(a(vH8}N-dCqk~RU4-7j^n-4Lky?V6<-pePZ}xNfoH~%Z>NXgz zLGaem{^fN7b!zIop_Uf>pp|=xm_LT@=fc{AY%tQ40=B91dlq$6lhYjE;C-3okscG<({HQ1+E;s@f>ajA}pNXaI1(4LNbRN@daq$_5xWD zkL7SOR?p#ZGxB93hZFzh;`a6s|Alb4xS@sBHIBoH|2A+q@!vTPC;k%;0cG^yaiHCZ z|K8R;Mg6$FF$UHq%HYLrV2l`*Ad8=P%{@h%xpIj-vKifK?kS@DY28!w4VE7ymn21~ ze7c4)nBvN$$qv?EYfn+gYwjtc@{KsoQoE-p1pANP1N3bCv$8!!!S?6eirb6u{9FFa zTYXQFzNhHr%M@FZtSjsOF8;M!viBu_Zc2vuyR_=fUhHbNm=u4Pzp%W#7bytkl66}P z%!<0dOEJc`cy5s5yD4P*;{A8h|69khj7~2pc2%=I;HywhMY@R$U?i>d>hOf{UMYVA z1iFtS^&=e#$;cO;9+ay_@87bg$Sl{~HiDwRP)Y&w@&)|F_nTI`@aeSrL#=;xe-}G{ z7j}@SZfgPlBYxBUU7$6jke0J?tvE@Mtz`fs<XXC!@XX85T?{dYT8G(DU>By0D zTXcVy5oklu&vj|3pX;KgqpR6C9M$=G*$Z?!N9d96C%zID|9E=;b{h=8jzf>4+hC|A zY_E>?ubXW)%{w(-Q%jtmfeL>YKjz1w`@66

dc|HW(TowC9NY4XE63RtM3a1}7%6 zEz;S!F?s_o8dMX z`%f16`H~Gr_j3VG(EVKa`PL}5iv2&{22hG60gRv5jhHp9el7=fKNoC4+Y8_RS~eJ; ze~F*VWZUZ7*^nyv`}m?!MYq8SLaxe2-fu&`$2~%3{ahFQT$kEKr)92wKM&bJ)(jtC z8BgMUJwF$RZ7|jV=IGgj%74Z8iF6x`ZiA8cIO;YS-3H^BjY#W=c-}TeIwmJ-(C0aH zKNzlIcv&5EWi?Hh*9kZ>@~v84`A0=Wx4}q_QIcK2=3zu(o@^Mp4JL(I{$3l5UxwRY z{OtW;{B#=(+70l9sP8pO;eUu3ZExi}-UguCU?dw9^Q*K8|MXs?H^>I#pSrVkgK%q- z<9;ypbUzsK<=4Moq!^`auM3Dm;^`IWr|`D>!IW_D+?Nub@3{*?w2BSJjkRb2sgd=) zM9>cUULt)jku)Aa*HsI=P7FGknqJG>9!PiNY4Y^6bnJi2UZN=e0q|b;V^MDyNBcLU zZ7BY_AB)&QG!8S$hC<_m{8&uL090-`s|5%$iHOrYLw+m<)Ny$~77OA;hx}M*@*z6p z$6~@siEw!M^z>s%MEblRiw~Z=Alt6(w)OaDxDCbr7#BZ(vY{NrdV_APJg>zQ2O!|e zF&o3-X7)RTsT^(2-o6)W2 zc`cM*p?-^b`21SmfF6y{9VC||MJPXA!x&6)Wzqz$-RL(yt(G6leLM)T8D+#PpC9gV zDA}Z>@{RaoHuh_N_J`~(yy_d!$xOw9;D8@XVCv4!)%OzV=e6kPwWOOLi}?Oqx)g0l zEpr=WzbWzjo25%%qJ$t0XD7kMxwvz2p{3up>~uP<6PqH~m!Xy|qmwnH`>(!YXP1>> z^Gjzo!AU!gTyhvSy=_GDw*Pb+477)CgVAj;(zvK&J3Qn&rF;$`=tRmvO9}b+Jn2sK zJ6(BtP_7!ie~S%fB2}EbqNuO?v2g9;X#b*$#^tuZRpSl&RQBh&1n4#xv6*NbW|R$v z#s}G8EXV*~%=zEE{hQeFE{k3c`Z;&5LNUF}v)z5R$_Y&!QiPB{+5!yr8 z%(7?^+F;u8ek_X?$u=3>%O=`j+I{P9|Fsue8_eRxLLR}@i3PC5FnuT{wYC`D1_P76 zZiCTnFw)Ckx4}s5z}u2$NU+_1-3DXVBqG4e>RL9ojJCl9>NXg$Kgbr6Q8pMFAG!?& z$Ag_8OkiqlFaZMlQju?<_&*f>vqN*?zpwaTW#dqwy$vQ%x54OpiGU+B`Ww=^4F<GY_&Zm9zZ7{w*_)%zw&U5h(^-c9Rq{*iW+Rq68*nfBC(Ie@2 zaKC)H{h60c(qpUp%a<$8oQ0%LqLZ6OixUxbGI}HU{Wx-NvBX7^E@(w%Hg+_p+Vw z?EO-;+C}!QR}cVyRX(scnN6TQ1vVhN;nTft{r)LkAN={1XSW9Fy1v-e)Ss`b>k}Qx z2b_IN7#WB7lyrR~G63-#`CHK51ERz4c_BIxtk&S4VMazL93Cb;_OQU-8Tjsv73nAA zb96`i92)WDab~Bx2c=eb4;Hm{@iWD~q`TWwwb$2!NMDC%zl9Y7!4u?v3L)r_1h{hS z#c{Y9Gi=~+E8^!k+$c)8>_;~#0nxW0-ju^>A{oTtW^7*zhg%W9&*8*Bp4bmmF7c0% z!wuLjF&s|(^S16qxrpt7-76R$qgg{Cv&JzbLVWfFq@3|ljxtN6VT6%bSM9MC94 z3E@T&kerP8vKU~<1~N|h)4CU>9G1`Kf15z%(>09!N^xaElY{lw)WLBtPg?h)Q2DvA zVW2zmu|KNTtM;PAV*ia+J`{`d&sxdfmo}F;q=N^h!4D!fPf8_>VpP|`*}DzbwG}o7 z{kt}Q>v->qZ_9;Y|?MJrZz`cFYZA>rNS7{aPr}OvU&)-g` zcb~r#OlQg}&J#Mb`~1rn>=#A<01G?C34J#kScGhAl+Ky)yZ^uzN}*Hae;fJ=8y)2% zIyB#zg&CK{f}CAkGr47^7aBlZP_dEe-z93PpNT8$WD0&kwMBv0%anC&eoeXIWmnKm z9ic}$YzieQ#?ymx)##=7ULsyr=IcfGYV|8fKPs-gOisGIB8eE)`$N5d`S#P|7e1X9 zpQ^PpiupEO!qe00H$L6#)=!PE)c77%eVaO~-KgbNOIMhIN}FG>Zu1kHiTbk~y8~OA z1(iSIuS$rM@*OSa5(KtKO-ye_2BGwo5w{{vd}T!3gbYCG;R@xF&4%jJ2ywF65DvPs zn$0f~aVri0s%JaIO~@!jr!(S-h*N#KBW`eG5f-Tau`DjO58^~;0OE8wIMEq~xCw15 zgfm!358LEuMh9$@iAX;VpL-_a_0YB;&j)r^#9&8klfFu4B3rYh(xnLE{-S%4nBHG> zHS+fZgb8TyUuBx5a z9IU^Vt<@9li}3zX2EHt~$DyrECQ$ha_#+G_@QuUi;+5zA#GxR+)`qJ6voc$2Kx)oT z_6zdGv#?+?m8K%XCrnrz$;( z4TZ{PcnHacAU=-PzZ6>>l`s2K$yss|ofKO{=|S*oc&C`&wLA3dAg8p8`1`*Ugq$}1 zNU|-3ah0kqSI9YD@OmFeQMpJqr;6>+zWxgOl#l38d2vF!%T^Wo%vJ+|S1@hsuV^2l zNA$(qEdMB>l!NUf6^QxR1z(XV0LEmQMe&Q8oUeTULsF2j)Y9?enPfTzc`>S1E{c0L zNqKro*-n{|uOG;aj?|B2OC>Fc^YpZySFO%GEx1>!i&{E(h1YNTL3pi-K0fUIkgngk zh4O$eT!ja0@Yn|z)wcn(1>Xx&UKjE0X-fyDevsWMP=CRZ)_|Mv2jYuDh+7e-^j?S? zk&&sNN+E9H@Ct}i(L@KxriTvT$LN3#V8TaB!18M%?uiU7^R=i0bc^lVrBi#>lal-| z3hd%$0a3gcoeq4(4FkUTomV-7B(KZ2vaBA1pF;4<-US z5Vay6$>G%gW)7$JkLPe||F>1!T!-1^5|J#-NHik<39d2>Y-p(4gOi zO;tj-zn^FE%N>h9UYfW1wD#W1ryt!utyjp^`&|dR>}wISp=i4%Vxe~b(kin>9|2Of zyUGQJWi~z^|9o-6FF#sU=sP5{Rh8RMmO1(M6a)jKE;v_x;GAe?-OlseM&iwPS zxgJQ!{n!4&&|b!{qywei^{RI2N2}}48%K39>in^#VOd|7x{Isc$$flS*dNC(gyb=OdaKWc=jGoY`s0rg6CUr|o9pt! zyRE`w3tTXt8+mS9qaj@3_Rr5`^7QLpxrwmY*Oi&squYe;Hg_pE_zIN)kac(re&p$q zOeAN-2+di9_hAt=dXCDZe7RcB!KZuO`nk~qyyEKUbAVZcWNRkRz45X&^#jS)W^5;F zcV4z8+>50HS=@*W5BvdvWa~u4iGF$Zo0uLun9{?%0(c_gL?39Shs+(w=zz>^K<2e# zy=o&)N|h`+*vQ<myxbDAupb zpnigPpDsN+cy|Vai+9Jqec63)>84ZfUcI_}#1eeeyI&XYy6?BB*tcJYPCc;RuY1Yp z{jRRu#9-hm?8WY($&4IMHoHW`Q!9(t=E^1V*nM=XdG0&q&nBmoB7A-=S^Rx0KS(1# z(FtR}Q(T#Jtb_H}lEp*t1=LJQRHZB^n^;ttlzimpVCA44z;s6MHCm&Be!-!m%r1~F z5NU(jKP!{PLsGNf)h{qG)%#sTH0;0sv@9+*O=@L1)*lAQ=;Ycu)@O6u=Z1~-j(R@# zsCanPw2zh?z11xEOjQ54=XvfG4E7#!@#g9+TTg|T`Y=zI^P^_myQVZ&0F4Zm)!0WYWA$^a;M5W?o*WqQd!F*AMtnBFBkP1uhnQ=OoVYWxe1qJ%gAHHqZ?ve& z=@Gml$~^!MEgAj0WLY?9Lc8X{aq+{Jm~Mg)9y>MBQKkh>`1aHy?}@hyu`XPJ1bO}1?neWHidqn zkRGxo$haVDnvqeaV)?*tfagNl3NM1K+^GD1k|=8`#Y`Ki6u*N+5~lnOq&O@WidDY% z&na-5cOBk9dNGRiRm!S>o7o=(URI^{wQzJ2k(J7|hgz_s|y7atMr_Jr3CVkK;`*-bb6{+0o=Ehoun&v1{*3JDZ%ZsWX zRNLA(D(FgckLeR8*Y>5Cg;+5A_xH<;_V!gR`#8?if~I{us_ti5;#!|PR{#0Uzfz#n z+P=;&w;jz=+T-wTQlMp!{sL~6Laq_+_~|x z90e!jEVpag3u;*D%Jcf0A`{v^McQRTl393qG=~sQvMAltH6vw0<^%knwO7(GcT^^% zej=IBii}Hipg+=6CN$yL=4C>%+sUs!8%a<3J%_)R3DIAdWJ39y49c~B<$K-HwSIc} zXW?W#Gcqi{)^EagG;`^xecx7@@Da8LHkE`M)s!+J~$zyRVECO8B0mk zUZ&HM2`RslcYqRhvrJS=CajL-r&T8G=V1M{WWvPPlnDo6`Dv92t!M{zKqmA}&G#ci zg9Fe7z;Qp)rp4v%dWB4wX|ud0O&zTzv(WFtnpz&uu3T-A^=7U@2NrCuaxpS0$NiQI z0$0xq^S?KK{Gv*}NdYI~Cis1kyI_Y;+PZ(~Spf+UBQ9WXse$ z;mZPh6N}!-GN8$Vku!=}#vcCZZ2rF0J~^Mm^LW_%t$Ga%?{v1&tvr9eS7zb`>ybKZ z_g2`t`of22vNUVnZPu`sjVFKEz4+m-hchLW+`iD#rOErh#jN*w&efsB;eB-a*e);^&lHMvX=rb{9J~AK39pw&CB7h}-!6s4)d9HZS8fH7K$8gvKs^+-^N0_a8TY9a`$% z;(AXnoxJqCg@69O7ko?QEfwGDo*~cj24(%b=gYIDS4929<8{yE%z3YFt2(={_9;8y z`nrzOHg=C5*rnNoOZmI+T6g24=97*6eI6Wg_j#vn!_qecOBAegW%%&ETeEk1r-ak@ z52Akj`j1DS{`yGiAC@jYe24kER_e=ve$+OXDhi@%{qBqj~MUJm90N`_wcS91Gm&mZd$fi?>?&swqNFL9oDM- zjb`B=Ht+c5!kWj}KQ&+T~mE+d1cZg*Lf5X8XF|XO(aEUh`ju%_-abR`Jh5X8x4uc{skz zw_UD8PtG%Mm&?fQyN7-7d&>=9U4NLPPS3>8O7uN>d+&=vhX-3md_HJ+=V1fy_x7t2 zbEW2oIR<-HxNYoTZqtOveyH0z5c<1ZFod*77gyf@_5`;YcbY(r{**CI8@jBH`Pjky&{H8HSr9wlm z)pM&H9ul$c-2YZ?%~N;BO4F|$JM?~j=wa6lnlIJ-@hBWRal+_@pBFFr(}iPWdmWpTvxad(-Q5o(j*T`rcmI0s z!Xg7NM%Nf!>UyqT&WA#?9xm_k+3;!M&FXlx8kbbG#*(;JIpZ7OII*H;|9xo!7>KW8rdq0Qv{UsN4asY&xe>o@v8y+6onWWTay z7hgKHs^ta$`E~aGYCbz>OOuu@XH;$SRkgWsOTYcR(cjT5nAO2FcUB^Bn7vBH)QlqC{k7B${+vew3+^yE5Arsof-uh~m(}v_9f7^LG zXQ5+x55?a9$SddA^$%+8{;^E^_G6Q4jOpwW{j!sX@nW~{KDp7|x>e?$ZP2V@)RH#Gfh^v8PN_XAUrq6{!-?|N2I(VF=*}?;>t`*-B z*r|21<`vss@DFI)YyRru;|pDKdpBkNw~N{6jEedHl|D)3mo15Xu>D4vKPrFWRBrL$ zyskeTYS<(q@4cBxdCP37y5@>k-bem-y4}7Ox;^{+d5b!nJJoH|zd-&?QT*c+G1Rh_nJd`_=#fBRsI z^THlybJu=h9^iF<`jQ?cTg~aTs_W)YVk)m6GkeyK3*W`g%ewLR^RvT~#!M{V-u2d$ zjgh%Su2x-gIJn!2kuAbjhWsyn?Xw~^vnSb zp8I(0lgMLJwzjN4sdS5iJ@QYWA+O6TOU|g3`cO|XNTq-w|{^8 z>otGAT%pm?9(}rhwQ%|#%Z!`_r_bM4YlP`!v{%FR@0Hq8w7*lfYTHf>nAj*G(}7`e zk)8f*-glAjl;zWF4z2!CbIW%hw4S+fT`@zAc+0M7FCRN~2>r&p>4KAECXBvaq2H7J z!$!D&Fn!{lLHC|RbTlZAgd|SWR`rgXc zMSR;A8M9(?ks^J@jjp?NqW8g_r@x%+>0bR>a(=gx&xUxd@#=bT&-+6Tzh7jq$NC<- z7tI)&boqx~>-Ps9uH^smo!}0Yy?nR(~M?3P(ON6y^mH!#8yd*E8z%e4+VKb)EG{CIPn=EF({Mi;znT35H% z<&Rb+erJu|V|m!TnAe%*wJtT8yrM(G$uDbPsJ`Lr#!o+b>bs?!c_H=eRp` z--}&W>V1&u>tCX?lxuU=^ZMg44~89!{kF@3UCp`_AGtc9cfPQw+>>8eO3eQ{m(?x$ zM11HWYK6Vt$r)nE84B(Zeg> zXtKLrq2q(XPaZCkR3l+QY4e&qhZ=1kzCZR!(QZwucW!kk%4zf}?;$HY<+$H?{O>DQ zFB|h|`~9T@v$Y>)4@3jvx3oe(T*o!h#2R z{O%vwysF>)HRlQ@Y;E{(=e02p3r4Le7yjGu-zRqN8j^c{tDfQin-$@?e@fD{sOaXs z+7yq=(!N5=0q(y?Uh5w?u;-K=9yN;BEj+Ka%d8f6_uOwW?!fM>+w+ExIiGc1^(NQ0 zjsEe_;d16*v+WKU^-f~11>SY;wtmvU+n9UX#)e;5Tt^RctCFSGy02E>n^5AjZ50Pb z^jY`S_Tl+wY^{}Pn@6|YVg1h)I`5rr==?qNdVVqH(2d*`Zbk1ixqt95xb=psr}|at z>>dz&$79Dk!><~{>&*DL+^5@TH_Ec7Thr|$cOJYp*JIYI`jdwGY#ToPPPS*!cgNOP zJE(ZVftyv1)Xy9Hym;h+8N&(&Eh@kKT)7b|K3>?$=W(Lv^hJ-3zU$KL)Xiq!_xq+m z#j>Y2o{gFq+jC%2m`mR5v&!VF_N3JIoHdiSv@ARJ{l~w~fB$FG(d?POu2rDo)anfe zcTc|KQ@@aDY>rkx)R+(@geR5lQ8n^(x#z|zt-U9BPu(qORvE(>gj;$!;H) zvoMKm7Rw}+7R?X+G3@sWO>6A^ zB+DqDKP=U%xW&&ewd~>dzdU@p?Dm5Ccam0}$@_Kv+7ISeUGz!rz}fDXZ;l_jEOL~a zbA!5gTF+{Q9QzMM~5t zwBOYI#jf00EB4Hqx1;xoI5O{02uh{1EuvuBwYG)mxN#*y^@9cK$x; z`bqCC%j@TQ+;rxcS&1Vro823PCS9y}DBD2qZ@>0A?4H?Y(I-DgUEEPJK4*avMdw<| zlSEtE9hY>gz07k^aLCrBpY`onc+>F`Q!Q7Q z`nHSgAJ;xxr&Yf`y;pK@pM_8Nw!E3M!~W=JJN_5q-n&HphMDTuiO=%o?j_?^J(&5> z{b91z!|zn^f!%$(T#wH6tX*>L1`Y2%|E2w;CAoVy9sW2xU+K^O2s|4Q8I{%XC34H{)8Pp{Q~Cf zj9)l&;CFQocuiYLrX+=XW-2_e+W#Y#M$^_};g) zd)WrVmi6tw>VCJ)YpyojQsOWy3w)bsu4YZo^rXRo2c>00ZlfRz6Fl6@9?9VE` z`{N*=(zPB{NXi`V?6!GnscSXezqp^X&B$lhrd29x9a}WhP?y5zCk?v#bIT!#GnSZ^ z6mY-x-DjCgbdRq1uw#xTLRp{6aX)q#?A*5B_3ld-&VIVN!IYXu4;Pv{@9?8PR)k&% zH7s$d{ku!ly7(W?=YE#lzt_E}V-X{(WbM7i&9hx52O zQufj}*IV!Q2=Sd=-7>52t~n?ETru9-?~_3{YHt59{L$z?%WYrub-Z)J;`L9f)+pzC z<#1H?BX4H<74l)qY+_st&;J$2#TT5j1I{=R*F zs|nS1Egv0ncS_^nRnxaGiyd6rrN_Ms=fCx9>0N5l^cLQALq=qO&*??`UI%~keq1f7 zRQOMsO*LL@OW5OEbK(GxWo|)_vNmis?7=&}GaB~sTHd4X&|`^fuY6H@Wc`b0?-uS@ zu}+)*#?5UnblO$v2ag)Yh=|rr~eFc%`|u4lFHc( zts_I`KV31q;;z~Ql5cz!Yw9xLTJb%;^UiHQoax5Iz1MR`Re$GLndh71RyO#t<*??> zVmB4*R$%PBLl<-1$=R#Z+LJUtDXw<&uVTI<`-+zRMP4(~?Jv6hMYq4`_7~m$^6#?0 ze7*0zWgDXB71`Bd@+XQppO4zuUtG^skmY0AL&y7p`bmp0?EPQ>TF%dEjv0Qw_tk73 zeLMenar~tfpKi3a&$0i#^6geki}bAD@xZf-1-Cw0xxww@97|)my>R>K@QFgRJ_)_i zDc|<>A9>FBJp9&~eM3iGUNAE}-~6TR%gw1Dmu=}6&qsKyE-?MZodXw~zplA5|Cog9 zJ0iCps1R2B>h`NYwVQWkLG;wmI!>AQgc-rB-1(-5SN?)(-~+HTqx2=DW+}^!;_{_2Sk^1Am*B+~tSln61sP zpWon;=aWYvBZtj@y7Wx8hfn(_FSvfly0lIY56^*y@x;WNFIJxBOyQ6B%UAaDXe!JY^-R|$LzOv1PO=06IbXs@xrs;J52fywdd9k+l z4>xKg&HH?5q2f=>>!QkD`@v^a#k(^a)PHZ&H=q4>(0kL6Un>Q9kN7U@cMJAB`eIXu z@g=6sEOCF{#5wbWn?$^9mbB#b%m)YC9jmx3@t1@TOxb=ZwQ7pFV%KUFf2q1|#ff&l z+w(2j`0R(+UtE5BR`x`dW^0!mS=gb#>>2mxZRp>+>V?AhEK|e3_^QaloV6FNcd2iR zOS-w`vTc4FG|?1M@Q>hDXAjMOyyL5}ouli|I9F}o%%H?WmKII#4Eyr% z!_p(CwTt|4eXo$}{ud&y@A>{^!prPgk5_RqZ81OC_|+ftHpX=MxYV}=+Ey)4%itg1 zDZ>2a1PS6+;=<2&Zv`E(D=vuy+$@Zbn#HVB1J2YsMf9S2dl#eZlCkc2hr=kHEo|? zcFdBC?w4c@H11jDLlMhk3m=?#DQlUDBdh({c-{F0Wp}syW^#>to1!Z%o0%`~ z$>+;{Jlt#AgUMl|PQPrM)W|#EupQNmQN3n=U#(oxOAE*D7pyDu{&}$C;h7&DSsDFa z`#Ht>qn;GlZH`ub_m(qc~zgyfW@J!!pwc2d;$dbSD zihVn7J~_7PSeGo78g+g5*w1yEl+R@D?O(b>&qJBR!?f99`YkAh4G$h}V$0f29FdXv#u64pUbD!P!KAqe1 z>m}Jc%^P>UPu?s0!lpNw`dK^g6?Z0uTMxGurgd0&I(tm_Ll451Z+Kx^k>zEDZqJRi zewkG|Y{6H%H*cC(^=z*#Bf1^?HRhDl;yUk|cE&U=b)tELALj)I-8|twf5*&DSG&|Z zai;XgTU>h2?RE6T$T|s`j}*@TCW)uo?D-EYw5kQ z@Z9?EjsN!JLu(QqRJ`OKVDwtta((+-NryJN^lwqRK;;)@KMyR@;?pCAn`i#GU!_kT zw&-h|a-#SB+vmFmp4d3GbB(7*0>a1V|08&He7>sZbNBuB^JT``?^gTzN(cA#Pow4+ zJC4kct|wStr||oacLna=VfkVF=jD4W>b5Xf_tuw=_Z_kH zhhpWn7pd7HtKY7x^SZt}?Zvc0U*x~>!`Q-mm-eY0y5j;1(!|1?Wc#>ERPbds3}%$SDg} zq+grGVV^)E&VjP)i;Yj1^82!OK4EM-s`yD7Zci$HF_yf;@N2QRuzV;Un+&QWgcK1k ztPO1W+{ELUDUQdH!8dTYi3-8zBl^@YWq2I>r74F~zr3x!WJ%Z_QZEUDfg*VIVprfD zBi_>`q?i;-L?E^M3tSDDk-I=YDuXY(0gRttDL+3?^7*xV$vg~FDQWd3tBv_3Dk=Z@ z@?n}#o8ObM{hFm@6=QsUwP%Nf^$cQiA+38-tzJ_8SMN#n^Tz{U3=r)18c0YGx{&$% zr+!arq@ojzVzm@!5=sq1=ffz@_h%fzzQOu8pBd=5|Gm>o47X2Ko>qLz`?qfw?y&pe zs^ZfIC66wdxb{iUm_kbq#P$5{n`(>e#z=j^|JTo_N%!+NXN~&xdquer zwSWFM>iioz^N)Kf@qNc*iYZF|NoEm5y34=VM)>(3WK14|96UXeMQy32>>(q(4~sZL zFN!j7S2ewYOCsL#_0xJ@KHcj+M|$fxaCQUfIPCrZ#_Kr5$E4$!vGb^ZWE}^E3+fLL z0Yn{#!%4?UL>%}F0_iwL>|o+2S;s+~$_3p7=o^qZi4N>x7Ih-TsXkCfdgw$o7#+}k zXdp*oy})lC@JM7Rb)5*m+bJD`31{+X9@ZmjN1?VmuY{MqD`QiRX1rBf}(^4Xkf z6DU7j!`QDBS0=pZVEwgpDmtj3nUbhVSx`2zv`tDYmVXc{2kii5kxlVcd$!{-VMiOP z_Rq@pYzL<5%*{0H&q@9-p7Y~E=ls+<9=xl{q=v$wbI28}?I$`zEd)q!*_u$5cmS-w2aNqpB zyR~TZ`R|M_w&>^h9PQ@M<;vr4?aNPv&OpSp&OBXKW!k`L`Kw#1ZS0glX;rRi)frsr zoS-3xv&`?jw*9Bgj;xQqe!qTm_hNY(?2Vb4#N6SFve0lwaO6LJe(qPPtjg z`vnk5)7gtD^tJXpI*$_aI7pwWC_WPVM@ye{Pgk{}pvGP_RZ+f16ydJQ`4oPFbUX%l zdSmG=TL3SUY!TAl$1lCb3+SJWJj?JMMjvDX3e;ckB5uMT2#4GBc=yB7u;@d8^o_`f zFqewOYoM41D?QT^#B! zuI5YsUbUw07Z8~0Z@!#UOyWkd7Mky3$L$~TgJ{`5Uj5A%u_|e`e`Ip>%)mNv3H@&7 ztl%*|_HkLU#FT#-Z2wSMlTDFDsQum`SqJ7IwIIK96hAs5>vUJ7S4R2qsMMpC>1Zqx z270*iT|~HAUFbLEl`mKM4p*k*%g~a=6vIxL-7fBE{b2r)WvBEOoEU9j$&8ep@`z=m zv@-R-qjnkM123dw!ZAesR0{D#4rg$>$Y5aK0a?p{kHDY#w*eVL9uKxMmEt?!cK)5V zDQ(v+L&)?}2Fr!V174soNP#PP)57D}E(bZ>jD$QfGbDp3wXc!GseRv8nQpVPky$$# z*q<_Zu^UyH4hQ;FOq^Pojz4RV%EWG^TTPjc@+)}Zh!K^ge^SMvAw^-YCL$G-Z9M+7=R}Wsqbbv+ ztIWYaYj&}0`+xErsQ5|kJ%>|~oQmdh8NdkXp2ZYDaKljiCB5IdK#$(Jp%wo-_6lgM z^sq~S-2>i_+WfRR$Xm)|?=u_FXlDD_5do|E>Z16(r^70m`3N`@s>|XC#UsYbq>qVf>(HFLm!aN^QyG~D>i5?mPZ-*$71g)|J1An`1u5+ z`kMtIiizJSRz~w(_2$?g+#Eeq|JspFmo9v>Kk4py({IY2VDSvLKk$A1rt0s?`JHP) zn_C5&+2H&Q$P)59{Vmp`pT}Xj@AaqUxD;f4H>{*FSZp0csZbNw;^4i z>H^8}P%O=hfRkSY;7S?5iuIFmyw8GjCE;cu0^u!{8HRB$V}sZjDgV4!R83|uV+Wfs zX=-JLom{z8B6btqYU;O?Kdt)hek?z&GQ%?m>#rpsw<-xVu-d3|uk$e8X`=OYZ&oaDf#gyQ!9(;WC50OyZOZpIoZ5 zUHevBI^+0gOJvdQJC~im`8=fU#D{y=tZaXE&QDo$M7%8b@pP}?0-ZNod%P$x@BPk0 zZ+~9w!Pe8iPj9-SXsty9b}U&CUOUgW9^>l;U4PtXkXt#+u;Y^~HL_M7oX>5EW%*41 zCs!LRE@+J#xB2;&O)DCmn=rDf^Qp>LpYLrlc#!vm5(WPJZhCCr$kX5YG}+v_M!9}_ z>L1;?Bcx=mu|4yRdbT#|$gW+zZ??#^s@ICTM|(|px@?Hgz(zIwc0Oz3o~iy}Z{f3p zo$?+oIdIbM;aHp~#$;_V&$-2h28q_|E+sD~&Ut+O)|bn3oan#DwQJp& zs0&52 z&e(Wr^OgBuW}ZFSsqxj!!vcH#@ZqL2TipBgca7Ovb@Z)<>gDre{ogJ#c4v>Fe8szJJ>+3_Nt{5yA*b;bw zLV^NU^1qeGk)M_O-5`k>2}NSX|KHw~z*E({|7&fJHmSGe%98B+7Ig^`Nung#N|sWg zvZYkgh7wYwv=S0gQIV9Tg;ps_Bq>@bNgMw&*UWY9x%d9Ny!ySbH}m=2J9C~h%QMf+ znfab)o|yxp0lFQGkFXq~Bl-TRn7EnNz#W1kcX+gaAuI%gb+oCO4njeLXL;JO0r0!)^pWUc7k-72M0yR&1s?vHQ-d88(DD7;j!1{;ku52T zA3)`rM0!k!kFeLDim}$wek7C+#P1{jbndLo^3Q~UMz)rox#Ki-2PkfY5t zh=BRba1D(m7!N-;;*xf<4v9$LfsX^i=vhMaKM7+g_F*iVUIyQf{&|e0$U?tGhp`mt zF_t1yZBe^&AI3sYbcg>J=7F&Y_o`35L81OL{t?G5fSCb}0HsJ2n6wXLK|w$d$q)HD z7#)T2G5;Klr6kv-^N{-N!ANA#QFu;B#jjeRogiUQ;8-^(aHY3d^A@LB?xWg5woaCM z$rY^{f9TFgGH=kxViCKC_ZQ0uu6M23i|=7r_%~xLV!!UK7>77E5~N7GWQNOVH*o=+ zJ(#@GAB;7CNO}TO2x0kj+a63_i4jxK!3iaLIHA-DCy-?Sk=o)GkT?aAUHW{ytapj=jt-d>0ObH6#(Jdd+n z$~9|doNBnk@qW`o-VT*DzHtA7eCoNqij+s0J8ric9Uy-kdSLLHOP^lv%(vSyZ6P=? z8SnZq16~>=R(g@&i5al49cG~aPL4eMP7dI`4>JHM zbUI3BkS>JgIz;Tl3>`QCv&o}#eKzDB;?Sj&N+)JQWLeDqrAs#Ca&leXBQ1z~0i;k1 zW@#@Y&i1*(vv1GKF8#+RTOvGWEX4OBm)Uuxhe}JNhW?T#{@P^ssu>HH5GQ(N|s@1 ziTY5G-|xf(*jjF{#{{SykgcvA5E|xyJb^=)po)6c`Mo}H*^`)n0-rhJzA{VLA!uuI zbaOuZb_Cx3gZ@6f9zms3k6-}H10G(FupdXq_orL}y$T2bbNICl5Z?|Ef%`-Em01%W zU@}!0oqs}DkePjl9c*Ab7`3bR9R~^Jq7q@Vp-Yzb9Vk7pYrs2VdRF!wCt>;BweNV! zCjYGLJ944?%<#-(VIu$Fnpsg*kl5XQWrDDL-CvZCVFKkY+0g#pwFh0=oQ(waOB-5L z!6TO8D~?^O@m%WgQD5Ha!1#;v$)l&u`dZ|$U&g(i^W;{myV5$s!I#B;-uMWBG;;Kq zp|kv7Vun#^HE!ZTNrR7HnX&qf=_d7AQ(My1_Qsr!crm>^>(Ye5(LKGSqBFs1{pmtzLsj#@DM6ZF3)gAK4Gze{!n~*)lSUNr$<0fNQY0MzocEE zp%f9o@CRtbXN>|QtS3CcWJpJz5EcN_3k4CN9{}eZJ9yny%y5}dF3O(BKdXH=D1CP^ zL!Ta@L*i^;2DG`Hx&fV0r$E??{(CV)H}>7!J^gKQ^oY`*4*pZak1Q%%n`d6!aioA`6u+a@no4z_9JIaG0&Gl#%LFUJgcTRMErh>t#gj>5;ozZ(MjKe6_J zshfJeo&mK35i|6TwFk9d*ej^f>ltXLx%RC+5V14`|8U{L#5uPQGxV)J5b+}DF6^IQ zqon>XvToEgr2O?$w@&xYRt!GgG1!kcCkhQ#epPu1&?~CZuGju#R=pSJ&|+LH`7YTw%A;)*?4Rk5&ME;Sq)_F^(q6&3 z>uVFXwZfsBuT~~m9vi!Xyx`H%>)Mlf4_v(P#LQKQr@%v@;AMzs62E(c%9Pg&9&hGb zbA_`kMm_3nb?xTyP7%W|UY_Y|*%EU=>#zymh?qPobM$}om|`i7zhACh*f?BUM>g$e zvFby~h=Y8`&kVPl5bhbN^ir@`f@fWl{`lCb68HAClQOn@AF}X$ZY1_ye?xVXbmZVO zNB3PgeDjNHgjeg%gb9lq{)5Y-)f<*ph6_phk*E9Z~b9VpNm}BVlHXe@lcFbyI z*rfJ0MO|#bqn^h=s|dmzQvyfLZLcYPdF^4LmeNcwPUSPBDjr@;iF6!$)O(a!$n_~d z)_jfP4>(`1nHu}U)lD%VI@z%J)Q!j$KC3Q#v^9*d_;JXQAS`g%Rm_2XOqmSQaeOzA zQBcdBsMa()De&3&VIxm|9UrT8wBIORokyX{oI{rlm1oFwZ;mzk#1eXJI| z>A%78oK5u9Njo;=WM?#uG)TYqazFhK#FOXRq)KO7Se)9W4wBz}z2>Il#Ho zc=u0Wj{m~B5xpC8FgYKB4rI_D4WWQL8ln$#;GZ5w41n&^hFVDY)!IlO=0K9`@R9tG z--kJr(Z}f6v#03Bx9j$!gB!6XpirBk3wn-Ti#ZZXz2}*bYS-<}S6)*8Ub^vtMYFDs z*okdsftKg2qyD<>_Aqf-fGyYbCXM5AHWjBYmWVk&)u!BCTCMU$&sVu2{Qc$W86xpZ zf+E($1&!4yuG$oGDO%A=PB7G39PJ7H&6tA;reV}WF=-#_9x3#Ik@P$@$`>t&<_zQ; zyCR)@Pk6M)u6egjFC7wHe`4@Xo<_M#{d1E)&)v&?h@!D%zze^<6l>ug)<>u5@<8 z`UQ&m)k34Ini zTfYkCkIr}1!14#@hpdM0$K2@oM-ADN&`TnWA_HXeBS|Si0N7F3(A4zcUKQa{3Ze7msmb4Js1VzFf)`8 z`o#3$8a^s?FhtKDpyPrb^K@b|nqCg-=}^Pc^kCs33ynp~rY@B{ zR9qz++ zHv1m>!8`osljVG6=Fex`Gx!-cK!?=2ZFkAWhFtTK5e=G(Qe!DMrz8%&Ji_Fe{_aD2 z6XOJy58d=`vuV(3zdNFwP9J@DO5}dOcIVu@qJ7@|c~8^B<=wMhw%O z5~#YaWsHMX#N&R7sZLXz{Q`>#?T)|fZvW(*AE7HL5;WXN(&y|Am1e^hE77*4)(sOC z9&oSuu-zbc(G9Zj;(J!!2cL3>Hf$a%qoq+&=@YVzTRbb%^2PWmmd(CX_UDwp4IWnO zd0ur{cH7*3EvwMG666nc5ybAl9g_oWhQ}m`@9tvqokRh^42hVWRk^q@(^1>qW~474nC!O%uP{M5aow^G^s1 z0#Q;rNz_m(#FX8}MpCu-TIMfVP6#7K| z!8HxO;NrHz^1F@6Vf(Rx$p$oOUD?fB5pvhf6;4 zlJb_Tp}ryy-wZP}I%>8s&1LtCg=)4A#g|4mlG5)FZ%q^R&6U|QXyZIjtJ?81;@0XZd_tgRK=L(zq3*?=@ zo#oz-5^_(g`m(<+ztiz+-mVAZKU_3^>oTxIOy4EYt)@8a<7v@Omgz z2Jnf`!{60&_B6Huj~3E5V&hA%x4}p4K*TnP&I;Rrw(1G2B824w^n`J+!*$Ib?ic3+ zDX7qE4RPlK^{q{V7VLDC&LCZgI1Y4RS9<&g5>Q~OzO`v62#ze@El;!Ti;5`IAWPZJ50qA%Bh_(m5{*NdnF5BpzxGJWsi} zDY>M{A=qc@Gy*_TNdLu9Y$t(HPsgu8A*AC&*QmY$q{-BeuIVjtUZrcl#=bKT5E=7*~v2Z+CoBt!+GC?3p}kBK}P`N!pt(xH41|JzA6l~veHL`U&BVN1Yk zI}ix*G>W!V)n{`USCl}eHQWPJ1mK`5+xw` z%*thkkBIq!a+x_Ie*mj7s|PVZR+x^MAFKK@(w+$f%tpAU%#i2SXOMTv#;92V~n5*iZ$_hx!c)n13cL-w@ITVTY#mYn&cy z?b6k@SW9;7(S%7efNqEVfRlrfQ2Z(?l|-^6&{2B?5a_5q5(so!SNKEqUgKyTqC=o$C|BeOVF3_@ zf(X#x4hNP5c-_^tXlp{bD0|Spc*jcbh0+hjN5;a$^sMw=uCRRY+~6Hbk9-~MCJN)@ z#j(jhE4`N-#9iIhd!h0JAag+f2V{Ykbp;`_pj}{>hm;PF4BOA1j>=e9Sw$6vF6q70 z(Y8_cF=!lO8smjR<%i{3bT`hMx-I)I`&-%8vPH28rmlLe4`RJMo=+Sa)0}?7>XUKW zxXFR76Eq1zfS29HaLaCk3}{#xVp(=E95EfjSO{}%C%q}JVv;{w7_JNFWl1;BwY(FY zMoBrkQsG6cvTyOFei!3X7ylekQnDa<&bLWv)6Hk-Jvg;5x^fh6w9IwmBA1awIWl5Y z#`fbR)(;!&f%s?--TZB_XUmc;+QYIZJ&84*^F2eHZ)^#<+_oyuM0oNQ&-klahe|*K z7LFdn{<{9y{6hg*ap}l$J(eJ z5Y`TW(m`@3W7l}Bjp#(I4f+Rg64(#K&xKt|GdQ!=m9W65rJL>>5T+B1=gDaD+(?_6x2@6L^^DbJp?*x zzdzMZl$+2c$xzxF8!uY7$+2o%UHaCD1k{LczCS`%LVb`ULiOSy(nHz}R1!h=ip8F*>heOU% zx?CCSieYo5F4>7HE5hjPV{>ub@JFHY^Y6gsR93o*?XdPBgM=L1i&o2JEdEI@$`7zS zy6;5IGOe3;>XS$5Z(_)VKd^p0R(QsmZ~&lJXxLmYD5`y{zigbeg_&_~_7x|0`@u6CErW zj}d6hU;*?jBO1UMa2iA;s?TC5qKgAAh~*+ILyX97xjl_V!5D_eqCLHT2(*YeNBKxVdKILjd@wTBFPQg&u3$@mY4Q49WT&VD=?H^C z2t~Jdr~?qPyMGAAW>oCb_7QvLx%E0o)8vbh7l=nfY<{gb`>Kk(K;F`sl$iON+Yt;-=g&0#fUnv{O)2zZ#Ma7 zg%R&U`E?f~qVl_Iw^#*-6yo$vls|?MRl4$xA$3(1cmxmo7|~9c*4!itHOLAh@?7n{ zyf8ZOY0`m5PsN6FPS^E2V|UwceN)H;m%rS_qbI)TmmKW1@X%jlPpFj2X1>h(?!&pZ zwrbprTdBSmrB7FkxV)NQe@(9ZbMrA1TgmQ=a$Y>FoUr2kfWhZCIjyxev)H~MW0u>q zOG~z;6}DHrX>`%sq&tD9JV@x%nxhH)2Q(LrX;zny-qJEG+R>@(U{>wLSpyG?s5Gw{ zbG0q$(~Ah9V;^pCRr?+IKpwYDeq)l8+V>h?{wG@obM`a2n;7E1*WN6z&*||z-@PY}_ln`S?;pP}@^C)+J!GQ2QoB>X(!=AggrtmF{&?etH=IE#n_3F2 zg^$nTTK#Uo!HSa9uYraI_KUa1`3u^s?pkA>HLSYzOr%ti>-y!Nc;7Z?-tgs9b6k?k zIWy&yV*QO{KZPEMFCLpPr1{{sq^X}bP5CMQ;pNn6dH1G1sZ}uHlUaJ#-8ffQ@{qW* z-tjqA=VEkHRzwunO70Fa3yYJC;&1dx_b4%1wxs$)YRVJ0Gd^nV%fBB!^~!muk%aw# z<4*hAtJ=#a-ufgZ?GnGM06xl5-ljntcq_pDF&y zF!|uwPdb_-_&2va8ad#=L$@~?(ysDG5?KafC7M-ZZ>o>J^Z1o|K$6AjY zzP(aif8Fikm93+-oDcmp3cEkTs>m}Z@7P95mEbAUe=dy9wrvzBy~=;vT>j;>!1D5G zD}-CD^_|~c5NVMAi6hgM%8spA zw#qatOK!Tualg+Lee1PtE2qA2;H%ift8XH|^u}Wo&J!aao;q1SpW|e}`uO&OG~0cK z=XmxRnu{O5f8qU`7|tJJPrXkJTYflneY(W^Fl7PRkgq<*0&hw-LIwfd>98W8#8g63@-k3%7`V;;&_r=HxEJ8JscPdw!#hEK}5u!0gHcj`Q! z`~6irl*^LezYz={VmINaVRekQ;KKE48+if;ElV=L_=93|?62G`&AF6Y4{G;KmE^rK zXLQ+|vYAy|qbh@r%Pbv6Qqpzh-`C`(kv8PzM>EocfOWGK6SVJ1@~Te18ajC9ldZu+ zg%-TY4$^EDzIN@Wzg>O5B+W3H^Nnv?Qg@uO_|)%>9Y1A8*bs7os#8uyQeD2O-Qu?! z7v1HQJ(8}txF+-r`!sH=RN0)Z*LQgByURIUNmr7Cd%@UT+i98g z-aKn!TLi`@>+_GyS``)dO!DC(QRj=2Ye!zOy?OkW@WtcSk_~y^zP+1x-`{Z23fqVm z@s~eqT0j1@`Rc{XpH`0gB$KbZ@qtZqUH(_Ad=J&MB9Xy$d@nhj+VwWxRx2H2RkKCw z6sL6HgV(lt!yYctJ#+4@+mZ!uL+><<^)T7&|6-#@Y{a zdUR!hvfitZkfj$Y)`uP3+4i=vu5r?GAId)2F=Ia#nU#`WC7+HmKlz~4HYF-{f|XN7 znafho!K+(DuYSH6Q@1&*TxMO0O!1z=j6 zzquq3IsVXCTopZ8P=(%^Q zY3R3~MPdCi^rg3}L_6vxS#FvWJ!15D<V$FCoDnw&P+@aR>@x?|ghpPT9!x+E)pY=f+pxvN8Lr1PwwO9dYYyuY(|FQJ5(99ERw99mOJF-=3DcMZ)hZ>+;_5{>iBc{`=b-j9Bos+JFfLWL$Qa; zkEPr1RSBELsE#^uc|=KxiZpjWZXwB)k`mg>Hct^7V!Fum!<+-xcO}JGoF*HFLVg z?1C9BnisB*(oe4rDM>edm>l-q7W$-08t?^{azYrxaiHlYExECNwfo>916=qLCqy+Q(hE zbA~iOFB)b(eot!35%v8)4~7h!IWC!BNQqNM;xb3o^STltEAMWK>%@oK#D?oT?^9c`Y0%k2=PI6G5)f+5 zFPtq}bp8cjnOJOe-s+IK^ZFGThs+&wT|!37e*efFo-aq=D$h?;v)tvQSK}2RYM=h- zZt3yN;g6O%rAf9Gh0Qfj%$YRqL+YRbH`i;w89j5D#-7TE2`iFsmk+Psv)eb!^^DN2 zr7c<0?~APXvB2W9&-O94URARCrrNjH-?(^ktz%LNpVivO?Q6!HE!ghy{YY-b-0C-b z?zmqs`DiFmdtjfem_V!8*29|W9|N_gxLMy7Jv~t)X2K<_6CxuMYv!qazs5Cf#)-jq z?+ITpbQ)&a?r>^H;ghP_ijGqalk5BhmNjpjl(D1c@Cv)ze=S&baN}m~AXm%&8_ovD zuL@Hb^Q!!M;egjRu7TSxotr6pK6rTlka(r($##YHVY+&Wu6&I?bFUW;l@20#WT=~_ zyKCK7tGbrH*5XO+n_=JLmb!f7ZP`&}tFWhS=ZbXq&+GMbudL_J-f46o$LY3{;3DIr z;@Y0PwVaLVr&ERo6b8uDEp#ukQF1+gNY%5p;^OqHCw3)^{m^nRY7x4gS(LdvIzl`{ zuVU^P&b9lM-{tbIetSIFXXaE6{#o%PzKlxB+VqSki|)^t9co@~6jE<+Y_G`Nv~hy> zZmhraXy-(Mwc^QB8Z;M&ottV`oKwvqbxG7|Zk^vK{g+D*I}JOWB;-2dor=>3*$Ylz zrp{Mfxa4qNmWAhnp9z(^+vcC*cx`;#F^5aQXO8QzVUaD{#vJ4mDatq3Ot`}~yY)vRzJvfOV*+cOMlf@I~t6*KJ1x4 zz;Z#({y=&DUDrgHY~E5+@MQ6|4Ndo>=gnPyUQ8u-Y=K>(w$8f1yIPV{G>#9-v4Sy*?$J}TRx2#~!1Yvx{Bnnl)qd^(UxT{l{Qd1lw&x-~s%?;Zvu7oFZHfH5 z!4ggSEvf;_cbjdEEt9R?kyaSxlJfe~`gi-DS+9O~MdzkSi|qQFfv4h68K&PdvDf;Z z?46^&O+8Vqd{iulGEpgoCV~ICj+FcHuWfiaN!jth_RsIf_?gM;=l1@`Wqr<}g;z;8 zf~_C*OZDO~`w*G6G-kHNp#EONDAqEGNnYOs#wH9FHlHe{?=O%(Ss`mt`CZPF0>+P? zHC0MI9if$JH+@I*24l+OTMx#KaK2R#?yt2k#Ubs`$BKimk5&(`tG6-#GOzUhvLmOY z*Y29u=%KbQUg(U@tM9q<20FHttc-m>GNFW=DF5c{5LMq#L&BQIjN92D*K%ASx1G0s z*_szZJMY{U(ByV_B_tvul9#(_sU2si+SyOj#Kk4wtZ?Fr*rS)1C3&-7 zKdbf(Uy^U3aIGMiZ$zr}x`F07M~Y*{=fy_~-fi5a>FuErJojd+^wtuttRF2dbtIeR z`?aLAqa0`DUY{6gW1VU`*LdDhlkoGK*JTU8yr;LqdXv_Tez$p?6GyoX)th$bbA_JX z5}xPB_fc#V77UuAoaP^Ea{1KI=+&m0Hti#~dmX)XVR36H`7e`(82g)?f#T*89{t{X zEz`et`81D!hS9OqJqH$9M%~#y^18#vmlPl44I>Ov4xOz`3h#eyTCDaNzmJ2LZ~k1Q zbUN{T{@qQ7(<%iYRV4aNkQ02e!LK>y@O_tnQ)LJID`kz1wIk$eN*DUS+G;w%;?0Bn z$6~W;WZ(00u5wJd+4Ow&%y{ofvNzoeZ+Tj_1vjb$o)~#W=44rMd5xdVTSGsaE7<{K zk6n*#nh>b%IAy=IW4O=J!gs=kLq3Hn)!N-KYkMHFVY9%cAGaj5$q{uarv`DT27QtC znD9r;E zdtmCBw86XP36eDIbUdE0o4e%pS&NrSceFF2Q6 ztzB9^ETZk~x&C)}hYj90Px}T>wrPEtz}LSPT;J7n&HRx2of8{BtPL9X#c%2CiZ{9u z-!qRZPPOo#;`@!evFXbLfnu?3Mbkr$iOqL;z$zKe5i2&gX4I}xd7 zG)6i!O1J5ze@!__t|fG~?e2y=!zin&wMnPOA8BiIe0ctg(>yh)G8J8gxi0l~$*+R; z*Su=i-fE*XC1*oa0N+&iL291{E}rzlrSN)bQ=oC}R{Q$Nl(KW&8YPQ{cn9BFUA1g3$fU-% z8KsZ&weDWcigL5g`o7_L#HGW#)_gv>!SB%McTxwc4ruG1ELk$)#N&&%sx`+fjHnV* zjJ>+0dZ5n1n31_(DrX%^*Lk8W6=cx#rSh@pqjZajZx$#O%yN3U@n?VYYh%p(EM|F? z+HA1qTbkUa`T1Jp!{pQ}W~)W*4`f;#EV=Mf#X~^g*#@h(k=zT)JOcz}U-{3!QO6hU zW~wx?SxmY1bwu`uFD~L={DKMsHo3n}_<5+G*h zr+?|wzx3%}`t&b-`j>x~{zbd&8=uhxF_Co9QBk-tpBSXmzi>a6qU~`*_QXW}i$aH? z3DU!GwqGdjKmDPXlJx3~VPkK%gl~KB^{UQ#p7Gb$4EN%UE7|0)@bcggj_gwFaU71z zmDJMRwcpL26aHMnSm5B11+|~14G#o8cVv9+7Fa)x-^QtB-Su^>QmK|r(6~}~VcPXlgYRyXqvu}KY3QsU zm#=bp%1!UDDi@p2ht{nrys>kQ^p9mB@(!aGk}l1AV03zC6zR*JXTBdRIXAC;ow8YQ zWZpHd$>DsG1!;G8rHEgeer~2tfv3jV$Ge3p`7^9`nQMs@?z%E0f0NmGp#k={w@bLy z>J^TTm@F8>U4J4b%IB+n&2<}jQ(n#)>$kQT=kvSqrQ1Yt9QIm#+u1NB(d@R{rc--1 z@ei2(%-a6;wcMiX)&oYUBLrxidSCBJSUNgj@t^U>MbpaN;iv?csCAQ|e?s}adw8OI8_||Gux9K(}ch(Q& z{_5lPz&vqpj^S8gy9vg;$1iE!TVMRC#eUX%NnNk-m#?h@W(=4VIoa;4Uds>J`=7rJ zdPW+Mx}v;g*ZMorwgVWzl-gZbJAb4`w&#B&J77Bu668uK#DK$rI z9cbX=FwV+%sC2?}eyb5DMV__}el`9>;7Wf!pR**g^s5Y^nI zaffn1N40uxnR1$d&eS!Z^*rJ))qN@1pELYv^@bRgj0c4$9)9MppXcQ@HbiG0$zkpK z8~!Jkw57#mjt?*n3rQX_X!7)+#>wy3e)riPzB>F$kyB`0SY6P-ecxns_gV0t^5&fO z?fIcmPoCV>8F9dW^yHK)5{3zbk65f3K-PE9EKE<&`7|s!#=Pv*Y%ANX;s=(7=j6WH zDJt4vc+8}6rR|ijb6(8-oGsTNPYM$~lD4=s`hD>HGa{B_c7+-WY%Txkab?gx_p?_8 z)6?^RXzL}2uPv;L|DYN6f`5>!iO*lb2{T-W=)Br6C*Nd(=4j=n-6xL>UTK%Lza}?Q ztoTOo8iTc4zjM8{i%NDVnD}sGwQSv218a^d?l4F9m`T=+HrL-Qy%Djqzxwi+iJr3_ z`805<9v;gvt3+;+yrL}S=JF?va|&9lb9BTX{kSu8+q$Zj*U`0?42LLaHJNW)Uh3?U z%74_Wq|9spvw9fOUkuL7pjkZ zjWOW3e74Tu$>miOF70}yE!liM`%qH?&HpFe4$sGM%5((r{=53f#AZ&fwBu{R~~LtuvA{=deA@(n3}`}M=X+zUYs z*S1#aXBR%3{#fmlT#Qp?x~Su)mJR1QhhDB0zADmxl97#_--Sl4wWeQeKVI~iam}_u zc5v2Dxy?I0rfWVluY1!Rq{S)NGF@l2{g-%IFmd}`bB5>*j58krJIo0P*ToQQyV0U$bNTsbrShP-^ z)qR<$7yZs#hGqsgU71jzX<$1=ko5HZn`;Y4P1x3Ow!VLO&A{+l;$%X9jb0%TwWn>g z>RGfI?bQSpjBIldAIK-Fr9gfJa|voxVtzwel*@vQilh0&{8-fk*j(TpD3=+3c>5X< ze-b8mX1w&Y%@=Y1K~JAg2l~(d(&h`b1G4!-Cj5v_#`vMyd_g05)UQM#-44=G|3Efh z0l-KEb0{CQ{~!Py6oWYwAMHPg0|&)m4zwe3Jz*n;_8(M@@5mL|Mj2z5z;-NmVh5dO z`oggP;Qu|(4%>R5%3}Wk-RX8624u7o?ntE9kRMQ8C_*YDY7;v60d#!7weh!G3sWFsb7z z7ZST_TgFX>2?-u(N4#TYTZYni*S2gpxucZs+Ljr>^mtxDn8-gX+p_+`9VxqOTZYQ- z?*4-+(6E?W+TqduiTq=>W$In|UYnw#LYHmJ)Nqp@g~~~XZP~x@{22D_^J#))WuM=- zH@V~cdPLm>9D_K1%id%Wwrvw>08edSvP@d~)8L;@1vl>$TMcR(I&?jJTo`okB=-9U zZ8BulKL(pjT$xhZ9`CxPoO<34?GdF9(CL0izux;X0m^!SM7aXNvICGq+usS zzo}&Q%m~FtOz6Gf>ZjhlnL9^p6h<1u*e^@XOFCLd#;^_G2G=V@5 zz|sMCmq5paN_DLSx*epGp`rj>g8WhY8W8BHeOD9caZrx?iFC+pE`d%)mH0!?Q&J)f zTx4qNbp8opLC{o`P7*cL2nX&)Nbl-9(;7m#D0|oq&?U<~+bBK0Z-PX`^c~MPJfnq{ zD~YrjmXD3AbPlCQz7BR5h4B$H+2o(qJ5v=980NbB&VPfFssbR#6olkVFQK@%^cTqN3Ds>XL%0a+lBaq%n<^PXSC||APSW?_g3|MOb0d zU%#_ZS?Mk&cvr*2Z{W#st3FLu^6fu3TKx; z;+dkVy&Rh(`4X`?!op-sQtV)J)b0{6eiiKCD1U^_?O+3={6RzX1f~WUA7JMym_IsG zbS9+lhnN$3O!l0scAP0HPlMBhql{D;K{PWGJjw|F{Yv~v%mz0y#4=aJa{C~52kO)wH zdMh?%7t=w=fT~LZHVDidF&-=IjGxy*J|I6L4bXo#HdX7xra;WJ_C(k;7j|&e&Ip^5 zVFTmawI{J@0L-6=P1WF>OoIjt`d+nPU{fZ?Y%(K3Y`Put0mOjErjK!Sy8cSQnj|Pc z{8^nKN&xl)j(Aq59gH7G$Op-rcvdHBpFb6wYSKDFhdjw09_?QU3xOyU8l@wEuuXTd z>3TxBD0|p^=#r&g7NzelHr)x!?=CjYWs`qa*wo-}VpCLp02EkPu_=XpY>L1pTY6b} z6%`0&**_;K7dHS%=m4y`>Qy^ksEIJADjFo&w!%E2S6nOJ~=n~eG$K!tOrb4RgQ9qDmfCXPA~E9cf|Cp))Y^`h~1sL zDu@L^CWvHKbC)yheBITnRKbG!Lm$jtpbgm7s~~;n9K7(bFp+;uuc9VTowYjtez~S7 zrv#4#WPk3W;3fhJl^>RK7yD~Yw2J&gYl^&RZ{w`zM{9%MXw|+uKT~4%7}4fH9@Q() z4&1#ucCtc_+2O(uW(Uh1NmEpV#qYkfBs4~!-hfUZU=4z9%!YS+dX5L!f^LrQ;Rzme z&EGk<3t;)<=XO^pr>?FUfn+^_1w^rYs8|3#lY-F4^c_^XHw1nE4;Em2pJv1h%~PVu$rm9vwm;k;o_jeId+e zh8?!UhPH$8x{4i$-!_KXFw9-7umeip-S^&`u-@Ip4s@LjF^~DMo6#t&u)}L8zwTlO zRK6N45MT$OS3=K*AmjkF3;wx)WD?SUnIZ!8iTukds>vyK1v{v!ciA3E95IdYK%w%{ zlh}caYeK@&@u`IHT3Y~lUu?uL;D z+|8W2K~=S7~LHX?sxxvVDbCI!)g%_Cj)++i zos8XM%gzb5lLU-k1sf9OgORa*!MqoA>l+%dlQDcl1J2pdW3*?Imt(}Z*d768VBW-N z{ExLS5dh1}b$*o%`-TSO15|$?s3dfmI6D4$s3Ov#-1toi;;C;`Q63H z-fZ&E3M1cz^6M@}M&+Y-NAL`RIS!5Qzrx5>aDYd9nvm3q^2ac;f^t_d^6%BJb?)Ot zjI#WO2C^v+ic!tZ92)peS%~Cb6m$9Ab`{&18{O|b-8A#g-8DHDW5(|J_{cIgJV|NC zCm$pQoKKHoI?MkRM&|OBm0q*2-^3vzAHrQXeu#X#^Gcyh`1gc8$3CX$dR38SIDjBbPc@N)v9 z_cT@^=-1@2F{oGXmqhJA#43nR#stX>s{r}-1ojZc^7&i(HF4@Wj7?@PHOcR%9e>kevXVAYN{n7xNXC; ze6n6pJ89;T_u{Lawa$*5)y9))p0xL_HpRqq`Q=%t*FgU_V+Th48hdAaP~R754+Sgv zI!Me*z4T3XqU$%*l)%dkr5~%t0e5aI#@pNK-(k74?8NLi^)Jz| z{O;;s?y|{0D-6{L2S77gO*;a_`h#oOW$9v~@{yh3Kt`mc#!VU&DnI`L48?OoDt^@h?F5OcwtT@=zLVZ8;+DGSdvu?;+p5>o zw};idKe+tHx-g%>q&nYg$+~5-C-oZILkNxWFU3&&fK6JbL>MZO&c!tU`aAc;zRn6m z(dHbSc$nb_8cQ%9evZT??PMJi`>X-@e5l4Qv=IjjK^ZhD>7m&McOhLE3CzUso--$#8em{r8@lnE5Ld{2bo0N zfAyzhtu+M9K!$Qco)8vbhPC40VAox&l|d*Ml}8+ZF+DT2Nr~eqO5a_ql?Ti3F4k&g zlYdrNOAz9V?qV%ees{4JI`54QtfemB6|D7p*Sb3Gu~0{0xz>ex6v6_FViQbV^;#dq zdU-sbI5ejDH=j?%yXJYEzCQr+zcmLLx+x>aAD@2h~wknEK4{8MBDQwJvP`Q?Fj@LRg`z z`W+yfp1>BOSU!JmtxJiGwJs$_SfSLn)&-t%;`2elXv`dOJP^Yo0UB|tqrk*{Yh6$f z&_nV=z79r5VY-+^ffCZAxU8^4?^)|om+z7-d9T3^=3eF$%jQOoz^@DSP-`*qyK5)I zab0ts%o$rj?(17#-1=-O{a!-NV~Ewg_1A-hE*K~@y>-|v{bg9-a>|?VqWYo}EsM2< zBSR+>%J0JtbOHf(9n2m(;@C)+2zSw4?9ki4k<|OK1CwtUG3YKBcdN_8?-ijnCoqm9 zJvQhTeReXqhXV@|=ea)Y&><7drk~FB?L+Gjhbf&@82gW`qPk+&Y;5Jbd^R9jZvw1P zsQj>8;}K{3+-BN?z)J5xEr|G?NjX~nzp|m_7?oDzCLWYD_`6}|_VCP-Pd^3p^F?z9 zKU*NF@uMWKjgLP{GIYny9SdMN%)DNX4Q!az38N8pgzT=NEW^_N6W9RLJ@#t70%`}O zSFnTa0^|uC8T$eIkSfdv4&NRB*|eFy_KV6u@1 ze#OH8mIpjMHrS7&;&S&q}XQ1m)M=H3?L{8Wb2SFfN;o4Zj*`Q@4f>PqYL%{aoi%ii63{WaA;*mFuiL8XenTEZ;% zktXwa#I?AG^9W^SI*l~9i5;Ab(qKNlUZJ!6Ut)*jS7xk!W4cLwfq3X}Pujzn5bNUz`~6 zLE@u>pR4fk@Z&t7gZ%JgJc|3f^$NZHn+T{K5OxTFfi1o$YXSc}GO91-;CTIi?fv8kph!y|WHxV5tW(yjLG zWizT(+g0W#5z6o7*a7Ln3AMuBH0d3?*x{dAlfd4Od$ryHwF4150C@sO#(w{9?7-x# zc?Rsjc(}a0S|4@*b5|dBz=VKvm*D`^UA;r!nnZ^%f2ns+l9T%v*+Q~^b{hx$uFgKf zcXfuj2B*F7xN~UR79oLqxDLfCNRJ)5ux0_jyF)0SgOiJ!dsu4Z=~GdndB=Wi-BQb{ zV2s|&v4aDPs&yATEW`3+2HA;YBa32LoSwxPn`jG(oz2~=u>)!cB6a}s1dfdT{@vI? zoef(^Cc7@w`>;bFc3@m1?ZXb>sV9-TyJo@mxw=Yn3SF{=l<)ev9|1TcH43#>EbSSr zyS`@8wm4+wsXCd#PbEdZM7U{IEae|Ar5gI|w9IpNn7xoCad>C(_~58R9r z11!y#_@5ho@wMRz<@8y)8}c(E*00cRDhwG^#yh8w${hV4J+@d%C_@aoxSr%M5f6AdXQEy+GV)i%hy;hJpwz9wyx!-@DGJhQ&OGP4rRpB#ESFe z0u`;yYxerQFCG}L8G3~8xm49;-{9%K`CH>JyI;49m%9@a&j(rT<=A5{y`*VZ>|zhF zhKG02*u_79JroprIrc#9fUrj#6e^G>aAfQUum=T9RG7o-k$TczA`a#+2z_KPkqJ8l zT!v*l?^J=wc^X8$1=dQ8qz>$n0Lud&ejTk9N5}UoGUNx`26QAB0|Gq`yGM0@sJ#T5 z!;u)sC;)vS%m-~sf!D}G>-~0+&{cbhAFv%ze#nQ-i7r{%OQ7`K)msdNou#|>5)^!A zqjAf)KEi6vLmbYxX1KHsEZAJ{B(ju*u!P~?65g*0s?K?PsEe&Cp_aRcq44@;yFZJJKH#9On5=rXqkJL z&nt2yR`9GF*RJXE!aMVf^<0^k_DhV^J;F6T+c+toK*j{uRqTOvSTe|hBcarLo(ZXT z-Ou5BbCO@I^DA0AyWLx3@>SQ}x$~xdFZ}C}$h_-=w@MjUT^O|0_wvqf$8P6s?4vKVVS9dw5FOAi4B&oP2JpU0*xT8Lg}7maOi%NaWicxo*h&s7Kf7ay^0apv3GtsrB2O!R zA}3dR6*RArSRZn`t=7w_Hu(kj+51b!@dg}Jp8pUE^EYD;CTlv3dMPIDBL~={Jt*(^ zD`PKT;H)Bha*ilXa^%-;m6YCayU;b%>#y>fsGVLnE)@KnmlVuz(Y_<^CI9Z`xySjo z$7RbZI&F|B&R2c;jKbm0WqGD`n#j3FA7Q=mUN^8I1*GQ)4_Rm|S~hj5iKv>JNPD^u z`6l-O(Mu%%=DjxGzkMPP&Zu83`DE#Yg=6AE?|CjXygxebrfTjhuWI9>ZLPZ5rc+-G zIQ81*GhgMykXqZESrJnHyMqktOg%px)Rj8h!5~cp9hcN^9l#)+M|+>gQE{q58kP8t zf-nOu0t^u2;q?^wxa{hUnDK(o2Zf2{vf_{3a(jBM4A{Hl&MH&r?dOId`F2%bC5p)b z=&|Bp2SxcvKsp6BB+`3<_U#G%mMoSJ^}JY^KRUxq2hvx=2Z8oHFes{+oHN4udp=nE zGG@@B=>j#v_VqwMfEYmEKn{I}8PM^#$_`#2It9vaJAobtGkQ#c=t&<)Z9SGofpFEC6VznGhYN@2-9< z50>9u{a7oT{IkNSrVy8zp$b8tSbt`92T@V^&M*OZhQJwBNOvpRqu3R#$+Z)Mo!o{shD{#sh`QM^9qZ;!*v_zv8+(=Evz2r`5&L zMXGu8U6lrE+cz7`x<9!jSyc+J_BqtvhF z-&lBc0@pFw{M8w?SM#L*3VXjzYT1e(lY?X{_dXOgdpY0`$07YOQ!@AGl^5Mey8U`& z|GF}MuY@xa(H8t;qrchsQH9s}_dmy|9OksONm_kb=r3sxba&fl;g>JMTJ`zWGJ#*3 zeFyTV3QgR;X7DlVX5mLqf@d2J8~AF8*pUarPtAX|QcPw;`R;uEdHh2;?2itfzUP)# zl~`8A)hQwcQtFS_>YhHIuG7Df^8m-F#gpd_=b!T;!e##O7!&_b;fLN=L^uzsIFpgf zciL;vm(NnKwSpp!9ND_L)MtcD|B-3^)%frB3xC|tK&(<&DMZTQk*uje{cMFBht9S- zD`_V*#tTns-BXiiy1<%iyZG#&C}DTKg_kc~i40BM67l}wy$spI4dh);Unu;67B#Og zPdf9s&@&}iAaEfiV&1LFNjw(U3T8~(6FzHGjiO(`$Eqnc3)+rw1c;qm@_u5xfKb_( zSwp7OZ5~;+e-mbS#L{)Qe{$-+I^g|WVRQcnZ#USEJuhdt_w%02Pe$7V!;XsyOjW#Y z7oZonctpNia>F5Bi^+$?3PcsFjyaROg^dn<{QPs?=z-dk3KJq0Z_RvOY&Oc>*Gfa= z)w5W7E>Raj)SfolX8(Vswa0%}_<5Ppm(< zCeA4!YAY)&cynL5z?|<(acBg$B5)>0XWycye`sQYnyZb?v5koHK7^kWa z&-58N`sZb{v+1ha9UoklX^bCN?c`VOH+AQHPyd5qJSST(#oYcK>fQ_F|lxsyM?K{{&R*sL)tDvjJj ztH0kg7&tLSSZ)2nUwQ9BT^4x*E>`ZB{hK*l|RT|}{bfPOI!cDSzF&#`gd zkOJd*LkjS`p}sY2(2|{w(ix-+5yt~D>@J`YpE(Ll)whNX1pz%IKjiCRbQH$Nq+wP( Okx5)u*rT`D&;1_C^7I5BT9^@unB?z`I8qyjHs}p z#ysSQd8jcU;u!%W0!CDfh`6E;@=!6NVu*q(B1TjUJjIBZ{JN&9cB^Y<_I8%r)4QAb zd}_DnJKfdQ->UBEp4q;edfcLAXD>N^%rP1FXcMQHmY>F@a2Y!t4QZNGrqWU1|0NnR^k+>35qwK`wp< z<%-kHo*-+kL0SKt*%Rd6NhpubF?)hMdq^OoM$a*UOkH3`fppt*ko+wuuX)al0(sq; zC<`7mqd?B=Ksjf<83l6TIF#j=nNc8DOhWmuJIyGNYuBQD=6W*<8D!s99zq%Su-OabWvft*nq&3?nez;a_4QsL zZ+sr*>|4!VAj{4~x#D`W7s%C*pnU2+vlqy%cc6UzX|or||I9%7=|r;^$P>FzcG$W= z{<$KMy~o^X0y*$Tvp2|$Z78`(W^a&Jo`!PjHD+&+w>*e)UW?fq+omGZy51D^NcAoEZzU{vwpGK5fQ=Ja8_`qfeNzAb&g)<+=OJ zSdf3-7|6Jm7fc`%pEu(`4!RHJuxrdXkfYB)>6l^0fxKcd%DfxRIFQ$GL%G1FK`yoW zK(1JTvieRl4&>T#D4#mtj03spew1%cG2=jfd{H11MlCae9CnMD0P@O{QO@0ECV-Ug zMEU+IGXdn0=TM%!-%J4c%lbejj=bCivj1!|5#)%uC@)`ZCW8FOEhuk(+Drsl(u%Uu z<^@?j1LeBY%tVlzpGWzcEerC^`%xbD%|wvxRv*YeY}(4cV|Srst}^?AWGA7VxZdmw z@}_%H&f8}81$oc&DA!Ch`-1eeqTG41*%#z{=b}7vrP&u``;CF@XKpotOn%<%2jWdb zIq4d+AIPG+QQrNO*$?E}i72-oZ}tPZ?|hVPYt4QjHa0-^AM*^#^eJY4kYnefykVKy zALNoVY5HT-_HzW(%9K1kQp6j5=i&?D6hT7OafW- z9Ljsvnn@rZpNMkX9cB{9cbB1TTVW=FJb!l}2aH{70y*qja{$P(*PxvCpg92K;<+fR z?luR2+;}R=*KHc)$LFH#IL#bjW%7tgDEn_SlR;+Ph;r;=Ga2O687PIP&18^E?m$_! z%uEKkt^;NLa5EX?c6$!;jgwKnce$AivgKNoU)*mdgFN*D%5$w|GRQw|T~-bpwH9UH z2hD*XhwMU`?VAHZI_9FBaE3V$#Bv$P!u!mDAZI_1a`9|)AjoBBqI~FDb0El?`%!M# zW)1||@C?dVr{<*ALQmkP`*CVOaXb|RFq$j zF;hTZv~^oK=#I-!e%WdcvT|_yVw4pRnS(*BZvy#YhdJ2F%l4Uu^7?V+Wgzc)IFLiy z?l*zF?`d-g$d+9wPp>zJfc(8BkV7X9H-Q}WkU13OxLZ+9S!E6dIp=PatDZ84f^3|K z^58CWD9CT04kTj^F@YR9(PTjE{3DQa&Nms5s~X`Sct!6=cKlC|^3?Oa-}XEy}m< zGgCpn--2St!l@wJY<(cVxfbQGbInwc7ncPxZI8Q5Ad}BG(?Dh)f^z)zW*W%+R+P7$ zY^H&%d@7^5rX0?r$;EL4NTd%HLbfbSsBV zd=TZZGtFTj9otY&T44?YDZGHP{9bby$kivHTxauwe10*?*RC;#fo#4W<>$|s!$8W< zp*+`O4zqIj=!qyZo-&7n96JW(b(fpNLC$yr#jZyV2l>ydP*xpp4hQ+vdX(E*%;6y4 zw)#MRbP>uEmzl#so}U!Rj6F^;fsC7LW`G=UGD>EJnE`Ud^(gJfn;9VaCs0l~)64*Q z(>9cIo;NcrEgBKVoKq%(@lj*l}hS z$m{Gm$fCI@%T6}4KtAvk$|oK+vp_z7FUoz}%q);cY*~=sFGhLsTr2bhH}v}<_M50r=fgefjI(X!^tS$yxbfC^3a_qzq-pD0rIyK0+~Jh zE)&Q;%gk($DQi&<=JKvrS@{Y$*md-J=K`z^ca^)FjHpoXVLiwcC1@hVZ zQEr=JW`lgK73JO&%xsVcI#9NpY-WQzdM3&fwk*gWYfz={kdLlHS-0LC338Lw2XgzvC|`fx90_vY zX(->n$Q%js)2mP(v*kgavSmU3Z0!Ttxh;^RhIg1i_PW*_1#-Y#l<6;+qo%*Ge9@Bg z&T8|{YHRb1NS}4dd6%6d0AHr{#jLoP)faQ(VoqOd7Z=<0#SU??LtpF^7d!REE^)C- zU+fkayVXUnt$NXG(-#Fpo~JJghCE+i6byNqAx|*mX@)$(kf#~)1Vf%?$P)~Cnjudx zU?`^<$_a*YnxULvD5n|935If-p`2hSry0r# zhH{#roM0%Y8OjNUa+;xb!BD$qs9iABt{G|<47F>9+66=HnxS^VP`ksBFYXROS`Kdj zaGgO~U*tOBqEjaTTxXEhCD|)*(eVlZ?3Ey`OR`tsqT>|+*egL=mt?QNMaL@^sN5Zb zv?}SbSKy-K6#xW7?%e?{3WnUf16&jgxpxP+C>V0@4scO0sop~~F>E^3AE^3AdK{|U9pIvKcK|>znxV?w0WNBW+C?vG*9^6bUe>M|Y8Nrot{G|yf&H@1NG%4(I*}fEcMeG(#O?r0&oRb%=4OLo?JN#-R?)P={csLo?JN80ydrbqIz! zG(#PNp$^SZhhV5fGt?;<>eLK%3Whp0L!E-5PR&rKV5n0w)F~M1)C_eBhB`Gvor0lG z%}}Rcs8ci4DH!V140Q^IIyFOGf}t+WP?un+OEc6Z80yjtbqR*LG(%m2p)So(mtd$% zGt?y*>e38#35L2fLtTQQF3nJvV5mzo)GZk5)(mwEhPpLF-GZTR%}}>ss9Q7CEg0(7 z40Q{Jx-~=Hf}w8BP`6;HTQk%x80yvxbqj{N6+>QIl_8sUM{2L~#Kk|$ruD@tLtdL= z$ZM-IWYfB2l_9T9G32#X8M0|zvdWOxrWo?tstnn*E?H&BYf}t)ZB>SBT9p)YYR`S* zVp$P$YMa(21w(pH?TIO~bPHoe=q+m$TsXZ~LwrN#T z%&9&1iHl`O%&Bc!mlO=?IkhL|)Hbb43WoHY+7okXo7N=-LwZi_i8-}R>ym;YJ*W1> zoZ6;UNinDP+$S!UAu*@6X~wN2}if+0Pp_Qagprgcfd zke*X}Voq(-x};!8Azr?zQTQp~A6J*W1>oZ6;!Nx_hwQ+r}gZPU7>U`WrYJu#=Y zXO~bPHoe=q+m$TsXZ~LwrRJdFXq%XtuIzr9loAZ`{FsZ zP3w}?Ikm6n)V_F5ZPU7Bbx!T;IkhjIQ`@vIS)Eh+dQR<&=hQZ>OIGL9zMfP2Voq(- zs-&1x`+838i|5oftxF1q^qkrk%%mlO=?IkhjIQ`@vIDHzgoYF|93wrO2bFr??y zzL-OA3bcoZ1)9scl-9 z6b$J(wJ+w>HmypEIkm6n)V_F5ZPU7>U`WrYees;yrgcfdke*Zf;yJZV%aU399*4(- zAgwR*s0kMxYXM+ugS0Nmqb6K*tObCr4br+KkD72XWG(v>E;^$o06c02X|0z12^XDF z(*l(-AxNu|l`#P>I`p)Ntr)6|32;#}R2dWCqK=`;IvXxJcU}MlL++RW7X?G^m;e_A zL++RW7X?G^m;e_AL++RW7X?G^m|!nf#)KfP7^;j3a8WZ<857{5W~j2xhKrh^%9sEb zbuX)|v*DsMHvvE}6dDsM>ukuVds*e(6wW~lP+3NC7fD(h^x=rEMCg9P{NAT6y0fO~e3))zT$;i6L~035eLT9;(6 zz(r^51AyZ;Nb8auw{X$%3IObtAgxMP#y)$|oeu%PcZVRYOA3bEu@7lMM>e(pmu6pdhU;vO#dsaTx$?P>|Lo*&w*+xC{VxS&-Hx z*=2CiaTx&YvLLNWR$OK;x-J7ikl=a+E(#J{ufRn?g6kEyC`fR<0vAO)-J1?v6zz0x zI`(4az7nKWJ1h4Uxaf=t0El+F_Z7G(n&RF%;G$@XbL)8flCzht=&%-B{weSsNSG&a zGQ@#mvJ(9=s~oW;PAzbt7_HPEnN^Nv5~pZ&pct*>Q<+uX3nWe+cAyxo6xTAVoQ(;b zquha_wem0}v&wjpc-UJ`FOgZp-g5ek%o_HV(}QHzFayqPOJwEF;Xu(0a95F8V;JC$ zBeTkTs>H(#II}dFHOzq1@nqI;yvB7yp2*44a*&mHI9{FEoy;1JS7)v#vxdFp%=|=F zo&Y*fw6}OVD6__RizkONYmB#eswlI@j4nKJlv(9%PvT*3IkQQbH9WdFb4!^u>@8=e zDYJ&X<;*)}*08snS*Xa$lTinX_7+b~W!4yP@kCW-jqw&wTV>W5Z}B8nW{vR{PibY= zn0o>LI7?=Y>0A6-NoI|?7w`|aWL7!3k$Bi!&YLHZm0v(PP_(!Bb(G8+<1PNdm&_XD zEq+xcv&MLfe+(wG#(0ZgW67*B-r^sM$*eKn;#XWUYmB$}M`SW9FbTVs9-{K#_$*eJbi(lc%tTBCyeU_bq;XDYM4(E&hR^%o@|T_|>M&8q>G<$AdC!OyAF)&Pp|7T~HE1W-&?)e9hN6t94* zUJyVrT2(KAtWmrIu6jWL#b{N%0J28$3b^V80TiuOujFl3=dqRGo1b1eP>j~F3nG{2 zP+Qmqk;`+)8g_y6xJw!qc7gLqQf3XizZ!C72qIO7FpaXEIz3C`kD=Zp`Og?n-3H0%KGy__W?NV(T?7CC=q z%;m-Dshq{-#p$7#<Y?kA4 z%o^^4h&!$)D8>NY%`kUlSEEa^gL7`(w?T$jdwn)^AL?hegMYhe0Y?~KpgCA*wA8CUhX@ehW zgCA*wAIYyD$*&*DuOG>;AKA8SWZSZlZOcZsEgRXkY-HQAk!{OHwk;dkwrphEvXO1e zMYb&$*|uC{+j5a@%SE;=7umL4WZQC)ZOcWrEf?9g_QxgVyM`YVNBHPvx*|v_zwsl0dts}B+9g%J8jBHzH zWZOC;+twM`w$8}5bw;+WGqP=+k!|aYY+Gk!+qxp#))m>duE@4^MYgRgvTa?FZR?6` zTUTV;x+2@w71_4#$hLJywyis|ZQYS=>yB(&cVyeTBiq&;*|zS;wsnWwW*=L&h3y42 zY%ic;djSpG3uxG0K*RO|8nzeENP8pZ1U9c1*@}p}Kje*Ug%{ZhFR~S0WGlSLRz%Dy ztPK&f3P8gV1!!d3BIX2;H*A@G@)O}>K*K%;G|Ud5VRirwvjb?f4Pka5Z`j8cjqov` zVRirwvjb>k+af#v_sD=?|gB5=$Ta|mtCSr<_ zP$>~LoF~*45iOi2)D{sXoF`)f^zITaBo$ z2~pj8M71{&)hr+y;Xt~e+!~-EM}Bk4bd4EqCQQq|dcms43UFoooZY*MkgyjfOxwN7UfDey z&*^jchs^DNhqSFYC}~WKJ!|uhhSwC%p>2VD^&G<7O7=Y}srbYQb!o0WucutSb}9At zpR_b~)MHbm=GVOHRdX`4PG5ZKMawVEbhfs)wjG_lG&u7vw>P}D+!2UI7OsNemyzb# z-BqNT8W9;m#*DCm5_OEQSM;%u1%`?I;0HcN*qWn`5iy<`VMaw|x3%sW!oeRCgr4~n zfSCXvZst*miUs1&sJEVNmcDa2y=Rk~ZZM5cIjKBb1nOn%tfcFJJFK)`^6m?lFIsF` zFIm0}zn5@o`8g|>o7T54TE57%F23Xv)4J?pJXvZj#KEH zzcQSl@0s=+xOKR*=U3Bp{iW+a%4PseM=F=s5u?j@Q+Zu~kHz8Oc)~MdGMu3Aoc)H_ z%F{W2tt5qQ1dO)dFa~fOO(y&#`wcd6K7!2-GITZr^v(A3_h}aAw9Gn16Qas<-_5> z0BC*j87yY%xqk)q1+~PlHMN~~d~RI7JLf2wU=ur~Lh zo$*HyTH>-?*9bV2tgNNPmB3}?keKV~ zGg){Bqggj5?wKs`1`PdS($`R`}6` z=cxm5ewe0!{vL&Q63$KI{KpYqpe8eZ0^ucv&m%lT6Bo{ZD&a+izmf2=!p|T)Pr=N3 z3WWD4{9MBMfidU5fbc?#P1u9^TxQb&|AcdXc*Y#?Pd9GHFDJZ6IP3W!;bnziMR=Z` zIdOgqTZ*Z%a3YSrct*d*>XXmtyU4B^0(`hxNA^@KkPr3f8NGc_@59sjEPUkPqa8jv z;G+{hy5OT5KJ2f?;nNE~gF<#Q7a&0~y9Eoc>o*ge(*`l?%UA<@f^dERVQ%MO>cTS}CH-$Gs~u@DjuxJg(tc*#5Y8 zMe}F^!~HSoyP~e~SmSK2n7-M5{*HTBw3y1P;)csH4(Bu^Fcf?*q4I6y7?@jTtgu`7 zU02+@qILTQYRv8URr%EQ$Gt0BJqe2}u9U=tE?>Q^z%My^e^-?4%ywjgqyBeA>-MS| zkq?ql?}`FT`}A4ckbRdEjKRG>i%g%T_V%uEU_R@t^fr99EuS^_$+KD*+Ja}P@VluR zhaPKa3Q(g2UZSaslaHnq4yI4^ILvDToll?Zdnc>`8mUjN9dsS?T-OJ7HnYCI;sxxi z=NU$#G)-wV-0OKgu@R|cfd5Vo_<}Wlff~pCtKMfa-2bPO zo+1rMtY;SCWx_dsz0YJ=kA5b@xPB(XI5el3&lXOw`sK5QB6SdWwll%5c z!2Z|I2zc$GpAq!XfU2Jn1jbsM^fQ72@tv+|(P8&6AM8K+=C8Ol?Te}$=O_2`sfkwsO-p8YQ{v|nsyf51V@psV}gZF2`!&T+bQc z+7>FmlL|m{V3}I)nszfi6F3W$i9^>Px2A2Qb>w1E7LvMrbu@x~2>;48ZDGWT@95j# zkECnb+H1CSO95mO=Dct} zNY}LKp1yQVi~ToU(;^Rgp4fM5TKH23b*yQqt*oV%*G0RY(;cI*9Ues(!P4@({{qzte!*L+3Yo4z44)KPuEKIt(CYx0AKL_uSi64 z9PwJItZ@EKcAh#k>zQuzfu0iKtcTzKWhn4C-uV4rQQ=TsGvC|6Z@%RkXDiize1H!( zo9VnV?o^j3?e(p3L;6yKNDY^RDASBnNIUA{Vsz~37C zm#;PVDqV{NYmtshXaxz~*J6egw~#%n z%n8JmM&{~EMEP1tJ^sL)s*(D5E>^29xTfm^JDXXb9-nz`nAA=vSI>K*DF4+{uHN|2 zcBg9*h$$Ua;rBM&A71KOg!N3fju_-?k&dKm5&FL)!EXlX|MXPmJTM-nYmtHbw+_>_ z2#&nzS_FB}^P9d~i@=|C?tLxdw|6A|TZi&>bUtWC?0b>%$5#JtaO``L(ZR%J@bAxR z)>;XE1{%zr;fMD%4jpUt&XuC(VvWo->zy<5^OBePx18#oOZU~>7V4{KjvB>hJ>}~4 zmkxn+Zd>2nmgAG>wgn=R1d0dVwANL%)Ocil_a`_A==sRb>Ay)Hr&R-cC z_&Cmz&K>7b2bj$Y>6_cn-*NjymQ^~CtANWf3g`M>0@qej`6W~U#(H@7&i#p>!^b_x zF4N66Z_CI-*B>``Tu1yZmW6Fvm#=ny_&*rE&mFzC_N*WL*NOW7_QBG1)mrm`J+X7g zmXG#2cdRz3S#zsO4dK6oD))}Z%xz!N->L2p&+%iPLysJG{K?kBmI9cWh%YGM9O3r$ z>EE7!x~%8rJ`1TorhN(i&TCkIUHrXV@V6#GygA&#NtnNuMEb(zB|kCoW&e(NoogpB zv8nur?Qi+-gnTOd>hj-l!hcEY15PSO*!}^}|F!+V|FMGqr1e#}hr}S{|6~2Y{~W=8 z()tEF{~zxM{<{VLN$VTz{C}b!`0o<@C#`Q#@oyW`$o;cZ@V7Rhzk1=XC6T^CIR1Y! zA)k%-uS57RX??x;Z@|xg*7XDb?SlWL^$jZi8ytUfg1_q$`l}cIS`z6SgyYZk3HfYf z{K*RcC9SU){|)%@=TrT_zc2VtTHj#j|Av0x-xK^Nt#7dN|LK0HM$Kis%4GI0#3x6$%^bNxC{|gEEY{Y+u z3I8RnuNVIf`0@YNe&Bz);6G`74*%i)EBTLEzbE*8X8-rEy5=v_1b<&l=r4!AaQj*k z=?j;a{Ku@{|Gj_zd0Rq08ySD53jZaouNVIfc>Zti2mUjH|D^Q|cK+|^2mTKg{3oq% zQ1NdY)5!R7h~V!_3H{Xze=Ujh4Z`t%V?sU~@!!jY|B}|%i~k1v`2Xd8;QwI3f71E} zJO6j~1OEpJ{*%@>sQ9;yQR9bvKNYin`S*VR_?3Q$pD7}KlGfKt{7C*|)-UP%N91sL zOnfF-Ux(wruJ!MM!v9}Q7;nA!za^$L(=&xS*Ye}SU5YB(TosiE){5MYc zFKK&Yy7ym}@AH(+7_56F3@c;iLjJIC=-;zjQ zc>XN;k9mHczJEj?{OjI7?kVEu{yvVMMEb(l^I+|8GC=KT`0Yw7$X4|AYO&{|Lc<()tD!|F$uWjNiirf8S5&uU`0T zNu+NO-hY3Pkk3Z^H%$01X??x;Z@}Mwf7lQF8^M3l`UX4y5A_58yHBz#(*M6mTHm1J z-!`U^@ne_Z??(y!)eC+hxqxch@YhOIq}o~{7C*|;xobivIzbk?Fat|NYyttsnURKf!;}`UVyMVgJ_k{`@(?-!BsSs~7%S66qU+@&C(&e5(0V zUH*Gk_%CUFz4&jyk3Wy~1OGb&|4Hi`?EF985B&dG@Sn84!Os7$`hovv1pi6v8|?g- z`+@&I3I3DTH`w|AbwBX`N5Oy6`UX4yPxJ%-e-Qj9t#45AZyVFd{PAhQ-)|E7s~7%S z66qW0^Zy3<|GnV<$v);kk-mY>f7t$(-zMaQX?ft<2Zw3EJ>l;-3hsPiJ{wwDF z&cNUQ_@wav?-RybFaB>yq%S=FNd9Bq@1*-5(Fc97|1r#e%hL(tp^@?bHzNL$*4In? z4fyf@5B{Iw*~ z7al(c{P^>ignTyQzek1tlGfLY{{|NS4aWag!QWpK`l}cIS`z6Sgz^7;LOvUb|DOy0 zC9SU){|&78564f--}-_7M+E;#>l;-3H#q+MOz^iep}%_JuO*SbaQqDT`2TxCJ{uW- zek%Nzw7y>aH{khyp&$7FiQqqJeS?bs@c1L&e+}CAj}Hs~|07|%_2U1QMEb(xr{q6< z{}_%>Iljfj=S$oF_+r9%Xk`5Vv53E<_4N{elAoCPNw7b$$^2)tSOGkRSoK%|nidiN zyNAPt$}w!U`QgZnJ>6AA%wFET%W4=t%uL9>>+}hT2A|>n)wld$eL*c`ztrCc@foy7 z>X-b)=uhzbkg)v&LjTFu4ZEan`*AYqEH=U!!Ig39T8F6Wk2uwq6pc-?W&Jc4x zLg5SSc_Z~fxq1#=-vzc%BlXR#r!t#I*9Yb5sV~Y8T33__edULN#EWio$_p}(@?uO> zKT3H?d5Ib$0MoJ2=zXl-@w2buv)T8f{^mv3*X;K7l^>cNFDWn4JvZegHBnl&#&u!uBh#7v|PH* z!M>#VOnFIpsgAPYR2nZ~P5?=HNqGSV()m2bfu4t?yrjG!1JR#pyrjGU1O2`3Nawp4 zcj^2ky8orTq`UwF>HG!bAiYmV_lJSPi?*}b&lRKI_v_zGMlq_#-Ts~zH2Pez(Q@fL z1fxLvJ>{kEd5P+88jI?;+Bdokoa;RO-EY%)L9b{(q`aiOAOq2#X}qMo00Zed2jf7` zlT%(&UXX$4&oo|AUVwpgzKe07=MyO}DKE%C^k*6`DKE@`js?c$x4z#t`#GkzslUgw zMxQG-S}uKFfYGM?p7N6NBF7<}PUA&0lEzCkBPlN_FI5K8=S#?ip4X+kq`XvnNjR0p zOPCWtQeIMCfPwyAr>5&8jJtFl5Z(V$UQ%9wfx$Mf)A!r-c_hZU?(gaINaRJw%V6sd z+VAN+B)UJOyrjG!1JR#pKT3IF26QYiF28l2bbLW}QeI?~RMROhRW4*Ixb)5Z-D}o@e^1N;jCvK>!Cl0%JrT~c#&|{^G3qU3O|GJJOvKx zFR&iMS^v3&n--g}2kVFHf&B_!MtF&E*1wW)v!_kigY{o-(*gg4v;GefURL;3gy%=u zggsdQ8k-LE5YGD75^hFA?yCJa*mPjO!q*dCBAoSaAe;vs)_(`#MH-CQ{;v{VR`}h7 z=l8M+d$698O@lop!nxl22{(J&ggsdQ4{SQHU*QiEULu_JY$e=`wF!G%fM4cu`yKE` zIO~6s@Up_6COkh56|nvttcP&c|2*MAN49C!|03Z9=-~EXe7Nmz0S|<;o>7G7$76o3 zcO2nG!dcILgqIaQh4oBu^<-EN;au+w!p%g?&-#xdyr6KO@Dkx{XBX?)7xl3I;|VVk z&iY?Xcv;~m6P~9V2J4^CdI)Fz3kWy+yY|18@Pfh@6J8>m^)F#PlU(~RBD_dA+rOOf zvcfMTJbwV{Vf{tcLpa;Nif}X8wf}0u3ktuM@Dkyye;wmObaC z&%?yS9&CS}@FL+{?_9#oVVIxwpF(&+;inN^BAoRvWIczY9@c*r;YGq(|G9*h6@DS% z`5CB(^)F{VgtPwl5N>9=_FqYOLE-;Jc!_YJx92D zZeu-!bG=_7+{||Eznk!a!oNd!iE!p;GwV4L^|1aQ5nd#m?SF*uvcexDJb#p{=Sjj# zgmb-rAl$&j)gG+>Il>DH|2yj;ob|x`75bxTMLlf)o`e?(XZ_;{FDrb1!t=+V9@c*_ z>mi)=Pbb{8VSd&>oA83dJ;F~g76~YtbZ=yWre?%@VxKpc_ZN^!nxkJ z5N@)r{fh}NDEvIuLpbYM%6f8cz3(EtNI2VnIpJl6e~9pWJL+NmSF;|%ng5RwZaQ51 zuP3~q@Xr!nBAoSaU_G!PvIpz`65&O{+5Wo-FDv|8gy*|Z58nsBM|h9IzfZX7#{6v0 z!>osJw&zj8ON6ujGU1syZoR)Fyhu3P{|w<}h5wcC{IRHq>wS^%65(v;h>_Iq2w?qV z2rnpn0^udXS^s3h^DlRKIF#@r;jDiK;bny%&3cY^_2gI&;au;rgqv4je%5~i;RS`C zM0kmC=3zeT$)g_D|0cqVgtPuL2`?-B9K!RjboE?7c!_YX_Y%U*37DVtUq*OA;qPZX zgtMO2tmjp3y&omKNI2_XOL$q~pC&y2YShE}Z(==!Ge2J>+??pze<$Gug@1$a65*`B z#Cpg;*8c$EMZ($shX^k#{AYycU*p>UOV&d;>;DbmW}a*R(}Wik{w(1o!rA_vtmh=u z!}@m

OMPCgaH-Fx!lgcsC_Dq*jw`$c z{0W8Uh2k=e=-$5{RYr*v^&`#%d6;CG0B|!X8;{|>-@Si7ukw}T(M{#HcJE(_ukAoO ze%;=`Uqt@%E~mmH@x@&tSp0s_r;q!0rC*1w(?KR7cMrPv?^fi03>os?znquW0XZAL zpGrwPAl!Ee09Tj4W=3APptKQwH#fqEZ*vF7YT=_h*)MbX<<2F_DQ>a$Wp^^VM-VPAFf^ ze>t3v8=G(4d*GAJNxLhA)zRNYf~V%wql3A9o#lMn@Y;#eV79XzB*j& z`_`3D%3|kVa4nP<+otmI3lh?8{9^dJl(gG^$1m338Hpr>^*P=VT+==^?TvlNDff2% zMFR}h)+-deD+3F&^$H*a9FaT3T_Rlke#ntq(>^t`0~hxEB`J0#qT_(XieLC z1=mbU8Q;#o7)!>+%5jl`M1#_2|2-T(tRw2aO7}KSf)-h)D`?%LP6yE8R;r_f($jhi z7d@oog|KnF=gFLqei(`)>lLQ#{PTP~Bt_>EnS2`&ZG()HM4nGx&KmGeBA=3z$ZhXm zTd%CteU4JsLor7%i<&&YxkfjXV zYpziD-kqQSI`^Qk9k|uvXXRyf;F1<*2QFyQw;kBdLEh*xaKGmuPkHAcPuV%hHea4O zi_MoW_^Td^-8eFE+&Rd$Z%xq-__vhtY%WCaxe)!yz@PbgO4N;zf!Fzbd2T}_)7xAQ zCInq;O@`O=He`-KQQGoX+dx)oXAjK-31Q=95qkP!bpp3<&AiR~UX631rTz3f@0%-k z7;A1U^)|l_O z;if%1uHUnNPqO3M+i$1)TZ^0Zt%KOUHC6U3I)u1O^jQ3U$kE%kChi<+n~PGm64ODL z79^?Ftl16FXX`~Lv~JODhkxfMI9(l%vF?lduF3Eq%juHgujsCp9MQ5lmru*}955tb zhp=JG+-@$4ogcg+JG|7t-Ye2?kHe6mSFmqQIp6pe^&*jo_MFx`R;_7_s-XkRMhOkwWf$efNKC8>wOuqaN9A|9X zWp91|{h#|P`@Cr+fljHT#u4IiPW2>*Imh9N75%y{w^86)pB$|J6TTNeno@I=ZflvK1(QLH~A}9?9j(@6z|rpu&4QI)FaSomfusR(eq%WKm zNK@-Bdjnw@(z*-lI2x-9r}N-&qDT3AK8C_+Y!^okT)HfEx|L3Er8=TcuTJ;V;p*Na zmM)?C4Pl`=50I}*|E;4-?0e|?;P=&Wxg4P~^SLbg8uUHt+H;7`y3AaLab1v_``Ger zrTF=tp0vUEM%dF+=qqQEH9;Tg2hX8<+^#loDGv?r<>{xWYzZ%WdNzSe`b!AkQQ>z3&(MG+9nL2&Kk&VDFV`@} zz1~2H@tJ2S8eALYY5?zGK*IH_QiYE^H@TcU#(RLy@HDci+5C4d|MlmTRs1+vxp>>{ zC?8kjGYTmGJ>cOedXBdg-b9>Z3hw}yvz$16PA5Zq$;OKSf=fHvr*I-+ejQeL1Negq zZv*crJjF{i!B8aMCh#K)?*KopaA`-oQGb$7ODb|i&szHu=uy;GlBD8+J3%g!D8s!t zn|VN=t}B_4boIM#=0zMKa3MMOWQu%@p?Nr5;-i`!uH)C8Gx06Rf8NC`JQ82rC4$B8 z2i+4{{yJO5)zHs#vDiyk=f(H>-8uL^m!HGu6u!3$ z09WVl*xPj6dCz96Fk3}o3ld%5Y!#lZD9TpxKXPHp>F8#w$a#~rC$m)u%htRaqLVy! zu824eAP>YoAL{zf?5#X4Z}j(so2$k+w8l7G=vyY=aI;k~)ygZDE}{AjVWB!Nb1Qwi zjzm{0Lliz8ZkG;#d)*E=oQ}&uLuDQXTgCJSIX_+ah1n{KhQD@g6(r0La9&AITLm>@ zPggKo1vLTwJ~QuYf&rSXqUaa$tL2vq=z-8o!myj+#%vWJ1RSBCxJ!hK-w!!@wu-oO z;muZIwhFUVfK#}618!bRl&#{^SEQ7H*(!M6PxrhNvsK7AXu5824tYNRpATRnUN(&8s-WjfYEr*hc-p=2aBTU{hdL z&*1Yarl*E)tC;d^6;o!b$lI>jD!BD#{1dpe{Bi+>VNA;n8RD9)0)&7g^b^-?75i?y zW^($Psp;vcvsuknVYUjhRe+fcXsh_qD>6#JY!zm!Ks%~&AW7|yV(&0om(_zh4F(S4KTBKmM3bR#k|KH?R#8tV$kZl#y!?#sT zd$x*cvsF;_iQe7B2gK%8RNJ(cU(8lfv>BRaSGjBrNI{PHH6Sx)t4I>tufpp^wqHf> z{X7EuRRs3ia5f3IU&SBZ*B~l89BV)V`)zdFLdyL%hO!?C6(j$kxcwvo<@eV3aN8KO z{VJFYx#pVB3(@pBnAm<51%>1{Rws|u@wIJ%Z4f#x=dH0}+bZhP)A^dMqG$;ro7zas ztC%rc1<#+zpu9+b*hbA_HRe@FzZ~8DDyCyN`Y!x$RtH|4~&8uL}p7BrMGFwHJ zD7Ifk_naE0Q2+Z?%$lvjY!#KxWwwgdu~qE&IVQ8&Dr{awrMq?A=x_aaSBL@#>43Hd z#B3Ec%_Z7~6KiwPwjbzCk>sGW|4tzy<}6=tg_dgCdYS1~($Tg9wrtC%%g1yv`1 zpPBdByo#c2>t8LuTtESYW`5WVH?{`Er%FL9Mud(_p5G5Sdizz(nXSTX6@C{;%vP~F zwu-mG0JcBi|@_V77{a5?VL5c@+g+LiQ@shhe`C$2N%2 zrR&3N6$O>#9FXZbvsIX_qG%JR$W}2od|SnwXRDYqTLo38=-pkgCvsDz$=oHy1=7(>qnD=ZI^Jc4{>NHzL(WbM) z>H5|3i`gp7RuTH{_HV1$8D*=Onw^|X^Q&?8doH_t*BN7FiyTWXcJo#IhWns5KvT5q zEIEfxUoB%6q3dLY(A?4U{S4r*i?4&m${L(6pN~FG3m@0x-dOzJ!#L;rX_OA1^DS2k zp68OwxZJyXDi62XN#9KG&i9v}J2{7!+e4*pM)aKN`#@iDQt`l@AeU*K;a;5Gs3QM7 zV}^vjg1-!y<{Mv12&eiF6E&+(k#&OV2|Tk?b}KkGkzdYv;W^x1OJ z3H{z`kCQXrmwf7D2=KY1Th=|_$j3R))DX^>KwaI51spg|~AwNgh?W(0vOMmGp(~3knyyCnGBRJ>V0c zXqtkq;!KbyB>Rb>^#}rT|L3X@o_R9a?<*=_B$IG``B$CnC-DcB{T@gDgUWs{aUI4l zE%)*2RVVu$0RtXX_M1fhO=QTjAM2=^{&lk7Q84z`R*TzJ{<4cN#>swDQ`7y*eogNq zljY?R*^h2kTeivR=gw7}^kgUO>!)O=v4hFCKAt5{5ke=M&dl1$i$9bkPrazgg@4tP z#aR&S?|tR6)d2Z#c_8x=&hz)~T6;0AhtMG=Jx>sc`yzbKc?R%NdgfOsd7jLig zRXx(TCpW5_ESyAazIAl)ijjLmWzk{y-pNMv(Or*r9W5Jiz4E1HBdJG`jXHU# zBoUl%hauCjjK#7`18qxWnwJ7UhKhFW!e?T+Of#F@_O|_V{IlQ*E{ne36JjKN&dzmv z@;`|D+40+3N8t^6&ezo_mxS-+DE*A6?D1LEAyc6T+zE2I4l~?~a|{*R0MM`Oajsuk zk|?>THiy*79ui;plSI(*S;l5e&ue@p@*h<8cui#a>tv7ZU|fUB9#$WqKak9tG>AuGbI$kAad0|eQ?6D9dd$eBT%N}IEp{v#E zUj`{C@iFI-a|SeXhSVnJK?K7nI*m zAL+UDQO>)PFXWAWY};jT?L9BBq)&gc;i;C*G%Mh5bBxS&i`0{Hr8`V`cu3B1-&QZ2 zE(<>j#r2{%ulf`uSGgxuj}9lYNHtXTd(6)`oQ}(Q=skQp1&85F$Mt2JB1G{!?%(wA z$I|6IN`vicGxQPJ$g-ofM=d)_I}p2ChL42Q`!=Ev+tpeMe+h7@IKRGzA%ni0(q|d8 ziH5NmE`QS)mv5YFU;f9eO9mxDbdjaesmc7;+x~>=-HTZYrOU{VU)yi5M?Ku{j}Ixl zLGk!HfIyrMdpq>cS4-hS_hSkdx^KmcN;*RKQI%~!=qkRTXIeP!cY=HzBy&jN>41S8 z0p71{`&pH*B+vEYUv;vr#Fy`Y#L@BVWZOSN{)5W4Ppx5$I{!M^b{Pd9RJPrM{F}(I zU%T32)ZgVoIJmm}Wv8BslWiyap9drF!bQmPa-2@tR_s#5h-%JVxcU!tulkLBBy|fe!K?)XpU`alD-??!5Ww^)3sXq3tr=V{AjUbD1pQ`Z{}j z9xe}7O%|9oS>QCw0yy`!9P{#J0q+Fc8UF-ZlLe$_6mC|%b$9w(dI3FQO!u)2F-#T! zA>au8#9bm>{C>#MlLg|=b6xkcKsi^r)-J%3aXH^+g=1bO3;5lti%;>xRg(oa$T@nV z=j-_|bz>M3o@slUWdWQk7nTLQ6XIt46XHx3;F>G1tn^lV`nzSaKzRO(*#(Mb6K@xY zJ1=bnWP!2PZj%ML^~krT!hq;T>mB^<3EA(R&Dcvo$K^-k-t%7GP#&T1Zj4}qoKqv; z_H`%=;M|t5EZ|Q;@K0bdS)kggv+Aw8Gg-iqBKOqI7cg0%pi{go5O*HQ^yKV9zw2-^ zkBMh_u`2Tg2pLPGa;H`gP%P$SX9Uh<7` z0pJOx7y5?Brl;fb+&dkYvkv7O!s_UN;yWiq1NYGL@c3swzhHyx8!z>$We34!E@T@t zkhze2J4`!5iUzz7uFNlxIfkxo%lQR?ebl{&-uwc8NA>pB;aG!2u8V+u$*UH~7Wr zdQ9Q%9HpNTonP=l)k#yK2iysAxehbjiz9PX8vy#9U!d3TNV=#VxviaFAn^yCU+_nG z??LAmJk@V(uC(3b4|Vek9!19(bbf)XQ6F@E!EWRqFFVBT4?c9+A#V`gxBX5^`Z1Mf8o4i)6;R+tn9E(_hpUUzhfQ94!plB zuao4TY5wu&EbR2`4m-Vd4JJDXCn(&kdh71=cg|#o;@hwH?=ZVV(PZN74srX&&QHzv zJ!WzBvt9E|vfS&9S>z46zx^A&`A;Yn+BEUSTS#VpwEulITxr~xhRdJ!rzqAy=3hoy z13BjQ3OmD%X?*1$Ifa=0DNfM7A9_r~t+5P_X|!60k{5lF(|0lx=3J7j>2mk3 z{Qj5;;_3XBlc!wJp~yP@Gf)$paCxcnJNnRiew1I+>#pR>(e$Bw@?7t|7h_gkd%N9x zuQ%qy#iG64p7+Pux~P9H?rPF6Q2(xehS7el{Jr;|G5Vi`KGy#4|J+x(7u8>iKM?=c z{95zrL&-MYFu03ziG_=-g^%vFZ@Jz`R~2AyZq(; zPW^o!e(b{;XOP@MLLuaX{J!{+@_A5=x6I#tU%S3ft(NzGoDO}TKK79;PjRLB=by$r zrQ&DY^ZQ<{!|(MUdj612;4JUCcy)TBbINmZV{HODJ+>W$E}b6dtK)J!jn%!c4j20# zb@|E|=nK5U>oSMRXZaQc)3jP^bPn|oUFOxOU!4c{4~=oYq4I^WLEAm&tK+UD-@P0; zaOphi!i@*whM*7+3x#_jf%)8|4RZd0&`sthHSyBB;L6;j4(^5T>V4V--$vm=`?PHb zE{#L-Wicc_F98)Q`OqpMq{H+4bGj*fKX5rWN9cSf@CH68l1>wN8@Pl& z2t37vti5#4*9Yl8&sX96Y#4LTK1}KGK6xomI-=`J(BmHRGk)9oIV{zac&6P2&j##I zUMFktPBsZI@Q=TpUT!U(%FV@7GyHHWk2aNW06jIIBYDiJJnB>)cRJsSZ@REF=i#UG z@Y8viX>YIS8E+5i89Dr7JKl@stmhT4lK)=m;XWU3DZGg|#}wWH{+Plu2y|P|E&}i^ zr{4meDV#{0U;7l^1b$fI9pD{>OMlypO$c4Sc)6<;E*08Txb(N<3YY%&gu!d!W(eXCFx6lYbad$+p@x?zdfXI>2LX=4PN>!^tVx+ z%eWu?J|{Z;q~d`)K`yi44EN%+pHcWSv{UXL>=km#p42Y`=J!30`5BcjV|;PF`&Zpw zNfKY=c!{Iq*R6y2E#yBh5#dUFahC`ezaR8#k>#(O%b389KImM=Cy@VE5SG~l>oS`D zTrZmT{2p6Sf4{^x-lgBQoGBD}9?9fF-+O{L@GatEWO-R?#}sJKZqfOvwbkrvID0;& z@~q^kFK*MjKU&O77-Y}xuuV|gaNNBcQ}|+Dse_Iw==40B1le48OyQ;%Gm%`l+A#%P zmte6RxpG0os$gD~IGp>pf8FBWc>Yj&p*E<~+vTOtY z=rDZGeJs~Sh}mp}xsFn={puo2i($yBdLPDpXvi<6^jTItg35Pw>ochy^A&sy$isD*2>|y9 zDz<_9er1cVsC*@PRGZw^u9J}XgUS|| zq5h)hE6hfoH?rEYMZ`Xd@BUzBvIVtA-4^Ss_{(rSUJ5EkZ4azqOiE7p-PfU^k7yWeZ|b^|A$3j}t;>Cr!3Uo=a80JVNt@tf-o< zU(HW0pb(7dzMUba$rd049HF1MON5Kx4>@|WMeKPGt8KT?`nspra|O{{gIp3eyG2*K z)jUMnb4V5leIc|gV6sI)L9tuRl9AP9i%`osWwOOoFWJI7KVmlK{0OsK2!|+K{T(#f zqL2+prKntHwtK%r{!<>D_K4lpOY=7 zO}03_VKVpU~}^JC6P zw=t10FR1&bn%$zHm;UWrw%8!&TZlbs{mr+S#rYOt*}~f^Vm9V{3zIFXJ;G#*Dn07v za+=+upi{ivBKCZXRh2EW7}?^1*JT6PEoeXKe3xpk{dDiIKNVTj0Emux#O-moXc2UWUmQUMD24$re?5 zm~7EK*M=$7zuhA4yo|Z2o%3maHO_v|WtZOJMIQUH;|diu*cL3l7J7#_m1k;(;FS9_ieb zd?9ijO<8_#-%=&pt>yDf0_E?be|PzplTRINbkU#I5a+C2^LM(>C17`+Oi7<0{l}8K zl6OU)_d>%5<_<>bDx36Xrd)^P{LiwFm`gHHzvz+|p{Vgh4l|HT3VDxFVTsnR8 z??LF(YQ^)vLH9P=@<7H#!!zVg>#&@!j?3{hw${s6S097EM=V|H=sfIvL+uLN98{`V=eyR+S66T2mA9(D3H7Z| z=;si~>s)6y$a!Eww|;FSyoMy-I|htT+Q&BFE#Tb#`PxqZ99|fL;1>dKputHxG-W0a z-&VNnxs!qcNjeuJd=t35*QJs#8oq>ot>mk4z2}aUhg~jziiRTT#O}Ex>Fh%~vImHy z!{c9^zU%=a_s;+SpT{=bJ#nxD zPQH82biRAew71VXbv>^TSZB11@^iD3eK(j+M?D;`#;{xD%;6bt(m!9@vG`f=PL9%E zK?={%z7Ht81zh%2k#vZ}`E^W%ZvcNx;cehsc@i02l8&_dOySb*_bFT!3m#T@0~Pw9 z!rQ<*3YT`jS?$HsM1Qzi;T_;jg-g3XqHt;VPbgg4{iyCubCdcwr+I5AexxO4W*=GaWu%HA}k&CA)0x@=zEI=9&zi?%QO^?Pdw`#eLrq`$M7bvk3<3-)mpo@YcG`@f6c%-Ps&ZLLaj^ieyo^ zA-jl{^+Z>##_X1BSO?Z|IgZ9eS3X&KoUe`>N^h-~Z?Aq)-0OFXeUDhW)X{m^`9h_v zyk$r{*ZHpX^3~Pbc;!v&Z$f=56x!Jw=QqZDETNm(9E;jEn`1$TgXFL+vWLylKgao$ z+8n(zqG#odXtOyM^=3B5J;{!1Z@)d+@s3-s-?N`?uDkW-n{T*ff3oA2Tle3vipu*C=It? zou1CGnZ%wEYvn)58Io=uqR&5!{@iZlvi2{O2)NdM`aOfxoe@g&YcOwB_c!C8XN{dW zu^zr(gU<7{?>~5n@eku4R~i3fDZ5+;r0G%Im){GMfBE}R(nHhBzMt#m`)T^$N%S-N zOq%`?&^rV&`N8A|lOJ*}Ve*48g{o`(vr3Q3o$*iOpT<9_OPKyu;S1i4@lTH!+H3sN z_^0tt>J`R6HEWQ2KMj91Kc5pjDOZqhH&Gb#y^dJQb#cUS;r-e zf7VgP_~&JBweiPGjei>d?7d?7_HskpT<9pe;WVn!6J-*_8^Y&Pvf7)KaGF(U=hYYdl1L?r}0nYpT<9X zun6OyJ&0rc)A*g*JY5ddpr}57oEW-F_58@dAH2!J))A(l(7GeCe z2XTyl8viu@Y5cPXi!lD#gE+=Njei>dH2&FxMHv6=K^)_s#y^dJ8vpFUB8-3bAdc}* zc>Y5ddpXAc%({IdsfjDH&c zH2!J)vj>YX{@H^##y@-WPoqz7`sAD^$*FYk;RZLfEf;04dh)EX6DP)!GoJp!6Hm@u zYWz8;lBQ3RoRK6ao=nCPO|NG1m49SXj%~Z_t?xJbTl=y0!`-3gvhRBhVHmdWS5N*q zGea~QV?rH03jUm4bmGY-Bf_6strNtky=!ba`OEuT1n6*QASExXqrXd^zK=SdyT|vk znSAl}oJJh~KYCPue|389KL6gdT6ZO1h)lnvPpbv`OrD%R2a}I|B+H3#$7GUhdUVs7 zSv$YQk9_ZZEbPw->OC6w{JytZK}oXLf9Uzo^!(yIOFW*d)7#}e^Szt=8}eU8|2i%Q z(HMsdT{=C^SI6ae8moI>9WM4g>hcZIPuEeXe3ma$h5AC_xL>1lK?-YE_zbz0QFunZ z|L#@vklPT?mS?^@Z2DQgK6OjK(Yd6B?~CR4)~y{H~d~v`i*atwD5h#H;iv^doaG?_lnYQe50g=?=!w(e1qGA@eRLMlz!tI zB`tiP@eSh}+#ZZ?_`Ra^8{a5t;ronl7~kObV0^>x6{X+!MoA0bXMDr>2Db;}8-A}S z{l+&+TKGQW8^$-dJs98cdqwFtzERS`_Zi%bQPRTq8Q(Cz!R^8LhTkhnzwwQd7QWB;hVcz<55_nAUQzmuZrjzazh!`k|@$9h0*=rY2ufJV>V}r{*W;Cl__T`hJXnGn22K&^X_3 zO89B_wW+JNiZGifC4D`OfH5z;(Ct~kn}{Iw_#EIJ;L;AB4?IJW1m6a{1zghE4qUR9 zd@lsvM1@NDY2Y1&F96Tbpd|doz*`Ex6u6K=!oL=H10)jsO5kmU^ZPN~QZy6^|7PG# zgI!X2xPVx)n=J^7bbdCb=DE!xeXJ7^r z{=X6u}-vLj!!_p<;pCEr;euX~?yshvvsULFqbPK0argJv%roy)X?`DErq`jc=C*D`0c|t?*gk=`*Y8Tm-zS@CL!i!rubCt?=uCr{7Rb=lg&+6@DA=j>5kmc=nCebbbJMOW{8ZJlR?ezYM&g z@E-x*R`^GOr~DzHOX&6!z?%wh0q-dM=YeP6R88jr;4Ov!GVtWN)$k7jZz%kCfwvX@ z`@qxZRnz%zz?%v`4!ooAKLMV7b2Xhm1Kv{jUjR?|LrIs=?NQ(jh5s$^w!;4&c>02B zI{ys3sc`D*d4KOHd>nX|R?|5bcuV2W0G>=#!*2!NQ26tKw-x>(;OPsi>AVzpQ{j`q zI|`o%p0R*Im(cT-z*`Dm0-n668h$tMhQhA^-d6Y3kA+OW{X> zCoipr|8?LEh5s(_w!;52@bp`%>3kM=Q{jIEyrb|h0MA}lP3O;nw-o*;@Pq|ax}?2* z6?jA8{|LOT@UH_;cU03kljPJ~eo**1z&i?m2Jr0V)pVW%yru9IcrsZH|61ra={yg3Q{mfycNG3o;Mv91bf$o}6utmF zc~v$1tAIBYz6*F;;jaUpX4Q1w0KBR2?*ZOX__e^ZZ>^?tBk-2OZv&nzRl~m%cthbo z1iY>A_W@5YsiyNm;7x^p1b9c`KLI?uw3^Pnz*`DG0zA2_8vd7nHx&MBz}pJ{9pEWC zuJqsE2i{cp9{}$t{C@(^UR^EEp8{_wyaPPhT@C-gfj1QXx4_#9{|DgdYpUt|3-G4G zH=PCfQ{iU=&t6+i=jp&(3f~Gm`L=5K7XWW4`~u)@g#FIz26#*1R{~G2sD^(N@P@+Q0=%v88-Sp9G$KcQyP@;0=Xe47{!I%YdifQ%&b` z;7x^pC-9EKzZ-b==4v{7fVULB4|wvu)$q3hZz%lxfwvX@gTT|bRMUAc@TS5)0KB8{ z4+GDxsiyPez*`DuJ8~}nG^*i00lcB`Uj*J(_^$#__f*sQZQxCX|0m!bh5t9;*|pVl z{s-`u!XE;jTvrYM{{n9){1M=7h5rrk^!jQ#e-FH=@c$opN8x8YrJ!eaLp7bJ0&gjN z3ve-b?<%4t-w3?1x0=rLfwvX@uYjj-t%iRY@TS6NfOiyr5%6qZHJxt--ctB(;K_~E z@ZS!+q42AKw-x@qz|-%mrgJ^;ro!I_yrb}U0MFi5P3K*}TMBOiPj0G)KLos?@E-x* zR`|aIp59zd=cj--75=lpI|}~=;MpzJbUqEdrSJ!VC%0C^{|Dd=h5r}eZH0dhczRnk zozDYrD*TJUI|}~`;Mv=&>HHP&mckzcp1h+P{{I8sQ23L;+X_ExbJ6e8+pFoE3%sfD zX9Dji{F{Jh`>W|p0BAVPdQ{mqNyrb}G;Mu>arn3mVrEngf&gGx?R>Qv&;OTNTosR-^PE!+#ZcL*f4jyshxB15baXn$DSL7wxmD@N;4OtG=YaqJR5kolfHxF=KJd1}pA9_y>1sO91Kw2lHsBqF zzZ7_OPc@w>;4OtO08jpXHT|3>AV4WQ{mqOyrb}IfoJzt)436N zOX0TxPkyEv{++-Z3jZPCZH2!Nc>1%|bUp~Ysql{g?HI$Mro#UKct_#?6L|KCYC3-kyru9C@Z?A}{Qm~tQ25^h zZ!7#CfTy3Vrt>ern+o4_Zqe^L3O^fo_6yZ?o({aF@U6g;`>Ww!0KB2_3xKy3ej)Jm zfoeLlz?%wx1@Ml-mw;!Vs;2WA;4Ot;2|W45YWOz+Zz%jNz}pJH0eJdL)pTwG-c2rLbnXM*RQUbCI|~10;MuQK z)AR8j9|CVH{EvaBzgkV_&ww`-{=a~C6#m!1vtO&G^EKct zg+Bp2`Soh}6Tlk^A3v{n-?qZf1D-xuP3Kv_n+ks}@Q%V?2t50ZYC10g-ctA^@Z>kE z;dcUWDEwmJZG~S3JpHX|I+p`)D*QWvcNG5Jz_Z`3rn3ilOX2%~C%;n-e=G2Y!oMGQ zTj4(lJpJ8jI`0MERQLygcNG3%;Msqurt{;#TMBOhPukV+p8(!a_%8x)EBsf1r@vQC z=eL13{||fb0%gZ>o(J|2Z<2ul-tH&hIHcAp8#$9}#}bD_#3a|IfUf zmnxnSKBIW@_w(_;L-9W0->LYJ@b6N*_7C!M-l6z_@Rs5u!tYT$J)f8JZpAag7Zgwa zVLtv3D&8mj0mX-e|ES`%f0UQ=F~tXjKce`E@J}k9{^PuyPbr=eK2SXQC;9l#D&8mj zzg2ul_?F)H1Kco17@Sj(FMEEZ$p8nIkoWH4fM)*0!lYf?v|9>dnC;aa#J|z4L ziq|gW<@`&<2ZVoF@e$$wM)CBY=jHr+#WTV$E1vvc`S|})@jl@%C_W_owpY1!SNj)v zIWJdyK=^AE9})gW#nXS8mvdP0jPO~-lV8ur{~pErgm)Dm68?RP*Z%LkoO=}?5dJ~M zM}&V^@$_Hi<@|BQGs63dCl~YaKdyM6@W&M&68@CpwJ+x7{Dk5I!hcHf5#fJU@$^f1 zIe$U%jPNsxCtuFT|7(i(3I7GfhlKxi#cRKjm-8!%4+#HN#YcqyUB%O{%b)mYz4=k|2I`TAl9fkJHsqr%A07GV%Ez31^yFh+J{ooVX=65;Hr%qG zHd(`_YuJPho3de(Hf-9aP203-n>KCJrfu4^O`Eo9(>86|rcK+lXCfhaieZiH|jQdqi)kT>Q+FbZY4D8Rz#z2Wi;wm zNW;9+EEWb6b5hjE8cs^XNl`mfLsLsrQ**Y~aK_ef*4A+5)^PULa0b_K7T0hl*Kju1 za7Nc~R@ZQ5*Kl^%aE8}#me+8m*KoGiaK_hg*4J?6*KqdNa0b|L7T9Pzy*L|eI3sL0 zD{MG3lvlz<6V4DD&Jr8W6dTSK8_pOT&Keue92?Fa8_pmb&LSJmBpc2q&8y>9w6n^F zGs}jv%Z4+|hO^9uGtGvx&4x41hO^FwGtY*z&xSM5hO^LyGtq{#(S|e9hO^R!Gt-8% z(}pwDhO^X$Gu4K()rK?HhO^d&GuMW**M>9LhO^j)Guei-*@iRPhO^p+Guwu<+lDjT zhO^v;Gu?)>-KMi$^KQMUr|E3B>1?;@Y`5ubx9M!R>1?;@Y`5ubx9M!R*>F;v?KYk5 zHl6J@o$WTA?KYk5Hl6J@wV%|E5+>EDeESS&=_6mC`TEe;r@lV+ zo$a=q?Y5llww&#@ob9%p?Y5llww&#@ob9%p?Y5llww&#@ob9%p?Y5llww&#@ob9%p z?Y5llww&#@ob9%p?Y5llww&#@ob9%p?Y5llww&#@ob9%p?Y5llww&#@ob9%p?Y5ll zww&#@ob9%p?Y5llww&#@ob9%p?Y5llww&#@ob9%p?Y5llww&#@ob9%p?Y5llww&#@ zob9%p?Y5llww&#@ob9%p?Y5llww&#@ob9%q?Y5omww>*^o$a=r?Y5omww>*^o$a=r z?Y5omww>*^o$a=r?Y5omww>*^o$a=r?Y5omww>*^o$a=r?Y5omww>*^o$a=r?Y5om zww>*^o$a=r?Y5omww>*^o$a=r?Y3RN+jh3wcDCDgw%c~L+jh3w)-kINT6NUwY`2YZ zs~rWkb>yl;R~@_R;MLh~+u3g0*>2m}Zrj;z+u3g0*>2m}Zrj;z+u3g0*>2m}Zrj;z z+u3g0*>2m}Zrj;z+u3g0*>2m}Zrj;z+u3g0*>2m}Zrj;z+u3g0*>2m}Zrj;z+u3g0 z*>2m}Zrj;z+u3g0*>2m}Zrj;z+u3g0*>2m}Zrj;z+u3g0*>2m}Zrj;z+u3g0*>2m} zZrj;z+u3g0*>1<#ZpYbf$JuVj*>1<#ZpYbf$JuVj*>1<#ZpYbf$JuVj*>1<#ZpYbf z$JuVj*>1<#ZpYbf$JuVj*>1<#ZpYbf$JuVj*>1<#ZpYbf$JuVj*>1<#ZpYbf$JuVj z*>1<#ZpYbf$JuVj*>1<#ZpYbf$JuVj*>1<#ZpYbf$JuVj*>1=6yB%k{9cQ~8XS*F| zyB%k{9cQ~8XS*F|yB%k{9cQ~8XS*F|yB%k{9cQ~8XS*F|yB%k{9cQ~8XS*F|yB%k{ z9cQ~8XS*F|yB%k{9cQ~8XS*F|yB%k{9cQ~8XS*F|yB%k{9cQ~8XS*F|yB%k{9cQ~8 zXS*F|yB%k{9cQ~8XS*F|yB%k=9cQ#1XS5w>v>j)(9cQ#1XS5w>v>j)(9cQ#%XS7{s zv|VSkU1zjiXS7{sw8qJljD@?-XuHm6#qX4W&S<;NOuNoZyUt9z#uNi;Aq;=?$xnRx zVbBj}m8TF^V)+)JNpc~;4~*fY_HW&V#20+vE|UeqM~bfyo;vy?IYW4+_>gdU;-?6&-R9DtCw!pzWx_{_ zr~f{mFZ@d_6Au4U=LiR7H6pzK5+}F*|K#Nl6+ccm{7aoB9R8&)5Dx!RwXf&p!@tx5 z;n_=FyfcKuztknd2QPE+XTFh_5C2kq!r@I~uVFLjA<_?Mdb zgS>qBm+BJ^|5B@j!@tx;!r@;k`OkUz@GrGUIQ&bUA{_pu&Jzy*QkMybf2s7p?hkvOB!r@=)4B_xE zH6$GVrDn`7Kso&L>yNnndW6Hj)GFcdFSSlM{7WTMdHL`!HA^`BOPwMd{-rX);a}=9 z;qWhY=$3rG@GrGY_~3}U-_wM{zto6u_?J3(ATJ;OrH&I0|55|O;a}d+n zTDUczFZ@fb5Dx!RL&D)->Js7bFV(v(FCYG;`h>&3)H>ntFLjY{_?McU&dY~?sYSx! zUn(OU{-w?n4*ybzUXqs&|57R8{jSzK;qWhYj&S&wI(RTIAO5B4gu}nofN=PiI!ieG zOI;xx{-tU!&F2gMQY(bRztkDR;a}4AOPwbi{-rJx4*yc=%k%ldztl3}@Go_aaQK%R5f1-S^;hKO z!@tyV!fUBfsyWUQK1eN`Tp)a;cfo#M^5I|VIN|UwH6R@Rr7jQ-|58^7hkvPs*W~ksf2kG1NAGuf z8xjuxQkMvaf2rPU^YYKx(lFEt_@{-x^T;M*MXDfR~cQpX90 zf2p&C!@tx8!r@=4_U62N_?KEB9R8)w5Dx!RL&D)-YUVrh^5I{qM>zaTtr8CZQtO1n zzf|&v^YYI~uVFLjA< z_?McQ&C7>>sXpQGFSSZI{7YRVJbBdFZSwZK{J!Fggbx)zML7IRohKarr7jZ=|5E86 z$>$6IQp<$HztlOx;a_S*IQ&c1zdJ7<{-ur+4*ybT35S2F3xvbJRP7yk`S35bKsfwM zogp0lrG|vVztqg#dHL`!)gv7KrB(@tf2noC;a@5_l9vzvQnQ4^ztkzh;a@5v9R8&) z6Au4UhrTDDFZ@d_6Au4UrwNCDsS)AuFLkh!r@;k zBOLyv&Jzy*Qis}k`S3555)S`TrwNCDsdI$Gztq7_UOxOw)d`1xsR7~X!1ae`3C|S2 zLU{7Di(l*J^X)6XLikYeGlavx)Fr~&3)GFcdFLjad)uUur}+{7W5t zS6)8+OC2X1{-p+l!@tx8!r@=)3gPfCwUFlXg@36P!r@VFO?Av|5E1(hkvO<@5#%Df2ovk_?J3OIQ&bU zBOLyv4&IxW5C2ki!r@hI6XhkvQ#gx4~shqHta6u&_DNb%YS^77L)Cuf21Oz|^> z!@ty!aQK&+`Cwi?{7dx+hkvP6!r@MY^#FLi-%_?N2v@w|Nams%hk{-w?k4*ya^!r@x9F|iM)LHmr4nTf2q@i z!@txy!r@=);DdSj@Gn&-9R8&Sgu}noS;FC8>I&iTFI9UepD+ANtq>0XQfCNE*~@H@3iIQ&jsBpiOHW>4nj z!|&80;qW_kig5UyI!`$KP9;a4{M2J7PdsSOCqL=V%Ltu(_|(bd$R{6u^u&>moj7?S zIr89>Pnzo|+{HsrJoebbkDCaOKXLNmBk#NK{=1(%dE%i*oO-wY`6eSl?tGdgrF4x; zrzKn^$=gg&Fxgua9;se@?^F2{wJ?$iA2$E;DrIW^!{gM@r8_n6PWw*&0n{1`)`pR=cDEu zgnc9v_*)gre}{?7_bzfS|Gty@VYvtn&P%TO-X;1_^Y7i`62Hux9x)MF|57hS`Cs`P zE~ih;xb*ns{KxMs_l`XAJ+)fBHa=X~eRkVz`$gBh1Mgz=U-pyl{r+ROOpPT@CGRZM z<@whmci35)+-~l~ykf7)&$4H}(w9i}d#=7Pkbu?7)fbX1yP8+e)HBJuzm+C0fg+Lv zx2D77uAfelm)3`Un{F6K0(z^EnDVx9l znR`;ce}8?)Tduxf;t!H9Tcet~^SvK`?(<*J_d<*Au+_S1B)eSn{%V1KRbFs^QxgB# zANr4{wqm7W{}qkjPgnN8pmY& z+j0F()<4R(llt@aJE6a#{`ad-r=plWufMTmd?ccS} z^>vA)hp&GxKWv}d?!P1#lb_8+%OA?$cKffQpULO{YVx(uXQpI%{bbqJ^pj;?j_+Tp zK3}(@pDe5Xd>ZR#bM50Ve38lf%fZx(!e}Dxn z)%#r{z2S1JdbwWtV$S=AQQ(5Ql&^~HxdvR=yUkKlGWeB=X#%z*TbT&phKfdcD(mHEp4 zCY6eY-elM;_<-;?D2}X;>G$8McwZkdu%kN_9}+&Rcuk86Id>~QAiSygNO8zFYPaP~ zwF3wKPQ^3DA^%>*p$gz1P`s}V2l%4mL&cZOwH%U<=qFV}LHv&>o)P|_;vgjl0=C|*-vXG`W< zjx*+8$_XE6z~#H0_$`8;Gjim&2;{e8{G zZR?X>Jr7&==<0Xa;>OWszzl}rz?ckFM|&L+j`n)+<+k|a@@oax2}gT9PB_}@ zfN-?evxK9)ULYLpRet+U4(I{x^^E$$1CI7OBpmJa65(jCy;tVtqrLVCM|)i*9PRZY z;b^b$sfTi+z3$gFoRivbIISm14FNqLHfJ%pRImNX@<~auqISL6H5~bkpQ1zRB|IAD zLNLw7e}(iI&*BSCF9Qp~%ycz($ZrYB(RC;PiS#%hHQylYBbmTAE0+Hb6F2OqAYFQ{ zW7BImhrYvSpQJVz*Kn*FJO}4Fl8_^_9Ncy|rnrW)@fz274Z(9{6Z)TA0~sW74M(gO z9KPp3l{1cOIJRv|uU@hS{oDU_nk2XF{WS==k3G4D^Ak6Q{>B`*Ut=j)V~uM#vQkvG z#ue9aTq{)lR9fSVYdE5_$-{Fe!B<86Cy&QNt|v%3F>VL96vmM-&kux~;yffCW8kpl zyYOInk}s!~_>A2w<*RzXOQF(&aFHGGJaaqx+iT^+y~Q=5zz9r`+ecY@<9JouQJEbS z*`LybxdL*&W%gV(-gHiS`9)EmSQPuM2DEEJhJ=Z0LboJ+C0AfacN+c3n!%9pS;cEw zaj>VjCgiN_an%nvX6SRjuL*&>|0SazSrfwV!TA0pB=fGz?^ADWO=vz?6Pk}}LY5Pj zG2KqD3Gv!bsvSG8{lKnx?FVZ@3$&JlH6dQ(L3^E{wHd4l@!Aj8gm{eyB=AjIP4tu(^;vB@ICnUfkxI(5*8hP%riI=)Wvm z6GD27XOV!@m#qoiuK9P7kn)F|qXtJfjQZ}1Az3A=WC{E7hw@9x zznc8@XZj`$%Xj;txh+un!!?t_ece;Z)5)hQ>SugEzWky5lJXCds`_`D$>~3oAIono zC+bJ+r10?VE!yWzsULGwv41P9SqDb@-|)RzQPK@6 z1u7WEwMO6(@K->~(J!?7Jr+JVOY&eo*m@@cR`{)KC!rM-=Z9 zenRmf;U8DLHf;jtfSkunSoDcCM&M5>jx|Q$pHduajKF_VajY={|1*kXjS={tQygoI z!2g2cSYrhKS;eu&2>fRiAIOV2<^cZlCM@?gBK#K>PxXC8#Qz(LZ|zfbtzQG7`FKTy1;@B2Z{7Zk_)guwrW;vKNNxwO&YGSz zxJPW0SXTW=w<3KBj&lL7P27GpB7C3;4$|8CNbx%1srFyT3C|QC5N@i_9%l*fD}IIW zq2e`Kqes7n_nsv?xi9ozXDI$aZ~7A9=)Y!k?G$p*-}MPc|Fudu`n!vSqhB+|YY)gr zzqUv?`ma-jqrW>(IQp;4grmPpU!Bhv{ns+#=H=+_nqN56K4aP(_K!qKnIXukpZ=+}CLqhH&v?+O31>ciD`lGG5; z^I>zAzBkotociK~)*O9pfAV;fCavAKe^2!tiiLfXfs$`fzJkdi^%Wisb0L^^7yc`x z$9NuJaQd=6A>Y#cyGW>Kq{sQF!4VFlzWw##)i}&?rTOx`OYEUKKlt!CsSR;@x#oM9 zh;_}srw>LMMtryVXZ=gP6y?ACM)QR^zU@x_lk*=xiW-&ngf#1TQMme^kn=y_vrkeR z+}@s$U;f{ml%KJuxFWv$vrJ`Plz?alJ{KWo)+FKc&UPkiUj7`QpGm)Bj5KY3r!1Lmuuy+({lyrP5U zNxqy`(lJ)Gd}Z>m2Q0pGm#>wm=e#~}Rn<Rj8|J{jsrZoM|3}5)^8)ez zi{b8R7q<;)(hUK>W`u-Y5KTDn2Cqe^tDuz9S&#e^-1!_}^1} zMEE~cJpDuY^8Yi%Gs1se@#M|<_+M7MPxx;sJ|z6#DPB|G4JiNbC_W(kTZ)ee|9!<% zU9g0ltBPlY-)0_Nw*RT+%YVD#eZuchd`S3rC|*09m-A-D2ZZ0L_=xbgE1tf^$ystI z`?(W7q3TAy{hce7e_Gq$_bR^Fa~T%+glgP8KA~FHpH$2GlWJLCRBh{vs%?EywXHv? zwsU!9{Yka0KPlr$O8iOLv~8QVZPOaBQU>qXv>ltaW7Bq=zbu=!W7BqQ+Kx@zv1z+D zZP%vl+O%DpwrkUNZQ8C)+qG%CHf`6YowI4@Y}z@ScFv}qvuWpS+Butc&ZeESY3FR( zo=w}cX?r$p&!+9!v^|@)XVdm<+MZ3@vuWpT+IgFH-lmm|e5Ckk!c!4wj&p=(ijN2fv2pONE*;9#H|;}?d-b8WN6i_$9*ow>i1Jx8>!-*H)i!_}W@0 z96q%!5U5{_~BDZ()hKTkNu;g<==I6S>OpD)JY z%Y`Ocw+b-IUon)@L9q!4nIXW#^D*^7>8db9OLjq z&3wKXhc6S3arkM%F%BOQj&bGs_=s?f!}qHX!ynT5fYW+{>cM4l*o1C1|EWh@;M~1> z*5~s}&7};L^fJ+Dvwds`ro$hX$b9}K$`@ZuA)sgJ9t6{2nEw{(b(rCCPCu{dwR`jN z{s+xp&CugWkMmJY?;~j7pI0pZ9VR~CyNFo%0Vn9g?&Lp_F95mbdzbGnYW}B1@#c7$ z`Tv;tXZ_39MfoqwjhW*INI2&|_F>qp=EJbv>DKH~-G|{t9a~CyQu#2Sx0^dD*n@uP zo~wDENJYQ<@`c}VQsj3n4_unEx0Gcfmkz&2-~X;m_`8PI$558}{Jf90FWXAH_U~3o zZYE!w%QIi;%Vj9P&_`RAJ)L}M>+-|jtt^rMZ1Urum!kOl()%=e^7@ePlOp}!RKL4( zpS#V8PihjLf=KvNRFH0YURCiQ(X? z`QC1#+qFV7_PQC?3SlR&HTNZ4V&AF5+l5fRf)5E7>QeBUcB)eEa@=YD1s^CL*2_+C zfU`!vaDehB$2rYMhKz!rQ-k!j6?XEae&Oc=z9-~?nx6YPsQF2D@;t(EJix=YFd)3I z3Cq`_Ggw z#7n(|N7A7#@^krkZ18UG)9n;PG1`(E4+G_qN8`FV1+v=Du)%=$=Luo^=F#lD@ zbZ52x-kUG(MES?fy;W^Y*RA(9JEmI+DlxU?abvpi7-M(FT=HAtS$@n_Feb|XR(O^@ zn>>1#6mm;rqMaR+no>~tKEPd{ zJnK2Fq+kqVi@dbSF{9+mX(dfjzCqLTVvFv#2;)4$v56OE0%dv)<4CwjryNJF{g~14 zW;er_5q833MvMV@%m_Q+F(c&MX>=5h86ii;dV-JC@WcAriLs>6=Jq#+)G#oXlxMKu zht!C?Erk!4(y^plehdbbtuX8dlqQd5%~x(uYy`)-01w;1i15B9IH-|Cjs%B_*9otw z9*+|~Q2Z?6(EENJYyKf$@lK&N)hkYiO+ccg0Q9^v?E+`@db4BAk5Il4uhoQ0yL=&- znuW)ap8HBpUpCf!Nb}$7So5z`EPvTp^N<#Nt7FYf^M_r_So4+Uzv@`CruFv$uTd9Z z{f)bWcBQdqt1-7}{_w1Fpi+X=7USj^YZi=^!?A1$Ke?LR_qmbL0*_^Hu~lQnmbqg$ z$C_jQb~sf2v(i}kuYV!6WeoY-;V@Thcj5WU-I+^BCMMrq{1|Q$!fPL{C0QMwfcbOZcTA{!VEpPEmapWsY;}Rc} z%CO#dVlMH0M!w7$25PXfS5=Ppn}5OA)lj@mhJ%NV=Mrugq-@i)`xqPH=EQa|w`hlR zi&ZU$JQ&6Ha9j-VT-(xuNqoWknqZdjq2h~#*K}}nitvHr7?VN%Nb&O&KUKY5COlI- zRXsuu>T|!&QGSIwpqkbXPKQlERG9+Mb6*F;m-TwHbClnsd?8+|6_=%R6r|_AoYR-h zQT{;l@A{lv0O@f)YG8!JsEv{ip5vCyQ5JPvzSTKOPxC*o8Oj_*@~S#VLBt;pZ_0$Z z{Nrw>Q*DmYZ8bN|hX>?EYRePnD0^#;;^z>R<|zARkI8rrx4y1(xNwf5bI@QtMQnR& zHTl}-GZQGDgRZYjBt85b&dU$iJ4)ubgJd&%a7=!?HisMQ$J@_MwMPbHMpPHhxp9#J zWelmq4@9wN#xT~*MKTvGPx9rol7=yif#tjK;CNN_8-SN;CSy4>itfmpKu)r z_P<+mK;-+qnr~klD)6I<4;5cB*En`!&bVNN$=oni!^Iw;A5wfq8=<%Ba4@&2Iir2` ztzln%YlKtAPB4A!`03+uhl29}9^nJU z`-G1aUnM+6!=82-L4KzAEaB*w7YTm!fO7?11-+OiQtcUrz!c3L-8J_rTYK_UQhmnDW zmwql4$WM6==CAkM`wZi`l%EU6xn@wmWBvI0jdRUFKN#8oDw|V<<1&eR%=~j&!5Ncy zMMu?mRrAH8FwQme+SZ|F9xS-hA#cGqdC1Q-&7dXDHLpF_g#E|4rrJ?BnA?%LW;d8? zcH>;rs9E~VIM>YgTd7{gxn^E3m}}vD)O?L_7<2#4HRr0$HG9qWX4f_AFCS|*wZXWq zS+?$#Wn*1Q$XxH*x>UhjdB@k)cD4MI`U&TPJGeJ8?oG{G<@jni%-QEI=|9e8dHyIh zz}R-@vbxMLu3Qt6{egUNz8Ld!ysC3qjwknl`E4kZ^ToPW7)Qb!?|PN5NPk6G)ww6% z#}ePDUQd_c3|GxpIBmPWYBqbuIq&x8yhn^a!#%cWr{Zft@JuTj_I!`xc4A|~u-{a1 z%yodvS>z10AwmB4D_&D0Tr$@$>dE&_k!D^^DVD6A;r$0q7ZiKzpJ{b8L29_BSYBCuMS8+Av>87HS@dmLNTg(c<`c zW$UtE)r4Ii(*=+o=c5KjIE?xREP#e!LEN%+*^Ap;m#u03GpZO_mz8&_QLIB+E~yta zeMQ`ggg09zSnX0)vGjDZg)37S6+OT&tB~;&Xwa_`IeHo?4I@mx3hbsO|!`I zT*!{jHKo<|y)$4W1w{&pOaF{Qo%E4S3 z_=4h?OQRhKwkZP^HBpM97a7+vHWFR(v?>_X~Ip12j?Z% z+Qh6TJeyhnQZHeD0wEW5uftCP&@<;h?l$Kmm$c9J_{V)0(kM&=yZVCR zTq^yhz|Ot{VRFwRm!$f?#db~C^L_isC2iXN<2xLpGClaYjkyuN$C;nc$IKU;R^s}( z3=*32UgnbIK8g;$U(rj^{Z@@vq?aOjRXGk$TUKuz?|R+ucJxxD1HO-?qDnK^bP3LI zQ63yeu05Az2I-MYx_(>|>@;#o&ML*;x5y>Um+ud>rwsT#}uS zOCK1yBxk=>Ki^~`${?Ei@w7w$a{+JD^!)rm`p6~a6$$;}d{p(9k7a&ae7|u?-FhW1 zsny*4?=Qmli0C-AijMn|_QJlT@xGGyj*2zQf{)=azN1n!mn)i2@SNpXfj$M|XI0r; zljW7o`BaSI6FZkr5u8N7ef+D<9v7+%K=CNd86lQG^xMQCNP2`97BL z1)Znqy6m!QzT($R_APYlajq%r_%$7rz>e-T`myW&io*_P6(3Q2-nRfbyl(;Ri07JN zz3;?+0QSc|P(ypaDZk9^FzEHR>le1nU}RJK0YZQ5#+m{-!PG2yvHY=TdV^A3(#8i` zZ|rv+^~rwMQ`OrcZCH?#DSn!8-@zVv@>7qUJn^7eM?d*VcV0&5KjAJOdg8Ii9)8?Jc>IZz4lb8L0}9Pc1))gSw!)}QQu3J<>5are-ObDn*+emw$a z?jujyO}2~c+XecM>ytrerH^!vV65f=4e(syn87)%MD=4UO(&-~=b6;iQlOtOSn@~= zquB7K=R9T;U0h#_bDm(X(%8nFC-^<8ZX?cl;+&^OJ=9@y9p^lx6mz-%<~+?f=ZSNk zIOn0RAkKM;=L$vRTApXf+@t8=If~3>IIW~(EY5kHHjCzNMOaZCISKhs*7J3r^O%K* zIOmCTo?yF4@J3;s8Na_@Q#q)vLUon7b)l6s`lg^mfE+-d~*Z^5COukbL9YB4Fyy_kR4j&wt@}A*}d3 zsXvqt@;JYzldo5lKi1!k>2pdnwikbwcjlMVpfas}1=py*04fQx4VJA_RGlyI++eTG z>9~AlbC;s~<$0*6l;u^uUx~+QMc!8DU}bY%&SSgfE7D8w=#pEo2j^R+=V>Ik#<{9q zUTx&qy@0JaN360J5cPt+fG|qf3HAc^wL*boFW^vd*q?D7Wu8Z7ZmNw1@!zTVfbe@2 zA1RLV7}#t-E3Wkeg}YfL{3d=+0Hyrws?Lij-OA>kw3^gi8l*rrW;HCGM(^RNktDWo28 zfkXP95$bufdk#-hz7VhGfy>f8he*$2IDOfk!#}AByFMouKzf{y8W`a)>fhvy^-GRh zw&$?7P5;mEowe296VA(K?AJswAZ&N}qVp%^BGAj>-zei?*0 zt;FNB5?zOWLCWGFr^Q@=V{^Rimaj-JdvY#neq<-ES6+L)680bGqS|u8!QRI2u~nXn zwu8B7JI+PzoH@=#^F4K{mvJtd*9+#7I3G1%BOJ!ue{<1JwYlhgx3}5f?H$J7?KP%_ zb-2}J@6AQM&yPxT(ZSm%=c2>m=I5fue`o972Xa0&%wE*66-xN(c*r>=@t;jr|BT>R zAA?>6qr=a2{r#DBWnKqmIh$K|9S(El_wo&YuItvEUtD)}wFLd}{(#N>78T8}E@L0KN=2(Gl_PnLIIL0Ker(VUUf zN<7ZDs$L`>rxkg7eJ;&9kb0Yzg44nGwnX3KvM4RS3(r;c;@5RMaV}kDT^H?y=hD(H z#cwZA_gbx)zPdL^KFB3k{iOr#DmryQkzS;pS6W&++G~q+VM})(U4yxWEA9jRw zdEl_4;}jouG$0&yv|oSw<@Zz{TJ1><0X-i!XR-BEuW>r01nQzF-W;1`rQO79VV^DC2c$1Jmg^B;ch=EvTCZe_J@_ssgagU+=EN&6`gv(-JbEN^n| z)~YCfte?1NHea#sYOEh$zk70S<;N1iP3U7bKqmVEjL~wD%tevBqCSB8m18VOuQ{#6 z{EWs>x4ZCRy74-lohvj#&ywM+pzCG==QTgM?STGH4rzlGJZ!tmg!j$&a-1f7Xwf9W zSQ>I_s^5cpL%>lVb;3~}1Hw@s`*zIj4ZE_(!}Wra@~%gu3g7+A0 zk7DOk{#GUfmF8qyUr&?zH|;IdpQ#^~ms<}s@t;lJ{HPR_=W1q;tS_(Lioc#pw0^w& z@%?jttH~E{?-$5-dq=r{pz`}Us~IzGdp(fzn%3Lm6F(cmu~itC9(DGsqHdh!9Sem7 z;cz@7u#62kt>BDd3@P7*2g{RuIjzJmDsw0YVNSaly>MAXCd=EdUbcE4+tpu@9msr# zk7))KC~#|E&3t3mi5l(RJ!B{pW(Vvv4g|Am|tP zI~3EQkWc^HK9mn|J1y(8k)FFwPG8n%e_gZPYM*_WGg5gBm-X3w)!$b8>{-nSzpo>G zw&a#nI-lqM24Ma(Lr1l*7Ix{;~z9Y}qWZARHqj!mt zm`~e?ukmZdHxyqt=AV4|Js)J*gFWu|tDyX|lkciCU-n$`SHCLt%X}PPn<$=-+a3Kx zK5=8eapOH0<$F}7!uKzvTBlZ%AA6!^0$iU}-=*htz8~=G1)JH!L;L>=_;$|k=_Kyq zk%~nB?Denf8r9#w7~79;zm?XbUhMZHmgM#e4jCu%ksD*{mpb(DQIGjhKEPu};nz5= zq+kp@TwYp!zkqxv`Epvp8LL{ps`7qJGATH=n(y_}OHo}G+{T3d%IagQ_gkjtBKr%L zf_+gr-@RVGC13Jr^tDL9 zv7Rtg9Q^^-6KdM=AwJd<28zR8?=^YI{f-F#fa0k(2*{E30lOZeIONFL>P-y=@js$? zpYR722VV|3%ZkG<9^^c(_+Z)u%mMtQ3ET23zGT03A3MP%ecFf;&Io&pX7s+FQG7)^ z2ZfV>F`5tFciGfBiCI!X}B$KbF$#lY}n7H{j@P#;SY|@hlNnuYFSAR znVW-G5iOk#@bFnVB77i`&2do40g)r|N9JFSI^n630LKZ>6dw?7RBVs4g!dJ{K=@Gc zD}=-DYsx31oUr=^!eRF-gv0KKglAgOmk0+DIHNo|@`c^^35VUU5)QjxCmeQqRH&;aqcO#`Id)#GiO-w$^9D_IB z>*%-^GbY;hUbg~naJdTi_@Dohl#DqazP?qPdS4=YPIgn}-evtp?lN+h_ddXO8@Wqq zux7NR{fqDKBX{W(llv^7rCpjb>oMcTW_e)lq``AfN zGE@1NRDaKyEQG6E)y_fH5pa@b61>H|+gsoyn{#6x(lotbCa#?1SuMYqUC2pZ2yneM ztGt@d7$m;n1B)if0^uXYR|rqlzRwU2yB`t`yT3$uUpv|v;sA$=V=pVp3A^uee7(6< z!eRILEeptj-Cv~mu=|8K!&L2imT=hpDZ&%AWB5KnzOeiA6d!gEUpI&kyWg*zckmEUP+z%B*ft-0>@w#l*_i&$=EC)3#-Q8gbjSO} z%J&;)SqL2nImyp!5PC`O1=vZmM8ggT8YnC)$&!9w-gpC2=8>heohwTQ8a8Ts-qx@ z4|4g+^vv3_JdS;(awZ$N}dwBwW&ooSGU6%41-|85CR3W_|}(xFh=xp^942`&d>S zT!C*NW7?y!9quLA{nfBOlAFzdQ3-Z`%{9g^Dw;BdzeoETbB%+4j}~}s+J$7!CAT(k zmkIwK?MQL{J=#}xch5X<2qWc?q+?p)s=UVqNKJwk?Sz6N#|C< zT<$vk&hK9F)mE^7$?r3=z0Hlsb*xm`fA#x+P8tDo8+;9}V+ZzO*)~`35xEkh6w|>P zJIk`jl~@azdM1hQ9_HJMK7u`nxsL}lz|Y}h2IsUAl`)A|bZk}LFBAzg*iPr`=TJd@ zkt-?wJ*hxNK3F{4^|i97n1R1pNiL zl1y>P0apV01GuCUIsIMcN=7AI$*j(Sd^-;(3)|SIvN2Z@@+Qq3S8_?qDf6|ED`DS# zXgJsxA@QY(2KvS7vot+~bcD7%+5^xS`4oM9GJs&n_X$z@d?E8_Xvkkf3afu%eaz@+vG~H4=dI7v{|m?@}{|xRyD39 z?hC2BZXEsEZ~QLLO~{oL{EoKcK+Kp&xv}Sx^M6%(8s>9b@B&T*p`!8q!Co$1!*DfCh9Z>S39)a9a72F^N}nY*n7@@h>`dI$u8r3Nnja z$1ZXm=Eun**Kz&04zwe19jP`*v{!H)8R7Su_8=UEofw%g`U`L!eQh|91FmC8IJl15 zE^{4O3D>c~zL3`L?F(rIdqi3}t|RUXaUE^k7ZN;hOfbz~`YWE7zs-Cj7(Z82O%eBn zs3P|F4WG=&LB@JVk^T>DMu~m6Xp^zZF z)A>fOBT#M-oDRYp1$BzKQ55@~-`CNOT!-B+p#yHT!#j%DfXzVvV4pZHjpGU64 z>4N*$bfRZ<0MEdd*v;ID^=-V{@ z-cs1O5WWuk5+=DC$0?XGm+sSHj^XL#>))0Fx;IF^@Vh8%!FjU$hU@V1buQ|!{W~m+ z;*{(L;W~Cxf6=$;#`~Ve`tiPh3%In%b)aPmhrxV+e8*ViI-JI;>V@MSbIB(@t8zP4 zITp@$X(C4l@YuN|8eVfR``Y8;OThXf?M7}Qaud!hc7vO^q6WTfvJfAo_?;8qKF0en zy4&F#6ahN(Jo;_sd+0KZn(9U5 zCPJ-@c?jq+auds+_-MWP(Z*aaaubo8h}^_>xrrC@+(ed5auYYwZ^FiX6Zz){U&Y^q zot*bBv6A%KuLlO-7mfJ0Iv0-Igi~zfCISNsfmN--L0b5PfxCKVO~bH};GF zicN46z1`y`dcnSlUgRcBFM#=UT)ieYG4=b>t>oml?T< z$W1UWBbIU9ePQ;Rk(-FzMC2x}8#lpR1alRUn<$=pM{dH693nTtbMVMbILlzY#C;P^ zFPr8jnvt7`?{uI|6Wj_1`zqj@(4#CL%YnJ#M02 ziJSPcv~b=h!Pl-=kmqFSamQO)_gV*b-dEzxJt@m^*Jg})$6KzxVB!ywZ+u%MPTl$5 zk8eCTmRMPq*j%3ZN?$I${INXFuljGWMs8wb{g3tI>$kwZc>m2a$;>aOQdfE$xHTOj zEN9q5h!uy~_NI%YP54w?Dv1|=r(@DLhp395|7H5)c*jcg9QREWD`wN&L_2a5k(+R~ z^dfT;?cL)h+5tDwj@*Q)?#N9zn~&T?NtcI_-X_>_eRJyLs4liQPn$yUeS@BUVryyPGx+OhXtKb<5my=Nd;^|7~` zbx9gO_BV4c{+$JX?dNu1{;;IE_S~-3y2^9AS}=E2dBNObO5#78JbIVN_xb93~gOwLVxI+f?IRnF7Nmn!OKT>iDS z@!U5rZ*9$Ad;NduLsGuj#xT zum2COjSA#D{hRXU4k~|WpN0BgTYEbBVnzLo_3!P+a}VsJbIe8T9d4tb{Ify(QhP*y z0B+{FBpr&1eZ6QsF~?$}Ot!Bb*Ux1Aa(TI2JInp7tp)v$sAXz3`RXrbCcye}_Gx^7 zjt{RN|2r$8eU{k&AgS7ZC8N#y8r_WjkDouj{1fdr%O>^nwa;g!WO@B$+1B)vWnPZ& z->N=ewxXXbtKL74_2c`8$c>58^(sYlz4|t+Ti=HD>)W(me4Ez!Z_|4JZ3e$8WSZ^R zi*F}jRcG~ngqe7wy9N8X7~tWvJ0pCcY0eWqQv5REsZt<^Ug{#qrO3||PYD;(lVh3i zzT&3|A1Z#1aI~8d;b=Dp6 zW`%IHn=^!?-3$pwyO~jYg?zM|0t9(?jibNz(7c<7189((w46XEeEPCk6(efQme_md}2JoJcD>$X34oBRFKst**j zhJc&HK4r#=9C>FLQ`RdmwUyW|<5MenRcWxHbZ2VV9 zuic)rj(@EAcXOzVD-h%y4Z>m6saJ$o<1o?zxx)nb-sQWquXZsk z4d#OOlheyJ-@8OSsQF*gFQqxXS#bH%9MHeiOHuxpUuB~uKkrWdlk*?Y>m}9+FyV|})_Ifd6akU$cU%<&;2mO+LZ>^kihXu!&`zz;0BX=x{E7wotjzvGd ze~H|&s6!7Pw+Tm3G!|qGTmt0a%<_ao;ItB#F>no#gEPz9>*cF@zdwf?r1MtwQkJh$ zMU>0rCFfgKzZ|b>y_J>Eb2>qhbXpxCllHRL%eRy({rF;f9NaKewcb2;+>P9^aFnS| zE@2;c8ZBGyQgPVptm5d1fZwfnUkx2{t~Ym#{sG+aNE-^uDdn>FOI$Fx<4kds|3TcZ z8X)8><9-PTcRW-aa=;zeh$9AfJRp3a@<+SO9rrO(Ry~0`9x4ap`xaeJugT%>>ENa%92uHg)PI#v6WO0(Qbx>r`kSdh{Hv@=@Fi2JLnVMSA3mtw3~~B zqunHGm!e*|CA6DG!qIN_D|ZYIR?Rl4A)x2O<}7VH)oYwCZj(E{wIcUg#vLR5R=MNb zHUBPdNYC0FP2ca1qvnLLLiY6TisdikjxTMKJ6_QIx5^#Ywf=rSys3hF9e3w*6}jVj zeY4zgEpo?^J0?4{m!4bm`)+r1-(lpAH-2ZffP3}aqn$CD-$9%5`|!b;?&*EQ1>6+x z!+kFK+1H8nU5h&|-p8FYV{gBn8{2XHMQ%8!@rjGLuXsWwIbgH;iTjFk>Pw1vB%O-+ zh{t>=AJD0m2ZaORwDKim;0k;~4X`}Pm(xmA#%`AKRlVOO)fb<(s+Y2Si)@4Qlxxnn ztbRFO)p{!{pXY3XLg{omKyJM9mDTTb?ykx&s@9w5hUX$Td^2&wupe;4Lv1M1j^vQ` zDfe4bLjewMc%V4i@q-$FMDdpuPt`CX2i$O`IOKpEPKW~rH{2(Dpz?>i%nhf?jrLVf z;D)nuZg_4l>?@uNxZ$~g8(s*w-jEw!3Gnb)J0x86F2^OpM;0|3O^BmSm0;=-o+;iZ z91o0D!u$GwSSNg__(j6O4JX9if*YPC9Nh3C;i=a9DZzAs!#PAr*qrnhJTy#gSG7?7sKB9 zJX!w8Ew2Yk^7`@nc6W5`NOIaNcN%?G_;yp+|3q#%uwN4_;-PdZ=OcnM@PG!w`Kds{ zA#hs383WfK--QRulYBX?#AobgDPPt5{e@6zL3pcrDa*IWHiGPYkn=68UyfI`-pb0S zlz=aX1a#V+!#Ll)UcRMV>Bkq-ABk;FebdPWX*bm^rTpcNQSRw#hBO zwIVlLw(l6}x5_Plx8~o)4e42%qv`wIanzg;R>+=CR4jklzT<<+r+zpTT9B9ItxY=@ zb9tNG^5Uks<@t)-a@==Z)t_YaS6p@9Yvh(Aw`_VryU)46_d~8{3@$wP=(*)y6>j+p zzb-O7M^?fuU!8IuvB5D1`64)(f8>TEH=IO&#?nAsd!F>!5r69o-3QJ*{sUKl?{Ut} zR}Cl}1gDj_j7hwrgXKxSoL15?_F|Q<>ir7$QgrZrRMksazEwF!&bLf|9B;ej^PEkf z44qB~NcH;NE9G0tm419NJq~Uds#BPr zO1R+>#a~uAsTwBagB#8iM}GirI3W%g+;E@pfyy5$zGSX(>?AjwmT^q*{3*2z% z+ju_UhU30tXC-mpv9^|d>d!dtJ4SEm&ftM@K5Afu!7sa>LedX`VCM&TkDx zZa8wolfT8cn#A9-yL#1(y{r2L4m;*BJju;g^GRVh&g9$q+8X;O-hdNE87A|O+;HTE zBR6c@hhdV;T2JJL(OJZO!_dS|bBru6JJAl4l$C4M%QR4Lx$hRuMH-2Tq4gplIK4^hp5?<x|}*=@XbRYgCO+~;cKhV3K7wdYCw#C^m0C+sBeSjHVz z@YXn*bCfnBjAP`ksFTOF!_|ge*69EQzGsg9`}C| z0=J9v(Etl$?!SG*&BzT$Za8woYtJS>{$0`&Fn2gLHRiIlr||nmJ-1zBp9XQ?Ft07_ z9Je{H53m1;eZ$xfJl?1LT=FxrZ+N19nPc4>`-USotZl926#WgCC`RGU>L>ae&g-*? z|Jy2ux7WGXyce+UV1z6R3 z^W1PVa>H@oaFTq)*plcW`jl|{iOYRT%s2M}H{1-k;b!E9BR3qmVf!>p^_dvCVO4~l zzzO3Vx#8tce6-&DXk)$=x#7qSM{YQB!!O)6b=CYnikWfSeZ0)&4w7$tTRKzcjrR+` zo9|!wYB#yfF*oe}4cG5^ATnbL~eMJ6D;GFinyvG9x2}-oZsKE(T_vC|8%c& zuY0|G!sW8=Mca&()i1{rc|`};TUowEwoxRH^NrlF(^64;tKtv2tbV79lwW{VtvAmN zw<0$jx#7qS_qD-(#`kuRq>e+xnWV2=e8%_3z+no z5PeFxag<@iqQ7CM3jN&c-0NO1Ul~Ws+-n(k$niv8(Gj`fBCSkv@Y~hj4Z{t$BR3qm z;m8edf*Wq{1#Y+Mq)p6cU0a>My?4tQXkBR7nF!=1GdYRxpBR4E+iQKSgfsgUpLa=XtVr_=^okxGetViZ7%l4I4(qk>bdIvQ?8G)`sH|4>rLWuTDg<0a<6;6d`qsHCO)SpkYb=}z4?8^oyZMG zZa8woo8X2!dx0D71l({Za>J1uj@+<)Ag20QjNEX3d;m@u=cDFpgu|HoZ{Kh?a>J1u zj@)qMhHrXq_-ixL(=#{B99Hxx5q(Nva1goSaBPHdkW2(=`$PMQQ3gCfpj@&Tz4bMexIC8_08;;!YP0tO#%e*6MUU<(>*{9-f z(HW)0eZ#?UVa$C-Za7ej503Q{_YHfc1OeWEy4Shay;i@Z4VDhUWrqcrJ3oksFTO zuzeb)`b>=6aDH$AP8jE-=4*t*nEP+va4&MhksFTOaO8$>WN!GbdnVp#kH1A1KG(wV znA#Z!`svINd zyVtqbyt>vE|xvM+g(z@49q&+t_b5F{0n42CX-}tsjnY#16AAj!iU-;de#EFY6 zOKdLBe5EhndHH6pcE?+;zF_j_{GLv}UQvGJhBwxK75zkRSj^Jfe?j}>{rS<~uxKni zs&a=_IZKvTl>?QojMGXv8M9qpcmo>V?edjzv|PS2?vUeE)k|5vRXIk^w@iN=Z@cA- z{)P*T)Ie41&2z)^ksFTOaO8$J!41z}A8xp1S>d+*>?lJ#=7#43Zg@U&!;u?~+^~Hh zrutZn+^{M_PvC@cK5B4;!~JZF?; z{#v=1LGtAfi_B|tJFV7L;aWp(CwymHm!tWuCii`AWD%5S(SpHAiZYnAhK@}-LU8JB-;ZOnb;<*lvx zYp?$=eMpK}P5*}5+m!y-_9Zv`{PSh{fByMN{eN+>y8fSkeslVN{`qH<(BRp6Z(T*#`!&${MA=a z>hJmId5xgho^!@M`TX$rw^Q~v*?!m_xZFFtw(q5W2+qfUSC^@<#QFi)%q=4BVu_=WKX!{cp|Up*yPjtTgKiVqb>|G2DpI&A{xK>Wu|*yc<4NyU?wNbIrCvQL|^#2+XQ zIRnKKrs@x^+_s=VyDGoWGQ9OC6377-;855R#`-(%(&nZ5n_@7g}_A(PN2ju*c z3ET234mmOf5`0AQ{};v6+fBe6kn^`qSmI}jFWGP1#{pDUfJyKGlsSP<6Otr<*C2No z`88eJIiykksp3659}a$d8Owu0YCj}Ph7I|!ONe#_u`8GMofG@YiGAawQMVCo%tq6O z?aE`rCTrMq4V$oGQ#NeUhE3bFX`41})23}su3Fl(EgQ3CW43I}mcy;gmX+CV`ZZ1I z;)0ve_08E}jq9y}wiW|C97AM;4>Zkr!bgfCFK=FgGborn>BgN~4r`nGkCmj9DfN+@XS;G6;k6a*psQ4Aa(ZAGQ zl`m(e_Panhn#2m>=wHqdj{fBm;pksxW+-3nUwVY2e_16Q{mVMx=wB`pj{ar#j(olY z?MD^~NB?q)aP%+d2}l2u9C`9nkDWa6pgEuXq&qJobn@X-CzB(eeE885M?QAqZ6ES@kS3?*kQ~yl-=UaBQ#46_ zg7U=|T>ggnLNIO4i00GlFYj*3;dMk-z6OBaXzZ)DO&QkDwbc&jqhD# zoqD5__+fYQpU4-0T=TulcSFtpq6(MhaF_XK{Y$+R<$vb&<_mNDraSph&VT%*XjEFu z?R4vPyOdk2zLr~ijn6(wZ7{Conp#(`HsG4$T5iZ?Tdq8=rLPDY1Yjo^?mPo&pox-`yYJj@sm&0I!D?^>UVdavR92i z)#x6nw~sXHZ+BnROoDE`TbHTnhKCF=ZcV;>tN1{_5c`qi4d&l+xb`YZUH z^_DG9O*=lwd8gt7!tYglMED03Pqjgye^^v}s5sI_<3aG{r}|IY)S+?O;SW+D)C-D9~>9D>oe9^KtftPq8~Wa6TG@?HBs7 z|K9UyR^*0T&CPPdY2=0K=U2#GI!iR=oH4>@ld%q z-_MMx+U8#1j>G-b&44>z*835&eWSZI`*}LR!)NV?@PVc|sQc|jj>I1+UMC#w<~ZS* zwwnRrcwn3*ysr<43xp39ze0FTZvy*sQBH8j3&ib$J6<6i-0>O0(Qbx>qutC9hl_U8 zBOL9fPdM7mI^k$H7YRqZNr)pxyWxHEXgB+nJN`A*lbUT(LqN}m%~{%Zs@FJS|M!gA zotT{jwV7OVU-7NFuOISo*5-iAq-fCckeB4GD$d1R(EKmym(u*+Z2npQQZHdY1|jts7y5Ysdggl_cjv8& z+;QAj9DPKIF=1aQb0F3CrH%K6M(%iRt(c3PN>%~sl1{0EPS{dzr?aL2|c zl{vuanR=K!Ci9Qn@Oq#ouOH8??&#W(nQeC>vyX!a;CaiO3kZ3M(Y|V0nAJd{yrk`v!wswZX0Gr7Yj793$sj zR=*stYQ2?}&vQ0`B6K<(Ad~j8*UPt*EB*LldK}y^RJGnbH{6QcuyDZOxL_Z58ZF<5 z+%WnFaKpnAZn##$4G&7V;St4OR{f-En9@$=05_Z|4t;_fPKX2kv`Hg+?h`&xe5m-6 zxyJD#?<;QY1#Wo!JG0GtE8vC~0 zvZwvGuee=}8*Vnbo84EO34yLhYR}Qy88N1>F1Fgu z_#GBbReUB4lslbKeLSN$-evdw#(1Mtd)K(l0x!dJfp3I%7*;-WRm(3t1$=#)V6qG2xxvY0E*qSBf63s~`+>pxDCj+g zE2Z8y4c>(cb`4IwziM#m{Y`^&44`4=xpE9(R_CpL+6+`SppQK57l#&EP5|d+td~51 zK58+mN`xMSFXSPvw9I6Hvhxs_(&~o za-qF6_IkK?gE_#t%S+-Wr8XsQ(sPr(Z@%vH{(2j`9_zt6-`wYYtpu-j_1Cqk^6fkK zFyytXr(Ql=le?|M-6d{Hb-?R?gc}al%T}**TWjyQSPuiQG<_O(u&=^vp6z>0`#?6V z`n4GQN{okR8=t0Y!>V74)y-es`2IRGWX`^i6yP?`dTY}BRmm@wZVZc+Wsp_xwE3$l z59@EOa*pLWW`^2y&-$E~9lOhyl~;A;@|eWnxSu15`eOnI>M!&Uo91P+=hx{%BCpX~hM`-k~ zVehAr{how(38D_&!K|??TR}e6#tD`~%dQ1@sog_GRR4;1(a1IEt=_J;A_fj-?aIQ1+yTv3DNVDK*Rfx)R~dkmLDJ!=}Ade${~206|u=kXsQ z52!=dpabXqa@M+#=>^tqRz7vpjs3*f>SAJ2%6mzA6c!%xb2yaVYk`jiR>)93lP zz;uURf4FA;t2mDy`uUS`9v6^)j(Vn?$7Ax(;v_Gt-b(EQ9)jzmzJzO@?6VHrsKt7m z$HK9(=VOt7(LCfXBZ>16%QbNxzEAJ_d|RFKi1b-EVm{M!I1#O?Q~g$WG=BLO(#p$n zL$74}zg2T)arw5^>yzHkvc$R6-Q&jBzli=O&ZW?%VowCTjtRN5#n?A0d6EnJo<1R% z4Xa@+rv75br171NMJAZ<69xBe8hUHJ^Jmjg`B}S9(~adXhSB8LFsmK*IjYLd`de#x z#PYnExEbC4({VG4iJRF-Zie-e+)R#&L4D)iCq08dDdpuj6(|<sdZ~TIGZyPk8(EIZjCX^F5~(1n?}Viqc4Q)hI@@Hu6^Fj$R6FY zBX`g%3f*9C_8_0ymwHq)jH4OgVVl-9co+V!8hil!ronS`+U^>>2fSgp6E@H%4cOqD0~Z&taSpMyN0CRu|H zocGIFiy+4}Pj|uPbfGUAjTSk?e&6{kzirZGyoipMm0S+PLyf$D8@_7(%D+SU@;WLV z4A1j%xl4EG@r_EJL=Nk>ip#n1a1nS?E{E$Vo<=>>?C3kz%3mKdY&VKjWj|?@-;Wc( z+2()PY8|b|<;aH4<9=JW7jvOB3%Scj;&P-mB`(MJy?tMDt8+Q$>daqx^?%VyV7Z8b z!*H#v+slFLusU?EOUbSzE*JG=2>s8cm8Y| zDnDyCYPzxf#jseJYj}Iu=cp<->u;^)5zF(YKnPBfx({? z#di6GVo{ID1@#P0E+{jckA~BDItC{f)CYbxs7UL{1?9Voh%Fby^@x1E2|GP&n7`w8 zlWnce1%=;D9R(M368Y4=SjYvP3-GW_>l?fa`Q0}70Qg?Rz2xZhEg8HAykl@S(BU^- znx76DGW$(epADShWT<~5-*n;OP8t6>3dnw=Mg6;D{8RtzH(Jy``z;prZ&tY=aw<@h ztU(9P`{k@fkmH)CCCp3dLSM$^g5Fe+_L7)8XB1HO45=atA5=au5k_7zw zD{<+GOP3x@;?hSdT8vkZ>{AK%k!q>(uLGb z`vR~3-Vf9t`^_usCAsuIxJUXYm)^iUBjQhrRx1bI1x`JFFL18+M4ViD4vvTM=zWc+ zXK-@q8I<&FP>a@+OYb6n%cbwbTpnLs?9eVvQYv#X-OTUW`-Y1<` z*+cr1a_M(9V{+7=S9z=!m%gyj9-B*FL7mk6C2jajd_FOtG6NRf=!1@nV-LBzfleM(~OSAT)FZ}_Cw#S@+p@~ zjO&QVe_hu#n|A((?MGS@UrXE`L;3jnRjYm7`^$L{m1|#vYu3jAs&Lx(>h21EI}9H7 z6~bHImJh&Kzum@nBJdwNV;q7FtNtym8pyhs{eYe}7%U z$YGziD!y2`#jsdeMv@)Lb5(iRXIrbBV|m_89L!@PEcb1zOfX3t%*Jsr)GKl@4O9&3 zB{>+*Gh=;vQp!uYlY#M14km}fF&=U-J>X1N?`u4qXGWYH4Ck4h4Jy-maxeo_T&_p< zoTQ`Qww?mF@6c5|9j={Tyw`|4W z1K`&Tp5q00%iuk}7%S#89yE9d4cRG!_kmw9IQ6e*aO&R;gH!)>@}^F62sP?M}d2hRKDtaT*EHBZ;Txpkp0<8m;cHt8~6svobbI2eY9y3o6{ zHRYpfKI18)h%|D{1B z{^DE8UQccXhg>_R>f-No6b(5l#OLEr986h0P99gTc=fWyXjLU0>ay;@BD#g1vmSND0(#xf^Z-TYa9ny$4gH3{EW)C(Lj z3|%>TsXSXbSCyOfx7PBA<#{u4MO+81)l6KGawj=DAk>coqET*M3vlYgLEx;w#18@Q zK#_>s`8vewaz$sM*-tWEC>G-(SJVN{{F5u{8(i<}b2U(b7!SFkuEEd1{{T4iquE*y z4ry89QLczw3+M5i2YwfQKs-jUKALov*8ENELU!&W=UYeJ?~?mHroZj^A$ueh#M4%- zCYYowTi&e_DEh5mQ#jr4r2r4xyn(^H2(!m>F~FM!r+%I`cn|v7H8}P2s==wBHx1s0 z-rhBM0}s(KoK6?`NrSTiKWA|2=WT;iKlh@X^>H+6>gSTdsh=wbr+&^V$Molr2h=BP z(1G)QIcputam~{O%*VP6J<@1Y6;Mp~T|e!enD@u{ct&)*tXw~h;h}ckzYSl-F+G9w z7k$XW!SFmE7nttQ>q|BBU&S$T&9F&1rY_Pyhx(_N`{dusU&|$IPxuU+m-i_GINN6( zwqdP$9MjQOdt8p`YA|Oiclk&hlhmffF-7NDrFlNAvJZe`I#=hL-%Ydrn+Pg#RPusw z-)a>c@wIEz9y$B^OQaar|DX|RHOHO(IBlDhAwm9EAF&% zt|~X{Z>{AK%k!q>sAPaT&1c%Y92M)`lcL^^OM_xjKi>#*5u*W#!an@7gpukm&;@iTY%NgP$;s6-KbAKK58kUn(cs9Y71 zpN;3J(zK9feNF zzYVLn#nfNyn09>n95yeS4~ucVE1So<`Lq5sUE8nMxILE_BoxCyMFzg&PWv2HvmB;-wT}Uc2U2{@pIiS;(FG2xNaBYA;-^k zyNI8G{|=P*tX%V0PmX_p_$|kO0UVmIPa#>gAsm0Ob8oBdIsV(oukwZ=$G_LC*G5@& z4Bo|!6@w3e^BYu+U)#r+#v84CaUWxd(bdoccMd9RH67a{yI^8u}9)`^BwwC=W1o z-hD#>OgazsS4_H$UdtssWGGqMol(1j;jJxT!&hos&JJ0pXm6x+Gd_bS2 z&RPQMP5oBOr`H>m&+mP%Ct=F+>Gje)V3lN+I6^0e@TXkCif`J(`*d3_O#9k4topSW z`{ay=XB(gP@oiZ3YcX;HjE83%-+Je-ZhTy?jrro)a{&b8Z1b$Q?DN)@Use9tNBPDe zU19;mX=@=Ab=&+^m524W*5`=HuMRi4+4FZcD&;KOU4dJ;E~oqr5>VHBY|SU`)Xh6a zC!6|lK;+{%M&Q)fgTPrai5~*qfub`Wp{89teS_O?_!-Z;;Gf(S@h5=~&`1y`cbcO@ zu)QI7+5=AinlF7WR&e6vPB|}?`9H(_L$T<8893*q64&(`HU92yamc}V^qYLe2f*q7 z?{XO6}!BGMZ*AAFpueAe4R-tT_*AdXw z1l%eEZRfKctV=1?c1R-6dqy|Q4hHj*zm5Wv^Qiz2-!nafcM;}>!3V(a7(7S)*k|S| z_kiaHSJl(Q?pxgfe#!Xn1HW$Y1|EW(tR|-r>&+g_J0;F~(=<5iP1oS8H&+eLdeaEF zb4{1^=A^;f&U(`~IO|Qw&1?LuH&>ik$)894716n)fiqA0#i4aO zCxG*9aG86dcdB;kgxcSCO@l`~h~Aq-^yRh1x-Mh{VYfM{bC6neb!;?xlof!UTTiJ zrop+yC4Ug>PKI1g;*vd=IUTNUo zSsShUbAdyy*K^4myYAta`N=xdcSxPc}YH*M?Qk7JE?ntNXlX{S%fQp2G-W zD+9e{pSQ03s`AG^OyZgY!B0WXvGN72P)gXAZbVpDC5~^u9^BnuDK6IWIi=t`dkge9g}PB0%!iu!2iJbUk0A< z7Ka>+pImbfIO8GLoEc7;Tyw|ZU5Qik*#~}B6Tz{bTyqW*!*b1cs=4Nc&A>G;1YGk% zz%`%5^QhW}T=TgA58pF=gLfh0+Xf#1x9hs*s2_G+SJs=3;fPsp?0T=PH`k2+KI+pg zgE#mPh70ZjKWOj)@KXjS*UWjr`Z(&9_2!20&w7(vju`c0+2E`FabdB2=vT=O0!QRSGFYhI|y)mCxM3{N|)$c?sz z<)eygeh1QDEPMCi8P9RKPj~3`him4)ifi7t#(lE+oxr4Ab7yR>`A9vkxjp{cBsZW- zD&O1*In7&^9!=t!r_9wQuK6cF_iKOTDqQ@>%inWFTXbz0pZ{81^WXZiio=fqU`)Vr z-o-rBem^cchkE(>v4(Y@*DUF~RO;@LHqN|VeFhVMI97u8$;v71VO3}Z+wZb`5?5PD zhrj3!@Y0>pmGRgK?epi1C4Y6F_bdfw&M_{} z%5*LAtID5EL(A9p3pCwW{$f~6CpEl1tR7V9mGxIwU#gxrmS=R2OIft(R+ZcCQmE>S zx^nq?iNej#J(4)n#F=JUUCxyCXIb>e$qkCB^*|5HnG(00>Dj`&`&|zX^y3nf&bRHN zQCUI-ya@a{Dxa^H!wFhPrpAG`n{LOhmiukH-^GCIJQBLWd#)h=%4g_aJ3Ouhc&RNl z+-4U6!g;#te*oOh)6GGgTrlzUfcFf}7ptAW+d)HS=kNA`+xffXJnj5la-MenE;&y- zf0vx6ou^CA)6UZ+=V|BZcF}O!`MBgfZyN5DoabGGlk>Fmbp6Zj@Cz?Jd;aM&!eyTS zSaDva>-;kp&S!@|_RL40KK$XQ&p(|VKJ&s0a{YX9@uBCRefF8>#KUvXpMU1?d*1)l zp%>0S{h^PbT-SQi_kkAqZWB>%u6YUd;AQp}aVb{PO}WnHUyolgFTaLEhd=wpsdY0S zLe6ywYYz;Npi<|mQcz1@N8S$1rvK+AT^FhR*!)*%yZ!FCY>*vBmL_tbU9SrRadP1wOp+11fvx-{R7ndLR!b)o+IDwd-p?p^3@Y8%%icR~_ zFsBH)v&GogE_sp*YiFGh%!bu47E^z*!^XGS^H=wIKNEXc!8`{L+_y5&Ta(JKDt|T& zm9yPyx0#_}BNj@fk2st_W_?g$ox>dM7)po@tE-A)|n zXP^|EH=02qR8RF#{nzL17@QnvA2{pD8TfBN0f{dI?*eE1ZD|h6Sp6&Bm47{! z4L)#amR&M<4l?4p!F#|52Iq@mkD15WK||Iwcpvy_gE#OHU4wUlUp4pu_)UZ7DA0!C zBB}Q$4Nkp3XK?EMZG%(q_dm$MdSj%%K7 zu8{+MXH5>ViUVbMR6k~`=o0xW;VQ+gy3q_Ubw0614)mp(`LE(YudR^-<$UBxInX7P zUwsbrXe|zOadB~B+%*GEe(kVua_3AOs95@m15F&L)CPG`%N{pZt`zeItIdI4 zQ{P$Ek^hHIaSz0yJVx{X$=_E0=|~bt5=atA5}29MEjIOE|MQUly4agHI8 zlRO(}@p_ISW%zd9jv+09OZD|~IEHleLCvE-8qA|ViZP@;$iMQ@;TTdgz{9q*Yw#}Q zdez_q;5QAPYeI6|HFytr1M^_@(xr!iUuz|R@H5B##h8+eGm!Mnh38+-tKFF0xD zhhs<`i$m{M3{JhjW^n5L!M#o#ZahGfq~4!0IQ9O5!KwE*3{JhD)iI=ZqW%@q&9Vj^ zIPaIU*3BH(Jnh8>oC7UzIdlk7RSH9!zK*;d7}P|risMI3y2KG3FSC}o6oa~YoZ+pl zV#8OBA^il>U-U5+4u>AIV$BNh{ok!nC`jd_!U3j!ezy27~ zQmrwhBkl3WkZuOD%w4w97?Nmw8bg{g2bAW~&)huvw1;8Q?E7Cc2AS6S@RHGa`uFS@ zXGA{1JoGvB|4R1Jw`wHiG00wTweJA@7;R*&njn6SHgS|Hh0fD^#RRc(>-hM^D-8e_rh~sxx7gNxivv# z^SJjs@x4T-~(J!4|MOs?ZjoW z-k-vA^`MB9gFd&D8x(~&xlGO%rhLx8Kj#Y*Czr|j!i?uR`0wr(haB`zE|c?x&lb1c z?|O2X9W*K(JoiOOLDvc)_vGv4kjq?}0+)%I@bhjRkZ|9;bJoW+bronR%D5nkH1Ku?_tK3zCcTg2?8oUquuE864h?8c1dl&dQ zgAagTHh7K#y=`#n{a!P_J%ipa8Jv25&EVAgTL!1zlLJ+8X%?yXr@-+Or{2#hm-(+D z52#_*pabXqa@L~Eam~|ZaLxl2q#Rnzs!~uVUq`CA%w09-leZ*JO#MsBISZAqyYH zukYgpV2l^Bw%&=rf9OQl!$aDqwPE$9#n|`t0pYOmX}UJ7dbQYQ%U?{+4}$9)M-Qy* z*COYta+GUpv7Vd}tx;}tVDM$&ITZ5*w2NG44>;o?*U3tMHqgfP-lSN z3*GFCu2ApKB}}`o99g>|&^Grg@t)H*d2R*O~Tk8&>ds`P=re{ixtl6W3WtZ|(E$)B44QBu@<0vE;ILmG)^Z zZ=(S$#=dVUGP$tvX}UJ7hOyXY%b)K{Yi4mIu5+|}RS#_cLB$o5UkpQ+6%wvKS$(O} zKkIL;dKJs_?npLmx@RMP6pDq7d95oKa-A{(EpeUFs^sXrQa=ueaFyfh0jEA31kQ$t zxYlv?-$8*go;L8l!DTwF^WQ+j$9Ucayle0$fe#G+Uf|?>&dRkOoYzUthw*E^G@lJ9 z3h~+HI;C?x(K^SAI%l(W)cr2G-(zkTXR*IqF_+WbZM(Z|cXz%$)c*@y(O;GHOu~oTq)1TUAydWd&lf?ovnIY=ltT>d%ZQ^;KiEd&Y8YZmmXF6 zMt#cj;u6<6b6jWI>uuQ7I#<8UWv=_YP!oURN(1>%d#o#QrG>EBmkvbloanN9So`3h z13ab#)7>@B3;l4-d6iZ3LK)uL zD&#ns&#HN$A6etP&?`0bUo|iE)*9!9UR~q7P_DCE`y2RnyB1fvc(gh8o^a>BmZe2K zOI)c~pouF@T&YwH>G7p+;MeIJ__Qb7u%%6|B!MJ>B!O)#fhpS$D!G0dYbt#=bnRN8 zPhS4lu0_5Zs`xHx^L$s8#+r(iD^_mE;9c#h@I%3l3WD(9+lvuUUvSpG)SjpZ+f)g4o@&rzj+*56w7DwgNn z`he!J>7F(Bc^M1Kd*QjRT>QLznK+)tnzqka6YD+4njZAtajb6~YvLYSp`NejSQGb- zvtvyiaIU^y4#%3>4{EF_oTJ~ySktWS9cTB5<5-j3BaUNDOBj1lu3z6NISSP75l6kZ zd&F_?xLYP3uA6N4h~rq2-6O7#v83MKqV;8dIHq~W;MDtB9c%h9>L1@#4LWeH8f#iw z)vZW^f{HRT?1*gz1KXK z8O9GT)9$^tlKtN2dXe~x`jxoSi`m{^&P6^vcJ9jibnBV*GsNO^UY_sJrCg%simDZI@m7HyP zXt~+`LaaQvHpO^FU zId7Tu_ze7W-ZK4jUOwk76X(2q&Rb@>C#&vU*Pah%?azZr&9ZRb{u?PMIp4wask(-3ZN8`Q zM7&#EX3GX20Ka5#){E-~XT2C0oG<7-X8wE!4PDdVec-1J-oQhw*S!6PnTOAMk>>NG z;3qtNy@XTU+HJz;=9-siPI;NVMO@TP4~iql#iaB3_kpXviv(4@RMnua_ubQu^YM`l zf3o>+$sNU@#@-*pTbs#-ui{uA^nCuk;1wt3SUI2nCIq9^Pi+n>e=V1=y`lgwU@YV3 z3E*tyH*BsKYI3X#OXKcow~{#4#IYJZbeEpvn+`{o);^h)wNIv_KdPhKjAN~}4)(h3 z`6u%0l{xm1BaN;joj6#}J+JwDuQXrPy=5}?p^K~GueF=BPi^f`^=&csy@xRsE*qbw zYs0Efi*2_2`M!MdSnhY0IM}nnbB9h_zE%1XlV6NijA3DVbX$F?(m(5Ot$G!Ej@`^u zaJK1I$uAZ*h{ikX%EfcA3yFhG9Bh_Z4wia&Ml?(1Gk{{T{wxE}p_s(U!S;ZkfM$|| z8gLm;FxnuAF z@O_4B%~7zNzpB|*ujF8tjsFaKe#zh+;MWb#deO9Np+Nsn8=Uo`YjDM(6*qZy;k$G$( z$5HW3YuanisbGctuUwINc;Bo(JQw2Rc;(9IJiMX&JqI`<|0`E~JSgv#>^rXvBJrnr zuDZ6&TsB+tTzgaGD2Mv#=egG6VAEcNTK|iq-!G(yH3P!>9p#X<{aF62hV}Knvi%rx zq-h>+uQ%Gh4&}3&{@QuYX&x_B*PqZu^w;DLJOGE~7*7ap!>U({slV7^*WGb@j^ntNXlF`W(yi z?nq8;x@RMP6pDq7d95p#Zw$>U~#hi!GkaKv2%IBD*^ zqp06d=d3{o&im!8bw9^7PuH*}!9nPws;@dxt?oNt`BzN3j91GyJgT^IhPO7A4PP~1 z`ClRZ#V|2(Gd$1711$9VXEpO*#g*Us>LRvDx$^8`Dl2VjgJv+{D)3!H&$_fHa>C}VO;9A@oBm?topOqX3Jkp&WAMP z=9u(3)>|%B@!9gwaI;a#l*EIu6>ki{|uDtjGR?I4JhCV;LE_f z1}E1(0M7bGu01#0`Nt7Y4>;rR0w-C*crF6(fJ8Yf*F4sfYabwf%e7wzr{wE*NWQG= zyz;eh?TZ1|zF6YgZ{xX?LkhX}y@uPSOgjee;>L=>2f(ixJO^2I%iukdScco?i|nAm zJ7_3R8N3htg25YjsogMm7x*264}kA8+%~!P+~DNemkmy?{gT1SwGRx=dbP)J;jC9p zgR@?7Ed&*#W}Wrwrt!~ub=TmmS0|y*jED7VR=IX^)==lHK?lzJ<*ao-$2CuPz|~I5 zwf}iduDT@&YFR<;nS93Z);3hX;Zeo4?*vyZ=0NFSc%F~TUAjY$$H;YuV8pMA301A+ zb07HSNxAl%=_7Kj-s5oXIm+*|rCg0Z>#(^$T8nEx+FojoJ1_lO@BvWn@{{JJi^hY? z3Fg(!-IH(WU&%iDRuz)x2pwk_o3|I4cN%gz2Zrlzexf~0!aefTmn;`%b?Qhr?E=d*=c=$SDWV2cR{vQ zvD^l^U+d5E2+AGXuo}i<>MwTK_%vM`R>N6rt@-m@a*(N68mr`9jKSkOXG|`(jMSqo zkGkbsr7t!OEnmy4X}Yoe#jv_#a`ri@^ve3H`@B{99Lw`=eL!>AbkCamyo`nAz3^OD zE`F@?Xd0_bW0j+0m25xGh;pfXIv8VNz2I17-{2gp!0#A5$H2xuv*&3Kcy4gMc$N*`K|^`T;C*?6G^H0&g0e zW0j{3&auj_!8ulW)!-bfylHTbRW>jtqK~gxVZAzOaMr7H24}tE-k6Ms^@{7k6KB0z zg5DBmz2chb#96Oqb*%EwAt$JF)}RCD{c_g2pW~XRCiXg=bgc57_%4R=@vP+%9xb_0 z3~KLhF}$^@Z1}3N$|sQiqK~m~Fg(x41*SXn`clpOt2&463*$JA@wrLID!WV{k&io8 z*?p|YN&T_PrCMW^3-hh9*U;LBHdJ$zyKJSgO40Z_?eVBf3cNiOVrT>EY|tcI}|`*?aU zJSL4V>;s1J`94|z+BEdmr1?|1*svO3EZrDZm#eX9RF#MIw^ljF@{I1jKBhlxx>e<| z+lN@)QCBW%vbnWwmJ)|G4GxR?(-t{v{CyNO%U8ti@Enzj{@(?>2b}u)Byd&`;_n6C zfxHp~%S@ulTfd}$RczJzPNECrm-Qi;>KihOFnjNKr8pql|6wtEdcvieuNEB|_& zH2A=wS$59gIXZxs4c-IZH@Jw*9k&hM0lpWVR_3PI^=wu-kw@{J0n{OD(1G)QIjg91T=R4qobEF8LZi{5g?R6~R?7F7bQv$A z<7HOGi7@=6oXGbf{Y9Tr;b8ha9~YSJ(Cg3C%zqUp(g(*qDJR0Um~zx7t|2qp=U>Tw?{htA$;$HU^)`O~ls2u2 z6B+GCpH;y`4sUY@_h9A*$Y^{gN_U4B_PwWl3%o9eo+6m~iybyTO}9>bb@Nv@zO%8+ z2^N!|&9erzd9ItkD*46IjbX8}j6I6YUsZWne|4XuO3tx7Z%R%?2KwIf#1oG<4nB3} z#plky*f?@{;c)ZN;*0L8^<%BY!_9@mt>)W`8;y3ewb)#2>hR#IhuVI-vOkt}sYZ{T zBbH&|XXl7E5g(PN4&!Uzo(J_E4#Vk$oDn!3+c&L0 z4j%a?e~WS=p3`YQ{;HM7C@1psU!x)}`%9ciM}-n{hTtUaJcz`JsGwZWH_92MZ^{b! z41b5cv;t!vYv`kJS$;wLP&Takv>5wZMJ&VLN#i>^jH2Wk?S;n2Lnh6i%EgA&48+on zVTltd6_>xLE0@P4gw7M0ZzfJ8aUzBKJlJ_6(kWQOw?eDV6A>l%y2M&3=61L=q>W zx?tZ!>Dw7?5rx}=V5a`<%zQg>B8d}8oXGS!k)mR!c_P`c&!0FEC`IWsluzPBN`k>f z-9EjwEfObE2(YgFVsk=bSlzyV-SV*hPQ;WzF#8|aZ)fJ^irJ8>dX)`=5QjW5;(R#{liIoF$!L;Z%wTjYYW4DlQnX`V#m~cj$BW=84QFP9$+6i4)lXPUQF8dgbN$Bv-E3@&2@)NLo*XFQ>$bgzsj$ZC|)* zo`dZlCr+f0U|spexP%y%I1y@Q`CL~nk4Z51?aX}QMAEl2tfO)5*_bs}=jW%#iOdI_ z$b8~Nq`29SPxC|yStL%R{2od3L<)Iq+&qzm#EB$MByl1ez=?d@g4S)zfuwzBL?~%J zk)qjmziFOGAq*Y&j~#XU^obLRNpEz1MHQzM<3D0py!SSmcHQ!@{_5(1`m*#|sNWMO?dks|>QvJkoxCn9B?I1$zOG*2Y$I}?9@Z}`45^G6aV zk~opXiL8widF$i%Ur!`UYpfRUzG0s~eLGV~r2IRSPnsuEmP~P#IFV6aLnUMRfVx~l z;zSC)vhq7yz$3rAN02yBmn-t~M2;j*B+U~kbm;+eB1hJj6A9N43HgyDi4&3HPMk=g z^Is2H*!DFqZjb!(n-AW2i#RAtVtUSTk-nXQAaJ7mcs?#T-J#Ff`*vnAaUzKmNu0>q zIFXUPcq419WSn+70gY$w zz`K9oCqMUVe`MkeF6Za(Ws<&2<>K#j^iDXBBf6LLl`F4gKlIJ&)u)Sm%*_q=8PfY% zT2JJ@@)sewms8?IoWhu&#EB$ML{-A-!3n`Euc7|7%si3B#EB$ML^W1*JI<(W(6=*- z)8j-IgLxv0i4&2s)>pl@Wj!`%d*nh6;%vYU8oYys?Ucd$z*tG$4?X|vv(G#y9-e#t{4R~N4}GM_?wWrSCsLHTeTSuQXA0HIA(-i|u{!_#&1SuQXIjS=mm2Qqyza-} z{k{`Bq^rYYE_+vD!V|#xPGF4W4$HIGXM3bibZ`F250?5|`yRh%0*Bui%&GrZvYW2W z@O>`y&1^XBbGi5*``Ul=k*`CaZk^+oG||(m)o0W!&aGqze!U?Mn}1n9!uN62V^J>( zSMh6kQ{H0}%Io)w;}g6H&OtGFl+B|D#9`~A#uqzmx;oAni?1r*HqKaB>qoC&Bmd3$ zL!z?V!*-;6bvqih1v_%qgZLZ8t$1HSIaJO(*28A{28rwuiNArWybtGZ0lox<@cL71 zqE|E;!@c_4)_b&c+)Y?L&K+1i2NA!X@Va)7b1J|?-Rc><<9uh?4TJZA%R7E1-}Ub_ z6}Lfo;JjbXT825Ud0Iljb^yFq&KecVW*_jk0}IPWZ~drA7v4o@%SY9mP=?of9UeCP zF}bOjY*ku1egf%BSF&_4JkQ7FF5RKWe^E34k4PZ<>>AHy$nU$tNX2c_((71KeSk{{ zpznJ9ro+l#%O#fnU4ZY9`{7~JA6DCX>#4Vo%rB1nu0I$QV(v1tq3?Q0aV{I@U4P^s zY9{@=*zvbkZt4TJgt&bCAwP_8!S|4`RetRy4ejHHtx_0GHXXUX5C81rL3%6M?|z^Y ziGS3V7}^%A<=@ATe7=%>_Dh>1|5jF2HifMpRko0=hkV!S(}stC=LKNQPOC=IEcXMzy9R$7@PWYv z7Tt(Te;oenFG@UW%jHm@OGroG4T=|ir+^<0Ukc8ao6pXDoqK59okY5tZ1`Q`xd0FA=w*XRC3|b?w#;;DweaYaId&l6E`>fiC zpNBjk&a6QP&imyYvk?!X0l5l)s&6XRrCnEPGMrH}Cup zv~73p%KLKvp#1AgHRJxf>W&`~8@m=?xAG~CkMZxQ7Cn8zKE6U%Y z4dDSesP6lN8zQce!^THj!g^$Ujo?Pia+r2}&jsm+&RA1fCx7>o-~FDqsyxHIsXLYz z>qoD(eRVeOHd)`1@|~8AOMTEPuQsv%>A`f>y&g91A&EzA*$(1w;;ip}#V9NPyrhSKI*=d6}&~RNf zIBfy)KkChSL3*=l<9^x~d?C;VwAJHJJZLB%*rry_^?BT|EVM|f zY#zKSSZuXz*eaVd*0jZ%3%+`oa8-OZf9h`|;;WJu^UHHAFT59?JrBCDy~mU zS(bRvu$GMPp7y-B#DkX0gzpuekIQYkL!aA)2d!@-)>}VmYw@5gTyG-^&*p6s*eJnR zwkm+wh(GnQhB&N0y;(k{ZX+fhR0JNB4{YqjgRaenWWT!+sB_E?v^FkzuOOInPHHoU zd|4Q0-TbY$jr*`tBTj<$@k+6r5w#>I zKa!2;-h(ppw|qQ`&N|0Uc$c;vudC)$rf-G{39-*hd0F`l=Tk0iI~y_b-E`!e6gwvV zO7_b?qSCTBB{)1!eXLxPlJZJ6VzLpP(%CkWHpWmR3s+rUa%wi>QnC@ZiH*24rj581 z*oaHXMzl3^vg>3cCL7VV{i;dp^<8;=8}Zn-vk@cTO-F3RV7{ITe(sg*tN*S#l8u<% zdsS>yD~Gi9P#SC2`Z0QV9#J~(+hLD+ww>e7N8Cm{;;}Jp#PA!OW64Gwts|2l$wo{z z;-;_>Tg`1~BaX~RT-`=2zUi2|=?cW!Mx(Vm@rWuDuKmL`h{|%BCJ$;k@hV=-@@o3- z|3o>P?#k9f+6dNbvJtIBifh`4vU1@}+lb?Sm%Vw{r<9k1S-WSo^(m#?{jgN4NeeN3 zmmRMy_0eP_CL7Vdn^b$&i$|=zK4q)kekEIeK4OjiQ0_TD$wo{(V!RzsHey^Z-bR!O zaI?%KZX+A9HI|JStY_Y8B^&W0@oF+Qnry^mBW?~GG3|4cVQrW{xun%N7=w2BXw^UA&vXZN^8dVx!FEr&8_x$W6e_XLng6JD=~eu5@~G4fRc@v zY{Y5Wi1s~a$LEGsy5>GNTYE1=S)0aIPHPLklKt9$Qa_eQ934wdHloUDYubpP(5#!o z*2AiALK2T?1cyt{BX0A3VyG8YYu{`m8*zS28*x6c5&d2<$wrLVm%3=O5tEH*-%YAJ z>owL~-$tytPs~j0g?LX6Ya@=<=&9R?X$^1@`lt<`)&NgyfNO26nty6*YF!@mVF{>f zfXiwwX{=mW^#%w9+QbJ$KKi|O7x;4!H0M*2h!5X6>#@%b_xtYPMajJo-y!L*z87K( z``irI?pbv{Ww44*E7<8~8R_a{r@atS=wqCwZR4gjz{`a}9+2nba+~hZ=XO~Gy#9R3 z?YPg)$Tv5&c+g*s@}Li3FT`ZyN|oHaHZI@&VY{Jjt~a(nxRLhz_S->wsf4zW2Lt&v z0x)K$PR+*M=KI`GZ>xCRy7NJ4<8m*@Y1z1w@AuupJ~wVrO1CEE$c{I|fxuv&n^xNA z=KRwi+A8xwlZ_iRl;Wg4%ky@(ao<~heEG*9 z#qG_5QZLqOBQhS^hy%Qoh^tiBg9oLJn1he3zu$LjjD2oe!9F*ww9m~JvJulhH|6$> zwjs||HsZ|fbJN<6``k#`yMp#MV&m~wz3rE5L~nBi@)^!?fPB2XV5`l}`jp|jI&4Lf zjTlN}==L_^Hs9xlda+(MBFD<7Wg~K|+}em7E3e+?MqUcztUVO$a?|p=+@!UKhBag| z*R;pVlZ{v|7utqAZ+9E9{#g0;+vg^-hWYCIS*xndt<3$=j)pj_ZIpP#V&CdyBPJVB zE6V8MZNzQ9&&~a8#BKD=(3tz&w1RzZT4|q~(JC?#l5E6+>H!VzWtjFtEJV?TF{|zG z!}7le655CJYvpXm()89XOhB@8mS`Izc<>qEOzd-0$41QV-D`+=l8rd)>r>JeU|r!k z*@%=x`Rr}PW3xThyp3$cG55J?1^e8z(mprk>M`+EvJsPwXzgQFrVanDyuBUwxe-A+ zqj-xjAz>4tQ?kt(lvVQe8k6rSI+#C(g0u9^ ziptactH3h-2<^(+>8zX{UW|;?-nqG}(yBMzrrH zRicd_Yp%J^&6ZljTm(6Rjri-kzAdtb`2*k)r)=vvXJ8m-|YJJSzX$x4rt%+`W6DO|58nL~QJRb@n0JENht4RtTR- z-D!QtdTXrPxzdy)<<}q}=Z#$7u|4Da^wi}+pF{cZyKJE<-4T}SdaT{U@3K3Hzy2EL z?U8+YN))J$mxttMuuD(d@6wZHX$^A}^n|Br+qh|c$8y2&oy+raxlMQIbLQ4CZ*Rwa zdRVyQ&8NJxvmpU3k4Rf?s3j2_E#xUj*9O9V;=lHi#&Q4nr_EC)8@DJ+`^}oZqd!sH zD*fUW>#=0x7NVGx7Y=P9FH~_na2t1<@6$uQt>SUVwQ)JtKP?-V>r+}A_n7F)>ihJ_ zOU=y(t+R%CJDe99?9!8L+^}v=;!ZYhoX7n<8cw!%l&!T#RnHZZY3ilpiwM71LWlM& z!G&dv*TF4+@X&dF?`bS%<01 zX$|v264qu{n`R?;P(Rk6_PLRIyW_rlInvf74?2KC6W7vQPaZT!Cyi^EzeD0z8*!ES zpd>6P%X*Hk7?V8X?@Ca+3>x>bCr#_UDhzKy*_1o`|Wcxv?*5O zLA}j5_8Q&EM%22s19BVXiS@43v#Hs*tizg)9?3>5Y?SmEBoVnF;6>H(;~-C zv4LX8&d6>>UnL&Zw&OvbR;R8g-oXvpa8*3wHu|m{``j$(mqJI}x8$pTS03zj)AoDa zBpZ<$HQ71Yi0(ZS)XYMTX?@B<4qY^T+DCs_{-?G+WxM7+Hw&%BhC4d1`|)?b@5GM6 zG;o=n%ia}jsjmeu@7(#!v)9X$z{Uz~h+6Xji+-=Q?OepApG`6rJofX|o$na2QESPs ze*7X%uy@06mN?IowxOLbx{`hRHyRSq`kOuvIO&+}b0w`AURYa8ZH5>hH)*=GL53+7 zE}O2}B(ZdZYGtD+UB|+fJmA9ffZKeZ8kRS0yaAq{<-xJy9BnW0ZxVlMEB1iXR@C6@ z!S{WO#G||(UxwuS#N;l4gy>?_yG7_gHx^zM9TOn*X-~MFFkwy=`(UZ|FPn{OxO8mE}YK}f9#o$ zK7IJZPoIA}JACGa7v%c+;^ITkKl|)6&xwcUop5)z2-Kf!d$QrS+BV-WW>Q=2fRxZQZ8e=A7_-%6 zn&tg$HS7!H$Tr8jxs@F;KpV92fu-iRgUOPu=BwVSj%o91$yO_ipSB9m+uc@sclq&0 zY{g+cuDS2a4A^QfK32z8d$n&wJ90Uxt@i8xN~2=@w24NdCod^C{Md3WUafxoF6xjM z)NgG1MNXKnQCsc6UulRJ>o3`ATgFzCQPAx?cDfC1HSEuFKU*!>mZj~tWl6SL(V*S; zH`!_hS7qC=#H$smvsPZMwyic_Z~v9~_K~s2K<_H~ha-3A4IBgAQJSZBi#25JV|>%%6S7Xne85rd!2p#?saCQ+sSgy5ZO* z)32K@$F3R-DCd~`s`MiW=A5yx){kEAmH+1aq2|1N2)Uj623imF;Fx>gU1b^dzG}?< zfcOh}TgukK*QPSK|zChh{1 zWh=;swtEi`vz}cGa5&xFTL$ki3^J_osFyzQg9gvhz+NzT4|vbu9ALd;@DAj*4@KhB z1-@)>mglU_CD>&ess_r3r~Tqk5$6POzJ^HycW^!KT!JS}x{Myh&C9H6E&;={J!SwK zzNojO-;aMM(qCjioEe_yEA%+^qr<@*|{85a|uqt z<6jFOO5FBYhmAwM{e%|UOU-fTecshc5IAyop7B1f;@?+38RnlndXRBABYmP;Yg~Qm{|n+D z``aj%EA!>&FZ;Frzx%0&$X^WT1ZZcT+IcSSDg76ROIo6VH-RG#P55eO*XDlz) zk6u3}|E`ZOMsMol%l>9)fLQ+zh8&Fi@?BjQVv;MJT~_#N~Ge0vZY{gvE8@cBUOdr;*W++4NRG5xqeb{p2;U{&S$l6%NJ2={<|YB7Jc z{PVaL;CKXg>z2Vg41fx%@u>ek@Ph`=p--m_PCdI|aO&9&gHzA$7@T^x4-E_RLp{q4 z-owLPGC1{YVDJtKZV$?l@l(%E8=QJJtDMJwggl@QS%VIo_sdyDn&XIxep1cw^;huUtf6mIQ;QspLN*$)!QF$p}Dj)F6Xf{ zJDkVqU>tdLO+GCI**oMH|BqEThf2<)Vs8;!pe$%PCr(25UYW2@@54p<^iOp}x`~s> z?!78)=jb?pT}~)*5~81;6B^~5Y}JOT71Z#;Y1{v*zP$B!LW0AbEX9dej>rD4cagQqLU4t(G9~k^`;5ix$#*+i@8C;)3^TR$M{p;F(in9+$Ty1QZe^fl;0!teZ*OGBK zh0_v`atiEAo415_zxv%%3QN22+V5TZ4kudMpCvc2IiBt$SW||KtHTZ2vvx9h4 zEyg#5PN0r2Yv z&+!m@3^&jNe%j#FqprcJM>h@LXF<;BnhPIgCllq~z?rB0;!qLg1aQ8DKIbWvzxGYF z2pJvwtW|3+{4zb7coCgPt2hIOM{#=pHhdLl@XwI`q7PX(7@p_j0@EFO{eznMui^{_ z;9Mr<49IOBM7>eYK;M1L7Uf^X8SF#(y%;`}xb3qJo41<#rMBA(<8lUUQ#32N{>bl! zt&g<{=Y}7Cdj)6E711bXp#Q#4s_ytPai6Q^IJ4CiG~FYa3Ex9{Q*Dt?jQASmwoZs2 zylzUqq4FMk&b!JEwhg*wC67Asg*FAl>6!600x%X|l^lX#&KV19{phvUVQ16I08bh} z8;+la<+L8Q-vN=c+I~GKHu-Sw$GHcJOp_s)VTye>-GEUzS2bupL*K=y&{d?PCoN+h zHv>GZJ9iDyVfC$&EOYty73(+t@lnFeO`OQ`$P= z{)=&2C)jmy9=k3kTc_M)P5YbwWb2gW&38S|$K^KNq0iZ~b!zUPm~0)dCX?Dahko}y zwvPL7m~#z$awCpp>l7l{Hnz?--*-@XJU#4KC3!oJRg$0BM7&P8k6_%^3HA=0$KHX- z)+x%Hzsc4qYz@m>Ctjz}kd5PYYVHG=Y#mlznO7=KXDIu%AeZXQd;JgpK5pxD`x2k$ zb&{<^LGxY6Yo5vZZW~)iNa)1tY)W1S`{AuJh8669H;*0glC8sud^JXQAGHWbI_@_zE1gbzbH7 zQ&OsS9WM(m{p7{hY5PU3ZDme*NG`!dP&x6NqlNaGk=ZzveIlCtxkv@SH$H|M^Q z3>?YUNw&`BuyyL~L)2bqjlK8kwcSI7&z*Av*Vma~?(pHPig&puhdhAVBlUTga37a? z`{;ZsjGt@DDpo!s-(jtD{E{AapuPAz9Zg*J=^@|5dKD-<(5BohB@dM&VZLuB{cfG$8J1FtHJt^@*xP){T zfOB4h*SDc{)e3B}Bf6+#xJ_l?EilMhert$5NKcbf9pKRn@K7ha2JaxiRf7+J-!*uS z=V~BQy;LXVI;-mgeL57f$fF_u;jv#XwCwW`6gSt(yaasQ^?|t0y@@tMF?qOZeISPC zw;~K+!&j{j^hG?ke40@@7@p_ja+mJV<0HO8gy^W>s`Y_RqamGieV~0ve;Jw6I;7hW z)LkE_iw64L#!cz+&|&i;@JBqTn!eF&Ru>s&{o@oYat%GRb>l`aP&o?|K8S7 zcl>~@wvo2r7TZ%%h3?FS|N`Y zmVd;Sw&|^8b@!x<$M55NiX+n3*kbzS_B54; z@%okW&%(udn)*3y{lTl(KT%cR$e36gwiawG-B`aYX3E6;!KC)j8}>y!C=Q!$RbMie zZrB%KoHkwdrFfs`wWRx?o|pC-pFz*|d8Z-gnCv$q-M57g3in2&yO!r=AEOcEJ*F>J z^*;#aoUyRhk6yn?{v9{c-rn5E2|PTxkv^_j&&TCPl+#eogcXVPhkJ;2pm2=8Sngp* zHULilMc+}z!O*Y}|2D+mGx)oiE|iV_*J}?^-TPCYi+wl7{~_Q5C>HS_1kQabhzl%j zbX*I^**D~QiN~!S4aM)^x&J0`SWPIDR&LtL6`;_2#rVm_ko`@ zcn*W%vcY@6`v#}}?!`-j@l$`73{HJqF*x=5n!$5EoRT+kFn&k)$n`;kvwXRCBmMVL zz&+!?0TsJraO&?qyzChd^>^9e)Zba<=ystVxk8ek1|2x>m$Mc@j%%KJ4;QX$DquOZ z7_^Cl8f4rrqiVmBCr!E*51DjU&YaVC(>W^Aqxk?^L$)jxT>^Quam*)V_IOE&mqa2`Z>tKRuvZceepYNBupD6h# zF08*30>><2G}%4|mtB7~blCVb-B^6y1|9~D`m^bVHhU0sOMzRd=Kh5 zV(EU9c96|spSMbWv`HF4_?Y~v^eqVHoUyRhk6yn){#~Cw?Q10M>Tr&!)*C$z$bW3U z!$IKAfE72(^+EONB@0pqT3Z*>z2{Jp@NP*kt~p|Mw|58ZUzZMsEY zTIHT}5K}NkW4@T8v5W+@{SAg^vr7RUwtd$P-jQ&63=H0PsMx>|oyM>6wjw##!c(D zsxP{PzT~8R(d$T``>APP^sD8+ZeR2oIGpA1p~P+TKWtR$?I*R+UTBWHcjir<=z=46 z=h^Oy9{RcJzD}m|5%fRJ7pds0O}{U?Uh{dh6s5kUzNnj5GCH?=+T;Ck`QNXvJC1&B z?fD}1T~O6`3hhRfsoMUZP=`6JzY}sFW?jiAOgoR&?c-{?vG`!J`uNll^Jmj#pQIE} zF6?utzdG^NeU7U59@KNh($#*iJ=R-(v2Ye<2V3T@S87=MN~?(1jwNM8ouhz;B>4;Ok6i%&&!OIOay@ z9TU-ZOoWWr2XTjP|AC0)X$ASz_lovacw7tcux-6%@D2l@f@(bKzYqMN!E?O8E*QKA zyk~F`r8{mIyaW7>!3V%|^u?H;91pQ<@E&mX-RPej#K8FPpx~M)NBZvrKW*>^&TCL_Vf#QqaV-1e1aP+U8#Yn( z_KRF-E{*-|%TnSphNU2DvaHv*ZTj}*-aWCYz_$|82B@c!F`T6+gizpm{_;dd4fqL+q<~ z01g|UrW=dT+uA_{F@H8)?eoVDn{E|1VB@R%998i>sON~KYoAT!WU;l%FP83sEjS;+ za}8-fUU?tYpO5f1(JA#$#iBm_Mc^GM9P5>c*ZCg+r~h{VXCILGw*zM%kobFmvkyr8 zF9T;Ekob24XCIKbz+xN6S{lV|&q94GKHAFuRl${0U|*7)!ZW~^VU+v&5*pQxQ<(Ql zN4SamOK!eGIBUVp?Qc16nE&rQwhEsGw=f@Y2*K{e3)r1l=Cb2a^}P{tk*5MYY&$O) zyd&ZC=o!54(BXOr8o$Pq;{~2lyp}4}cF0p5r0*7;c~k{ItQT zM_q$ck8T>AdNiw?!AIH2EQ%{@;LOv0aj3561aM}bll%T^-&Bi`(Xr23H5dPv>Cwas zb@FHxXTb0%PVe7_ui^~;8PZ?$Aqxk?^L$)jx$1`<$XNJ|4Me~;vf>g^m*m5w?!^4nupx^q2J!QEAMA-{b~7p=kc!I;dryU%g3}ik4X85{Foo9 zSZ__<4&jQ$S)e$OS@ z^j^;XQO)?BLNg&b!*mId!s%_r;10~L0P&``$4+=x*%8`xdPi;GI`M_Jau}nHPt&av zpM7^QP8;8Pa|N4SF8aK&qpn=4^vK2;DRR*;JW^8E7l(lVngrOnVrKC^s7i%i%E5w$K3#j$lR?4Dv0`5yyMU;J8AGf@N))l zKp!p}oO;qXIQ3-j?jk~;F7#o^;M9|j!5esp6@zzyUo-ds_$`A|PiD1m`##e-Y@nQZ z+Aj`Ootyy9r`(uNmMx+D$L-txlu4J-BRXDI&h2M-8;uQL)wlio2)O7|DjW>Y^KpUc z4!!;xn=o!#zg2x(ekVR@-}IKN8_qNE zeNV4nllN_R-Kx{K{rrFB`nGekee9U=W9N(?yJq}&Xqz3Q?_Wj49t*hlpnY70oBPew zKFX_M#+%0-Gu}Mzobl#y*EVY&!6SvOr0uJM+6lclx98%5JCW!}O?h7@ysPX0mE=L? zD(l2YPSXd3!^WrS)`{;&Y(y3DDF+&hZ@bFn;n>5946K~hU(9Qj9$9h6!dgFi?Z+0j z$@)L67qc?9Kz-uaf?HHm%9Xg5@p_IeG#=I%v&@by+`#y)ueTvNx1M7QoLQ%13s@US z^K%gS(snl-TeuM5VIAXIr0QSsj{NI!!}#wzG|TQ7oMQ|7zN+xRcsRC@8=MXJC4+as zkzO}=ANauF4Lrmi$lIq2ylLi4Q*~9b5Q{ zP&tD%wH(8vB^Qc84g4*Jw-mn(Up2Py)kuHRv4!ubnSb>L)$@5*#~$$Mla4K%Li&@A zEp$+R^~VEhvH6YyYhYU&ZNr zE;T6C7_Vf2aE=XefJ)y3u5P0NC$~+UV?!5^Y2q9k z>KVL&hT?|7yTI=ld;okO%7^h&PiA#&=%*kL6mQm`1Lys6j*Sgn!q~>7V?)1c(q*z* zF5%IV3&revpW!DR8~RP8Kk3-eYcaMG=2hJ`|Eh*iy^_}(j}@2SRYFI@$DUn->_z&M zjtwLsV_Fz5pS2ds0%K6Rmf{*Ea-Tc}3*4o}%{j2+)QGc=Lh{-h6ce-O? zc`rOa9$u*1jjE`_uXz-%sf0NN{<~AZCQVv%N@d3NnZ11ccazipF83eEf>OHH*JfXH zD$UKAmAN@ru3Y?`j#i41HN~!6@!u8u_Tvj@)oY#a*6(Fku7qR1nXD;i<14QzcIC<| z*%x&&8?&a^l`E^QS?BW~#_#I$X#Q8SKYdFl5`XbszvQ=cnEZ$Gfjs>4AibBfTQ%h~ zY`>ZR(%5)K{=3RzsSF~{qNrgFJ~W1 z?f<6I+?1Ilfh2*oN?-=t{}KCN))mjaz3=S*x#2u0*#A4S-*{5yn_lRMz-7E(=)XK( z?8gsY&eB>MYt_vZK1m=+V8bQg+s8CNa>Hex5=;_E64*o%m_hqkq@U(TZXy*-SxFK| z5_muon8Ehn+yDH&HO-HFK+2brO%g~Fc%TxP!S-L|ZN^7Wy?x~SVesXi@0L{(Bv3Y& zc<%?Qt|{>(fh2(`NMNJi1FJtmxqZ&g*J+<0Iw^5(=wrm6A-y5ua!F{CK$5`LmB5BJ zts9(JsZ>_uhx~j=Kc6PepDzh7T_g!432Yw;Y;Z%op~+R3Qn~*Tj1Tzr9nt>#_d%LJ zUoFjaCrKblU~5WXLmT7`POQ2_%I&|dFY4Fxg}v{uF`xdG?6Y6e_$*#`eNh|EUn9Mh z?9jzQB>rN3QOWP{80o*%od5qTy54k0;#p<>e|p~y<(yne0!ac}PXfMuO!NP@Ug4!2 zCkZ48te*rn*yP^OVhf1Uv}N9{Qld&4<0Yp=h&IP!>E>Ox|1Z3B(NPMP;MWyFV$%uciogH z-^r)n$aa3C)8aG6&*=>jmrFvE1d;@{t^_u^mEFknY^j*{-@5W!^YfCLB%rH=U;Lep zI>PudAMBoNq!}D@E7_m_>xKZHmx4d}KJStFzwy)~fnU#W`S|xfK3sng;e0%v-}=H? zjbm=d&Rq}fe$AdBKI<&fbEzQzVf<14@5+^zvs;tLAIhg9{&D8dIeCTo-%|0<&)=JW z@`K_2+u6Ry@7Y2M^k+`}zmnZ_wwe9z(}v5ktslQU(~gpSL_h6w2l7!7?D$mnPyS3D zyy4ogEMq(efOmoa2*Mo%&PRAZ@I$~mcr@Z|;Cp0Xukz^uXZ+s-oT4NCp8@Yc)QqPCybt^jaXw4@_2Q6&_(#R9 z>Gsiv6aN_TuT|ee{};sV{Qm_9`*?ngxE6#QjOUZ$cK+Yy;Ot@K=WhcaxOvAz|Cfj_ z6#f~{e?eTRFg=L>oVYdqL9S?)T}1r9Aa2FG5X?VzceCs&@ccam@Xz7@8u08d7dYep z?}>kR8JEw=UHsW!EpV30{|vli@EgGUz$u6S4fx=%7x6IN&lCS}8UHQfKUCmMcK|&9 zNE!cq;631sUq9zp`Sjel*idf&FXQ1B0Iep8x$K9=1Op1l}|FUjv?fy6pc9@D6b1Uw!S& zUQ>8BzdN(t2FbEziRTeEl5%(NYYQ*uf%6*8Q z!nR%5whP;KVcRZj+l6f({rl(a+Yi$?xU_5w^}@`}Kmw@qX=D{6G=U9gE}rx(^kU>GJ(bd3b!Gi06{^ zkN4|!i|2*^fx-EHZ9*Q5pYPGr7RP(EYjM06uNs{1(Yprcd$fV3jOp?{deY(_F7kiQ z;&_iJvKL4@eyiC{mXD*!24u9;Kk3N0)!%v@oIy-#kg%{-d z`QqY3&p-R@GtY^K=bk_R%;ERE|EWVSoPYX5FguEeTEp+xOIUqo6o-!~_pY)-{f5U| zruS#c%wlF&im!8s-NSUr{-r0*D2HsjYgXUh&S5@k8cNN)BhfmF1)+E z(yix~{A>Qv+$iLZ4#NKvwEM&xbl`kU&KkaH@UQ%b1+Zvv^{WTZ#{;*!fuAQ3KE%|` zaKyFwv(K*gx-c-miym>d;q}@+yLvr|^gB?D*9oS1wenXn#nQj}OL9YwPniVGW$^A@ zJpBA$Y&4pU;ZeAY-^GOmccay6w+mP2bwB>@_nnZb&qYG=JD0s{L_T_R-`l*GEO*X4 zd%Zr1=hXO3WEOG?nB(?pw+Ow%b84@3ZRY(sHQ`(|KZcXC@dcd4ocezy``ogo==~ud z@}NGyMUIBoKL5gb*>L_E`5$9VFiFPbKa>yR^YJ5}FK2sd%cn>{Qvv6gkLEv+k3RO? z#q1aK9WMQ)7p2neyj>`O^tqfOJoMW;cjf);tv{V*uYJ6$0mzA}yL?Q_iLHD}<6*qi zi*nrV%9odazK~Oeylgz(?BlMIO{!luzCeD^uQw?D!cxc9t z-5Y$!%OG-;-w#3iZP(QH?fJ{uYg79zFRvMIzIV)c^SyJ%o9|sS-h4l_!Ob^#f>IMc z(*LQoru4o4TE>R3ru2o!b8DaDI<@zvgOb|&*>3Sud%w9`{8GzUT#U4jfqm=SH{1Rt zexhjjQhS%$yIF4YHg{_`{oHK=`&L@bWmf7}JqJ>e5ip)Gl8$5T6=+VSbP zm(xxmV&9ImkJ+`#Z%%{u(S36|H)(!1$9qAg;Rd7wvBW46y^Sd@fzM*jVF{26J5S?; z^?++TA4BKrVwzVegpH4LdP|<qoD@M*iKGJ2IJS{lDBP>ghDU-6_7& z8I}g??W6Ksb5g52a@K?O?~USCysw}f#J@q@iZ{@(FrEXzyTDoR4gzPx!MX6oH#(9o zvc!1W@ZSf{bdNG!C;;)l#B_l(o+p40fK%_j19%T}>xlmq;2jl|9IAhMJSG47yj>NP z9Q6Nv;#NHWItP3IPXq6KV}bvEadN-0Z>RLeICJ@bK>X`m{!T+f${aa7-wWba{OSP* z58LzMT>iy6bNSu;bvJ!|tZDo~D&cfGKb1XOZWQ@a_0YP+<9efTDUL^Rz`)=ghsxZ) z{e^@6`@ow9r+%I`IQ6q@a1ot5ZW_D;{I0?Kz#DHa!p+G^^WVTjoHTeB_&I|QfL}H^ z^|Nnq>gR2PQ$P0}DCdXzxnywa=d8{N{$$^Y4HBSfMTDbUagEk{O zC@E{DzuR+(G*Yq{){e|z-aQXro+H*Efg4cgIKbAsFL z=Gb$BPvUzC%}Va_lja1E&N;3-XVcFCPIH3i?%fmH1afeSRsIyakaC})b31k$|fZxw@J8-=2q8|Uiq~fUWvWw z-onK7vQZ4qBkiN^qu}ku3j6W#%*|=bCVjk(ww>3KULdOq zXPJM|In!Q#74|gVFEVF3@i6*^N$;2Reo60_Nn6v+6E5CBmfOeD`=zpd+*)&{r}%yu zeLsh5mQ}o;yIES(O?8p;7X14d@=9yE`I;KlFFPN>U!%UJ`5V)nzv1N#ef8H~{$Kus zG=C%6jk9evruiG2$MSnHIa!O{wb5by8+XJ}wvToGhHdZtwYOjXG`0VUH%Rk0W|=gQ zXMZrQ?&e8#qucPcq&L#+7r;pWtJa!w+4sFWoWJ4U59lBG>-4@T1~BoPc;?yeG0gbu zV$;7bB5h=(eGJyzsNhF1zLs^f#FJ>#m)gD5?#*)Bw|OkqwdJHv`>5k<*8cO?un*Jx zjZl(h{$-Ul@AT{Zd#}p3?8EsRiHAw=mmP_RndO(uHsWEzR&nSqw~wXwO9kJ6_sf=9 z^KJ^f4#X$2D;>K_SHp{4L#KDe))T{0CEgF$sPX_DcD)i^d2XEjM@0CzSQ;iW~;ar<)-n)@@JnzZ?Pd2`;h==X|({ictcXUH-Ip|;4j8weaP&CWv|5 z-rw)wjP0(jC8;>qHl%&=67cSu3;)D_9QXh@ObDbblWBz~H|KJpbl$Jf8*L15Ww>Q{vxR_$U6~5!c1|%_kjOW+Ht?}f?9qh|RuhwI&(BG7JbWPCi6Gi-&&@la5;CtU& z;Ql=wE_(N&?A%ArxAdp2KlA#tpg%|SXHkD9Tq{&Uwp`G*i>mG7Y9G}Y+Xe2{ADwS1 zGGCryHE=*)Pl?SLOWQC^l0cV)+JqmT;@a!Sk}=AT^TYZDG-P(K7r29?9^^(EaZgmXKc5B7pY`3l%obA>vi=*Aj^aUda z<=;cQbJnGz$v3gW+F80B7|Z9#w0|ejn0@8u=g$ z&+~D)L$~)Nj-RQS|3}0xnxZgxb_a{cPP&HdWu)KG!ja>3^8YRJZ{@G$5=;L&43;}` zKRoQS4qvBBwbqbrEw=xE_TC1{j^jEHtQia-P?R9(j~Ys{)F34ak_qs=nZaNH%XAy! z42S!J_6i3XxL0+Eya5n|1wMHGXQHQKClaq^+_dV+Cm^0&h7rS-E z*%rH9!wCC7W9C24Z}i@y4oB|N8IPz#w%b}AzsPO5Er`{c)S4gPU%qe}=oai}TwX-(#)r7?v|v zz1d*{eZN3TzHz|2<5ZM?=i@>5j?NFoaeyYlao#)JBSD<^uI_&NMyGDMeR*}?%x{YQ zvze>YKX2r-MQ@){d;O-^mFL697N@C)86vv}s9+Pf#f8Q_t zKp$D^AEW%G*q2?;75ll^&&7VO-`;5LhwEj2y3&3FeZN4(`Tcctq-goe=yN8@UwC|o z<3Jn-;yAGO`}1%gS?nLLqa(%ZAMH18M*HQ+N{O_!^5B<}f#2>~p!O<^l7aW%_q2pkO;4P`Zpfe$OTX6JOr1HbkPox3>XH^0=Uco`< zBZ7AXM|u zGKSj^n;)fr#ybhSy1Eabd&1o1aI|0Oo-lVi9O;4XiA3%+L$?C^8icL{)?vZA5?Wjk zWUdJRSXTw(`=>2z@AF!lf4TD}=t^i>?FJK8yTL@$(`7K@+nrtmPT#ELgR3RCVVDaZ zE?Km%Itp(|fX$Q6!gSbw+c`}`;R$;nb5P-#;F-dSrPf?hcuVkW3U3RZOu2AK58B0k zg=dnv6AJGLeoo3U0hK(+Qrsg#q?y-E@l*-B+g$;;T^%}6^?dsUgOd(E-M`E zVp#9ue_Yz9Ph-6E66?B=KL8mwXrh-Sl7gF8%^5 zDIoJj_sD;B`n%oro_crj8@pzv=q7$Ick$23SjLG+ZA#)@{CF2X-o=;iZi*i6k&&+M z0NY4Hx&)H^E<5)cR)4oXD?V?2_|^^)$Z_#EYMZ`p|Kz@jck$^i5cIj{vZFkma`rJZ zzyD9;S@$SoA8rYIJnP=CEP1ttlRjNNiv6$GKVIjq`@f3)W88y`cio411CsK-TKlYdVO8zE}z{H8j15l*NMh{GWL_h+*hv7-mdpl)#)G2 z);j&8J?oo)4>3%aQN7o+slsbK3mZPOxL)~!vunCK_~)+p9s3KN$JFN~s_51AS2tem z?*U3EE8c6#N;B8nar?nxcN< ztf`T+roeI5G}+=34*U_xSNhf>jE-IdZ3$-PJmpA~x@Jk33%Ks17K+CHN_Yw*_BNcp{m&sPIhis|xQ3KAx!bNc~I|j`}&P zaMaJU3P=6Cpm5aBVLg+1_cl{7!k!%C*P%0+ufETDImZ=;3>Onu1$`!vkHRwM*J*N^ zr&PR*u@Q34LBCaJG7-MtGnpqPetonO@#DEKkS0#tmnA&geS>hos?KDlcR3&Zp2<8f z@t=_P$7eFR3)cMSa?!l!m=h_#pJIn+bo%oSt=WiYGDjAvex5O3nPrB(mN~Xj0ob!| zb;lRg%~mN zeVlafqNeA4pNK<`oHj4<7 zjdy^0@3C%f2(Mp+HPk=GGnqBJyt@6udi59kyJ4O^4#k}w>L>O3y3Uy+D-(}rGNm6~ zul--$e8qk;_LDbvrgvjv!=$nJEcTD_OlFZg&ZYO)`K(juJe_RS=Ol18ECGG)Zr^}-%UhS`{9&FMXt8j<%7V?TSnN8Ynk7qLDnas6!CX)^q z-Gnol)IPl9Oz})6AIRZ8E0c~Zp2-aLu4U|91TpV)Kc1GoT7>=j<}Px8_dcGABc93h zx#D=m2>7_qv->`W?@VU1-kHql$;oNblG%%%%&p(swS}O?g`eD87R*PMGiy`L=LP;4%FN#UX$Lc3#2$cdj0=( z^njj>{eLw>B&*GzOpag^3yg)_31XKH`%W!j4wZxK-%FS=)NEA^bl z@uGtN5sn;)99X>^DD{ut{P;TG5sC7V)mx-7Wsw7s1O0HI=2UY{daLF~Q9d$uwU;x) zao$_a*Z3xKAaY1NxsKJL7Hs&6^?dsR^!qxE+{-rTznmcqg`y4`UU==T{JW=i>5i^EN$B2V{?rePo~%JGreKA3#WgDTn<-#p9$gn{XWxMC4QBC+rBw+ zq+_3F&l5$KkJe0o)%Te$eArRz_xnr-B>qd%zWMu1@1}ozZbv?sXUoO!uUxED&Qg9~ z1Rzi38*sO~o`|{t;`f>2_n97zx&Stg*zZOa@7~Z{&wWSgIrEvCx)RE|80zh{K5{?n z0vL8vSAXbw^%wP`M!l#vMpNn9pt@-d8O$cjPnvJq6F2Vrk6!K{|BwCu+UTioOe)t<_g}TSQaWo{?=1Q!cF-PE54r&2c)@F>y8Y^U^%uvBI9}YC zo_H`+%X8x>A6br!XTA1gb@LVbyV&0ire|84RMx@#n1+O+e58l7=ydlo&U@p$cXTw4 z192Q!n>~2FR0rnG9#rfx=BisMlnkA{0R zTD{->^#%=COZ}s_KY1NpjPZO*?B`-X7yG%TW{~Uq{W_Q*(>PFEKlC7fAzc7*z8lAZ zI1a>dV14)Vm@J2%#s0Gg`OD~1TwD9&3-P94s*cG-T>#-bPvo)CJ%e7~;L=F}rhJ0CcxF>H>(m0HQ7cX(j&U(#P#>eS1xx ze61&o5bJ2+GzEg78rnfX@}jD@MS_ zeV*O-IefYRChO?}XiV*zPS~_w|JnOL{s5_W%h@(!?#=m{gJc=!N-8F`&(z$?S`A8j zG5p>3*D~i7caL+o+)d8REq0RD?|0iZz4CY4zcR}y$o=*B-F6)=cT4)`&5qNZ0R2(R z$SyZI4Yr@ch)BA0$5^zS+D(i-F(IVKlcCYy^p_M{?>l~Kgs$}WmPNd z%klF1-dlg$0pql}pM_#?Gv)(ZNoILvqooksmnq2)#xCdIv8z1Gx!0y?#AGI(>Et1( zZhyR9{l#%6jx*Qmhu6wG?mU$#^^fM;b^6D#OWZ~FoA0$hZuwlK!N-%o()hCYePQ`n zKHj+T#l*Y1vc6fb<3`-9|JGsvKN>NAlK(fiQ)Z@u!R?wQTHXGNKRA*0WV);&{thpxCnT$dZu z3zeJp$Miz}^qH7Y9vBOS4f(x|K>PhBl1s!ho9q9~ChGkoRPOeBOe9ZYgL;lLo2|Dy z9QFDTIobaLR~RzzkMB3NSw2Mu{@Ff=?=JCop!oYr=DV1pF(;&<@b{h=Kanu%zTILi z-LsaHH~hOxUR>VE%E|7@O8QQTq?@}3VVzCpK@a!aex~r2^=-_n3U3R3N#Tj~L)R3Z z37)*i1!SjaR(P=|TM+*6$=TckPSEL-2_p69tjk?HmONMBEE zu+oo^%kir3BO!dh-$(j2iGMne$ypFTp8E)f-S_&P#CLV=+HckOk=pNfVfy_((lv>H zUfLypABpc_)crnEcBhN~@3}|*tJB}@>ZWR)iJaQi+}-P$$O~V~qnCOX&qS8bT#nkJ z(d9#KPbRlI&P3i$bBNJ{=9Uk%dC$rniX|DUP5Q=fZWv1me<*SP#z2PHtpl)4PA*Q~ z_h=!1v}cC5czSzgBkcc-ng2Y$1Km+M8w&s4vn&&)Gq-s-IYXMe^E0>4*8KhtrJwr_ zzkCvpzR)YApZuRO?|!O~{vOZV=IO0S|GfF(TRRki_E)!l<>4g#xjR2|yNvH6oyz%> z%aC*WIsaeypZNPoUO7f<99Z!VdWi%C*jifu)cZcs*H67(NcHcn7^i0>ULy9G`la z-_!Ri;`~0$(}+e6L=LP~4(M+5`uQmKpFPa)N!jV@GU0rx{L%T#Tt}#!C(PY)e({X? z^0%3m#_1euzFv^Ha(AvX)Tb}>ayk-U4?0gv^yB_RxRfIrIS@IpzB#bEMw@bK!rU*8 zKRv8ZHpKNwn4=Mm9EcoPyByFx=k;?^>_2;0pKQ?ath76j&p5viFeO5f1Cay6$AOjZ zpO=b1Tq4EssfYRfSe)O7IU3Q(fyjZi%K_bwUOy+r{b3}KYN(pZ`ARuv^$W` zIKK}tB|?z{kpsiWftBu`mx@1JBE|8khxz@cIKK~bG@_9MkppX&1G*o*eol)0XAkrH zO*)>Hb_enq=l21oL@06~a$xv4u+shWQt^jNq&PnHFu#9YoZp8z8qvss$bq%X0o{*Y zKPSchvxoWp>vTLT?GEHK&hGm-SRn zWBJDNjs3VANkaYec0I_DJJh!ayamVFkiYLEuralx(VQ~o!H;}oZ?gT7!=FAj_vvKU z&Z(V^9n+t-uI5iPr*}4{b~YOybT5*LMsvC`-PjYN>0>-^95dfp^fA~s7(J_WZ#I-h zd*Ed*y@_6pc>Xbue4F4c7t~-rc)Q?jg>zrTbP`Dt=-erICOGDSTsAgd8TfhL$7Top zGu{#$bS4CE3y$>c7Cey&3GnX~JQEyrJ|cKWaI~L~3chd)S;zqYYh<_SVMdYJBJ-<9 z$j*4ij3NX7pCCKq={qfKc>cuZ5dB;K@3l_D;}Dx4rGHC5VON*VQL;0h+-2dM&Pl;r z-|cYF`HbM{-3|vIJ}dZw!apy#WjNW9{x1mLW`>hN`hSM(oE|e{;XM8SSn!VEp!0Kr zFWl?=gU-*xKNkcUr2orgXZr2?ES#t3mjur~=5WyYW%%a;A_F?VMs}vNaKOSjo!=0= zC5!=`e*ynoaAZK|8)RoX*<%*Y>HI6f)58u2o&Od7xj@N)&c7u)(`n6GIH&V}2%a2s zIOzNt{BuE*0iExVo#~`=7S8GXrQqgShl9@l2mf3F$bilUYKKfG$t;}Hxkc~}R}3n!7DxgEnp02^)68MPe7U4>j2G7wj`1S-VliHf7bg^s@#37qFYHj%$JJsE_}kd4=5bt#VLhjyjW0p zCga6bg=4%J|EI-xFgE+`!1MMvT3XI*@a1r=}R+y@no@gh@rBICs+ zg=4(9rf`fG$&1Dsl&_Kg#q2!!nWJ-u4%2h)Y4@CkZSKgaIkWTWBTpUL`NW~QLuTjU zlPAf2+&LaUe)Q;(W8~r3@wp>AAAIPM9Vh1wJ^rMNX4${*A_|<=O^Q;g+;FmA-|+M< z&#U($75lHh=z(NSicYhQ+&reG3cvQM17>BwudaL%){=H|LXAU)_G^oslpy${#~&CS=~5gq_m=p>so1>VrGH{Y@N+T?wYX66>llabL4V;eWU4h(UD3cr(+i<}-C%jrLE@w>#M zFZ33>>>pwOXUtb-*=ruJq=Pb=rbHiBL zHXr!=#@w9_Uk-A@(L-(&sC=~twG-u&>b9g0Bvt6RVFaKew= zE%7~PK2w`Nl-*Ikd^djGG;CGD9J~>&MA7^)W z*C!SI-Ciez7@>LcBQ#GQ3C9-E$bra#$bra#L35znkC*#zb6=hQdn3utme+4f8v2}H zPwbg;cRY#WU$8*XO$ zV_cB~kpqzf>yZQDzS*LE%15T?uE@r>wTJ}u=S#{*G86mr^;oZBo+1a<69>xuWO@EN zcBRhz+sa2aP`{VZJa%k7@hIjcav*Xba)3F&=hOB140EbZ|2Wp6zV@cC@5}vr`F=vZ z^LPL9!!+}KphW~}JXmu6EBk|SJc!LEav*YG)pDTRKbHIV9_GJeH2-}s&3`wp+6>2p zMGiy`L=N=Hfo0BrZ@OHd+`sEPr<=-NERySV@!s1jw4R%--HXER#RKX+occaCs|>0` zPgDzmO#amLINmz+p2;Z`Et=j#74+5%Uv4XA-+YUhr}_6)0(ALq(Vm2kruRQq(9?W= zwt~<7#(TPEyuVNpug*t^-u`9qW zBLzoM#~XW$6ZZ#f9-)86+oI!-+dmst{lj?rcI(XP91^_sPKR@QWb>o+Z|NuO zGKSkTo1^q^=_l+m2L5v$e|I??>HG{i*?;!k4(E2lhE?`3z933exIMD@JpD7?VkIqP zK!;WHSUS@dHlV{Q+bo^$aX9F(YY;lxSd|a!Xls#tip{(XP(M$0#;>G|I(;_Q($zk; zYZd8e^HSxjU+L;Zo0a@=bKt%M=7NX&eP~DFEeWvsd!2>pu>ZDmnufv?X?F(|o(Y~Q zoLFtmC55*HzoziE;K{u%9MY3WCiW{l6a0k2JA$9nxU|Q%!qFbDC>-r^>-QDYgZ4P1 zaJ0vk!cF4B&nvtw_<4o5q&;3%INGC09X;>|?Qy%p(H;*dJd^f#O5qFA9*0#2*0+Tp zMoa>WJh#!4yOLDgcpSXn*$ztm&|YGud_c zDjisp62DZ7oC?C@xi3JIJ%38V=K;lnaKNi{V4Z)^`RG>%)(MHfA?^P4L@uF!&3`Tz z@j|w)S-8*HzutwcO{c%xAy3!Rfi=;Xo|>`RuG;MIS@GzIWQ;=bmw;kTc2mpzqm*;>WeKR6?I?@s)Qn) z$bra#mE=I7XS9y;8Jvv^bdurY_rDu!-C?rx>(QtK zYn2piOh)8DPf*~2=*TLksetr3|DO0L&Agos+EcaX-*G%z z_bni1Fmhn+a-h&NI!E3=zVwp&#$Ndj{!1_A=UMV^;GF$k>K_lZhz8Bq>&ho$|G0Lm zPE2{^z`Ex^xqmFrZ#QnQGrzU+3DP;z`Rh@a>bkEsF@uo-PjhIM&B1Yp)>An6Y@m_c7CXP3C3Ml%C9EcoP z5e}%nk)3(}*qi*}XXx(Z#_cU45c|g!DasgW%#W@7VT|Mt z4@Vu?11_XUE^;7pU`04k>>Jrt?jOy!>-3LfmniT}*8#W^Oe^!uN3^bqP5w*IE~<(F~9M2s*^@1Y8M>xD13DLxEZ2jL%5 zVd(N;orapvKT^SGU9X_)OC{UreEed~ct5wyc>7J?->jLw-&>*dF`wzLU_#|~2X!Rc z9|x-HPYMLd5elpQu=_pqZ*>(;M_q-i%Px@)9R2K_#2>5sPH^;ZYgJbv_Zw`WtFR-w z3b~(PQ&(3Z_XBKxl>RN>5_TEG?VgR+Rfzrtx(Yk*cm9AwSD_JIh1`zWe3t&1eoJ%} za=T^odHQEOtWG*W_6Wn~nz0czvb?yTSZwY=%;cdYe6rOBwbS^496a1>e zJA#kjS43;PF2h-cqrIM0ICL3aP&jlMb`+i@E*+ciFQ%t0cthc6uh5Z~^HbVu zru?J5zN&Dv*GmdVd%dP`wAV!13F2KyUAl)=$KijC0ZP~)#U?Iewvla&{?iT;ks^{Q>JZ+(!R(bsV-n=2G~pNT@t@`rRywSfL@gbMyY@6E ztct^=zK+9#GI!u4q&6LuIu5t&O<&8b7ef`#>VC`Jat1atx4(;hEL!9IhJPm~7rDOJ zoi2CA)+BouHN8ct;Y4GE{hu*knPqypzaDka>2SGQ(m!u@obCkZkJ_Tq<)hNSrJVkp zzNGUxGhUlNlnjYg_%q|t7kVCl$h#RiZQl39Yj)87R*S~yE2Nu`VY6W@ZJX&o|GfPt z1ZS7|ZH3AAAaO>+Q2DEHBXE!A<^TM5F}-@_PYF}yujzUDqw+T+XUuzljOoK4+sTYj zKJ)ZCsO!$tPxVWOgB$6eH=nqrLj-^et&y7L{~E%99^9bwocTgc{%{CYzh1xhwY)wF zzjL?Lhs^x^Kcc-2)0`j~pe4XR-S(x^>VV3U4DG}Uj3*lzcc1vA7=(={#4YzM_er|^MCcz57eJp{m;l>QU60G(EnK6 z{V4upZvD-}t$O-);Nz@{*#wJv^88wxjT#_#cOv3m%2KT4Q>KJDPMvX3j;HCd zzmU=NINmzxI~F2F*m}wDZ7P2$xtTA1xigRJ@>%<_`wG1ErcZmO%R5-*-?6vgU3ZFr|(pW&}Uc@VSN^Um%p3~VD z9Q1i+LEQ-!xIYRs&{ z+k&4}cp~lUg2FSwH_PCa$1Clpq41XA2Nm8HJX3fgnRr#L{a*Ul{O58J zFMjgPRw=(AQc|0qC{r)X9O}wcmy$WumzhMF z(jp1buVaET(WUqwWlEZ(G8HMnp>?1PHMu{`wR1o$y1(PObRByBoZF|V>2bWvq1SId zs^Zn@<9v8sYMzylzfeBv`jaVJPQS_$iX-HA3xN$@)6-tediaJg>gSDG)1$s_C%)M= zu}oAD?+(E+M+1&E{eo0P(Ah2iF<}7CpI&A9EvXp52_~=M(%oS6%#3}r|8lL_N4Q;^ z3jKzp>mk9fN)%&EfQ>&Xx&GSJp8c{%zY42VkAP1MYe`85vr|5IY@;2Q1TgNmkyPO= z>zme+3U3R3R^f@1+XaPZf@AH4csqh`7QO&SIX4uJaz3bVWFk{|3z^$_@-s*04jrbo z(cIJSISbp|kyCSK=hH`?I<)hNLvx4B&ci29lKZ%GJbwJ>(Idym!?ELYM|M8=&?7re z&K-LENy-0mAABT$^Q>!9T0vOYmA}1^_dx6zY}Dit>#7i99i zSt9IpO*Ex5B!qSPtJXvauUnoDU$rLs9*KV%8B+0s4!2j>eXoD3X8NnvL~W6!^t&cH zCGn$u@EG_O`mehtIw&4L>1T@UI2bVu=wYAOr^WX5n%^q^^;>RLeAeZ`@!kv>md?kZ%Xhu=uVTrk zn+LYLO1K6>ZBYARHy;bPvcjn-D`eSRB8yb?pLY^}7|#Spy@sriUReYGkQKHBN4-MA7&A+ zRABh$_e_65aHI$4e<0Qb{;c?KsdGM=;BAGU7CaGI1L7r^#-woV??smSJkeoUY9{pO zg@631LB==BzOlf*EOlz<^<}9A2`XQ{9rU$ZPp;xgWvBeBwq{=P#nswg4WcKT%N|}B zOGKu`{uyu4Kb!3eZ(Eekohdw#_H#<%ncx={&Q+7mRfV?%$6hzm(-u6H!47yLnV400 zCiq!}cLcwnaI~wA!qKia>+?BM1se)SyE>?Fw5wMYo=W?w5$CJ zN4q+qaI~voJsyS3urh0fV+L{u3EC|>E`a~US-#RJG#sWn(bH}4Z8lEHc|G@{2^05?-*t8{sO+tpMl;n#vIlaM)~{;@O*6#fSw`A zf=u;uU-#vnE`K<9NYI+=R9eR-6__Wx*Uh`X39(Bu2`>QGs?XN1{y5$xs z4-r2UicZt3s#k;dr}I1LdUdn-9OBE(;IoK!3S}8`$Q75+s{$5k`vni;Na$&0{=1^g zpJmjE32@bw#nLqq%nLpB#34O>WfuBaaBFq6Dmet$x zQuqskcN9)A$$rAErI$Sd>;>QsEJ(gg^m&gU-NG?>xHBv5H=A4K7eJIYKa`R!lCH}7{|82pyN@olIiL|>Jg=d1#E1at|oAU~9 z34U4OZNZI_ohOos?F!EXKcMiA;HMOh_PC(%g)x`TiwZ}*8CNp+mQ>MH;cdZZ6^{0J zR^e!m9ff1B0DD>BKlTb5B1;91_IOa?*el2so=LlVRpDrl!@9R{pY#i^HW-t@BF}B~ zBE?KhZj*DdR6Ju`KXGwZa&7mbipdqVmR$n)2rh1p#4?V zqe9}yF=$x`PpPadWID=1cnzIM14n(kllWuT)(YP)ct>#5;~j#hQh`BdLhuEJ_j*@) zpU`Pb1w_0A)0`{R;uuHkWM5qqxLkp^=~()&Y#UzLiQw-Pmb}5|7;f}h??%(teU%!@@}5nmCb^p}GMy-3GF8j5`*K^+f++(~ofMTK$z`l1cQ0{= ztmayBx3`wu9oLf7S#e+8k`6nrC0*~Gx`+7>Y5-0I$735=xbIH^$TO}b6+^_S=QrzT zEjd$bExBu^_kGDLQC}C;9^5fl``-n8@}<{md>8PwcDMz3sJ#ut?!vxk+w(!MKnMKG z%sYRUebm_(%4jTa|>kC{zhwl*H4Fo8~LeUzJawY z-??aWGP~^!Zin{5p8$Q9g|r`c&L_%*x%3e)W3k?*oFaURP9|mqK{#4OfM)IxqEiB;V5rC{M(X z=RU$=_r3miif?$Q{Z`4i&n{E1*9F8c<0J1k^BhNpiTv&pABz$%NTPjS=vlAVo?0^Q znVHFnUiEsl`2&MuQu~Z|Z%77~IhN4e#p;hC86g>6zsPMR!6Ks_sNR%-jHs53D(dxe zCFe@Um0DMZuJt6r4VmTY`6fj<{Tsjj=2X|q+$}PtJGbAtedE_3{8_ih5Pu^FA_pP| zA_rD82V}eoJc{#+vCFiFmpN}3uX4A{Q%1(_;EAYd(SIB-R&%Mxv_%d?4%FoU_i05F zSRc_IE9Ud!H-59tU!QvX!T6#174^otnuB$}K0_4s#^$ZCe4l8b@{fu$OqrC=vd>Vg zb^2NsB_jO1cwou*jsVazv~No_zF_VvxVjE4&*VL^I`sU#vo5u=e3av@Ll1j{J}tJd z*Zh7f#1zV}E{`qbFXUC1Z&i6{e|76YRk?-AV>R8+()k^9y^4HxEwrkCa&No8p}O0B z+qETRwP#9blPTVBTl#(*>h;Y&Q-Xer`v*R&k%_JV?x)z`Ov%C)=SF+MnG*9Rhoc|j z_e`gyaGWV=3l2Jm#eX7uZoqM-BvUx^iRpI)2j6g}q$PW=p!2NwZwroeW{8)S`j7#R zGbNeepu=ZDY`hA8LGV=eEa9JN4&n?7&YCRXu8Wk*%S4~grYwweOy0QKRpPK`rO%** z^~Ub;&ZF$f&!fC5`Qv$$uQ&FZhx=n`BFdfEKjSU>XR}}7ZHpRnLg9%_(9S756a0$8 ziPhF@6}^yoyn@dtye&As%LM<4WMW?V&jdfOacPg26^{03Zgc4ZeYD5z3P*c9rEs*z z1%;zMUQ{^R<5h*DJ*Mv{rU&hDR^e!mXBD1E`|2nh?QyfzcjUJt{u>HMdmPrYD=!N_ zTxl4Sz#`9W^cJPeQW)Zy7JT|~j>c8R}Vy|D-1?a2LdfoeDZfb(IZ*@$OX z)`G5|0p8yU$Y$f&75XOEdw+~uhnBfk+^>6-{pR;eJ=rbeWJW*-vfR~vb_MBm$uFnh zon86WFV@`?i2fo6A_pP|A_rEE1JaiV9yI^-_8$4{3i^MHS8!uI7#aJA3ENxr&u3Tk zd$q!iM=)*R<=NLm_;mg=vh%r z9;$26^f=x+^suMcrQ~d@DZin7^qXJo0qgu~dhzUvsfWY;G&7JhmcqTaNbv(Ob*<<3_6~~8j z^sr}CdOo{Co08Z6KGF@>pAtN~LLGv)ZyL|8Q2Fv$7|*UaKE$&tuHEZjy`H#>JTRu` zQK{)b+5AWF(^Y*)!JVd)ps@9_uiO{YKJn{@?Ak|8To_WBQ7zVY6y;}8ADy$50f z>Pg&t$m@kzh%*IKC4<##n=09=rUzMCArf+gWUwK5rltp(ou;SLS67BT==}bGPMElL z`u+~#b@E%4zJB>qRc@j3SWPl#%tH@_pQE%AZ!$jPBSj~G6=(o6ku=hfx!{UC5 z4erghq@zH4IY95&e_L=4&xYUI{7NSW9QS53!9nM+`0pqjdk@eV4gcK!nLczzqd%BK zymH|R{&8+?ZTe@^ zP;-mDq_@REBE|JjW2fMIA4=w1B8tpv804fU=5-oySHdk-VW z{u$BP-eO|QO3zK%d$1Gz8?$#7mfd16plWZR$GwfX_rUdxCIMyHaG?Iw>L2612glNI z{axx@|8r*C>sN$Q_)*^580fu$K>F7deLb(OlI_{Ij|EhgvN?8NZYx@3shWe_ zMb@F`%S`gXWYP3E-a7P-`9wVXdd=@cULJj`=HE}y%R2n4Dvy5aK~=eh%0t8`el|+= zpsHT!{4Up@&hMb>RphfP=BoawPzfsPuJ*(3g#PWlhsn72U}f<#AaFZmb0_^Xo(Yb6 zyg|N!ZH3PWo=AfP9sM0x^jrL%(*s#2_fu>>M*oaM)`@uI-h*Y2 zc|rICStt0zZ&!HlVRCiuJxqFg50i24!PXO6(MvmB?%qRtjBB1Tdha2TNk`m!I5~TA z?&-Nhht1BpBd6xf&Zmz&b!g`khvp8Morh1JB=>RWc>MU$qeqUBhhxX*j_iE!p+|O{ zoICXRla9U1{^eyBcl~$gOD9i5Sy$9PqxPeXjm(dzbv)>}%#9 zyusde@P4}K^=$#!ZD4OkpBs-lkD|^aSBnDmC(8aG&CKon%jVue@kJ#^SP>j$}5^!LUmXBVRu6RR`x#?W&f*L_K$vx z>$flaNB;xae<~dX+5u$$3kv6OOb3Gm=-}Q#ODYiX!{WcKaNIjcq+((`;V09_IcLzp zy#pg1F4Bp62Q7tXh*xmXIW2gi?iV~Sc&2cI2O{I=Jp{f-&=LCJ-PxoTmz@dW5o zt3$@$z3?#QCr+gMS0rCNFOpBnkjb2Nd2C{FK7mf-fjMkqOg9g=d0~tNQ>Q!Bd5!z0E2d?d^iXQC~U= zM|<0>?g^m1H588amMI+V?Nx=NyP3+X;oEy$$RAfj<#`xY}t< z0*gGi(UbdxRNQzp-r{Vj)KhK-Y(@8i&uZN*m{da-h<@Liz)2OL6D^ zb@;0L1K%z2Pv;?>1>y1BM=d0rH-SQofxCiMf4DSEs{1JYgF<<^R`_Op#ep|Tx<>BIY zR~(~D>tmMfhV~)!I{cV~*Nb%r9bKPk=__;Z0q>4BFof+k@N{_aImE9whoLuD5n? zPlTjs7atQG_iNA&um_2~BH$d3>9l3<2XwFpnMkDvepvix3ZE6cBRJYUKbd|@_F6y( zdys9xk)CJ8e^cZhBr`fOY zw%{ieo`^8;oWe7~p<@X2v5~O#O^zV&mJ9?l3U3SEQg|Ynm{)iv_+^DJU{hjiF6aJ0A0QlCK|?G1Zp zz|r1@br14o;geKzlfWX+ZS>?mAr&_sS8sE+RO)H3dys#k;ssqU7vD6=!I(soze0G- zfAK1Ae)BO4BU(Y{tv_$;fUUzq`J;*(iyC!Ee5C6nH$W^unIlA@kC1r?v zZ6~(jPcyS+*M>hOM>IptfpF8dXsLaVZmv_mMrlsF;ZH}S8EOu=dPReacLrl@^WN8% z9{=7L`=z1okzD47y79!!^P;LW{%qJ@9)I*1E1uub_u*)M^VUyuAGFrbR>bs24%`S1 z7!z1O#xpu@+Twn>|A}XG94}~4?)JwH3e=xk@`tD+SSne$enmY2{>ECFKLgc4Yz1FZ z6#OXf%DI>Mo}1@4wBx7cz}Rc_f?2DUH*=Qj(DPa2)711h-a7P-`9wVXdd=?xx_~6l z8opNp;!pGWUSd=oKL1S}Q0QTAWIdh@@~TsA)oiF+pR4@oVj6UPt{ZRNc3#ykL+wqD zJ>LTy3&VfUT%Z}k)Gj%R~b^VuNumt1c-ogFD)^p77CJdraD z+#j+zK>zlPj+~)E|Hti#@wS|SK>Nzi2FY0jj*rb@`e*-{!t=91f`bmXfA){F3&3$U zXhF^*0Do5e8`*0{|B)eH!Qub3;2pt{&irhU?D+zJLHsWW4m#%qH*X^g8Q^@@$MQ|# z>}L>Xj9w->tmmLD^iN57o)>)Pog9;=C&=GiUKMAIPCPj`F>UyFxBZ>*P8#j@?YUlK z&JXlp@_f%9Yscj~WsLiMVXE*Jy=OD4@U}&bIjitQCYBczo(aDBHWx6DR|c|%!drqL zRCrtPOyP-S;#Gxbf?rZN+VeGqqdh0@D5kR|?fHbl(VovKJdyUeo>w^9^JRr+(r%5M?a1R5e7nL^X}6~oj`qBuaJ1)(3U5h!8`d*SAC`Va znu|$bk>@sgj?sTAZal8M$JyqkzV~{D>Bm*Ppv&d%o2oNR2#!szgO=mld9c#!8$ zO8nCbM|eE<(RjiN7WN2hU0Gpnn`$l;&lR zD*F8=h$K>ezX3p=I zcFr)x?=ZTO>&j&F@9+g=_&CdjdvmM#JB+MHLGqSAbo!khh0#ZD#J)(R895L+5IL|C z9LPJo+!EMh3-s^$3`ErB9(B39Dio+cagX-Vs7Jxo4$KGjIw0y%(CgVpiD9Ar4ZUt= ze<7pkv5dG5J;bM8!|e5E0tf|N7iYC491t=*2!;GdFXPh%a^Kh3zbLR zJ-kpp>Xt`ce>%T|u2+%IuEq{}uQVaDcCU0M?v?W1SR%qhwAVX{Ka6LBqh48$fj_KfD zH|XShrP8?oKaBJ!Jl`u79Q@%Y(~o)-4$Xe*lZ{=UY&2(9n=W^McXKA{Q7}B#p}j>t z3d9UDQICS-!(H^?AwbWEQuo?KJqp4IdB|{SdB)H_`UfUn>|^NkC`>eJ?LkI83SKQ4 z(mlwiM?va9u>7%SCw@lYhRkU-??KkrqcCh@LXl`a}(dj>K5l~N$!W&}0G}Jwk%lvS+o|t>;E=uDM>ro)QVDddc(S5#` zrZiU#&u^k0g_Sr9660JO9Jon(6pDHX=$^Po4Y<80S>Sr38j-_|hwp*W*cET6&aIj|dH`5EXN z{Vf&$jQz5|6%ww$dOXhEa#lZ{(b2Mgt^%R66tbl&9ZUDVWe$i%)8oC^I`puos_Bhs zpe8-+0qfv8eJhn;+zZy}(|pD~VeL=n<3{LF_0@)BPIm2_+S%AK z{b}oJ{zP+nXJcw-v++UqBAIA3ryJ7^zP5N>!~20_<~xfaPaA@}g}nc&Ym*DT!QSvJ zQerg#d+OsM00`-Tl)!H*L3g>Hvj3=^z2|COl#xucDuW$C*AoQ12HJ z1{L&=A4B@(VrA5$Knx*+a(sd8%s1S-MtwLZIPP5o|B~RicMY6is-K||opGEnWnWzr z`c})!^twMi3beVr+Vv<Qw8D0sD`ECcmr zJW-Fr$YS?fCm!2!Ynguol_5_~(lSIe(7HWv)^h>bFl5NyJ=hWUf5yD`$2f)XC#j{4 z(e9p@VCD3C^brnp5Z`J(!!&mJ!>Ob@f9Uk@HD|{7WoEwd34X4P9haEO$bra#$bo7O za9>t5fjzcB|L%<+9DJllJqo2gF5Tb4EoqB;w6CodJq>~S6ZI%WJqnp?$(RquJzDA6 z@`s4bayQFjLlW5TE`amu%WU(&WYP3kMqGy;WdA-bw%h5i0_)J@ctb{~Z>92!`^Y+t zka9;o3PsNJTW*7{S5@_1w~xB@ud027>iufklOFV5X+p(q_ex3GYuqbcy?dqTx47Qg zJwMqKMZ3UWY1E_O_>;cT^<&@R>JF?r)>chj)BI`%ld z1bI7}&8SDAu$Ng^j{@|QY~Sk2o%dPnn8`}H$(&L+^p-3rJdr`>qQW!5uPVGFcq-p+ zK)ldfGOO_Rtu8%h6`qLh`i{ag!J{4p$G4^SAfp}y$0z(^zY))>J;>qHqcBl(53m+9H^G&$2XA!kpqzfYl{PUub5i`dq{)dgS3JG{~jFrTS-Pq4^RE^ z&yKG*dXKY6-{TL)Yn`8XPt=txNr>$?e7y0NUyPhKYwCO3#qy8$M18>?&u@$Tq4uHI z1G!u3L%b*2@7|8jdg(pwL({9;W6^sygWfCRctb{~kMmJyPjk@ug)CpEakcM3hWIC9 z$U;^^{z81N>o3F?9hMVNw_b(lh0>?#Rn-ISuWtRTY9Bgp9PiEG^Pu+@c`x1WEl$L} zMc%VZM1+U>aVPPI@l0^^gWCm1g@*sAqn#K-hWW&N!(Ip4<(%Ny>j2-L6&!mVz%#+I z*8w`G1@Fin2=M0xzgc^Wm&YhVGT2)@RlT=3v7EidDgI`3bC>Yi|*I`Fd{=dyWUxo*?!X^`0a47WJOv zp!OEguJqm_+Tn$Yy+ys}i1w!U9MRr}^*hl&F74j+2F4_?$a5P#xvNOUjmO2?oGq0J zO0VCE{&f{E=*n;fr)iRnF+C4Lc+9sDK!>mTPV{d|{L=_1PlU&FAK|e3UjI|g^mFyp zb1tT{S@zQ&_KA{R$Hi`)cN;{$lRhrQc@D>OB00KamikWgxRl>7Sz_HE9e=miovO9B z7t=5;>S&ibP~IE$WUJz*BpY7M_Z#c$Xy5oQ($T(QvT52Elb+m7MSJW~*+#GO~iRLS|7WJf~J@!jO-6Ofo4|nT{xu^c4H2$!T zc5g4&o+Z@t^Sv~sxoUWR6Lqw&tU;gL0k`lKD@`Zf5oJ*E1q$IINk>dwXl&er+zxn=8^*Rs^AJ#g8IE0kWH zGXvObECeKnmN)YrV;y?zFJv@5j<*gy>^Wovd7Ijr-m<@eA*to>;|M;+~sLz*vD z^?A_#bh!<>K3BCj9dF%sUezu`?d@iq`KenTRsEuFAE7=+`(gK;^l#4wO~tc8tNCmY z`b)02oX(CEF#5-j37*KNX4KJ63?YO5;03ZX-`0VS_NnEZF|wzHn*K?ne$N=uS)~aZ zcEX-dn%Lu=G@A15QAfM2dv30oNk<=bv~%kuBWF8!{?Dv|E_SV>9lG12j&^2R*XVWA zUGxgP?D{e$6-U(3?sLWQiV^T}pJ(@d4xf(pUA4|IMIG&4Eh+7hunur7)5+cI<_y#O zo_Nie_Zai77WLs*oPvxIvtcZ4o9RFQy!|I8L00SWOIyqQi#pmBkEoxrToU~rH~2fN ztfO7;@u3_cbMNYC|6RLCce2*_8#xd;5IL}RIiNaTat8L;0%ugc{*p;V9qnsIhkAIA zOOJPOOa18KJK%x(6ZdH29&P4o66RC+`e4=V0b`9UHQ!Y2MTGWHLi-W@?%h=FX=!>@ zdq#S%g=NHb(l_WmEy$+9Pds({Rw}=1RX;+g{;j4xJY7!*U9YO@y^gnT{i|vptDVnP z{S(?5o}spncm6XWhutgP757S4^Ij?XEv~nA&rkM5(Jru8ihJE?2M5GI?sWs_a7+jH zxU-{E?Ii{+FkbcEaAeBE?0cMq~M7h`IzXv2+dQyY*?QU(QnA#py$FI#}l)U zpLk|EX*72<8l-z00lsM0s+z@OXjO!H+`)0h%&D#j)ITsA`4Q3GEr{QY{ z{2iK>5WOhRoq}(dijb$w&V3w5KiO!0k~oSfQ2C9UixfQLkQL7{*)Vy(%r98f;e|T0 z^WqY&L#vKg7>P+=P4C0$ZNPtmk+{kK|p!x@Kw5eo)wSN72!c=AH9d&_j*1A2K-j( z@@WYF9`=a_!gDmE$`3mc|7J-CFQvE)WQn(=E}siR^Z_R38J(?rCMGca*ymDX(B$sv zp2whT@+}}vMrzZ7F^E_{S{Q@UH+RpG$k^hIL0nX$qj!wnY0{$~9J%-ETgbhI{ztz0 zchBr~bf_V`q5W_E=xa6_{@HBVyNRCfAZ17&%o)e;@^ct3z9{Dm9(!||k8M^i{o;$c zThc@E-(enm=ieR;$3N;)WH!As<0xKyky5l>QZzxp0UEZ(i+d|y`3B)n&_6m)va+Fl z6wRMwHTiSwi|00M-f}j;AIFd7r83M-muUaD%-<(!@b^yQ?-PId#@B_@zr2*c(H|oD zJ0iq;|D4HEb0G46#{99J%mm8N&$}(ZwM{?JKDO>nk#Fi?NYD9;FT(9I|CMiK=D&SV zF`~lB{HONe^S`vu{FQHb?Vs-6zxd)A^N;=`6GXg7$H+)Gy%J%${(1Bf4s=|YuY6